fix: Make nodes.exclude and nodes.include work with lazy-loaded nodes (#4833)

This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™ 2022-12-06 19:15:15 +01:00 committed by GitHub
parent a09ff27f43
commit 85241fd230
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 45 deletions

View file

@ -1,8 +1,32 @@
/* eslint-disable no-restricted-syntax */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import path from 'path';
import * as core from 'n8n-core';
import convict from 'convict';
import { UserSettings } from 'n8n-core';
import { jsonParse } from 'n8n-workflow';
convict.addFormat({
name: 'nodes-list',
// @ts-ignore
validate(values: string[], { env }: { env: string }): void {
try {
if (!Array.isArray(values)) {
throw new Error();
}
for (const value of values) {
if (typeof value !== 'string') {
throw new Error();
}
}
} catch (error) {
throw new TypeError(`${env} is not a valid Array of strings.`);
}
},
coerce(rawValue: string): string[] {
return jsonParse(rawValue, { errorMessage: 'nodes-list needs to be valid JSON' });
},
});
export const schema = {
database: {
@ -716,47 +740,14 @@ export const schema = {
nodes: {
include: {
doc: 'Nodes to load',
format: function check(rawValue: string): void {
if (rawValue === '') {
return;
}
try {
const values = JSON.parse(rawValue);
if (!Array.isArray(values)) {
throw new Error();
}
for (const value of values) {
if (typeof value !== 'string') {
throw new Error();
}
}
} catch (error) {
throw new TypeError(`The Nodes to include is not a valid Array of strings.`);
}
},
format: 'nodes-list',
default: undefined,
env: 'NODES_INCLUDE',
},
exclude: {
doc: 'Nodes not to load',
format: function check(rawValue: string): void {
try {
const values = JSON.parse(rawValue);
if (!Array.isArray(values)) {
throw new Error();
}
for (const value of values) {
if (typeof value !== 'string') {
throw new Error();
}
}
} catch (error) {
throw new TypeError(`The Nodes to exclude is not a valid Array of strings.`);
}
},
default: '[]',
format: 'nodes-list',
default: undefined,
env: 'NODES_EXCLUDE',
},
errorTriggerType: {
@ -804,7 +795,7 @@ export const schema = {
location: {
doc: 'Log file location; only used if log output is set to file.',
format: String,
default: path.join(core.UserSettings.getUserN8nFolderPath(), 'logs/n8n.log'),
default: path.join(UserSettings.getUserN8nFolderPath(), 'logs/n8n.log'),
env: 'N8N_LOG_FILE_LOCATION',
},
},
@ -861,7 +852,7 @@ export const schema = {
},
localStoragePath: {
format: String,
default: path.join(core.UserSettings.getUserN8nFolderPath(), 'binaryData'),
default: path.join(UserSettings.getUserN8nFolderPath(), 'binaryData'),
env: 'N8N_BINARY_DATA_STORAGE_PATH',
doc: 'Path for binary data storage in "filesystem" mode',
},

View file

@ -77,7 +77,8 @@ type ToReturnType<T extends ConfigOptionPath> = T extends NumericPath
type ExceptionPaths = {
'queue.bull.redis': object;
binaryDataManager: IBinaryDataConfig;
'nodes.include': undefined;
'nodes.exclude': string[] | undefined;
'nodes.include': string[] | undefined;
'userManagement.isInstanceOwnerSetUp': boolean;
'userManagement.skipInstanceOwnerSetup': boolean;
};

View file

@ -43,8 +43,8 @@ export abstract class DirectoryLoader {
constructor(
protected readonly directory: string,
private readonly excludeNodes?: string,
private readonly includeNodes?: string,
protected readonly excludeNodes: string[] = [],
protected readonly includeNodes: string[] = [],
) {}
abstract loadAll(): Promise<void>;
@ -69,11 +69,11 @@ export abstract class DirectoryLoader {
const fullNodeName = `${packageName}.${tempNode.description.name}`;
if (this.includeNodes !== undefined && !this.includeNodes.includes(fullNodeName)) {
if (this.includeNodes.length && !this.includeNodes.includes(fullNodeName)) {
return;
}
if (this.excludeNodes?.includes(fullNodeName)) {
if (this.excludeNodes.includes(fullNodeName)) {
return;
}
@ -338,6 +338,28 @@ export class LazyPackageDirectoryLoader extends PackageDirectoryLoader {
this.types.nodes = await this.readJSON('dist/types/nodes.json');
this.types.credentials = await this.readJSON('dist/types/credentials.json');
if (this.includeNodes.length) {
const allowedNodes: typeof this.known.nodes = {};
for (const nodeName of this.includeNodes) {
allowedNodes[nodeName] = this.known.nodes[nodeName];
}
this.known.nodes = allowedNodes;
this.types.nodes = this.types.nodes.filter((nodeType) =>
this.includeNodes.includes(nodeType.name),
);
}
if (this.excludeNodes.length) {
for (const nodeName of this.excludeNodes) {
delete this.known.nodes[nodeName];
}
this.types.nodes = this.types.nodes.filter(
(nodeType) => !this.excludeNodes.includes(nodeType.name),
);
}
Logger.debug(`Lazy Loading credentials and nodes from ${this.packageJson.name}`, {
credentials: this.types.credentials?.length ?? 0,
nodes: this.types.nodes?.length ?? 0,