@node-red/nodes 3.1.0 → 3.1.1
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 +1 -1
- package/core/common/20-inject.js +2 -3
- package/core/common/21-debug.html +136 -1
- package/core/common/60-link.html +1 -1
- package/core/common/lib/debug/debug-utils.js +17 -138
- package/core/common/lib/debug/debug.js +5 -0
- package/core/function/10-switch.html +27 -1
- package/core/function/15-change.html +26 -55
- package/core/function/16-range.html +6 -1
- package/core/function/80-template.html +1 -1
- package/core/function/89-delay.js +1 -1
- package/core/function/90-exec.html +1 -1
- package/core/function/rbe.html +4 -2
- package/core/network/10-mqtt.js +17 -16
- package/core/parsers/70-CSV.js +16 -13
- package/core/parsers/70-HTML.html +2 -2
- package/core/parsers/70-JSON.html +1 -0
- package/core/parsers/70-XML.html +2 -1
- package/core/parsers/70-YAML.html +1 -0
- package/core/sequence/17-split.html +17 -2
- package/core/storage/10-file.html +2 -2
- package/locales/fr/common/20-inject.html +1 -1
- package/locales/fr/messages.json +82 -82
- package/package.json +1 -1
package/core/network/10-mqtt.js
CHANGED
|
@@ -104,6 +104,7 @@ module.exports = function(RED) {
|
|
|
104
104
|
* @returns `true` if it is a valid topic
|
|
105
105
|
*/
|
|
106
106
|
function isValidPublishTopic(topic) {
|
|
107
|
+
if (topic.length === 0) return false;
|
|
107
108
|
return !/[\+#\b\f\n\r\t\v\0]/.test(topic);
|
|
108
109
|
}
|
|
109
110
|
|
|
@@ -219,8 +220,8 @@ module.exports = function(RED) {
|
|
|
219
220
|
*/
|
|
220
221
|
function subscriptionHandler(node, datatype ,topic, payload, packet) {
|
|
221
222
|
const msg = {topic:topic, payload:null, qos:packet.qos, retain:packet.retain};
|
|
222
|
-
const v5 = (node && node.brokerConn)
|
|
223
|
-
? node.brokerConn.v5()
|
|
223
|
+
const v5 = (node && node.brokerConn)
|
|
224
|
+
? node.brokerConn.v5()
|
|
224
225
|
: Object.prototype.hasOwnProperty.call(packet, "properties");
|
|
225
226
|
if(v5 && packet.properties) {
|
|
226
227
|
setStrProp(packet.properties, msg, "responseTopic");
|
|
@@ -451,7 +452,7 @@ module.exports = function(RED) {
|
|
|
451
452
|
|
|
452
453
|
/**
|
|
453
454
|
* Perform the disconnect action
|
|
454
|
-
* @param {MQTTInNode|MQTTOutNode} node
|
|
455
|
+
* @param {MQTTInNode|MQTTOutNode} node
|
|
455
456
|
* @param {Function} done
|
|
456
457
|
*/
|
|
457
458
|
function handleDisconnectAction(node, done) {
|
|
@@ -611,7 +612,7 @@ module.exports = function(RED) {
|
|
|
611
612
|
node.brokerurl = node.url;
|
|
612
613
|
} else {
|
|
613
614
|
// if the broker is ws:// or wss:// or tcp://
|
|
614
|
-
if (node.broker.indexOf("://") > -1) {
|
|
615
|
+
if ((typeof node.broker === 'string') && node.broker.indexOf("://") > -1) {
|
|
615
616
|
node.brokerurl = node.broker;
|
|
616
617
|
// Only for ws or wss, check if proxy env var for additional configuration
|
|
617
618
|
if (node.brokerurl.indexOf("wss://") > -1 || node.brokerurl.indexOf("ws://") > -1) {
|
|
@@ -865,7 +866,7 @@ module.exports = function(RED) {
|
|
|
865
866
|
* Call end and wait for the client to end (or timeout)
|
|
866
867
|
* @param {mqtt.MqttClient} client The broker client
|
|
867
868
|
* @param {number} ms The time to wait for the client to end
|
|
868
|
-
* @returns
|
|
869
|
+
* @returns
|
|
869
870
|
*/
|
|
870
871
|
let waitEnd = (client, ms) => {
|
|
871
872
|
return new Promise( (resolve, reject) => {
|
|
@@ -905,7 +906,7 @@ module.exports = function(RED) {
|
|
|
905
906
|
node.subid = 1;
|
|
906
907
|
|
|
907
908
|
//typedef for subscription object:
|
|
908
|
-
/**
|
|
909
|
+
/**
|
|
909
910
|
* @typedef {Object} Subscription
|
|
910
911
|
* @property {String} topic - topic to subscribe to
|
|
911
912
|
* @property {Object} [options] - options object
|
|
@@ -933,7 +934,7 @@ module.exports = function(RED) {
|
|
|
933
934
|
const ref = _ref || 0;
|
|
934
935
|
let options
|
|
935
936
|
let qos = 1 // default to QoS 1 (AWS and several other brokers don't support QoS 2)
|
|
936
|
-
|
|
937
|
+
|
|
937
938
|
// if options is an object, then clone it
|
|
938
939
|
if (typeof _options == "object") {
|
|
939
940
|
options = RED.util.cloneMessage(_options || {})
|
|
@@ -947,7 +948,7 @@ module.exports = function(RED) {
|
|
|
947
948
|
if (typeof qos === "number" && qos >= 0 && qos <= 2) {
|
|
948
949
|
options.qos = qos;
|
|
949
950
|
}
|
|
950
|
-
|
|
951
|
+
|
|
951
952
|
subscription.topic = _topic;
|
|
952
953
|
subscription.qos = qos;
|
|
953
954
|
subscription.options = RED.util.cloneMessage(options);
|
|
@@ -957,16 +958,16 @@ module.exports = function(RED) {
|
|
|
957
958
|
}
|
|
958
959
|
|
|
959
960
|
/**
|
|
960
|
-
* If topic is a subscription object, then use that, otherwise look up the topic in
|
|
961
|
+
* If topic is a subscription object, then use that, otherwise look up the topic in
|
|
961
962
|
* the subscriptions object. If the topic is not found, then create a new subscription
|
|
962
963
|
* object and add it to the subscriptions object.
|
|
963
|
-
* @param {Subscription|String} topic
|
|
964
|
-
* @param {*} options
|
|
965
|
-
* @param {*} callback
|
|
966
|
-
* @param {*} ref
|
|
964
|
+
* @param {Subscription|String} topic
|
|
965
|
+
* @param {*} options
|
|
966
|
+
* @param {*} callback
|
|
967
|
+
* @param {*} ref
|
|
967
968
|
*/
|
|
968
969
|
node.subscribe = function (topic, options, callback, ref) {
|
|
969
|
-
/** @type {Subscription} */
|
|
970
|
+
/** @type {Subscription} */
|
|
970
971
|
let subscription
|
|
971
972
|
let doCompare = false
|
|
972
973
|
let changesFound = false
|
|
@@ -1004,7 +1005,7 @@ module.exports = function(RED) {
|
|
|
1004
1005
|
_brokerConn.unsubscribe(sub.topic, sub.ref, true)
|
|
1005
1006
|
}
|
|
1006
1007
|
})
|
|
1007
|
-
|
|
1008
|
+
|
|
1008
1009
|
// if subscription is found (or sent in as a parameter), then check for changes.
|
|
1009
1010
|
// if there are any changes requested, tidy up the old subscription
|
|
1010
1011
|
if (subscription) {
|
|
@@ -1091,7 +1092,7 @@ module.exports = function(RED) {
|
|
|
1091
1092
|
delete sub[ref]
|
|
1092
1093
|
}
|
|
1093
1094
|
}
|
|
1094
|
-
// if instructed to remove the actual MQTT client subscription
|
|
1095
|
+
// if instructed to remove the actual MQTT client subscription
|
|
1095
1096
|
if (unsub) {
|
|
1096
1097
|
// if there are no more subscriptions for the topic, then remove the topic
|
|
1097
1098
|
if (Object.keys(sub).length === 0) {
|
package/core/parsers/70-CSV.js
CHANGED
|
@@ -63,7 +63,7 @@ module.exports = function(RED) {
|
|
|
63
63
|
if (!(notemplate && (msg.hasOwnProperty("parts") && msg.parts.hasOwnProperty("index") && msg.parts.index > 0))) {
|
|
64
64
|
template = clean(node.template);
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
const ou = [];
|
|
67
67
|
if (!Array.isArray(msg.payload)) { msg.payload = [ msg.payload ]; }
|
|
68
68
|
if (node.hdrout !== "none" && node.hdrSent === false) {
|
|
69
69
|
if ((template.length === 1) && (template[0] === '')) {
|
|
@@ -74,7 +74,7 @@ module.exports = function(RED) {
|
|
|
74
74
|
template = Object.keys(msg.payload[0]);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
-
ou
|
|
77
|
+
ou.push(template.map(v => v.indexOf(node.sep)!==-1 ? '"'+v+'"' : v).join(node.sep));
|
|
78
78
|
if (node.hdrout === "once") { node.hdrSent = true; }
|
|
79
79
|
}
|
|
80
80
|
for (var s = 0; s < msg.payload.length; s++) {
|
|
@@ -93,7 +93,7 @@ module.exports = function(RED) {
|
|
|
93
93
|
msg.payload[s][t] = node.quo + msg.payload[s][t].toString() + node.quo;
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
-
ou
|
|
96
|
+
ou.push(msg.payload[s].join(node.sep));
|
|
97
97
|
}
|
|
98
98
|
else {
|
|
99
99
|
if ((template.length === 1) && (template[0] === '') && (msg.hasOwnProperty("columns"))) {
|
|
@@ -105,6 +105,7 @@ module.exports = function(RED) {
|
|
|
105
105
|
node.warn(RED._("csv.errors.obj_csv"));
|
|
106
106
|
tmpwarn = false;
|
|
107
107
|
}
|
|
108
|
+
const row = [];
|
|
108
109
|
for (var p in msg.payload[0]) {
|
|
109
110
|
/* istanbul ignore else */
|
|
110
111
|
if (msg.payload[s].hasOwnProperty(p)) {
|
|
@@ -118,21 +119,22 @@ module.exports = function(RED) {
|
|
|
118
119
|
}
|
|
119
120
|
if (q.indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
|
120
121
|
q = q.replace(/"/g, '""');
|
|
121
|
-
|
|
122
|
+
row.push(node.quo + q + node.quo);
|
|
122
123
|
}
|
|
123
124
|
else if (q.indexOf(node.sep) !== -1 || p.indexOf("\n") !== -1) { // add quotes if any "commas" or "\n"
|
|
124
|
-
|
|
125
|
+
row.push(node.quo + q + node.quo);
|
|
125
126
|
}
|
|
126
|
-
else {
|
|
127
|
+
else { row.push(q); } // otherwise just add
|
|
127
128
|
}
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
|
-
ou
|
|
131
|
+
ou.push(row.join(node.sep)); // add separator
|
|
131
132
|
}
|
|
132
133
|
else {
|
|
134
|
+
const row = [];
|
|
133
135
|
for (var t=0; t < template.length; t++) {
|
|
134
136
|
if (template[t] === '') {
|
|
135
|
-
|
|
137
|
+
row.push('');
|
|
136
138
|
}
|
|
137
139
|
else {
|
|
138
140
|
var tt = template[t];
|
|
@@ -146,19 +148,20 @@ module.exports = function(RED) {
|
|
|
146
148
|
p = RED.util.ensureString(p);
|
|
147
149
|
if (p.indexOf(node.quo) !== -1) { // add double quotes if any quotes
|
|
148
150
|
p = p.replace(/"/g, '""');
|
|
149
|
-
|
|
151
|
+
row.push(node.quo + p + node.quo);
|
|
150
152
|
}
|
|
151
153
|
else if (p.indexOf(node.sep) !== -1 || p.indexOf("\n") !== -1) { // add quotes if any "commas" or "\n"
|
|
152
|
-
|
|
154
|
+
row.push(node.quo + p + node.quo);
|
|
153
155
|
}
|
|
154
|
-
else {
|
|
156
|
+
else { row.push(p); } // otherwise just add
|
|
155
157
|
}
|
|
156
158
|
}
|
|
157
|
-
ou
|
|
159
|
+
ou.push(row.join(node.sep)); // add separator
|
|
158
160
|
}
|
|
159
161
|
}
|
|
160
162
|
}
|
|
161
|
-
|
|
163
|
+
// join lines, don't forget to add the last new line
|
|
164
|
+
msg.payload = ou.join(node.ret) + node.ret;
|
|
162
165
|
msg.columns = template.map(v => v.indexOf(',')!==-1 ? '"'+v+'"' : v).join(',');
|
|
163
166
|
if (msg.payload !== '') { send(msg); }
|
|
164
167
|
done();
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
color:"#DEBD5C",
|
|
42
42
|
defaults: {
|
|
43
43
|
name: {value:""},
|
|
44
|
-
property: {value:"payload"},
|
|
45
|
-
outproperty: {value:"payload"},
|
|
44
|
+
property: {value:"payload", validate: RED.validators.typedInput({ type: 'msg' }) },
|
|
45
|
+
outproperty: {value:"payload", validate: RED.validators.typedInput({ type: 'msg' }) },
|
|
46
46
|
tag: {value:""},
|
|
47
47
|
ret: {value:"html"},
|
|
48
48
|
as: {value:"single"}
|
package/core/parsers/70-XML.html
CHANGED
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
defaults: {
|
|
28
28
|
name: {value:""},
|
|
29
29
|
property: {value:"payload",required:true,
|
|
30
|
-
label:RED._("node-red:common.label.property")
|
|
30
|
+
label:RED._("node-red:common.label.property"),
|
|
31
|
+
validate: RED.validators.typedInput({ type: 'msg' })},
|
|
31
32
|
attr: {value:""},
|
|
32
33
|
chr: {value:""}
|
|
33
34
|
},
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
arraySplt: {value:1},
|
|
58
58
|
arraySpltType: {value:"len"},
|
|
59
59
|
stream: {value:false},
|
|
60
|
-
addname: {value:""}
|
|
60
|
+
addname: {value:"", validate: RED.validators.typedInput({ type: 'msg', allowBlank: true })}
|
|
61
61
|
},
|
|
62
62
|
inputs:1,
|
|
63
63
|
outputs:1,
|
|
@@ -208,7 +208,22 @@
|
|
|
208
208
|
validate:RED.validators.typedInput("propertyType", false)
|
|
209
209
|
},
|
|
210
210
|
propertyType: { value:"msg"},
|
|
211
|
-
key: {value:"topic"
|
|
211
|
+
key: {value:"topic", validate: (function () {
|
|
212
|
+
const typeValidator = RED.validators.typedInput({ type: 'msg' })
|
|
213
|
+
return function(v, opt) {
|
|
214
|
+
const joinMode = $("#node-input-mode").val() || this.mode
|
|
215
|
+
if (joinMode !== 'custom') {
|
|
216
|
+
return true
|
|
217
|
+
}
|
|
218
|
+
const buildType = $("#node-input-build").val() || this.build
|
|
219
|
+
if (buildType !== 'object') {
|
|
220
|
+
return true
|
|
221
|
+
} else {
|
|
222
|
+
return typeValidator(v, opt)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
})()
|
|
226
|
+
},
|
|
212
227
|
joiner: { value:"\\n"},
|
|
213
228
|
joinerType: { value:"str"},
|
|
214
229
|
accumulate: { value:"false" },
|
|
@@ -198,7 +198,7 @@
|
|
|
198
198
|
category: 'storage',
|
|
199
199
|
defaults: {
|
|
200
200
|
name: {value:""},
|
|
201
|
-
filename: {value:""},
|
|
201
|
+
filename: {value:"", validate: RED.validators.typedInput({ typeField: 'filenameType' })},
|
|
202
202
|
filenameType: {value:"str"},
|
|
203
203
|
appendNewline: {value:true},
|
|
204
204
|
createDir: {value:false},
|
|
@@ -297,7 +297,7 @@
|
|
|
297
297
|
category: 'storage',
|
|
298
298
|
defaults: {
|
|
299
299
|
name: {value:""},
|
|
300
|
-
filename: {value:""},
|
|
300
|
+
filename: {value:"", validate: RED.validators.typedInput({ typeField: 'filenameType' }) },
|
|
301
301
|
filenameType: {value:"str"},
|
|
302
302
|
format: {value:"utf8"},
|
|
303
303
|
chunk: {value:false},
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
<p><b>Remarque</b> : Les options <i>"Intervalle entre les heures"</i> et <i>"à une heure précise"</i> utilisent le système cron standard.
|
|
37
37
|
Cela signifie que pour la première option, vous pouvez envoyer un message à intervalle régulier entre les heures voulues.
|
|
38
38
|
Si vous voulez envoyer un message toutes les minutes à partir de maintenant, utiliser l'option <i>"intervalle"</i>.</p>
|
|
39
|
-
<p><b>Remarque</b> : Pour inclure une nouvelle ligne dans une chaîne, vous devez utiliser un noeud de fonction pour créer la charge utile.</p>
|
|
39
|
+
<p><b>Remarque</b> : Pour inclure une nouvelle ligne dans une chaîne, vous devez utiliser soit un noeud de fonction soit le noeud template pour créer la charge utile.</p>
|
|
40
40
|
</script>
|