Skip to content

Commit

Permalink
fix(core): Prevent backend from loading duplicate copies of nodes pac…
Browse files Browse the repository at this point in the history
…kages (#10979)
  • Loading branch information
netroy authored Sep 26, 2024
1 parent 1944b46 commit 4584f22
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
9 changes: 9 additions & 0 deletions packages/cli/src/load-nodes-and-credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import type {
} from 'n8n-workflow';
import { NodeHelpers, ApplicationError, ErrorReporterProxy as ErrorReporter } from 'n8n-workflow';
import path from 'path';
import picocolors from 'picocolors';
import { Container, Service } from 'typedi';

import {
Expand Down Expand Up @@ -146,6 +147,7 @@ export class LoadNodesAndCredentials {
path.join(nodeModulesDir, packagePath),
);
} catch (error) {
this.logger.error((error as Error).message);
ErrorReporter.error(error);
}
}
Expand Down Expand Up @@ -258,6 +260,13 @@ export class LoadNodesAndCredentials {
dir: string,
) {
const loader = new constructor(dir, this.excludeNodes, this.includeNodes);
if (loader.packageName in this.loaders) {
throw new ApplicationError(
picocolors.red(
`nodes package ${loader.packageName} is already loaded.\n Please delete this second copy at path ${dir}`,
),
);
}
await loader.loadAll();
this.loaders[loader.packageName] = loader;
return loader;
Expand Down
27 changes: 15 additions & 12 deletions packages/core/src/DirectoryLoader.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import glob from 'fast-glob';
import { readFile } from 'fs/promises';
import { readFileSync } from 'node:fs';
import { readFile } from 'node:fs/promises';
import type {
CodexData,
DocumentationLink,
Expand Down Expand Up @@ -350,18 +351,11 @@ export class CustomDirectoryLoader extends DirectoryLoader {
* e.g. /nodes-base or community packages.
*/
export class PackageDirectoryLoader extends DirectoryLoader {
packageName = '';
packageJson: n8n.PackageJson = this.readJSONSync('package.json');

packageJson!: n8n.PackageJson;

async readPackageJson() {
this.packageJson = await this.readJSON('package.json');
this.packageName = this.packageJson.name;
}
packageName = this.packageJson.name;

override async loadAll() {
await this.readPackageJson();

const { n8n } = this.packageJson;
if (!n8n) return;

Expand Down Expand Up @@ -391,6 +385,17 @@ export class PackageDirectoryLoader extends DirectoryLoader {
});
}

protected readJSONSync<T>(file: string): T {
const filePath = this.resolvePath(file);
const fileString = readFileSync(filePath, 'utf8');

try {
return jsonParse<T>(fileString);
} catch (error) {
throw new ApplicationError('Failed to parse JSON', { extra: { filePath } });
}
}

protected async readJSON<T>(file: string): Promise<T> {
const filePath = this.resolvePath(file);
const fileString = await readFile(filePath, 'utf8');
Expand All @@ -408,8 +413,6 @@ export class PackageDirectoryLoader extends DirectoryLoader {
*/
export class LazyPackageDirectoryLoader extends PackageDirectoryLoader {
override async loadAll() {
await this.readPackageJson();

try {
const knownNodes: typeof this.known.nodes = await this.readJSON('dist/known/nodes.json');
for (const nodeName in knownNodes) {
Expand Down

0 comments on commit 4584f22

Please sign in to comment.