fix(core): Fix node exclusion on the frontend types (#12544)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2025-01-10 15:13:31 +01:00 committed by GitHub
parent 68da9bb164
commit b2cbed9865
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 32 additions and 42 deletions

View file

@ -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(

View file

@ -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';