mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
refactor(core): Modularize community packages (#18641)
This commit is contained in:
@@ -22,7 +22,10 @@ describe('eligibleModules', () => {
|
||||
|
||||
it('should consider a module ineligible if it was disabled via env var', () => {
|
||||
process.env.N8N_DISABLED_MODULES = 'insights';
|
||||
expect(Container.get(ModuleRegistry).eligibleModules).toEqual(['external-secrets']);
|
||||
expect(Container.get(ModuleRegistry).eligibleModules).toEqual([
|
||||
'external-secrets',
|
||||
'community-packages',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should consider a module eligible if it was enabled via env var', () => {
|
||||
@@ -30,6 +33,7 @@ describe('eligibleModules', () => {
|
||||
expect(Container.get(ModuleRegistry).eligibleModules).toEqual([
|
||||
'insights',
|
||||
'external-secrets',
|
||||
'community-packages',
|
||||
'data-store',
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -26,7 +26,11 @@ export class ModuleRegistry {
|
||||
private readonly modulesConfig: ModulesConfig,
|
||||
) {}
|
||||
|
||||
private readonly defaultModules: ModuleName[] = ['insights', 'external-secrets'];
|
||||
private readonly defaultModules: ModuleName[] = [
|
||||
'insights',
|
||||
'external-secrets',
|
||||
'community-packages',
|
||||
];
|
||||
|
||||
private readonly activeModules: string[] = [];
|
||||
|
||||
@@ -83,7 +87,7 @@ export class ModuleRegistry {
|
||||
|
||||
if (entities?.length) this.entities.push(...entities);
|
||||
|
||||
const loadDir = Container.get(ModuleClass).loadDir?.();
|
||||
const loadDir = await Container.get(ModuleClass).loadDir?.();
|
||||
|
||||
if (loadDir) this.loadDirs.push(loadDir);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,12 @@ import { CommaSeparatedStringArray, Config, Env } from '@n8n/config';
|
||||
|
||||
import { UnknownModuleError } from './errors/unknown-module.error';
|
||||
|
||||
export const MODULE_NAMES = ['insights', 'external-secrets', 'data-store'] as const;
|
||||
export const MODULE_NAMES = [
|
||||
'insights',
|
||||
'external-secrets',
|
||||
'community-packages',
|
||||
'data-store',
|
||||
] as const;
|
||||
|
||||
export type ModuleName = (typeof MODULE_NAMES)[number];
|
||||
|
||||
|
||||
@@ -11,8 +11,6 @@ import { ExecutionEntity } from './execution-entity';
|
||||
import { ExecutionMetadata } from './execution-metadata';
|
||||
import { Folder } from './folder';
|
||||
import { FolderTagMapping } from './folder-tag-mapping';
|
||||
import { InstalledNodes } from './installed-nodes';
|
||||
import { InstalledPackages } from './installed-packages';
|
||||
import { InvalidAuthToken } from './invalid-auth-token';
|
||||
import { ProcessedData } from './processed-data';
|
||||
import { Project } from './project';
|
||||
@@ -35,8 +33,6 @@ import { WorkflowTagMapping } from './workflow-tag-mapping';
|
||||
|
||||
export {
|
||||
EventDestinations,
|
||||
InstalledNodes,
|
||||
InstalledPackages,
|
||||
InvalidAuthToken,
|
||||
ProcessedData,
|
||||
Settings,
|
||||
@@ -72,8 +68,6 @@ export {
|
||||
|
||||
export const entities = {
|
||||
EventDestinations,
|
||||
InstalledNodes,
|
||||
InstalledPackages,
|
||||
InvalidAuthToken,
|
||||
ProcessedData,
|
||||
Settings,
|
||||
|
||||
@@ -12,8 +12,6 @@ export { EventDestinationsRepository } from './event-destinations.repository';
|
||||
export { FolderRepository } from './folder.repository';
|
||||
export { FolderTagMappingRepository } from './folder-tag-mapping.repository';
|
||||
export { ScopeRepository } from './scope.repository';
|
||||
export { InstalledNodesRepository } from './installed-nodes.repository';
|
||||
export { InstalledPackagesRepository } from './installed-packages.repository';
|
||||
export { InvalidAuthTokenRepository } from './invalid-auth-token.repository';
|
||||
export { LicenseMetricsRepository } from './license-metrics.repository';
|
||||
export { ProjectRelationRepository } from './project-relation.repository';
|
||||
|
||||
@@ -33,10 +33,10 @@ export interface ModuleInterface {
|
||||
settings?(): Promise<ModuleSettings>;
|
||||
|
||||
/**
|
||||
* @returns Path to a dir to load nodes and credentials from.
|
||||
* @returns Path to a dir to load nodes and credentials from. `null` to skip.
|
||||
* @example '/Users/nathan/.n8n/nodes/node_modules'
|
||||
*/
|
||||
loadDir?(): string;
|
||||
loadDir?(): Promise<string | null>;
|
||||
}
|
||||
|
||||
export type ModuleClass = Constructable<ModuleInterface>;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { type InstalledNodes, type CredentialsEntity, type User } from '@n8n/db';
|
||||
import type { CredentialsEntity, User } from '@n8n/db';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
|
||||
import { CommunityNode } from '../community-node';
|
||||
import { CommunityNode } from '@/modules/community-packages/community-node.command';
|
||||
import type { InstalledNodes } from '@/modules/community-packages/installed-nodes.entity';
|
||||
|
||||
describe('uninstallCredential', () => {
|
||||
const userId = '1234';
|
||||
|
||||
@@ -8,12 +8,12 @@ import { mock } from 'jest-mock-extended';
|
||||
import type { IRun } from 'n8n-workflow';
|
||||
|
||||
import { ActiveExecutions } from '@/active-executions';
|
||||
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
import { DeprecationService } from '@/deprecation/deprecation.service';
|
||||
import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus';
|
||||
import { TelemetryEventRelay } from '@/events/relays/telemetry.event-relay';
|
||||
import { ExternalHooks } from '@/external-hooks';
|
||||
import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import { CommunityPackagesService } from '@/modules/community-packages/community-packages.service';
|
||||
import { PostHogClient } from '@/posthog';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { ShutdownService } from '@/shutdown/shutdown.service';
|
||||
|
||||
@@ -7,12 +7,12 @@ import { mock } from 'jest-mock-extended';
|
||||
import type { IRun } from 'n8n-workflow';
|
||||
|
||||
import { ActiveExecutions } from '@/active-executions';
|
||||
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
import { DeprecationService } from '@/deprecation/deprecation.service';
|
||||
import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus';
|
||||
import { TelemetryEventRelay } from '@/events/relays/telemetry.event-relay';
|
||||
import { ExternalHooks } from '@/external-hooks';
|
||||
import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import { CommunityPackagesService } from '@/modules/community-packages/community-packages.service';
|
||||
import { PostHogClient } from '@/posthog';
|
||||
import { OwnershipService } from '@/services/ownership.service';
|
||||
import { ShutdownService } from '@/shutdown/shutdown.service';
|
||||
|
||||
@@ -33,11 +33,11 @@ import { TelemetryEventRelay } from '@/events/relays/telemetry.event-relay';
|
||||
import { ExternalHooks } from '@/external-hooks';
|
||||
import { License } from '@/license';
|
||||
import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import { CommunityPackagesConfig } from '@/modules/community-packages/community-packages.config';
|
||||
import { NodeTypes } from '@/node-types';
|
||||
import { PostHogClient } from '@/posthog';
|
||||
import { ShutdownService } from '@/shutdown/shutdown.service';
|
||||
import { WorkflowHistoryManager } from '@/workflows/workflow-history.ee/workflow-history-manager.ee';
|
||||
import { CommunityPackagesConfig } from '@/community-packages/community-packages.config';
|
||||
|
||||
export abstract class BaseCommand<F = never> {
|
||||
readonly flags: F;
|
||||
@@ -133,10 +133,11 @@ export abstract class BaseCommand<F = never> {
|
||||
);
|
||||
}
|
||||
|
||||
// @TODO: Move to community-packages module
|
||||
const communityPackagesConfig = Container.get(CommunityPackagesConfig);
|
||||
if (communityPackagesConfig.enabled && this.needsCommunityPackages) {
|
||||
const { CommunityPackagesService } = await import(
|
||||
'@/community-packages/community-packages.service'
|
||||
'@/modules/community-packages/community-packages.service'
|
||||
);
|
||||
await Container.get(CommunityPackagesService).init();
|
||||
}
|
||||
|
||||
@@ -30,8 +30,6 @@ import { deepCopy, NodeConnectionTypes, UnexpectedError, UserError } from 'n8n-w
|
||||
import path from 'path';
|
||||
import picocolors from 'picocolors';
|
||||
|
||||
import { CommunityPackagesConfig } from './community-packages/community-packages.config';
|
||||
|
||||
import { CUSTOM_API_CALL_KEY, CUSTOM_API_CALL_NAME, CLI_DIR, inE2ETests } from '@/constants';
|
||||
|
||||
@Service()
|
||||
@@ -91,14 +89,6 @@ export class LoadNodesAndCredentials {
|
||||
await this.loadNodesFromNodeModules(nodeModulesDir, '@n8n/n8n-nodes-langchain');
|
||||
}
|
||||
|
||||
if (!Container.get(CommunityPackagesConfig).preventLoading) {
|
||||
// Load nodes from any other `n8n-nodes-*` packages in the download directory
|
||||
// This includes the community nodes
|
||||
await this.loadNodesFromNodeModules(
|
||||
path.join(this.instanceSettings.nodesDownloadDir, 'node_modules'),
|
||||
);
|
||||
}
|
||||
|
||||
for (const dir of this.moduleRegistry.loadDirs) {
|
||||
await this.loadNodesFromNodeModules(dir);
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import type { CommunityNodeType } from '@n8n/api-types';
|
||||
import type { InstalledPackages } from '@n8n/db';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
|
||||
import { CommunityPackagesController } from '@/community-packages/community-packages.controller';
|
||||
import { CommunityPackagesController } from '@/modules/community-packages/community-packages.controller';
|
||||
import type { NodeRequest } from '@/requests';
|
||||
|
||||
import type { EventService } from '../../events/event.service';
|
||||
import type { Push } from '../../push';
|
||||
import type { EventService } from '../../../events/event.service';
|
||||
import type { Push } from '../../../push';
|
||||
import type { CommunityNodeTypesService } from '../community-node-types.service';
|
||||
import type { CommunityPackagesService } from '../community-packages.service';
|
||||
import type { InstalledPackages } from '../installed-packages.entity';
|
||||
|
||||
describe('CommunityPackagesController', () => {
|
||||
const push = mock<Push>();
|
||||
@@ -1,21 +1,30 @@
|
||||
import { mockInstance } from '@n8n/backend-test-utils';
|
||||
import type { InstalledNodes, InstalledPackages } from '@n8n/db';
|
||||
import path from 'path';
|
||||
|
||||
import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
import { CommunityPackagesService } from '@/modules/community-packages/community-packages.service';
|
||||
import type { InstalledNodes } from '@/modules/community-packages/installed-nodes.entity';
|
||||
import type { InstalledPackages } from '@/modules/community-packages/installed-packages.entity';
|
||||
|
||||
import { COMMUNITY_PACKAGE_VERSION } from './shared/constants';
|
||||
import { createOwner } from './shared/db/users';
|
||||
import type { SuperAgentTest } from './shared/types';
|
||||
import { setupTestServer, mockPackage, mockNode, mockPackageName } from './shared/utils';
|
||||
import { COMMUNITY_PACKAGE_VERSION } from '../../../../test/integration/shared/constants';
|
||||
import { createOwner } from '../../../../test/integration/shared/db/users';
|
||||
import type { SuperAgentTest } from '../../../../test/integration/shared/types';
|
||||
import {
|
||||
setupTestServer,
|
||||
mockPackage,
|
||||
mockNode,
|
||||
mockPackageName,
|
||||
} from '../../../../test/integration/shared/utils';
|
||||
|
||||
const communityPackagesService = mockInstance(CommunityPackagesService, {
|
||||
hasMissingPackages: false,
|
||||
});
|
||||
mockInstance(LoadNodesAndCredentials);
|
||||
|
||||
const testServer = setupTestServer({ endpointGroups: ['community-packages'] });
|
||||
const testServer = setupTestServer({
|
||||
endpointGroups: ['community-packages'],
|
||||
modules: ['community-packages'],
|
||||
});
|
||||
|
||||
const commonUpdatesProps = {
|
||||
createdAt: new Date(),
|
||||
@@ -1,22 +1,15 @@
|
||||
import type { Logger } from '@n8n/backend-common';
|
||||
import { randomName, mockInstance } from '@n8n/backend-test-utils';
|
||||
import { LICENSE_FEATURES } from '@n8n/constants';
|
||||
import {
|
||||
InstalledNodes,
|
||||
InstalledPackages,
|
||||
InstalledNodesRepository,
|
||||
InstalledPackagesRepository,
|
||||
} from '@n8n/db';
|
||||
import axios from 'axios';
|
||||
import { exec } from 'child_process';
|
||||
import { mkdir, readFile, writeFile, rm, access, constants } from 'fs/promises';
|
||||
import { mocked } from 'jest-mock';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { InstanceSettings, PackageDirectoryLoader } from 'n8n-core';
|
||||
import type { PublicInstalledPackage } from 'n8n-workflow';
|
||||
import { exec } from 'node:child_process';
|
||||
import { mkdir, readFile, writeFile, rm, access, constants } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
import {
|
||||
NODE_PACKAGE_PREFIX,
|
||||
NPM_COMMAND_TOKENS,
|
||||
@@ -31,10 +24,15 @@ import { COMMUNITY_NODE_VERSION, COMMUNITY_PACKAGE_VERSION } from '@test-integra
|
||||
import { mockPackageName, mockPackagePair } from '@test-integration/utils';
|
||||
|
||||
import type { CommunityPackagesConfig } from '../community-packages.config';
|
||||
import { CommunityPackagesService } from '../community-packages.service';
|
||||
import type { CommunityPackages } from '../community-packages.types';
|
||||
import { InstalledNodes } from '../installed-nodes.entity';
|
||||
import { InstalledNodesRepository } from '../installed-nodes.repository';
|
||||
import { InstalledPackages } from '../installed-packages.entity';
|
||||
import { InstalledPackagesRepository } from '../installed-packages.repository';
|
||||
|
||||
jest.mock('fs/promises');
|
||||
jest.mock('child_process');
|
||||
jest.mock('node:fs/promises');
|
||||
jest.mock('node:child_process');
|
||||
jest.mock('axios');
|
||||
|
||||
type ExecOptions = NonNullable<Parameters<typeof exec>[1]>;
|
||||
@@ -2,7 +2,7 @@ import type { CommunityNodeType } from '@n8n/api-types';
|
||||
import { Get, RestController } from '@n8n/decorators';
|
||||
import { Request } from 'express';
|
||||
|
||||
import { CommunityNodeTypesService } from '@/community-packages/community-node-types.service';
|
||||
import { CommunityNodeTypesService } from './community-node-types.service';
|
||||
|
||||
@RestController('/community-node-types')
|
||||
export class CommunityNodeTypesController {
|
||||
@@ -3,9 +3,8 @@ import { Logger, inProduction } from '@n8n/backend-common';
|
||||
import { Service } from '@n8n/di';
|
||||
import { ensureError } from 'n8n-workflow';
|
||||
|
||||
import { CommunityPackagesConfig } from '@/community-packages/community-packages.config';
|
||||
|
||||
import { getCommunityNodeTypes, StrapiCommunityNodeType } from './community-node-types-utils';
|
||||
import { CommunityPackagesConfig } from './community-packages.config';
|
||||
import { CommunityPackagesService } from './community-packages.service';
|
||||
|
||||
const UPDATE_INTERVAL = 8 * 60 * 60 * 1000;
|
||||
@@ -1,13 +1,16 @@
|
||||
import { type InstalledNodes, type InstalledPackages, type User } from '@n8n/db';
|
||||
import { CredentialsRepository, InstalledNodesRepository, UserRepository } from '@n8n/db';
|
||||
import type { User } from '@n8n/db';
|
||||
import { CredentialsRepository, UserRepository } from '@n8n/db';
|
||||
import { Command } from '@n8n/decorators';
|
||||
import { Container } from '@n8n/di';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { BaseCommand } from '@/commands/base-command';
|
||||
import { CredentialsService } from '@/credentials/credentials.service';
|
||||
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
|
||||
import { BaseCommand } from './base-command';
|
||||
import { CommunityPackagesService } from './community-packages.service';
|
||||
import { InstalledNodes } from './installed-nodes.entity';
|
||||
import { InstalledNodesRepository } from './installed-nodes.repository';
|
||||
import { InstalledPackages } from './installed-packages.entity';
|
||||
|
||||
const flagsSchema = z.object({
|
||||
uninstall: z.boolean().describe('Uninstalls the node').optional(),
|
||||
@@ -1,21 +1,21 @@
|
||||
import { Delete, Get, Patch, Post, RestController, GlobalScope } from '@n8n/decorators';
|
||||
|
||||
import {
|
||||
RESPONSE_ERROR_MESSAGES,
|
||||
STARTER_TEMPLATE_NAME,
|
||||
UNKNOWN_FAILURE_REASON,
|
||||
} from '@/constants';
|
||||
import type { InstalledPackages } from '@n8n/db';
|
||||
import { Delete, Get, Patch, Post, RestController, GlobalScope } from '@n8n/decorators';
|
||||
|
||||
import type { CommunityPackages } from './community-packages.types';
|
||||
import { CommunityNodeTypesService } from './community-node-types.service';
|
||||
|
||||
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||
import { InternalServerError } from '@/errors/response-errors/internal-server.error';
|
||||
import { EventService } from '@/events/event.service';
|
||||
import { Push } from '@/push';
|
||||
import { NodeRequest } from '@/requests';
|
||||
|
||||
import { CommunityNodeTypesService } from './community-node-types.service';
|
||||
import { CommunityPackagesService } from './community-packages.service';
|
||||
import type { CommunityPackages } from './community-packages.types';
|
||||
import { InstalledPackages } from './installed-packages.entity';
|
||||
|
||||
const {
|
||||
PACKAGE_NOT_INSTALLED,
|
||||
PACKAGE_NAME_NOT_PROVIDED,
|
||||
@@ -0,0 +1,38 @@
|
||||
import type { EntityClass, ModuleInterface } from '@n8n/decorators';
|
||||
import { BackendModule } from '@n8n/decorators';
|
||||
import { Container } from '@n8n/di';
|
||||
import { InstanceSettings } from 'n8n-core';
|
||||
import path from 'node:path';
|
||||
|
||||
@BackendModule({ name: 'community-packages' })
|
||||
export class CommunityPackagesModule implements ModuleInterface {
|
||||
async init() {
|
||||
await import('./community-packages.controller');
|
||||
}
|
||||
|
||||
async entities() {
|
||||
const { InstalledNodes } = await import('./installed-nodes.entity');
|
||||
const { InstalledPackages } = await import('./installed-packages.entity');
|
||||
|
||||
return [InstalledNodes, InstalledPackages] as EntityClass[];
|
||||
}
|
||||
|
||||
async settings() {
|
||||
const { CommunityPackagesConfig } = await import('./community-packages.config');
|
||||
|
||||
return {
|
||||
communityNodesEnabled: Container.get(CommunityPackagesConfig).enabled,
|
||||
unverifiedCommunityNodesEnabled: Container.get(CommunityPackagesConfig).unverifiedEnabled,
|
||||
};
|
||||
}
|
||||
|
||||
async loadDir() {
|
||||
const { CommunityPackagesConfig } = await import('./community-packages.config');
|
||||
|
||||
const { preventLoading } = Container.get(CommunityPackagesConfig);
|
||||
|
||||
if (preventLoading) return null;
|
||||
|
||||
return path.join(Container.get(InstanceSettings).nodesDownloadDir, 'node_modules');
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,15 @@
|
||||
import { Logger } from '@n8n/backend-common';
|
||||
import { LICENSE_FEATURES } from '@n8n/constants';
|
||||
import type { InstalledPackages } from '@n8n/db';
|
||||
import { InstalledPackagesRepository } from '@n8n/db';
|
||||
import { OnPubSubEvent } from '@n8n/decorators';
|
||||
import { Service } from '@n8n/di';
|
||||
import axios from 'axios';
|
||||
import { exec } from 'child_process';
|
||||
import { access, constants, mkdir, readFile, rm, writeFile } from 'fs/promises';
|
||||
import type { PackageDirectoryLoader } from 'n8n-core';
|
||||
import { InstanceSettings } from 'n8n-core';
|
||||
import { jsonParse, UnexpectedError, UserError, type PublicInstalledPackage } from 'n8n-workflow';
|
||||
import { join } from 'path';
|
||||
import { promisify } from 'util';
|
||||
import { exec } from 'node:child_process';
|
||||
import { access, constants, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { promisify } from 'node:util';
|
||||
|
||||
import {
|
||||
NODE_PACKAGE_PREFIX,
|
||||
@@ -28,6 +26,8 @@ import { toError } from '@/utils';
|
||||
|
||||
import { CommunityPackagesConfig } from './community-packages.config';
|
||||
import type { CommunityPackages } from './community-packages.types';
|
||||
import { InstalledPackages } from './installed-packages.entity';
|
||||
import { InstalledPackagesRepository } from './installed-packages.repository';
|
||||
import { isVersionExists, verifyIntegrity } from './npm-utils';
|
||||
|
||||
const DEFAULT_REGISTRY = 'https://registry.npmjs.org';
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from '@n8n/typeorm';
|
||||
import { BaseEntity, Column, Entity, JoinColumn, ManyToOne, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import { InstalledPackages } from './installed-packages';
|
||||
import { InstalledPackages } from './installed-packages.entity';
|
||||
|
||||
@Entity()
|
||||
export class InstalledNodes {
|
||||
export class InstalledNodes extends BaseEntity {
|
||||
@Column()
|
||||
name: string;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Service } from '@n8n/di';
|
||||
import { DataSource, Repository } from '@n8n/typeorm';
|
||||
|
||||
import { InstalledNodes } from '../entities';
|
||||
import { InstalledNodes } from './installed-nodes.entity';
|
||||
|
||||
@Service()
|
||||
export class InstalledNodesRepository extends Repository<InstalledNodes> {
|
||||
@@ -1,7 +1,7 @@
|
||||
import { WithTimestamps } from '@n8n/db';
|
||||
import { Column, Entity, JoinColumn, OneToMany, PrimaryColumn } from '@n8n/typeorm';
|
||||
|
||||
import { WithTimestamps } from './abstract-entity';
|
||||
import type { InstalledNodes } from './installed-nodes';
|
||||
import type { InstalledNodes } from './installed-nodes.entity';
|
||||
|
||||
@Entity()
|
||||
export class InstalledPackages extends WithTimestamps {
|
||||
@@ -3,7 +3,7 @@ import { DataSource, Repository } from '@n8n/typeorm';
|
||||
import type { PackageDirectoryLoader } from 'n8n-core';
|
||||
|
||||
import { InstalledNodesRepository } from './installed-nodes.repository';
|
||||
import { InstalledPackages } from '../entities';
|
||||
import { InstalledPackages } from './installed-packages.entity';
|
||||
|
||||
@Service()
|
||||
export class InstalledPackagesRepository extends Repository<InstalledPackages> {
|
||||
@@ -7,6 +7,7 @@ import { InstanceSettings } from 'n8n-core';
|
||||
import type { IWorkflowBase } from 'n8n-workflow';
|
||||
|
||||
import { N8N_VERSION } from '@/constants';
|
||||
import { CommunityPackagesConfig } from '@/modules/community-packages/community-packages.config';
|
||||
import { isApiEnabled } from '@/public-api';
|
||||
import {
|
||||
ENV_VARS_DOCS_URL,
|
||||
@@ -16,7 +17,6 @@ import {
|
||||
} from '@/security-audit/constants';
|
||||
import type { RiskReporter, Risk, n8n } from '@/security-audit/types';
|
||||
import { toFlaggedNode } from '@/security-audit/utils';
|
||||
import { CommunityPackagesConfig } from '@/community-packages/community-packages.config';
|
||||
|
||||
@Service()
|
||||
export class InstanceRiskReporter implements RiskReporter {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { InstalledPackages } from '@n8n/db';
|
||||
import { Service } from '@n8n/di';
|
||||
// eslint-disable-next-line n8n-local-rules/misplaced-n8n-typeorm-import
|
||||
import { DataSource, Repository } from '@n8n/typeorm';
|
||||
|
||||
import { InstalledPackages } from '@/modules/community-packages/installed-packages.entity';
|
||||
|
||||
@Service()
|
||||
export class PackagesRepository extends Repository<InstalledPackages> {
|
||||
constructor(dataSource: DataSource) {
|
||||
|
||||
@@ -65,7 +65,6 @@ import '@/webhooks/webhooks.controller';
|
||||
|
||||
import { ChatServer } from './chat/chat-server';
|
||||
import { MfaService } from './mfa/mfa.service';
|
||||
import { CommunityPackagesConfig } from './community-packages/community-packages.config';
|
||||
|
||||
@Service()
|
||||
export class Server extends AbstractServer {
|
||||
@@ -119,11 +118,6 @@ export class Server extends AbstractServer {
|
||||
await Container.get(LdapService).init();
|
||||
}
|
||||
|
||||
if (Container.get(CommunityPackagesConfig).enabled) {
|
||||
await import('@/community-packages/community-packages.controller');
|
||||
await import('@/community-packages/community-node-types.controller');
|
||||
}
|
||||
|
||||
if (inE2ETests) {
|
||||
await import('@/controllers/e2e.controller');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Logger, LicenseState, ModuleRegistry } from '@n8n/backend-common';
|
||||
import type { GlobalConfig, SecurityConfig } from '@n8n/config';
|
||||
import { Container } from '@n8n/di';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { InstanceSettings, BinaryDataConfig } from 'n8n-core';
|
||||
|
||||
@@ -8,12 +9,11 @@ import type { CredentialsOverwrites } from '@/credentials-overwrites';
|
||||
import type { License } from '@/license';
|
||||
import type { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import type { MfaService } from '@/mfa/mfa.service';
|
||||
import { CommunityPackagesConfig } from '@/modules/community-packages/community-packages.config';
|
||||
import type { PushConfig } from '@/push/push.config';
|
||||
import { FrontendService } from '@/services/frontend.service';
|
||||
import type { UrlService } from '@/services/url.service';
|
||||
import type { UserManagementMailer } from '@/user-management/email';
|
||||
import { CommunityPackagesConfig } from '@/community-packages/community-packages.config';
|
||||
import { Container } from '@n8n/di';
|
||||
|
||||
describe('FrontendService', () => {
|
||||
let originalEnv: NodeJS.ProcessEnv;
|
||||
|
||||
@@ -10,8 +10,6 @@ import { BinaryDataConfig, InstanceSettings } from 'n8n-core';
|
||||
import type { ICredentialType, INodeTypeBaseDescription } from 'n8n-workflow';
|
||||
import path from 'path';
|
||||
|
||||
import { CommunityPackagesConfig } from '@/community-packages/community-packages.config';
|
||||
import type { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
import config from '@/config';
|
||||
import { inE2ETests, N8N_VERSION } from '@/constants';
|
||||
import { CredentialTypes } from '@/credential-types';
|
||||
@@ -20,6 +18,8 @@ import { getLdapLoginLabel } from '@/ldap.ee/helpers.ee';
|
||||
import { License } from '@/license';
|
||||
import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import { MfaService } from '@/mfa/mfa.service';
|
||||
import { CommunityPackagesConfig } from '@/modules/community-packages/community-packages.config';
|
||||
import type { CommunityPackagesService } from '@/modules/community-packages/community-packages.service';
|
||||
import { isApiEnabled } from '@/public-api';
|
||||
import { PushConfig } from '@/push/push.config';
|
||||
import { getSamlLoginLabel } from '@/sso.ee/saml/saml-helpers';
|
||||
@@ -60,8 +60,9 @@ export class FrontendService {
|
||||
|
||||
this.initSettings();
|
||||
|
||||
// @TODO: Move to community-packages module
|
||||
if (Container.get(CommunityPackagesConfig).enabled) {
|
||||
void import('@/community-packages/community-packages.service').then(
|
||||
void import('@/modules/community-packages/community-packages.service').then(
|
||||
({ CommunityPackagesService }) => {
|
||||
this.communityPackagesService = Container.get(CommunityPackagesService);
|
||||
},
|
||||
@@ -200,8 +201,11 @@ export class FrontendService {
|
||||
executionMode: config.getEnv('executions.mode'),
|
||||
isMultiMain: this.instanceSettings.isMultiMain,
|
||||
pushBackend: this.pushConfig.backend,
|
||||
|
||||
// @TODO: Move to community-packages module
|
||||
communityNodesEnabled: Container.get(CommunityPackagesConfig).enabled,
|
||||
unverifiedCommunityNodesEnabled: Container.get(CommunityPackagesConfig).unverifiedEnabled,
|
||||
|
||||
deployment: {
|
||||
type: this.globalConfig.deployment.type,
|
||||
},
|
||||
|
||||
@@ -12,11 +12,11 @@ import { LogStreamingEventRelay } from '@/events/relays/log-streaming.event-rela
|
||||
import { ExternalHooks } from '@/external-hooks';
|
||||
import { License } from '@/license';
|
||||
import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import { CommunityPackagesService } from '@/modules/community-packages/community-packages.service';
|
||||
import { Push } from '@/push';
|
||||
import { Publisher } from '@/scaling/pubsub/publisher.service';
|
||||
import { Subscriber } from '@/scaling/pubsub/subscriber.service';
|
||||
import { ScalingService } from '@/scaling/scaling.service';
|
||||
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
import { TaskBrokerServer } from '@/task-runners/task-broker/task-broker-server';
|
||||
import { TaskRunnerProcess } from '@/task-runners/task-runner-process';
|
||||
import { Telemetry } from '@/telemetry';
|
||||
|
||||
@@ -5,12 +5,12 @@ import { mock } from 'jest-mock-extended';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import { LoadNodesAndCredentials } from '@/load-nodes-and-credentials';
|
||||
import { CommunityPackagesService } from '@/modules/community-packages/community-packages.service';
|
||||
import { NodeTypes } from '@/node-types';
|
||||
import { OFFICIAL_RISKY_NODE_TYPES, NODES_REPORT } from '@/security-audit/constants';
|
||||
import { PackagesRepository } from '@/security-audit/security-audit.repository';
|
||||
import { SecurityAuditService } from '@/security-audit/security-audit.service';
|
||||
import { toReportTitle } from '@/security-audit/utils';
|
||||
import { CommunityPackagesService } from '@/community-packages/community-packages.service';
|
||||
|
||||
import { getRiskSection, MOCK_PACKAGE, saveManualTriggerWorkflow } from './utils';
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { GlobalConfig } from '@n8n/config';
|
||||
import type { InstalledNodes, InstalledPackages } from '@n8n/db';
|
||||
import { WorkflowRepository } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
import nock from 'nock';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
import * as constants from '@/constants';
|
||||
import type { InstalledNodes } from '@/modules/community-packages/installed-nodes.entity';
|
||||
import type { InstalledPackages } from '@/modules/community-packages/installed-packages.entity';
|
||||
import type { Risk } from '@/security-audit/types';
|
||||
import { toReportTitle } from '@/security-audit/utils';
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ type EndpointGroup =
|
||||
| 'data-store'
|
||||
| 'module-settings';
|
||||
|
||||
type ModuleName = 'insights' | 'external-secrets' | 'data-store';
|
||||
type ModuleName = 'insights' | 'external-secrets' | 'community-packages' | 'data-store';
|
||||
|
||||
export interface SetupProps {
|
||||
endpointGroups?: EndpointGroup[];
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import { randomName } from '@n8n/backend-test-utils';
|
||||
import { InstalledPackages, InstalledNodesRepository, InstalledPackagesRepository } from '@n8n/db';
|
||||
import { Container } from '@n8n/di';
|
||||
|
||||
import { NODE_PACKAGE_PREFIX } from '@/constants';
|
||||
import { InstalledNodesRepository } from '@/modules/community-packages/installed-nodes.repository';
|
||||
import { InstalledPackages } from '@/modules/community-packages/installed-packages.entity';
|
||||
import { InstalledPackagesRepository } from '@/modules/community-packages/installed-packages.repository';
|
||||
|
||||
import { COMMUNITY_NODE_VERSION, COMMUNITY_PACKAGE_VERSION } from '../constants';
|
||||
|
||||
|
||||
@@ -232,7 +232,7 @@ export const setupTestServer = ({
|
||||
break;
|
||||
|
||||
case 'community-packages':
|
||||
await import('@/community-packages/community-packages.controller');
|
||||
await import('@/modules/community-packages/community-packages.controller');
|
||||
break;
|
||||
|
||||
case 'me':
|
||||
|
||||
Reference in New Issue
Block a user