@node-red/runtime 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.
package/lib/api/comms.js CHANGED
@@ -36,7 +36,7 @@ var connections = [];
36
36
  const events = require("@node-red/util").events;
37
37
 
38
38
  function handleCommsEvent(event) {
39
- publish(event.topic,event.data,event.retain);
39
+ publish(event.topic,event.data,event.retain,event.session,event.excludeSession);
40
40
  }
41
41
  function handleStatusEvent(event) {
42
42
  if (!event.status) {
@@ -74,13 +74,17 @@ function handleEventLog(event) {
74
74
  publish("event-log/"+event.id,event.payload||{});
75
75
  }
76
76
 
77
- function publish(topic,data,retain) {
77
+ function publish(topic, data, retain, session, excludeSession) {
78
78
  if (retain) {
79
79
  retained[topic] = data;
80
80
  } else {
81
81
  delete retained[topic];
82
82
  }
83
- connections.forEach(connection => connection.send(topic,data))
83
+ connections.forEach(connection => {
84
+ if ((!session || connection.session === session) && (!excludeSession || connection.session !== excludeSession)) {
85
+ connection.send(topic,data)
86
+ }
87
+ })
84
88
  }
85
89
 
86
90
 
@@ -109,6 +113,10 @@ var api = module.exports = {
109
113
  */
110
114
  addConnection: async function(opts) {
111
115
  connections.push(opts.client);
116
+ events.emit('comms:connection-added', {
117
+ session: opts.client.session,
118
+ user: opts.client.user
119
+ })
112
120
  },
113
121
 
114
122
  /**
@@ -126,6 +134,9 @@ var api = module.exports = {
126
134
  break;
127
135
  }
128
136
  }
137
+ events.emit('comms:connection-removed', {
138
+ session: opts.client.session
139
+ })
129
140
  },
130
141
 
131
142
  /**
@@ -157,5 +168,23 @@ var api = module.exports = {
157
168
  * @return {Promise<Object>} - resolves when complete
158
169
  * @memberof @node-red/runtime_comms
159
170
  */
160
- unsubscribe: async function(opts) {}
171
+ unsubscribe: async function(opts) {},
172
+
173
+ /**
174
+ * @param {Object} opts
175
+ * @param {User} opts.user - the user calling the api
176
+ * @param {CommsConnection} opts.client - the client connection
177
+ * @param {String} opts.topic - the message topic
178
+ * @param {String} opts.data - the message data
179
+ * @return {Promise<Object>} - resolves when complete
180
+ */
181
+ receive: async function (opts) {
182
+ if (opts.topic) {
183
+ events.emit('comms:message:' + opts.topic, {
184
+ session: opts.client.session,
185
+ user: opts.user,
186
+ data: opts.data
187
+ })
188
+ }
189
+ }
161
190
  };
@@ -65,6 +65,25 @@ var api = module.exports = {
65
65
  runtime.log.audit({event: "plugins.configs.get"}, opts.req);
66
66
  return runtime.plugins.getPluginConfigs(opts.lang);
67
67
  },
68
+
69
+ /**
70
+ * Gets the editor content for one registered plugin
71
+ * @param {Object} opts
72
+ * @param {User} opts.user - the user calling the api
73
+ * @param {User} opts.user - the user calling the api
74
+ * @param {Object} opts.req - the request to log (optional)
75
+ * @return {Promise<NodeInfo>} - the plugin information
76
+ * @memberof @node-red/runtime_plugins
77
+ */
78
+ getPluginConfig: async function(opts) {
79
+ if (/[^0-9a-z=\-\*]/i.test(opts.lang)) {
80
+ throw new Error("Invalid language: "+opts.lang)
81
+ return;
82
+ }
83
+ runtime.log.audit({event: "plugins.configs.get"}, opts.req);
84
+ return runtime.plugins.getPluginConfig(opts.module, opts.lang);
85
+ },
86
+
68
87
  /**
69
88
  * Gets all registered module message catalogs
70
89
  * @param {Object} opts
package/lib/flows/Flow.js CHANGED
@@ -678,6 +678,9 @@ class Flow {
678
678
  if (logMessage.hasOwnProperty('stack')) {
679
679
  errorMessage.error.stack = logMessage.stack;
680
680
  }
681
+ if (logMessage.hasOwnProperty('cause')) {
682
+ errorMessage.error.cause = logMessage.cause;
683
+ }
681
684
  targetCatchNode.receive(errorMessage);
682
685
  handled = true;
683
686
  });
@@ -15,6 +15,7 @@
15
15
  **/
16
16
 
17
17
  const clone = require("clone");
18
+ const jsonClone = require("rfdc")();
18
19
  const Flow = require('./Flow').Flow;
19
20
  const context = require('../nodes/context');
20
21
  const util = require("util");
@@ -108,7 +109,7 @@ class Subflow extends Flow {
108
109
  }
109
110
  }
110
111
 
111
- subflowInternalFlowConfig.subflows = clone(subflowDef.subflows || {});
112
+ subflowInternalFlowConfig.subflows = jsonClone(subflowDef.subflows || {});
112
113
 
113
114
  remapSubflowNodes(subflowInternalFlowConfig.configs,node_map);
114
115
  remapSubflowNodes(subflowInternalFlowConfig.nodes,node_map);
@@ -220,7 +221,7 @@ class Subflow extends Flow {
220
221
  }
221
222
  if (this.subflowDef.in) {
222
223
  subflowInstanceConfig.wires = this.subflowDef.in.map(function(n) { return n.wires.map(function(w) { return self.node_map[w.id].id;})})
223
- subflowInstanceConfig._originalWires = clone(subflowInstanceConfig.wires);
224
+ subflowInstanceConfig._originalWires = jsonClone(subflowInstanceConfig.wires);
224
225
  }
225
226
 
226
227
  this.node = new Node(subflowInstanceConfig);
@@ -244,14 +245,14 @@ class Subflow extends Flow {
244
245
  if (self.subflowDef.out) {
245
246
  var node,wires,i,j;
246
247
  // Restore the original wiring to the internal nodes
247
- subflowInstanceConfig.wires = clone(subflowInstanceConfig._originalWires);
248
+ subflowInstanceConfig.wires = jsonClone(subflowInstanceConfig._originalWires);
248
249
  for (i=0;i<self.subflowDef.out.length;i++) {
249
250
  wires = self.subflowDef.out[i].wires;
250
251
  for (j=0;j<wires.length;j++) {
251
252
  if (wires[j].id != self.subflowDef.id) {
252
253
  node = self.node_map[wires[j].id];
253
254
  if (node && node._originalWires) {
254
- node.wires = clone(node._originalWires);
255
+ node.wires = jsonClone(node._originalWires);
255
256
  }
256
257
  }
257
258
  }
@@ -300,7 +301,7 @@ class Subflow extends Flow {
300
301
  var node = self.node_map[wires[j].id];
301
302
  if (node) {
302
303
  if (!node._originalWires) {
303
- node._originalWires = clone(node.wires);
304
+ node._originalWires = jsonClone(node.wires);
304
305
  }
305
306
  node.wires[wires[j].port] = (node.wires[wires[j].port]||[]).concat(this.subflowInstance.wires[i]);
306
307
  } else {
@@ -323,7 +324,7 @@ class Subflow extends Flow {
323
324
  var node = self.node_map[wires[j].id];
324
325
  if (node) {
325
326
  if (!node._originalWires) {
326
- node._originalWires = clone(node.wires);
327
+ node._originalWires = jsonClone(node.wires);
327
328
  }
328
329
  node.wires[wires[j].port] = (node.wires[wires[j].port]||[]);
329
330
  node.wires[wires[j].port].push(subflowStatusId);
@@ -463,7 +464,7 @@ class Subflow extends Flow {
463
464
  * @return {[type]} [description]
464
465
  */
465
466
  function createNodeInSubflow(subflowInstanceId, def) {
466
- let node = clone(def);
467
+ let node = jsonClone(def);
467
468
  let nid = `${subflowInstanceId}-${node.id}` //redUtil.generateId();
468
469
  // console.log("Create Node In subflow",node._alias, "--->",nid, "(",node.type,")")
469
470
  // node_map[node.id] = node;
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  **/
16
16
 
17
- var clone = require("clone");
17
+ const jsonClone = require("rfdc")();
18
18
 
19
19
  var Flow = require('./Flow');
20
20
 
@@ -140,16 +140,16 @@ function setFlows(_config,_credentials,type,muteLog,forceStart,user) {
140
140
  if (type === "load") {
141
141
  isLoad = true;
142
142
  configSavePromise = loadFlows().then(function(_config) {
143
- config = clone(_config.flows);
144
- newFlowConfig = flowUtil.parseConfig(clone(config));
143
+ config = jsonClone(_config.flows);
144
+ newFlowConfig = flowUtil.parseConfig(jsonClone(config));
145
145
  type = "full";
146
146
  return _config.rev;
147
147
  });
148
148
  } else {
149
149
  // Clone the provided config so it can be manipulated
150
- config = clone(_config);
150
+ config = jsonClone(_config);
151
151
  // Parse the configuration
152
- newFlowConfig = flowUtil.parseConfig(clone(config));
152
+ newFlowConfig = flowUtil.parseConfig(jsonClone(config));
153
153
  // Generate a diff to identify what has changed
154
154
  diff = flowUtil.diffConfigs(activeFlowConfig,newFlowConfig);
155
155
 
@@ -609,7 +609,7 @@ async function addFlow(flow, user) {
609
609
  nodes.push(node);
610
610
  }
611
611
  }
612
- var newConfig = clone(activeConfig.flows);
612
+ var newConfig = jsonClone(activeConfig.flows);
613
613
  newConfig = newConfig.concat(nodes);
614
614
 
615
615
  return setFlows(newConfig, null, 'flows', true, null, user).then(function() {
@@ -650,7 +650,7 @@ function getFlow(id) {
650
650
  var nodeIds = Object.keys(flow.nodes);
651
651
  if (nodeIds.length > 0) {
652
652
  result.nodes = nodeIds.map(function(nodeId) {
653
- var node = clone(flow.nodes[nodeId]);
653
+ var node = jsonClone(flow.nodes[nodeId]);
654
654
  if (node.type === 'link out') {
655
655
  delete node.wires;
656
656
  }
@@ -662,7 +662,7 @@ function getFlow(id) {
662
662
  if (flow.configs) {
663
663
  var configIds = Object.keys(flow.configs);
664
664
  result.configs = configIds.map(function(configId) {
665
- const node = clone(flow.configs[configId]);
665
+ const node = jsonClone(flow.configs[configId]);
666
666
  delete node.credentials;
667
667
  return node
668
668
 
@@ -674,17 +674,17 @@ function getFlow(id) {
674
674
  if (flow.subflows) {
675
675
  var subflowIds = Object.keys(flow.subflows);
676
676
  result.subflows = subflowIds.map(function(subflowId) {
677
- var subflow = clone(flow.subflows[subflowId]);
677
+ var subflow = jsonClone(flow.subflows[subflowId]);
678
678
  var nodeIds = Object.keys(subflow.nodes);
679
679
  subflow.nodes = nodeIds.map(function(id) {
680
- const node = clone(subflow.nodes[id])
680
+ const node = jsonClone(subflow.nodes[id])
681
681
  delete node.credentials
682
682
  return node
683
683
  });
684
684
  if (subflow.configs) {
685
685
  var configIds = Object.keys(subflow.configs);
686
686
  subflow.configs = configIds.map(function(id) {
687
- const node = clone(subflow.configs[id])
687
+ const node = jsonClone(subflow.configs[id])
688
688
  delete node.credentials
689
689
  return node
690
690
  })
@@ -709,7 +709,7 @@ async function updateFlow(id,newFlow, user) {
709
709
  }
710
710
  label = activeFlowConfig.flows[id].label;
711
711
  }
712
- var newConfig = clone(activeConfig.flows);
712
+ var newConfig = jsonClone(activeConfig.flows);
713
713
  var nodes;
714
714
 
715
715
  if (id === 'global') {
@@ -779,7 +779,7 @@ async function removeFlow(id, user) {
779
779
  throw e;
780
780
  }
781
781
 
782
- var newConfig = clone(activeConfig.flows);
782
+ var newConfig = jsonClone(activeConfig.flows);
783
783
  newConfig = newConfig.filter(function(node) {
784
784
  return node.z !== id && node.id !== id;
785
785
  });
package/lib/flows/util.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  **/
16
- const clone = require("clone");
16
+ const jsonClone = require("rfdc")();
17
17
  const redUtil = require("@node-red/util").util;
18
18
  const Log = require("@node-red/util").log;
19
19
  const typeRegistry = require("@node-red/registry");
@@ -68,7 +68,7 @@ function mapEnvVarProperties(obj,prop,flow,config) {
68
68
  if (obj[prop][0] === "$" && (EnvVarPropertyRE_old.test(v) || EnvVarPropertyRE.test(v)) ) {
69
69
  const envVar = v.substring(2,v.length-1);
70
70
  const r = redUtil.getSetting(config, envVar, flow);
71
- if (r !== undefined && r !== '') {
71
+ if (r !== undefined) {
72
72
  obj[prop] = r
73
73
  }
74
74
  }
@@ -106,14 +106,22 @@ async function evaluateEnvProperties(flow, env, credentials) {
106
106
  result = { value: result, __clone__: true}
107
107
  }
108
108
  evaluatedEnv[name] = result
109
+ } else {
110
+ evaluatedEnv[name] = undefined
111
+ flow.error(`Error evaluating env property '${name}': ${err.toString()}`)
109
112
  }
110
113
  resolve()
111
114
  });
112
115
  }))
113
116
  } else {
114
- value = redUtil.evaluateNodeProperty(value, type, {_flow: flow}, null, null);
115
- if (typeof value === 'object') {
116
- value = { value: value, __clone__: true}
117
+ try {
118
+ value = redUtil.evaluateNodeProperty(value, type, {_flow: flow}, null, null);
119
+ if (typeof value === 'object') {
120
+ value = { value: value, __clone__: true}
121
+ }
122
+ } catch (err) {
123
+ value = undefined
124
+ flow.error(`Error evaluating env property '${name}': ${err.toString()}`)
117
125
  }
118
126
  }
119
127
  evaluatedEnv[name] = value
@@ -167,7 +175,7 @@ async function createNode(flow,config) {
167
175
  try {
168
176
  var nodeTypeConstructor = typeRegistry.get(type);
169
177
  if (typeof nodeTypeConstructor === "function") {
170
- var conf = clone(config);
178
+ var conf = jsonClone(config);
171
179
  delete conf.credentials;
172
180
  try {
173
181
  Object.defineProperty(conf,'_module', {value: typeRegistry.getNodeInfo(type), enumerable: false, writable: true })
@@ -194,8 +202,8 @@ async function createNode(flow,config) {
194
202
  var subflowInstanceConfig = subflowConfig.subflows[nodeTypeConstructor.subflow.id];
195
203
  delete subflowConfig.subflows[nodeTypeConstructor.subflow.id];
196
204
  subflowInstanceConfig.subflows = subflowConfig.subflows;
197
- var instanceConfig = clone(config);
198
- instanceConfig.env = clone(nodeTypeConstructor.subflow.env);
205
+ var instanceConfig = jsonClone(config);
206
+ instanceConfig.env = jsonClone(nodeTypeConstructor.subflow.env);
199
207
 
200
208
  instanceConfig.env = nodeTypeConstructor.subflow.env.map(nodeProp => {
201
209
  var nodePropType;
@@ -248,7 +256,7 @@ function parseConfig(config) {
248
256
  flow.missingTypes = [];
249
257
 
250
258
  config.forEach(function (n) {
251
- flow.allNodes[n.id] = clone(n);
259
+ flow.allNodes[n.id] = jsonClone(n);
252
260
  if (n.type === 'tab') {
253
261
  flow.flows[n.id] = n;
254
262
  flow.flows[n.id].subflows = {};
package/lib/index.js CHANGED
@@ -22,6 +22,7 @@ var storage = require("./storage");
22
22
  var library = require("./library");
23
23
  var plugins = require("./plugins");
24
24
  var settings = require("./settings");
25
+ const multiplayer = require("./multiplayer");
25
26
 
26
27
  var express = require("express");
27
28
  var path = require('path');
@@ -135,6 +136,7 @@ function start() {
135
136
  .then(function() { return storage.init(runtime)})
136
137
  .then(function() { return settings.load(storage)})
137
138
  .then(function() { return library.init(runtime)})
139
+ .then(function() { return multiplayer.init(runtime)})
138
140
  .then(function() {
139
141
  if (settings.available()) {
140
142
  if (settings.get('instanceId') === undefined) {
@@ -0,0 +1,119 @@
1
+ let runtime
2
+
3
+ /**
4
+ * Active sessions, mapped by multiplayer session ids
5
+ */
6
+ const sessions = new Map()
7
+
8
+ /**
9
+ * Active connections, mapping comms session to multiplayer session
10
+ */
11
+ const connections = new Map()
12
+
13
+
14
+ function getSessionsList() {
15
+ return Array.from(sessions.values()).filter(session => session.active)
16
+ }
17
+
18
+ module.exports = {
19
+ init: function(_runtime) {
20
+ runtime = _runtime
21
+ runtime.events.on('comms:connection-removed', (opts) => {
22
+ const existingSessionId = connections.get(opts.session)
23
+ if (existingSessionId) {
24
+ connections.delete(opts.session)
25
+ const session = sessions.get(existingSessionId)
26
+ session.active = false
27
+ session.idleTimeout = setTimeout(() => {
28
+ sessions.delete(existingSessionId)
29
+ }, 30000)
30
+ runtime.events.emit('comms', {
31
+ topic: "multiplayer/connection-removed",
32
+ data: { session: existingSessionId }
33
+ })
34
+ }
35
+ })
36
+ runtime.events.on('comms:message:multiplayer/connect', (opts) => {
37
+ let session
38
+ if (!sessions.has(opts.data.session)) {
39
+ // Brand new session
40
+ let user = opts.user
41
+ if (!user || user.anonymous) {
42
+ user = user || { anonymous: true }
43
+ user.username = `Anon ${Math.floor(Math.random()*100)}`
44
+ }
45
+ session = {
46
+ session: opts.data.session,
47
+ user,
48
+ active: true
49
+ }
50
+ sessions.set(opts.data.session, session)
51
+ connections.set(opts.session, opts.data.session)
52
+ runtime.log.trace(`multiplayer new session:${opts.data.session} user:${user.username}`)
53
+ } else {
54
+ // Reconnected connection - keep existing state
55
+ connections.set(opts.session, opts.data.session)
56
+ // const existingConnection = connections.get(opts.data.session)
57
+ session = sessions.get(opts.data.session)
58
+ session.active = true
59
+ runtime.log.trace(`multiplayer reconnected session:${opts.data.session} user:${session.user.username}`)
60
+ clearTimeout(session.idleTimeout)
61
+ }
62
+ // Tell existing sessions about the new connection
63
+ runtime.events.emit('comms', {
64
+ topic: "multiplayer/connection-added",
65
+ excludeSession: opts.session,
66
+ data: session
67
+ })
68
+
69
+ // Send init info to new connection
70
+ const initPacket = {
71
+ topic: "multiplayer/init",
72
+ data: { sessions: getSessionsList() },
73
+ session: opts.session
74
+ }
75
+ // console.log('<<', initPacket)
76
+ runtime.events.emit('comms', initPacket)
77
+ })
78
+ runtime.events.on('comms:message:multiplayer/disconnect', (opts) => {
79
+ const existingSessionId = connections.get(opts.session)
80
+ connections.delete(opts.session)
81
+ sessions.delete(existingSessionId)
82
+
83
+ runtime.events.emit('comms', {
84
+ topic: "multiplayer/connection-removed",
85
+ data: { session: existingSessionId, disconnected: true }
86
+ })
87
+ })
88
+ runtime.events.on('comms:message:multiplayer/location', (opts) => {
89
+ // console.log('>>>', opts.user, opts.data)
90
+
91
+ const sessionId = connections.get(opts.session)
92
+ const session = sessions.get(sessionId)
93
+
94
+ if (opts.user) {
95
+ if (session.user.anonymous !== opts.user.anonymous) {
96
+ session.user = opts.user
97
+ runtime.events.emit('comms', {
98
+ topic: 'multiplayer/connection-added',
99
+ excludeSession: opts.session,
100
+ data: session
101
+ })
102
+ }
103
+ }
104
+
105
+ session.location = opts.data
106
+
107
+ const payload = {
108
+ session: sessionId,
109
+ workspace: opts.data.workspace,
110
+ node: opts.data.node
111
+ }
112
+ runtime.events.emit('comms', {
113
+ topic: 'multiplayer/location',
114
+ data: payload,
115
+ excludeSession: opts.session
116
+ })
117
+ })
118
+ }
119
+ }
@@ -14,9 +14,8 @@
14
14
  * limitations under the License.
15
15
  **/
16
16
 
17
- var path = require("path");
18
- var fs = require("fs");
19
- var clone = require("clone");
17
+
18
+ const jsonClone = require("rfdc")();
20
19
  var util = require("util");
21
20
 
22
21
  var registry = require("@node-red/registry");
@@ -98,7 +97,7 @@ function createNode(node,def) {
98
97
  }
99
98
  var creds = credentials.get(id);
100
99
  if (creds) {
101
- creds = clone(creds);
100
+ creds = jsonClone(creds);
102
101
  //console.log("Attaching credentials to ",node.id);
103
102
  // allow $(foo) syntax to substitute env variables for credentials also...
104
103
  for (var p in creds) {
@@ -173,7 +172,11 @@ function installModule(module,version,url) {
173
172
  if (info.pending_version) {
174
173
  events.emit("runtime-event",{id:"node/upgraded",retain:false,payload:{module:info.name,version:info.pending_version}});
175
174
  } else {
176
- events.emit("runtime-event",{id:"node/added",retain:false,payload:info.nodes});
175
+ if (!info.nodes.length && info.plugins.length) {
176
+ events.emit("runtime-event",{id:"plugin/added",retain:false,payload:info.plugins});
177
+ } else {
178
+ events.emit("runtime-event",{id:"node/added",retain:false,payload:info.nodes});
179
+ }
177
180
  }
178
181
  return info;
179
182
  });
package/lib/plugins.js CHANGED
@@ -7,5 +7,6 @@ module.exports = {
7
7
  getPluginsByType: registry.getPluginsByType,
8
8
  getPluginList: registry.getPluginList,
9
9
  getPluginConfigs: registry.getPluginConfigs,
10
+ getPluginConfig: registry.getPluginConfig,
10
11
  exportPluginSettings: registry.exportPluginSettings
11
12
  }
@@ -242,7 +242,9 @@ function loadProject(name) {
242
242
 
243
243
  function getProject(user, name) {
244
244
  checkActiveProject(name);
245
- return Promise.resolve(activeProject.export());
245
+ return loadProject(name).then(function () {
246
+ return Promise.resolve(activeProject.export());
247
+ });
246
248
  }
247
249
 
248
250
  function deleteProject(user, name) {
@@ -56,7 +56,6 @@
56
56
  "refresh-interval": "Erneuerung der https-Einstellungen erfolgt alle __interval__ Stunden",
57
57
  "settings-refreshed": "https-Einstellungen wurden erneuert",
58
58
  "refresh-failed": "Erneuerung der https-Einstellungen fehlgeschlagen: __message__",
59
- "nodejs-version": "httpsRefreshInterval erfordert Node.js 11 oder höher",
60
59
  "function-required": "httpsRefreshInterval erfordert die https-Eigenschaft in Form einer Funktion"
61
60
  }
62
61
  },
@@ -25,6 +25,7 @@
25
25
  "removing-modules": "Removing modules from config",
26
26
  "added-types": "Added node types:",
27
27
  "removed-types": "Removed node types:",
28
+ "removed-plugins": "Removed plugins:",
28
29
  "install": {
29
30
  "invalid": "Invalid module name",
30
31
  "installing": "Installing module: __name__, version: __version__",
@@ -57,7 +58,6 @@
57
58
  "refresh-interval": "Refreshing https settings every __interval__ hours",
58
59
  "settings-refreshed": "Server https settings have been refreshed",
59
60
  "refresh-failed": "Failed to refresh https settings: __message__",
60
- "nodejs-version": "httpsRefreshInterval requires Node.js 11 or later",
61
61
  "function-required": "httpsRefreshInterval requires https property to be a function"
62
62
  }
63
63
  },
@@ -57,7 +57,6 @@
57
57
  "refresh-interval": "Actualizando la configuración HTTPS cada __interval__ horas",
58
58
  "settings-refreshed": "La configuración HTTPS del servidor se ha actualizado",
59
59
  "refresh-failed": "No se pudo actualizar la configuración HTTPS: __message__",
60
- "nodejs-version": "httpsRefreshInterval requiere Node.js 11 o superior",
61
60
  "function-required": "httpsRefreshInterval requiere que la propiedad HTTPS sea una función"
62
61
  }
63
62
  },
@@ -20,10 +20,12 @@
20
20
  "errors-help": "Exécuter avec -v pour plus de détails",
21
21
  "missing-modules": "Modules de noeud manquants :",
22
22
  "node-version-mismatch": "Le module de noeud ne peut pas être chargé sur cette version. Nécessite : __version__ ",
23
+ "set-has-no-types": "L'ensemble n'a aucun type. Nom : '__name__', module : '__module__', fichier : '__file__'",
23
24
  "type-already-registered": "'__type__' déjà enregistré par le module __module__",
24
25
  "removing-modules": "Suppression de modules de la configuration",
25
26
  "added-types": "Types de noeuds ajoutés :",
26
27
  "removed-types": "Types de noeuds supprimés :",
28
+ "removed-plugins": "Plugins supprimés :",
27
29
  "install": {
28
30
  "invalid": "Nom de module invalide",
29
31
  "installing": "Installation du module : __name__, version : __version__",
@@ -56,7 +58,6 @@
56
58
  "refresh-interval": "Actualisation des paramètres https toutes les __interval__ heures",
57
59
  "settings-refreshed": "Les paramètres https du serveur ont été actualisés",
58
60
  "refresh-failed": "Échec de l'actualisation des paramètres https : __message__",
59
- "nodejs-version": "httpsRefreshInterval nécessite Node.js 11 ou version ultérieure",
60
61
  "function-required": "httpsRefreshInterval nécessite que la propriété https soit une fonction"
61
62
  }
62
63
  },
@@ -134,7 +135,8 @@
134
135
  "flow": {
135
136
  "unknown-type": "Type inconnu : __type__",
136
137
  "missing-types": "Types manquants",
137
- "error-loop": "Le message a dépassé le nombre maximum de captures (catches)"
138
+ "error-loop": "Le message a dépassé le nombre maximum de captures (catches)",
139
+ "non-message-returned": "Le noeud a tenté d'envoyer un message du type __type__"
138
140
  },
139
141
  "index": {
140
142
  "unrecognised-id": "Identifiant non reconnu : __id__",
@@ -25,6 +25,7 @@
25
25
  "removing-modules": "設定からモジュールを削除します",
26
26
  "added-types": "追加したノード:",
27
27
  "removed-types": "削除したノード:",
28
+ "removed-plugins": "削除したプラグイン:",
28
29
  "install": {
29
30
  "invalid": "不正なモジュール名",
30
31
  "installing": "モジュール __name__, バージョン: __version__ をインストールします",
@@ -57,7 +58,6 @@
57
58
  "refresh-interval": "__interval__ 時間毎にhttps設定を更新します",
58
59
  "settings-refreshed": "サーバのhttps設定が更新されました",
59
60
  "refresh-failed": "https設定の更新で失敗しました: __message__",
60
- "nodejs-version": "httpsRefreshIntervalにはNode.js 11以降が必要です",
61
61
  "function-required": "httpsRefreshIntervalでは、httpsプロパティはfunctionである必要があります"
62
62
  }
63
63
  },
@@ -57,7 +57,6 @@
57
57
  "refresh-interval": "Atualizando as configurações de https a cada __interval__ hora(s)",
58
58
  "settings-refreshed": "As configurações https do servidor foram atualizadas",
59
59
  "refresh-failed": "Falha ao atualizar as configurações https: __message__",
60
- "nodejs-version": "httpsRefreshInterval requer Node.js 11 ou posterior",
61
60
  "function-required": "httpsRefreshInterval requer que a propriedade https seja uma função"
62
61
  }
63
62
  },
@@ -55,7 +55,6 @@
55
55
  "refresh-interval": "Обновление настроек https каждые __interval__ часов",
56
56
  "settings-refreshed": "Настройки сервера https обновлены",
57
57
  "refresh-failed": "Не удалось обновить настройки https: __message__",
58
- "nodejs-version": "httpsRefreshInterval требует Node.js 11 или выше",
59
58
  "function-required": "httpsRefreshInterval требует, чтобы свойство https было функцией"
60
59
  }
61
60
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-red/runtime",
3
- "version": "4.0.0-beta.1",
3
+ "version": "4.0.0-beta.3",
4
4
  "license": "Apache-2.0",
5
5
  "main": "./lib/index.js",
6
6
  "repository": {
@@ -16,12 +16,13 @@
16
16
  }
17
17
  ],
18
18
  "dependencies": {
19
- "@node-red/registry": "4.0.0-beta.1",
20
- "@node-red/util": "4.0.0-beta.1",
19
+ "@node-red/registry": "4.0.0-beta.3",
20
+ "@node-red/util": "4.0.0-beta.3",
21
21
  "async-mutex": "0.4.0",
22
22
  "clone": "2.1.2",
23
- "express": "4.18.2",
23
+ "express": "4.19.2",
24
24
  "fs-extra": "11.1.1",
25
- "json-stringify-safe": "5.0.1"
25
+ "json-stringify-safe": "5.0.1",
26
+ "rfdc": "^1.3.1"
26
27
  }
27
28
  }