@node-red/nodes 4.0.9 → 4.1.0-beta.2
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/core/common/20-inject.html +19 -19
- package/core/common/24-complete.js +10 -1
- package/core/common/25-status.js +10 -1
- package/core/common/91-global-config.html +2 -1
- package/core/common/98-unknown.html +26 -4
- package/core/common/lib/debug/debug-utils.js +16 -4
- package/core/function/10-function.html +1 -9
- package/core/function/10-function.js +11 -1
- package/core/function/10-switch.html +3 -3
- package/core/function/16-range.html +9 -9
- package/core/function/89-trigger.html +3 -3
- package/core/function/90-exec.js +3 -2
- package/core/function/rbe.html +2 -2
- package/core/network/10-mqtt.html +12 -0
- package/core/network/10-mqtt.js +1 -1
- package/core/network/21-httpin.html +27 -9
- package/core/network/21-httpin.js +82 -9
- package/core/network/21-httprequest.html +1 -1
- package/core/network/21-httprequest.js +24 -2
- package/core/network/31-tcpin.html +2 -2
- package/core/parsers/70-CSV.html +6 -6
- package/core/parsers/70-HTML.html +1 -1
- package/core/parsers/70-JSON.html +2 -2
- package/core/parsers/70-XML.html +2 -2
- package/core/parsers/70-YAML.html +1 -1
- package/core/sequence/17-split.html +2 -2
- package/core/sequence/17-split.js +4 -3
- package/locales/de/network/21-httprequest.html +1 -1
- package/locales/en-US/messages.json +6 -3
- package/locales/en-US/network/21-httpin.html +1 -0
- package/locales/fr/messages.json +2 -1
- package/locales/ja/messages.json +1 -0
- package/locales/ja/network/10-mqtt.html +2 -2
- package/package.json +7 -7
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
|
|
47
47
|
<div class="form-row inject-time-row hidden" id="inject-time-row-interval">
|
|
48
48
|
<span data-i18n="inject.every"></span>
|
|
49
|
-
<input id="inject-time-interval-count" class="inject-time-count" value="1"
|
|
49
|
+
<input id="inject-time-interval-count" class="inject-time-count" value="1">
|
|
50
50
|
<select style="width:100px" id="inject-time-interval-units">
|
|
51
51
|
<option value="s" data-i18n="inject.seconds"></option>
|
|
52
52
|
<option value="m" data-i18n="inject.minutes"></option>
|
|
53
53
|
<option value="h" data-i18n="inject.hours"></option>
|
|
54
|
-
</select><br
|
|
54
|
+
</select><br>
|
|
55
55
|
</div>
|
|
56
56
|
|
|
57
57
|
<div class="form-row inject-time-row hidden" id="inject-time-row-interval-time">
|
|
@@ -68,46 +68,46 @@
|
|
|
68
68
|
<option value="20">20</option>
|
|
69
69
|
<option value="30">30</option>
|
|
70
70
|
<option value="0">60</option>
|
|
71
|
-
</select> <span data-i18n="inject.minutes"></span><br
|
|
71
|
+
</select> <span data-i18n="inject.minutes"></span><br>
|
|
72
72
|
<span data-i18n="inject.between"></span> <select id="inject-time-interval-time-start" class="inject-time-times"></select>
|
|
73
|
-
<span data-i18n="inject.and"></span> <select id="inject-time-interval-time-end" class="inject-time-times"></select><br
|
|
73
|
+
<span data-i18n="inject.and"></span> <select id="inject-time-interval-time-end" class="inject-time-times"></select><br>
|
|
74
74
|
<div id="inject-time-interval-time-days" class="inject-time-days" style="margin-top:5px">
|
|
75
75
|
<div style="display:inline-block; vertical-align:top; margin-right:5px;" data-i18n="inject.on">on</div>
|
|
76
76
|
<div style="display:inline-block;">
|
|
77
77
|
<div>
|
|
78
|
-
<label><input type='checkbox' checked value='1'
|
|
79
|
-
<label><input type='checkbox' checked value='2'
|
|
80
|
-
<label><input type='checkbox' checked value='3'
|
|
78
|
+
<label><input type='checkbox' checked value='1'> <span data-i18n="inject.days.0"></span></label>
|
|
79
|
+
<label><input type='checkbox' checked value='2'> <span data-i18n="inject.days.1"></span></label>
|
|
80
|
+
<label><input type='checkbox' checked value='3'> <span data-i18n="inject.days.2"></span></label>
|
|
81
81
|
</div>
|
|
82
82
|
<div>
|
|
83
|
-
<label><input type='checkbox' checked value='4'
|
|
84
|
-
<label><input type='checkbox' checked value='5'
|
|
85
|
-
<label><input type='checkbox' checked value='6'
|
|
83
|
+
<label><input type='checkbox' checked value='4'> <span data-i18n="inject.days.3"></span></label>
|
|
84
|
+
<label><input type='checkbox' checked value='5'> <span data-i18n="inject.days.4"></span></label>
|
|
85
|
+
<label><input type='checkbox' checked value='6'> <span data-i18n="inject.days.5"></span></label>
|
|
86
86
|
</div>
|
|
87
87
|
<div>
|
|
88
|
-
<label><input type='checkbox' checked value='0'
|
|
88
|
+
<label><input type='checkbox' checked value='0'> <span data-i18n="inject.days.6"></span></label>
|
|
89
89
|
</div>
|
|
90
90
|
</div>
|
|
91
91
|
</div>
|
|
92
92
|
</div>
|
|
93
93
|
|
|
94
94
|
<div class="form-row inject-time-row hidden" id="inject-time-row-time">
|
|
95
|
-
<span data-i18n="inject.at"></span> <input type="text" id="inject-time-time" value="12:00"
|
|
95
|
+
<span data-i18n="inject.at"></span> <input type="text" id="inject-time-time" value="12:00"><br>
|
|
96
96
|
<div id="inject-time-time-days" class="inject-time-days">
|
|
97
97
|
<div style="display:inline-block; vertical-align:top; margin-right:5px;" data-i18n="inject.on"></div>
|
|
98
98
|
<div style="display:inline-block;">
|
|
99
99
|
<div>
|
|
100
|
-
<label><input type='checkbox' checked value='1'
|
|
101
|
-
<label><input type='checkbox' checked value='2'
|
|
102
|
-
<label><input type='checkbox' checked value='3'
|
|
100
|
+
<label><input type='checkbox' checked value='1'> <span data-i18n="inject.days.0"></span></label>
|
|
101
|
+
<label><input type='checkbox' checked value='2'> <span data-i18n="inject.days.1"></span></label>
|
|
102
|
+
<label><input type='checkbox' checked value='3'> <span data-i18n="inject.days.2"></span></label>
|
|
103
103
|
</div>
|
|
104
104
|
<div>
|
|
105
|
-
<label><input type='checkbox' checked value='4'
|
|
106
|
-
<label><input type='checkbox' checked value='5'
|
|
107
|
-
<label><input type='checkbox' checked value='6'
|
|
105
|
+
<label><input type='checkbox' checked value='4'> <span data-i18n="inject.days.3"></span></label>
|
|
106
|
+
<label><input type='checkbox' checked value='5'> <span data-i18n="inject.days.4"></span></label>
|
|
107
|
+
<label><input type='checkbox' checked value='6'> <span data-i18n="inject.days.5"></span></label>
|
|
108
108
|
</div>
|
|
109
109
|
<div>
|
|
110
|
-
<label><input type='checkbox' checked value='0'
|
|
110
|
+
<label><input type='checkbox' checked value='0'> <span data-i18n="inject.days.6"></span></label>
|
|
111
111
|
</div>
|
|
112
112
|
</div>
|
|
113
113
|
</div>
|
|
@@ -20,7 +20,16 @@ module.exports = function(RED) {
|
|
|
20
20
|
function CompleteNode(n) {
|
|
21
21
|
RED.nodes.createNode(this,n);
|
|
22
22
|
var node = this;
|
|
23
|
-
this.scope = n.scope;
|
|
23
|
+
this.scope = n.scope || [];
|
|
24
|
+
|
|
25
|
+
// auto-filter out any directly connected nodes to avoid simple loopback
|
|
26
|
+
const w = this.wires.flat();
|
|
27
|
+
for (let i=0; i < this.scope.length; i++) {
|
|
28
|
+
if (w.includes(this.scope[i])) {
|
|
29
|
+
this.scope.splice(i, 1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
this.on("input",function(msg, send, done) {
|
|
25
34
|
send(msg);
|
|
26
35
|
done();
|
package/core/common/25-status.js
CHANGED
|
@@ -20,7 +20,16 @@ module.exports = function(RED) {
|
|
|
20
20
|
function StatusNode(n) {
|
|
21
21
|
RED.nodes.createNode(this,n);
|
|
22
22
|
var node = this;
|
|
23
|
-
this.scope = n.scope;
|
|
23
|
+
this.scope = n.scope || [];
|
|
24
|
+
|
|
25
|
+
// auto-filter out any directly connected nodes to avoid simple loopback
|
|
26
|
+
const w = this.wires.flat();
|
|
27
|
+
for (let i=0; i < this.scope.length; i++) {
|
|
28
|
+
if (w.includes(this.scope[i])) {
|
|
29
|
+
this.scope.splice(i, 1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
24
33
|
this.on("input", function(msg, send, done) {
|
|
25
34
|
send(msg);
|
|
26
35
|
done();
|
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
RED.nodes.registerType('global-config',{
|
|
12
12
|
category: 'config',
|
|
13
13
|
defaults: {
|
|
14
|
-
name: { value: "" },
|
|
15
14
|
env: { value: [] },
|
|
15
|
+
modules: { value: {} }
|
|
16
16
|
},
|
|
17
17
|
credentials: {
|
|
18
18
|
map: { type: "map" }
|
|
19
19
|
},
|
|
20
|
+
label: 'global-config',
|
|
20
21
|
oneditprepare: function() {
|
|
21
22
|
$('#node-input-edit-env-var').on('click', function(evt) {
|
|
22
23
|
RED.actions.invoke('core:show-user-settings', 'envvar')
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
|
|
2
2
|
<script type="text/html" data-template-name="unknown">
|
|
3
|
-
<div class="form-tips"
|
|
3
|
+
<div class="form-tips">
|
|
4
|
+
<span data-i18n="[html]unknown.tip"></span>
|
|
5
|
+
<p id="unknown-module-known">
|
|
6
|
+
<button id="unknown-manage-dependencies" class="red-ui-button"><span data-i18n="unknown.manageModules"></span></button>
|
|
7
|
+
</p>
|
|
8
|
+
</div>
|
|
9
|
+
</div>
|
|
10
|
+
|
|
4
11
|
</script>
|
|
5
12
|
|
|
6
13
|
<script type="text/javascript">
|
|
7
|
-
RED.nodes.registerType('unknown',{
|
|
14
|
+
RED.nodes.registerType('unknown', {
|
|
8
15
|
category: 'unknown',
|
|
9
|
-
color:"#
|
|
16
|
+
color:"#fff000",
|
|
10
17
|
defaults: {
|
|
11
|
-
name: {value:""}
|
|
18
|
+
name: {value:""},
|
|
19
|
+
modules: { value: [] }
|
|
12
20
|
},
|
|
13
21
|
inputs:1,
|
|
14
22
|
outputs:1,
|
|
@@ -18,6 +26,20 @@
|
|
|
18
26
|
},
|
|
19
27
|
labelStyle: function() {
|
|
20
28
|
return "node_label_unknown";
|
|
29
|
+
},
|
|
30
|
+
oneditprepare: function () {
|
|
31
|
+
const node = this
|
|
32
|
+
if (this.modules && this.modules.length > 0) {
|
|
33
|
+
$('#unknown-manage-dependencies').on('click', function () {
|
|
34
|
+
RED.actions.invoke('core:cancel-edit-tray')
|
|
35
|
+
RED.actions.invoke('core:manage-palette', {
|
|
36
|
+
view: 'install',
|
|
37
|
+
filter: '"' + node.modules.join('", "') + '"'
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
} else {
|
|
41
|
+
$('#unknown-module-known').hide()
|
|
42
|
+
}
|
|
21
43
|
}
|
|
22
44
|
});
|
|
23
45
|
</script>
|
|
@@ -536,10 +536,22 @@ RED.debug = (function() {
|
|
|
536
536
|
e.stopPropagation();
|
|
537
537
|
showMessageMenu(filterMessage,debugMessage,sourceNode&&sourceNode.id);
|
|
538
538
|
});
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
539
|
+
const msgInfos = `${o.topic ? " : " : ""}msg${o.property ? "." + property : ""} : ${format}`
|
|
540
|
+
const topicTruncated = RED.utils.truncateString((o.topic ? topic : ""), 120 - msgInfos.length);
|
|
541
|
+
const topicElem = $('<span class="red-ui-debug-msg-topic">' + topicTruncated + msgInfos + '</span>').appendTo(metaRow);
|
|
542
|
+
if (topic !== topicTruncated) {
|
|
543
|
+
RED.popover.create({
|
|
544
|
+
content: topic,
|
|
545
|
+
delay: { show: 750, hide: 50 },
|
|
546
|
+
direction: "bottom",
|
|
547
|
+
interactive: true,
|
|
548
|
+
maxWidth: 300,
|
|
549
|
+
target: topicElem,
|
|
550
|
+
trigger: "hover",
|
|
551
|
+
tooltip: true,
|
|
552
|
+
size: "small"
|
|
553
|
+
});
|
|
554
|
+
}
|
|
543
555
|
}
|
|
544
556
|
|
|
545
557
|
var atBottom = (sbc.scrollHeight-messageList.height()-sbc.scrollTop) < 5;
|
|
@@ -197,14 +197,6 @@
|
|
|
197
197
|
// object that maps from library name to its descriptor
|
|
198
198
|
var allLibs = [];
|
|
199
199
|
|
|
200
|
-
function moduleName(module) {
|
|
201
|
-
var match = /^([^@]+)@(.+)/.exec(module);
|
|
202
|
-
if (match) {
|
|
203
|
-
return [match[1], match[2]];
|
|
204
|
-
}
|
|
205
|
-
return [module, undefined];
|
|
206
|
-
}
|
|
207
|
-
|
|
208
200
|
function getAllUsedModules() {
|
|
209
201
|
var moduleSet = new Set();
|
|
210
202
|
for (var id in knownFunctionNodes) {
|
|
@@ -302,7 +294,7 @@
|
|
|
302
294
|
if (val === "_custom_") {
|
|
303
295
|
val = $(this).val();
|
|
304
296
|
}
|
|
305
|
-
var varName = val.trim().replace(/^@/,"").replace(/@.*$/,"").replace(/[-_/\.].?/g, function(v) { return v[1]?v[1].toUpperCase():"" });
|
|
297
|
+
var varName = val.trim().replace(/^node:/,"").replace(/^@/,"").replace(/@.*$/,"").replace(/[-_/\.].?/g, function(v) { return v[1]?v[1].toUpperCase():"" });
|
|
306
298
|
fvar.val(varName);
|
|
307
299
|
fvar.trigger("change");
|
|
308
300
|
|
|
@@ -162,6 +162,8 @@ module.exports = function(RED) {
|
|
|
162
162
|
console:console,
|
|
163
163
|
util:util,
|
|
164
164
|
Buffer:Buffer,
|
|
165
|
+
URL: URL,
|
|
166
|
+
URLSearchParams: URLSearchParams,
|
|
165
167
|
Date: Date,
|
|
166
168
|
RED: {
|
|
167
169
|
util: {
|
|
@@ -403,6 +405,8 @@ module.exports = function(RED) {
|
|
|
403
405
|
if(node.timeout>0){
|
|
404
406
|
finOpt.timeout = node.timeout;
|
|
405
407
|
finOpt.breakOnSigint = true;
|
|
408
|
+
} else if (RED.settings.globalFunctionTimeout > 0){
|
|
409
|
+
finOpt.timeout = RED.settings.globalFunctionTimeout * 1000
|
|
406
410
|
}
|
|
407
411
|
}
|
|
408
412
|
var promise = Promise.resolve();
|
|
@@ -419,8 +423,14 @@ module.exports = function(RED) {
|
|
|
419
423
|
var opts = {};
|
|
420
424
|
if (node.timeout>0){
|
|
421
425
|
opts = node.timeoutOptions;
|
|
426
|
+
} else if (RED.settings. globalFunctionTimeout > 0){
|
|
427
|
+
opts.timeout = RED.settings. globalFunctionTimeout * 1000
|
|
428
|
+
}
|
|
429
|
+
try {
|
|
430
|
+
node.script.runInContext(context,opts);
|
|
431
|
+
} catch (err) {
|
|
432
|
+
return done(err);
|
|
422
433
|
}
|
|
423
|
-
node.script.runInContext(context,opts);
|
|
424
434
|
context.results.then(function(results) {
|
|
425
435
|
sendResults(node,send,msg._msgid,results,false);
|
|
426
436
|
if (handleNodeDoneCall) {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
</div>
|
|
22
22
|
<div class="form-row">
|
|
23
23
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="switch.label.property"></span></label>
|
|
24
|
-
<input type="text" id="node-input-property" style="width: calc(100% - 105px)"
|
|
25
|
-
<input type="hidden" id="node-input-outputs"
|
|
24
|
+
<input type="text" id="node-input-property" style="width: calc(100% - 105px)">
|
|
25
|
+
<input type="hidden" id="node-input-outputs">
|
|
26
26
|
</div>
|
|
27
27
|
<div class="form-row node-input-rule-container-row">
|
|
28
28
|
<ol id="node-input-rule-container"></ol>
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
</div>
|
|
36
36
|
<div class="form-row">
|
|
37
37
|
<input type="checkbox" id="node-input-repair" style="display: inline-block; width: auto; vertical-align: top;">
|
|
38
|
-
<label style="width: auto;" for="node-input-repair"><span data-i18n="switch.label.repair"></span></label
|
|
38
|
+
<label style="width: auto;" for="node-input-repair"><span data-i18n="switch.label.repair"></span></label>
|
|
39
39
|
</div>
|
|
40
40
|
</script>
|
|
41
41
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<script type="text/html" data-template-name="range">
|
|
3
3
|
<div class="form-row">
|
|
4
4
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label>
|
|
5
|
-
<input type="text" id="node-input-property" style="width:calc(70% - 1px)"
|
|
5
|
+
<input type="text" id="node-input-property" style="width:calc(70% - 1px)">
|
|
6
6
|
</div>
|
|
7
7
|
<div class="form-row">
|
|
8
8
|
<label for="node-input-action"><i class="fa fa-dot-circle-o"></i> <span data-i18n="range.label.action"></span></label>
|
|
@@ -13,23 +13,23 @@
|
|
|
13
13
|
<option value="drop" data-i18n="range.scale.drop"></option>
|
|
14
14
|
</select>
|
|
15
15
|
</div>
|
|
16
|
-
<br
|
|
16
|
+
<br>
|
|
17
17
|
<div class="form-row"><i class="fa fa-sign-in"></i> <span data-i18n="range.label.inputrange"></span>:</div>
|
|
18
18
|
<div class="form-row"><label></label>
|
|
19
|
-
<span data-i18n="range.label.from"></span>: <input type="text" id="node-input-minin" data-i18n="[placeholder]range.placeholder.min" style="width:100px;"
|
|
20
|
-
<span data-i18n="range.label.to"></span>: <input type="text" id="node-input-maxin" data-i18n="[placeholder]range.placeholder.maxin" style="width:100px;"
|
|
19
|
+
<span data-i18n="range.label.from"></span>: <input type="text" id="node-input-minin" data-i18n="[placeholder]range.placeholder.min" style="width:100px;">
|
|
20
|
+
<span data-i18n="range.label.to"></span>: <input type="text" id="node-input-maxin" data-i18n="[placeholder]range.placeholder.maxin" style="width:100px;">
|
|
21
21
|
</div>
|
|
22
22
|
<div class="form-row"><i class="fa fa-sign-out"></i> <span data-i18n="range.label.resultrange"></span>:</div>
|
|
23
23
|
<div class="form-row"><label></label>
|
|
24
|
-
<span data-i18n="range.label.from"></span>: <input type="text" id="node-input-minout" data-i18n="[placeholder]range.placeholder.min" style="width:100px;"
|
|
25
|
-
<span data-i18n="range.label.to"></span>: <input type="text" id="node-input-maxout" data-i18n="[placeholder]range.placeholder.maxout" style="width:100px;"
|
|
24
|
+
<span data-i18n="range.label.from"></span>: <input type="text" id="node-input-minout" data-i18n="[placeholder]range.placeholder.min" style="width:100px;">
|
|
25
|
+
<span data-i18n="range.label.to"></span>: <input type="text" id="node-input-maxout" data-i18n="[placeholder]range.placeholder.maxout" style="width:100px;">
|
|
26
26
|
</div>
|
|
27
|
-
<br
|
|
27
|
+
<br>
|
|
28
28
|
<div class="form-row"><label></label>
|
|
29
29
|
<input type="checkbox" id="node-input-round" style="display: inline-block; width: auto; vertical-align: top;">
|
|
30
|
-
<label style="width: auto;" for="node-input-round"><span data-i18n="range.label.roundresult"></span></label
|
|
30
|
+
<label style="width: auto;" for="node-input-round"><span data-i18n="range.label.roundresult"></span></label>
|
|
31
31
|
</div>
|
|
32
|
-
<br
|
|
32
|
+
<br>
|
|
33
33
|
<div class="form-row">
|
|
34
34
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
35
35
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
<li><span data-i18n="trigger.label.resetPayload"></span> <input type="text" id="node-input-reset" style="width:150px" data-i18n="[placeholder]trigger.label.resetprompt"></li>
|
|
64
64
|
</ul>
|
|
65
65
|
</div>
|
|
66
|
-
<br
|
|
66
|
+
<br>
|
|
67
67
|
<div class="form-row">
|
|
68
68
|
<label data-i18n="trigger.for" for="node-input-bytopic"></label>
|
|
69
69
|
<select id="node-input-bytopic" style="width:120px;">
|
|
@@ -71,12 +71,12 @@
|
|
|
71
71
|
<option value="topic" data-i18n="trigger.bytopics"></option>
|
|
72
72
|
</select>
|
|
73
73
|
<span class="form-row" id="node-stream-topic">
|
|
74
|
-
<input type="text" id="node-input-topic" style="width:46%;"
|
|
74
|
+
<input type="text" id="node-input-topic" style="width:46%;">
|
|
75
75
|
</span>
|
|
76
76
|
</div>
|
|
77
77
|
<div class="form-row">
|
|
78
78
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
79
|
-
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name"
|
|
79
|
+
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
|
80
80
|
<input type="hidden" id="node-input-outputs" value="1">
|
|
81
81
|
</div>
|
|
82
82
|
</script>
|
package/core/function/90-exec.js
CHANGED
|
@@ -109,7 +109,7 @@ module.exports = function(RED) {
|
|
|
109
109
|
child.stderr.on('data', function (data) {
|
|
110
110
|
if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) {
|
|
111
111
|
if (isUtf8(data)) { msg.payload = data.toString(); }
|
|
112
|
-
else { msg.payload =
|
|
112
|
+
else { msg.payload = data; }
|
|
113
113
|
nodeSend([null,RED.util.cloneMessage(msg),null]);
|
|
114
114
|
}
|
|
115
115
|
});
|
|
@@ -146,7 +146,8 @@ module.exports = function(RED) {
|
|
|
146
146
|
delete msg.payload;
|
|
147
147
|
if (stderr) {
|
|
148
148
|
msg2 = RED.util.cloneMessage(msg);
|
|
149
|
-
msg2.payload = stderr;
|
|
149
|
+
msg2.payload = Buffer.from(stderr,"binary");
|
|
150
|
+
if (isUtf8(msg2.payload)) { msg2.payload = msg2.payload.toString(); }
|
|
150
151
|
}
|
|
151
152
|
msg.payload = Buffer.from(stdout,"binary");
|
|
152
153
|
if (isUtf8(msg.payload)) { msg.payload = msg.payload.toString(); }
|
package/core/function/rbe.html
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
</div>
|
|
26
26
|
<div class="form-row">
|
|
27
27
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="node-red:common.label.property"></span></label>
|
|
28
|
-
<input type="text" id="node-input-property" style="width:70%;"
|
|
28
|
+
<input type="text" id="node-input-property" style="width:70%;">
|
|
29
29
|
</div>
|
|
30
30
|
<div class="form-row" style="margin-bottom: 0px;">
|
|
31
31
|
<label> </label>
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
</div>
|
|
35
35
|
<div class="form-row">
|
|
36
36
|
<label> </label>
|
|
37
|
-
<input type="text" id="node-input-topi" style="width:70%;"
|
|
37
|
+
<input type="text" id="node-input-topi" style="width:70%;">
|
|
38
38
|
</div>
|
|
39
39
|
<div class="form-row">
|
|
40
40
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="rbe.label.name"></span></label>
|
|
@@ -477,6 +477,16 @@
|
|
|
477
477
|
}
|
|
478
478
|
return RED._("node-red:mqtt.errors.invalid-topic");
|
|
479
479
|
}
|
|
480
|
+
function setupTopicField(node, input) {
|
|
481
|
+
input.autoComplete({
|
|
482
|
+
minLength: 0,
|
|
483
|
+
completionPluginType: 'node-red-mqtt-topic-autocomplete-source',
|
|
484
|
+
context: {
|
|
485
|
+
node
|
|
486
|
+
}
|
|
487
|
+
})
|
|
488
|
+
}
|
|
489
|
+
|
|
480
490
|
RED.nodes.registerType('mqtt-broker',{
|
|
481
491
|
category: 'config',
|
|
482
492
|
defaults: {
|
|
@@ -852,6 +862,7 @@
|
|
|
852
862
|
},
|
|
853
863
|
oneditprepare: function() {
|
|
854
864
|
const node = this;
|
|
865
|
+
setupTopicField(this, $("#node-input-topic"));
|
|
855
866
|
const isV5Broker = function() {
|
|
856
867
|
var confNode = RED.nodes.node($("#node-input-broker").val());
|
|
857
868
|
return confNode && confNode.protocolVersion === "5";
|
|
@@ -930,6 +941,7 @@
|
|
|
930
941
|
},
|
|
931
942
|
oneditprepare: function() {
|
|
932
943
|
var that = this;
|
|
944
|
+
setupTopicField(this, $("#node-input-topic"));
|
|
933
945
|
|
|
934
946
|
function showHideDynamicFields() {
|
|
935
947
|
var confNode = RED.nodes.node($("#node-input-broker").val());
|
package/core/network/10-mqtt.js
CHANGED
|
@@ -675,7 +675,7 @@ module.exports = function(RED) {
|
|
|
675
675
|
node.options.password = node.password;
|
|
676
676
|
node.options.keepalive = node.keepalive;
|
|
677
677
|
node.options.clean = node.cleansession;
|
|
678
|
-
node.options.clientId = node.clientid || '
|
|
678
|
+
node.options.clientId = node.clientid || 'nodered' + RED.util.generateId();
|
|
679
679
|
node.options.reconnectPeriod = RED.settings.mqttReconnectTime||5000;
|
|
680
680
|
delete node.options.protocolId; //V4+ default
|
|
681
681
|
delete node.options.protocolVersion; //V4 default
|
|
@@ -25,11 +25,22 @@
|
|
|
25
25
|
<option value="patch">PATCH</option>
|
|
26
26
|
</select>
|
|
27
27
|
</div>
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
<div id="form-reqBody-http-in-controller" class="form-row hide" style="display: flex;">
|
|
29
30
|
<label> </label>
|
|
30
|
-
<
|
|
31
|
-
|
|
31
|
+
<div style="display: flex; margin-left: 5px; flex-direction: column-reverse; gap: 10px; justify-content: center;">
|
|
32
|
+
<div id="form-row-http-in-upload" class="hide" style="display: flex; gap: 10px">
|
|
33
|
+
<input type="checkbox" id="node-input-upload" style="margin: 0px;">
|
|
34
|
+
<label for="node-input-upload" style="text-wrap: nowrap; margin-bottom: 0;" data-i18n="httpin.label.upload"></label>
|
|
35
|
+
</div>
|
|
36
|
+
<div id="form-row-http-in-parsing" class="hide" style="display: flex; gap: 10px">
|
|
37
|
+
<input type="checkbox" id="node-input-skipBodyParsing" style="margin: 0px;">
|
|
38
|
+
<label for="node-input-skipBodyParsing" style="text-wrap: nowrap; margin-bottom: 0;" data-i18n="httpin.label.parsing"></label>
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
32
41
|
</div>
|
|
42
|
+
|
|
43
|
+
|
|
33
44
|
<div class="form-row">
|
|
34
45
|
<label for="node-input-url"><i class="fa fa-globe"></i> <span data-i18n="httpin.label.url"></span></label>
|
|
35
46
|
<input id="node-input-url" type="text" placeholder="/url">
|
|
@@ -74,6 +85,7 @@
|
|
|
74
85
|
label:RED._("node-red:httpin.label.url")},
|
|
75
86
|
method: {value:"get",required:true},
|
|
76
87
|
upload: {value:false},
|
|
88
|
+
skipBodyParsing: {value:false},
|
|
77
89
|
swaggerDoc: {type:"swagger-doc", required:false}
|
|
78
90
|
},
|
|
79
91
|
inputs:0,
|
|
@@ -115,16 +127,22 @@
|
|
|
115
127
|
$('.row-swagger-doc').hide();
|
|
116
128
|
}
|
|
117
129
|
$("#node-input-method").on("change", function() {
|
|
118
|
-
|
|
119
|
-
|
|
130
|
+
var method = $(this).val();
|
|
131
|
+
if(["post", "put", "patch","delete"].includes(method)){
|
|
132
|
+
$("#form-reqBody-http-in-controller").show();
|
|
133
|
+
$("#form-row-http-in-parsing").show();
|
|
134
|
+
if (method === "post") {
|
|
135
|
+
$("#form-row-http-in-upload").show();
|
|
136
|
+
} else {
|
|
137
|
+
$("#form-row-http-in-upload").hide();
|
|
138
|
+
}
|
|
120
139
|
} else {
|
|
121
|
-
$("
|
|
140
|
+
$("#form-row-http-in-parsing").hide();
|
|
141
|
+
$("#form-row-http-in-upload").hide();
|
|
142
|
+
$("#form-reqBody-http-in-controller").hide();
|
|
122
143
|
}
|
|
123
144
|
}).change();
|
|
124
|
-
|
|
125
|
-
|
|
126
145
|
}
|
|
127
|
-
|
|
128
146
|
});
|
|
129
147
|
var headerTypes = [
|
|
130
148
|
{value:"content-type",label:"Content-Type",hasValue: false},
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
module.exports = function(RED) {
|
|
18
18
|
"use strict";
|
|
19
|
+
var rootApp;
|
|
19
20
|
var bodyParser = require("body-parser");
|
|
20
21
|
var multer = require("multer");
|
|
21
22
|
var cookieParser = require("cookie-parser");
|
|
@@ -26,6 +27,7 @@ module.exports = function(RED) {
|
|
|
26
27
|
var mediaTyper = require('media-typer');
|
|
27
28
|
var isUtf8 = require('is-utf8');
|
|
28
29
|
var hashSum = require("hash-sum");
|
|
30
|
+
var rawDataRoutes = new Set();
|
|
29
31
|
|
|
30
32
|
function rawBodyParser(req, res, next) {
|
|
31
33
|
if (req.skipRawBodyParser) { next(); } // don't parse this if told to skip
|
|
@@ -71,7 +73,65 @@ module.exports = function(RED) {
|
|
|
71
73
|
});
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
|
|
76
|
+
/**
|
|
77
|
+
* This method retrieves the root app by traversing the parent hierarchy.
|
|
78
|
+
* @param {import('express').Application} app
|
|
79
|
+
* @returns {import('express').Application}
|
|
80
|
+
*/
|
|
81
|
+
function getRootApp(app) {
|
|
82
|
+
if (typeof app.parent === 'undefined') {
|
|
83
|
+
return app;
|
|
84
|
+
}
|
|
85
|
+
return getRootApp(app.parent);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* It provide the unique route key
|
|
90
|
+
* @param {{method: string, url: string}} obj
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
function getRouteKey(obj) {
|
|
94
|
+
var method = obj.method.toUpperCase();
|
|
95
|
+
// Normalize the URL by replacing double slashes with a single slash and removing the trailing slash
|
|
96
|
+
var url = obj.url.replace(/\/{2,}/g, '/').replace(/\/$/, '');
|
|
97
|
+
return `${method}:${url}`;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* This middleware is for capture raw body
|
|
102
|
+
* @param {import('express').Request} req
|
|
103
|
+
* @param {import('express').Response} _res
|
|
104
|
+
* @param {import('express').NextFunction} next
|
|
105
|
+
* @returns
|
|
106
|
+
*/
|
|
107
|
+
function rawBodyCapture(req, _res, next) {
|
|
108
|
+
var routeKey = getRouteKey({ method: req.method, url: req._parsedUrl.pathname });
|
|
109
|
+
// Check if routeKey exist in rawDataRoutes
|
|
110
|
+
if (rawDataRoutes.has(routeKey)) {
|
|
111
|
+
// Convert the request stream to buffer
|
|
112
|
+
getBody(req, {
|
|
113
|
+
length: req.headers['content-length'],
|
|
114
|
+
}, function (err, buf) {
|
|
115
|
+
if (err) {
|
|
116
|
+
return next(err);
|
|
117
|
+
}
|
|
118
|
+
req.body = buf;
|
|
119
|
+
// Skip the body parsing
|
|
120
|
+
req.skipRawBodyParser = true;
|
|
121
|
+
req._body = true;
|
|
122
|
+
next();
|
|
123
|
+
})
|
|
124
|
+
} else {
|
|
125
|
+
next();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if(typeof RED.httpNode === 'function' && (rootApp = getRootApp(RED.httpNode))) {
|
|
130
|
+
// Add middleware to the stack
|
|
131
|
+
rootApp.use(rawBodyCapture);
|
|
132
|
+
// Move the middleware to top of the stack
|
|
133
|
+
rootApp._router.stack.unshift(rootApp._router.stack.pop());
|
|
134
|
+
}
|
|
75
135
|
|
|
76
136
|
function createRequestWrapper(node,req) {
|
|
77
137
|
// This misses a bunch of properties (eg headers). Before we use this function
|
|
@@ -125,6 +185,7 @@ module.exports = function(RED) {
|
|
|
125
185
|
|
|
126
186
|
return wrapper;
|
|
127
187
|
}
|
|
188
|
+
|
|
128
189
|
function createResponseWrapper(node,res) {
|
|
129
190
|
var wrapper = {
|
|
130
191
|
_res: res
|
|
@@ -188,9 +249,16 @@ module.exports = function(RED) {
|
|
|
188
249
|
}
|
|
189
250
|
this.method = n.method;
|
|
190
251
|
this.upload = n.upload;
|
|
252
|
+
this.skipBodyParsing = n.skipBodyParsing;
|
|
191
253
|
this.swaggerDoc = n.swaggerDoc;
|
|
192
254
|
|
|
193
255
|
var node = this;
|
|
256
|
+
var routeKey = getRouteKey({method: this.method, url: RED.httpNode.path() + this.url});
|
|
257
|
+
|
|
258
|
+
// If the user enables raw body, add it to the raw data routes.
|
|
259
|
+
if(this.skipBodyParsing) {
|
|
260
|
+
rawDataRoutes.add(routeKey);
|
|
261
|
+
}
|
|
194
262
|
|
|
195
263
|
this.errorHandler = function(err,req,res,next) {
|
|
196
264
|
node.warn(err);
|
|
@@ -227,7 +295,9 @@ module.exports = function(RED) {
|
|
|
227
295
|
}
|
|
228
296
|
|
|
229
297
|
var maxApiRequestSize = RED.settings.apiMaxLength || '5mb';
|
|
298
|
+
|
|
230
299
|
var jsonParser = bodyParser.json({limit:maxApiRequestSize});
|
|
300
|
+
|
|
231
301
|
var urlencParser = bodyParser.urlencoded({limit:maxApiRequestSize,extended:true});
|
|
232
302
|
|
|
233
303
|
var metricsHandler = function(req,res,next) { next(); }
|
|
@@ -254,25 +324,27 @@ module.exports = function(RED) {
|
|
|
254
324
|
var mp = multer({ storage: multer.memoryStorage() }).any();
|
|
255
325
|
multipartParser = function(req,res,next) {
|
|
256
326
|
mp(req,res,function(err) {
|
|
257
|
-
req._body = true;
|
|
258
327
|
next(err);
|
|
259
328
|
})
|
|
260
329
|
};
|
|
261
330
|
}
|
|
262
331
|
|
|
263
332
|
if (this.method == "get") {
|
|
264
|
-
RED.httpNode.get(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,this.callback,this.errorHandler);
|
|
333
|
+
RED.httpNode.get(this.url, cookieParser(), httpMiddleware, corsHandler, metricsHandler, this.callback, this.errorHandler);
|
|
265
334
|
} else if (this.method == "post") {
|
|
266
|
-
RED.httpNode.post(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,multipartParser,rawBodyParser,this.callback,this.errorHandler);
|
|
335
|
+
RED.httpNode.post(this.url,cookieParser(), httpMiddleware, corsHandler, metricsHandler, jsonParser, urlencParser, multipartParser, rawBodyParser, this.callback, this.errorHandler);
|
|
267
336
|
} else if (this.method == "put") {
|
|
268
|
-
RED.httpNode.put(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler);
|
|
337
|
+
RED.httpNode.put(this.url, cookieParser(), httpMiddleware, corsHandler, metricsHandler, jsonParser, urlencParser, rawBodyParser, this.callback, this.errorHandler);
|
|
269
338
|
} else if (this.method == "patch") {
|
|
270
|
-
RED.httpNode.patch(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler);
|
|
339
|
+
RED.httpNode.patch(this.url, cookieParser(), httpMiddleware, corsHandler, metricsHandler, jsonParser, urlencParser, rawBodyParser, this.callback, this.errorHandler);
|
|
271
340
|
} else if (this.method == "delete") {
|
|
272
|
-
RED.httpNode.delete(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler);
|
|
341
|
+
RED.httpNode.delete(this.url, cookieParser(), httpMiddleware, corsHandler, metricsHandler, jsonParser, urlencParser, rawBodyParser, this.callback, this.errorHandler);
|
|
273
342
|
}
|
|
274
|
-
|
|
343
|
+
|
|
344
|
+
|
|
275
345
|
this.on("close",function() {
|
|
346
|
+
// Remove it from the raw data routes if the node is closed
|
|
347
|
+
rawDataRoutes.delete(routeKey);
|
|
276
348
|
var node = this;
|
|
277
349
|
RED.httpNode._router.stack.forEach(function(route,i,routes) {
|
|
278
350
|
if (route.route && route.route.path === node.url && route.route.methods[node.method]) {
|
|
@@ -284,9 +356,9 @@ module.exports = function(RED) {
|
|
|
284
356
|
this.warn(RED._("httpin.errors.not-created"));
|
|
285
357
|
}
|
|
286
358
|
}
|
|
359
|
+
|
|
287
360
|
RED.nodes.registerType("http in",HTTPIn);
|
|
288
361
|
|
|
289
|
-
|
|
290
362
|
function HTTPOut(n) {
|
|
291
363
|
RED.nodes.createNode(this,n);
|
|
292
364
|
var node = this;
|
|
@@ -361,5 +433,6 @@ module.exports = function(RED) {
|
|
|
361
433
|
done();
|
|
362
434
|
});
|
|
363
435
|
}
|
|
436
|
+
|
|
364
437
|
RED.nodes.registerType("http response",HTTPOut);
|
|
365
438
|
}
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
<div class="form-row">
|
|
31
31
|
<label for="node-input-url"><i class="fa fa-globe"></i> <span data-i18n="httpin.label.url"></span></label>
|
|
32
|
-
<input id="node-input-url" type="text" placeholder="
|
|
32
|
+
<input id="node-input-url" type="text" placeholder="https://">
|
|
33
33
|
</div>
|
|
34
34
|
|
|
35
35
|
<div class="form-row node-input-paytoqs-row">
|
|
@@ -431,7 +431,7 @@ in your Node-RED user directory (${RED.settings.userDir}).
|
|
|
431
431
|
normalisedHeaders[k.toLowerCase()] = response.headers[k]
|
|
432
432
|
})
|
|
433
433
|
if (normalisedHeaders['www-authenticate']) {
|
|
434
|
-
let authHeader = buildDigestHeader(digestCreds.user,digestCreds.password, response.request.options.method, requestUrl.pathname, normalisedHeaders['www-authenticate'])
|
|
434
|
+
let authHeader = buildDigestHeader(digestCreds.user,digestCreds.password, response.request.options.method, requestUrl.pathname + requestUrl.search, normalisedHeaders['www-authenticate'])
|
|
435
435
|
options.headers.Authorization = authHeader;
|
|
436
436
|
}
|
|
437
437
|
// response.request.options.merge(options)
|
|
@@ -586,9 +586,31 @@ in your Node-RED user directory (${RED.settings.userDir}).
|
|
|
586
586
|
opts.https.certificate = opts.https.cert;
|
|
587
587
|
delete opts.https.cert;
|
|
588
588
|
}
|
|
589
|
+
// The got library uses a different case for some https properties compared to the
|
|
590
|
+
// standard node tls options object.
|
|
591
|
+
if (opts.https.ALPNProtocols) {
|
|
592
|
+
opts.https.alpnProtocols = opts.https.ALPNProtocols
|
|
593
|
+
delete opts.https.ALPNProtocols
|
|
594
|
+
}
|
|
595
|
+
// The got library doesn't support servername at this time
|
|
596
|
+
// https://github.com/sindresorhus/got/issues/2320
|
|
597
|
+
if (opts.https.servername) {
|
|
598
|
+
delete opts.https.servername
|
|
599
|
+
}
|
|
589
600
|
} else {
|
|
590
601
|
if (msg.hasOwnProperty('rejectUnauthorized')) {
|
|
591
|
-
|
|
602
|
+
if (typeof msg.rejectUnauthorized === 'boolean') {
|
|
603
|
+
opts.https = { rejectUnauthorized: msg.rejectUnauthorized }
|
|
604
|
+
} else if (typeof msg.rejectUnauthorized === 'string') {
|
|
605
|
+
if (msg.rejectUnauthorized.toLowerCase() === 'true' || msg.rejectUnauthorized.toLowerCase() === 'false') {
|
|
606
|
+
opts.https = { rejectUnauthorized: (msg.rejectUnauthorized.toLowerCase() === 'true') }
|
|
607
|
+
} else {
|
|
608
|
+
node.warn(RED._("httpin.errors.rejectunauthorized-invalid"))
|
|
609
|
+
}
|
|
610
|
+
} else {
|
|
611
|
+
node.warn(RED._("httpin.errors.rejectunauthorized-invalid"))
|
|
612
|
+
}
|
|
613
|
+
|
|
592
614
|
}
|
|
593
615
|
}
|
|
594
616
|
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
</div>
|
|
51
51
|
|
|
52
52
|
<div id="node-row-newline" class="form-row hidden" style="padding-left:110px;">
|
|
53
|
-
<span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;" data-i18n="[placeholder]tcpin.label.optional"><br
|
|
53
|
+
<span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;" data-i18n="[placeholder]tcpin.label.optional"><br>
|
|
54
54
|
<input type="checkbox" id="node-input-trim" style="display:inline-block; width:auto; vertical-align:top;"> <span data-i18n="tcpin.label.reattach"></span>
|
|
55
55
|
</div>
|
|
56
56
|
|
|
@@ -317,7 +317,7 @@
|
|
|
317
317
|
<span id="node-units"></span>
|
|
318
318
|
</div>
|
|
319
319
|
<div id="node-row-newline" class="form-row hidden" style="padding-left:162px;">
|
|
320
|
-
<span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;" data-i18n="[placeholder]tcpin.label.optional"><br
|
|
320
|
+
<span data-i18n="tcpin.label.delimited"></span> <input type="text" id="node-input-newline" style="width:110px;" data-i18n="[placeholder]tcpin.label.optional"><br>
|
|
321
321
|
<input type="checkbox" id="node-input-trim" style="display:inline-block; width:auto; vertical-align:top;"> <span data-i18n="tcpin.label.reattach"></span>
|
|
322
322
|
</div>
|
|
323
323
|
<div class="form-row">
|
package/core/parsers/70-CSV.html
CHANGED
|
@@ -35,21 +35,21 @@
|
|
|
35
35
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
36
36
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
|
37
37
|
</div>
|
|
38
|
-
<hr align="middle"
|
|
38
|
+
<hr align="middle">
|
|
39
39
|
<div class="form-row">
|
|
40
40
|
<label style="width:100%;"><span data-i18n="csv.label.c2o"></span></label>
|
|
41
41
|
</div>
|
|
42
42
|
<div class="form-row" style="padding-left:20px;">
|
|
43
43
|
<label><i class="fa fa-sign-in"></i> <span data-i18n="csv.label.input"></span></label>
|
|
44
|
-
<span data-i18n="csv.label.skip-s"></span> <input type="text" id="node-input-skip" style="width:40px; height:25px;"
|
|
44
|
+
<span data-i18n="csv.label.skip-s"></span> <input type="text" id="node-input-skip" style="width:40px; height:25px;"> <span data-i18n="csv.label.skip-e"></span><br>
|
|
45
45
|
<label> </label>
|
|
46
|
-
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-hdrin"><label style="width:auto; margin-top:7px;" for="node-input-hdrin"><span data-i18n="csv.label.firstrow"></span></label><br
|
|
46
|
+
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-hdrin"><label style="width:auto; margin-top:7px;" for="node-input-hdrin"><span data-i18n="csv.label.firstrow"></span></label><br>
|
|
47
47
|
<label> </label>
|
|
48
|
-
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-strings"><label style="width:auto; margin-top:7px;" for="node-input-strings"><span data-i18n="csv.label.usestrings"></span></label><br
|
|
48
|
+
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-strings"><label style="width:auto; margin-top:7px;" for="node-input-strings"><span data-i18n="csv.label.usestrings"></span></label><br>
|
|
49
49
|
<label> </label>
|
|
50
|
-
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-include_empty_strings"><label style="width:auto; margin-top:7px;" for="node-input-include_empty_strings"><span data-i18n="csv.label.include_empty_strings"></span></label><br
|
|
50
|
+
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-include_empty_strings"><label style="width:auto; margin-top:7px;" for="node-input-include_empty_strings"><span data-i18n="csv.label.include_empty_strings"></span></label><br>
|
|
51
51
|
<label> </label>
|
|
52
|
-
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-include_null_values"><label style="width:auto; margin-top:7px;" for="node-input-include_null_values"><span data-i18n="csv.label.include_null_values"></span></label><br
|
|
52
|
+
<input style="width:20px; vertical-align:baseline; margin-right:5px;" type="checkbox" id="node-input-include_null_values"><label style="width:auto; margin-top:7px;" for="node-input-include_null_values"><span data-i18n="csv.label.include_null_values"></span></label><br>
|
|
53
53
|
</div>
|
|
54
54
|
<div class="form-row" style="padding-left:20px;">
|
|
55
55
|
<label><i class="fa fa-sign-out"></i> <span data-i18n="csv.label.output"></span></label>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<label for="node-input-chr" style="width: 230px;"><i class="fa fa-tag"></i> <span data-i18n="html.label.prefix"></span></label>
|
|
34
34
|
<input type="text" id="node-input-chr" style="text-align:center; width: 40px;" placeholder="_">
|
|
35
35
|
</div>
|
|
36
|
-
<br
|
|
36
|
+
<br>
|
|
37
37
|
<div class="form-row">
|
|
38
38
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
39
39
|
<input type="text" id="node-input-name" style="width:70%" data-i18n="[placeholder]common.label.name">
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
</div>
|
|
11
11
|
<div class="form-row">
|
|
12
12
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="json.label.property"></span></label>
|
|
13
|
-
<input type="text" id="node-input-property" style="width:70%;"
|
|
13
|
+
<input type="text" id="node-input-property" style="width:70%;">
|
|
14
14
|
</div>
|
|
15
15
|
<div class="form-row">
|
|
16
16
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
17
17
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
|
18
18
|
</div>
|
|
19
|
-
<hr align="middle"
|
|
19
|
+
<hr align="middle">
|
|
20
20
|
<div class="form-row node-json-to-json-options">
|
|
21
21
|
<label style="width:100%;"><span data-i18n="json.label.o2j"></span></label>
|
|
22
22
|
</div>
|
package/core/parsers/70-XML.html
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
<script type="text/html" data-template-name="xml">
|
|
3
3
|
<div class="form-row">
|
|
4
4
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label>
|
|
5
|
-
<input type="text" id="node-input-property" style="width:70%;"
|
|
5
|
+
<input type="text" id="node-input-property" style="width:70%;">
|
|
6
6
|
</div>
|
|
7
7
|
<div class="form-row">
|
|
8
8
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
9
9
|
<input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
|
|
10
10
|
</div>
|
|
11
|
-
<hr align="middle"
|
|
11
|
+
<hr align="middle">
|
|
12
12
|
<div class="form-row">
|
|
13
13
|
<label style="width:100%;"><span data-i18n="xml.label.x2o"></span></label>
|
|
14
14
|
</div>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<script type="text/html" data-template-name="yaml">
|
|
3
3
|
<div class="form-row">
|
|
4
4
|
<label for="node-input-property"><i class="fa fa-ellipsis-h"></i> <span data-i18n="common.label.property"></span></label>
|
|
5
|
-
<input type="text" id="node-input-property" style="width:70%;"
|
|
5
|
+
<input type="text" id="node-input-property" style="width:70%;">
|
|
6
6
|
</div>
|
|
7
7
|
<div class="form-row">
|
|
8
8
|
<label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<input type="text" id="node-input-name" data-i18n="[placeholder]node-red:common.label.name">
|
|
22
22
|
</div>
|
|
23
23
|
<div class="form-row">
|
|
24
|
-
<label for="node-input-property"
|
|
24
|
+
<label for="node-input-property" style="padding-left:10px; margin-right:-10px;" data-i18n="split.splitThe"></label>
|
|
25
25
|
<input type="text" id="node-input-property" style="width:70%;"/>
|
|
26
26
|
</div>
|
|
27
27
|
<div class="form-row"><span data-i18n="[html]split.strBuff"></span></div>
|
|
@@ -202,7 +202,7 @@
|
|
|
202
202
|
<div class="form-row">
|
|
203
203
|
<label> </label>
|
|
204
204
|
<input type="checkbox" id="node-input-reduceRight" style="display:inline-block; width:auto; vertical-align:top; margin-left:10px;">
|
|
205
|
-
<label for="node-input-reduceRight"
|
|
205
|
+
<label for="node-input-reduceRight" data-i18n="join.reduce.right" style="width:70%; margin-left:10px;"></label>
|
|
206
206
|
</div>
|
|
207
207
|
</div>
|
|
208
208
|
<div class="form-tips form-tips-auto hide" data-i18n="[html]join.tip"></div>
|
|
@@ -151,10 +151,11 @@ module.exports = function(RED) {
|
|
|
151
151
|
if (node.arraySplt === 1) {
|
|
152
152
|
m = m[0];
|
|
153
153
|
}
|
|
154
|
-
RED.util.
|
|
155
|
-
|
|
154
|
+
const newmsg = RED.util.cloneMessage(msg)
|
|
155
|
+
RED.util.setMessageProperty(newmsg,node.property,m);
|
|
156
|
+
newmsg.parts.index = i;
|
|
156
157
|
pos += node.arraySplt;
|
|
157
|
-
send(
|
|
158
|
+
send(newmsg);
|
|
158
159
|
}
|
|
159
160
|
done();
|
|
160
161
|
}
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
<p>Wenn <code>msg.payload</code> ein Objekt ist, setzt der Node automatisch den Inhaltstyp der Anforderung
|
|
82
82
|
auf <code>application/json</code> und kodiert den Hauptteil als solchen.</p>
|
|
83
83
|
<p>Um die Anforderung als Formulardaten zu kodieren, sollte <code>msg.headers["content-type"]</code> auf
|
|
84
|
-
<code>application/x-
|
|
84
|
+
<code>application/x-www-form-urlencoded</code> gesetzt werden.</p>
|
|
85
85
|
<h4><b>Datei-Upload</b></h4>
|
|
86
86
|
<p>Um einen Datei-Upload umzusetzen, sollte <code>msg.headers["content-type"]</code> auf <code>multipart/form-data</code>
|
|
87
87
|
gesetzt werden und das an den Node zu sendende <code>msg.payload</code> muss ein Objekt mit folgender Struktur sein:</p>
|
|
@@ -406,6 +406,7 @@
|
|
|
406
406
|
"label": {
|
|
407
407
|
"unknown": "unknown"
|
|
408
408
|
},
|
|
409
|
+
"manageModules": "Manage modules",
|
|
409
410
|
"tip": "<p>This node is a type unknown to your installation of Node-RED.</p><p><i>If you deploy with the node in this state, it's configuration will be preserved, but the flow will not start until the missing type is installed.</i></p><p>See the Info side bar for more help</p>"
|
|
410
411
|
},
|
|
411
412
|
"mqtt": {
|
|
@@ -514,7 +515,8 @@
|
|
|
514
515
|
"url": "URL",
|
|
515
516
|
"doc": "Docs",
|
|
516
517
|
"return": "Return",
|
|
517
|
-
"upload": "Accept file uploads
|
|
518
|
+
"upload": "Accept file uploads",
|
|
519
|
+
"parsing": "Do not parse request body",
|
|
518
520
|
"status": "Status code",
|
|
519
521
|
"headers": "Headers",
|
|
520
522
|
"other": "other",
|
|
@@ -562,7 +564,8 @@
|
|
|
562
564
|
"timeout-isnan": "Timeout value is not a valid number, ignoring",
|
|
563
565
|
"timeout-isnegative": "Timeout value is negative, ignoring",
|
|
564
566
|
"invalid-payload": "Invalid payload",
|
|
565
|
-
"invalid-url": "Invalid url"
|
|
567
|
+
"invalid-url": "Invalid url",
|
|
568
|
+
"rejectunauthorized-invalid": "msg.rejectUnauthorized should be a boolean"
|
|
566
569
|
},
|
|
567
570
|
"status": {
|
|
568
571
|
"requesting": "requesting"
|
|
@@ -1017,7 +1020,7 @@
|
|
|
1017
1020
|
"objectSend": "Send a message for each key/value pair",
|
|
1018
1021
|
"strBuff": "<b>String</b> / <b>Buffer</b>",
|
|
1019
1022
|
"array": "<b>Array</b>",
|
|
1020
|
-
"splitThe": "Split
|
|
1023
|
+
"splitThe": "Split property",
|
|
1021
1024
|
"splitUsing": "Split using",
|
|
1022
1025
|
"splitLength": "Fixed length of",
|
|
1023
1026
|
"stream": "Handle as a stream of messages",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
<p>If the content type of the request can be determined, the body will be parsed to
|
|
51
51
|
any appropriate type. For example, <code>application/json</code> will be parsed to
|
|
52
52
|
its JavaScript object representation.</p>
|
|
53
|
+
<p>The node can be configured to not parse the body, in which case it will be provided as a Buffer object.</p>
|
|
53
54
|
<p><b>Note:</b> this node does not send any response to the request. The flow
|
|
54
55
|
must include an HTTP Response node to complete the request.</p>
|
|
55
56
|
</script>
|
package/locales/fr/messages.json
CHANGED
|
@@ -406,6 +406,7 @@
|
|
|
406
406
|
"label": {
|
|
407
407
|
"unknown": "inconnu"
|
|
408
408
|
},
|
|
409
|
+
"manageModules": "Gérer les modules",
|
|
409
410
|
"tip": "<p>Ce noeud est un type inconnu de votre installation Node-RED.</p><p><i>Si vous déployez avec le noeud dans cet état, sa configuration sera préservée, mais le flux ne démarrera pas avant que le type manquant soit installé.</i></p><p>Consulter la barre latérale d'informations pour plus d'aide</p>"
|
|
410
411
|
},
|
|
411
412
|
"mqtt": {
|
|
@@ -1017,7 +1018,7 @@
|
|
|
1017
1018
|
"objectSend": "Envoie un message pour chaque paire clé/valeur",
|
|
1018
1019
|
"strBuff": "<b>Chaîne</b> / <b>Tampon</b>",
|
|
1019
1020
|
"array": "<b>Tableau</b>",
|
|
1020
|
-
"splitThe": "Diviser
|
|
1021
|
+
"splitThe": "Diviser la propriété",
|
|
1021
1022
|
"splitUsing": "Diviser en utilisant",
|
|
1022
1023
|
"splitLength": "Longueur fixe de",
|
|
1023
1024
|
"stream": "Gérer comme un flux de messages",
|
package/locales/ja/messages.json
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
<p>これらは、動的購読が設定されている場合のみ適用されます。</p>
|
|
48
48
|
<dl class="message-properties">
|
|
49
49
|
<dt>action <span class="property-type">文字列</span></dt>
|
|
50
|
-
<dd>本ノードが行う動作の名前。利用可能な動作は<code>"connect"</code>、<code>"disconnect"</code>、<code>"subscribe"</code>、<code>"unsubscribe"</code>です。</dd>
|
|
50
|
+
<dd>本ノードが行う動作の名前。利用可能な動作は<code>"connect"</code>、<code>"disconnect"</code>、<code>"getSubscriptions"</code>、<code>"subscribe"</code>、<code>"unsubscribe"</code>です。</dd>
|
|
51
51
|
<dt class="optional">topic <span class="property-type">文字列|オブジェクト|配列</span></dt>
|
|
52
52
|
<dd><code>"subscribe"</code>と<code>"unsubscribe"</code>の動作に対して、本プロパティはトピックを提供します。次のいずれかを設定できます:<ul>
|
|
53
53
|
<li>トピックフィルターを含む文字列</li>
|
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
<h3>入力</h3>
|
|
106
106
|
<dl class="message-properties">
|
|
107
107
|
<dt>action <span class="property-type">文字列</span></dt>
|
|
108
|
-
<dd>本ノードが行う動作の名前。利用可能な動作は<code>"connect"</code
|
|
108
|
+
<dd>本ノードが行う動作の名前。利用可能な動作は<code>"connect"</code>と<code>"disconnect"</code>です。</dd>
|
|
109
109
|
<dt class="optional">broker <span class="property-type">broker</span> </dt>
|
|
110
110
|
<dd><code>"connect"</code>の動作に対して、本プロパティは次の様な個々のブローカ設定を上書きします: <ul>
|
|
111
111
|
<li><code>broker</code></li>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node-red/nodes",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.1.0-beta.2",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
}
|
|
16
16
|
],
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"acorn": "8.
|
|
18
|
+
"acorn": "8.15.0",
|
|
19
19
|
"acorn-walk": "8.3.4",
|
|
20
20
|
"ajv": "8.17.1",
|
|
21
21
|
"body-parser": "1.20.3",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"cors": "2.8.5",
|
|
27
27
|
"cronosjs": "1.7.1",
|
|
28
28
|
"denque": "2.1.0",
|
|
29
|
-
"form-data": "4.0.
|
|
30
|
-
"fs-extra": "11.
|
|
29
|
+
"form-data": "4.0.2",
|
|
30
|
+
"fs-extra": "11.3.0",
|
|
31
31
|
"got": "12.6.1",
|
|
32
32
|
"hash-sum": "2.0.0",
|
|
33
33
|
"hpagent": "1.2.0",
|
|
@@ -35,13 +35,13 @@
|
|
|
35
35
|
"is-utf8": "0.2.1",
|
|
36
36
|
"js-yaml": "4.1.0",
|
|
37
37
|
"media-typer": "1.1.0",
|
|
38
|
-
"mqtt": "5.
|
|
39
|
-
"multer": "
|
|
38
|
+
"mqtt": "5.11.0",
|
|
39
|
+
"multer": "2.0.1",
|
|
40
40
|
"mustache": "4.2.0",
|
|
41
41
|
"node-watch": "0.7.4",
|
|
42
42
|
"on-headers": "1.0.2",
|
|
43
43
|
"raw-body": "3.0.0",
|
|
44
|
-
"tough-cookie": "
|
|
44
|
+
"tough-cookie": "5.1.2",
|
|
45
45
|
"uuid": "9.0.1",
|
|
46
46
|
"ws": "7.5.10",
|
|
47
47
|
"xml2js": "0.6.2",
|