From b2cbed9865888f6f3bc528984d4091d86a88f0d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Fri, 10 Jan 2025 15:13:31 +0100 Subject: [PATCH] fix(core): Fix node exclusion on the frontend types (#12544) --- packages/core/src/DirectoryLoader.ts | 43 ++++++++++++++-------- packages/core/test/DirectoryLoader.test.ts | 31 +++------------- 2 files changed, 32 insertions(+), 42 deletions(-) diff --git a/packages/core/src/DirectoryLoader.ts b/packages/core/src/DirectoryLoader.ts index 26dace0fd1..559c0c5531 100644 --- a/packages/core/src/DirectoryLoader.ts +++ b/packages/core/src/DirectoryLoader.ts @@ -80,8 +80,8 @@ export abstract class DirectoryLoader { constructor( readonly directory: string, - protected readonly excludeNodes: string[] = [], - protected readonly includeNodes: string[] = [], + protected excludeNodes: string[] = [], + protected includeNodes: string[] = [], ) {} abstract packageName: string; @@ -121,13 +121,12 @@ export abstract class DirectoryLoader { this.addCodex(tempNode, filePath); const nodeType = tempNode.description.name; - const fullNodeType = `${this.packageName}.${nodeType}`; - if (this.includeNodes.length && !this.includeNodes.includes(fullNodeType)) { + if (this.includeNodes.length && !this.includeNodes.includes(nodeType)) { return; } - if (this.excludeNodes.includes(fullNodeType)) { + if (this.excludeNodes.includes(nodeType)) { return; } @@ -151,7 +150,7 @@ export abstract class DirectoryLoader { if (currentVersionNode.hasOwnProperty('executeSingle')) { throw new ApplicationError( '"executeSingle" has been removed. Please update the code of this node to use "execute" instead.', - { extra: { nodeType: fullNodeType } }, + { extra: { nodeType } }, ); } } else { @@ -430,9 +429,25 @@ export class CustomDirectoryLoader extends DirectoryLoader { * e.g. /nodes-base or community packages. */ export class PackageDirectoryLoader extends DirectoryLoader { - packageJson: n8n.PackageJson = this.readJSONSync('package.json'); + packageJson: n8n.PackageJson; - packageName = this.packageJson.name; + packageName: string; + + constructor(directory: string, excludeNodes: string[] = [], includeNodes: string[] = []) { + super(directory, excludeNodes, includeNodes); + + this.packageJson = this.readJSONSync('package.json'); + this.packageName = this.packageJson.name; + this.excludeNodes = this.extractNodeTypes(excludeNodes); + this.includeNodes = this.extractNodeTypes(includeNodes); + } + + private extractNodeTypes(fullNodeTypes: string[]) { + return fullNodeTypes + .map((fullNodeType) => fullNodeType.split('.')) + .filter(([packageName]) => packageName === this.packageName) + .map(([_, nodeType]) => nodeType); + } override async loadAll() { const { n8n } = this.packageJson; @@ -524,9 +539,8 @@ export class LazyPackageDirectoryLoader extends PackageDirectoryLoader { if (this.includeNodes.length) { const allowedNodes: typeof this.known.nodes = {}; - for (const fullNodeType of this.includeNodes) { - const [packageName, nodeType] = fullNodeType.split('.'); - if (packageName === this.packageName && nodeType in this.known.nodes) { + for (const nodeType of this.includeNodes) { + if (nodeType in this.known.nodes) { allowedNodes[nodeType] = this.known.nodes[nodeType]; } } @@ -538,11 +552,8 @@ export class LazyPackageDirectoryLoader extends PackageDirectoryLoader { } if (this.excludeNodes.length) { - for (const fullNodeType of this.excludeNodes) { - const [packageName, nodeType] = fullNodeType.split('.'); - if (packageName === this.packageName) { - delete this.known.nodes[nodeType]; - } + for (const nodeType of this.excludeNodes) { + delete this.known.nodes[nodeType]; } this.types.nodes = this.types.nodes.filter( diff --git a/packages/core/test/DirectoryLoader.test.ts b/packages/core/test/DirectoryLoader.test.ts index 01a8c8d34a..226b5a6fee 100644 --- a/packages/core/test/DirectoryLoader.test.ts +++ b/packages/core/test/DirectoryLoader.test.ts @@ -235,10 +235,7 @@ describe('DirectoryLoader', () => { return JSON.stringify({}); } if (path.endsWith('types/nodes.json')) { - return JSON.stringify([ - { name: 'n8n-nodes-testing.node1' }, - { name: 'n8n-nodes-testing.node2' }, - ]); + return JSON.stringify([{ name: 'node1' }, { name: 'node2' }]); } if (path.endsWith('types/credentials.json')) { return JSON.stringify([]); @@ -254,7 +251,7 @@ describe('DirectoryLoader', () => { node1: { className: 'Node1', sourcePath: 'dist/Node1/Node1.node.js' }, }); expect(loader.types.nodes).toHaveLength(1); - expect(loader.types.nodes[0].name).toBe('n8n-nodes-testing.node1'); + expect(loader.types.nodes[0].name).toBe('node1'); expect(classLoader.loadClassInIsolation).not.toHaveBeenCalled(); }); @@ -274,10 +271,7 @@ describe('DirectoryLoader', () => { return JSON.stringify({}); } if (path.endsWith('types/nodes.json')) { - return JSON.stringify([ - { name: 'n8n-nodes-testing.node1' }, - { name: 'n8n-nodes-testing.node2' }, - ]); + return JSON.stringify([{ name: 'node1' }, { name: 'node2' }]); } if (path.endsWith('types/credentials.json')) { return JSON.stringify([]); @@ -314,10 +308,7 @@ describe('DirectoryLoader', () => { return JSON.stringify({}); } if (path.endsWith('types/nodes.json')) { - return JSON.stringify([ - { name: 'n8n-nodes-testing.node1' }, - { name: 'n8n-nodes-testing.node2' }, - ]); + return JSON.stringify([{ name: 'node1' }, { name: 'node2' }]); } if (path.endsWith('types/credentials.json')) { return JSON.stringify([]); @@ -333,7 +324,7 @@ describe('DirectoryLoader', () => { node2: { className: 'Node2', sourcePath: 'dist/Node2/Node2.node.js' }, }); expect(loader.types.nodes).toHaveLength(1); - expect(loader.types.nodes[0].name).toBe('n8n-nodes-testing.node2'); + expect(loader.types.nodes[0].name).toBe('node2'); expect(classLoader.loadClassInIsolation).not.toHaveBeenCalled(); }); }); @@ -654,18 +645,6 @@ describe('DirectoryLoader', () => { expect(nodeWithIcon.description.icon).toBeUndefined(); }); - it('should skip node if included in excludeNodes', () => { - const loader = new CustomDirectoryLoader(directory, ['CUSTOM.node1']); - const filePath = 'dist/Node1/Node1.node.js'; - - loader.loadNodeFromFile(filePath); - - expect(loader.nodeTypes).toEqual({}); - expect(loader.known.nodes).toEqual({}); - expect(loader.types.nodes).toEqual([]); - expect(loader.loadedNodes).toEqual([]); - }); - it('should skip node if not in includeNodes', () => { const loader = new CustomDirectoryLoader(directory, [], ['CUSTOM.other']); const filePath = 'dist/Node1/Node1.node.js';