diff --git a/packages/@n8n/backend-common/src/index.ts b/packages/@n8n/backend-common/src/index.ts index 45d8721e66..189bf0beac 100644 --- a/packages/@n8n/backend-common/src/index.ts +++ b/packages/@n8n/backend-common/src/index.ts @@ -1,2 +1,8 @@ export * from './license-state'; export * from './types'; + +const { NODE_ENV } = process.env; + +export const inTest = NODE_ENV === 'test'; +export const inProduction = NODE_ENV === 'production'; +export const inDevelopment = !NODE_ENV || NODE_ENV === 'development'; diff --git a/packages/cli/src/__tests__/controller.registry.test.ts b/packages/cli/src/__tests__/controller.registry.test.ts index 7bde813316..95c56b0656 100644 --- a/packages/cli/src/__tests__/controller.registry.test.ts +++ b/packages/cli/src/__tests__/controller.registry.test.ts @@ -1,6 +1,9 @@ -jest.mock('@/constants', () => ({ - inProduction: true, -})); +jest.mock('@n8n/backend-common', () => { + return { + ...jest.requireActual('@n8n/backend-common'), + inProduction: true, + }; +}); import type { GlobalConfig } from '@n8n/config'; import { ControllerRegistryMetadata } from '@n8n/decorators'; diff --git a/packages/cli/src/abstract-server.ts b/packages/cli/src/abstract-server.ts index 70508d94f3..6316826ea7 100644 --- a/packages/cli/src/abstract-server.ts +++ b/packages/cli/src/abstract-server.ts @@ -1,3 +1,4 @@ +import { inTest, inDevelopment } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import { OnShutdown } from '@n8n/decorators'; import { Container, Service } from '@n8n/di'; @@ -10,7 +11,7 @@ import isbot from 'isbot'; import { Logger } from 'n8n-core'; import config from '@/config'; -import { N8N_VERSION, TEMPLATES_DIR, inDevelopment, inTest } from '@/constants'; +import { N8N_VERSION, TEMPLATES_DIR } from '@/constants'; import { DbConnection } from '@/databases/db-connection'; import { ServiceUnavailableError } from '@/errors/response-errors/service-unavailable.error'; import { ExternalHooks } from '@/external-hooks'; diff --git a/packages/cli/src/commands/base-command.ts b/packages/cli/src/commands/base-command.ts index a6b34bd8e1..d15f4a44d8 100644 --- a/packages/cli/src/commands/base-command.ts +++ b/packages/cli/src/commands/base-command.ts @@ -1,5 +1,5 @@ import 'reflect-metadata'; -import { LicenseState } from '@n8n/backend-common'; +import { inDevelopment, inTest, LicenseState } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import { LICENSE_FEATURES } from '@n8n/constants'; import { Container } from '@n8n/di'; @@ -17,7 +17,7 @@ import { ensureError, sleep, UserError } from 'n8n-workflow'; import type { AbstractServer } from '@/abstract-server'; import config from '@/config'; -import { N8N_VERSION, N8N_RELEASE_DATE, inDevelopment, inTest } from '@/constants'; +import { N8N_VERSION, N8N_RELEASE_DATE } from '@/constants'; import * as CrashJournal from '@/crash-journal'; import { DbConnection } from '@/databases/db-connection'; import { getDataDeduplicationService } from '@/deduplication'; diff --git a/packages/cli/src/commands/worker.ts b/packages/cli/src/commands/worker.ts index bf77b08cc5..e31bb8d619 100644 --- a/packages/cli/src/commands/worker.ts +++ b/packages/cli/src/commands/worker.ts @@ -1,8 +1,9 @@ +import { inTest } from '@n8n/backend-common'; import { Container } from '@n8n/di'; import { Flags, type Config } from '@oclif/core'; import config from '@/config'; -import { N8N_VERSION, inTest } from '@/constants'; +import { N8N_VERSION } from '@/constants'; import { EventMessageGeneric } from '@/eventbus/event-message-classes/event-message-generic'; import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus'; import { LogStreamingEventRelay } from '@/events/relays/log-streaming.event-relay'; diff --git a/packages/cli/src/config/index.ts b/packages/cli/src/config/index.ts index 6d718b630c..77162a9213 100644 --- a/packages/cli/src/config/index.ts +++ b/packages/cli/src/config/index.ts @@ -1,3 +1,4 @@ +import { inTest } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import { Container } from '@n8n/di'; import convict from 'convict'; @@ -8,7 +9,7 @@ import { Logger } from 'n8n-core'; import { setGlobalState, UserError } from 'n8n-workflow'; import assert from 'node:assert'; -import { inTest, inE2ETests } from '@/constants'; +import { inE2ETests } from '@/constants'; const globalConfig = Container.get(GlobalConfig); diff --git a/packages/cli/src/constants.ts b/packages/cli/src/constants.ts index 3c266ca7b2..0107cdff55 100644 --- a/packages/cli/src/constants.ts +++ b/packages/cli/src/constants.ts @@ -4,10 +4,7 @@ import type { ITaskDataConnections } from 'n8n-workflow'; import { jsonParse, TRIMMED_TASK_DATA_CONNECTIONS_KEY } from 'n8n-workflow'; import { resolve, join, dirname } from 'path'; -const { NODE_ENV, E2E_TESTS } = process.env; -export const inProduction = NODE_ENV === 'production'; -export const inDevelopment = !NODE_ENV || NODE_ENV === 'development'; -export const inTest = NODE_ENV === 'test'; +const { E2E_TESTS } = process.env; export const inE2ETests = E2E_TESTS === 'true'; export const CUSTOM_API_CALL_NAME = 'Custom API Call'; diff --git a/packages/cli/src/controller.registry.ts b/packages/cli/src/controller.registry.ts index 4503c3c311..acf2171661 100644 --- a/packages/cli/src/controller.registry.ts +++ b/packages/cli/src/controller.registry.ts @@ -1,5 +1,6 @@ +import { inProduction } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; -import type { BooleanLicenseFeature } from '@n8n/constants'; +import { type BooleanLicenseFeature } from '@n8n/constants'; import { ControllerRegistryMetadata } from '@n8n/decorators'; import type { AccessScope, Controller, RateLimit } from '@n8n/decorators'; import { Container, Service } from '@n8n/di'; @@ -10,7 +11,7 @@ import { UnexpectedError } from 'n8n-workflow'; import type { ZodClass } from 'zod-class'; import { AuthService } from '@/auth/auth.service'; -import { inProduction, RESPONSE_ERROR_MESSAGES } from '@/constants'; +import { RESPONSE_ERROR_MESSAGES } from '@/constants'; import { UnauthenticatedError } from '@/errors/response-errors/unauthenticated.error'; import { License } from '@/license'; import { userHasScopes } from '@/permissions.ee/check-access'; diff --git a/packages/cli/src/crash-journal.ts b/packages/cli/src/crash-journal.ts index 93f7b2e737..8e80d56d1b 100644 --- a/packages/cli/src/crash-journal.ts +++ b/packages/cli/src/crash-journal.ts @@ -1,3 +1,4 @@ +import { inProduction } from '@n8n/backend-common'; import { Container } from '@n8n/di'; import { existsSync } from 'fs'; import { mkdir, utimes, open, rm } from 'fs/promises'; @@ -5,8 +6,6 @@ import { InstanceSettings, Logger } from 'n8n-core'; import { sleep } from 'n8n-workflow'; import { join, dirname } from 'path'; -import { inProduction } from '@/constants'; - export const touchFile = async (filePath: string): Promise => { await mkdir(dirname(filePath), { recursive: true }); const time = new Date(); diff --git a/packages/cli/src/databases/db-connection.ts b/packages/cli/src/databases/db-connection.ts index 05d818b0c7..e6f70c8276 100644 --- a/packages/cli/src/databases/db-connection.ts +++ b/packages/cli/src/databases/db-connection.ts @@ -1,11 +1,10 @@ +import { inTest } from '@n8n/backend-common'; import { Memoized } from '@n8n/decorators'; import { Container, Service } from '@n8n/di'; import { DataSource } from '@n8n/typeorm'; import { ErrorReporter } from 'n8n-core'; import { DbConnectionTimeoutError, ensureError } from 'n8n-workflow'; -import { inTest } from '@/constants'; - import { DbConnectionOptions } from './db-connection-options'; import type { Migration } from './types'; import { wrapMigration } from './utils/migration-helpers'; diff --git a/packages/cli/src/databases/utils/migration-helpers.ts b/packages/cli/src/databases/utils/migration-helpers.ts index 95120584af..a3cb7a19d3 100644 --- a/packages/cli/src/databases/utils/migration-helpers.ts +++ b/packages/cli/src/databases/utils/migration-helpers.ts @@ -1,3 +1,4 @@ +import { inTest } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import { Container } from '@n8n/di'; import type { ObjectLiteral } from '@n8n/typeorm'; @@ -6,7 +7,6 @@ import { readFileSync, rmSync } from 'fs'; import { InstanceSettings, Logger } from 'n8n-core'; import { jsonParse, UnexpectedError } from 'n8n-workflow'; -import { inTest } from '@/constants'; import { createSchemaBuilder } from '@/databases/dsl'; import type { BaseMigration, Migration, MigrationContext, MigrationFn } from '@/databases/types'; diff --git a/packages/cli/src/eventbus/message-event-bus-writer/message-event-bus-log-writer.ts b/packages/cli/src/eventbus/message-event-bus-writer/message-event-bus-log-writer.ts index 0cc5d5e3a6..bfe0ee8bb3 100644 --- a/packages/cli/src/eventbus/message-event-bus-writer/message-event-bus-log-writer.ts +++ b/packages/cli/src/eventbus/message-event-bus-writer/message-event-bus-log-writer.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import { inTest } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import { Container } from '@n8n/di'; import { once as eventOnce } from 'events'; @@ -11,8 +12,6 @@ import path, { parse } from 'path'; import readline from 'readline'; import { Worker } from 'worker_threads'; -import { inTest } from '@/constants'; - import type { EventMessageTypes } from '../event-message-classes'; import { isEventMessageOptions } from '../event-message-classes/abstract-event-message'; import type { AbstractEventMessageOptions } from '../event-message-classes/abstract-event-message-options'; diff --git a/packages/cli/src/load-nodes-and-credentials.ts b/packages/cli/src/load-nodes-and-credentials.ts index 36d216e1be..86a00572f7 100644 --- a/packages/cli/src/load-nodes-and-credentials.ts +++ b/packages/cli/src/load-nodes-and-credentials.ts @@ -1,3 +1,4 @@ +import { inTest } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import { Container, Service } from '@n8n/di'; import glob from 'fast-glob'; @@ -29,13 +30,7 @@ import { deepCopy, NodeConnectionTypes, UnexpectedError, UserError } from 'n8n-w import path from 'path'; import picocolors from 'picocolors'; -import { - CUSTOM_API_CALL_KEY, - CUSTOM_API_CALL_NAME, - inTest, - CLI_DIR, - inE2ETests, -} from '@/constants'; +import { CUSTOM_API_CALL_KEY, CUSTOM_API_CALL_NAME, CLI_DIR, inE2ETests } from '@/constants'; import { isContainedWithin } from '@/utils/path-util'; @Service() diff --git a/packages/cli/src/push/__tests__/index.test.ts b/packages/cli/src/push/__tests__/index.test.ts index c97f434e55..9233a070d2 100644 --- a/packages/cli/src/push/__tests__/index.test.ts +++ b/packages/cli/src/push/__tests__/index.test.ts @@ -18,9 +18,12 @@ jest.mock('ws', () => ({ Server: jest.fn(), })); jest.unmock('@/push'); -jest.mock('@/constants', () => ({ - inProduction: true, -})); +jest.mock('@n8n/backend-common', () => { + return { + ...jest.requireActual('@n8n/backend-common'), + inProduction: true, + }; +}); describe('Push', () => { const pushRef = 'valid-push-ref'; diff --git a/packages/cli/src/push/index.ts b/packages/cli/src/push/index.ts index 09a18be6cf..f372689c9d 100644 --- a/packages/cli/src/push/index.ts +++ b/packages/cli/src/push/index.ts @@ -1,4 +1,5 @@ import type { PushMessage } from '@n8n/api-types'; +import { inProduction } from '@n8n/backend-common'; import type { User } from '@n8n/db'; import { OnShutdown } from '@n8n/decorators'; import { Container, Service } from '@n8n/di'; @@ -11,7 +12,7 @@ import { parse as parseUrl } from 'url'; import { Server as WSServer } from 'ws'; import { AuthService } from '@/auth/auth.service'; -import { inProduction, TRIMMED_TASK_DATA_CONNECTIONS } from '@/constants'; +import { TRIMMED_TASK_DATA_CONNECTIONS } from '@/constants'; import { BadRequestError } from '@/errors/response-errors/bad-request.error'; import { Publisher } from '@/scaling/pubsub/publisher.service'; import { TypedEmitter } from '@/typed-emitter'; diff --git a/packages/cli/src/response-helper.ts b/packages/cli/src/response-helper.ts index a0e2d6c847..61747eb778 100644 --- a/packages/cli/src/response-helper.ts +++ b/packages/cli/src/response-helper.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ +import { inDevelopment } from '@n8n/backend-common'; import { Container } from '@n8n/di'; import type { Request, Response } from 'express'; import { ErrorReporter, Logger } from 'n8n-core'; @@ -6,8 +7,6 @@ import { FORM_TRIGGER_PATH_IDENTIFIER, NodeApiError } from 'n8n-workflow'; import { Readable } from 'node:stream'; import picocolors from 'picocolors'; -import { inDevelopment } from '@/constants'; - import { ResponseError } from './errors/response-errors/abstract/response.error'; export function sendSuccessResponse( diff --git a/packages/cli/src/security-audit/risk-reporters/instance-risk-reporter.ts b/packages/cli/src/security-audit/risk-reporters/instance-risk-reporter.ts index e838009ef9..7fe2fa7906 100644 --- a/packages/cli/src/security-audit/risk-reporters/instance-risk-reporter.ts +++ b/packages/cli/src/security-audit/risk-reporters/instance-risk-reporter.ts @@ -1,3 +1,4 @@ +import { inDevelopment } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import { separate } from '@n8n/db'; import { Service } from '@n8n/di'; @@ -6,7 +7,7 @@ import { InstanceSettings, Logger } from 'n8n-core'; import type { IWorkflowBase } from 'n8n-workflow'; import config from '@/config'; -import { inDevelopment, N8N_VERSION } from '@/constants'; +import { N8N_VERSION } from '@/constants'; import { isApiEnabled } from '@/public-api'; import { ENV_VARS_DOCS_URL, diff --git a/packages/cli/src/server.ts b/packages/cli/src/server.ts index ee7eec4f4d..6d35fd3d1f 100644 --- a/packages/cli/src/server.ts +++ b/packages/cli/src/server.ts @@ -1,3 +1,4 @@ +import { inDevelopment, inProduction } from '@n8n/backend-common'; import { SecurityConfig } from '@n8n/config'; import { Container, Service } from '@n8n/di'; import cookieParser from 'cookie-parser'; @@ -11,15 +12,7 @@ import { resolve } from 'path'; import { AbstractServer } from '@/abstract-server'; import config from '@/config'; -import { - CLI_DIR, - EDITOR_UI_DIST_DIR, - inDevelopment, - inE2ETests, - inProduction, - N8N_VERSION, - Time, -} from '@/constants'; +import { CLI_DIR, EDITOR_UI_DIST_DIR, inE2ETests, N8N_VERSION, Time } from '@/constants'; import { ControllerRegistry } from '@/controller.registry'; import { CredentialsOverwrites } from '@/credentials-overwrites'; import { MessageEventBus } from '@/eventbus/message-event-bus/message-event-bus'; diff --git a/packages/cli/src/task-runners/task-broker/task-broker-server.ts b/packages/cli/src/task-runners/task-broker/task-broker-server.ts index 802c9fa98e..1d8f98f7c1 100644 --- a/packages/cli/src/task-runners/task-broker/task-broker-server.ts +++ b/packages/cli/src/task-runners/task-broker/task-broker-server.ts @@ -1,3 +1,4 @@ +import { inTest } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import { Service } from '@n8n/di'; import compression from 'compression'; @@ -11,7 +12,6 @@ import type { AddressInfo, Socket } from 'node:net'; import { parse as parseUrl } from 'node:url'; import { Server as WSServer } from 'ws'; -import { inTest } from '@/constants'; import { bodyParser, rawBodyReader } from '@/middlewares'; import { send } from '@/response-helper'; import { TaskBrokerAuthController } from '@/task-runners/task-broker/auth/task-broker-auth.controller'; diff --git a/packages/cli/src/user-management/email/user-management-mailer.ts b/packages/cli/src/user-management/email/user-management-mailer.ts index b0af7ff052..d5e3cc3f8a 100644 --- a/packages/cli/src/user-management/email/user-management-mailer.ts +++ b/packages/cli/src/user-management/email/user-management-mailer.ts @@ -1,3 +1,4 @@ +import { inTest } from '@n8n/backend-common'; import { GlobalConfig } from '@n8n/config'; import type { User } from '@n8n/db'; import { UserRepository } from '@n8n/db'; @@ -9,7 +10,6 @@ import { Logger } from 'n8n-core'; import type { IWorkflowBase } from 'n8n-workflow'; import { join as pathJoin } from 'path'; -import { inTest } from '@/constants'; import { InternalServerError } from '@/errors/response-errors/internal-server.error'; import { EventService } from '@/events/event.service'; import { UrlService } from '@/services/url.service'; diff --git a/packages/core/package.json b/packages/core/package.json index db53f05654..f8364e01e8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -38,6 +38,7 @@ "dependencies": { "@aws-sdk/client-s3": "3.808.0", "@langchain/core": "catalog:", + "@n8n/backend-common": "workspace:^", "@n8n/client-oauth2": "workspace:*", "@n8n/config": "workspace:*", "@n8n/decorators": "workspace:*", diff --git a/packages/core/src/constants.ts b/packages/core/src/constants.ts index db453cbb7f..63fce74113 100644 --- a/packages/core/src/constants.ts +++ b/packages/core/src/constants.ts @@ -1,8 +1,3 @@ -const { NODE_ENV } = process.env; -export const inProduction = NODE_ENV === 'production'; -export const inDevelopment = !NODE_ENV || NODE_ENV === 'development'; -export const inTest = NODE_ENV === 'test'; - export const CUSTOM_EXTENSION_ENV = 'N8N_CUSTOM_EXTENSIONS'; export const PLACEHOLDER_EMPTY_EXECUTION_ID = '__UNKNOWN__'; export const PLACEHOLDER_EMPTY_WORKFLOW_ID = '__EMPTY__'; diff --git a/packages/core/src/instance-settings/instance-settings.ts b/packages/core/src/instance-settings/instance-settings.ts index d6247a7977..2322ec19ae 100644 --- a/packages/core/src/instance-settings/instance-settings.ts +++ b/packages/core/src/instance-settings/instance-settings.ts @@ -1,3 +1,4 @@ +import { inTest } from '@n8n/backend-common'; import { InstanceSettingsConfig } from '@n8n/config'; import { Memoized } from '@n8n/decorators'; import { Service } from '@n8n/di'; @@ -27,8 +28,6 @@ type InstanceRole = 'unset' | 'leader' | 'follower'; export type InstanceType = 'main' | 'webhook' | 'worker'; -const inTest = process.env.NODE_ENV === 'test'; - @Service() export class InstanceSettings { /** The path to the n8n folder in which all n8n related data gets saved */ diff --git a/packages/core/src/logging/logger.ts b/packages/core/src/logging/logger.ts index 81e1d766bf..f272ada087 100644 --- a/packages/core/src/logging/logger.ts +++ b/packages/core/src/logging/logger.ts @@ -1,3 +1,4 @@ +import { inDevelopment, inProduction } from '@n8n/backend-common'; import type { LogScope } from '@n8n/config'; import { GlobalConfig, InstanceSettingsConfig } from '@n8n/config'; import { Service } from '@n8n/di'; @@ -14,7 +15,6 @@ import path, { basename } from 'node:path'; import pc from 'picocolors'; import winston from 'winston'; -import { inDevelopment, inProduction } from '@/constants'; import { isObjectLiteral } from '@/utils/is-object-literal'; const noOp = () => {}; diff --git a/packages/core/src/nodes-loader/__tests__/load-class-in-isolation.test.ts b/packages/core/src/nodes-loader/__tests__/load-class-in-isolation.test.ts index 8640baf670..cf28ed04e1 100644 --- a/packages/core/src/nodes-loader/__tests__/load-class-in-isolation.test.ts +++ b/packages/core/src/nodes-loader/__tests__/load-class-in-isolation.test.ts @@ -2,9 +2,12 @@ import vm from 'vm'; import { loadClassInIsolation } from '../load-class-in-isolation'; -jest.mock('@/constants', () => ({ - inTest: false, -})); +jest.mock('@n8n/backend-common', () => { + return { + ...jest.requireActual('@n8n/backend-common'), + inTest: false, + }; +}); describe('loadClassInIsolation', () => { const filePath = '/path/to/TestClass.js'; diff --git a/packages/core/src/nodes-loader/load-class-in-isolation.ts b/packages/core/src/nodes-loader/load-class-in-isolation.ts index a4157cf263..3ff48810dc 100644 --- a/packages/core/src/nodes-loader/load-class-in-isolation.ts +++ b/packages/core/src/nodes-loader/load-class-in-isolation.ts @@ -1,7 +1,6 @@ +import { inTest } from '@n8n/backend-common'; import { createContext, Script } from 'vm'; -import { inTest } from '@/constants'; - const context = createContext({ require }); export const loadClassInIsolation = (filePath: string, className: string) => { if (process.platform === 'win32') { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ac80f811a9..77622d902e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1456,6 +1456,9 @@ importers: '@langchain/core': specifier: 'catalog:' version: 0.3.30(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) + '@n8n/backend-common': + specifier: workspace:^ + version: link:../@n8n/backend-common '@n8n/client-oauth2': specifier: workspace:* version: link:../@n8n/client-oauth2