diff --git a/src/cli/facade/dev.ts b/src/cli/facade/dev.ts index f2fda0f56..03619e62b 100644 --- a/src/cli/facade/dev.ts +++ b/src/cli/facade/dev.ts @@ -204,6 +204,7 @@ const dev = ({ local, logger }: { logger: Logger; local: Local }) => hotReloading, liveReloadPort: liveReload.port, local: true, + componentConsole: console, postRequestPayloadSize, components: opts.components, path: path.resolve(componentsDir), diff --git a/src/registry/domain/options-sanitiser.ts b/src/registry/domain/options-sanitiser.ts index 5c4a0d00a..c830c4c1b 100644 --- a/src/registry/domain/options-sanitiser.ts +++ b/src/registry/domain/options-sanitiser.ts @@ -2,6 +2,7 @@ import zlib from 'node:zlib'; import { compileSync } from 'oc-client-browser'; import settings from '../../resources/settings'; import type { Config } from '../../types'; +import createNoopConsole from '../../utils/noop-console'; import * as auth from './authentication'; const DEFAULT_NODE_KEEPALIVE_MS = 5000; @@ -174,6 +175,10 @@ export default function optionsSanitiser(input: RegistryOptions): Config { options.tarExtractMode = 766; } + if (!options.componentConsole) { + options.componentConsole = createNoopConsole(); + } + if ( typeof options.fallbackRegistryUrl !== 'undefined' && !options.fallbackRegistryUrl.endsWith('/') diff --git a/src/registry/routes/helpers/get-component.ts b/src/registry/routes/helpers/get-component.ts index cd7afe812..7134f70a7 100644 --- a/src/registry/routes/helpers/get-component.ts +++ b/src/registry/routes/helpers/get-component.ts @@ -70,10 +70,6 @@ export interface GetComponentResult { } export const stream = Symbol('stream'); -const noop = () => {}; -const noopConsole = Object.fromEntries( - Object.keys(console).map((key) => [key, noop]) -); /** * Converts the plugins to a function that returns a record of plugins with the context applied @@ -676,7 +672,7 @@ export default function getComponent(conf: Config, repository: Repository) { exports: {} as Record any> }, exports: {} as Record any>, - console: conf.local ? console : noopConsole, + console: conf.componentConsole, setTimeout, Buffer, AbortController: globalThis?.AbortController, diff --git a/src/types.ts b/src/types.ts index 234f4d2e3..6e92aeb9d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -289,6 +289,24 @@ export interface Config { * system (`true`) or from the remote storage (`false`). */ local: boolean; + /** + * Console interface provided to components during execution. + * Allows for flexible logging strategies: pass the real console, a custom + * implementation that sends logs to a monitoring provider, or a no-op console. + * + * @example + * // Log to console + * componentConsole: console + * @example + * // Log to monitoring provider + * componentConsole: createCustomConsole(monitoringClient) + * @example + * // Disable component logs + * componentConsole: createNoopConsole() + * + * @default createNoopConsole() - a no-op console that discards all logs + */ + componentConsole: Partial; /** * File and directory mode (octal) applied when extracting tarballs during * publishing. diff --git a/src/utils/noop-console.ts b/src/utils/noop-console.ts new file mode 100644 index 000000000..d8bea5115 --- /dev/null +++ b/src/utils/noop-console.ts @@ -0,0 +1,12 @@ +/** + * Creates a no-op console object that silently discards all logging calls. + * Useful as a default console implementation when component logging is disabled. + * + * @returns Console object with all methods mapped to no-op functions + */ +export function createNoopConsole(): Partial { + const noop = () => {}; + return Object.fromEntries(Object.keys(console).map((key) => [key, noop])); +} + +export default createNoopConsole;