@node-red/nodes 4.0.0-beta.1 → 4.0.0-beta.3

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.
@@ -378,7 +378,7 @@
378
378
  return { id: id, label: RED.nodes.workspace(id).label } //flow id + name
379
379
  } else {
380
380
  const instanceNode = RED.nodes.node(id)
381
- const pathLabel = (instanceNode.name || RED.nodes.subflow(instanceNode.type.substring(8)).name)
381
+ const pathLabel = (instanceNode.name || RED.nodes.subflow(instanceNode.type.substring(8))?.name || instanceNode.type)
382
382
  return { id: id, label: pathLabel }
383
383
  }
384
384
  })
@@ -374,7 +374,7 @@ module.exports = function(RED) {
374
374
  iniOpt.breakOnSigint = true;
375
375
  }
376
376
  }
377
- node.script = vm.createScript(functionText, createVMOpt(node, ""));
377
+ node.script = new vm.Script(functionText, createVMOpt(node, ""));
378
378
  if (node.fin && (node.fin !== "")) {
379
379
  var finText = `(function () {
380
380
  var node = {
@@ -438,10 +438,9 @@ module.exports = function(RED) {
438
438
 
439
439
  //store the error in msg to be used in flows
440
440
  msg.error = err;
441
-
442
- var line = 0;
443
- var errorMessage;
444
441
  if (stack.length > 0) {
442
+ let line = 0;
443
+ let errorMessage;
445
444
  while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) {
446
445
  line++;
447
446
  }
@@ -455,11 +454,13 @@ module.exports = function(RED) {
455
454
  errorMessage += " (line "+lineno+", col "+cha+")";
456
455
  }
457
456
  }
457
+ if (errorMessage) {
458
+ err.message = errorMessage
459
+ }
458
460
  }
459
- if (!errorMessage) {
460
- errorMessage = err.toString();
461
- }
462
- done(errorMessage);
461
+ // Pass the whole error object so any additional properties
462
+ // (such as cause) are preserved
463
+ done(err);
463
464
  }
464
465
  else if (typeof err === "string") {
465
466
  done(err);
@@ -233,9 +233,12 @@ module.exports = function(RED) {
233
233
  // only replace if they match exactly
234
234
  RED.util.setMessageProperty(msg,property,value);
235
235
  } else {
236
- // if target is boolean then just replace it
237
- if (rule.tot === "bool") { current = value; }
238
- else { current = current.replace(fromRE,value); }
236
+ current = current.replace(fromRE,value);
237
+ if (rule.tot === "bool" && current === ""+value) {
238
+ // If the target type is boolean, and the replace call has resulted in "true"/"false",
239
+ // convert to boolean type (which 'value' already is)
240
+ current = value
241
+ }
239
242
  RED.util.setMessageProperty(msg,property,current);
240
243
  }
241
244
  } else if ((typeof current === 'number' || current instanceof Number) && fromType === 'num') {
@@ -0,0 +1,362 @@
1
+
2
+ <script type="text/html" data-template-name="array">
3
+ <div class="form-row">
4
+ <label for="node-input-name"><i class="fa fa-tag"></i> <span data-i18n="common.label.name"></span></label>
5
+ <input type="text" id="node-input-name" style="width: calc(100% - 105px)" data-i18n="[placeholder]common.label.name">
6
+ </div>
7
+ <div class="form-row" style="margin-bottom:0;">
8
+ <label><i class="fa fa-list"></i> <span data-i18n="change.label.rules"></span></label>
9
+ </div>
10
+ <div class="form-row node-input-rule-container-row">
11
+ <ol id="node-input-rule-container"></ol>
12
+ </div>
13
+ </script>
14
+
15
+ <script type="text/javascript">
16
+ (function() {
17
+ RED.nodes.registerType('array', {
18
+ color: "#E2D96E",
19
+ category: 'function',
20
+ defaults: {
21
+ name: {value:""},
22
+ rules:{
23
+ value:[{t:"set",p:"payload",pt:"msg",to:"",tot:"str"}],
24
+ validate: function(rules, opt) {
25
+ let msg;
26
+ const errors = []
27
+ if (!rules || rules.length === 0) { return true }
28
+ for (var i=0;i<rules.length;i++) {
29
+ const opt = { label: RED._('node-red:change.label.rule')+' '+(i+1) }
30
+ const r = rules[i];
31
+ if (r.t === 'set' || r.t === 'change' || r.t === 'delete' || r.t === 'move') {
32
+ if ((msg = RED.utils.validateTypedProperty(r.p,r.pt,opt)) !== true) {
33
+ errors.push(msg)
34
+ }
35
+ }
36
+ if (r.t === 'set' || r.t === 'change' || r.t === 'move') {
37
+ if ((msg = RED.utils.validateTypedProperty(r.to,r.tot,opt)) !== true) {
38
+ errors.push(msg)
39
+ }
40
+ }
41
+ if (r.t === 'change') {
42
+ if ((msg = RED.utils.validateTypedProperty(r.from,r.fromt,opt)) !== true) {
43
+ errors.push(msg)
44
+ }
45
+ }
46
+ }
47
+ if (errors.length) {
48
+ return errors
49
+ }
50
+ return true;
51
+ }
52
+ },
53
+ // legacy
54
+ action: {value:""},
55
+ property: {value:""},
56
+ from: {value:""},
57
+ to: {value:""},
58
+ reg: {value:false}
59
+ },
60
+ inputs: 1,
61
+ outputs: 1,
62
+ icon: "swap.svg",
63
+ label: function() {
64
+ function prop2name(type, key) {
65
+ var result = RED.utils.parseContextKey(key);
66
+ return type +"." +result.key;
67
+ }
68
+ if (this.name) {
69
+ return this.name;
70
+ }
71
+ if (!this.rules) {
72
+ if (this.action === "replace") {
73
+ return this._("change.label.set",{property:"msg."+this.property});
74
+ } else if (this.action === "change") {
75
+ return this._("change.label.change",{property:"msg."+this.property});
76
+ } else if (this.action === "move") {
77
+ return this._("change.label.move",{property:"msg."+this.property});
78
+ } else {
79
+ return this._("change.label.delete",{property:"msg."+this.property});
80
+ }
81
+ } else {
82
+ if (this.rules.length == 1) {
83
+ if (this.rules[0].t === "set") {
84
+ return this._("change.label.set",{property:prop2name((this.rules[0].pt||"msg"), this.rules[0].p)});
85
+ } else if (this.rules[0].t === "change") {
86
+ return this._("change.label.change",{property:prop2name((this.rules[0].pt||"msg"), this.rules[0].p)});
87
+ } else if (this.rules[0].t === "move") {
88
+ return this._("change.label.move",{property:prop2name((this.rules[0].pt||"msg"), this.rules[0].p)});
89
+ } else {
90
+ return this._("change.label.delete",{property:prop2name((this.rules[0].pt||"msg"), this.rules[0].p)});
91
+ }
92
+ } else {
93
+ return this._("change.label.changeCount",{count:this.rules.length});
94
+ }
95
+ }
96
+ },
97
+ labelStyle: function() {
98
+ return this.name ? "node_label_italic" : "";
99
+ },
100
+ oneditprepare: function() {
101
+ var set = this._("change.action.set");
102
+ var change = this._("change.action.change");
103
+ var del = this._("change.action.delete");
104
+ var move = this._("change.action.move");
105
+ var to = this._("change.action.to");
106
+ var toValueLabel = this._("change.action.toValue",to);
107
+ var search = this._("change.action.search");
108
+ var replace = this._("change.action.replace");
109
+ var regex = this._("change.label.regex");
110
+ var deepCopyLabel = this._("change.label.deepCopy");
111
+
112
+ function createPropertyValue(row2_1, row2_2, defaultType) {
113
+ var propValInput = $('<input/>',{class:"node-input-rule-property-value",type:"text"})
114
+ .appendTo(row2_1)
115
+ .typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','date','jsonata','env']});
116
+
117
+ var dcLabel = $('<label style="padding-left: 130px;"></label>').appendTo(row2_2);
118
+ var deepCopy = $('<input type="checkbox" class="node-input-rule-property-deepCopy" style="width: auto; margin: 0 6px 0 0">').appendTo(dcLabel)
119
+ $('<span>').text(deepCopyLabel).appendTo(dcLabel)
120
+
121
+ propValInput.on("change", function(evt,type,val) {
122
+ row2_2.toggle(type === "msg" || type === "flow" || type === "global" || type === "env");
123
+ })
124
+ return [propValInput, deepCopy];
125
+ }
126
+ function createFromValue(row3_1, defaultType) {
127
+ return $('<input/>',{class:"node-input-rule-property-search-value",type:"text"})
128
+ .appendTo(row3_1)
129
+ .typedInput({default:defaultType||'str',types:['msg','flow','global','str','re','num','bool','env']});
130
+ }
131
+ function createToValue(row3_2, defaultType) {
132
+ return $('<input/>',{class:"node-input-rule-property-replace-value",type:"text"})
133
+ .appendTo(row3_2)
134
+ .typedInput({default:defaultType||'str',types:['msg','flow','global','str','num','bool','json','bin','env']});
135
+ }
136
+ function createMoveValue(row4, defaultType) {
137
+ return $('<input/>',{class:"node-input-rule-property-move-value",type:"text"})
138
+ .appendTo(row4)
139
+ .typedInput({default:defaultType||'msg',types:['msg','flow','global']});
140
+ }
141
+
142
+ $('#node-input-rule-container').css('min-height','150px').css('min-width','450px').editableList({
143
+ addItem: function(container,i,opt) {
144
+ var rule = opt;
145
+ if (!rule.hasOwnProperty('t')) {
146
+ rule = {t:"set",p:"payload",to:"",tot:"str"};
147
+ }
148
+ if (rule.t === "change" && rule.re) {
149
+ rule.fromt = 're';
150
+ delete rule.re;
151
+ }
152
+ if (rule.t === "set" && !rule.tot) {
153
+ if (rule.to.indexOf("msg.") === 0 && !rule.tot) {
154
+ rule.to = rule.to.substring(4);
155
+ rule.tot = "msg";
156
+ } else {
157
+ rule.tot = "str";
158
+ }
159
+ }
160
+ if (rule.t === "move" && !rule.tot) {
161
+ rule.tot = "msg";
162
+ }
163
+ container.css({
164
+ overflow: 'hidden',
165
+ whiteSpace: 'nowrap'
166
+ });
167
+ let fragment = document.createDocumentFragment();
168
+ var row1 = $('<div/>',{style:"display:flex; align-items: baseline"}).appendTo(fragment);
169
+ var row2 = $('<div/>',{style:"margin-top:8px;"}).appendTo(fragment);
170
+ var row3 = $('<div/>',{style:"margin-top:8px;"}).appendTo(fragment);
171
+ var row4 = $('<div/>',{style:"display:flex;margin-top:8px;align-items: baseline"}).appendTo(fragment);
172
+
173
+ var selectField = $('<select/>',{class:"node-input-rule-type",style:"width:110px; margin-right:10px;"}).appendTo(row1);
174
+ var selectOptions = [{v:"set",l:set},{v:"change",l:change},{v:"delete",l:del},{v:"move",l:move}];
175
+ for (var i=0; i<4; i++) {
176
+ selectField.append($("<option></option>").val(selectOptions[i].v).text(selectOptions[i].l));
177
+ }
178
+
179
+ var propertyName = $('<input/>',{class:"node-input-rule-property-name",type:"text"})
180
+ .appendTo(row1)
181
+ .typedInput({types:['msg','flow','global']});
182
+
183
+ var row2_1 = $('<div/>', {style:"display:flex;align-items: baseline"}).appendTo(row2);
184
+ $('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
185
+ .text(toValueLabel)
186
+ .appendTo(row2_1);
187
+
188
+ var row2_2 = $('<div/>', {style:"margin-top: 4px;"}).appendTo(row2);
189
+
190
+ var row3_1 = $('<div/>', {style:"display:flex;align-items: baseline"}).appendTo(row3);
191
+ $('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
192
+ .text(search)
193
+ .appendTo(row3_1);
194
+
195
+ var row3_2 = $('<div/>',{style:"display:flex;margin-top:8px;align-items: baseline"}).appendTo(row3);
196
+ $('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
197
+ .text(replace)
198
+ .appendTo(row3_2);
199
+
200
+ $('<div/>',{style:"display:inline-block;text-align:right; width:120px; padding-right:10px; box-sizing:border-box;"})
201
+ .text(to)
202
+ .appendTo(row4);
203
+
204
+ let propertyValue = null;
205
+ let fromValue = null;
206
+ let toValue = null;
207
+ let moveValue = null;
208
+
209
+ selectField.on("change", function() {
210
+ var type = $(this).val();
211
+ if (propertyValue) {
212
+ propertyValue.typedInput('hide');
213
+ }
214
+ if (fromValue) {
215
+ fromValue.typedInput('hide');
216
+ }
217
+ if (toValue) {
218
+ toValue.typedInput('hide');
219
+ }
220
+ if (moveValue) {
221
+ moveValue.typedInput('hide');
222
+ }
223
+
224
+ if (type == "set") {
225
+ if(!propertyValue) {
226
+ var parts = createPropertyValue(row2_1, row2_2);
227
+ propertyValue = parts[0];
228
+ deepCopy = parts[1];
229
+ }
230
+ propertyValue.typedInput('show');
231
+ row2.show();
232
+ row3.hide();
233
+ row4.hide();
234
+ } else if (type == "change") {
235
+ if(!fromValue) {
236
+ fromValue = createFromValue(row3_1);
237
+ }
238
+ fromValue.typedInput('show');
239
+ if(!toValue) {
240
+ toValue = createToValue(row3_2);
241
+ }
242
+ toValue.typedInput('show');
243
+ row2.hide();
244
+ row3.show();
245
+ row4.hide();
246
+ } else if (type == "delete") {
247
+ row2.hide();
248
+ row3.hide();
249
+ row4.hide();
250
+ } else if (type == "move") {
251
+ if(!moveValue) {
252
+ moveValue = createMoveValue(row4);
253
+ }
254
+ moveValue.typedInput('show');
255
+ row2.hide();
256
+ row3.hide();
257
+ row4.show();
258
+ }
259
+ });
260
+
261
+ selectField.val(rule.t);
262
+ propertyName.typedInput('value',rule.p);
263
+ propertyName.typedInput('type',rule.pt);
264
+ if (rule.t == "set") {
265
+ var parts = createPropertyValue(row2_1, row2_2, rule.tot);
266
+ propertyValue = parts[0];
267
+ deepCopy = parts[1];
268
+ propertyValue.typedInput('value',rule.to);
269
+ deepCopy.prop("checked", !!rule.dc);
270
+ }
271
+ if (rule.t == "move") {
272
+ moveValue = createMoveValue(row4,rule.tot);
273
+ moveValue.typedInput('value',rule.to);
274
+ }
275
+ if (rule.t == "change") {
276
+ fromValue = createFromValue(row3_1, rule.fromt);
277
+ fromValue.typedInput('value',rule.from);
278
+
279
+ toValue = createToValue(row3_2,rule.tot);
280
+ toValue.typedInput('value',rule.to);
281
+ }
282
+ selectField.change();
283
+ container[0].appendChild(fragment);
284
+ },
285
+ removable: true,
286
+ sortable: true
287
+ });
288
+
289
+ if (!this.rules) {
290
+ var rule = {
291
+ t:(this.action=="replace"?"set":this.action),
292
+ p:this.property,
293
+ pt:"msg"
294
+ };
295
+
296
+ if ((rule.t === "set")||(rule.t === "move")) {
297
+ rule.to = this.to;
298
+ } else if (rule.t === "change") {
299
+ rule.from = this.from;
300
+ rule.to = this.to;
301
+ rule.re = this.reg;
302
+ }
303
+
304
+ delete this.to;
305
+ delete this.from;
306
+ delete this.reg;
307
+ delete this.action;
308
+ delete this.property;
309
+
310
+ this.rules = [rule];
311
+ }
312
+
313
+ for (var i=0; i<this.rules.length; i++) {
314
+ var rule = this.rules[i];
315
+ $("#node-input-rule-container").editableList('addItem',rule);
316
+ }
317
+ },
318
+ oneditsave: function() {
319
+ var rules = $("#node-input-rule-container").editableList('items');
320
+ var node = this;
321
+ node.rules= [];
322
+ rules.each(function(i) {
323
+ var rule = $(this);
324
+ var type = rule.find(".node-input-rule-type").val();
325
+ var r = {
326
+ t:type,
327
+ p:rule.find(".node-input-rule-property-name").typedInput('value'),
328
+ pt:rule.find(".node-input-rule-property-name").typedInput('type')
329
+ };
330
+ if (type === "set") {
331
+ r.to = rule.find(".node-input-rule-property-value").typedInput('value');
332
+ r.tot = rule.find(".node-input-rule-property-value").typedInput('type');
333
+ if (rule.find(".node-input-rule-property-deepCopy").prop("checked")) {
334
+ r.dc = true;
335
+ }
336
+ } else if (type === "move") {
337
+ r.to = rule.find(".node-input-rule-property-move-value").typedInput('value');
338
+ r.tot = rule.find(".node-input-rule-property-move-value").typedInput('type');
339
+ } else if (type === "change") {
340
+ r.from = rule.find(".node-input-rule-property-search-value").typedInput('value');
341
+ r.fromt = rule.find(".node-input-rule-property-search-value").typedInput('type');
342
+ r.to = rule.find(".node-input-rule-property-replace-value").typedInput('value');
343
+ r.tot = rule.find(".node-input-rule-property-replace-value").typedInput('type');
344
+ }
345
+ node.rules.push(r);
346
+ });
347
+ },
348
+ oneditresize: function(size) {
349
+ var rows = $("#dialog-form>div:not(.node-input-rule-container-row)");
350
+ var height = size.height;
351
+ for (var i=0; i<rows.length; i++) {
352
+ height -= $(rows[i]).outerHeight(true);
353
+ }
354
+ var editorRow = $("#dialog-form>div.node-input-rule-container-row");
355
+ height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
356
+ height += 16;
357
+ $("#node-input-rule-container").editableList('height',height);
358
+ }
359
+ });
360
+ })();
361
+ </script>
362
+
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Copyright JS Foundation and other contributors, http://js.foundation
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ **/
16
+
17
+ module.exports = function(RED) {
18
+ "use strict";
19
+ function RangeNode(n) {
20
+ RED.nodes.createNode(this, n);
21
+ this.action = n.action;
22
+ this.round = n.round || false;
23
+ this.minin = Number(n.minin);
24
+ this.maxin = Number(n.maxin);
25
+ this.minout = Number(n.minout);
26
+ this.maxout = Number(n.maxout);
27
+ this.property = n.property||"payload";
28
+ var node = this;
29
+
30
+ this.on('input', function (msg, send, done) {
31
+ var value = RED.util.getMessageProperty(msg,node.property);
32
+ if (value !== undefined) {
33
+ var n = Number(value);
34
+ if (!isNaN(n)) {
35
+ if (node.action === "drop") {
36
+ if (n < node.minin) { done(); return; }
37
+ if (n > node.maxin) { done(); return; }
38
+ }
39
+ if (node.action === "clamp") {
40
+ if (n < node.minin) { n = node.minin; }
41
+ if (n > node.maxin) { n = node.maxin; }
42
+ }
43
+ if (node.action === "roll") {
44
+ var divisor = node.maxin - node.minin;
45
+ n = ((n - node.minin) % divisor + divisor) % divisor + node.minin;
46
+ }
47
+ value = ((n - node.minin) / (node.maxin - node.minin) * (node.maxout - node.minout)) + node.minout;
48
+ if (node.round) { value = Math.round(value); }
49
+ RED.util.setMessageProperty(msg,node.property,value);
50
+ send(msg);
51
+ }
52
+ else { node.log(RED._("range.errors.notnumber")+": "+value); }
53
+ }
54
+ else { send(msg); } // If no payload - just pass it on.
55
+ done();
56
+ });
57
+ }
58
+ RED.nodes.registerType("range", RangeNode);
59
+ }
@@ -20,6 +20,7 @@ module.exports = function(RED) {
20
20
  var exec = require('child_process').exec;
21
21
  var fs = require('fs');
22
22
  var isUtf8 = require('is-utf8');
23
+ const isWindows = process.platform === 'win32'
23
24
 
24
25
  function ExecNode(n) {
25
26
  RED.nodes.createNode(this,n);
@@ -85,9 +86,12 @@ module.exports = function(RED) {
85
86
  }
86
87
  });
87
88
  var cmd = arg.shift();
89
+ // Since 18.20.2/20.12.2, it is invalid to call spawn on Windows with a .bat/.cmd file
90
+ // without using shell: true.
91
+ const opts = isWindows ? { ...node.spawnOpt, shell: true } : node.spawnOpt
88
92
  /* istanbul ignore else */
89
93
  node.debug(cmd+" ["+arg+"]");
90
- child = spawn(cmd,arg,node.spawnOpt);
94
+ child = spawn(cmd,arg,opts);
91
95
  node.status({fill:"blue",shape:"dot",text:"pid:"+child.pid});
92
96
  var unknownCommand = (child.pid === undefined);
93
97
  if (node.timer !== 0) {
@@ -103,7 +103,7 @@
103
103
  <h4>Automatic mode</h4>
104
104
  <p>Automatic mode uses the <code>parts</code> property of incoming messages to
105
105
  determine how the sequence should be joined. This allows it to automatically
106
- reverse the action of a <b>split</b> node.
106
+ reverse the action of a <b>split</b> node.</p>
107
107
 
108
108
  <h4>Manual mode</h4>
109
109
  <p>When configured to join in manual mode, the node is able to join sequences
@@ -0,0 +1,3 @@
1
+ <script type="text/html" data-help-name="global-config">
2
+ <p>Un noeud pour contenir la configuration globale des flux.</p>
3
+ </script>
@@ -94,6 +94,7 @@
94
94
  },
95
95
  "catch": {
96
96
  "catch": "catch : tout",
97
+ "catchGroup": "catch: groupe",
97
98
  "catchNodes": "catch : __number__",
98
99
  "catchUncaught": "catch : non capturé",
99
100
  "label": {
@@ -109,6 +110,7 @@
109
110
  },
110
111
  "status": {
111
112
  "status": "statut : tout",
113
+ "statusGroup": "statut: groupe",
112
114
  "statusNodes": "statut : __number__",
113
115
  "label": {
114
116
  "source": "Signaler l'état de",
@@ -250,7 +252,8 @@
250
252
  "initialize": "Au démarrage",
251
253
  "finalize": "À l'arrêt",
252
254
  "outputs": "Sorties",
253
- "modules": "Modules"
255
+ "modules": "Modules",
256
+ "timeout": "Délai d'attente"
254
257
  },
255
258
  "text": {
256
259
  "initialize": "// Le code ajouté ici sera exécuté une fois\n// à chaque démarrage du noeud.\n",
@@ -847,7 +850,13 @@
847
850
  "newline": "Nouvelle ligne",
848
851
  "usestrings": "Analyser les valeurs numériques",
849
852
  "include_empty_strings": "Inclure les chaînes vides",
850
- "include_null_values": "Inclure les valeurs nulles"
853
+ "include_null_values": "Inclure les valeurs nulles",
854
+ "spec": "Analyseur"
855
+ },
856
+ "spec": {
857
+ "rfc": "RFC4180",
858
+ "legacy": "Hérité (Legacy)",
859
+ "legacy_warning": "Le mode hérité sera supprimé dans une prochaine version."
851
860
  },
852
861
  "placeholder": {
853
862
  "columns": "noms de colonnes séparés par des virgules"
@@ -876,6 +885,7 @@
876
885
  "once": "envoyer les en-têtes une fois, jusqu'à msg.reset"
877
886
  },
878
887
  "errors": {
888
+ "bad_template": "Colonnes du modèle mal formées.",
879
889
  "csv_js": "Ce noeud ne gère que les chaînes CSV ou les objets js.",
880
890
  "obj_csv": "Aucun modèle de colonnes spécifié pour l'objet -> CSV.",
881
891
  "bad_csv": "Données CSV mal formées - sortie probablement corrompue."
@@ -885,12 +895,14 @@
885
895
  "label": {
886
896
  "select": "Sélecteur",
887
897
  "output": "Sortie",
888
- "in": "dans"
898
+ "in": "dans",
899
+ "prefix": "Nom de la propriété pour le contenu HTML"
889
900
  },
890
901
  "output": {
891
902
  "html": "le contenu html des éléments",
892
903
  "text": "uniquement le contenu textuel des éléments",
893
- "attr": "un objet de n'importe quel attribut des éléments"
904
+ "attr": "un objet de n'importe quel attribut des éléments",
905
+ "compl": "un objet pour tous les attributs de tous les éléments ainsi que du contenu HTML"
894
906
  },
895
907
  "format": {
896
908
  "single": "comme un seul message contenant un tableau",
@@ -30,6 +30,8 @@
30
30
  avant d'être envoyé.</p>
31
31
  <p>Si <code>msg._session</code> n'est pas présent, la charge utile est
32
32
  envoyé à <b>tous</b> les clients connectés.</p>
33
+ <p>En mode Répondre à, définir <code>msg.reset = true</code> réinitialisera la connexion
34
+ spécifiée par _session.id ou toutes les connexions si aucun _session.id n'est spécifié.</p>
33
35
  <p><b>Remarque</b> : Sur certains systèmes, vous aurez peut-être besoin d'un accès root ou administrateur
34
36
  pour accéder aux ports inférieurs à 1024.</p>
35
37
  </script>
@@ -40,6 +42,8 @@
40
42
  caractères renvoyés dans un tampon fixe, correspondant à un caractère spécifié avant de revenir,
41
43
  attendre un délai fixe à partir de la première réponse, puis revenir, s'installer et attender les données, ou envoie puis ferme la connexion
42
44
  immédiatement, sans attendre de réponse.</p>
45
+ <p>Dans le cas du mode veille (maintien de la connexion), vous pouvez envoyer <code>msg.reset = true</code> ou <code>msg.reset = "host:port"</code> pour forcer une interruption
46
+ de la connexion et une reconnexion automatique.</p>
43
47
  <p>La réponse sortira dans <code>msg.payload</code> en tant que tampon, vous pouvez alors utiliser la fonction .toString().</p>
44
48
  <p>Si vous laissez l'hôte ou le port tcp vide, ils doivent être définis à l'aide des propriétés <code>msg.host</code> et <code>msg.port</code> dans chaque message envoyé au noeud.</ p>
45
49
  </script>
@@ -36,7 +36,9 @@
36
36
  </dl>
37
37
  <h3>Détails</h3>
38
38
  <p>Le modèle de colonne peut contenir une liste ordonnée de noms de colonnes. Lors de la conversion de CSV en objet, les noms de colonne
39
- seront utilisés comme noms de propriété. Alternativement, les noms de colonne peuvent être tirés de la première ligne du CSV.</p>
39
+ seront utilisés comme noms de propriété. Alternativement, les noms de colonne peuvent être tirés de la première ligne du CSV.
40
+ <p>Lorsque l'analyseur RFC est sélectionné, le modèle de colonne doit être conforme à la norme RFC4180.</p>
41
+ </p>
40
42
  <p>Lors de la conversion au format CSV, le modèle de colonnes est utilisé pour identifier les propriétés à extraire de l'objet et dans quel ordre.</p>
41
43
  <p>Si le modèle de colonnes est vide, vous pouvez utiliser une simple liste de propriétés séparées par des virgules fournies dans <code>msg.columns</code> pour
42
44
  déterminer quoi extraire et dans quel ordre. Si ni l'un ni l'autre n'est présent, toutes les propriétés de l'objet sont sorties dans l'ordre
@@ -1,3 +1,3 @@
1
1
  <script type="text/html" data-help-name="global-config">
2
- <p>大域的なフローの設定を保持するノード。大域的な環境変数の定義を含みます。</p>
3
- </script>p
2
+ <p>大域的なフローの設定を保持するノード。グローバル環境変数の定義を含みます。</p>
3
+ </script>
@@ -850,7 +850,13 @@
850
850
  "newline": "改行コード",
851
851
  "usestrings": "数値を変換する",
852
852
  "include_empty_strings": "空の文字を含む",
853
- "include_null_values": "null値を含む"
853
+ "include_null_values": "null値を含む",
854
+ "spec": "パーサ"
855
+ },
856
+ "spec": {
857
+ "rfc": "RFC4180",
858
+ "legacy": "従来",
859
+ "legacy_warning": "従来モードは将来のリリースで削除される予定です"
854
860
  },
855
861
  "placeholder": {
856
862
  "columns": "コンマ区切りで列名を入力"
@@ -879,6 +885,7 @@
879
885
  "once": "ヘッダを一度だけ送信する(msg.resetの受け付けると再送)"
880
886
  },
881
887
  "errors": {
888
+ "bad_template": "不正な列テンプレート",
882
889
  "csv_js": "本ノードが処理できる形式は、CSV文字列またはJSONのみです",
883
890
  "obj_csv": "オブジェクトをCSVへ変換する際の列名が設定されていません",
884
891
  "bad_csv": "不正なCSVデータ - 出力の修正を試みました"
@@ -888,12 +895,14 @@
888
895
  "label": {
889
896
  "select": "抽出する要素",
890
897
  "output": "出力",
891
- "in": "対象:"
898
+ "in": "対象:",
899
+ "prefix": "HTMLコンテンツのプロパティ名"
892
900
  },
893
901
  "output": {
894
902
  "html": "要素内のHTML",
895
903
  "text": "要素のテキストのみ",
896
- "attr": "要素の全ての属性"
904
+ "attr": "要素の全ての属性",
905
+ "compl": "要素やHTMLコンテンツの属性オブジェクト"
897
906
  },
898
907
  "format": {
899
908
  "single": "配列化した1つのメッセージ",
@@ -24,12 +24,14 @@
24
24
  <p><code>msg.payload</code>のみが送信対象となります。</p>
25
25
  <p><code>msg.payload</code>がバイナリデータをBase64エンコーディングの文字列に変換したものの場合、Base64デコードオプションを指定するとデータをバイナリに変換して送信します。</p>
26
26
  <p><code>msg._session</code>が存在しない場合、接続している<b>全ての</b>クライアントに送信します。</p>
27
+ <p>応答モードでは、<code>msg.reset = true</code>を設定すると_session.idで指定した接続がリセットされます。もし_session.idを指定しない場合は、全ての接続がリセットされます。</p>
27
28
  <p><b>注: </b>1024番より小さな番号のポートをアクセスするにはrootもしくはadministrator権限が必要なシステムもあります。</p>
28
29
  </script>
29
30
 
30
31
  <script type="text/html" data-help-name="tcp request">
31
32
  <p>シンプルなTCPリクエストノード。<code>msg.payload</code>をサーバのTCPポートに送信し、レスポンスを待ちます。</p>
32
33
  <p>サーバに接続、"リクエスト"送信、"レスポンス"受信を行います。固定長の文字数、指定文字へのマッチ、最初のリプライの到着から指定した時間待つ、データの到着待ち、データ送信を行いリプライを待たず接続を即時解除、などから動作を選択できます。</p>
34
+ <p>待機モード(接続を維持)の場合は、<code>msg.reset = true</code>または<code>msg.reset = "host:port"</code>を送信することで、強制的に接続を切断して、自動的に再接続することもできます。</p>
33
35
  <p>レスポンスはバッファ形式で<code>msg.payload</code>に出力されます。文字列として扱いには、.toString()を使用してください。</p>
34
36
  <p>TCPホストのポート番号設定を空にした場合、本ノードに送信される全てのメッセージにおいて<code>msg.host</code>および<code>msg.port</code>プロパティを設定しなくてはなりません。</p>
35
37
  </script>
@@ -34,7 +34,9 @@
34
34
  </dd>
35
35
  </dl>
36
36
  <h3>詳細</h3>
37
- <p>「列名」にカラム名のリストを指定することができます。CSVからオブジェクトに変換を行う際、カラム名をプロパティ名として使用します。「列名」の代わりに、CSVデータの1行目にカラム名を含めることもできます。</p>
37
+ <p>「列名」にカラム名のリストを指定することができます。CSVからオブジェクトに変換を行う際、カラム名をプロパティ名として使用します。「列名」の代わりに、CSVデータの1行目にカラム名を含めることもできます。
38
+ <p>RFCパーサが選択されている場合、列のテンプレートはRFC4180に準拠する必要があります。</p>
39
+ </p>
38
40
  <p>CSVへの変換を行う際には、オブジェクトから取り出すべきプロパティとその順序を「列名」を参照して決めます。</p>
39
41
  <p>列名がない場合、本ノードは<code>msg.columns</code>プロパティの単純なコンマ区切りリストを使用して、何をどの順序で抽出するかを決定します。もし存在しない場合、すべてのオブジェクトプロパティを見つけた順序で出力します。</p>
40
42
  <p>入力が配列の場合には、「列名」はカラム名を表す行の出力指定がされた場合だけ用います。</p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-red/nodes",
3
- "version": "4.0.0-beta.1",
3
+ "version": "4.0.0-beta.3",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",