@node-red/registry 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/externalModules.js +1 -18
- package/lib/index.js +1 -0
- package/lib/installer.js +27 -10
- package/lib/plugins.js +71 -12
- package/lib/registry.js +17 -2
- package/lib/subflow.js +1 -1
- package/package.json +3 -3
package/lib/externalModules.js
CHANGED
|
@@ -28,11 +28,6 @@ let installEnabled = true;
|
|
|
28
28
|
let installAllowList = ['*'];
|
|
29
29
|
let installDenyList = [];
|
|
30
30
|
|
|
31
|
-
let IMPORT_SUPPORTED = true;
|
|
32
|
-
const nodeVersionParts = process.versions.node.split(".").map(v => parseInt(v));
|
|
33
|
-
if (nodeVersionParts[0] < 12 || (nodeVersionParts[0] === 12 && nodeVersionParts[1] < 17)) {
|
|
34
|
-
IMPORT_SUPPORTED = false;
|
|
35
|
-
}
|
|
36
31
|
|
|
37
32
|
function getInstallDir() {
|
|
38
33
|
return path.resolve(settings.userDir || process.env.NODE_RED_HOME || ".");
|
|
@@ -110,18 +105,6 @@ function requireModule(module) {
|
|
|
110
105
|
return require(moduleDir);
|
|
111
106
|
}
|
|
112
107
|
function importModule(module) {
|
|
113
|
-
if (!IMPORT_SUPPORTED) {
|
|
114
|
-
// On Node < 12.17 - fall back to try a require
|
|
115
|
-
return new Promise((resolve, reject) => {
|
|
116
|
-
try {
|
|
117
|
-
const mod = requireModule(module);
|
|
118
|
-
resolve(mod);
|
|
119
|
-
} catch(err) {
|
|
120
|
-
reject(err);
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
|
|
125
108
|
if (!registryUtil.checkModuleAllowed( module, null,installAllowList,installDenyList)) {
|
|
126
109
|
const e = new Error("Module not allowed");
|
|
127
110
|
e.code = "module_not_allowed";
|
|
@@ -273,7 +256,7 @@ async function installModule(moduleDetails) {
|
|
|
273
256
|
let extraArgs = triggerPayload.args || [];
|
|
274
257
|
let args = ['install', ...extraArgs, installSpec]
|
|
275
258
|
log.trace(NPM_COMMAND + JSON.stringify(args));
|
|
276
|
-
return exec.run(NPM_COMMAND, args, { cwd: installDir },true)
|
|
259
|
+
return exec.run(NPM_COMMAND, args, { cwd: installDir, shell: true },true)
|
|
277
260
|
} else {
|
|
278
261
|
log.trace("skipping npm install");
|
|
279
262
|
}
|
package/lib/index.js
CHANGED
|
@@ -319,6 +319,7 @@ module.exports = {
|
|
|
319
319
|
getPluginsByType: plugins.getPluginsByType,
|
|
320
320
|
getPluginList: plugins.getPluginList,
|
|
321
321
|
getPluginConfigs: plugins.getPluginConfigs,
|
|
322
|
+
getPluginConfig: plugins.getPluginConfig,
|
|
322
323
|
exportPluginSettings: plugins.exportPluginSettings,
|
|
323
324
|
|
|
324
325
|
|
package/lib/installer.js
CHANGED
|
@@ -25,12 +25,17 @@ const registryUtil = require("./util");
|
|
|
25
25
|
const library = require("./library");
|
|
26
26
|
const {exec,log,events,hooks} = require("@node-red/util");
|
|
27
27
|
const child_process = require('child_process');
|
|
28
|
-
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
29
|
-
let installerEnabled = false;
|
|
30
28
|
|
|
29
|
+
const plugins = require("./plugins");
|
|
30
|
+
|
|
31
|
+
const isWindows = process.platform === 'win32'
|
|
32
|
+
const npmCommand = isWindows ? 'npm.cmd' : 'npm';
|
|
33
|
+
|
|
34
|
+
let installerEnabled = false;
|
|
31
35
|
let settings;
|
|
36
|
+
|
|
32
37
|
const moduleRe = /^(@[^/@]+?[/])?[^/@]+?$/;
|
|
33
|
-
const slashRe =
|
|
38
|
+
const slashRe = isWindows ? /\\|[/]/ : /[/]/;
|
|
34
39
|
const pkgurlRe = /^(https?|git(|\+https?|\+ssh|\+file)):\/\//;
|
|
35
40
|
const localtgzRe = /^([a-zA-Z]:|\/).+tgz$/;
|
|
36
41
|
|
|
@@ -225,7 +230,7 @@ async function installModule(module,version,url) {
|
|
|
225
230
|
let extraArgs = triggerPayload.args || [];
|
|
226
231
|
let args = ['install', ...extraArgs, installName]
|
|
227
232
|
log.trace(npmCommand + JSON.stringify(args));
|
|
228
|
-
return exec.run(npmCommand,args,{ cwd: installDir}, true)
|
|
233
|
+
return exec.run(npmCommand,args,{ cwd: installDir, shell: true }, true)
|
|
229
234
|
} else {
|
|
230
235
|
log.trace("skipping npm install");
|
|
231
236
|
}
|
|
@@ -260,7 +265,7 @@ async function installModule(module,version,url) {
|
|
|
260
265
|
log.warn("------------------------------------------");
|
|
261
266
|
e = new Error(log._("server.install.install-failed")+": "+err.toString());
|
|
262
267
|
if (err.hook === "postInstall") {
|
|
263
|
-
return exec.run(npmCommand,["remove",module],{ cwd: installDir}, false).finally(() => {
|
|
268
|
+
return exec.run(npmCommand,["remove",module],{ cwd: installDir, shell: true }, false).finally(() => {
|
|
264
269
|
throw e;
|
|
265
270
|
})
|
|
266
271
|
}
|
|
@@ -330,10 +335,18 @@ function reportRemovedModules(removedNodes) {
|
|
|
330
335
|
//comms.publish("node/removed",removedNodes,false);
|
|
331
336
|
log.info(log._("server.removed-types"));
|
|
332
337
|
for (var j=0;j<removedNodes.length;j++) {
|
|
333
|
-
for (var i=0;i<removedNodes[j].types
|
|
338
|
+
for (var i=0;i<removedNodes[j].types?.length;i++) {
|
|
334
339
|
log.info(" - "+(removedNodes[j].module?removedNodes[j].module+":":"")+removedNodes[j].types[i]);
|
|
335
340
|
}
|
|
336
341
|
}
|
|
342
|
+
|
|
343
|
+
log.info(log._("server.removed-plugins"));
|
|
344
|
+
for (let j=0;j<removedNodes.length;j++) {
|
|
345
|
+
for (var i=0;i<removedNodes[j].plugins?.length;i++) {
|
|
346
|
+
log.info(" - "+(removedNodes[j].module?removedNodes[j].module+":":"")+removedNodes[j].plugins[i].id);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
337
350
|
return removedNodes;
|
|
338
351
|
}
|
|
339
352
|
|
|
@@ -356,7 +369,7 @@ async function getModuleVersionFromNPM(module, version) {
|
|
|
356
369
|
}
|
|
357
370
|
|
|
358
371
|
return new Promise((resolve, reject) => {
|
|
359
|
-
child_process.execFile(npmCommand,['info','--json',installName],function(err,stdout,stderr) {
|
|
372
|
+
child_process.execFile(npmCommand,['info','--json',installName],{ shell: true },function(err,stdout,stderr) {
|
|
360
373
|
try {
|
|
361
374
|
if (!stdout) {
|
|
362
375
|
log.warn(log._("server.install.install-failed-not-found",{name:module}));
|
|
@@ -495,8 +508,12 @@ function uninstallModule(module) {
|
|
|
495
508
|
} catch(err) {
|
|
496
509
|
return reject(new Error(log._("server.install.uninstall-failed",{name:module})));
|
|
497
510
|
}
|
|
511
|
+
|
|
512
|
+
// need to remove the plugins first,
|
|
513
|
+
// as registry data necessary to perform this operation
|
|
514
|
+
var list = plugins.removeModule(module);
|
|
515
|
+
list = list.concat(registry.removeModule(module));
|
|
498
516
|
|
|
499
|
-
var list = registry.removeModule(module);
|
|
500
517
|
log.info(log._("server.install.uninstalling",{name:module}));
|
|
501
518
|
|
|
502
519
|
let triggerPayload = {
|
|
@@ -511,7 +528,7 @@ function uninstallModule(module) {
|
|
|
511
528
|
let extraArgs = triggerPayload.args || [];
|
|
512
529
|
let args = ['remove', ...extraArgs, module]
|
|
513
530
|
log.trace(npmCommand + JSON.stringify(args));
|
|
514
|
-
return exec.run(npmCommand,args,{ cwd: installDir}, true)
|
|
531
|
+
return exec.run(npmCommand,args,{ cwd: installDir, shell: true }, true)
|
|
515
532
|
} else {
|
|
516
533
|
log.trace("skipping npm uninstall");
|
|
517
534
|
}
|
|
@@ -578,7 +595,7 @@ async function checkPrereq() {
|
|
|
578
595
|
installerEnabled = false;
|
|
579
596
|
} else {
|
|
580
597
|
return new Promise(resolve => {
|
|
581
|
-
child_process.execFile(npmCommand,['-v'],function(err,stdout) {
|
|
598
|
+
child_process.execFile(npmCommand,['-v'],{ shell: true },function(err,stdout) {
|
|
582
599
|
if (err) {
|
|
583
600
|
log.info(log._("server.palette-editor.npm-not-found"));
|
|
584
601
|
installerEnabled = false;
|
package/lib/plugins.js
CHANGED
|
@@ -39,6 +39,8 @@ function registerPlugin(nodeSetId,id,definition) {
|
|
|
39
39
|
pluginSettings[id] = definition.settings;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
// reset the cache when a new plugin is incoming!
|
|
43
|
+
pluginConfigCache = {};
|
|
42
44
|
|
|
43
45
|
if (definition.onadd && typeof definition.onadd === 'function') {
|
|
44
46
|
definition.onadd();
|
|
@@ -55,29 +57,47 @@ function getPluginsByType(type) {
|
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
function getPluginConfigs(lang) {
|
|
60
|
+
// we're not re-using getPluginConfig() here,
|
|
61
|
+
// to avoid calling registry.getModuleList() multiple times!
|
|
62
|
+
|
|
58
63
|
if (!pluginConfigCache[lang]) {
|
|
59
64
|
var result = "";
|
|
60
|
-
var script = "";
|
|
61
65
|
var moduleConfigs = registry.getModuleList();
|
|
62
66
|
for (var module in moduleConfigs) {
|
|
63
67
|
/* istanbul ignore else */
|
|
64
68
|
if (moduleConfigs.hasOwnProperty(module)) {
|
|
65
|
-
|
|
66
|
-
for (var plugin in plugins) {
|
|
67
|
-
if (plugins.hasOwnProperty(plugin)) {
|
|
68
|
-
var config = plugins[plugin];
|
|
69
|
-
if (config.enabled && !config.err && config.config) {
|
|
70
|
-
result += "\n<!-- --- [red-plugin:"+config.id+"] --- -->\n";
|
|
71
|
-
result += config.config;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
69
|
+
result += generateModulePluginConfig(moduleConfigs[module]);
|
|
75
70
|
}
|
|
76
71
|
}
|
|
77
72
|
pluginConfigCache[lang] = result;
|
|
78
73
|
}
|
|
79
74
|
return pluginConfigCache[lang];
|
|
80
75
|
}
|
|
76
|
+
|
|
77
|
+
function getPluginConfig(id, lang) {
|
|
78
|
+
let result = '';
|
|
79
|
+
let moduleConfigs = registry.getModuleList();
|
|
80
|
+
if (moduleConfigs.hasOwnProperty(id)) {
|
|
81
|
+
result = generateModulePluginConfig(moduleConfigs[id]);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function generateModulePluginConfig(module) {
|
|
87
|
+
let result = '';
|
|
88
|
+
const plugins = module.plugins
|
|
89
|
+
for (let plugin in plugins) {
|
|
90
|
+
if (plugins.hasOwnProperty(plugin)) {
|
|
91
|
+
let config = plugins[plugin];
|
|
92
|
+
if (config.enabled && !config.err && config.config) {
|
|
93
|
+
result += "\n<!-- --- [red-plugin:"+config.id+"] --- -->\n";
|
|
94
|
+
result += config.config;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
81
101
|
function getPluginList() {
|
|
82
102
|
var list = [];
|
|
83
103
|
var moduleConfigs = registry.getModuleList();
|
|
@@ -142,12 +162,51 @@ function exportPluginSettings(safeSettings) {
|
|
|
142
162
|
return safeSettings;
|
|
143
163
|
}
|
|
144
164
|
|
|
165
|
+
function removeModule(moduleId) {
|
|
166
|
+
|
|
167
|
+
// clean the (plugin) registry when a module is removed / uninstalled
|
|
168
|
+
|
|
169
|
+
let pluginList = [];
|
|
170
|
+
let module = registry.getModule(moduleId);
|
|
171
|
+
let keys = Object.keys(module.plugins ?? {});
|
|
172
|
+
keys.forEach( key => {
|
|
173
|
+
let _plugins = module.plugins[key].plugins ?? [];
|
|
174
|
+
_plugins.forEach( plugin => {
|
|
175
|
+
let id = plugin.id;
|
|
176
|
+
|
|
177
|
+
if (plugin.onremove && typeof plugin.onremove === 'function') {
|
|
178
|
+
plugin.onremove();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
delete pluginToId[id];
|
|
182
|
+
delete plugins[id];
|
|
183
|
+
delete pluginSettings[id];
|
|
184
|
+
pluginConfigCache = {};
|
|
185
|
+
|
|
186
|
+
let psbtype = pluginsByType[plugin.type] ?? [];
|
|
187
|
+
for (let i=psbtype.length; i>0; i--) {
|
|
188
|
+
let pbt = psbtype[i-1];
|
|
189
|
+
if (pbt.id == id) {
|
|
190
|
+
psbtype.splice(i-1, 1);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
pluginList.push(registry.filterNodeInfo(module.plugins[key]));
|
|
196
|
+
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
return pluginList;
|
|
200
|
+
}
|
|
201
|
+
|
|
145
202
|
module.exports = {
|
|
146
203
|
init,
|
|
147
204
|
registerPlugin,
|
|
148
205
|
getPlugin,
|
|
149
206
|
getPluginsByType,
|
|
150
207
|
getPluginConfigs,
|
|
208
|
+
getPluginConfig,
|
|
151
209
|
getPluginList,
|
|
152
|
-
exportPluginSettings
|
|
210
|
+
exportPluginSettings,
|
|
211
|
+
removeModule
|
|
153
212
|
}
|
package/lib/registry.js
CHANGED
|
@@ -65,7 +65,13 @@ function filterNodeInfo(n) {
|
|
|
65
65
|
r.err = n.err;
|
|
66
66
|
}
|
|
67
67
|
if (n.hasOwnProperty("plugins")) {
|
|
68
|
-
r.plugins = n.plugins
|
|
68
|
+
r.plugins = n.plugins.map(p => {
|
|
69
|
+
return {
|
|
70
|
+
id: p.id,
|
|
71
|
+
type: p.type,
|
|
72
|
+
module: p.module
|
|
73
|
+
}
|
|
74
|
+
});
|
|
69
75
|
}
|
|
70
76
|
if (n.type === "plugin") {
|
|
71
77
|
r.editor = !!n.template;
|
|
@@ -386,7 +392,8 @@ function getModuleInfo(module) {
|
|
|
386
392
|
local: moduleConfigs[module].local,
|
|
387
393
|
user: moduleConfigs[module].user,
|
|
388
394
|
path: moduleConfigs[module].path,
|
|
389
|
-
nodes: []
|
|
395
|
+
nodes: [],
|
|
396
|
+
plugins: []
|
|
390
397
|
};
|
|
391
398
|
if (moduleConfigs[module].dependencies) {
|
|
392
399
|
m.dependencies = moduleConfigs[module].dependencies;
|
|
@@ -399,6 +406,14 @@ function getModuleInfo(module) {
|
|
|
399
406
|
nodeInfo.version = m.version;
|
|
400
407
|
m.nodes.push(nodeInfo);
|
|
401
408
|
}
|
|
409
|
+
|
|
410
|
+
let plugins = Object.values(moduleConfigs[module].plugins ?? {});
|
|
411
|
+
plugins.forEach((plugin) => {
|
|
412
|
+
let nodeInfo = filterNodeInfo(plugin);
|
|
413
|
+
nodeInfo.version = m.version;
|
|
414
|
+
m.plugins.push(nodeInfo);
|
|
415
|
+
});
|
|
416
|
+
|
|
402
417
|
return m;
|
|
403
418
|
} else {
|
|
404
419
|
return null;
|
package/lib/subflow.js
CHANGED
|
@@ -88,7 +88,7 @@ function generateSubflowConfig(subflow) {
|
|
|
88
88
|
this.credentials['has_' + prop.name] = (this.credentials[prop.name] !== "");
|
|
89
89
|
} else {
|
|
90
90
|
switch(prop.type) {
|
|
91
|
-
case "str": this[prop.name] = prop.value||""; break;
|
|
91
|
+
case "str": case "conf-type": this[prop.name] = prop.value||""; break;
|
|
92
92
|
case "bool": this[prop.name] = (typeof prop.value === 'boolean')?prop.value:prop.value === "true" ; break;
|
|
93
93
|
case "num": this[prop.name] = (typeof prop.value === 'number')?prop.value:Number(prop.value); break;
|
|
94
94
|
default:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@node-red/registry",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.3",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
}
|
|
17
17
|
],
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@node-red/util": "4.0.0-beta.
|
|
19
|
+
"@node-red/util": "4.0.0-beta.3",
|
|
20
20
|
"clone": "2.1.2",
|
|
21
21
|
"fs-extra": "11.1.1",
|
|
22
22
|
"semver": "7.5.4",
|
|
23
|
-
"tar": "6.1
|
|
23
|
+
"tar": "6.2.1",
|
|
24
24
|
"uglify-js": "3.17.4"
|
|
25
25
|
}
|
|
26
26
|
}
|