Merge pull request #3064 from node-red/revert-external-modules-dir

Move externalModules back into the user dir
This commit is contained in:
Nick O'Leary
2021-07-15 09:56:23 +01:00
committed by GitHub
8 changed files with 341 additions and 243 deletions

View File

@@ -12,7 +12,6 @@ const log = require("@node-red/util").log;
const hooks = require("@node-red/util").hooks;
const BUILTIN_MODULES = require('module').builtinModules;
const EXTERNAL_MODULES_DIR = "externalModules";
// TODO: outsource running npm to a plugin
const NPM_COMMAND = (process.platform === "win32") ? "npm.cmd" : "npm";
@@ -28,15 +27,30 @@ let installAllowList = ['*'];
let installDenyList = [];
function getInstallDir() {
return path.resolve(path.join(settings.userDir || process.env.NODE_RED_HOME || ".", "externalModules"));
return path.resolve(settings.userDir || process.env.NODE_RED_HOME || ".");
}
let loggedLegacyWarning = false;
async function refreshExternalModules() {
const externalModuleDir = path.resolve(path.join(settings.userDir || process.env.NODE_RED_HOME || ".", EXTERNAL_MODULES_DIR));
if (!loggedLegacyWarning) {
loggedLegacyWarning = true;
const oldExternalModulesDir = path.join(path.resolve(settings.userDir || process.env.NODE_RED_HOME || "."),"externalModules");
if (fs.existsSync(oldExternalModulesDir)) {
try {
log.warn(log._("server.install.old-ext-mod-dir-warning",{oldDir:oldExternalModulesDir, newDir:getInstallDir()}))
} catch(err) {console.log(err)}
}
}
const externalModuleDir = getInstallDir();
try {
const pkgFile = JSON.parse(await fs.readFile(path.join(externalModuleDir,"package.json"),"utf-8"));
knownExternalModules = pkgFile.dependencies;
knownExternalModules = pkgFile.dependencies || {};
} catch(err) {
knownExternalModules = {};
}
}
@@ -44,6 +58,7 @@ function init(_settings) {
settings = _settings;
knownExternalModules = {};
installEnabled = true;
if (settings.externalModules && settings.externalModules.modules) {
if (settings.externalModules.modules.allowList || settings.externalModules.modules.denyList) {
installAllowList = settings.externalModules.modules.allowList;
@@ -82,10 +97,33 @@ function requireModule(module) {
e.code = "module_not_allowed";
throw e;
}
const externalModuleDir = path.resolve(path.join(settings.userDir || process.env.NODE_RED_HOME || ".", EXTERNAL_MODULES_DIR));
const externalModuleDir = getInstallDir();
const moduleDir = path.join(externalModuleDir,"node_modules",module);
return require(moduleDir);
}
function importModule(module) {
if (!registryUtil.checkModuleAllowed( module, null,installAllowList,installDenyList)) {
const e = new Error("Module not allowed");
e.code = "module_not_allowed";
throw e;
}
const parsedModule = parseModuleName(module);
if (BUILTIN_MODULES.indexOf(parsedModule.module) !== -1) {
return import(parsedModule.module);
}
if (!knownExternalModules[parsedModule.module]) {
const e = new Error("Module not allowed");
e.code = "module_not_allowed";
throw e;
}
const externalModuleDir = getInstallDir();
const moduleDir = path.join(externalModuleDir,"node_modules",module);
// Import needs the full path to the module's main .js file
const moduleFile = require.resolve(moduleDir);
return import(moduleFile);
}
function parseModuleName(module) {
var match = /((?:@[^/]+\/)?[^/@]+)(?:@([\s\S]+))?/.exec(module);
@@ -214,6 +252,9 @@ async function installModule(moduleDetails) {
return hooks.trigger("postInstall", triggerPayload)
}).then(() => {
log.info(log._("server.install.installed", { name: installSpec }));
const runtimeInstalledModules = settings.get("modules") || {};
runtimeInstalledModules[moduleDetails.module] = moduleDetails;
settings.set("modules",runtimeInstalledModules)
}).catch(result => {
var output = result.stderr || result.toString();
var e;
@@ -235,9 +276,10 @@ async function installModule(moduleDetails) {
}
module.exports = {
init: init,
register: register,
registerSubflow: registerSubflow,
checkFlowDependencies: checkFlowDependencies,
require: requireModule
init,
register,
registerSubflow,
checkFlowDependencies,
require: requireModule,
import: importModule
}

View File

@@ -50,6 +50,16 @@ function requireModule(name) {
return require("./externalModules").require(name);
}
}
function importModule(name) {
var moduleInfo = require("./index").getModuleInfo(name);
if (moduleInfo && moduleInfo.path) {
var relPath = path.relative(__dirname, moduleInfo.path);
return import(relPath);
} else {
// Require it here to avoid the circular dependency
return require("./externalModules").import(name);
}
}
function createNodeApi(node) {
var red = {
@@ -61,6 +71,7 @@ function createNodeApi(node) {
util: runtime.util,
version: runtime.version,
require: requireModule,
import: importModule,
comms: {
publish: function(topic,data,retain) {
events.emit("comms",{