@node-red/nodes 3.0.0-beta.1 → 3.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/99-sample.html.demo +1 -1
- package/core/common/20-inject.html +1 -1
- package/core/common/20-inject.js +3 -2
- package/core/common/21-debug.html +2 -3
- package/core/common/60-link.html +1 -2
- package/core/common/60-link.js +7 -10
- package/core/common/lib/debug/debug-utils.js +1 -1
- package/core/function/10-function.html +6 -6
- package/core/function/10-switch.html +16 -11
- package/core/function/80-template.js +24 -0
- package/core/function/89-delay.js +13 -9
- package/core/network/10-mqtt.js +54 -17
- package/core/network/21-httpin.html +4 -4
- package/core/network/21-httprequest.html +4 -2
- package/core/network/31-tcpin.js +15 -17
- package/core/parsers/70-CSV.js +5 -2
- package/core/sequence/17-split.html +1 -1
- package/core/sequence/17-split.js +4 -2
- package/core/storage/10-file.html +8 -8
- package/examples/function/delay/06 - Simple Queue with release +149 -0
- package/locales/en-US/common/60-link.html +3 -2
- package/locales/en-US/messages.json +109 -107
- package/locales/ja/common/60-link.html +3 -2
- package/locales/ja/function/10-function.html +1 -1
- package/locales/ja/messages.json +65 -58
- package/locales/ja/network/10-mqtt.html +1 -1
- package/locales/ja/network/21-httprequest.html +1 -1
- package/locales/ja/storage/10-file.html +8 -6
- package/package.json +3 -3
package/99-sample.html.demo
CHANGED
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
outputs:1, // set the number of outputs - 0 to n
|
|
70
70
|
color: "#ddd", // set icon color
|
|
71
71
|
// set the icon (held in icons dir below where you save the node)
|
|
72
|
-
icon: "myicon.
|
|
72
|
+
icon: "myicon.svg", // saved in icons/myicon.svg
|
|
73
73
|
label: function() { // sets the default label contents
|
|
74
74
|
return this.name||this.topic||"sample";
|
|
75
75
|
},
|
package/core/common/20-inject.js
CHANGED
|
@@ -109,9 +109,10 @@ module.exports = function(RED) {
|
|
|
109
109
|
if (!property) return;
|
|
110
110
|
|
|
111
111
|
if (valueType === "jsonata") {
|
|
112
|
-
if (p.
|
|
112
|
+
if (p.v) {
|
|
113
113
|
try {
|
|
114
|
-
var
|
|
114
|
+
var exp = RED.util.prepareJSONataExpression(p.v, node);
|
|
115
|
+
var val = RED.util.evaluateJSONataExpression(exp, msg);
|
|
115
116
|
RED.util.setMessageProperty(msg, property, val, true);
|
|
116
117
|
}
|
|
117
118
|
catch (err) {
|
|
@@ -499,7 +499,7 @@
|
|
|
499
499
|
types:['msg', fullType, "jsonata"],
|
|
500
500
|
typeField: $("#node-input-targetType")
|
|
501
501
|
});
|
|
502
|
-
|
|
502
|
+
if (this.targetType === "jsonata") {
|
|
503
503
|
var property = this.complete || "";
|
|
504
504
|
$("#node-input-typed-complete").typedInput('type','jsonata');
|
|
505
505
|
$("#node-input-typed-complete").typedInput('value',property);
|
|
@@ -530,7 +530,6 @@
|
|
|
530
530
|
if (type !== 'full') {
|
|
531
531
|
comp = $("#node-input-typed-complete").typedInput('value');
|
|
532
532
|
}
|
|
533
|
-
console.log('hihi')
|
|
534
533
|
that.statusType = "auto";
|
|
535
534
|
that.statusVal = comp;
|
|
536
535
|
}
|
|
@@ -559,7 +558,7 @@
|
|
|
559
558
|
onadd: function() {
|
|
560
559
|
if (this.name === '_DEFAULT_') {
|
|
561
560
|
this.name = ''
|
|
562
|
-
RED.actions.invoke("core:generate-node-names", this)
|
|
561
|
+
RED.actions.invoke("core:generate-node-names", this, {generateHistory: false})
|
|
563
562
|
}
|
|
564
563
|
}
|
|
565
564
|
});
|
package/core/common/60-link.html
CHANGED
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
function onAdd() {
|
|
222
222
|
if (this.name === '_DEFAULT_') {
|
|
223
223
|
this.name = ''
|
|
224
|
-
RED.actions.invoke("core:generate-node-names", this)
|
|
224
|
+
RED.actions.invoke("core:generate-node-names", this, {generateHistory: false})
|
|
225
225
|
}
|
|
226
226
|
for (var i=0;i<this.links.length;i++) {
|
|
227
227
|
var n = RED.nodes.node(this.links[i]);
|
|
@@ -302,7 +302,6 @@
|
|
|
302
302
|
return this.name?"node_label_italic":"";
|
|
303
303
|
},
|
|
304
304
|
oneditprepare: function() {
|
|
305
|
-
console.log("link call oneditprepare")
|
|
306
305
|
const updateVisibility = function() {
|
|
307
306
|
const static = $('#node-input-linkType').val() !== "dynamic";
|
|
308
307
|
if(static) {
|
package/core/common/60-link.js
CHANGED
|
@@ -109,16 +109,13 @@ module.exports = function(RED) {
|
|
|
109
109
|
},
|
|
110
110
|
remove(node) {
|
|
111
111
|
const target = generateTarget(node);
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if (targs.length === 0) {
|
|
120
|
-
delete registry.name[tn.name];
|
|
121
|
-
}
|
|
112
|
+
const targs = this.getTargets(target.name);
|
|
113
|
+
const idx = getIndex(targs, target.id);
|
|
114
|
+
if (idx > -1) {
|
|
115
|
+
targs.splice(idx, 1);
|
|
116
|
+
}
|
|
117
|
+
if (targs.length === 0) {
|
|
118
|
+
delete registry.name[tn.name];
|
|
122
119
|
}
|
|
123
120
|
delete registry.id[target.id];
|
|
124
121
|
},
|
|
@@ -582,7 +582,7 @@ RED.debug = (function() {
|
|
|
582
582
|
$('<span class="red-ui-debug-msg-date">'+ getTimestamp()+'</span>').appendTo(metaRow);
|
|
583
583
|
if (sourceNode) {
|
|
584
584
|
|
|
585
|
-
var nodeLink = $('<a>',{href:"#",class:"red-ui-debug-msg-name"}).text("node: "+(o.name||sourceNode.name||sourceNode.id))
|
|
585
|
+
var nodeLink = $('<a>',{href:"#",class:"red-ui-debug-msg-name"}).text(RED._("node-red:debug.node")+": "+(o.name||sourceNode.name||sourceNode.id))
|
|
586
586
|
.appendTo(metaRow)
|
|
587
587
|
.on("click", function(evt) {
|
|
588
588
|
evt.preventDefault();
|
|
@@ -460,7 +460,7 @@
|
|
|
460
460
|
}
|
|
461
461
|
});
|
|
462
462
|
|
|
463
|
-
var buildEditor = function(id, stateId, focus, value, defaultValue, extraLibs) {
|
|
463
|
+
var buildEditor = function(id, stateId, focus, value, defaultValue, extraLibs, offset) {
|
|
464
464
|
var editor = RED.editor.createEditor({
|
|
465
465
|
id: id,
|
|
466
466
|
mode: 'ace/mode/nrjavascript',
|
|
@@ -484,14 +484,14 @@
|
|
|
484
484
|
extraLibs: extraLibs
|
|
485
485
|
});
|
|
486
486
|
if (defaultValue && value === "") {
|
|
487
|
-
editor.moveCursorTo(defaultValue.split("\n").length
|
|
487
|
+
editor.moveCursorTo(defaultValue.split("\n").length +offset, 0);
|
|
488
488
|
}
|
|
489
489
|
editor.__stateId = stateId;
|
|
490
490
|
return editor;
|
|
491
491
|
}
|
|
492
|
-
this.initEditor = buildEditor('node-input-init-editor', this.id + "/" + "initEditor", false, $("#node-input-initialize").val(), RED._("node-red:function.text.initialize"))
|
|
493
|
-
this.editor = buildEditor('node-input-func-editor', this.id + "/" + "editor", true, $("#node-input-func").val(), undefined, that.libs || [])
|
|
494
|
-
this.finalizeEditor = buildEditor('node-input-finalize-editor', this.id + "/" + "finalizeEditor", false, $("#node-input-finalize").val(), RED._("node-red:function.text.finalize"))
|
|
492
|
+
this.initEditor = buildEditor('node-input-init-editor', this.id + "/" + "initEditor", false, $("#node-input-initialize").val(), RED._("node-red:function.text.initialize"), undefined, 0);
|
|
493
|
+
this.editor = buildEditor('node-input-func-editor', this.id + "/" + "editor", true, $("#node-input-func").val(), undefined, that.libs || [], undefined, -1);
|
|
494
|
+
this.finalizeEditor = buildEditor('node-input-finalize-editor', this.id + "/" + "finalizeEditor", false, $("#node-input-finalize").val(), RED._("node-red:function.text.finalize"), undefined, 0);
|
|
495
495
|
|
|
496
496
|
RED.library.create({
|
|
497
497
|
url:"functions", // where to get the data from
|
|
@@ -639,7 +639,7 @@
|
|
|
639
639
|
onadd: function() {
|
|
640
640
|
if (this.name === '_DEFAULT_') {
|
|
641
641
|
this.name = ''
|
|
642
|
-
RED.actions.invoke("core:generate-node-names", this)
|
|
642
|
+
RED.actions.invoke("core:generate-node-names", this, {generateHistory: false})
|
|
643
643
|
}
|
|
644
644
|
}
|
|
645
645
|
});
|
|
@@ -146,13 +146,13 @@
|
|
|
146
146
|
|
|
147
147
|
function createTypeValueField(row, defaultType){
|
|
148
148
|
return $('<input/>',{class:"node-input-rule-type-value",type:"text",style:"width: 100%;"}).appendTo(row).typedInput({default:defaultType || 'string',types:[
|
|
149
|
-
{value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.
|
|
150
|
-
{value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.
|
|
151
|
-
{value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.
|
|
152
|
-
{value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.
|
|
153
|
-
{value:"buffer",label:RED._("common.type.buffer"),hasValue:false,icon:"red/images/typedInput/bin.
|
|
154
|
-
{value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.
|
|
155
|
-
{value:"json",label:RED._("common.type.jsonString"),hasValue:false,icon:"red/images/typedInput/json.
|
|
149
|
+
{value:"string",label:RED._("common.type.string"),hasValue:false,icon:"red/images/typedInput/az.svg"},
|
|
150
|
+
{value:"number",label:RED._("common.type.number"),hasValue:false,icon:"red/images/typedInput/09.svg"},
|
|
151
|
+
{value:"boolean",label:RED._("common.type.boolean"),hasValue:false,icon:"red/images/typedInput/bool.svg"},
|
|
152
|
+
{value:"array",label:RED._("common.type.array"),hasValue:false,icon:"red/images/typedInput/json.svg"},
|
|
153
|
+
{value:"buffer",label:RED._("common.type.buffer"),hasValue:false,icon:"red/images/typedInput/bin.svg"},
|
|
154
|
+
{value:"object",label:RED._("common.type.object"),hasValue:false,icon:"red/images/typedInput/json.svg"},
|
|
155
|
+
{value:"json",label:RED._("common.type.jsonString"),hasValue:false,icon:"red/images/typedInput/json.svg"},
|
|
156
156
|
{value:"undefined",label:RED._("common.type.undefined"),hasValue:false},
|
|
157
157
|
{value:"null",label:RED._("common.type.null"),hasValue:false}
|
|
158
158
|
]});
|
|
@@ -247,14 +247,16 @@
|
|
|
247
247
|
var row2 = $('<div/>',{style:"display: flex; padding-top: 5px; padding-left: 175px;"}).appendTo(inputRows);
|
|
248
248
|
var row3 = $('<div/>',{style:"display: flex; padding-top: 5px; align-items: center"}).appendTo(inputRows);
|
|
249
249
|
|
|
250
|
+
var row4 = $('<div/>',{style:"visibility: hidden; height: 0px;"}).appendTo(inputRows);
|
|
251
|
+
var textSpan = $("<span/>").appendTo(row4);
|
|
250
252
|
var selectField = $('<select/>',{style:"width:120px; text-align: center;"}).appendTo(row);
|
|
251
|
-
var group0 = $('<optgroup/>', { label: "value
|
|
253
|
+
var group0 = $('<optgroup/>', { label: RED._("node-red:switch.label.value-rules") }).appendTo(selectField);
|
|
252
254
|
for (var d in operators) {
|
|
253
255
|
if(operators[d].kind === 'V') {
|
|
254
256
|
group0.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t));
|
|
255
257
|
}
|
|
256
258
|
}
|
|
257
|
-
var group1 = $('<optgroup/>', { label: "sequence
|
|
259
|
+
var group1 = $('<optgroup/>', { label: RED._("node-red:switch.label.sequence-rules") }).appendTo(selectField);
|
|
258
260
|
for (var d in operators) {
|
|
259
261
|
if(operators[d].kind === 'S') {
|
|
260
262
|
group1.append($("<option></option>").val(operators[d].v).text(/^switch/.test(operators[d].t)?node._(operators[d].t):operators[d].t));
|
|
@@ -340,9 +342,12 @@
|
|
|
340
342
|
row3.hide();
|
|
341
343
|
}
|
|
342
344
|
var selectedLabel = selectField.find("option:selected").text();
|
|
343
|
-
|
|
345
|
+
|
|
346
|
+
textSpan.text(selectedLabel);
|
|
347
|
+
var width = textSpan.width();
|
|
348
|
+
if (width <= 30) {
|
|
344
349
|
selectField.outerWidth(60);
|
|
345
|
-
} else if (
|
|
350
|
+
} else if (width <= 85) {
|
|
346
351
|
selectField.outerWidth(120);
|
|
347
352
|
} else {
|
|
348
353
|
selectField.width("auto")
|
|
@@ -44,6 +44,14 @@ module.exports = function(RED) {
|
|
|
44
44
|
return undefined;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function parseEnv(key) {
|
|
48
|
+
var match = /^env\.(.+)/.exec(key);
|
|
49
|
+
if (match) {
|
|
50
|
+
return match[1];
|
|
51
|
+
}
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
/**
|
|
48
56
|
* Custom Mustache Context capable to collect message property and node
|
|
49
57
|
* flow and global context
|
|
@@ -74,6 +82,11 @@ module.exports = function(RED) {
|
|
|
74
82
|
return value;
|
|
75
83
|
}
|
|
76
84
|
|
|
85
|
+
// try env
|
|
86
|
+
if (parseEnv(name)) {
|
|
87
|
+
return this.cachedContextTokens[name];
|
|
88
|
+
}
|
|
89
|
+
|
|
77
90
|
// try flow/global context:
|
|
78
91
|
var context = parseContext(name);
|
|
79
92
|
if (context) {
|
|
@@ -156,6 +169,17 @@ module.exports = function(RED) {
|
|
|
156
169
|
var tokens = extractTokens(mustache.parse(template));
|
|
157
170
|
var resolvedTokens = {};
|
|
158
171
|
tokens.forEach(function(name) {
|
|
172
|
+
var env_name = parseEnv(name);
|
|
173
|
+
if (env_name) {
|
|
174
|
+
var promise = new Promise((resolve, reject) => {
|
|
175
|
+
var val = RED.util.evaluateNodeProperty(env_name, 'env', node)
|
|
176
|
+
resolvedTokens[name] = val;
|
|
177
|
+
resolve();
|
|
178
|
+
});
|
|
179
|
+
promises.push(promise);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
|
|
159
183
|
var context = parseContext(name);
|
|
160
184
|
if (context) {
|
|
161
185
|
var type = context.type;
|
|
@@ -275,18 +275,22 @@ module.exports = function(RED) {
|
|
|
275
275
|
if (msg.hasOwnProperty("flush")) {
|
|
276
276
|
var len = node.buffer.length;
|
|
277
277
|
if (typeof(msg.flush) == 'number') { len = Math.min(Math.floor(msg.flush),len); }
|
|
278
|
-
|
|
279
|
-
const msgInfo = node.buffer.shift();
|
|
280
|
-
if (Object.keys(msgInfo.msg).length > 1) {
|
|
281
|
-
node.send(msgInfo.msg);
|
|
282
|
-
msgInfo.done();
|
|
283
|
-
}
|
|
284
|
-
len = len - 1;
|
|
285
|
-
}
|
|
286
|
-
if (node.buffer.length === 0) {
|
|
278
|
+
if (len === 0) {
|
|
287
279
|
clearInterval(node.intervalID);
|
|
288
280
|
node.intervalID = -1;
|
|
289
281
|
}
|
|
282
|
+
else {
|
|
283
|
+
while (len > 0) {
|
|
284
|
+
const msgInfo = node.buffer.shift();
|
|
285
|
+
if (Object.keys(msgInfo.msg).length > 1) {
|
|
286
|
+
node.send(msgInfo.msg);
|
|
287
|
+
msgInfo.done();
|
|
288
|
+
}
|
|
289
|
+
len = len - 1;
|
|
290
|
+
}
|
|
291
|
+
clearInterval(node.intervalID);
|
|
292
|
+
node.intervalID = setInterval(sendMsgFromBuffer, node.rate);
|
|
293
|
+
}
|
|
290
294
|
node.status({fill:"blue",shape:"dot",text:node.buffer.length});
|
|
291
295
|
done();
|
|
292
296
|
}
|
package/core/network/10-mqtt.js
CHANGED
|
@@ -453,6 +453,7 @@ module.exports = function(RED) {
|
|
|
453
453
|
node.options = {};
|
|
454
454
|
node.queue = [];
|
|
455
455
|
node.subscriptions = {};
|
|
456
|
+
node.clientListeners = []
|
|
456
457
|
/** @type {mqtt.MqttClient}*/ this.client;
|
|
457
458
|
node.setOptions = function(opts, init) {
|
|
458
459
|
if(!opts || typeof opts !== "object") {
|
|
@@ -591,7 +592,7 @@ module.exports = function(RED) {
|
|
|
591
592
|
// Only for ws or wss, check if proxy env var for additional configuration
|
|
592
593
|
if (node.brokerurl.indexOf("wss://") > -1 || node.brokerurl.indexOf("ws://") > -1) {
|
|
593
594
|
// check if proxy is set in env
|
|
594
|
-
let prox, noprox;
|
|
595
|
+
let prox, noprox, noproxy;
|
|
595
596
|
if (process.env.http_proxy) { prox = process.env.http_proxy; }
|
|
596
597
|
if (process.env.HTTP_PROXY) { prox = process.env.HTTP_PROXY; }
|
|
597
598
|
if (process.env.no_proxy) { noprox = process.env.no_proxy.split(","); }
|
|
@@ -718,11 +719,16 @@ module.exports = function(RED) {
|
|
|
718
719
|
setStatusConnecting(node, true);
|
|
719
720
|
try {
|
|
720
721
|
node.serverProperties = {};
|
|
722
|
+
if(node.client) {
|
|
723
|
+
//belt and braces to avoid left over clients
|
|
724
|
+
node.client.end(true);
|
|
725
|
+
node._clientRemoveListeners();
|
|
726
|
+
}
|
|
721
727
|
node.client = mqtt.connect(node.brokerurl, node.options);
|
|
722
728
|
node.client.setMaxListeners(0);
|
|
723
|
-
let callbackDone = false; //prevent re-connects causing node.
|
|
729
|
+
let callbackDone = false; //prevent re-connects causing node._clientOn('connect' firing callback multiple times
|
|
724
730
|
// Register successful connect or reconnect handler
|
|
725
|
-
node.
|
|
731
|
+
node._clientOn('connect', function (connack) {
|
|
726
732
|
node.closing = false;
|
|
727
733
|
node.connecting = false;
|
|
728
734
|
node.connected = true;
|
|
@@ -754,7 +760,7 @@ module.exports = function(RED) {
|
|
|
754
760
|
}
|
|
755
761
|
setStatusConnected(node, true);
|
|
756
762
|
// Remove any existing listeners before resubscribing to avoid duplicates in the event of a re-connection
|
|
757
|
-
node.
|
|
763
|
+
node._clientRemoveListeners('message');
|
|
758
764
|
|
|
759
765
|
// Re-subscribe to stored topics
|
|
760
766
|
for (var s in node.subscriptions) {
|
|
@@ -766,7 +772,7 @@ module.exports = function(RED) {
|
|
|
766
772
|
if (node.subscriptions[s].hasOwnProperty(r)) {
|
|
767
773
|
qos = Math.max(qos,node.subscriptions[s][r].qos);
|
|
768
774
|
_options = node.subscriptions[s][r].options;
|
|
769
|
-
node.
|
|
775
|
+
node._clientOn('message',node.subscriptions[s][r].handler);
|
|
770
776
|
}
|
|
771
777
|
}
|
|
772
778
|
_options.qos = _options.qos || qos;
|
|
@@ -779,11 +785,11 @@ module.exports = function(RED) {
|
|
|
779
785
|
node.publish(node.birthMessage);
|
|
780
786
|
}
|
|
781
787
|
});
|
|
782
|
-
node.
|
|
788
|
+
node._clientOn("reconnect", function() {
|
|
783
789
|
setStatusConnecting(node, true);
|
|
784
790
|
});
|
|
785
791
|
//Broker Disconnect - V5 event
|
|
786
|
-
node.
|
|
792
|
+
node._clientOn("disconnect", function(packet) {
|
|
787
793
|
//Emitted after receiving disconnect packet from broker. MQTT 5.0 feature.
|
|
788
794
|
const rc = (packet && packet.properties && packet.reasonCode) || packet.reasonCode;
|
|
789
795
|
const rs = packet && packet.properties && packet.properties.reasonString || "";
|
|
@@ -797,7 +803,7 @@ module.exports = function(RED) {
|
|
|
797
803
|
setStatusDisconnected(node, true);
|
|
798
804
|
});
|
|
799
805
|
// Register disconnect handlers
|
|
800
|
-
node.
|
|
806
|
+
node._clientOn('close', function () {
|
|
801
807
|
if (node.connected) {
|
|
802
808
|
node.connected = false;
|
|
803
809
|
node.log(RED._("mqtt.state.disconnected",{broker:(node.clientid?node.clientid+"@":"")+node.brokerurl}));
|
|
@@ -809,7 +815,7 @@ module.exports = function(RED) {
|
|
|
809
815
|
|
|
810
816
|
// Register connect error handler
|
|
811
817
|
// The client's own reconnect logic will take care of errors
|
|
812
|
-
node.
|
|
818
|
+
node._clientOn('error', function (error) {
|
|
813
819
|
});
|
|
814
820
|
}catch(err) {
|
|
815
821
|
console.log(err);
|
|
@@ -822,7 +828,7 @@ module.exports = function(RED) {
|
|
|
822
828
|
if(node.connected || node.connecting) {
|
|
823
829
|
setStatusDisconnected(node, true);
|
|
824
830
|
}
|
|
825
|
-
if(node.client) { node.
|
|
831
|
+
if(node.client) { node._clientRemoveListeners(); }
|
|
826
832
|
node.connecting = false;
|
|
827
833
|
node.connected = false;
|
|
828
834
|
callback && typeof callback == "function" && callback();
|
|
@@ -836,8 +842,12 @@ module.exports = function(RED) {
|
|
|
836
842
|
if(!client) {
|
|
837
843
|
resolve();
|
|
838
844
|
} else {
|
|
839
|
-
|
|
840
|
-
|
|
845
|
+
const t = setTimeout(() => {
|
|
846
|
+
//clean end() has exceeded WAIT_END, lets force end!
|
|
847
|
+
client && client.end(true);
|
|
848
|
+
reject();
|
|
849
|
+
}, ms);
|
|
850
|
+
client.end(() => {
|
|
841
851
|
clearTimeout(t);
|
|
842
852
|
resolve()
|
|
843
853
|
});
|
|
@@ -894,7 +904,7 @@ module.exports = function(RED) {
|
|
|
894
904
|
};
|
|
895
905
|
node.subscriptions[topic][ref] = sub;
|
|
896
906
|
if (node.connected) {
|
|
897
|
-
node.
|
|
907
|
+
node._clientOn('message',sub.handler);
|
|
898
908
|
node.client.subscribe(topic, options);
|
|
899
909
|
}
|
|
900
910
|
};
|
|
@@ -905,7 +915,7 @@ module.exports = function(RED) {
|
|
|
905
915
|
if (sub) {
|
|
906
916
|
if (sub[ref]) {
|
|
907
917
|
if(node.client) {
|
|
908
|
-
node.
|
|
918
|
+
node._clientRemoveListeners('message',sub[ref].handler);
|
|
909
919
|
}
|
|
910
920
|
delete sub[ref];
|
|
911
921
|
}
|
|
@@ -995,13 +1005,40 @@ module.exports = function(RED) {
|
|
|
995
1005
|
|
|
996
1006
|
node.on('close', function(done) {
|
|
997
1007
|
node.disconnect(function() {
|
|
998
|
-
if(node.client) {
|
|
999
|
-
node.client.removeAllListeners();
|
|
1000
|
-
}
|
|
1001
1008
|
done();
|
|
1002
1009
|
});
|
|
1003
1010
|
});
|
|
1004
1011
|
|
|
1012
|
+
/**
|
|
1013
|
+
* Add event handlers to the MQTT.js client and track them so that
|
|
1014
|
+
* we do not remove any handlers that the MQTT client uses internally.
|
|
1015
|
+
* Use {@link node._clientRemoveListeners `node._clientRemoveListeners`} to remove handlers
|
|
1016
|
+
* @param {string} event The name of the event
|
|
1017
|
+
* @param {function} handler The handler for this event
|
|
1018
|
+
*/
|
|
1019
|
+
node._clientOn = function(event, handler) {
|
|
1020
|
+
node.clientListeners.push({event, handler})
|
|
1021
|
+
node.client.on(event, handler)
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
/**
|
|
1025
|
+
* Remove event handlers from the MQTT.js client & only the events
|
|
1026
|
+
* that we attached in {@link node._clientOn `node._clientOn`}.
|
|
1027
|
+
* * If `event` is omitted, then all events matching `handler` are removed
|
|
1028
|
+
* * If `handler` is omitted, then all events named `event` are removed
|
|
1029
|
+
* * If both parameters are omitted, then all events are removed
|
|
1030
|
+
* @param {string} [event] The name of the event (optional)
|
|
1031
|
+
* @param {function} [handler] The handler for this event (optional)
|
|
1032
|
+
*/
|
|
1033
|
+
node._clientRemoveListeners = function(event, handler) {
|
|
1034
|
+
node.clientListeners = node.clientListeners.filter((l) => {
|
|
1035
|
+
if (event && event !== l.event) { return true; }
|
|
1036
|
+
if (handler && handler !== l.handler) { return true; }
|
|
1037
|
+
node.client.removeListener(l.event, l.handler)
|
|
1038
|
+
return false; //found and removed, filter out this one
|
|
1039
|
+
})
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1005
1042
|
}
|
|
1006
1043
|
|
|
1007
1044
|
RED.nodes.registerType("mqtt-broker",MQTTBrokerNode,{
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
var headerTypes = [
|
|
130
130
|
{value:"content-type",label:"Content-Type",hasValue: false},
|
|
131
131
|
{value:"location",label:"Location",hasValue: false},
|
|
132
|
-
{value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.
|
|
132
|
+
{value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.svg"}
|
|
133
133
|
]
|
|
134
134
|
var contentTypes = [
|
|
135
135
|
{value:"application/json",label:"application/json",hasValue: false},
|
|
@@ -139,7 +139,7 @@
|
|
|
139
139
|
{value:"text/plain",label:"text/plain",hasValue: false},
|
|
140
140
|
{value:"image/gif",label:"image/gif",hasValue: false},
|
|
141
141
|
{value:"image/png",label:"image/png",hasValue: false},
|
|
142
|
-
{value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.
|
|
142
|
+
{value:"other",label:RED._("node-red:httpin.label.other"),icon:"red/images/typedInput/az.svg"}
|
|
143
143
|
];
|
|
144
144
|
|
|
145
145
|
RED.nodes.registerType('http response',{
|
|
@@ -180,7 +180,7 @@
|
|
|
180
180
|
var propertyValue = $('<input/>',{class:"node-input-header-value",type:"text",style:"width: 100%"})
|
|
181
181
|
.appendTo(propertyValueCell)
|
|
182
182
|
.typedInput({types:
|
|
183
|
-
header.h === 'content-type'?contentTypes:[{value:"other",label:"other",icon:"red/images/typedInput/az.
|
|
183
|
+
header.h === 'content-type'?contentTypes:[{value:"other",label:"other",icon:"red/images/typedInput/az.svg"}]
|
|
184
184
|
});
|
|
185
185
|
|
|
186
186
|
var matchedType = headerTypes.filter(function(ht) {
|
|
@@ -223,7 +223,7 @@
|
|
|
223
223
|
if (type === 'content-type') {
|
|
224
224
|
propertyValue.typedInput('types',contentTypes);
|
|
225
225
|
} else {
|
|
226
|
-
propertyValue.typedInput('types',[{value:"other",label:"other",icon:"red/images/typedInput/az.
|
|
226
|
+
propertyValue.typedInput('types',[{value:"other",label:"other",icon:"red/images/typedInput/az.svg"}]);
|
|
227
227
|
}
|
|
228
228
|
});
|
|
229
229
|
},
|
|
@@ -127,12 +127,14 @@
|
|
|
127
127
|
{ value: "Cache-Control", label: "Cache-Control", hasValue: false },
|
|
128
128
|
{ value: "User-Agent", label: "User-Agent", hasValue: false },
|
|
129
129
|
{ value: "Location", label: "Location", hasValue: false },
|
|
130
|
-
{ value: "other", label: "
|
|
130
|
+
{ value: "other", label: RED._("node-red:httpin.label.other"),
|
|
131
|
+
hasValue: true, icon: "red/images/typedInput/az.svg" },
|
|
131
132
|
{ value: "msg", label: "msg.", hasValue: true },
|
|
132
133
|
]
|
|
133
134
|
const headerOptions = {};
|
|
134
135
|
const defaultOptions = [
|
|
135
|
-
{ value: "other", label: "
|
|
136
|
+
{ value: "other", label: RED._("node-red:httpin.label.other"),
|
|
137
|
+
hasValue: true, icon: "red/images/typedInput/az.svg" },
|
|
136
138
|
{ value: "msg", label: "msg.", hasValue: true },
|
|
137
139
|
];
|
|
138
140
|
headerOptions["accept"] = [
|
package/core/network/31-tcpin.js
CHANGED
|
@@ -435,7 +435,7 @@ module.exports = function(RED) {
|
|
|
435
435
|
});
|
|
436
436
|
}
|
|
437
437
|
else {
|
|
438
|
-
|
|
438
|
+
const connectedSockets = new Set();
|
|
439
439
|
node.status({text:RED._("tcpin.status.connections",{count:0})});
|
|
440
440
|
let srv = net;
|
|
441
441
|
let connOpts;
|
|
@@ -456,16 +456,16 @@ module.exports = function(RED) {
|
|
|
456
456
|
});
|
|
457
457
|
socket.on('close',function() {
|
|
458
458
|
node.log(RED._("tcpin.status.connection-closed",{host:socket.remoteAddress, port:socket.remotePort}));
|
|
459
|
-
connectedSockets.
|
|
460
|
-
node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.
|
|
459
|
+
connectedSockets.delete(socket);
|
|
460
|
+
node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.size})});
|
|
461
461
|
});
|
|
462
462
|
socket.on('error',function() {
|
|
463
463
|
node.log(RED._("tcpin.errors.socket-error",{host:socket.remoteAddress, port:socket.remotePort}));
|
|
464
|
-
connectedSockets.
|
|
465
|
-
node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.
|
|
464
|
+
connectedSockets.delete(socket);
|
|
465
|
+
node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.size})});
|
|
466
466
|
});
|
|
467
|
-
connectedSockets.
|
|
468
|
-
node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.
|
|
467
|
+
connectedSockets.add(socket);
|
|
468
|
+
node.status({text:RED._("tcpin.status.connections",{count:connectedSockets.size})});
|
|
469
469
|
});
|
|
470
470
|
|
|
471
471
|
node.on("input", function(msg, nodeSend, nodeDone) {
|
|
@@ -478,10 +478,10 @@ module.exports = function(RED) {
|
|
|
478
478
|
} else {
|
|
479
479
|
buffer = Buffer.from(""+msg.payload);
|
|
480
480
|
}
|
|
481
|
-
|
|
482
|
-
if (node.doend === true) {
|
|
483
|
-
else {
|
|
484
|
-
}
|
|
481
|
+
connectedSockets.forEach(soc => {
|
|
482
|
+
if (node.doend === true) { soc.end(buffer); }
|
|
483
|
+
else { soc.write(buffer); }
|
|
484
|
+
})
|
|
485
485
|
}
|
|
486
486
|
nodeDone();
|
|
487
487
|
});
|
|
@@ -498,12 +498,10 @@ module.exports = function(RED) {
|
|
|
498
498
|
} else {
|
|
499
499
|
node.log(RED._("tcpin.status.listening-port",{port:node.port}));
|
|
500
500
|
node.on('close', function() {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
}
|
|
506
|
-
}
|
|
501
|
+
connectedSockets.forEach(soc => {
|
|
502
|
+
soc.end();
|
|
503
|
+
soc.unref();
|
|
504
|
+
})
|
|
507
505
|
server.close();
|
|
508
506
|
node.log(RED._("tcpin.status.stopped-listening",{port:node.port}));
|
|
509
507
|
});
|
package/core/parsers/70-CSV.js
CHANGED
|
@@ -89,6 +89,9 @@ module.exports = function(RED) {
|
|
|
89
89
|
else if (msg.payload[s][t].toString().indexOf(node.sep) !== -1) { // add quotes if any "commas"
|
|
90
90
|
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
|
91
91
|
}
|
|
92
|
+
else if (msg.payload[s][t].toString().indexOf("\n") !== -1) { // add quotes if any "\n"
|
|
93
|
+
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
|
94
|
+
}
|
|
92
95
|
}
|
|
93
96
|
ou += msg.payload[s].join(node.sep) + node.ret;
|
|
94
97
|
}
|
|
@@ -112,7 +115,7 @@ module.exports = function(RED) {
|
|
|
112
115
|
q = q.replace(/"/g, '""');
|
|
113
116
|
ou += node.quo + q + node.quo + node.sep;
|
|
114
117
|
}
|
|
115
|
-
else if (q.indexOf(node.sep) !== -1) { // add quotes if any "commas"
|
|
118
|
+
else if (q.indexOf(node.sep) !== -1 || p.indexOf("\n") !== -1) { // add quotes if any "commas" or "\n"
|
|
116
119
|
ou += node.quo + q + node.quo + node.sep;
|
|
117
120
|
}
|
|
118
121
|
else { ou += q + node.sep; } // otherwise just add
|
|
@@ -134,7 +137,7 @@ module.exports = function(RED) {
|
|
|
134
137
|
p = p.replace(/"/g, '""');
|
|
135
138
|
ou += node.quo + p + node.quo + node.sep;
|
|
136
139
|
}
|
|
137
|
-
else if (p.indexOf(node.sep) !== -1) { // add quotes if any "commas"
|
|
140
|
+
else if (p.indexOf(node.sep) !== -1 || p.indexOf("\n") !== -1) { // add quotes if any "commas" or "\n"
|
|
138
141
|
ou += node.quo + p + node.quo + node.sep;
|
|
139
142
|
}
|
|
140
143
|
else { ou += p + node.sep; } // otherwise just add
|
|
@@ -314,11 +314,13 @@ module.exports = function(RED) {
|
|
|
314
314
|
if (err) {
|
|
315
315
|
return done(err);
|
|
316
316
|
}
|
|
317
|
-
msgInfo.
|
|
317
|
+
msgInfo.msg.payload = result;
|
|
318
|
+
msgInfo.send(msgInfo.msg);
|
|
318
319
|
done();
|
|
319
320
|
});
|
|
320
321
|
} else {
|
|
321
|
-
msgInfo.
|
|
322
|
+
msgInfo.msg.payload = result;
|
|
323
|
+
msgInfo.send(msgInfo.msg);
|
|
322
324
|
done();
|
|
323
325
|
}
|
|
324
326
|
} else {
|