@node-red/nodes 3.1.0-beta.3 → 3.1.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,7 +41,9 @@
41
41
  if (this.name) {
42
42
  return this.name;
43
43
  }
44
- if (this.scope) {
44
+ if (this.scope === "group") {
45
+ return this._("catch.catchGroup");
46
+ } else if (Array.isArray(this.scope)) {
45
47
  return this._("catch.catchNodes",{number:this.scope.length});
46
48
  }
47
49
  return this.uncaught?this._("catch.catchUncaught"):this._("catch.catch")
@@ -33,7 +33,15 @@
33
33
  outputs:1,
34
34
  icon: "status.svg",
35
35
  label: function() {
36
- return this.name||(this.scope?this._("status.statusNodes",{number:this.scope.length}):this._("status.status"));
36
+ if (this.name) {
37
+ return this.name;
38
+ }
39
+ if (this.scope === "group") {
40
+ return this._("status.statusGroup");
41
+ } else if (Array.isArray(this.scope)) {
42
+ return this._("status.statusNodes",{number:this.scope.length});
43
+ }
44
+ return this._("status.status")
37
45
  },
38
46
  labelStyle: function() {
39
47
  return this.name?"node_label_italic":"";
@@ -28,7 +28,7 @@
28
28
  <input type="text" id="node-input-name" data-i18n="[placeholder]common.label.name">
29
29
  </div>
30
30
  <div class="form-row">
31
- <label for="node-input-timeout"><span data-i18n="exec.label.timeout"></span></label>
31
+ <label for="node-input-timeout"><i class="fa fa-clock-o"></i> <span data-i18n="exec.label.timeout"></span></label>
32
32
  <input type="text" id="node-input-timeout" placeholder="30" style="width: 70px; margin-right: 5px;"><span data-i18n="inject.seconds"></span>
33
33
  </div>
34
34
  <div class="form-row">
@@ -82,6 +82,11 @@
82
82
  <input id="node-input-outputs" style="width: 60px;" value="1">
83
83
  </div>
84
84
 
85
+ <div class="form-row">
86
+ <label for="node-input-timeout"><i class="fa fa-clock-o"></i> <span data-i18n="function.label.timeout"></span></label>
87
+ <input id="node-input-timeout" style="width: 60px;" data-i18n="[placeholder]join.seconds">
88
+ </div>
89
+
85
90
  <div class="form-row node-input-libs-row hide" style="margin-bottom: 0px;">
86
91
  <label><i class="fa fa-cubes"></i> <span data-i18n="function.label.modules"></span></label>
87
92
  </div>
@@ -360,6 +365,7 @@
360
365
  name: {value:"_DEFAULT_"},
361
366
  func: {value:"\nreturn msg;"},
362
367
  outputs: {value:1},
368
+ timeout:{value:0},
363
369
  noerr: {value:0,required:true,
364
370
  validate: function(v, opt) {
365
371
  if (!v) {
@@ -464,6 +470,26 @@
464
470
  }
465
471
  });
466
472
 
473
+ // 4294967 is max in node.js timeout.
474
+ $( "#node-input-timeout" ).spinner({
475
+ min: 0,
476
+ max: 4294967,
477
+ change: function(event, ui) {
478
+ var value = this.value;
479
+ if(value == ""){
480
+ value = 0;
481
+ }
482
+ else
483
+ {
484
+ value = parseInt(value);
485
+ }
486
+ value = isNaN(value) ? 1 : value;
487
+ value = Math.max(value, parseInt($(this).attr("aria-valuemin")));
488
+ value = Math.min(value, parseInt($(this).attr("aria-valuemax")));
489
+ if (value !== this.value) { $(this).spinner("value", value); }
490
+ }
491
+ });
492
+
467
493
  var buildEditor = function(id, stateId, focus, value, defaultValue, extraLibs, offset) {
468
494
  var editor = RED.editor.createEditor({
469
495
  id: id,
@@ -503,7 +529,7 @@
503
529
  editor:this.editor, // the field name the main text body goes to
504
530
  mode:"ace/mode/nrjavascript",
505
531
  fields:[
506
- 'name', 'outputs',
532
+ 'name', 'outputs', 'timeout',
507
533
  {
508
534
  name: 'initialize',
509
535
  get: function() {
@@ -96,6 +96,13 @@ module.exports = function(RED) {
96
96
  node.name = n.name;
97
97
  node.func = n.func;
98
98
  node.outputs = n.outputs;
99
+ node.timeout = n.timeout*1000;
100
+ if(node.timeout>0){
101
+ node.timeoutOptions = {
102
+ timeout:node.timeout,
103
+ breakOnSigint:true
104
+ }
105
+ }
99
106
  node.ini = n.initialize ? n.initialize.trim() : "";
100
107
  node.fin = n.finalize ? n.finalize.trim() : "";
101
108
  node.libs = n.libs || [];
@@ -362,6 +369,10 @@ module.exports = function(RED) {
362
369
  })(__initSend__);`;
363
370
  iniOpt = createVMOpt(node, " setup");
364
371
  iniScript = new vm.Script(iniText, iniOpt);
372
+ if(node.timeout>0){
373
+ iniOpt.timeout = node.timeout;
374
+ iniOpt.breakOnSigint = true;
375
+ }
365
376
  }
366
377
  node.script = vm.createScript(functionText, createVMOpt(node, ""));
367
378
  if (node.fin && (node.fin !== "")) {
@@ -385,6 +396,10 @@ module.exports = function(RED) {
385
396
  })();`;
386
397
  finOpt = createVMOpt(node, " cleanup");
387
398
  finScript = new vm.Script(finText, finOpt);
399
+ if(node.timeout>0){
400
+ finOpt.timeout = node.timeout;
401
+ finOpt.breakOnSigint = true;
402
+ }
388
403
  }
389
404
  var promise = Promise.resolve();
390
405
  if (iniScript) {
@@ -396,9 +411,12 @@ module.exports = function(RED) {
396
411
  var start = process.hrtime();
397
412
  context.msg = msg;
398
413
  context.__send__ = send;
399
- context.__done__ = done;
400
-
401
- node.script.runInContext(context);
414
+ context.__done__ = done;
415
+ var opts = {};
416
+ if (node.timeout>0){
417
+ opts = node.timeoutOptions;
418
+ }
419
+ node.script.runInContext(context,opts);
402
420
  context.results.then(function(results) {
403
421
  sendResults(node,send,msg._msgid,results,false);
404
422
  if (handleNodeDoneCall) {
@@ -103,6 +103,7 @@
103
103
  } else if (type === "istype") {
104
104
  r.v = rule.find(".node-input-rule-type-value").typedInput('type');
105
105
  r.vt = rule.find(".node-input-rule-type-value").typedInput('type');
106
+ r.vt = (r.vt === "number") ? "num" : "str";
106
107
  } else if (type === "jsonata_exp") {
107
108
  r.v = rule.find(".node-input-rule-exp-value").typedInput('value');
108
109
  r.vt = rule.find(".node-input-rule-exp-value").typedInput('type');
@@ -229,6 +229,7 @@ module.exports = function(RED) {
229
229
  node.on("input", function(msg, send, done) {
230
230
  if (!node.drop) {
231
231
  var m = RED.util.cloneMessage(msg);
232
+ delete m.flush;
232
233
  if (Object.keys(m).length > 1) {
233
234
  if (node.intervalID !== -1) {
234
235
  if (node.allowrate && m.hasOwnProperty("rate") && !isNaN(parseFloat(m.rate)) && node.rate !== m.rate) {
@@ -93,7 +93,7 @@
93
93
 
94
94
  <div class="form-row">
95
95
  <input type="checkbox" id="node-input-insecureHTTPParser" style="display: inline-block; width: auto; vertical-align: top;">
96
- <label for="node-input-insecureHTTPParser", style="width: auto;" data-i18n="httpin.insecureHTTPParser"></label>
96
+ <label for="node-input-insecureHTTPParser" style="width: auto;" data-i18n="httpin.insecureHTTPParser"></label>
97
97
  </div>
98
98
 
99
99
 
@@ -23,6 +23,8 @@ module.exports = async function(RED) {
23
23
  const { v4: uuid } = require('uuid');
24
24
  const crypto = require('crypto');
25
25
  const URL = require("url").URL
26
+ const http = require("http")
27
+ const https = require("https")
26
28
  var mustache = require("mustache");
27
29
  var querystring = require("querystring");
28
30
  var cookie = require("cookie");
@@ -65,16 +67,27 @@ in your Node-RED user directory (${RED.settings.userDir}).
65
67
  function HTTPRequest(n) {
66
68
  RED.nodes.createNode(this,n);
67
69
  checkNodeAgentPatch();
68
- var node = this;
69
- var nodeUrl = n.url;
70
- var isTemplatedUrl = (nodeUrl||"").indexOf("{{") != -1;
71
- var nodeMethod = n.method || "GET";
72
- var paytoqs = false;
73
- var paytobody = false;
74
- var redirectList = [];
75
- var sendErrorsToCatch = n.senderr;
70
+ const node = this;
71
+ const nodeUrl = n.url;
72
+ const isTemplatedUrl = (nodeUrl||"").indexOf("{{") != -1;
73
+ const nodeMethod = n.method || "GET";
74
+ let paytoqs = false;
75
+ let paytobody = false;
76
+ let redirectList = [];
77
+ const sendErrorsToCatch = n.senderr;
76
78
  node.headers = n.headers || [];
77
- var nodeHTTPPersistent = n["persist"];
79
+ const useKeepAlive = n["persist"];
80
+ let agents = null
81
+ if (useKeepAlive) {
82
+ agents = {
83
+ http: new http.Agent({ keepAlive: true }),
84
+ https: new https.Agent({ keepAlive: true })
85
+ }
86
+ node.on('close', function () {
87
+ agents.http.destroy()
88
+ agents.https.destroy()
89
+ })
90
+ }
78
91
  if (n.tls) {
79
92
  var tlsNode = RED.nodes.getNode(n.tls);
80
93
  }
@@ -560,12 +573,14 @@ in your Node-RED user directory (${RED.settings.userDir}).
560
573
  opts.agent = {
561
574
  http: new HttpProxyAgent(proxyOptions),
562
575
  https: new HttpsProxyAgent(proxyOptions)
563
- };
564
-
576
+ }
565
577
  } else {
566
578
  node.warn("Bad proxy url: "+ prox);
567
579
  }
568
580
  }
581
+ if (useKeepAlive && !opts.agent) {
582
+ opts.agent = agents
583
+ }
569
584
  if (tlsNode) {
570
585
  opts.https = {};
571
586
  tlsNode.addTLSOptions(opts.https);
@@ -629,6 +629,9 @@ module.exports = function(RED) {
629
629
  joinChar = node.joiner;
630
630
  if (n.count === "" && msg.hasOwnProperty('parts')) {
631
631
  targetCount = msg.parts.count || 0;
632
+ if (msg.parts.hasOwnProperty('id')) {
633
+ partId = msg.parts.id;
634
+ }
632
635
  }
633
636
  if (node.build === 'object') {
634
637
  propertyKey = RED.util.getMessageProperty(msg,node.key);
@@ -68,9 +68,12 @@ module.exports = function(RED) {
68
68
  node.error(err,msg);
69
69
  return done();
70
70
  } else {
71
- filename = value;
71
+ processMsg2(msg,nodeSend,value,done);
72
72
  }
73
73
  });
74
+ }
75
+
76
+ function processMsg2(msg,nodeSend,filename,done) {
74
77
  filename = filename || "";
75
78
  msg.filename = filename;
76
79
  var fullFilename = filename;
@@ -311,9 +314,12 @@ module.exports = function(RED) {
311
314
  node.error(err,msg);
312
315
  return done();
313
316
  } else {
314
- filename = (value || "").replace(/\t|\r|\n/g,'');
317
+ processMsg2(msg, nodeSend, (value || "").replace(/\t|\r|\n/g,''), nodeDone);
315
318
  }
316
319
  });
320
+ });
321
+
322
+ function processMsg2(msg, nodeSend, filename, nodeDone) {
317
323
  filename = filename || "";
318
324
  var fullFilename = filename;
319
325
  if (filename && RED.settings.fileWorkingDirectory && !path.isAbsolute(filename)) {
@@ -434,7 +440,8 @@ module.exports = function(RED) {
434
440
  nodeDone();
435
441
  });
436
442
  }
437
- });
443
+ }
444
+
438
445
  this.on('close', function() {
439
446
  node.status({});
440
447
  });
@@ -216,7 +216,8 @@
216
216
  "initialize": "Start",
217
217
  "finalize": "Stopp",
218
218
  "outputs": "Ausgänge",
219
- "modules": "Module"
219
+ "modules": "Module",
220
+ "timeout": "Timeout"
220
221
  },
221
222
  "text": {
222
223
  "initialize": "// Der Code hier wird ausgeführt,\n// wenn der Node gestartet wird\n",
@@ -36,5 +36,5 @@ greater than one day you should consider using a scheduler node that can cope wi
36
36
  <p><b>Note</b>: The <i>"Interval between times"</i> and <i>"at a specific time"</i> options use the standard cron system.
37
37
  This means that 20 minutes will be at the next hour, 20 minutes past and 40 minutes past - not in 20 minutes time.
38
38
  If you want every 20 minutes from now - use the <i>"interval"</i> option.</p>
39
- <p><b>Note</b>: To include a newline in a string you must use a Function node to create the payload.</p>
39
+ <p><b>Note</b>: To include a newline in a string you must use the Function or Template node to create the payload.</p>
40
40
  </script>
@@ -94,6 +94,7 @@
94
94
  },
95
95
  "catch": {
96
96
  "catch": "catch: all",
97
+ "catchGroup": "catch: group",
97
98
  "catchNodes": "catch: __number__",
98
99
  "catchUncaught": "catch: uncaught",
99
100
  "label": {
@@ -109,6 +110,7 @@
109
110
  },
110
111
  "status": {
111
112
  "status": "status: all",
113
+ "statusGroup": "status: group",
112
114
  "statusNodes": "status: __number__",
113
115
  "label": {
114
116
  "source": "Report status from",
@@ -250,7 +252,8 @@
250
252
  "initialize": "On Start",
251
253
  "finalize": "On Stop",
252
254
  "outputs": "Outputs",
253
- "modules": "Modules"
255
+ "modules": "Modules",
256
+ "timeout": "Timeout"
254
257
  },
255
258
  "text": {
256
259
  "initialize": "// Code added here will be run once\n// whenever the node is started.\n",
@@ -103,6 +103,7 @@
103
103
  },
104
104
  "scope": {
105
105
  "all": "tous les noeuds",
106
+ "group": "dans le même groupe",
106
107
  "selected": "noeuds sélectionnés"
107
108
  }
108
109
  },
@@ -115,6 +116,7 @@
115
116
  },
116
117
  "scope": {
117
118
  "all": "tous les noeuds",
119
+ "group": "dans le même groupe",
118
120
  "selected": "noeuds sélectionnés"
119
121
  }
120
122
  },
@@ -414,6 +416,7 @@
414
416
  "port": "Port",
415
417
  "keepalive": "Rester en vie",
416
418
  "cleansession": "Utiliser une session propre",
419
+ "autoUnsubscribe": "Se désabonner automatiquement lors de la déconnexion",
417
420
  "cleanstart": "Utiliser un démarrage propre",
418
421
  "use-tls": "Utiliser TLS",
419
422
  "tls-config": "Configuration TLS",
@@ -30,5 +30,5 @@
30
30
  <p>また、フロー開始の際に一度だけメッセージを送出させることもできます。</p>
31
31
  <p>「<i>時間間隔</i>」に指定可能な値の最大値は、約596時間(もしくは24日)です。一日より長い間隔を扱いたい場合は、電源停止や再起動にも対応可能なスケジューラノードの利用を検討すると良いでしょう。</p>
32
32
  <p><b>注</b>:「<i>指定した時間間隔、日時</i>」と「<i>指定した日時</i>」オプションは標準的なcronシステムを内部で利用します。したがって「20分」という指定は、その時点から20分後ではなく、毎時きっかり、20分、40分を意味します。現時刻から20分毎を指定するには「<i>指定した時間間隔</i>」オプションを用います。</p>
33
- <p><b>注</b>: 文字列に改行を含めたい場合は、functionノードを使ってペイロードを設定してください。</p>
33
+ <p><b>注</b>: 文字列に改行を含めたい場合は、functionノードまたはtemplateノードを使ってペイロードを設定してください。</p>
34
34
  </script>
@@ -94,6 +94,7 @@
94
94
  },
95
95
  "catch": {
96
96
  "catch": "catch: 全て",
97
+ "catchGroup": "catch: グループ",
97
98
  "catchNodes": "catch: __number__",
98
99
  "catchUncaught": "catch: 未補足",
99
100
  "label": {
@@ -103,11 +104,13 @@
103
104
  },
104
105
  "scope": {
105
106
  "all": "全てのノード",
107
+ "group": "同一グループ内",
106
108
  "selected": "選択したノード"
107
109
  }
108
110
  },
109
111
  "status": {
110
112
  "status": "status: 全て",
113
+ "statusGroup": "status: グループ",
111
114
  "statusNodes": "status: __number__",
112
115
  "label": {
113
116
  "source": "ステータス取得元",
@@ -115,6 +118,7 @@
115
118
  },
116
119
  "scope": {
117
120
  "all": "全てのノード",
121
+ "group": "同一グループ内",
118
122
  "selected": "選択したノード"
119
123
  }
120
124
  },
@@ -248,7 +252,8 @@
248
252
  "initialize": "初期化処理",
249
253
  "finalize": "終了処理",
250
254
  "outputs": "出力数",
251
- "modules": "モジュール"
255
+ "modules": "モジュール",
256
+ "timeout": "タイムアウト"
252
257
  },
253
258
  "text": {
254
259
  "initialize": "// ここに記述したコードは、ノードをデプロイした時に\n// 一度だけ実行されます。\n",
@@ -212,7 +212,8 @@
212
212
  "function": "Функция",
213
213
  "initialize": "Настройка",
214
214
  "finalize": "Закрытие",
215
- "outputs": "Выходы"
215
+ "outputs": "Выходы",
216
+ "timeout":"Время ожидания"
216
217
  },
217
218
  "text": {
218
219
  "initialize": "// Добавленный здесь код будет исполняться\n// однократно при развертывании узла.\n",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-red/nodes",
3
- "version": "3.1.0-beta.3",
3
+ "version": "3.1.0-beta.4",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",