diff --git a/packages/cli/src/LoadNodesAndCredentials.ts b/packages/cli/src/LoadNodesAndCredentials.ts index cb1620115b..6e268b70fc 100644 --- a/packages/cli/src/LoadNodesAndCredentials.ts +++ b/packages/cli/src/LoadNodesAndCredentials.ts @@ -97,24 +97,28 @@ class LoadNodesAndCredentialsClass { * @memberof LoadNodesAndCredentialsClass */ async getN8nNodePackages(): Promise { - const packages: string[] = []; - for (const file of await fsReaddirAsync(this.nodeModulesPath)) { - if (file.indexOf('n8n-nodes-') !== 0) { - continue; + const getN8nNodePackagesRecursive = async (relativePath: string): Promise => { + const results: string[] = []; + const nodeModulesPath = `${this.nodeModulesPath}/${relativePath}`; + for (const file of await fsReaddirAsync(nodeModulesPath)) { + const isN8nNodesPackage = file.indexOf('n8n-nodes-') === 0; + const isNpmScopedPackage = file.indexOf('@') === 0; + if (!isN8nNodesPackage && !isNpmScopedPackage) { + continue; + } + if (!(await fsStatAsync(nodeModulesPath)).isDirectory()) { + continue; + } + if (isN8nNodesPackage) { results.push(`${relativePath}${file}`); } + if (isNpmScopedPackage) { + results.push(...await getN8nNodePackagesRecursive(`${relativePath}${file}/`)); + } } - - // Check if it is really a folder - if (!(await fsStatAsync(path.join(this.nodeModulesPath, file))).isDirectory()) { - continue; - } - - packages.push(file); - } - - return packages; + return results; + }; + return getN8nNodePackagesRecursive(''); } - /** * Loads credentials from a file * diff --git a/packages/cli/src/Server.ts b/packages/cli/src/Server.ts index 1d7f1506de..30b71b08a4 100644 --- a/packages/cli/src/Server.ts +++ b/packages/cli/src/Server.ts @@ -573,7 +573,7 @@ class App { const nodeTypes = NodeTypes(); - const loadDataInstance = new LoadNodeParameterOptions(nodeType, nodeTypes, JSON.parse('' + req.query.currentNodeParameters), credentials); + const loadDataInstance = new LoadNodeParameterOptions(nodeType, nodeTypes, JSON.parse('' + req.query.currentNodeParameters), credentials!); const workflowData = loadDataInstance.getWorkflowData() as IWorkflowBase; const workflowCredentials = await WorkflowCredentials(workflowData.nodes); @@ -607,8 +607,8 @@ class App { // Returns the node icon - this.app.get('/rest/node-icon/:nodeType', async (req: express.Request, res: express.Response): Promise => { - const nodeTypeName = req.params.nodeType; + this.app.get(['/rest/node-icon/:nodeType', '/rest/node-icon/:scope/:nodeType'], async (req: express.Request, res: express.Response): Promise => { + const nodeTypeName = `${req.params.scope ? `${req.params.scope}/` : ''}${req.params.nodeType}`; const nodeTypes = NodeTypes(); const nodeType = nodeTypes.getByName(nodeTypeName); diff --git a/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts b/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts index ac4b1f80e3..e9ba60b6dd 100644 --- a/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts +++ b/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts @@ -246,7 +246,7 @@ export class GraphQL implements INodeType { } } if (requestOptions.body.operationName === '') { - requestOptions.body.operation = null; + requestOptions.body.operationName = null; } requestOptions.json = true; } else { diff --git a/packages/nodes-base/nodes/Switch.node.ts b/packages/nodes-base/nodes/Switch.node.ts index 3702a7c598..80b3845bca 100644 --- a/packages/nodes-base/nodes/Switch.node.ts +++ b/packages/nodes-base/nodes/Switch.node.ts @@ -32,7 +32,7 @@ export class Switch implements INodeType { { name: 'Expression', value: 'expression', - description: 'Expression decides how to route date.', + description: 'Expression decides how to route data.', }, { name: 'Rules',