refactor(core): Overhaul commands setup. Add support for module commands (#16709)

Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
कारतोफ्फेलस्क्रिप्ट™
2025-07-01 19:14:22 +02:00
committed by GitHub
parent 346bc84093
commit 9f8d3d3bc8
41 changed files with 1061 additions and 541 deletions

View File

@@ -11,7 +11,6 @@ import { GlobalConfig } from '@n8n/config';
import { LICENSE_FEATURES } from '@n8n/constants';
import { DbConnection } from '@n8n/db';
import { Container } from '@n8n/di';
import { Command, Errors } from '@oclif/core';
import {
BinaryDataConfig,
BinaryDataService,
@@ -20,7 +19,7 @@ import {
DataDeduplicationService,
ErrorReporter,
} from 'n8n-core';
import { ensureError, sleep, UserError } from 'n8n-workflow';
import { ensureError, sleep, UnexpectedError, UserError } from 'n8n-workflow';
import type { AbstractServer } from '@/abstract-server';
import config from '@/config';
@@ -39,7 +38,9 @@ import { PostHogClient } from '@/posthog';
import { ShutdownService } from '@/shutdown/shutdown.service';
import { WorkflowHistoryManager } from '@/workflows/workflow-history.ee/workflow-history-manager.ee';
export abstract class BaseCommand extends Command {
export abstract class BaseCommand<F = never> {
readonly flags: F;
protected logger = Container.get(Logger);
protected dbConnection: DbConnection;
@@ -76,10 +77,6 @@ export abstract class BaseCommand extends Command {
/** Whether to init task runner (if enabled). */
protected needsTaskRunner = false;
protected async loadModules() {
await this.moduleRegistry.loadModules();
}
async init(): Promise<void> {
this.dbConnection = Container.get(DbConnection);
this.errorReporter = Container.get(ErrorReporter);
@@ -175,6 +172,14 @@ export abstract class BaseCommand extends Command {
process.exit(1);
}
protected log(message: string) {
this.logger.info(message);
}
protected error(message: string) {
throw new UnexpectedError(message);
}
async initObjectStoreService() {
const binaryDataConfig = Container.get(BinaryDataConfig);
const isSelected = binaryDataConfig.mode === 's3';
@@ -193,7 +198,7 @@ export abstract class BaseCommand extends Command {
this.logger.error(
'No license found for S3 storage. \n Either set `N8N_DEFAULT_BINARY_DATA_MODE` to something else, or upgrade to a license that supports this feature.',
);
return this.exit(1);
return process.exit(1);
}
this.logger.debug('License found for external storage - Initializing object store service');
@@ -264,13 +269,12 @@ export abstract class BaseCommand extends Command {
async finally(error: Error | undefined) {
if (error?.message) this.logger.error(error.message);
if (inTest || this.id === 'start') return;
if (inTest || this.constructor.name === 'Start') return;
if (this.dbConnection.connectionState.connected) {
await sleep(100); // give any in-flight query some time to finish
await this.dbConnection.close();
}
const exitCode = error instanceof Errors.ExitError ? error.oclif.exit : error ? 1 : 0;
this.exit(exitCode);
process.exit();
}
protected onTerminationSignal(signal: string) {