From ba22b07dcea0bf5bdbd93e25e58632733597925e Mon Sep 17 00:00:00 2001 From: Steve-Mcl Date: Thu, 16 Jun 2022 10:57:29 +0100 Subject: [PATCH] align functionality of `nodesDir` with coreNodesDir and userDir --- .../@node-red/registry/lib/localfilesystem.js | 195 +++++++++++++----- 1 file changed, 146 insertions(+), 49 deletions(-) diff --git a/packages/node_modules/@node-red/registry/lib/localfilesystem.js b/packages/node_modules/@node-red/registry/lib/localfilesystem.js index 62080b4a8..da4006ecc 100644 --- a/packages/node_modules/@node-red/registry/lib/localfilesystem.js +++ b/packages/node_modules/@node-red/registry/lib/localfilesystem.js @@ -88,9 +88,10 @@ function getLocalFile(file) { /** * Synchronously walks the directory looking for node files. * @param dir the directory to search + * @param skipValidNodeRedModules a flag to skip lading icons & files if the directory a valid node-red module * @return an array of fully-qualified paths to .js files */ -function getLocalNodeFiles(dir) { +function getLocalNodeFiles(dir, skipValidNodeRedModules) { dir = path.resolve(dir); var result = []; @@ -102,6 +103,14 @@ function getLocalNodeFiles(dir) { return {files: [], icons: []}; } files.sort(); + // when loading local files, if the path is a valid node-red module + // dont include it (will be picked up in scanTreeForNodesModules) + if(skipValidNodeRedModules && files.indexOf("package.json") >= 0) { + const package = getPackageDetails(dir) + if(package.isNodeRedModule) { + return {files: [], icons: []}; + } + } files.forEach(function(fn) { var stats = fs.statSync(path.join(dir,fn)); if (stats.isFile()) { @@ -114,7 +123,7 @@ function getLocalNodeFiles(dir) { } else if (stats.isDirectory()) { // Ignore /.dirs/, /lib/ /node_modules/ if (!/^(\..*|lib|icons|node_modules|test|locales)$/.test(fn)) { - var subDirResults = getLocalNodeFiles(path.join(dir,fn)); + var subDirResults = getLocalNodeFiles(path.join(dir,fn), skipValidNodeRedModules); result = result.concat(subDirResults.files); icons = icons.concat(subDirResults.icons); } else if (fn === "icons") { @@ -126,21 +135,30 @@ function getLocalNodeFiles(dir) { return {files: result, icons: icons} } -function scanDirForNodesModules(dir,moduleName) { - var results = []; - var scopeName; +function scanDirForNodesModules(dir,moduleName,package) { + let results = []; + let scopeName; + let files try { - var files = fs.readdirSync(dir); - if (moduleName) { - var m = /^(?:(@[^/]+)[/])?([^@/]+)/.exec(moduleName); - if (m) { - scopeName = m[1]; - moduleName = m[2]; + let isNodeRedModule = false + if(package) { + dir = path.join(package.moduleDir,'..') + files = [path.basename(package.moduleDir)] + moduleName = (package.package ? package.package.name : null) || moduleName + isNodeRedModule = package.isNodeRedModule + } else { + files = fs.readdirSync(dir); + if (moduleName) { + var m = /^(?:(@[^/]+)[/])?([^@/]+)/.exec(moduleName); + if (m) { + scopeName = m[1]; + moduleName = m[2]; + } } } - for (var i=0;i look for node_modules + 2. exist(package.json) && package.json.has(node-red) => load this only + 3. in original scan of nodesDir, ignore if:(exist(package.json) && package.json.has(node-red)) + */ + if (nodesDir) { + for (let dirIndex = 0; dirIndex < nodesDir.length; dirIndex++) { + const nodeDir = nodesDir[dirIndex]; + const packageDetails = getPackageDetails(nodeDir) + if(packageDetails.isNodeRedModule) { + //we have found a node-red module, scan it + const nrModules = scanDirForNodesModules(nodeDir, packageDetails.package.name, packageDetails); + results = results.concat(nrModules); + + } else if (packageDetails.has_node_modules) { + //If this dir has a `node_modues` dir, scan it + const nodeModulesDir = path.join(nodeDir, 'node_modules') + const nrModules = scanDirForNodesModules(nodeModulesDir, moduleName ); + results = results.concat(nrModules); + + } else { + //If this is not a node-red module AND it does NOT have a node_modules dir, + //it may be a directory of project directories or a node_modules dir? + //scan this instead + const nrModules = scanDirForNodesModules(nodeDir, moduleName); + results = results.concat(nrModules); + } } } return results; @@ -274,24 +328,26 @@ function getModuleNodeFiles(module) { } function getNodeFiles(disableNodePathScan) { - var dir; // Find all of the nodes to load - var nodeFiles = []; - var results; - - var dir; - var iconList = []; + let results; + let nodesDir; + if(settings.nodesDir) { + nodesDir = Array.isArray(settings.nodesDir) ? settings.nodesDir : [settings.nodesDir] + } + let dir; + let nodeFiles = []; + let iconList = []; if (settings.coreNodesDir) { results = getLocalNodeFiles(path.resolve(settings.coreNodesDir)); nodeFiles = nodeFiles.concat(results.files); iconList = iconList.concat(results.icons); - var defaultLocalesPath = path.join(settings.coreNodesDir,"locales"); + let defaultLocalesPath = path.join(settings.coreNodesDir,"locales"); i18n.registerMessageCatalog("node-red",defaultLocalesPath,"messages.json"); } if (settings.userDir) { dir = path.join(settings.userDir,"lib","icons"); - var icons = scanIconDir(dir); + let icons = scanIconDir(dir); if (icons.length > 0) { iconList.push({path:dir,icons:icons}); } @@ -301,13 +357,9 @@ function getNodeFiles(disableNodePathScan) { nodeFiles = nodeFiles.concat(results.files); iconList = iconList.concat(results.icons); } - if (settings.nodesDir) { - dir = settings.nodesDir; - if (typeof settings.nodesDir == "string") { - dir = [dir]; - } - for (var i=0;i