@node-red/runtime 3.1.0-beta.3 → 3.1.0

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/lib/flows/Flow.js CHANGED
@@ -14,19 +14,20 @@
14
14
  * limitations under the License.
15
15
  **/
16
16
 
17
- var clone = require("clone");
18
- var redUtil = require("@node-red/util").util;
17
+ const clone = require("clone");
18
+ const redUtil = require("@node-red/util").util;
19
19
  const events = require("@node-red/util").events;
20
- var flowUtil = require("./util");
20
+ const flowUtil = require("./util");
21
21
  const context = require('../nodes/context');
22
22
  const hooks = require("@node-red/util").hooks;
23
23
  const credentials = require("../nodes/credentials");
24
24
 
25
- var Subflow;
26
- var Log;
25
+ let Subflow;
26
+ let Log;
27
+ let Group;
27
28
 
28
- var nodeCloseTimeout = 15000;
29
- var asyncMessageDelivery = true;
29
+ let nodeCloseTimeout = 15000;
30
+ let asyncMessageDelivery = true;
30
31
 
31
32
  /**
32
33
  * This class represents a flow within the runtime. It is responsible for
@@ -52,6 +53,8 @@ class Flow {
52
53
  this.isGlobalFlow = false;
53
54
  }
54
55
  this.id = this.flow.id || "global";
56
+ this.groups = {}
57
+ this.groupOrder = []
55
58
  this.activeNodes = {};
56
59
  this.subflowInstanceNodes = {};
57
60
  this.catchNodes = [];
@@ -59,6 +62,11 @@ class Flow {
59
62
  this.path = this.id;
60
63
  // Ensure a context exists for this flow
61
64
  this.context = context.getFlowContext(this.id,this.parent.id);
65
+
66
+ // env is an array of env definitions
67
+ // _env is an object for direct lookup of env name -> value
68
+ this.env = this.flow.env
69
+ this._env = {}
62
70
  }
63
71
 
64
72
  /**
@@ -136,7 +144,7 @@ class Flow {
136
144
  * @param {[type]} msg [description]
137
145
  * @return {[type]} [description]
138
146
  */
139
- start(diff) {
147
+ async start(diff) {
140
148
  this.trace("start "+this.TYPE+" ["+this.path+"]");
141
149
  var node;
142
150
  var newNode;
@@ -145,6 +153,52 @@ class Flow {
145
153
  this.statusNodes = [];
146
154
  this.completeNodeMap = {};
147
155
 
156
+
157
+ if (this.isGlobalFlow) {
158
+ // This is the global flow. It needs to go find the `global-config`
159
+ // node and extract any env properties from it
160
+ const configNodes = Object.keys(this.flow.configs);
161
+ for (let i = 0; i < configNodes.length; i++) {
162
+ const node = this.flow.configs[configNodes[i]]
163
+ if (node.type === 'global-config' && node.env) {
164
+ const nodeEnv = await flowUtil.evaluateEnvProperties(this, node.env, credentials.get(node.id))
165
+ this._env = { ...this._env, ...nodeEnv }
166
+ }
167
+ }
168
+ }
169
+
170
+ if (this.env) {
171
+ this._env = { ...this._env, ...await flowUtil.evaluateEnvProperties(this, this.env, credentials.get(this.id)) }
172
+ }
173
+
174
+ // Initialise the group objects. These must be done in the right order
175
+ // starting from outer-most to inner-most so that the parent hierarchy
176
+ // is maintained.
177
+ this.groups = {}
178
+ this.groupOrder = []
179
+ const groupIds = Object.keys(this.flow.groups || {})
180
+ while (groupIds.length > 0) {
181
+ const id = groupIds.shift()
182
+ const groupDef = this.flow.groups[id]
183
+ if (!groupDef.g || this.groups[groupDef.g]) {
184
+ // The parent of this group is available - either another group
185
+ // or the top-level flow (this)
186
+ const parent = this.groups[groupDef.g] || this
187
+ this.groups[groupDef.id] = new Group(parent, groupDef)
188
+ this.groupOrder.push(groupDef.id)
189
+ } else {
190
+ // Try again once we've processed the other groups
191
+ groupIds.push(id)
192
+ }
193
+ }
194
+
195
+ for (let i = 0; i < this.groupOrder.length; i++) {
196
+ // Start the groups in the right order so they
197
+ // can setup their env vars knowning their parent
198
+ // will have been started
199
+ await this.groups[this.groupOrder[i]].start()
200
+ }
201
+
148
202
  var configNodes = Object.keys(this.flow.configs);
149
203
  var configNodeAttempts = {};
150
204
  while (configNodes.length > 0) {
@@ -177,7 +231,7 @@ class Flow {
177
231
  }
178
232
  }
179
233
  if (readyToCreate) {
180
- newNode = flowUtil.createNode(this,node);
234
+ newNode = await flowUtil.createNode(this,node);
181
235
  if (newNode) {
182
236
  this.activeNodes[id] = newNode;
183
237
  }
@@ -203,7 +257,7 @@ class Flow {
203
257
  if (node.d !== true) {
204
258
  if (!node.subflow) {
205
259
  if (!this.activeNodes[id]) {
206
- newNode = flowUtil.createNode(this,node);
260
+ newNode = await flowUtil.createNode(this,node);
207
261
  if (newNode) {
208
262
  this.activeNodes[id] = newNode;
209
263
  }
@@ -221,7 +275,7 @@ class Flow {
221
275
  node
222
276
  );
223
277
  this.subflowInstanceNodes[id] = subflow;
224
- subflow.start();
278
+ await subflow.start();
225
279
  this.activeNodes[id] = subflow.node;
226
280
 
227
281
  // this.subflowInstanceNodes[id] = nodes.map(function(n) { return n.id});
@@ -404,8 +458,7 @@ class Flow {
404
458
  * @return {Node} group node
405
459
  */
406
460
  getGroupNode(id) {
407
- const groups = this.global.groups;
408
- return groups[id];
461
+ return this.groups[id];
409
462
  }
410
463
 
411
464
  /**
@@ -416,95 +469,8 @@ class Flow {
416
469
  return this.activeNodes;
417
470
  }
418
471
 
419
- /*!
420
- * Get value of environment variable defined in group node.
421
- * @param {String} group - group node
422
- * @param {String} name - name of variable
423
- * @return {Object} object containing the value in val property or null if not defined
424
- */
425
- getGroupEnvSetting(node, group, name) {
426
- if (group) {
427
- if (name === "NR_GROUP_NAME") {
428
- return [{
429
- val: group.name
430
- }, null];
431
- }
432
- if (name === "NR_GROUP_ID") {
433
- return [{
434
- val: group.id
435
- }, null];
436
- }
437
-
438
- if (group.credentials === undefined) {
439
- group.credentials = credentials.get(group.id) || {};
440
- }
441
- if (!name.startsWith("$parent.")) {
442
- if (group.env) {
443
- if (!group._env) {
444
- const envs = group.env;
445
- const entries = envs.map((env) => {
446
- if (env.type === "cred") {
447
- const cred = group.credentials;
448
- if (cred.hasOwnProperty(env.name)) {
449
- env.value = cred[env.name];
450
- }
451
- }
452
- return [env.name, env];
453
- });
454
- group._env = Object.fromEntries(entries);
455
- }
456
- const env = group._env[name];
457
- if (env) {
458
- let value = env.value;
459
- const type = env.type;
460
- if ((type !== "env") ||
461
- (value !== name)) {
462
- if (type === "env") {
463
- value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
464
- }
465
- if (type === "bool") {
466
- const val
467
- = ((value === "true") ||
468
- (value === true));
469
- return [{
470
- val: val
471
- }, null];
472
- }
473
- if (type === "cred") {
474
- return [{
475
- val: value
476
- }, null];
477
- }
478
- try {
479
- var val = redUtil.evaluateNodeProperty(value, type, node, null, null);
480
- return [{
481
- val: val
482
- }, null];
483
- }
484
- catch (e) {
485
- this.error(e);
486
- return [null, null];
487
- }
488
- }
489
- }
490
- }
491
- }
492
- else {
493
- name = name.substring(8);
494
- }
495
- if (group.g) {
496
- const parent = this.getGroupNode(group.g);
497
- return this.getGroupEnvSetting(node, parent, name);
498
- }
499
- }
500
- return [null, name];
501
- }
502
-
503
-
504
472
  /**
505
- * Get a flow setting value. This currently automatically defers to the parent
506
- * flow which, as defined in ./index.js returns `process.env[key]`.
507
- * This lays the groundwork for Subflow to have instance-specific settings
473
+ * Get a flow setting value.
508
474
  * @param {[type]} key [description]
509
475
  * @return {[type]} [description]
510
476
  */
@@ -516,54 +482,14 @@ class Flow {
516
482
  if (key === "NR_FLOW_ID") {
517
483
  return flow.id;
518
484
  }
519
- if (flow.credentials === undefined) {
520
- flow.credentials = credentials.get(flow.id) || {};
521
- }
522
- if (flow.env) {
523
- if (!key.startsWith("$parent.")) {
524
- if (!flow._env) {
525
- const envs = flow.env;
526
- const entries = envs.map((env) => {
527
- if (env.type === "cred") {
528
- const cred = flow.credentials;
529
- if (cred.hasOwnProperty(env.name)) {
530
- env.value = cred[env.name];
531
- }
532
- }
533
- return [env.name, env]
534
- });
535
- flow._env = Object.fromEntries(entries);
536
- }
537
- const env = flow._env[key];
538
- if (env) {
539
- let value = env.value;
540
- const type = env.type;
541
- if ((type !== "env") || (value !== key)) {
542
- if (type === "env") {
543
- value = value.replace(new RegExp("\\${"+key+"}","g"),"${$parent."+key+"}");
544
- }
545
- try {
546
- if (type === "bool") {
547
- const val = ((value === "true") ||
548
- (value === true));
549
- return val;
550
- }
551
- if (type === "cred") {
552
- return value;
553
- }
554
- var val = redUtil.evaluateNodeProperty(value, type, null, null, null);
555
- return val;
556
- }
557
- catch (e) {
558
- this.error(e);
559
- }
560
- }
561
- }
485
+ if (!key.startsWith("$parent.")) {
486
+ if (this._env.hasOwnProperty(key)) {
487
+ return this._env[key]
562
488
  }
563
- else {
489
+ } else {
564
490
  key = key.substring(8);
565
- }
566
491
  }
492
+ // Delegate to the parent flow.
567
493
  return this.parent.getSetting(key);
568
494
  }
569
495
 
@@ -601,10 +527,9 @@ class Flow {
601
527
  // Delegate status to any nodes using this config node
602
528
  for (let userNode in node.users) {
603
529
  if (node.users.hasOwnProperty(userNode)) {
604
- node.users[userNode]._flow.handleStatus(node,statusMessage,node.users[userNode],true);
530
+ handled = node.users[userNode]._flow.handleStatus(node,statusMessage,node.users[userNode],true) || handled;
605
531
  }
606
532
  }
607
- handled = true;
608
533
  } else {
609
534
  const candidateNodes = [];
610
535
  this.statusNodes.forEach(targetStatusNode => {
@@ -618,10 +543,10 @@ class Flow {
618
543
  let distance = 0
619
544
  if (reportingNode.g) {
620
545
  // Reporting node inside a group. Calculate the distance between it and the status node
621
- let containingGroup = this.global.groups[reportingNode.g]
546
+ let containingGroup = this.groups[reportingNode.g]
622
547
  while (containingGroup && containingGroup.id !== targetStatusNode.g) {
623
548
  distance++
624
- containingGroup = this.global.groups[containingGroup.g]
549
+ containingGroup = this.groups[containingGroup.g]
625
550
  }
626
551
  if (!containingGroup && targetStatusNode.g && targetStatusNode.scope === 'group') {
627
552
  // This status node is in a group, but not in the same hierachy
@@ -688,10 +613,9 @@ class Flow {
688
613
  // Delegate status to any nodes using this config node
689
614
  for (let userNode in node.users) {
690
615
  if (node.users.hasOwnProperty(userNode)) {
691
- node.users[userNode]._flow.handleError(node,logMessage,msg,node.users[userNode]);
616
+ handled = node.users[userNode]._flow.handleError(node,logMessage,msg,node.users[userNode]) || handled;
692
617
  }
693
618
  }
694
- handled = true;
695
619
  } else {
696
620
  const candidateNodes = [];
697
621
  this.catchNodes.forEach(targetCatchNode => {
@@ -706,10 +630,10 @@ class Flow {
706
630
  let distance = 0
707
631
  if (reportingNode.g) {
708
632
  // Reporting node inside a group. Calculate the distance between it and the catch node
709
- let containingGroup = this.global.groups[reportingNode.g]
633
+ let containingGroup = this.groups[reportingNode.g]
710
634
  while (containingGroup && containingGroup.id !== targetCatchNode.g) {
711
635
  distance++
712
- containingGroup = this.global.groups[containingGroup.g]
636
+ containingGroup = this.groups[containingGroup.g]
713
637
  }
714
638
  if (!containingGroup && targetCatchNode.g && targetCatchNode.scope === 'group') {
715
639
  // This catch node is in a group, but not in the same hierachy
@@ -859,7 +783,7 @@ function handlePreRoute(flow, sendEvent, reportError) {
859
783
  return;
860
784
  } else if (err !== false) {
861
785
  sendEvent.destination.node = flow.getNode(sendEvent.destination.id);
862
- if (sendEvent.destination.node) {
786
+ if (sendEvent.destination.node && typeof sendEvent.destination.node === 'object') {
863
787
  if (sendEvent.cloneMessage) {
864
788
  sendEvent.msg = redUtil.cloneMessage(sendEvent.msg);
865
789
  }
@@ -909,9 +833,10 @@ module.exports = {
909
833
  asyncMessageDelivery = !runtime.settings.runtimeSyncDelivery
910
834
  Log = runtime.log;
911
835
  Subflow = require("./Subflow");
836
+ Group = require("./Group").Group
912
837
  },
913
838
  create: function(parent,global,conf) {
914
- return new Flow(parent,global,conf);
839
+ return new Flow(parent,global,conf)
915
840
  },
916
841
  Flow: Flow
917
842
  }
@@ -0,0 +1,55 @@
1
+ const flowUtil = require("./util");
2
+ const credentials = require("../nodes/credentials");
3
+
4
+ /**
5
+ * This class represents a group within the runtime.
6
+ */
7
+ class Group {
8
+
9
+ /**
10
+ * Create a Group object.
11
+ * @param {[type]} parent The parent flow/group
12
+ * @param {[type]} groupDef This group's definition
13
+ */
14
+ constructor(parent, groupDef) {
15
+ this.TYPE = 'group'
16
+ this.name = groupDef.name
17
+ this.parent = parent
18
+ this.group = groupDef
19
+ this.id = this.group.id
20
+ this.g = this.group.g
21
+ this.env = this.group.env
22
+ this._env = {}
23
+ }
24
+
25
+ async start() {
26
+ if (this.env) {
27
+ this._env = await flowUtil.evaluateEnvProperties(this, this.env, credentials.get(this.id))
28
+ }
29
+ }
30
+ /**
31
+ * Get a group setting value.
32
+ * @param {[type]} key [description]
33
+ * @return {[type]} [description]
34
+ */
35
+ getSetting(key) {
36
+ if (key === "NR_GROUP_NAME") {
37
+ return this.name;
38
+ }
39
+ if (key === "NR_GROUP_ID") {
40
+ return this.id;
41
+ }
42
+ if (!key.startsWith("$parent.")) {
43
+ if (this._env.hasOwnProperty(key)) {
44
+ return this._env[key]
45
+ }
46
+ } else {
47
+ key = key.substring(8);
48
+ }
49
+ return this.parent.getSetting(key);
50
+ }
51
+ }
52
+
53
+ module.exports = {
54
+ Group
55
+ }
@@ -119,7 +119,7 @@ class Subflow extends Flow {
119
119
  this.templateCredentials = credentials.get(subflowDef.id) || {};
120
120
  this.instanceCredentials = credentials.get(id) || {};
121
121
 
122
- var env = [];
122
+ var env = {};
123
123
  if (this.subflowDef.env) {
124
124
  this.subflowDef.env.forEach(e => {
125
125
  env[e.name] = e;
@@ -145,7 +145,7 @@ class Subflow extends Flow {
145
145
  }
146
146
  });
147
147
  }
148
- this.env = env;
148
+ this.env = Object.values(env);
149
149
  }
150
150
 
151
151
  /**
@@ -156,7 +156,7 @@ class Subflow extends Flow {
156
156
  * @param {[type]} diff [description]
157
157
  * @return {[type]} [description]
158
158
  */
159
- start(diff) {
159
+ async start(diff) {
160
160
  var self = this;
161
161
  // Create a subflow node to accept inbound messages and route appropriately
162
162
  var Node = require("../nodes/Node");
@@ -310,7 +310,7 @@ class Subflow extends Flow {
310
310
  }
311
311
  }
312
312
  }
313
- super.start(diff);
313
+ return super.start(diff);
314
314
  }
315
315
 
316
316
  /**
@@ -335,68 +335,35 @@ class Subflow extends Flow {
335
335
  }
336
336
  /**
337
337
  * Get environment variable of subflow
338
- * @param {String} name name of env var
338
+ * @param {String} key name of env var
339
339
  * @return {Object} val value of env var
340
340
  */
341
- getSetting(name) {
342
- if (!/^\$parent\./.test(name)) {
343
- var env = this.env;
344
- if (env && env.hasOwnProperty(name)) {
345
- var val = env[name];
346
- // If this is an env type property we need to be careful not
347
- // to get into lookup loops.
348
- // 1. if the value to lookup is the same as this one, go straight to parent
349
- // 2. otherwise, check if it is a compound env var ("foo $(bar)")
350
- // and if so, substitute any instances of `name` with $parent.name
351
- // See https://github.com/node-red/node-red/issues/2099
352
- if (val.type !== 'env' || val.value !== name) {
353
- let value = val.value;
354
- var type = val.type;
355
- if (type === 'env') {
356
- value = value.replace(new RegExp("\\${"+name+"}","g"),"${$parent."+name+"}");
357
- }
358
- try {
359
- return evaluateInputValue(value, type, this.node);
360
- }
361
- catch (e) {
362
- this.error(e);
363
- return undefined;
364
- }
365
- } else {
366
- // This _is_ an env property pointing at itself - go to parent
367
- }
368
- }
369
- } else {
370
- // name starts $parent. ... so delegate to parent automatically
371
- name = name.substring(8);
372
- }
341
+ getSetting(key) {
373
342
  const node = this.subflowInstance;
374
343
  if (node) {
375
- if (name === "NR_NODE_NAME") {
344
+ if (key === "NR_NODE_NAME" || key === "NR_SUBFLOW_NAME") {
376
345
  return node.name;
377
346
  }
378
- if (name === "NR_NODE_ID") {
347
+ if (key === "NR_NODE_ID" || key === "NR_SUBFLOW_ID") {
379
348
  return node.id;
380
349
  }
381
- if (name === "NR_NODE_PATH") {
350
+ if (key === "NR_NODE_PATH" || key === "NR_SUBFLOW_PATH") {
382
351
  return node._path;
383
352
  }
384
353
  }
385
- if (node.g) {
386
- const group = this.getGroupNode(node.g);
387
- const [result, newName] = this.getGroupEnvSetting(node, group, name);
388
- if (result) {
389
- return result.val;
354
+ if (!key.startsWith("$parent.")) {
355
+ if (this._env.hasOwnProperty(key)) {
356
+ return this._env[key]
390
357
  }
391
- name = newName;
358
+ } else {
359
+ key = key.substring(8);
392
360
  }
393
-
394
- var parent = this.parent;
395
- if (parent) {
396
- var val = parent.getSetting(name);
397
- return val;
361
+ // Push the request up to the parent.
362
+ // Unlike a Flow, the parent of a Subflow could be a Group
363
+ if (node.g) {
364
+ return this.parent.getGroupNode(node.g).getSetting(key)
398
365
  }
399
- return undefined;
366
+ return this.parent.getSetting(key)
400
367
  }
401
368
 
402
369
  /**
@@ -512,7 +479,7 @@ function remapSubflowNodes(nodes,nodeMap) {
512
479
  }
513
480
  }
514
481
  }
515
- if ((node.type === 'complete' || node.type === 'catch' || node.type === 'status') && node.scope) {
482
+ if ((node.type === 'complete' || node.type === 'catch' || node.type === 'status') && Array.isArray(node.scope)) {
516
483
  node.scope = node.scope.map(function(id) {
517
484
  return nodeMap[id]?nodeMap[id].id:""
518
485
  })
@@ -271,6 +271,10 @@ function getFlows() {
271
271
 
272
272
  async function start(type,diff,muteLog,isDeploy) {
273
273
  type = type || "full";
274
+ if (diff && diff.globalConfigChanged) {
275
+ type = 'full'
276
+ }
277
+
274
278
  started = true;
275
279
  state = 'start'
276
280
  var i;
@@ -359,7 +363,7 @@ async function start(type,diff,muteLog,isDeploy) {
359
363
  if (activeFlowConfig.flows.hasOwnProperty(id)) {
360
364
  if (!activeFlowConfig.flows[id].disabled && !activeFlows[id]) {
361
365
  // This flow is not disabled, nor is it currently active, so create it
362
- activeFlows[id] = Flow.create(flowAPI,activeFlowConfig,activeFlowConfig.flows[id]);
366
+ activeFlows[id] = Flow.create(activeFlows['global'],activeFlowConfig,activeFlowConfig.flows[id]);
363
367
  log.debug("red/nodes/flows.start : starting flow : "+id);
364
368
  } else {
365
369
  log.debug("red/nodes/flows.start : not starting disabled flow : "+id);
@@ -379,7 +383,7 @@ async function start(type,diff,muteLog,isDeploy) {
379
383
  activeFlows[id].update(activeFlowConfig,activeFlowConfig.flows[id]);
380
384
  } else {
381
385
  // This flow didn't previously exist, so create it
382
- activeFlows[id] = Flow.create(flowAPI,activeFlowConfig,activeFlowConfig.flows[id]);
386
+ activeFlows[id] = Flow.create(activeFlows['global'],activeFlowConfig,activeFlowConfig.flows[id]);
383
387
  log.debug("red/nodes/flows.start : starting flow : "+id);
384
388
  }
385
389
  } else {
@@ -391,7 +395,7 @@ async function start(type,diff,muteLog,isDeploy) {
391
395
  for (id in activeFlows) {
392
396
  if (activeFlows.hasOwnProperty(id)) {
393
397
  try {
394
- activeFlows[id].start(diff);
398
+ await activeFlows[id].start(diff);
395
399
  // Create a map of node id to flow id and also a subflowInstance lookup map
396
400
  var activeNodes = activeFlows[id].getActiveNodes();
397
401
  Object.keys(activeNodes).forEach(function(nid) {
@@ -432,7 +436,8 @@ function stop(type,diff,muteLog,isDeploy) {
432
436
  changed:[],
433
437
  removed:[],
434
438
  rewired:[],
435
- linked:[]
439
+ linked:[],
440
+ flowChanged:[]
436
441
  };
437
442
  if (!muteLog) {
438
443
  if (type !== "full") {
@@ -441,6 +446,9 @@ function stop(type,diff,muteLog,isDeploy) {
441
446
  log.info(log._("nodes.flows.stopping-flows"));
442
447
  }
443
448
  }
449
+ if (diff.globalConfigChanged) {
450
+ type = 'full'
451
+ }
444
452
  started = false;
445
453
  state = 'stop'
446
454
  var promises = [];
@@ -464,7 +472,7 @@ function stop(type,diff,muteLog,isDeploy) {
464
472
 
465
473
  activeFlowIds.forEach(id => {
466
474
  if (activeFlows.hasOwnProperty(id)) {
467
- var flowStateChanged = diff && (diff.added.indexOf(id) !== -1 || diff.removed.indexOf(id) !== -1);
475
+ var flowStateChanged = diff && (diff.flowChanged.indexOf(id) !== -1 || diff.added.indexOf(id) !== -1 || diff.removed.indexOf(id) !== -1);
468
476
  log.debug("red/nodes/flows.stop : stopping flow : "+id);
469
477
  promises.push(activeFlows[id].stop(flowStateChanged?null:stopList,removedList));
470
478
  if (type === "full" || flowStateChanged || diff.removed.indexOf(id)!==-1) {
@@ -784,17 +792,6 @@ const flowAPI = {
784
792
  log: m => log.log(m)
785
793
  }
786
794
 
787
-
788
- function getGlobalConfig() {
789
- let gconf = null;
790
- eachNode((n) => {
791
- if (n.type === "global-config") {
792
- gconf = n;
793
- }
794
- });
795
- return gconf;
796
- }
797
-
798
795
  module.exports = {
799
796
  init: init,
800
797
 
@@ -807,10 +804,7 @@ module.exports = {
807
804
 
808
805
  get:getNode,
809
806
  eachNode: eachNode,
810
-
811
-
812
- getGlobalConfig: getGlobalConfig,
813
-
807
+
814
808
  /**
815
809
  * Gets the current flow configuration
816
810
  */