From c3df1c6cdea0a5de0e3408d03f47df3377122ea2 Mon Sep 17 00:00:00 2001
From: Paul Wieland
Date: Thu, 23 Jan 2020 08:55:50 -0500
Subject: [PATCH 01/34] Add support for user definable properties to inject
node
---
.../nodes/core/common/20-inject.html | 179 ++++++++++++++----
.../@node-red/nodes/core/common/20-inject.js | 67 ++++---
2 files changed, 181 insertions(+), 65 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/common/20-inject.html b/packages/node_modules/@node-red/nodes/core/common/20-inject.html
index 77ced7d66..c45be4f86 100644
--- a/packages/node_modules/@node-red/nodes/core/common/20-inject.html
+++ b/packages/node_modules/@node-red/nodes/core/common/20-inject.html
@@ -15,15 +15,12 @@
-->
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
index 5dfe45fee..d0a350e6a 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
@@ -25,6 +25,7 @@ module.exports = function(RED) {
this.op1type = n.op1type || "str";
this.op2type = n.op2type || "str";
this.second = n.second || false;
+ this.property = n.property || "topic";
if (this.op1type === 'val') {
if (this.op1 === 'true' || this.op1 === 'false') {
@@ -112,7 +113,7 @@ module.exports = function(RED) {
});
var processMessage = function(msg) {
- var topic = msg.topic || "_none";
+ var topic = RED.util.getMessageProperty(msg,node.property) || "_none";
var promise;
if (node.bytopic === "all") { topic = "_none"; }
node.topics[topic] = node.topics[topic] || {};
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/function/89-trigger.html b/packages/node_modules/@node-red/nodes/locales/en-US/function/89-trigger.html
index 836cabc6f..3caa0ab0a 100644
--- a/packages/node_modules/@node-red/nodes/locales/en-US/function/89-trigger.html
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/function/89-trigger.html
@@ -14,7 +14,7 @@
limitations under the License.
-->
-
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
index 5eb83f9d1..5774d5dac 100755
--- a/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/messages.json
@@ -302,7 +302,7 @@
"wait-for": "wait for",
"wait-loop": "resend it every",
"for": "Handling",
- "bytopics": "each msg.topic independently",
+ "bytopics": "each",
"alltopics": "all messages",
"duration": {
"ms": "Milliseconds",
diff --git a/packages/node_modules/@node-red/nodes/locales/ja/messages.json b/packages/node_modules/@node-red/nodes/locales/ja/messages.json
index adc033390..be98d50e3 100755
--- a/packages/node_modules/@node-red/nodes/locales/ja/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/ja/messages.json
@@ -302,7 +302,7 @@
"wait-for": "指定した時間待機",
"wait-loop": "指定した時間間隔毎に送信を繰り返す",
"for": "処理対象",
- "bytopics": "msg.topic毎",
+ "bytopics": "毎",
"alltopics": "全メッセージ",
"duration": {
"ms": "ミリ秒",
diff --git a/test/nodes/core/function/89-trigger_spec.js b/test/nodes/core/function/89-trigger_spec.js
index ebf1c8db9..063fec47c 100644
--- a/test/nodes/core/function/89-trigger_spec.js
+++ b/test/nodes/core/function/89-trigger_spec.js
@@ -378,6 +378,51 @@ describe('trigger node', function() {
});
});
+ it('should handle multiple other properties individually if asked to do so', function(done) {
+ var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", bytopic:"topic", property:"foo", op1:"1", op2:"0", op1type:"num", op2type:"num", duration:"30", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(triggerNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var c = 0;
+ n2.on("input", function(msg) {
+ try {
+ c += 1;
+ if (c === 1) {
+ msg.should.have.a.property("payload", 1);
+ msg.should.have.a.property("foo", "A");
+ }
+ else if (c === 2) {
+ msg.should.have.a.property("payload", 1);
+ msg.should.have.a.property("foo", "B");
+ }
+ else if (c === 3) {
+ msg.should.have.a.property("payload", 1);
+ msg.should.have.a.property("foo", "C");
+ }
+ else if (c === 4) {
+ msg.should.have.a.property("payload", 0);
+ msg.should.have.a.property("foo", "A");
+ }
+ else if (c === 5) {
+ msg.should.have.a.property("payload", 0);
+ msg.should.have.a.property("foo", "B");
+ }
+ else if (c === 6) {
+ msg.should.have.a.property("payload", 0);
+ msg.should.have.a.property("foo", "C");
+ done();
+ }
+ } catch(err) {
+ done(err);
+ }
+ });
+ n1.emit("input", {payload:1,foo:"A"});
+ n1.emit("input", {payload:2,foo:"B"});
+ n1.emit("input", {payload:3,foo:"C"});
+ });
+ });
+
it('should be able to return things from flow and global context variables', function(done) {
var spy = sinon.stub(RED.util, 'evaluateNodeProperty',
function(arg1, arg2, arg3, arg4, arg5) { if (arg5) { arg5(null, arg1) } else { return arg1; } }
From 87aacb4270f1db52952e6257e115cc359f8350f9 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 30 Jan 2020 22:20:55 +0000
Subject: [PATCH 07/34] change property name to leave space if we want to also
do main payload property
---
.../@node-red/nodes/core/function/89-trigger.html | 10 +++++-----
.../@node-red/nodes/core/function/89-trigger.js | 4 ++--
test/nodes/core/function/89-trigger_spec.js | 2 +-
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.html b/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
index 5e250be28..187a87190 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
@@ -66,8 +66,8 @@
-
-
+
+
@@ -93,7 +93,7 @@
reset: {value:""},
bytopic: {value:"all"},
outputs: {value:1},
- property: {value:"topic",required:true}
+ topic: {value:"topic",required:true}
},
inputs:1,
outputs:1,
@@ -121,9 +121,9 @@
$("#node-input-bytopic").on("change", function() {
console.log("BYT",$("#node-input-bytopic").val());
if ($("#node-input-bytopic").val() === "all") {
- $("#node-trigger-property").hide();
+ $("#node-stream-topic").hide();
} else {
- $("#node-trigger-property").show();
+ $("#node-stream-topic").show();
}
});
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
index d0a350e6a..dab7a83ab 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
@@ -25,7 +25,7 @@ module.exports = function(RED) {
this.op1type = n.op1type || "str";
this.op2type = n.op2type || "str";
this.second = n.second || false;
- this.property = n.property || "topic";
+ this.topic = n.topic || "topic";
if (this.op1type === 'val') {
if (this.op1 === 'true' || this.op1 === 'false') {
@@ -113,7 +113,7 @@ module.exports = function(RED) {
});
var processMessage = function(msg) {
- var topic = RED.util.getMessageProperty(msg,node.property) || "_none";
+ var topic = RED.util.getMessageProperty(msg,node.topic) || "_none";
var promise;
if (node.bytopic === "all") { topic = "_none"; }
node.topics[topic] = node.topics[topic] || {};
diff --git a/test/nodes/core/function/89-trigger_spec.js b/test/nodes/core/function/89-trigger_spec.js
index 063fec47c..582b47904 100644
--- a/test/nodes/core/function/89-trigger_spec.js
+++ b/test/nodes/core/function/89-trigger_spec.js
@@ -379,7 +379,7 @@ describe('trigger node', function() {
});
it('should handle multiple other properties individually if asked to do so', function(done) {
- var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", bytopic:"topic", property:"foo", op1:"1", op2:"0", op1type:"num", op2type:"num", duration:"30", wires:[["n2"]] },
+ var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", bytopic:"topic", topic:"foo", op1:"1", op2:"0", op1type:"num", op2type:"num", duration:"30", wires:[["n2"]] },
{id:"n2", type:"helper"} ];
helper.load(triggerNode, flow, function() {
var n1 = helper.getNode("n1");
From 88e729664afa71b275c0f1ce38ede42adc81ef2b Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 31 Jan 2020 17:56:06 +0000
Subject: [PATCH 08/34] complete tidy up of trigger node
remove unnecessary console.log
---
.../@node-red/nodes/core/function/89-trigger.html | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.html b/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
index 187a87190..79b022519 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
@@ -92,8 +92,8 @@
units: {value:"ms"},
reset: {value:""},
bytopic: {value:"all"},
- outputs: {value:1},
- topic: {value:"topic",required:true}
+ topic: {value:"topic",required:true},
+ outputs: {value:1}
},
inputs:1,
outputs:1,
@@ -114,12 +114,9 @@
},
oneditprepare: function() {
var that = this;
- if (this.property === undefined) {
- $("#node-input-property").val("topic");
- }
- $("#node-input-property").typedInput({default:'msg',types:['msg']});
+ if (this.topic === undefined) { $("#node-input-topic").val("topic"); }
+ $("#node-input-topic").typedInput({default:'msg',types:['msg']});
$("#node-input-bytopic").on("change", function() {
- console.log("BYT",$("#node-input-bytopic").val());
if ($("#node-input-bytopic").val() === "all") {
$("#node-stream-topic").hide();
} else {
From 127b3619795970cb52f9378adddba46125e63d71 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 14 Feb 2020 20:13:37 -0500
Subject: [PATCH 09/34] change PR to only use a single property for the 2nd
output
---
.../@node-red/nodes/core/function/89-trigger.html | 4 +++-
.../node_modules/@node-red/nodes/core/function/89-trigger.js | 2 +-
test/nodes/core/function/89-trigger_spec.js | 2 +-
3 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.html b/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
index 79b022519..8917f81d8 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.html
@@ -88,7 +88,6 @@
op2type: {value:"val"},
duration: {value:"250",required:true,validate:RED.validators.number()},
extend: {value:"false"},
- second: {value:false},
units: {value:"ms"},
reset: {value:""},
bytopic: {value:"all"},
@@ -123,6 +122,9 @@
$("#node-stream-topic").show();
}
});
+
+ if (this.outputs == 2) { $("#node-input-second").prop('checked', true) }
+ else { $("#node-input-second").prop('checked', false) }
$("#node-input-second").change(function() {
if ($("#node-input-second").is(":checked")) {
diff --git a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
index dab7a83ab..e3fca00aa 100644
--- a/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
+++ b/packages/node_modules/@node-red/nodes/core/function/89-trigger.js
@@ -24,7 +24,7 @@ module.exports = function(RED) {
this.op2 = n.op2 || "0";
this.op1type = n.op1type || "str";
this.op2type = n.op2type || "str";
- this.second = n.second || false;
+ this.second = (n.outputs == 2) ? true : false;
this.topic = n.topic || "topic";
if (this.op1type === 'val') {
diff --git a/test/nodes/core/function/89-trigger_spec.js b/test/nodes/core/function/89-trigger_spec.js
index 582b47904..f13e23a5e 100644
--- a/test/nodes/core/function/89-trigger_spec.js
+++ b/test/nodes/core/function/89-trigger_spec.js
@@ -827,7 +827,7 @@ describe('trigger node', function() {
});
it('should be able to send 2nd message to a 2nd output', function(done) {
- var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"val", op1:"hello", op2:"world", duration:"50", second:true, wires:[["n2"],["n3"]] },
+ var flow = [{"id":"n1", "type":"trigger", "name":"triggerNode", op1type:"val", op2type:"val", op1:"hello", op2:"world", duration:"50", outputs:2, wires:[["n2"],["n3"]] },
{id:"n2", type:"helper"}, {id:"n3", type:"helper"} ];
helper.load(triggerNode, flow, function() {
var n1 = helper.getNode("n1");
From dea47a6e3db761bb2e2400e6d0e8a5ba9a0dd4e5 Mon Sep 17 00:00:00 2001
From: Thierry Le Gal
Date: Tue, 3 Mar 2020 18:43:44 +0100
Subject: [PATCH 10/34] Improve performance in change node panel
---
.../nodes/core/function/15-change.html | 118 +++++++++++++-----
1 file changed, 89 insertions(+), 29 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/function/15-change.html b/packages/node_modules/@node-red/nodes/core/function/15-change.html
index fc9fa8d84..59d4337c5 100644
--- a/packages/node_modules/@node-red/nodes/core/function/15-change.html
+++ b/packages/node_modules/@node-red/nodes/core/function/15-change.html
@@ -1,5 +1,10 @@
diff --git a/test/nodes/core/parsers/70-CSV_spec.js b/test/nodes/core/parsers/70-CSV_spec.js
index 3917d2d7c..9e7b45d8f 100644
--- a/test/nodes/core/parsers/70-CSV_spec.js
+++ b/test/nodes/core/parsers/70-CSV_spec.js
@@ -1,3 +1,4 @@
+/* eslint-disable no-undef */
/**
* Copyright JS Foundation and other contributors, http://js.foundation
*
@@ -70,12 +71,13 @@ describe('CSV node', function() {
it('should convert a simple csv string to a javascript object', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
msg.should.have.property('payload', { a: 1, b: 2, c: 3, d: 4 });
+ msg.should.have.property('columns', "a,b,c,d");
check_parts(msg, 0, 1);
done();
});
@@ -86,7 +88,7 @@ describe('CSV node', function() {
it('should remove quotes and whitespace from template', function(done) {
var flow = [ { id:"n1", type:"csv", temp:'"a", "b" , " c "," d " ', wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -102,12 +104,13 @@ describe('CSV node', function() {
it('should create column names if no template provided', function(done) {
var flow = [ { id:"n1", type:"csv", temp:'', wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
msg.should.have.property('payload', { col1: 1, col2: 2, col3: 3, col4: 4 });
+ msg.should.have.property('columns', "col1,col2,col3,col4");
check_parts(msg, 0, 1);
done();
});
@@ -118,12 +121,13 @@ describe('CSV node', function() {
it('should allow dropping of fields from the template', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,,,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
msg.should.have.property('payload', { a: 1, d: 4 });
+ msg.should.have.property('columns', 'a,d');
check_parts(msg, 0, 1);
done();
});
@@ -134,7 +138,7 @@ describe('CSV node', function() {
it('should leave numbers starting with 0, e and + as strings (except 0.)', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -150,7 +154,7 @@ describe('CSV node', function() {
it('should not parse numbers when told not to do so', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", strings:false, wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -166,7 +170,7 @@ describe('CSV node', function() {
it('should leave handle strings with scientific notation as numbers', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -183,7 +187,7 @@ describe('CSV node', function() {
it('should allow quotes in the input (but drop blank strings)', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g,h", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -234,7 +238,7 @@ describe('CSV node', function() {
it('should recover from an odd number of quotes in the input', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e,f,g", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -277,12 +281,13 @@ describe('CSV node', function() {
it('should be able to output multiple lines as one array', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", multi:"yes", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
msg.should.have.property('payload', [ { a: 1, b: 2, c: 3, d: 4 },{ a: 5, b: -6, c: '07', d: '+8' },{ a: 9, b: 0, c: 'a', d: 'b' },{ a: 'c', b: 'd', c: 'e', d: 'f' } ]);
+ msg.should.have.property('columns','a,b,c,d');
msg.should.not.have.property('parts');
done();
});
@@ -293,7 +298,7 @@ describe('CSV node', function() {
it('should handle numbers in strings but not IP addresses', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -309,7 +314,7 @@ describe('CSV node', function() {
it('should preserve parts property', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -353,7 +358,7 @@ describe('CSV node', function() {
it('should skip several lines from start if requested', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", skip: 2, wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -367,9 +372,9 @@ describe('CSV node', function() {
});
});
- it('should skip several lines from start then use next line as a tempate', function(done) {
+ it('should skip several lines from start then use next line as a template', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrin:true, skip: 2, wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -385,7 +390,7 @@ describe('CSV node', function() {
it('should skip several lines from start and correct parts', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", skip: 2, wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -417,11 +422,13 @@ describe('CSV node', function() {
n2.on("input", function(msg) {
if (c === 0) {
msg.should.have.property('payload', { w: 1, x: 2, y: 3, z: 4 });
+ msg.should.have.property('columns', 'w,x,y,z');
check_parts(msg, 0, 2);
c += 1;
}
else {
msg.should.have.property('payload', { w: 5, x: 6, y: 7, z: 8 });
+ msg.should.have.property('columns', 'w,x,y,z');
check_parts(msg, 1, 2);
done();
}
@@ -445,7 +452,7 @@ describe('CSV node', function() {
it('should convert a simple object back to a csv', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,,e", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -463,7 +470,7 @@ describe('CSV node', function() {
it('should convert a simple object back to a csv with no template', function(done) {
var flow = [ { id:"n1", type:"csv", temp:" ", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -481,7 +488,7 @@ describe('CSV node', function() {
it('should handle a template with spaces in the property names', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b o,c p,,e", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -499,7 +506,7 @@ describe('CSV node', function() {
it('should convert an array of objects to a multi-line csv', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -517,7 +524,7 @@ describe('CSV node', function() {
it('should convert a simple array back to a csv', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -535,7 +542,7 @@ describe('CSV node', function() {
it('should convert an array of arrays back to a multi-line csv', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -553,7 +560,7 @@ describe('CSV node', function() {
it('should be able to include column names as first row', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", hdrout:true, ret:"\r\n", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -569,9 +576,36 @@ describe('CSV node', function() {
});
});
+ it('should be able to pass in column names', function(done) {
+ var flow = [ { id:"n1", type:"csv", temp:"", hdrout:"once", ret:"\r\n", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(csvNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ var count = 0;
+ n2.on("input", function(msg) {
+ count += 1;
+ try {
+ if (count === 1) {
+ msg.should.have.property('payload', 'a,,b,a\r\n4,,3,4\r\n');
+ }
+ if (count === 3) {
+ msg.should.have.property('payload', '4,,3,4\r\n');
+ done()
+ }
+ }
+ catch(e) { done(e); }
+ });
+ var testJson = [{ d: 1, b: 3, c: 2, a: 4 }];
+ n1.emit("input", {payload:testJson, columns:"a,,b,a"});
+ n1.emit("input", {payload:testJson});
+ n1.emit("input", {payload:testJson});
+ });
+ });
+
it('should handle quotes and sub-properties', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -591,7 +625,7 @@ describe('CSV node', function() {
it('should just pass through if no payload provided', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
@@ -611,7 +645,7 @@ describe('CSV node', function() {
it('should warn if provided a number or boolean', function(done) {
var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d", wires:[["n2"]] },
- {id:"n2", type:"helper"} ];
+ {id:"n2", type:"helper"} ];
helper.load(csvNode, flow, function() {
var n1 = helper.getNode("n1");
var n2 = helper.getNode("n2");
From 24eb78d1371bf1ada68ebaa3556376fb92250943 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Fri, 3 Apr 2020 16:55:43 +0100
Subject: [PATCH 13/34] add ja translations
---
.../node_modules/@node-red/nodes/locales/ja/messages.json | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/packages/node_modules/@node-red/nodes/locales/ja/messages.json b/packages/node_modules/@node-red/nodes/locales/ja/messages.json
index e15947fa6..92f0b1677 100755
--- a/packages/node_modules/@node-red/nodes/locales/ja/messages.json
+++ b/packages/node_modules/@node-red/nodes/locales/ja/messages.json
@@ -719,6 +719,11 @@
"mac": "Mac (\\r)",
"windows": "Windows (\\r\\n)"
},
+ "hdrout": {
+ "none": "カラムヘッダを送信しない",
+ "all": "カラムヘッダを常に送信する",
+ "once": "ヘッダを一度だけ送信する(msg.resetの受け付けると再送)"
+ },
"errors": {
"csv_js": "本ノードが処理できる形式は、CSV文字列またはJSONのみです",
"obj_csv": "オブジェクトをCSVへ変換する際の列名が設定されていません"
From 2f869a55e2fd1fc3d229dc38989307f916d08ad2 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 6 Apr 2020 15:39:48 +0100
Subject: [PATCH 14/34] Handle nodes with no wires array
---
packages/node_modules/@node-red/editor-client/src/js/nodes.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js
index 61a5ae806..8beb9f9f4 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js
@@ -1109,7 +1109,7 @@ RED.nodes = (function() {
defaults: {},
label: "unknown: "+n.type,
labelStyle: "red-ui-flow-node-label-italic",
- outputs: n.outputs||n.wires.length,
+ outputs: n.outputs|| (n.wires && n.wires.length) || 0,
set: registry.getNodeSet("node-red/unknown")
}
} else {
From 572c03631da00f97409192e10510fec281289802 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 6 Apr 2020 15:40:06 +0100
Subject: [PATCH 15/34] Do not collapse whitespace in Debug string messages
---
.../node_modules/@node-red/editor-client/src/sass/debug.scss | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/debug.scss b/packages/node_modules/@node-red/editor-client/src/sass/debug.scss
index c92c43320..1e77e46e1 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/debug.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/debug.scss
@@ -217,6 +217,10 @@
.red-ui-debug-msg-type-number { color: $debug-message-text-color-msg-type-number; };
.red-ui-debug-msg-type-number-toggle { cursor: pointer;}
+.red-ui-debug-msg-type-string {
+ white-space: pre-wrap;
+}
+
.red-ui-debug-msg-row {
display: block;
padding: 4px 2px 2px;
From 513957eea16456862d88cc85e783532c860f86cf Mon Sep 17 00:00:00 2001
From: martinLim45
Date: Tue, 7 Apr 2020 16:41:49 +0900
Subject: [PATCH 16/34] Set flow.disabled when disabled property is false
---
.../node_modules/@node-red/runtime/lib/nodes/flows/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js b/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js
index 16166fbc1..1a350ce7c 100644
--- a/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js
+++ b/packages/node_modules/@node-red/runtime/lib/nodes/flows/index.js
@@ -553,7 +553,7 @@ function getFlow(id) {
if (flow.label) {
result.label = flow.label;
}
- if (flow.disabled) {
+ if (flow.hasOwnProperty('disabled')) {
result.disabled = flow.disabled;
}
if (flow.hasOwnProperty('info')) {
From 97c771f93a0b4129c2f0f61e5c3480bc65c69686 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Wed, 8 Apr 2020 11:32:39 +0100
Subject: [PATCH 17/34] Ensure file context does not write 'undefined' to store
Fixes #2522
---
.../@node-red/runtime/lib/nodes/context/localfilesystem.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js b/packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js
index cf1769700..9755681d8 100644
--- a/packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js
+++ b/packages/node_modules/@node-red/runtime/lib/nodes/context/localfilesystem.js
@@ -203,10 +203,10 @@ LocalFileSystem.prototype.open = function(){
var newContext = self.cache._export();
scopes.forEach(function(scope) {
var storagePath = getStoragePath(self.storageBaseDir,scope);
- var context = newContext[scope];
+ var context = newContext[scope] || {};
var stringifiedContext = stringify(context);
if (stringifiedContext.circular && !self.knownCircularRefs[scope]) {
- log.warn(log._("error-circular",{scope:scope}));
+ log.warn(log._("context.localfilesystem.error-circular",{scope:scope}));
self.knownCircularRefs[scope] = true;
} else {
delete self.knownCircularRefs[scope];
@@ -324,7 +324,7 @@ LocalFileSystem.prototype.set = function(scope, key, value, callback) {
}
var stringifiedContext = stringify(obj);
if (stringifiedContext.circular && !self.knownCircularRefs[scope]) {
- log.warn(log._("error-circular",{scope:scope}));
+ log.warn(log._("context.localfilesystem.error-circular",{scope:scope}));
self.knownCircularRefs[scope] = true;
} else {
delete self.knownCircularRefs[scope];
From c989f466ed99f36166080eaf870a1df63bb7b2ea Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Wed, 8 Apr 2020 12:38:49 +0100
Subject: [PATCH 18/34] Update changelog
---
CHANGELOG.md | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7ea3845c2..dbd14497a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,42 @@
+#### 1.0.5: Maintenance Release
+
+Runtime
+
+ - #2500 Support for context stores using JSONata and evaluateNodeProperty()
+ - Add better handling of host-key-verify error with projects
+ - #2517 Handle false values in $env() properly
+ - #2514 Ensure complete node scope is remapped in subflows
+ - #2513 Flows/subflows must preinitialise their context objects
+ - Clear node.close timeout to avoid unnecessary work on restart
+ - #2532 Set flow.disabled when disabled property is false
+ - #2522 Ensure file context does not write 'undefined' to store
+
+Editor
+
+ - #2489 Fix XPath in UI tests
+ - #2504 Fix paletteCategories order
+ - #2501 Add page objects for UI testing
+ - #2494 Check node props when deciding if pasted node can splice links
+ - #2521 Don't double-sanitize node name in debug sidebar
+ - #2519 German i18n updates
+ - #2523 Update nodeTabMap when replacing unknown nodes
+ - Update TypedInput to use flexbox and remove resizing code
+ - Handle nodes with no wires array
+ - Do not collapse whitespace in Debug string messages
+
+Nodes
+
+ - File: Remove old legacy wording from file node info to stop confusing users.
+ - Join: Ensure join node handles missing buffer joiner when not in string mode
+ - Exec: make exec node logging consistent with itself. (only be verbose when in verbose mode)
+ - Trigger: reset default timeout value when switching away from wait for reset
+ - Join: Fix join to not crash on appending invalid types to buffer.
+ - MQTT out: Add warning if topic contains + or #
+ - #2502 WebSocket i18n update
+ - #2508 Add Japanese translation for join node
+ - TCP out: tidy up select of which rows to display
+
+
#### 1.0.4: Maintenance Release
Runtime
From e26eb85718e55c91a688a5309287e47354ad901d Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Wed, 8 Apr 2020 17:06:11 +0100
Subject: [PATCH 19/34] Fine tune typedInput flexbox handling on option-button
---
.../src/js/ui/common/typedInput.js | 4 +++-
.../editor-client/src/sass/editor.scss | 2 +-
.../src/sass/ui/common/typedInput.scss | 24 ++++++++-----------
3 files changed, 14 insertions(+), 16 deletions(-)
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
index 88c842c2f..a6713951a 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
@@ -657,11 +657,13 @@
this.optionExpandButton.shown = false;
}
if (this.optionSelectTrigger) {
- this.optionSelectTrigger.show();
+ this.optionSelectTrigger.css({"display":"inline-flex"});
if (!opt.hasValue) {
+ this.optionSelectTrigger.css({"flex-grow":1})
this.elementDiv.hide();
this.valueLabelContainer.hide();
} else {
+ this.optionSelectTrigger.css({"flex-grow":0})
this.elementDiv.show();
this.valueLabelContainer.hide();
}
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/editor.scss b/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
index b13941f22..c95fecad6 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/editor.scss
@@ -633,7 +633,7 @@ button.red-ui-toggleButton.toggle {
.red-ui-typedInput-value-label,.red-ui-typedInput-option-label {
select,.placeholder-input {
margin: 3px;
- height: 26px;
+ height: 24px;
width: calc(100% - 10px);
padding-left: 3px;
}
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss
index 243c42e17..ffa424841 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/typedInput.scss
@@ -171,25 +171,21 @@ button.red-ui-typedInput-option-trigger {
padding: 0 0 0 0;
position:relative;
flex-grow: 1;
+ line-height: 32px;
+ display: inline-flex;
.red-ui-typedInput-option-label {
background:$form-button-background;
color: $form-text-color;
- position:absolute;
- left:0;
- right:23px;
- top: 0;
- padding: 0 5px 0 8px;
- i.red-ui-typedInput-icon {
- margin-right: 4px;
- }
+ flex-grow: 1;
+ padding: 0 0 0 8px;
+ display:inline-block;
}
.red-ui-typedInput-option-caret {
- top: 0;
- position: absolute;
- right: 0;
- bottom: 0;
- width: 17px;
- padding-left: 5px;
+ flex-grow: 0;
+ display:inline-block;
+ width: 23px;
+ text-align: center;
+ height: 100%;
&:before {
content:'';
display: inline-block;
From 7c1853431ac44725b97361a828bcf163fc566daf Mon Sep 17 00:00:00 2001
From: Paul Wieland
Date: Wed, 8 Apr 2020 12:29:55 -0400
Subject: [PATCH 20/34] Update 20-inject.html
Cleanup old payload, topic & type.
Move name and remove tip.
---
.../nodes/core/common/20-inject.html | 55 +++++++++++++++++--
1 file changed, 50 insertions(+), 5 deletions(-)
diff --git a/packages/node_modules/@node-red/nodes/core/common/20-inject.html b/packages/node_modules/@node-red/nodes/core/common/20-inject.html
index 5b3c53076..bc99fb92f 100644
--- a/packages/node_modules/@node-red/nodes/core/common/20-inject.html
+++ b/packages/node_modules/@node-red/nodes/core/common/20-inject.html
@@ -15,6 +15,10 @@
-->