Skip to content

Commit 1d31e6a

Browse files
authored
refactor(core): Start modularizing the community packages feature (#17757)
1 parent 1ed8239 commit 1d31e6a

35 files changed

+171
-172
lines changed

packages/@n8n/backend-common/tsconfig.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,12 @@
88
"experimentalDecorators": true,
99
"emitDecoratorMetadata": true
1010
},
11-
"include": ["src/**/*.ts"]
11+
"include": ["src/**/*.ts"],
12+
"references": [
13+
{ "path": "../../workflow/tsconfig.build.cjs.json" },
14+
{ "path": "../config/tsconfig.build.json" },
15+
{ "path": "../constants/tsconfig.build.json" },
16+
{ "path": "../decorators/tsconfig.build.json" },
17+
{ "path": "../di/tsconfig.build.json" }
18+
]
1219
}

packages/@n8n/config/src/configs/logging.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const LOG_SCOPES = [
2020
'workflow-activation',
2121
'ssh-client',
2222
'cron',
23+
'community-nodes',
2324
] as const;
2425

2526
export type LogScope = (typeof LOG_SCOPES)[number];
Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Config, Env, Nested } from '../decorators';
1+
import { Config, Env } from '../decorators';
22

33
function isStringArray(input: unknown): input is string[] {
44
return Array.isArray(input) && input.every((item) => typeof item === 'string');
@@ -20,33 +20,6 @@ class JsonStringArray extends Array<string> {
2020
}
2121
}
2222

23-
@Config
24-
class CommunityPackagesConfig {
25-
/** Whether to enable community packages */
26-
@Env('N8N_COMMUNITY_PACKAGES_ENABLED')
27-
enabled: boolean = true;
28-
29-
/** NPM registry URL to pull community packages from */
30-
@Env('N8N_COMMUNITY_PACKAGES_REGISTRY')
31-
registry: string = 'https://registry.npmjs.org';
32-
33-
/** Whether to reinstall any missing community packages */
34-
@Env('N8N_REINSTALL_MISSING_PACKAGES')
35-
reinstallMissing: boolean = false;
36-
37-
/** Whether to block installation of not verified packages */
38-
@Env('N8N_UNVERIFIED_PACKAGES_ENABLED')
39-
unverifiedEnabled: boolean = true;
40-
41-
/** Whether to enable and show search suggestion of packages verified by n8n */
42-
@Env('N8N_VERIFIED_PACKAGES_ENABLED')
43-
verifiedEnabled: boolean = true;
44-
45-
/** Whether to load community packages */
46-
@Env('N8N_COMMUNITY_PACKAGES_PREVENT_LOADING')
47-
preventLoading: boolean = false;
48-
}
49-
5023
@Config
5124
export class NodesConfig {
5225
/** Node types to load. Includes all if unspecified. @example '["n8n-nodes-base.hackerNews"]' */
@@ -64,7 +37,4 @@ export class NodesConfig {
6437
/** Whether to enable Python execution on the Code node. */
6538
@Env('N8N_PYTHON_ENABLED')
6639
pythonEnabled: boolean = true;
67-
68-
@Nested
69-
communityPackages: CommunityPackagesConfig;
7040
}

packages/@n8n/config/test/config.test.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,6 @@ describe('GlobalConfig', () => {
138138
files: [],
139139
},
140140
nodes: {
141-
communityPackages: {
142-
enabled: true,
143-
registry: 'https://registry.npmjs.org',
144-
reinstallMissing: false,
145-
unverifiedEnabled: true,
146-
verifiedEnabled: true,
147-
preventLoading: false,
148-
},
149141
errorTriggerType: 'n8n-nodes-base.errorTrigger',
150142
include: [],
151143
exclude: [],

packages/cli/src/commands/__tests__/execute-batch.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ import { GlobalConfig } from '@n8n/config';
33
import type { User, WorkflowEntity } from '@n8n/db';
44
import { WorkflowRepository, DbConnection } from '@n8n/db';
55
import { Container } from '@n8n/di';
6-
import type { SelectQueryBuilder } from '@n8n/typeorm';
6+
import { type SelectQueryBuilder } from '@n8n/typeorm';
77
import { mock } from 'jest-mock-extended';
88
import type { IRun } from 'n8n-workflow';
99

1010
import { ActiveExecutions } from '@/active-executions';
11+
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
1112
import { DeprecationService } from '@/deprecation/deprecation.service';
1213
import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus';
1314
import { TelemetryEventRelay } from '@/events/relays/telemetry.event-relay';
@@ -33,6 +34,7 @@ mockInstance(MessageEventBus);
3334
const posthogClient = mockInstance(PostHogClient);
3435
const telemetryEventRelay = mockInstance(TelemetryEventRelay);
3536
const externalHooks = mockInstance(ExternalHooks);
37+
mockInstance(CommunityPackagesService);
3638

3739
const dbConnection = mockInstance(DbConnection);
3840
dbConnection.init.mockResolvedValue(undefined);
@@ -69,7 +71,7 @@ test('should start a task runner when task runners are enabled', async () => {
6971
GlobalConfig,
7072
mock<GlobalConfig>({
7173
taskRunners: { enabled: true },
72-
nodes: { communityPackages: { enabled: false } },
74+
nodes: {},
7375
}),
7476
);
7577

packages/cli/src/commands/__tests__/execute.test.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { mock } from 'jest-mock-extended';
77
import type { IRun } from 'n8n-workflow';
88

99
import { ActiveExecutions } from '@/active-executions';
10+
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
1011
import { DeprecationService } from '@/deprecation/deprecation.service';
1112
import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus';
1213
import { TelemetryEventRelay } from '@/events/relays/telemetry.event-relay';
@@ -32,6 +33,7 @@ mockInstance(MessageEventBus);
3233
const posthogClient = mockInstance(PostHogClient);
3334
const telemetryEventRelay = mockInstance(TelemetryEventRelay);
3435
const externalHooks = mockInstance(ExternalHooks);
36+
mockInstance(CommunityPackagesService);
3537

3638
const dbConnection = mockInstance(DbConnection);
3739
dbConnection.init.mockResolvedValue(undefined);
@@ -63,7 +65,7 @@ test('should start a task runner when task runners are enabled', async () => {
6365
GlobalConfig,
6466
mock<GlobalConfig>({
6567
taskRunners: { enabled: true },
66-
nodes: { communityPackages: { enabled: false } },
68+
nodes: {},
6769
}),
6870
);
6971

packages/cli/src/commands/base-command.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import { NodeTypes } from '@/node-types';
3737
import { PostHogClient } from '@/posthog';
3838
import { ShutdownService } from '@/shutdown/shutdown.service';
3939
import { WorkflowHistoryManager } from '@/workflows/workflow-history.ee/workflow-history-manager.ee';
40+
import { CommunityPackagesConfig } from '@/community-packages/community-packages.config';
4041

4142
export abstract class BaseCommand<F = never> {
4243
readonly flags: F;
@@ -132,9 +133,11 @@ export abstract class BaseCommand<F = never> {
132133
);
133134
}
134135

135-
const { communityPackages } = this.globalConfig.nodes;
136-
if (communityPackages.enabled && this.needsCommunityPackages) {
137-
const { CommunityPackagesService } = await import('@/services/community-packages.service');
136+
const communityPackagesConfig = Container.get(CommunityPackagesConfig);
137+
if (communityPackagesConfig.enabled && this.needsCommunityPackages) {
138+
const { CommunityPackagesService } = await import(
139+
'@/community-packages/community-packages.service'
140+
);
138141
await Container.get(CommunityPackagesService).init();
139142
}
140143

packages/cli/src/commands/community-node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Container } from '@n8n/di';
55
import { z } from 'zod';
66

77
import { CredentialsService } from '@/credentials/credentials.service';
8-
import { CommunityPackagesService } from '@/services/community-packages.service';
8+
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
99

1010
import { BaseCommand } from './base-command';
1111

packages/cli/src/commands/start.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import { ExecutionsPruningService } from '@/services/pruning/executions-pruning.
3333
import { UrlService } from '@/services/url.service';
3434
import { WaitTracker } from '@/wait-tracker';
3535
import { WorkflowRunner } from '@/workflow-runner';
36+
import { CommunityPackagesConfig } from '@/community-packages/community-packages.config';
3637

3738
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
3839
const open = require('open');
@@ -178,14 +179,14 @@ export class Start extends BaseCommand<z.infer<typeof flagsSchema>> {
178179
}
179180

180181
const { flags } = this;
181-
const { communityPackages } = this.globalConfig.nodes;
182+
const communityPackagesConfig = Container.get(CommunityPackagesConfig);
182183
// cli flag overrides the config env variable
183184
if (flags.reinstallMissingPackages) {
184-
if (communityPackages.enabled) {
185+
if (communityPackagesConfig.enabled) {
185186
this.logger.warn(
186187
'`--reinstallMissingPackages` is deprecated: Please use the env variable `N8N_REINSTALL_MISSING_PACKAGES` instead',
187188
);
188-
communityPackages.reinstallMissing = true;
189+
communityPackagesConfig.reinstallMissing = true;
189190
} else {
190191
this.logger.warn(
191192
'`--reinstallMissingPackages` was passed, but community packages are disabled',

packages/cli/src/services/__tests__/community-node-types.service.test.ts renamed to packages/cli/src/community-packages/__tests__/community-node-types.service.test.ts

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import { inProduction } from '@n8n/backend-common';
22

3-
import { getCommunityNodeTypes } from '../../utils/community-node-types-utils';
3+
import { getCommunityNodeTypes } from '../community-node-types-utils';
44
import { CommunityNodeTypesService } from '../community-node-types.service';
55

66
jest.mock('@n8n/backend-common', () => ({
77
...jest.requireActual('@n8n/backend-common'),
88
inProduction: jest.fn().mockReturnValue(false),
99
}));
1010

11-
jest.mock('../../utils/community-node-types-utils', () => ({
11+
jest.mock('../community-node-types-utils', () => ({
1212
getCommunityNodeTypes: jest.fn().mockResolvedValue([]),
1313
}));
1414

1515
describe('CommunityNodeTypesService', () => {
1616
let service: CommunityNodeTypesService;
17-
let globalConfigMock: any;
17+
let configMock: any;
1818
let communityPackagesServiceMock: any;
1919
let loggerMock: any;
2020

@@ -24,21 +24,13 @@ describe('CommunityNodeTypesService', () => {
2424
delete process.env.ENVIRONMENT;
2525

2626
loggerMock = { error: jest.fn() };
27-
globalConfigMock = {
28-
nodes: {
29-
communityPackages: {
30-
enabled: true,
31-
verifiedEnabled: true,
32-
},
33-
},
27+
configMock = {
28+
enabled: true,
29+
verifiedEnabled: true,
3430
};
3531
communityPackagesServiceMock = {};
3632

37-
service = new CommunityNodeTypesService(
38-
loggerMock,
39-
globalConfigMock,
40-
communityPackagesServiceMock,
41-
);
33+
service = new CommunityNodeTypesService(loggerMock, configMock, communityPackagesServiceMock);
4234
});
4335

4436
describe('fetchNodeTypes', () => {

0 commit comments

Comments
 (0)