@node-red/runtime 2.2.0 → 3.0.0-beta.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.
- package/lib/api/diagnostics.js +202 -0
- package/lib/api/index.js +2 -0
- package/lib/api/settings.js +7 -0
- package/lib/flows/Flow.js +1 -1
- package/lib/flows/util.js +6 -5
- package/lib/index.js +12 -3
- package/lib/nodes/Node.js +41 -19
- package/lib/nodes/credentials.js +9 -1
- package/locales/en-US/runtime.json +3 -1
- package/package.json +5 -5
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
const os = require('os');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
let runtime;
|
|
6
|
+
let isContainerCached;
|
|
7
|
+
let isWSLCached;
|
|
8
|
+
|
|
9
|
+
const isInWsl = () => {
|
|
10
|
+
if (isWSLCached === undefined) {
|
|
11
|
+
isWSLCached = getIsInWSL();
|
|
12
|
+
}
|
|
13
|
+
return isWSLCached;
|
|
14
|
+
function getIsInWSL() {
|
|
15
|
+
if (process.platform !== 'linux') {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
if (os.release().toLowerCase().includes('microsoft')) {
|
|
20
|
+
if (isInContainer()) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return true;
|
|
24
|
+
}
|
|
25
|
+
return fs.readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft') ? !isInContainer() : false;
|
|
26
|
+
} catch (_) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const isInContainer = () => {
|
|
33
|
+
if (isContainerCached === undefined) {
|
|
34
|
+
isContainerCached = hasDockerEnv() || hasDockerCGroup();
|
|
35
|
+
}
|
|
36
|
+
return isContainerCached;
|
|
37
|
+
function hasDockerEnv() {
|
|
38
|
+
try {
|
|
39
|
+
fs.statSync('/.dockerenv');
|
|
40
|
+
return true;
|
|
41
|
+
} catch {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function hasDockerCGroup() {
|
|
46
|
+
try {
|
|
47
|
+
const s = fs.readFileSync('/proc/self/cgroup', 'utf8');
|
|
48
|
+
if (s.includes('docker')) {
|
|
49
|
+
return "docker"
|
|
50
|
+
} else if (s.includes('kubepod')) {
|
|
51
|
+
return "kubepod"
|
|
52
|
+
} else if (s.includes('lxc')) {
|
|
53
|
+
return "lxc"
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function buildDiagnosticReport(scope, callback) {
|
|
62
|
+
const modules = {};
|
|
63
|
+
const nl = runtime.nodes.getNodeList();
|
|
64
|
+
for (let i = 0; i < nl.length; i++) {
|
|
65
|
+
if (modules[nl[i].module]) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
modules[nl[i].module] = nl[i].version
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const now = new Date();
|
|
72
|
+
const {locale, timeZone} = Intl.DateTimeFormat().resolvedOptions();
|
|
73
|
+
const report = {
|
|
74
|
+
report: "diagnostics",
|
|
75
|
+
scope: scope,
|
|
76
|
+
time: {
|
|
77
|
+
utc: now.toUTCString(),
|
|
78
|
+
local: now.toLocaleString(),
|
|
79
|
+
},
|
|
80
|
+
intl: {
|
|
81
|
+
locale, timeZone
|
|
82
|
+
},
|
|
83
|
+
nodejs: {
|
|
84
|
+
version: process.version,
|
|
85
|
+
arch: process.arch,
|
|
86
|
+
platform: process.platform,
|
|
87
|
+
memoryUsage: process.memoryUsage(),
|
|
88
|
+
},
|
|
89
|
+
os: {
|
|
90
|
+
containerised: isInContainer(),
|
|
91
|
+
wsl: isInWsl(),
|
|
92
|
+
totalmem: os.totalmem(),
|
|
93
|
+
freemem: os.freemem(),
|
|
94
|
+
arch: os.arch(),
|
|
95
|
+
loadavg: os.loadavg(),
|
|
96
|
+
platform: os.platform(),
|
|
97
|
+
release: os.release(),
|
|
98
|
+
type: os.type(),
|
|
99
|
+
uptime: os.uptime(),
|
|
100
|
+
version: os.version(),
|
|
101
|
+
},
|
|
102
|
+
runtime: {
|
|
103
|
+
isStarted: runtime.isStarted(),
|
|
104
|
+
modules: modules,
|
|
105
|
+
version: runtime.settings.version,
|
|
106
|
+
settings: {
|
|
107
|
+
available: runtime.settings.available(),
|
|
108
|
+
apiMaxLength: runtime.settings.apiMaxLength || "UNSET",
|
|
109
|
+
//coreNodesDir: runtime.settings.coreNodesDir,
|
|
110
|
+
disableEditor: runtime.settings.disableEditor,
|
|
111
|
+
contextStorage: listContextModules(),
|
|
112
|
+
debugMaxLength: runtime.settings.debugMaxLength || "UNSET",
|
|
113
|
+
editorTheme: runtime.settings.editorTheme || "UNSET",
|
|
114
|
+
flowFile: runtime.settings.flowFile || "UNSET",
|
|
115
|
+
mqttReconnectTime: runtime.settings.mqttReconnectTime || "UNSET",
|
|
116
|
+
serialReconnectTime: runtime.settings.serialReconnectTime || "UNSET",
|
|
117
|
+
|
|
118
|
+
adminAuth: runtime.settings.adminAuth ? "SET" : "UNSET",
|
|
119
|
+
|
|
120
|
+
httpAdminRoot: runtime.settings.httpAdminRoot || "UNSET",
|
|
121
|
+
httpAdminCors: runtime.settings.httpAdminCors ? "SET" : "UNSET",
|
|
122
|
+
httpNodeAuth: runtime.settings.httpNodeAuth ? "SET" : "UNSET",
|
|
123
|
+
|
|
124
|
+
httpNodeRoot: runtime.settings.httpNodeRoot || "UNSET",
|
|
125
|
+
httpNodeCors: runtime.settings.httpNodeCors ? "SET" : "UNSET",
|
|
126
|
+
|
|
127
|
+
httpStatic: runtime.settings.httpStatic ? "SET" : "UNSET",
|
|
128
|
+
httpStaticRoot: runtime.settings.httpStaticRoot || "UNSET",
|
|
129
|
+
httpStaticCors: runtime.settings.httpStaticCors ? "SET" : "UNSET",
|
|
130
|
+
|
|
131
|
+
uiHost: runtime.settings.uiHost ? "SET" : "UNSET",
|
|
132
|
+
uiPort: runtime.settings.uiPort ? "SET" : "UNSET",
|
|
133
|
+
userDir: runtime.settings.userDir ? "SET" : "UNSET",
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// if (scope == "admin") {
|
|
139
|
+
// const moreSettings = {
|
|
140
|
+
// adminAuth_type: (runtime.settings.adminAuth && runtime.settings.adminAuth.type) ? runtime.settings.adminAuth.type : "UNSET",
|
|
141
|
+
// httpAdminCors: runtime.settings.httpAdminCors ? runtime.settings.httpAdminCors : "UNSET",
|
|
142
|
+
// httpNodeCors: runtime.settings.httpNodeCors ? runtime.settings.httpNodeCors : "UNSET",
|
|
143
|
+
// httpStaticCors: runtime.settings.httpStaticCors ? "SET" : "UNSET",
|
|
144
|
+
// settingsFile: runtime.settings.settingsFile ? runtime.settings.settingsFile : "UNSET",
|
|
145
|
+
// uiHost: runtime.settings.uiHost ? runtime.settings.uiHost : "UNSET",
|
|
146
|
+
// uiPort: runtime.settings.uiPort ? runtime.settings.uiPort : "UNSET",
|
|
147
|
+
// userDir: runtime.settings.userDir ? runtime.settings.userDir : "UNSET",
|
|
148
|
+
// }
|
|
149
|
+
// const moreNodejs = {
|
|
150
|
+
// execPath: process.execPath,
|
|
151
|
+
// pid: process.pid,
|
|
152
|
+
// }
|
|
153
|
+
// const moreOs = {
|
|
154
|
+
// cpus: os.cpus(),
|
|
155
|
+
// homedir: os.homedir(),
|
|
156
|
+
// hostname: os.hostname(),
|
|
157
|
+
// networkInterfaces: os.networkInterfaces(),
|
|
158
|
+
// }
|
|
159
|
+
// report.runtime.settings = Object.assign({}, report.runtime.settings, moreSettings);
|
|
160
|
+
// report.nodejs = Object.assign({}, report.nodejs, moreNodejs);
|
|
161
|
+
// report.os = Object.assign({}, report.os, moreOs);
|
|
162
|
+
// }
|
|
163
|
+
|
|
164
|
+
callback(report);
|
|
165
|
+
|
|
166
|
+
/** gets a sanitised list containing only the module name */
|
|
167
|
+
function listContextModules() {
|
|
168
|
+
const keys = Object.keys(runtime.settings.contextStorage);
|
|
169
|
+
const result = {};
|
|
170
|
+
keys.forEach(e => {
|
|
171
|
+
result[e] = {
|
|
172
|
+
module: String(runtime.settings.contextStorage[e].module)
|
|
173
|
+
}
|
|
174
|
+
})
|
|
175
|
+
return result;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
module.exports = {
|
|
181
|
+
init: function (_runtime) {
|
|
182
|
+
runtime = _runtime;
|
|
183
|
+
},
|
|
184
|
+
/**
|
|
185
|
+
* Gets the node-red diagnostics report
|
|
186
|
+
* @param {{scope: string}} opts - settings
|
|
187
|
+
* @return {Promise} the diagnostics information
|
|
188
|
+
* @memberof @node-red/diagnostics
|
|
189
|
+
*/
|
|
190
|
+
get: async function (opts) {
|
|
191
|
+
return new Promise(function (resolve, reject) {
|
|
192
|
+
opts = opts || {}
|
|
193
|
+
try {
|
|
194
|
+
runtime.log.audit({ event: "diagnostics.get", scope: opts.scope }, opts.req);
|
|
195
|
+
buildDiagnosticReport(opts.scope, (report) => resolve(report));
|
|
196
|
+
} catch (error) {
|
|
197
|
+
error.status = 500;
|
|
198
|
+
reject(error);
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
},
|
|
202
|
+
}
|
package/lib/api/index.js
CHANGED
|
@@ -29,6 +29,7 @@ var api = module.exports = {
|
|
|
29
29
|
api.projects.init(runtime);
|
|
30
30
|
api.context.init(runtime);
|
|
31
31
|
api.plugins.init(runtime);
|
|
32
|
+
api.diagnostics.init(runtime);
|
|
32
33
|
},
|
|
33
34
|
|
|
34
35
|
comms: require("./comms"),
|
|
@@ -39,6 +40,7 @@ var api = module.exports = {
|
|
|
39
40
|
projects: require("./projects"),
|
|
40
41
|
context: require("./context"),
|
|
41
42
|
plugins: require("./plugins"),
|
|
43
|
+
diagnostics: require("./diagnostics"),
|
|
42
44
|
|
|
43
45
|
isStarted: async function(opts) {
|
|
44
46
|
return runtime.isStarted();
|
package/lib/api/settings.js
CHANGED
|
@@ -142,6 +142,13 @@ var api = module.exports = {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
safeSettings.flowEncryptionType = runtime.nodes.getCredentialKeyType();
|
|
145
|
+
|
|
146
|
+
safeSettings.diagnostics = {
|
|
147
|
+
//unless diagnostics.ui and diagnostics.enabled are explicitly false, they will default to true.
|
|
148
|
+
enabled: (runtime.settings.diagnostics && runtime.settings.diagnostics.enabled === false) ? false : true,
|
|
149
|
+
ui: (runtime.settings.diagnostics && runtime.settings.diagnostics.ui === false) ? false : true
|
|
150
|
+
}
|
|
151
|
+
|
|
145
152
|
runtime.settings.exportNodeSettings(safeSettings);
|
|
146
153
|
runtime.plugins.exportPluginSettings(safeSettings);
|
|
147
154
|
}
|
package/lib/flows/Flow.js
CHANGED
|
@@ -582,7 +582,7 @@ class Flow {
|
|
|
582
582
|
reportingNode = node;
|
|
583
583
|
}
|
|
584
584
|
if (!muteStatusEvent) {
|
|
585
|
-
if (statusMessage.hasOwnProperty("text") && typeof
|
|
585
|
+
if (statusMessage.hasOwnProperty("text") && typeof statusMessage.text !== "string") {
|
|
586
586
|
try {
|
|
587
587
|
statusMessage.text = statusMessage.text.toString();
|
|
588
588
|
}
|
package/lib/flows/util.js
CHANGED
|
@@ -77,15 +77,16 @@ function createNode(flow,config) {
|
|
|
77
77
|
if (typeof nodeTypeConstructor === "function") {
|
|
78
78
|
var conf = clone(config);
|
|
79
79
|
delete conf.credentials;
|
|
80
|
-
for (var p in conf) {
|
|
81
|
-
if (conf.hasOwnProperty(p)) {
|
|
82
|
-
mapEnvVarProperties(conf,p,flow,conf);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
80
|
try {
|
|
86
81
|
Object.defineProperty(conf,'_module', {value: typeRegistry.getNodeInfo(type), enumerable: false, writable: true })
|
|
87
82
|
Object.defineProperty(conf,'_flow', {value: flow, enumerable: false, writable: true })
|
|
88
83
|
Object.defineProperty(conf,'_path', {value: `${flow.path}/${config._alias||config.id}`, enumerable: false, writable: true })
|
|
84
|
+
|
|
85
|
+
for (var p in conf) {
|
|
86
|
+
if (conf.hasOwnProperty(p)) {
|
|
87
|
+
mapEnvVarProperties(conf,p,flow,conf);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
89
90
|
newNode = new nodeTypeConstructor(conf);
|
|
90
91
|
} catch (err) {
|
|
91
92
|
Log.log({
|
package/lib/index.js
CHANGED
|
@@ -207,8 +207,12 @@ function start() {
|
|
|
207
207
|
if (settings.readOnly){
|
|
208
208
|
log.info(log._("settings.readonly-mode"))
|
|
209
209
|
}
|
|
210
|
-
if (settings.httpStatic) {
|
|
211
|
-
|
|
210
|
+
if (settings.httpStatic && settings.httpStatic.length) {
|
|
211
|
+
for (let si = 0; si < settings.httpStatic.length; si++) {
|
|
212
|
+
let p = path.resolve(settings.httpStatic[si].path);
|
|
213
|
+
let r = settings.httpStatic[si].root || "/";
|
|
214
|
+
log.info(log._("runtime.paths.httpStatic",{path:`${p} > ${r}`}));
|
|
215
|
+
}
|
|
212
216
|
}
|
|
213
217
|
return redNodes.loadContextsPlugin().then(function () {
|
|
214
218
|
redNodes.loadFlows().then(redNodes.startFlows).catch(function(err) {});
|
|
@@ -395,7 +399,12 @@ module.exports = {
|
|
|
395
399
|
* @memberof @node-red/runtime
|
|
396
400
|
*/
|
|
397
401
|
version: externalAPI.version,
|
|
398
|
-
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* @memberof @node-red/diagnostics
|
|
405
|
+
*/
|
|
406
|
+
diagnostics:externalAPI.diagnostics,
|
|
407
|
+
|
|
399
408
|
storage: storage,
|
|
400
409
|
events: events,
|
|
401
410
|
hooks: hooks,
|
package/lib/nodes/Node.js
CHANGED
|
@@ -503,10 +503,25 @@ function log_helper(self, level, msg) {
|
|
|
503
503
|
o.name = self.name;
|
|
504
504
|
}
|
|
505
505
|
// See https://github.com/node-red/node-red/issues/3327
|
|
506
|
+
// See https://github.com/node-red/node-red/issues/3389
|
|
507
|
+
|
|
508
|
+
let srcError;
|
|
509
|
+
if (msg instanceof Error) {
|
|
510
|
+
srcError = msg;//use existing err object for actual stack
|
|
511
|
+
} else {
|
|
512
|
+
srcError = new Error(msg);//generate a new error for generate a stack
|
|
513
|
+
}
|
|
506
514
|
try {
|
|
507
|
-
self._flow
|
|
515
|
+
if(self instanceof Node && self._flow) {
|
|
516
|
+
self._flow.log(o);
|
|
517
|
+
} else {
|
|
518
|
+
//if self._flow is not present, this is not a node-red Node
|
|
519
|
+
//Set info to "Node object is not a node-red Node" to point out the `Node type` problem in log
|
|
520
|
+
logUnexpectedError(self, srcError, "Node object is not a node-red Node")
|
|
521
|
+
}
|
|
508
522
|
} catch(err) {
|
|
509
|
-
|
|
523
|
+
//build an unexpected error report indicating using the original error (for better stack trace)
|
|
524
|
+
logUnexpectedError(self, srcError, `An error occured attempting to make a log entry: ${err}`)
|
|
510
525
|
}
|
|
511
526
|
}
|
|
512
527
|
/**
|
|
@@ -531,7 +546,7 @@ Node.prototype.error = function(logMessage,msg) {
|
|
|
531
546
|
logMessage = logMessage || "";
|
|
532
547
|
}
|
|
533
548
|
var handled = false;
|
|
534
|
-
if (msg && typeof msg === 'object') {
|
|
549
|
+
if (this._flow && msg && typeof msg === 'object') {
|
|
535
550
|
handled = this._flow.handleError(this,logMessage,msg);
|
|
536
551
|
}
|
|
537
552
|
if (!handled) {
|
|
@@ -619,27 +634,34 @@ function inspectObject(flow) {
|
|
|
619
634
|
}
|
|
620
635
|
}
|
|
621
636
|
|
|
622
|
-
function logUnexpectedError(node, error) {
|
|
623
|
-
|
|
624
|
-
Log.error(`
|
|
637
|
+
function logUnexpectedError(node, error, info) {
|
|
638
|
+
const header = `
|
|
625
639
|
********************************************************************
|
|
626
640
|
Unexpected Node Error
|
|
627
|
-
|
|
628
|
-
Node:
|
|
629
|
-
Type: ${node.type}
|
|
630
|
-
Module: ${moduleInfo}
|
|
631
|
-
ID: ${node._alias||node.id}
|
|
632
|
-
Properties:
|
|
633
|
-
${inspectObject(node)}
|
|
634
|
-
Flow: ${node._flow?node._flow.path:'undefined'}
|
|
635
|
-
Type: ${node._flow?node._flow.TYPE:'undefined'}
|
|
636
|
-
Properties:
|
|
637
|
-
${node._flow?inspectObject(node._flow):'undefined'}
|
|
641
|
+
********************************************************************`;
|
|
638
642
|
|
|
643
|
+
const footer = `
|
|
639
644
|
Please report this issue, including the information logged above:
|
|
640
645
|
https://github.com/node-red/node-red/issues/
|
|
641
|
-
|
|
642
|
-
|
|
646
|
+
********************************************************************`;
|
|
647
|
+
|
|
648
|
+
let detail = [`Info:\n ${info || 'No additional info'}`];
|
|
649
|
+
|
|
650
|
+
//Include Error info?
|
|
651
|
+
if(error && error.stack){
|
|
652
|
+
detail.push(`Stack:\n ${error.stack}`)
|
|
653
|
+
}
|
|
654
|
+
//Include Node info?
|
|
655
|
+
if(node && (node._module || node.type)){
|
|
656
|
+
const moduleInfo = node._module?`${node._module.module}@${node._module.version}`:"undefined";
|
|
657
|
+
const id = node._alias||node.id||"undefined";
|
|
658
|
+
detail.push(`Node:\n Type: ${node.type}\n Module: ${moduleInfo}\n ID: ${id}\n Properties:\n ${inspectObject(node)}`)
|
|
659
|
+
}
|
|
660
|
+
//Include Flow info?
|
|
661
|
+
if(node && node._flow){
|
|
662
|
+
detail.push(`Flow: ${node._flow.path}\n Type: ${node._flow.TYPE}\n Properties:\n ${inspectObject(node._flow)}`)
|
|
663
|
+
}
|
|
664
|
+
Log.error(`${header}\n${detail.join("\n")}\n${footer}`);
|
|
643
665
|
}
|
|
644
666
|
|
|
645
667
|
module.exports = Node;
|
package/lib/nodes/credentials.js
CHANGED
|
@@ -239,7 +239,15 @@ var api = module.exports = {
|
|
|
239
239
|
throw error;
|
|
240
240
|
}
|
|
241
241
|
} else {
|
|
242
|
-
|
|
242
|
+
if (encryptionEnabled) {
|
|
243
|
+
// Our config expects the credentials to be encrypted but the encrypted object is not found
|
|
244
|
+
log.warn(log._("nodes.credentials.encryptedNotFound"))
|
|
245
|
+
credentialCache = credentials;
|
|
246
|
+
} else {
|
|
247
|
+
// credentialSecret is set to False
|
|
248
|
+
log.warn(log._("nodes.credentials.unencrypted"))
|
|
249
|
+
credentialCache = credentials;
|
|
250
|
+
}
|
|
243
251
|
}
|
|
244
252
|
if (clearInvalidFlag) {
|
|
245
253
|
// TODO: this delves too deep into Project structure
|
|
@@ -104,7 +104,9 @@
|
|
|
104
104
|
"error":"Error loading credentials: __message__",
|
|
105
105
|
"error-saving":"Error saving credentials: __message__",
|
|
106
106
|
"not-registered": "Credential type '__type__' is not registered",
|
|
107
|
-
"system-key-warning": "\n\n---------------------------------------------------------------------\nYour flow credentials file is encrypted using a system-generated key.\n\nIf the system-generated key is lost for any reason, your credentials\nfile will not be recoverable, you will have to delete it and re-enter\nyour credentials.\n\nYou should set your own key using the 'credentialSecret' option in\nyour settings file. Node-RED will then re-encrypt your credentials\nfile using your chosen key the next time you deploy a change.\n---------------------------------------------------------------------\n"
|
|
107
|
+
"system-key-warning": "\n\n---------------------------------------------------------------------\nYour flow credentials file is encrypted using a system-generated key.\n\nIf the system-generated key is lost for any reason, your credentials\nfile will not be recoverable, you will have to delete it and re-enter\nyour credentials.\n\nYou should set your own key using the 'credentialSecret' option in\nyour settings file. Node-RED will then re-encrypt your credentials\nfile using your chosen key the next time you deploy a change.\n---------------------------------------------------------------------\n",
|
|
108
|
+
"unencrypted" : "Using unencrypted credentials",
|
|
109
|
+
"encryptedNotFound" : "Encrypted credentials not found"
|
|
108
110
|
},
|
|
109
111
|
"flows": {
|
|
110
112
|
"safe-mode": "Flows stopped in safe mode. Deploy to start.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node-red/runtime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-beta.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
}
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@node-red/registry": "
|
|
20
|
-
"@node-red/util": "
|
|
19
|
+
"@node-red/registry": "3.0.0-beta.1",
|
|
20
|
+
"@node-red/util": "3.0.0-beta.1",
|
|
21
21
|
"async-mutex": "0.3.2",
|
|
22
22
|
"clone": "2.1.2",
|
|
23
|
-
"express": "4.
|
|
24
|
-
"fs-extra": "10.
|
|
23
|
+
"express": "4.18.1",
|
|
24
|
+
"fs-extra": "10.1.0",
|
|
25
25
|
"json-stringify-safe": "5.0.1"
|
|
26
26
|
}
|
|
27
27
|
}
|