@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.
@@ -320,7 +320,7 @@
320
320
  }
321
321
  // but replace with repeat one if set to repeat
322
322
  if ((this.repeat && this.repeat != 0) || this.crontab) {
323
- suffix = " ↻";
323
+ suffix = "\t↻";
324
324
  }
325
325
  if (this.name) {
326
326
  return this.name+suffix;
@@ -109,9 +109,8 @@ module.exports = function(RED) {
109
109
  }
110
110
  const p = props.shift()
111
111
  const property = p.p;
112
- const value = p.v ? p.v : '';
113
- const valueType = p.vt ? p.vt : 'str';
114
-
112
+ const value = p.v !== undefined ? p.v : '';
113
+ const valueType = p.vt !== undefined ? p.vt : 'str';
115
114
  if (property) {
116
115
  if (valueType === "jsonata") {
117
116
  if (p.v) {
@@ -86,7 +86,7 @@
86
86
  },
87
87
  label: function() {
88
88
  var suffix = "";
89
- if (this.console === true || this.console === "true") { suffix = " ⇲"; }
89
+ if (this.console === true || this.console === "true") { suffix = "\t⇲"; }
90
90
  if (this.targetType === "jsonata") {
91
91
  return (this.name || "JSONata") + suffix;
92
92
  }
@@ -195,6 +195,119 @@
195
195
  node.dirty = true;
196
196
  });
197
197
  RED.view.redraw();
198
+ },
199
+ requestDebugNodeList: function(filteredNodes) {
200
+ var workspaceOrder = RED.nodes.getWorkspaceOrder();
201
+ var workspaceOrderMap = {};
202
+ workspaceOrder.forEach(function(ws,i) {
203
+ workspaceOrderMap[ws] = i;
204
+ });
205
+
206
+ var candidateNodes = [];
207
+ var candidateSFs = [];
208
+ var subflows = {};
209
+ RED.nodes.eachNode(function (n) {
210
+ var nt = n.type;
211
+ if (nt === "debug") {
212
+ if (n.z in workspaceOrderMap) {
213
+ candidateNodes.push(n);
214
+ }
215
+ else {
216
+ var sf = RED.nodes.subflow(n.z);
217
+ if (sf) {
218
+ subflows[sf.id] = {
219
+ debug: true,
220
+ subflows: {}
221
+ };
222
+ }
223
+ }
224
+ }
225
+ else if(nt.substring(0, 8) === "subflow:") {
226
+ if (n.z in workspaceOrderMap) {
227
+ candidateSFs.push(n);
228
+ }
229
+ else {
230
+ var psf = RED.nodes.subflow(n.z);
231
+ if (psf) {
232
+ var sid = nt.substring(8);
233
+ var item = subflows[psf.id];
234
+ if (!item) {
235
+ item = {
236
+ debug: undefined,
237
+ subflows: {}
238
+ };
239
+ subflows[psf.id] = item;
240
+ }
241
+ item.subflows[sid] = true;
242
+ }
243
+ }
244
+ }
245
+ });
246
+ candidateSFs.forEach(function (sf) {
247
+ var sid = sf.type.substring(8);
248
+ if (containsDebug(sid, subflows)) {
249
+ candidateNodes.push(sf);
250
+ }
251
+ });
252
+
253
+ candidateNodes.sort(function(A,B) {
254
+ var wsA = workspaceOrderMap[A.z];
255
+ var wsB = workspaceOrderMap[B.z];
256
+ if (wsA !== wsB) {
257
+ return wsA-wsB;
258
+ }
259
+ var labelA = RED.utils.getNodeLabel(A,A.id);
260
+ var labelB = RED.utils.getNodeLabel(B,B.id);
261
+ return labelA.localeCompare(labelB);
262
+ });
263
+ var currentWs = null;
264
+ var data = [];
265
+ var currentFlow;
266
+ var currentSelectedCount = 0;
267
+ candidateNodes.forEach(function(node) {
268
+ if (currentWs !== node.z) {
269
+ if (currentFlow && currentFlow.checkbox) {
270
+ currentFlow.selected = currentSelectedCount === currentFlow.children.length
271
+ }
272
+ currentSelectedCount = 0;
273
+ currentWs = node.z;
274
+ var parent = RED.nodes.workspace(currentWs) || RED.nodes.subflow(currentWs);
275
+ currentFlow = {
276
+ label: RED.utils.getNodeLabel(parent, currentWs),
277
+ }
278
+ if (!parent.disabled) {
279
+ currentFlow.children = [];
280
+ currentFlow.checkbox = true;
281
+ } else {
282
+ currentFlow.class = "disabled"
283
+ }
284
+ data.push(currentFlow);
285
+ }
286
+ if (currentFlow.children) {
287
+ if (!filteredNodes[node.id]) {
288
+ currentSelectedCount++;
289
+ }
290
+ currentFlow.children.push({
291
+ label: RED.utils.getNodeLabel(node,node.id),
292
+ node: {
293
+ id: node.id
294
+ },
295
+ checkbox: true,
296
+ selected: !filteredNodes[node.id]
297
+ });
298
+ }
299
+ });
300
+ if (currentFlow && currentFlow.checkbox) {
301
+ currentFlow.selected = currentSelectedCount === currentFlow.children.length
302
+ }
303
+ if (subWindow) {
304
+ try {
305
+ subWindow.postMessage({event:"refreshDebugNodeList", nodes:data},"*");
306
+ } catch(err) {
307
+ console.log(err);
308
+ }
309
+ }
310
+ RED.debug.refreshDebugNodeList(data)
198
311
  }
199
312
  };
200
313
 
@@ -396,6 +509,26 @@
396
509
  }
397
510
  }
398
511
 
512
+ function containsDebug(sid, map) {
513
+ var item = map[sid];
514
+ if (item) {
515
+ if (item.debug === undefined) {
516
+ var sfs = Object.keys(item.subflows);
517
+ var contain = false;
518
+ for (var i = 0; i < sfs.length; i++) {
519
+ var sf = sfs[i];
520
+ if (containsDebug(sf, map)) {
521
+ contain = true;
522
+ break;
523
+ }
524
+ }
525
+ item.debug = contain;
526
+ }
527
+ return item.debug;
528
+ }
529
+ return false;
530
+ }
531
+
399
532
  $("#red-ui-sidebar-debug-open").on("click", function(e) {
400
533
  e.preventDefault();
401
534
  subWindow = window.open(document.location.toString().replace(/[?#].*$/,"")+"debug/view/view.html"+document.location.search,"nodeREDDebugView","menubar=no,location=no,toolbar=no,chrome,height=500,width=600");
@@ -427,6 +560,8 @@
427
560
  options.messageSourceClick(msg.id,msg._alias,msg.path);
428
561
  } else if (msg.event === "clear") {
429
562
  options.clear();
563
+ } else if (msg.event === "requestDebugNodeList") {
564
+ options.requestDebugNodeList(msg.filteredNodes)
430
565
  }
431
566
  };
432
567
  window.addEventListener('message',this.handleWindowMessage);
@@ -275,7 +275,7 @@
275
275
  value: [],
276
276
  type: "link in[]",
277
277
  validate: function (v, opt) {
278
- if ((this.linkType === "static" && v.length > 0)
278
+ if (((this.linkType || "static") === "static" && v.length > 0)
279
279
  || this.linkType === "dynamic") {
280
280
  return true;
281
281
  }
@@ -167,19 +167,13 @@ RED.debug = (function() {
167
167
  var menu = RED.popover.menu({
168
168
  options: options,
169
169
  onselect: function(item) {
170
- if (item.value !== filterType) {
171
- filterType = item.value;
172
- $('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
173
- refreshMessageList();
174
- RED.settings.set("debug.filter",filterType)
175
- }
170
+ setFilterType(item.value)
176
171
  if (filterType === 'filterSelected') {
177
- refreshDebugNodeList();
172
+ config.requestDebugNodeList(filteredNodes);
178
173
  filterDialog.slideDown(200);
179
174
  filterDialogShown = true;
180
175
  debugNodeTreeList.focus();
181
176
  }
182
-
183
177
  }
184
178
  });
185
179
  menu.show({
@@ -254,131 +248,7 @@ RED.debug = (function() {
254
248
 
255
249
  }
256
250
 
257
-
258
- function containsDebug(sid, map) {
259
- var item = map[sid];
260
- if (item) {
261
- if (item.debug === undefined) {
262
- var sfs = Object.keys(item.subflows);
263
- var contain = false;
264
- for (var i = 0; i < sfs.length; i++) {
265
- var sf = sfs[i];
266
- if (containsDebug(sf, map)) {
267
- contain = true;
268
- break;
269
- }
270
- }
271
- item.debug = contain;
272
- }
273
- return item.debug;
274
- }
275
- return false;
276
- }
277
-
278
-
279
- function refreshDebugNodeList() {
280
- var workspaceOrder = RED.nodes.getWorkspaceOrder();
281
- var workspaceOrderMap = {};
282
- workspaceOrder.forEach(function(ws,i) {
283
- workspaceOrderMap[ws] = i;
284
- });
285
-
286
- var candidateNodes = [];
287
- var candidateSFs = [];
288
- var subflows = {};
289
- RED.nodes.eachNode(function (n) {
290
- var nt = n.type;
291
- if (nt === "debug") {
292
- if (n.z in workspaceOrderMap) {
293
- candidateNodes.push(n);
294
- }
295
- else {
296
- var sf = RED.nodes.subflow(n.z);
297
- if (sf) {
298
- subflows[sf.id] = {
299
- debug: true,
300
- subflows: {}
301
- };
302
- }
303
- }
304
- }
305
- else if(nt.substring(0, 8) === "subflow:") {
306
- if (n.z in workspaceOrderMap) {
307
- candidateSFs.push(n);
308
- }
309
- else {
310
- var psf = RED.nodes.subflow(n.z);
311
- if (psf) {
312
- var sid = nt.substring(8);
313
- var item = subflows[psf.id];
314
- if (!item) {
315
- item = {
316
- debug: undefined,
317
- subflows: {}
318
- };
319
- subflows[psf.id] = item;
320
- }
321
- item.subflows[sid] = true;
322
- }
323
- }
324
- }
325
- });
326
- candidateSFs.forEach(function (sf) {
327
- var sid = sf.type.substring(8);
328
- if (containsDebug(sid, subflows)) {
329
- candidateNodes.push(sf);
330
- }
331
- });
332
-
333
- candidateNodes.sort(function(A,B) {
334
- var wsA = workspaceOrderMap[A.z];
335
- var wsB = workspaceOrderMap[B.z];
336
- if (wsA !== wsB) {
337
- return wsA-wsB;
338
- }
339
- var labelA = RED.utils.getNodeLabel(A,A.id);
340
- var labelB = RED.utils.getNodeLabel(B,B.id);
341
- return labelA.localeCompare(labelB);
342
- });
343
- var currentWs = null;
344
- var data = [];
345
- var currentFlow;
346
- var currentSelectedCount = 0;
347
- candidateNodes.forEach(function(node) {
348
- if (currentWs !== node.z) {
349
- if (currentFlow && currentFlow.checkbox) {
350
- currentFlow.selected = currentSelectedCount === currentFlow.children.length
351
- }
352
- currentSelectedCount = 0;
353
- currentWs = node.z;
354
- var parent = RED.nodes.workspace(currentWs) || RED.nodes.subflow(currentWs);
355
- currentFlow = {
356
- label: RED.utils.getNodeLabel(parent, currentWs),
357
- }
358
- if (!parent.disabled) {
359
- currentFlow.children = [];
360
- currentFlow.checkbox = true;
361
- } else {
362
- currentFlow.class = "disabled"
363
- }
364
- data.push(currentFlow);
365
- }
366
- if (currentFlow.children) {
367
- if (!filteredNodes[node.id]) {
368
- currentSelectedCount++;
369
- }
370
- currentFlow.children.push({
371
- label: RED.utils.getNodeLabel(node,node.id),
372
- node: node,
373
- checkbox: true,
374
- selected: !filteredNodes[node.id]
375
- });
376
- }
377
- });
378
- if (currentFlow && currentFlow.checkbox) {
379
- currentFlow.selected = currentSelectedCount === currentFlow.children.length
380
- }
381
-
251
+ function refreshDebugNodeList(data) {
382
252
  debugNodeTreeList.treeList("data", data);
383
253
  }
384
254
 
@@ -401,7 +271,7 @@ RED.debug = (function() {
401
271
  },200);
402
272
  }
403
273
  function _refreshMessageList(_activeWorkspace) {
404
- if (_activeWorkspace) {
274
+ if (typeof _activeWorkspace === 'string') {
405
275
  activeWorkspace = _activeWorkspace.replace(/\./g,"_");
406
276
  }
407
277
  if (filterType === "filterAll") {
@@ -479,12 +349,12 @@ RED.debug = (function() {
479
349
  filteredNodes[n.id] = true;
480
350
  });
481
351
  delete filteredNodes[sourceId];
482
- $("#red-ui-sidebar-debug-filterSelected").trigger("click");
483
352
  RED.settings.set('debug.filteredNodes',Object.keys(filteredNodes))
353
+ setFilterType('filterSelected')
484
354
  refreshMessageList();
485
355
  }},
486
356
  {id:"red-ui-debug-msg-menu-item-clear-filter",label:RED._("node-red:debug.messageMenu.clearFilter"),onselect:function(){
487
- $("#red-ui-sidebar-debug-filterAll").trigger("click");
357
+ clearFilterSettings()
488
358
  refreshMessageList();
489
359
  }}
490
360
  );
@@ -713,9 +583,17 @@ RED.debug = (function() {
713
583
  if (!!clearFilter) {
714
584
  clearFilterSettings();
715
585
  }
716
- refreshDebugNodeList();
586
+ config.requestDebugNodeList(filteredNodes);
717
587
  }
718
588
 
589
+ function setFilterType(type) {
590
+ if (type !== filterType) {
591
+ filterType = type;
592
+ $('#red-ui-sidebar-debug-filter span').text(RED._('node-red:debug.sidebar.'+filterType));
593
+ refreshMessageList();
594
+ RED.settings.set("debug.filter",filterType)
595
+ }
596
+ }
719
597
  function clearFilterSettings() {
720
598
  filteredNodes = {};
721
599
  filterType = 'filterAll';
@@ -728,6 +606,7 @@ RED.debug = (function() {
728
606
  init: init,
729
607
  refreshMessageList:refreshMessageList,
730
608
  handleDebugMessage: handleDebugMessage,
731
- clearMessageList: clearMessageList
609
+ clearMessageList: clearMessageList,
610
+ refreshDebugNodeList: refreshDebugNodeList
732
611
  }
733
612
  })();
@@ -12,6 +12,9 @@ $(function() {
12
12
  },
13
13
  clear: function() {
14
14
  window.opener.postMessage({event:"clear"},'*');
15
+ },
16
+ requestDebugNodeList: function(filteredNodes) {
17
+ window.opener.postMessage({event: 'requestDebugNodeList', filteredNodes},'*')
15
18
  }
16
19
  }
17
20
 
@@ -26,6 +29,8 @@ $(function() {
26
29
  RED.debug.refreshMessageList(evt.data.activeWorkspace);
27
30
  } else if (evt.data.event === "projectChange") {
28
31
  RED.debug.clearMessageList(true);
32
+ } else if (evt.data.event === "refreshDebugNodeList") {
33
+ RED.debug.refreshDebugNodeList(evt.data.nodes)
29
34
  }
30
35
  },false);
31
36
  } catch(err) {
@@ -167,7 +167,33 @@
167
167
  label:RED._("node-red:common.label.payload"),
168
168
  validate: RED.validators.typedInput("propertyType", false)},
169
169
  propertyType: { value:"msg" },
170
- rules: {value:[{t:"eq", v:"", vt:"str"}]},
170
+ rules: {
171
+ value:[{t:"eq", v:"", vt:"str"}],
172
+ validate: function (rules, opt) {
173
+ let msg;
174
+ const errors = []
175
+ if (!rules || rules.length === 0) { return true }
176
+ for (var i=0;i<rules.length;i++) {
177
+ const opt = { label: RED._('node-red:switch.label.rule')+' '+(i+1) }
178
+ const r = rules[i];
179
+ if (r.hasOwnProperty('v')) {
180
+ if ((msg = RED.utils.validateTypedProperty(r.v,r.vt,opt)) !== true) {
181
+ errors.push(msg)
182
+ }
183
+ }
184
+ if (r.hasOwnProperty('v2')) {
185
+ if ((msg = RED.utils.validateTypedProperty(r.v2,r.v2t,opt)) !== true) {
186
+ errors.push(msg)
187
+ }
188
+ }
189
+ }
190
+ if (errors.length) {
191
+ console.log(errors)
192
+ return errors
193
+ }
194
+ return true;
195
+ }
196
+ },
171
197
  checkall: {value:"true", required:true},
172
198
  repair: {value:false},
173
199
  outputs: {value:1}
@@ -19,71 +19,42 @@
19
19
 
20
20
  <script type="text/javascript">
21
21
  (function() {
22
- function isInvalidProperty(v,vt) {
23
- if (/msg|flow|global/.test(vt)) {
24
- if (!RED.utils.validatePropertyExpression(v)) {
25
- return RED._("node-red:change.errors.invalid-prop", {
26
- property: v
27
- });
28
- }
29
- } else if (vt === "jsonata") {
30
- try{ jsonata(v); } catch(e) {
31
- return RED._("node-red:change.errors.invalid-expr", {
32
- error: e.message
33
- });
34
- }
35
- } else if (vt === "json") {
36
- try{ JSON.parse(v); } catch(e) {
37
- return RED._("node-red:change.errors.invalid-json-data", {
38
- error: e.message
39
- });
40
- }
41
- }
42
- return false;
43
- }
44
-
45
22
  RED.nodes.registerType('change', {
46
23
  color: "#E2D96E",
47
24
  category: 'function',
48
25
  defaults: {
49
26
  name: {value:""},
50
- rules:{value:[{t:"set",p:"payload",pt:"msg",to:"",tot:"str"}],validate: function(rules, opt) {
51
- var msg;
52
- if (!rules || rules.length === 0) { return true }
53
- for (var i=0;i<rules.length;i++) {
54
- var r = rules[i];
55
- if (r.t === 'set') {
56
- if (msg = isInvalidProperty(r.p,r.pt)) {
57
- return msg;
58
- }
59
- if (msg = isInvalidProperty(r.to,r.tot)) {
60
- return msg;
61
- }
62
- } else if (r.t === 'change') {
63
- if (msg = isInvalidProperty(r.p,r.pt)) {
64
- return msg;
65
- }
66
- if(msg = isInvalidProperty(r.from,r.fromt)) {
67
- return msg;
68
- }
69
- if(msg = isInvalidProperty(r.to,r.tot)) {
70
- return msg;
71
- }
72
- } else if (r.t === 'delete') {
73
- if (msg = isInvalidProperty(r.p,r.pt)) {
74
- return msg;
27
+ rules:{
28
+ value:[{t:"set",p:"payload",pt:"msg",to:"",tot:"str"}],
29
+ validate: function(rules, opt) {
30
+ let msg;
31
+ const errors = []
32
+ if (!rules || rules.length === 0) { return true }
33
+ for (var i=0;i<rules.length;i++) {
34
+ const opt = { label: RED._('node-red:change.label.rule')+' '+(i+1) }
35
+ const r = rules[i];
36
+ if (r.t === 'set' || r.t === 'change' || r.t === 'delete' || r.t === 'move') {
37
+ if ((msg = RED.utils.validateTypedProperty(r.p,r.pt,opt)) !== true) {
38
+ errors.push(msg)
39
+ }
75
40
  }
76
- } else if (r.t === 'move') {
77
- if (msg = isInvalidProperty(r.p,r.pt)) {
78
- return msg;
41
+ if (r.t === 'set' || r.t === 'change' || r.t === 'move') {
42
+ if ((msg = RED.utils.validateTypedProperty(r.to,r.tot,opt)) !== true) {
43
+ errors.push(msg)
44
+ }
79
45
  }
80
- if (msg = isInvalidProperty(r.to,r.tot)) {
81
- return msg;
46
+ if (r.t === 'change') {
47
+ if ((msg = RED.utils.validateTypedProperty(r.from,r.fromt,opt)) !== true) {
48
+ errors.push(msg)
49
+ }
82
50
  }
83
51
  }
52
+ if (errors.length) {
53
+ return errors
54
+ }
55
+ return true;
84
56
  }
85
- return true;
86
- }},
57
+ },
87
58
  // legacy
88
59
  action: {value:""},
89
60
  property: {value:""},
@@ -57,7 +57,12 @@
57
57
  action: {value:"scale"},
58
58
  round: {value:false},
59
59
  property: {value:"payload",required:true,
60
- label:RED._("node-red:common.label.property")},
60
+ label:RED._("node-red:common.label.property"),
61
+ validate: RED.validators.typedInput({ type: 'msg' })
62
+ },
63
+
64
+
65
+ // RED.validators.typedInput("propertyType", false)},
61
66
  name: {value:""}
62
67
  },
63
68
  inputs: 1,
@@ -153,7 +153,7 @@
153
153
  }
154
154
  var editorRow = $("#dialog-form>div.node-text-editor-row");
155
155
  height -= (parseInt(editorRow.css("marginTop"))+parseInt(editorRow.css("marginBottom")));
156
- $(".node-text-editor").css("height",height+"px");
156
+ $("#dialog-form .node-text-editor").css("height",height+"px");
157
157
  this.editor.resize();
158
158
  }
159
159
  });
@@ -284,7 +284,7 @@ module.exports = function(RED) {
284
284
  done();
285
285
  }
286
286
  }
287
- else {
287
+ else if (!msg.hasOwnProperty("reset")) {
288
288
  if (maxKeptMsgsCount(node) > 0) {
289
289
  if (node.intervalID === -1) {
290
290
  node.send(msg);
@@ -56,7 +56,7 @@
56
56
  color:"darksalmon",
57
57
  defaults: {
58
58
  command: {value:""},
59
- addpay: {value:""},
59
+ addpay: {value:"", validate: RED.validators.typedInput({ type: 'msg', allowBlank: true })},
60
60
  append: {value:""},
61
61
  useSpawn: {value:"false"},
62
62
  timer: {value:""},
@@ -56,9 +56,11 @@
56
56
  inout: {value:"out"},
57
57
  septopics: {value:true},
58
58
  property: {value:"payload", required:true,
59
- label:RED._("node-red:rbe.label.property")},
59
+ label:RED._("node-red:rbe.label.property"),
60
+ validate: RED.validators.typedInput({ type: 'msg' })},
60
61
  topi: {value:"topic", required:true,
61
- label:RED._("node-red:rbe.label.topic")}
62
+ label:RED._("node-red:rbe.label.topic"),
63
+ validate: RED.validators.typedInput({ type: 'msg' })}
62
64
  },
63
65
  inputs:1,
64
66
  outputs:1,