From 5d1aa2125528305e5a622dbbc624aef80fb01c66 Mon Sep 17 00:00:00 2001 From: ematipico Date: Tue, 7 Apr 2026 15:49:44 +0100 Subject: [PATCH 1/7] wip --- packages/astro/package.json | 1 + packages/astro/src/assets/build/generate.ts | 4 +- .../core/compute-font-families-assets.ts | 4 +- .../core/get-or-create-font-family-assets.ts | 4 +- .../src/assets/fonts/vite-plugin-fonts.ts | 4 +- .../astro/src/assets/vite-plugin-assets.ts | 4 +- packages/astro/src/cli/add/index.ts | 18 +-- .../src/cli/create-key/core/create-key.ts | 4 +- packages/astro/src/cli/docs/core/open-docs.ts | 4 +- packages/astro/src/cli/flags.ts | 7 +- packages/astro/src/cli/info/core/info.ts | 4 +- .../src/cli/info/infra/tinyclip-clipboard.ts | 6 +- .../src/cli/infra/logger-help-display.ts | 6 +- packages/astro/src/cli/install-package.ts | 6 +- packages/astro/src/container/index.ts | 7 +- packages/astro/src/content/content-layer.ts | 6 +- packages/astro/src/content/instance.ts | 4 +- .../astro/src/content/server-listeners.ts | 4 +- packages/astro/src/content/types-generator.ts | 8 +- packages/astro/src/content/utils.ts | 4 +- .../content/vite-plugin-content-imports.ts | 4 +- packages/astro/src/core/app/base.ts | 9 +- packages/astro/src/core/app/dev/app.ts | 12 +- packages/astro/src/core/app/logging.ts | 9 +- packages/astro/src/core/app/types.ts | 4 +- packages/astro/src/core/base-pipeline.ts | 4 +- packages/astro/src/core/build/generate.ts | 10 +- packages/astro/src/core/build/index.ts | 8 +- packages/astro/src/core/build/page-data.ts | 4 +- packages/astro/src/core/build/types.ts | 4 +- packages/astro/src/core/cache/runtime/noop.ts | 6 +- packages/astro/src/core/create-vite.ts | 4 +- .../astro/src/core/dev/adapter-validation.ts | 6 +- packages/astro/src/core/dev/container.ts | 6 +- packages/astro/src/core/dev/dev.ts | 4 +- packages/astro/src/core/logger/console.ts | 6 +- packages/astro/src/core/logger/core.ts | 62 +++++++-- packages/astro/src/core/logger/node.ts | 34 +++-- packages/astro/src/core/logger/public.ts | 10 ++ packages/astro/src/core/logger/vite.ts | 2 +- packages/astro/src/core/messages/runtime.ts | 4 +- .../src/core/preview/static-preview-server.ts | 4 +- .../astro/src/core/render/params-and-props.ts | 4 +- packages/astro/src/core/render/route-cache.ts | 8 +- packages/astro/src/core/render/slots.ts | 6 +- packages/astro/src/core/request.ts | 4 +- .../astro/src/core/routing/create-manifest.ts | 17 ++- packages/astro/src/core/routing/prerender.ts | 4 +- packages/astro/src/core/routing/rewrite.ts | 4 +- packages/astro/src/core/sync/index.ts | 8 +- .../src/integrations/features-validation.ts | 8 +- packages/astro/src/integrations/hooks.ts | 32 ++--- packages/astro/src/runtime/server/endpoint.ts | 4 +- packages/astro/src/types/astro.ts | 6 +- packages/astro/src/types/public/config.ts | 6 +- packages/astro/src/types/public/logger.ts | 7 + packages/astro/src/vite-plugin-app/app.ts | 10 +- .../vite-plugin-app/createAstroServerApp.ts | 9 +- .../astro/src/vite-plugin-app/pipeline.ts | 4 +- .../src/vite-plugin-astro-server/base.ts | 4 +- .../src/vite-plugin-astro-server/error.ts | 4 +- .../src/vite-plugin-astro-server/plugin.ts | 4 +- .../src/vite-plugin-astro-server/sec-fetch.ts | 4 +- .../astro/src/vite-plugin-astro/compile.ts | 6 +- packages/astro/src/vite-plugin-astro/hmr.ts | 4 +- packages/astro/src/vite-plugin-astro/index.ts | 4 +- .../index.ts | 4 +- .../astro/src/vite-plugin-markdown/index.ts | 4 +- .../astro/src/vite-plugin-routes/index.ts | 4 +- .../test/units/logger/destination.test.ts | 127 ++++++++++++++++++ .../astro/test/units/routing/manifest.test.js | 4 + 71 files changed, 425 insertions(+), 214 deletions(-) create mode 100644 packages/astro/src/core/logger/public.ts create mode 100644 packages/astro/src/types/public/logger.ts create mode 100644 packages/astro/test/units/logger/destination.test.ts diff --git a/packages/astro/package.json b/packages/astro/package.json index 7c7c9bf16b53..daeffb1266d6 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -81,6 +81,7 @@ "./zod": "./dist/zod.js", "./errors": "./dist/core/errors/userError.js", "./middleware": "./dist/core/middleware/index.js", + "./logger": "./disto/core/logger/public.js", "./virtual-modules/*": "./dist/virtual-modules/*" }, "bin": { diff --git a/packages/astro/src/assets/build/generate.ts b/packages/astro/src/assets/build/generate.ts index 82717a397a15..262469d69e3c 100644 --- a/packages/astro/src/assets/build/generate.ts +++ b/packages/astro/src/assets/build/generate.ts @@ -6,7 +6,7 @@ import type { StaticBuildOptions } from '../../core/build/types.js'; import { getTimeStat } from '../../core/build/util.js'; import { AstroError } from '../../core/errors/errors.js'; import { AstroErrorData } from '../../core/errors/index.js'; -import type { Logger } from '../../core/logger/core.js'; +import type { AstroLogger } from '../../core/logger/core.js'; import { isRemotePath, removeLeadingForwardSlash } from '../../core/path.js'; import type { MapValue } from '../../type-utils.js'; import type { AstroConfig } from '../../types/public/config.js'; @@ -31,7 +31,7 @@ interface GenerationDataCached { type GenerationData = GenerationDataUncached | GenerationDataCached; type AssetEnv = { - logger: Logger; + logger: AstroLogger; isSSR: boolean; count: { total: number; current: number }; useCache: boolean; diff --git a/packages/astro/src/assets/fonts/core/compute-font-families-assets.ts b/packages/astro/src/assets/fonts/core/compute-font-families-assets.ts index b3b2da7be390..0239dd0d407a 100644 --- a/packages/astro/src/assets/fonts/core/compute-font-families-assets.ts +++ b/packages/astro/src/assets/fonts/core/compute-font-families-assets.ts @@ -1,4 +1,4 @@ -import type { Logger } from '../../../core/logger/core.js'; +import type { AstroLogger } from '../../../core/logger/core.js'; import type { FontResolver, StringMatcher } from '../definitions.js'; import type { Collaborator, @@ -24,7 +24,7 @@ export async function computeFontFamiliesAssets({ }: { resolvedFamilies: Array; fontResolver: FontResolver; - logger: Logger; + logger: AstroLogger; bold: (input: string) => string; defaults: Defaults; stringMatcher: StringMatcher; diff --git a/packages/astro/src/assets/fonts/core/get-or-create-font-family-assets.ts b/packages/astro/src/assets/fonts/core/get-or-create-font-family-assets.ts index 589a8c4671c5..0f952e6163c4 100644 --- a/packages/astro/src/assets/fonts/core/get-or-create-font-family-assets.ts +++ b/packages/astro/src/assets/fonts/core/get-or-create-font-family-assets.ts @@ -1,4 +1,4 @@ -import type { Logger } from '../../../core/logger/core.js'; +import type { AstroLogger } from '../../../core/logger/core.js'; import type { FontFamilyAssetsByUniqueKey, ResolvedFontFamily } from '../types.js'; export function getOrCreateFontFamilyAssets({ @@ -8,7 +8,7 @@ export function getOrCreateFontFamilyAssets({ family, }: { fontFamilyAssetsByUniqueKey: FontFamilyAssetsByUniqueKey; - logger: Logger; + logger: AstroLogger; bold: (input: string) => string; family: ResolvedFontFamily; }) { diff --git a/packages/astro/src/assets/fonts/vite-plugin-fonts.ts b/packages/astro/src/assets/fonts/vite-plugin-fonts.ts index 3d18dfb91f8e..690930ca7587 100644 --- a/packages/astro/src/assets/fonts/vite-plugin-fonts.ts +++ b/packages/astro/src/assets/fonts/vite-plugin-fonts.ts @@ -7,7 +7,7 @@ import { getAlgorithm, shouldTrackCspHashes } from '../../core/csp/common.js'; import { generateCspDigest } from '../../core/encryption.js'; import { collectErrorMetadata } from '../../core/errors/dev/utils.js'; import { AstroError, AstroErrorData, isAstroError } from '../../core/errors/index.js'; -import type { Logger } from '../../core/logger/core.js'; +import type { AstroLogger } from '../../core/logger/core.js'; import { formatErrorMessage } from '../../core/messages/runtime.js'; import { appendForwardSlash, joinPaths, prependForwardSlash } from '../../core/path.js'; import { getClientOutputDirectory } from '../../prerender/utils.js'; @@ -54,7 +54,7 @@ import type { interface Options { settings: AstroSettings; sync: boolean; - logger: Logger; + logger: AstroLogger; } export function fontsPlugin({ settings, sync, logger }: Options): Plugin { diff --git a/packages/astro/src/assets/vite-plugin-assets.ts b/packages/astro/src/assets/vite-plugin-assets.ts index d9b88d9b29dc..f1341cc51c42 100644 --- a/packages/astro/src/assets/vite-plugin-assets.ts +++ b/packages/astro/src/assets/vite-plugin-assets.ts @@ -4,7 +4,7 @@ import MagicString from 'magic-string'; import picomatch from 'picomatch'; import type * as vite from 'vite'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { appendForwardSlash, joinPaths, @@ -119,7 +119,7 @@ const addStaticImageFactory = ( interface Options { settings: AstroSettings; sync: boolean; - logger: Logger; + logger: AstroLogger; fs: typeof fsMod; } diff --git a/packages/astro/src/cli/add/index.ts b/packages/astro/src/cli/add/index.ts index dc55d48b65f4..1f716b43b08f 100644 --- a/packages/astro/src/cli/add/index.ts +++ b/packages/astro/src/cli/add/index.ts @@ -22,7 +22,7 @@ import { presets, updateTSConfigForFramework, } from '../../core/config/tsconfig.js'; -import type { Logger } from '../../core/logger/core.js'; +import type { AstroLogger } from '../../core/logger/core.js'; import * as msg from '../../core/messages/runtime.js'; import { printHelp } from '../../core/messages/runtime.js'; import { appendForwardSlash } from '../../core/path.js'; @@ -652,7 +652,7 @@ async function updateAstroConfig({ configURL: URL; mod: ProxifiedModule; flags: Flags; - logger: Logger; + logger: AstroLogger; logAdapterInstructions: boolean; }): Promise { const input = await fs.readFile(fileURLToPath(configURL), { encoding: 'utf-8' }); @@ -713,7 +713,7 @@ async function updatePackageJsonOverrides({ }: { configURL: URL; flags: Flags; - logger: Logger; + logger: AstroLogger; overrides: Record; }): Promise { const pkgURL = new URL('./package.json', configURL); @@ -774,7 +774,7 @@ async function updatePackageJsonScripts({ }: { configURL: URL; flags: Flags; - logger: Logger; + logger: AstroLogger; scripts: Record; }): Promise { const pkgURL = new URL('./package.json', configURL); @@ -877,7 +877,7 @@ async function tryToInstallIntegrations({ integrations: IntegrationInfo[]; cwd?: string; flags: Flags; - logger: Logger; + logger: AstroLogger; }): Promise { const packageManager = await detect({ cwd, @@ -950,7 +950,7 @@ async function tryToInstallIntegrations({ async function validateIntegrations( integrations: string[], flags: yargsParser.Arguments, - logger: Logger, + logger: AstroLogger, ): Promise { // First, validate all package names to prevent command injection for (const integration of integrations) { @@ -1069,7 +1069,7 @@ async function validateIntegrations( async function updateTSConfig( cwd = process.cwd(), - logger: Logger, + logger: AstroLogger, integrationsInfo: IntegrationInfo[], flags: Flags, options?: { addIncludes?: string[] }, @@ -1193,7 +1193,7 @@ async function askToContinue({ logger, }: { flags: Flags; - logger: Logger; + logger: AstroLogger; }): Promise { if (flags.yes || flags.y) return true; if (!hasHintedAboutYesFlag) { @@ -1237,7 +1237,7 @@ function getDiffContent(input: string, output: string): string | null { async function setupIntegrationConfig(opts: { root: URL; - logger: Logger; + logger: AstroLogger; flags: Flags; integrationName: string; possibleConfigFiles: string[]; diff --git a/packages/astro/src/cli/create-key/core/create-key.ts b/packages/astro/src/cli/create-key/core/create-key.ts index b5beb3b8ba04..46cf0ac71926 100644 --- a/packages/astro/src/cli/create-key/core/create-key.ts +++ b/packages/astro/src/cli/create-key/core/create-key.ts @@ -1,9 +1,9 @@ -import type { Logger } from '../../../core/logger/core.js'; +import type { AstroLogger } from '../../../core/logger/core.js'; import { defineCommand } from '../../domain/command.js'; import type { KeyGenerator } from '../definitions.js'; interface Options { - logger: Logger; + logger: AstroLogger; keyGenerator: KeyGenerator; } diff --git a/packages/astro/src/cli/docs/core/open-docs.ts b/packages/astro/src/cli/docs/core/open-docs.ts index 93f75c550d8c..dfaf150c44b2 100644 --- a/packages/astro/src/cli/docs/core/open-docs.ts +++ b/packages/astro/src/cli/docs/core/open-docs.ts @@ -1,4 +1,4 @@ -import type { Logger } from '../../../core/logger/core.js'; +import type { AstroLogger } from '../../../core/logger/core.js'; import type { CommandExecutor, OperatingSystemProvider } from '../../definitions.js'; import { defineCommand } from '../../domain/command.js'; import type { CloudIdeProvider } from '../definitions.js'; @@ -6,7 +6,7 @@ import type { CloudIdeProvider } from '../definitions.js'; interface Options { url: string; operatingSystemProvider: OperatingSystemProvider; - logger: Logger; + logger: AstroLogger; commandExecutor: CommandExecutor; cloudIdeProvider: CloudIdeProvider; } diff --git a/packages/astro/src/cli/flags.ts b/packages/astro/src/cli/flags.ts index b73c18c669ee..4941ad6075c5 100644 --- a/packages/astro/src/cli/flags.ts +++ b/packages/astro/src/cli/flags.ts @@ -1,5 +1,5 @@ import type { Arguments } from 'yargs-parser'; -import type { Logger, LogOptions } from '../core/logger/core.js'; +import type { AstroLogger, LogOptions } from '../core/logger/core.js'; import { createNodeLogger, nodeLogDestination } from '../core/logger/node.js'; import type { AstroInlineConfig } from '../types/public/config.js'; @@ -40,10 +40,11 @@ export function flagsToAstroInlineConfig(flags: Flags): AstroInlineConfig { * The `logging` is usually created from an `AstroInlineConfig`, but some flows like `add` * doesn't read the AstroConfig directly, so we create a `logging` object from the CLI flags instead. */ -export function createLoggerFromFlags(flags: Flags): Logger { +export function createLoggerFromFlags(flags: Flags): AstroLogger { const logging: LogOptions = { - dest: nodeLogDestination, + destination: nodeLogDestination, level: 'info', + format: 'default', }; if (flags.verbose) { diff --git a/packages/astro/src/cli/info/core/info.ts b/packages/astro/src/cli/info/core/info.ts index 4d4135430055..2ef11b79f269 100644 --- a/packages/astro/src/cli/info/core/info.ts +++ b/packages/astro/src/cli/info/core/info.ts @@ -1,11 +1,11 @@ -import type { Logger } from '../../../core/logger/core.js'; +import type { AstroLogger } from '../../../core/logger/core.js'; import { defineCommand } from '../../domain/command.js'; import type { Clipboard, DebugInfoFormatter, DebugInfoProvider } from '../definitions.js'; interface Options { debugInfoProvider: DebugInfoProvider; getDebugInfoFormatter: (options: { pretty: boolean }) => DebugInfoFormatter; - logger: Logger; + logger: AstroLogger; clipboard: Clipboard; } diff --git a/packages/astro/src/cli/info/infra/tinyclip-clipboard.ts b/packages/astro/src/cli/info/infra/tinyclip-clipboard.ts index 85d4094fa052..a65c833302b1 100644 --- a/packages/astro/src/cli/info/infra/tinyclip-clipboard.ts +++ b/packages/astro/src/cli/info/infra/tinyclip-clipboard.ts @@ -1,16 +1,16 @@ -import type { Logger } from '../../../core/logger/core.js'; +import type { AstroLogger } from '../../../core/logger/core.js'; import type { Clipboard, Prompt } from '../definitions.js'; import { writeText } from 'tinyclip'; export class TinyclipClipboard implements Clipboard { - readonly #logger: Logger; + readonly #logger: AstroLogger; readonly #prompt: Prompt; constructor({ logger, prompt, }: { - logger: Logger; + logger: AstroLogger; prompt: Prompt; }) { this.#logger = logger; diff --git a/packages/astro/src/cli/infra/logger-help-display.ts b/packages/astro/src/cli/infra/logger-help-display.ts index edb924b618dc..6381f3216f2d 100644 --- a/packages/astro/src/cli/infra/logger-help-display.ts +++ b/packages/astro/src/cli/infra/logger-help-display.ts @@ -1,11 +1,11 @@ -import type { Logger } from '../../core/logger/core.js'; +import type { AstroLogger } from '../../core/logger/core.js'; import type { AstroVersionProvider, HelpDisplay, TextStyler } from '../definitions.js'; import type { HelpPayload } from '../domain/help-payload.js'; import type { Flags } from '../flags.js'; import { formatVersion } from '../utils/format-version.js'; export class LoggerHelpDisplay implements HelpDisplay { - readonly #logger: Logger; + readonly #logger: AstroLogger; readonly #textStyler: TextStyler; readonly #astroVersionProvider: AstroVersionProvider; // TODO: find something better @@ -17,7 +17,7 @@ export class LoggerHelpDisplay implements HelpDisplay { astroVersionProvider, flags, }: { - logger: Logger; + logger: AstroLogger; textStyler: TextStyler; astroVersionProvider: AstroVersionProvider; flags: Flags; diff --git a/packages/astro/src/cli/install-package.ts b/packages/astro/src/cli/install-package.ts index 495c6d2abbbc..2a33f424f8ac 100644 --- a/packages/astro/src/cli/install-package.ts +++ b/packages/astro/src/cli/install-package.ts @@ -3,7 +3,7 @@ import * as clack from '@clack/prompts'; import ci from 'ci-info'; import { detect, resolveCommand } from 'package-manager-detector'; import colors from 'piccolore'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { exec } from './exec.js'; const require = createRequire(import.meta.url); @@ -17,7 +17,7 @@ type GetPackageOptions = { export async function getPackage( packageName: string, - logger: Logger, + logger: AstroLogger, options: GetPackageOptions, otherDeps: string[] = [], ): Promise { @@ -57,7 +57,7 @@ export async function getPackage( async function installPackage( packageNames: string[], options: GetPackageOptions, - logger: Logger, + logger: AstroLogger, ): Promise { const cwd = options.cwd ?? process.cwd(); const packageManager = await detect({ diff --git a/packages/astro/src/container/index.ts b/packages/astro/src/container/index.ts index 6e1eb38025dd..c1dafb265ac8 100644 --- a/packages/astro/src/container/index.ts +++ b/packages/astro/src/container/index.ts @@ -3,7 +3,7 @@ import { getDefaultClientDirectives } from '../core/client-directive/index.js'; import { ASTRO_CONFIG_DEFAULTS } from '../core/config/schemas/index.js'; import { validateConfig } from '../core/config/validate.js'; import { createKey } from '../core/encryption.js'; -import { Logger } from '../core/logger/core.js'; +import { AstroLogger } from '../core/logger/core.js'; import { nodeLogDestination } from '../core/logger/node.js'; import { NOOP_MIDDLEWARE_FN } from '../core/middleware/noop-middleware.js'; import { removeLeadingForwardSlash } from '../core/path.js'; @@ -301,9 +301,10 @@ export class experimental_AstroContainer { astroConfig, }: AstroContainerConstructor) { this.#pipeline = ContainerPipeline.create({ - logger: new Logger({ + logger: new AstroLogger({ level: 'info', - dest: nodeLogDestination, + destination: nodeLogDestination, + format: 'default', }), manifest: createManifest(manifest, renderers), streaming, diff --git a/packages/astro/src/content/content-layer.ts b/packages/astro/src/content/content-layer.ts index 9d7c697ee235..fbce711833f0 100644 --- a/packages/astro/src/content/content-layer.ts +++ b/packages/astro/src/content/content-layer.ts @@ -9,7 +9,7 @@ import type { FSWatcher } from 'vite'; import xxhash from 'xxhash-wasm'; import type * as z from 'zod/v4'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { AstroSettings } from '../types/astro.js'; import type { ContentEntryType, RefreshContentOptions } from '../types/public/content.js'; import { @@ -35,7 +35,7 @@ import { createWatcherWrapper, type WrappedWatcher } from './watcher.js'; export interface ContentLayerOptions { store: MutableDataStore; settings: AstroSettings; - logger: Logger; + logger: AstroLogger; watcher?: FSWatcher; contentConfigObserver?: ContentObservable; } @@ -47,7 +47,7 @@ type CollectionLoader = () => | Promise>>; export class ContentLayer { - #logger: Logger; + #logger: AstroLogger; #store: MutableDataStore; #settings: AstroSettings; #watcher?: WrappedWatcher; diff --git a/packages/astro/src/content/instance.ts b/packages/astro/src/content/instance.ts index 2198440edfbb..e58d3e034e04 100644 --- a/packages/astro/src/content/instance.ts +++ b/packages/astro/src/content/instance.ts @@ -1,13 +1,13 @@ import type { FSWatcher } from 'vite'; import { ContentLayer } from './content-layer.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { AstroSettings } from '../types/astro.js'; import type { MutableDataStore } from './mutable-data-store.js'; interface ContentLayerOptions { store: MutableDataStore; settings: AstroSettings; - logger: Logger; + logger: AstroLogger; watcher?: FSWatcher; } diff --git a/packages/astro/src/content/server-listeners.ts b/packages/astro/src/content/server-listeners.ts index ec6df1e270a3..e6c0e8d447ac 100644 --- a/packages/astro/src/content/server-listeners.ts +++ b/packages/astro/src/content/server-listeners.ts @@ -1,13 +1,13 @@ import type fsMod from 'node:fs'; import type { ViteDevServer } from 'vite'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { AstroSettings } from '../types/astro.js'; import { createContentTypesGenerator } from './types-generator.js'; import { globalContentConfigObserver } from './utils.js'; interface ContentServerListenerParams { fs: typeof fsMod; - logger: Logger; + logger: AstroLogger; settings: AstroSettings; viteServer: ViteDevServer; } diff --git a/packages/astro/src/content/types-generator.ts b/packages/astro/src/content/types-generator.ts index fd31e8750c21..5cc3745eaffb 100644 --- a/packages/astro/src/content/types-generator.ts +++ b/packages/astro/src/content/types-generator.ts @@ -12,7 +12,7 @@ import { import * as z from 'zod/v4'; import { AstroError } from '../core/errors/errors.js'; import { AstroErrorData } from '../core/errors/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { isRelativePath } from '../core/path.js'; import type { AstroSettings } from '../types/astro.js'; import type { ContentEntryType } from '../types/public/content.js'; @@ -69,7 +69,7 @@ type CollectionEntryMap = { type CreateContentGeneratorParams = { contentConfigObserver: ContentObservable; - logger: Logger; + logger: AstroLogger; settings: AstroSettings; /** This is required for loading the content config */ viteServer: ViteDevServer; @@ -444,7 +444,7 @@ async function writeContentFiles({ contentEntryTypes: Pick[]; contentConfig?: ContentConfig; viteServer: ViteDevServer; - logger: Logger; + logger: AstroLogger; settings: AstroSettings; }) { let dataTypesStr = ''; @@ -608,7 +608,7 @@ async function generateJSONSchema( collectionConfig: CollectionConfig, collectionKey: string, collectionSchemasDir: URL, - logger: Logger, + logger: AstroLogger, ) { let zodSchemaForJson = typeof collectionConfig.schema === 'function' diff --git a/packages/astro/src/content/utils.ts b/packages/astro/src/content/utils.ts index 33a240fa6604..6ac7da29f0a9 100644 --- a/packages/astro/src/content/utils.ts +++ b/packages/astro/src/content/utils.ts @@ -10,7 +10,7 @@ import xxhash from 'xxhash-wasm'; import * as z from 'zod/v4'; import { AstroError, AstroErrorData, errorMap, MarkdownError } from '../core/errors/index.js'; import { isYAMLException } from '../core/errors/utils.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { appendForwardSlash } from '../core/path.js'; import { normalizePath } from '../core/viteUtils.js'; import type { AstroSettings } from '../types/astro.js'; @@ -269,7 +269,7 @@ export async function getSymlinkedContentCollections({ fs, }: { contentDir: URL; - logger: Logger; + logger: AstroLogger; fs: typeof fsMod; }): Promise> { const contentPaths = new Map(); diff --git a/packages/astro/src/content/vite-plugin-content-imports.ts b/packages/astro/src/content/vite-plugin-content-imports.ts index c5cb5f2d61e1..3e62807ed9c7 100644 --- a/packages/astro/src/content/vite-plugin-content-imports.ts +++ b/packages/astro/src/content/vite-plugin-content-imports.ts @@ -7,7 +7,7 @@ import type { Plugin, RunnableDevEnvironment } from 'vite'; import { getProxyCode } from '../assets/utils/proxy.js'; import { AstroError } from '../core/errors/errors.js'; import { AstroErrorData } from '../core/errors/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { AstroSettings } from '../types/astro.js'; import type { AstroConfig } from '../types/public/config.js'; import type { @@ -70,7 +70,7 @@ export function astroContentImportPlugin({ }: { fs: typeof fsMod; settings: AstroSettings; - logger: Logger; + logger: AstroLogger; }): Plugin[] { const contentPaths = getContentPaths( settings.config, diff --git a/packages/astro/src/core/app/base.ts b/packages/astro/src/core/app/base.ts index 8c18f264afdd..35f3435e1b31 100644 --- a/packages/astro/src/core/app/base.ts +++ b/packages/astro/src/core/app/base.ts @@ -31,7 +31,7 @@ import { import { getCookiesFromResponse } from '../cookies/response.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; import { consoleLogDestination } from '../logger/console.js'; -import { AstroIntegrationLogger, Logger } from '../logger/core.js'; +import { AstroIntegrationLogger, AstroLogger } from '../logger/core.js'; import { type CreateRenderContext, RenderContext } from '../render-context.js'; import { redirectTemplate } from '../routing/3xx.js'; import { ensure404Route } from '../routing/astro-designed-error-pages.js'; @@ -131,16 +131,17 @@ export abstract class BaseApp

{ pipeline: P; adapterLogger: AstroIntegrationLogger; baseWithoutTrailingSlash: string; - logger: Logger; + logger: AstroLogger; #router: Router; constructor(manifest: SSRManifest, streaming = true, ...args: any[]) { this.manifest = manifest; this.manifestData = { routes: manifest.routes.map((route) => route.routeData) }; this.baseWithoutTrailingSlash = removeTrailingForwardSlash(manifest.base); this.pipeline = this.createPipeline(streaming, manifest, ...args); - this.logger = new Logger({ - dest: consoleLogDestination, + this.logger = new AstroLogger({ + destination: consoleLogDestination, level: manifest.logLevel, + format: 'default', }); this.adapterLogger = new AstroIntegrationLogger(this.logger.options, manifest.adapterName); // This is necessary to allow running middlewares for 404 in SSR. There's special handling diff --git a/packages/astro/src/core/app/dev/app.ts b/packages/astro/src/core/app/dev/app.ts index 9c5b5734c083..b1a373671b6a 100644 --- a/packages/astro/src/core/app/dev/app.ts +++ b/packages/astro/src/core/app/dev/app.ts @@ -1,7 +1,7 @@ import type { RouteData } from '../../../types/public/index.js'; import { MiddlewareNoDataOrNextCalled, MiddlewareNotAResponse } from '../../errors/errors-data.js'; import { type AstroError, isAstroError } from '../../errors/index.js'; -import type { Logger } from '../../logger/core.js'; +import type { AstroLogger } from '../../logger/core.js'; import { BaseApp, type DevMatch, @@ -18,13 +18,17 @@ import type { RoutesList } from '../../../types/astro.js'; import { req } from '../../messages/runtime.js'; export class DevApp extends BaseApp { - logger: Logger; - constructor(manifest: SSRManifest, streaming = true, logger: Logger) { + logger: AstroLogger; + constructor(manifest: SSRManifest, streaming = true, logger: AstroLogger) { super(manifest, streaming, logger); this.logger = logger; } - createPipeline(streaming: boolean, manifest: SSRManifest, logger: Logger): NonRunnablePipeline { + createPipeline( + streaming: boolean, + manifest: SSRManifest, + logger: AstroLogger, + ): NonRunnablePipeline { return NonRunnablePipeline.create({ logger, manifest, diff --git a/packages/astro/src/core/app/logging.ts b/packages/astro/src/core/app/logging.ts index 4b73d1c72e49..b61378b29b20 100644 --- a/packages/astro/src/core/app/logging.ts +++ b/packages/astro/src/core/app/logging.ts @@ -1,10 +1,11 @@ import type { AstroInlineConfig } from '../../types/public/index.js'; import { consoleLogDestination } from '../logger/console.js'; -import { Logger } from '../logger/core.js'; +import { AstroLogger } from '../logger/core.js'; -export function createConsoleLogger(level: AstroInlineConfig['logLevel']): Logger { - return new Logger({ - dest: consoleLogDestination, +export function createConsoleLogger(level: AstroInlineConfig['logLevel']): AstroLogger { + return new AstroLogger({ + destination: consoleLogDestination, level: level ?? 'info', + format: 'default', }); } diff --git a/packages/astro/src/core/app/types.ts b/packages/astro/src/core/app/types.ts index 692fac82ea4b..7641ff1f3ca1 100644 --- a/packages/astro/src/core/app/types.ts +++ b/packages/astro/src/core/app/types.ts @@ -15,7 +15,7 @@ import type { } from '../../types/public/internal.js'; import type { SinglePageBuiltModule } from '../build/types.js'; import type { CspDirective } from '../csp/config.js'; -import type { LoggerLevel } from '../logger/core.js'; +import type { AstroLoggerLevel } from '../logger/core.js'; import type { RoutingStrategies } from './common.js'; import type { CacheProviderFactory, SSRManifestCache } from '../cache/types.js'; import type { BaseSessionConfig, SessionDriverFactory } from '../session/types.js'; @@ -150,7 +150,7 @@ export type SSRManifest = { placement: DevToolbarPlacement | undefined; }; internalFetchHeaders?: Record; - logLevel: LoggerLevel; + logLevel: AstroLoggerLevel; }; export type SSRActions = { diff --git a/packages/astro/src/core/base-pipeline.ts b/packages/astro/src/core/base-pipeline.ts index 02a128cb08e9..c6fbf8507df3 100644 --- a/packages/astro/src/core/base-pipeline.ts +++ b/packages/astro/src/core/base-pipeline.ts @@ -17,7 +17,7 @@ import type { ServerIslandMappings } from './app/types.js'; import type { SinglePageBuiltModule } from './build/types.js'; import { ActionNotFoundError } from './errors/errors-data.js'; import { AstroError } from './errors/index.js'; -import type { Logger } from './logger/core.js'; +import type { AstroLogger } from './logger/core.js'; import { NOOP_MIDDLEWARE_FN } from './middleware/noop-middleware.js'; import { sequence } from './middleware/sequence.js'; import { RedirectSinglePageBuiltModule } from './redirects/index.js'; @@ -82,7 +82,7 @@ export abstract class Pipeline { readonly serverIslands: SSRManifest['serverIslandMappings']; constructor( - logger: Logger, + logger: AstroLogger, manifest: SSRManifest, /** * "development" or "production" only diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 4a7b94f222cb..e86677ba93a0 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -20,7 +20,7 @@ import { } from '../../core/path.js'; import { runHookBuildGenerated, toIntegrationResolvedRoute } from '../../integrations/hooks.js'; import type { AstroConfig } from '../../types/public/config.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import type { AstroPrerenderer, RouteToHeaders } from '../../types/public/index.js'; import type { RouteData, RouteType, SSRError } from '../../types/public/internal.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; @@ -369,7 +369,7 @@ interface RenderToPathPayload { route: RouteData; options: StaticBuildOptions; routeToHeaders?: RouteToHeaders; - logger: Logger; + logger: AstroLogger; } /** @@ -532,7 +532,7 @@ async function generatePathWithPrerenderer( route: RouteData, options: StaticBuildOptions, routeToHeaders: RouteToHeaders, - logger: Logger, + logger: AstroLogger, ): Promise { const timeStart = performance.now(); const { config } = options.settings; @@ -565,7 +565,7 @@ async function generatePathWithPrerenderer( logRenderTime(logger, timeStart, false); } -function logRenderTime(logger: Logger, timeStart: number, notCreated: boolean) { +function logRenderTime(logger: AstroLogger, timeStart: number, notCreated: boolean) { const timeEnd = performance.now(); const isSlow = timeEnd - timeStart > THRESHOLD_SLOW_RENDER_TIME_MS; const timeIncrease = (isSlow ? colors.red : colors.dim)(`(+${getTimeStat(timeStart, timeEnd)})`); @@ -643,7 +643,7 @@ function checkPublicConflict( outFile: URL, route: RouteData, settings: AstroSettings, - logger: Logger, + logger: AstroLogger, ): boolean { const outRoot = settings.buildOutput === 'static' && !settings.adapter?.adapterFeatures?.preserveBuildClientDir diff --git a/packages/astro/src/core/build/index.ts b/packages/astro/src/core/build/index.ts index dce2b3ec6e77..d96f736efcaf 100644 --- a/packages/astro/src/core/build/index.ts +++ b/packages/astro/src/core/build/index.ts @@ -19,7 +19,7 @@ import { createSettings } from '../config/settings.js'; import { createVite } from '../create-vite.js'; import { createKey, getEnvironmentKey, hasEnvironmentKey } from '../encryption.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import { levels, timerMessage } from '../logger/core.js'; import { createRoutesList } from '../routing/create-manifest.js'; import { getPrerenderDefault } from '../../prerender/utils.js'; @@ -89,7 +89,7 @@ export default async function build( } interface AstroBuilderOptions extends BuildOptions { - logger: Logger; + logger: AstroLogger; mode: string; runtimeMode: RuntimeMode; /** @@ -106,7 +106,7 @@ interface AstroBuilderOptions extends BuildOptions { export class AstroBuilder { private settings: AstroSettings; - private logger: Logger; + private logger: AstroLogger; private mode: string; private runtimeMode: RuntimeMode; private origin: string; @@ -303,7 +303,7 @@ export class AstroBuilder { pageCount, buildMode, }: { - logger: Logger; + logger: AstroLogger; timeStart: number; pageCount: number; buildMode: AstroSettings['buildOutput']; diff --git a/packages/astro/src/core/build/page-data.ts b/packages/astro/src/core/build/page-data.ts index 0261748cd20e..ec18562f7b17 100644 --- a/packages/astro/src/core/build/page-data.ts +++ b/packages/astro/src/core/build/page-data.ts @@ -1,6 +1,6 @@ import colors from 'piccolore'; import type { AstroSettings, RoutesList } from '../../types/astro.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import { debug } from '../logger/core.js'; import { DEFAULT_COMPONENTS } from '../routing/default.js'; import { makePageDataKey } from './plugins/util.js'; @@ -8,7 +8,7 @@ import type { AllPagesData } from './types.js'; interface CollectPagesDataOptions { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; manifest: RoutesList; } diff --git a/packages/astro/src/core/build/types.ts b/packages/astro/src/core/build/types.ts index f6e2f9c3543d..b55f369d3563 100644 --- a/packages/astro/src/core/build/types.ts +++ b/packages/astro/src/core/build/types.ts @@ -4,7 +4,7 @@ import type { AstroSettings, ComponentInstance, RoutesList } from '../../types/a import type { MiddlewareHandler } from '../../types/public/common.js'; import type { RuntimeMode } from '../../types/public/config.js'; import type { RouteData } from '../../types/public/internal.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; type ComponentPath = string; export type ViteID = string; @@ -28,7 +28,7 @@ export type AllPagesData = Record; export interface StaticBuildOptions { allPages: AllPagesData; settings: AstroSettings; - logger: Logger; + logger: AstroLogger; routesList: RoutesList; runtimeMode: RuntimeMode; origin: string; diff --git a/packages/astro/src/core/cache/runtime/noop.ts b/packages/astro/src/core/cache/runtime/noop.ts index fadb1ffb27a4..73f8953977c1 100644 --- a/packages/astro/src/core/cache/runtime/noop.ts +++ b/packages/astro/src/core/cache/runtime/noop.ts @@ -2,7 +2,7 @@ import { AstroError } from '../../errors/errors.js'; import { CacheNotEnabled } from '../../errors/errors-data.js'; import type { CacheLike } from './cache.js'; import type { CacheOptions } from '../types.js'; -import type { Logger } from '../../logger/core.js'; +import type { AstroLogger } from '../../logger/core.js'; /** * A no-op cache implementation used in dev mode when cache is configured. @@ -38,9 +38,9 @@ let hasWarned = false; */ export class DisabledAstroCache implements CacheLike { readonly enabled = false; - #logger: Logger | undefined; + #logger: AstroLogger | undefined; - constructor(logger?: Logger) { + constructor(logger?: AstroLogger) { this.#logger = logger; } diff --git a/packages/astro/src/core/create-vite.ts b/packages/astro/src/core/create-vite.ts index e8aaaf05583e..2c80bb837123 100644 --- a/packages/astro/src/core/create-vite.ts +++ b/packages/astro/src/core/create-vite.ts @@ -41,7 +41,7 @@ import astroPluginRoutes from '../vite-plugin-routes/index.js'; import vitePluginStaticPaths from '../vite-plugin-static-paths/index.js'; import astroScriptsPlugin from '../vite-plugin-scripts/index.js'; import astroScriptsPageSSRPlugin from '../vite-plugin-scripts/page-ssr.js'; -import type { Logger } from './logger/core.js'; +import type { AstroLogger } from './logger/core.js'; import { createViteLogger } from './logger/vite.js'; import { vitePluginMiddleware } from './middleware/vite-plugin.js'; import { joinPaths } from './path.js'; @@ -57,7 +57,7 @@ import { vitePluginAstroServerClient } from '../vite-plugin-overlay/index.js'; type CreateViteOptions = { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; mode: string; fs?: typeof nodeFs; routesList: RoutesList; diff --git a/packages/astro/src/core/dev/adapter-validation.ts b/packages/astro/src/core/dev/adapter-validation.ts index 6118492e0643..8da1ba2d1fc1 100644 --- a/packages/astro/src/core/dev/adapter-validation.ts +++ b/packages/astro/src/core/dev/adapter-validation.ts @@ -2,11 +2,11 @@ import { getAdapterStaticRecommendation } from '../../integrations/features-vali import type { AstroSettings } from '../../types/astro.js'; import type { AstroAdapter } from '../../types/public/integrations.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; let hasWarnedMissingAdapter = false; -export function warnMissingAdapter(logger: Logger, settings: AstroSettings) { +export function warnMissingAdapter(logger: AstroLogger, settings: AstroSettings) { if (hasWarnedMissingAdapter) return; if (settings.buildOutput === 'server' && !settings.config.adapter) { logger.warn( @@ -18,7 +18,7 @@ export function warnMissingAdapter(logger: Logger, settings: AstroSettings) { } export function validateSetAdapter( - logger: Logger, + logger: AstroLogger, settings: AstroSettings, adapter: AstroAdapter, maybeConflictingIntegration: string, diff --git a/packages/astro/src/core/dev/container.ts b/packages/astro/src/core/dev/container.ts index 002fda9c1378..6fbe717d4c3e 100644 --- a/packages/astro/src/core/dev/container.ts +++ b/packages/astro/src/core/dev/container.ts @@ -11,7 +11,7 @@ import { import type { AstroSettings } from '../../types/astro.js'; import type { AstroInlineConfig } from '../../types/public/config.js'; import { createVite } from '../create-vite.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import { createRoutesList } from '../routing/create-manifest.js'; import { getPrerenderDefault } from '../../prerender/utils.js'; import { syncInternal } from '../sync/index.js'; @@ -19,7 +19,7 @@ import { warnMissingAdapter } from './adapter-validation.js'; export interface Container { fs: typeof nodeFs; - logger: Logger; + logger: AstroLogger; settings: AstroSettings; viteServer: vite.ViteDevServer; inlineConfig: AstroInlineConfig; @@ -29,7 +29,7 @@ export interface Container { } interface CreateContainerParams { - logger: Logger; + logger: AstroLogger; settings: AstroSettings; inlineConfig?: AstroInlineConfig; isRestart?: boolean; diff --git a/packages/astro/src/core/dev/dev.ts b/packages/astro/src/core/dev/dev.ts index 7ed92db0b13a..cd5041a0b353 100644 --- a/packages/astro/src/core/dev/dev.ts +++ b/packages/astro/src/core/dev/dev.ts @@ -25,9 +25,9 @@ import { } from './update-check.js'; import { BuildTimeAstroVersionProvider } from '../../cli/infra/build-time-astro-version-provider.js'; import { piccoloreTextStyler } from '../../cli/infra/piccolore-text-styler.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; -function warnIfVite8({ root, logger }: { root: URL | string; logger: Logger }) { +function warnIfVite8({ root, logger }: { root: URL | string; logger: AstroLogger }) { try { const require = createRequire(root); const { version } = require('vite/package.json') as { version: string }; diff --git a/packages/astro/src/core/logger/console.ts b/packages/astro/src/core/logger/console.ts index dd2257390fbd..b59b52484a21 100644 --- a/packages/astro/src/core/logger/console.ts +++ b/packages/astro/src/core/logger/console.ts @@ -1,7 +1,7 @@ -import { getEventPrefix, type LogMessage, type LogWritable, levels } from './core.js'; +import { getEventPrefix, type AstroLogMessage, type LogWritable, levels } from './core.js'; -export const consoleLogDestination: LogWritable = { - write(event: LogMessage) { +export const consoleLogDestination: LogWritable = { + write(event: AstroLogMessage) { let dest = console.error; if (levels[event.level] < levels['error']) { dest = console.info; diff --git a/packages/astro/src/core/logger/core.ts b/packages/astro/src/core/logger/core.ts index d79c6b2c31e3..f63890dd231f 100644 --- a/packages/astro/src/core/logger/core.ts +++ b/packages/astro/src/core/logger/core.ts @@ -4,7 +4,25 @@ export interface LogWritable { write: (chunk: T) => boolean; } -export type LoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; // same as Pino +// NOTE: this is a public type +/** + * How the log should be formatted + * - 'default': how Astro usually format the logs + * - 'json': logs are formatted in JSON format + */ +export type AstroLoggerFormat = 'default' | 'json'; + +// NOTE: this is a public type + +/** + * The level of logging. Priority is the following: + * 1. debug + * 2. error + * 3. warn + * 4. info + * 5. silent + */ +export type AstroLoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; // same as Pino /** * Defined logger labels. Add more as needed, but keep them high-level & reusable, @@ -42,8 +60,9 @@ type LoggerLabel = | 'SKIP_FORMAT'; export interface LogOptions { - dest: LogWritable; - level: LoggerLevel; + destination: LogWritable; + level: AstroLoggerLevel; + format: AstroLoggerFormat; } // Hey, locales are pretty complicated! Be careful modifying this logic... @@ -63,14 +82,29 @@ export const dateTimeFormat = new Intl.DateTimeFormat([], { hour12: false, }); -export interface LogMessage { +// NOTE: this is a public type now +export interface AstroLogMessage { + /** + * Label associated to the message. Used by Astro for pretty logging + */ label: string | null; - level: LoggerLevel; + /** + * The level of the log + */ + level: AstroLoggerLevel; + /** + * The message of the log + */ message: string; + /** + * Whether a newline should be appended to the end of the message i.e. message + '\n' + */ newLine: boolean; + + format: AstroLoggerFormat; } -export const levels: Record = { +export const levels: Record = { debug: 20, info: 30, warn: 40, @@ -81,18 +115,19 @@ export const levels: Record = { /** Full logging API */ function log( opts: LogOptions, - level: LoggerLevel, + level: AstroLoggerLevel, label: string | null, message: string, newLine = true, ) { const logLevel = opts.level; - const dest = opts.dest; - const event: LogMessage = { + const dest = opts.destination; + const event: AstroLogMessage = { label, level, message, newLine, + format: opts.format, }; // test if this level is enabled or not @@ -103,7 +138,7 @@ function log( dest.write(event); } -export function isLogLevelEnabled(configuredLogLevel: LoggerLevel, level: LoggerLevel) { +export function isLogLevelEnabled(configuredLogLevel: AstroLoggerLevel, level: AstroLoggerLevel) { return levels[configuredLogLevel] <= levels[level]; } @@ -133,7 +168,7 @@ export function debug(...args: any[]) { * This includes the timestamp, log level, and label all properly formatted * with colors. This is shared across different loggers, so it's defined here. */ -export function getEventPrefix({ level, label }: LogMessage) { +export function getEventPrefix({ level, label }: AstroLogMessage) { const timestamp = `${dateTimeFormat.format(new Date())}`; const prefix = []; if (level === 'error' || level === 'warn') { @@ -165,9 +200,12 @@ export function timerMessage(message: string, startTime: number = Date.now()) { return `${message} ${colors.dim(timeDisplay)}`; } -export class Logger { +export class AstroLogger { options: LogOptions; constructor(options: LogOptions) { + if (!options.format) { + options.format = 'default'; + } this.options = options; } diff --git a/packages/astro/src/core/logger/node.ts b/packages/astro/src/core/logger/node.ts index e43f98eaf4c8..afdafc579318 100644 --- a/packages/astro/src/core/logger/node.ts +++ b/packages/astro/src/core/logger/node.ts @@ -1,26 +1,35 @@ import type { Writable } from 'node:stream'; import { createDebug, enable as obugEnable } from 'obug'; import type { AstroInlineConfig } from '../../types/public/config.js'; -import { Logger } from './core.js'; -import { getEventPrefix, type LogMessage, type LogWritable, levels } from './core.js'; +import { AstroLogger } from './core.js'; +import { getEventPrefix, type AstroLogMessage, type LogWritable, levels } from './core.js'; type ConsoleStream = Writable & { fd: 1 | 2; }; -export const nodeLogDestination: LogWritable = { - write(event: LogMessage) { +export const nodeLogDestination: LogWritable = { + write(event: AstroLogMessage) { let dest: ConsoleStream = process.stderr; if (levels[event.level] < levels['error']) { dest = process.stdout; } + let trailingLine = event.newLine ? '\n' : ''; - if (event.label === 'SKIP_FORMAT') { - dest.write(event.message + trailingLine); - } else { - dest.write(getEventPrefix(event) + ' ' + event.message + trailingLine); + switch (event.format) { + case 'json': { + dest.write(JSON.stringify({ message: event.message, label: event.label }) + trailingLine); + return true; + } + case 'default': { + if (event.label === 'SKIP_FORMAT') { + dest.write(event.message + trailingLine); + } else { + dest.write(getEventPrefix(event) + ' ' + event.message + trailingLine); + } + return true; + } } - return true; }, }; @@ -52,11 +61,12 @@ export function enableVerboseLogging() { ); } -export function createNodeLogger(inlineConfig: AstroInlineConfig): Logger { +export function createNodeLogger(inlineConfig: AstroInlineConfig): AstroLogger { if (inlineConfig.logger) return inlineConfig.logger; - return new Logger({ - dest: nodeLogDestination, + return new AstroLogger({ + destination: nodeLogDestination, level: inlineConfig.logLevel ?? 'info', + format: 'default', }); } diff --git a/packages/astro/src/core/logger/public.ts b/packages/astro/src/core/logger/public.ts new file mode 100644 index 000000000000..000afa583f49 --- /dev/null +++ b/packages/astro/src/core/logger/public.ts @@ -0,0 +1,10 @@ +import type { AstroLoggerDestination } from '../../types/public/logger.js'; +import type { AstroLogger } from './core.js'; + +export function defineDestination(fn: AstroLoggerDestination) { + return fn; +} + +export function defineAstroLogger(fn: AstroLogger) { + return fn; +} diff --git a/packages/astro/src/core/logger/vite.ts b/packages/astro/src/core/logger/vite.ts index c6acab200088..24d88e1c2076 100644 --- a/packages/astro/src/core/logger/vite.ts +++ b/packages/astro/src/core/logger/vite.ts @@ -3,7 +3,7 @@ import { stripVTControlCharacters } from 'node:util'; import type { LogLevel, Rollup, Logger as ViteLogger } from 'vite'; import { isAstroError } from '../errors/errors.js'; import { serverShortcuts as formatServerShortcuts } from '../messages/runtime.js'; -import { type Logger as AstroLogger, isLogLevelEnabled } from './core.js'; +import { type AstroLogger as AstroLogger, isLogLevelEnabled } from './core.js'; const PKG_PREFIX = fileURLToPath(new URL('../../../', import.meta.url)); const E2E_PREFIX = fileURLToPath(new URL('../../../e2e', import.meta.url)); diff --git a/packages/astro/src/core/messages/runtime.ts b/packages/astro/src/core/messages/runtime.ts index f83062426916..7dd1e05ae38f 100644 --- a/packages/astro/src/core/messages/runtime.ts +++ b/packages/astro/src/core/messages/runtime.ts @@ -11,7 +11,7 @@ import { import { padMultilineString } from '../util-runtime.js'; import type { AstroVersionProvider, TextStyler } from '../../cli/definitions.js'; import type { AstroConfig } from '../../types/public/index.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; const { bgGreen, @@ -401,7 +401,7 @@ export function printHelp({ console.log(message.join('\n') + '\n'); } -export function warnIfCspWithShiki(config: AstroConfig, logger: Logger): void { +export function warnIfCspWithShiki(config: AstroConfig, logger: AstroLogger): void { // Check if CSP is enabled const cspEnabled = config.security.csp !== false; if (!cspEnabled) return; diff --git a/packages/astro/src/core/preview/static-preview-server.ts b/packages/astro/src/core/preview/static-preview-server.ts index cee1e448f089..0c3191a1676f 100644 --- a/packages/astro/src/core/preview/static-preview-server.ts +++ b/packages/astro/src/core/preview/static-preview-server.ts @@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url'; import type * as vite from 'vite'; import { mergeConfig, preview, type PreviewServer as VitePreviewServer } from 'vite'; import type { AstroSettings } from '../../types/astro.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import * as msg from '../messages/runtime.js'; import { getResolvedHostForHttpServer } from './util.js'; import { vitePluginAstroPreview } from './vite-plugin-astro-preview.js'; @@ -21,7 +21,7 @@ interface PreviewServer { export default async function createStaticPreviewServer( settings: AstroSettings, - logger: Logger, + logger: AstroLogger, ): Promise { const startServerTime = performance.now(); diff --git a/packages/astro/src/core/render/params-and-props.ts b/packages/astro/src/core/render/params-and-props.ts index 1c43a15d0162..2563b678f53e 100644 --- a/packages/astro/src/core/render/params-and-props.ts +++ b/packages/astro/src/core/render/params-and-props.ts @@ -4,7 +4,7 @@ import type { AstroConfig } from '../../types/public/index.js'; import type { RouteData } from '../../types/public/internal.js'; import { DEFAULT_404_COMPONENT } from '../constants.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import { routeHasHtmlExtension, routeIsFallback, routeIsRedirect } from '../routing/helpers.js'; import type { RouteCache } from './route-cache.js'; import { callGetStaticPaths, findPathItemByKey } from './route-cache.js'; @@ -14,7 +14,7 @@ interface GetParamsAndPropsOptions { routeData?: RouteData | undefined; routeCache: RouteCache; pathname: string; - logger: Logger; + logger: AstroLogger; serverLike: boolean; base: string; trailingSlash: AstroConfig['trailingSlash']; diff --git a/packages/astro/src/core/render/route-cache.ts b/packages/astro/src/core/render/route-cache.ts index 1e8ab80631c8..dd70c2cebb7c 100644 --- a/packages/astro/src/core/render/route-cache.ts +++ b/packages/astro/src/core/render/route-cache.ts @@ -8,7 +8,7 @@ import type { } from '../../types/public/common.js'; import type { AstroConfig, RuntimeMode } from '../../types/public/config.js'; import type { RouteData } from '../../types/public/internal.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import { stringifyParams } from '../routing/params.js'; import { validateDynamicRouteModule, validateGetStaticPathsResult } from '../routing/validation.js'; @@ -87,11 +87,11 @@ interface RouteCacheEntry { * responses during dev and only ever called once during build. */ export class RouteCache { - private logger: Logger; + private logger: AstroLogger; private cache: Record = {}; private runtimeMode: RuntimeMode; - constructor(logger: Logger, runtimeMode: RuntimeMode = 'production') { + constructor(logger: AstroLogger, runtimeMode: RuntimeMode = 'production') { this.logger = logger; this.runtimeMode = runtimeMode; } @@ -125,7 +125,7 @@ export function findPathItemByKey( staticPaths: GetStaticPathsResultKeyed, params: Params, route: RouteData, - logger: Logger, + logger: AstroLogger, trailingSlash: AstroConfig['trailingSlash'], ) { const paramsKey = stringifyParams(params, route, trailingSlash); diff --git a/packages/astro/src/core/render/slots.ts b/packages/astro/src/core/render/slots.ts index 01dde33e19bc..1d8abf67d66c 100644 --- a/packages/astro/src/core/render/slots.ts +++ b/packages/astro/src/core/render/slots.ts @@ -4,7 +4,7 @@ import { chunkToString } from '../../runtime/server/render/index.js'; import { isRenderInstruction } from '../../runtime/server/render/instruction.js'; import type { SSRResult } from '../../types/public/internal.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; function getFunctionExpression(slot: any) { if (!slot) return; @@ -16,9 +16,9 @@ function getFunctionExpression(slot: any) { export class Slots { #result: SSRResult; #slots: ComponentSlots | null; - #logger: Logger; + #logger: AstroLogger; - constructor(result: SSRResult, slots: ComponentSlots | null, logger: Logger) { + constructor(result: SSRResult, slots: ComponentSlots | null, logger: AstroLogger) { this.#result = result; this.#slots = slots; this.#logger = logger; diff --git a/packages/astro/src/core/request.ts b/packages/astro/src/core/request.ts index e2c79211e99a..6b83382bd958 100644 --- a/packages/astro/src/core/request.ts +++ b/packages/astro/src/core/request.ts @@ -1,5 +1,5 @@ import type { IncomingHttpHeaders } from 'node:http'; -import type { Logger } from './logger/core.js'; +import type { AstroLogger } from './logger/core.js'; type HeaderType = Headers | Record | IncomingHttpHeaders; @@ -9,7 +9,7 @@ interface CreateRequestOptions { headers: HeaderType; method?: string; body?: RequestInit['body']; - logger: Logger; + logger: AstroLogger; locals?: object | undefined; /** * Whether the request is being created for a static build or for a prerendered page within a hybrid/SSR build, or for emulating one of those in dev mode. diff --git a/packages/astro/src/core/routing/create-manifest.ts b/packages/astro/src/core/routing/create-manifest.ts index 729ad6200b73..e8a8a0dab88b 100644 --- a/packages/astro/src/core/routing/create-manifest.ts +++ b/packages/astro/src/core/routing/create-manifest.ts @@ -18,7 +18,7 @@ import { UnsupportedExternalRedirect, } from '../errors/errors-data.js'; import { AstroError } from '../errors/index.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import { hasFileExtension, removeLeadingForwardSlash, slash } from '../path.js'; import { injectServerIslandRoute } from '../server-islands/endpoint.js'; import { resolvePages } from '../util.js'; @@ -120,7 +120,7 @@ interface CreateRouteManifestParams { function createFileBasedRoutes( { settings, cwd, fsMod }: CreateRouteManifestParams, - logger: Logger, + logger: AstroLogger, ): RouteData[] { const { config } = settings; const pages = resolvePages(config); @@ -273,7 +273,7 @@ function createFileBasedRoutes( export function createRoutesFromEntries( entries: RouteEntry[], settings: RoutingSettings, - logger: Logger, + logger: AstroLogger, pagesDirRelative = 'src/pages', ): RouteData[] { const entriesByDir = groupEntriesByDir(entries); @@ -283,7 +283,7 @@ export function createRoutesFromEntries( function createRoutesFromEntriesByDir( entriesByDir: Map, settings: RoutingSettings, - logger: Logger, + logger: AstroLogger, pagesDirRelative: string, ): RouteData[] { const routes: RouteData[] = []; @@ -603,7 +603,12 @@ function isStaticSegment(segment: RoutePart[]) { * For example, `/foo/[bar]` and `/foo/[baz]` or `/foo/[...bar]` and `/foo/[...baz]` * but not `/foo/[bar]` and `/foo/[...baz]`. */ -function detectRouteCollision(a: RouteData, b: RouteData, _config: AstroConfig, logger: Logger) { +function detectRouteCollision( + a: RouteData, + b: RouteData, + _config: AstroConfig, + logger: AstroLogger, +) { if (a.type === 'fallback' || b.type === 'fallback') { // If either route is a fallback route, they don't collide. // Fallbacks are always added below other routes exactly to avoid collisions. @@ -667,7 +672,7 @@ function detectRouteCollision(a: RouteData, b: RouteData, _config: AstroConfig, */ export async function createRoutesList( params: CreateRouteManifestParams, - logger: Logger, + logger: AstroLogger, { dev = false, }: { diff --git a/packages/astro/src/core/routing/prerender.ts b/packages/astro/src/core/routing/prerender.ts index 36e9f42a4088..e82d51668d9d 100644 --- a/packages/astro/src/core/routing/prerender.ts +++ b/packages/astro/src/core/routing/prerender.ts @@ -2,7 +2,7 @@ import { runHookRouteSetup } from '../../integrations/hooks.js'; import { getPrerenderDefault } from '../../prerender/utils.js'; import type { AstroSettings } from '../../types/astro.js'; import type { RouteData } from '../../types/public/internal.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; const PRERENDER_REGEX = /^\s*export\s+const\s+prerender\s*=\s*(true|false);?/m; @@ -20,7 +20,7 @@ export async function getRoutePrerenderOption( content: string, route: RouteData, settings: AstroSettings, - logger: Logger, + logger: AstroLogger, ) { // Check if the route is pre-rendered or not const match = PRERENDER_REGEX.exec(content); diff --git a/packages/astro/src/core/routing/rewrite.ts b/packages/astro/src/core/routing/rewrite.ts index e37ab3849bd2..932c2334c25e 100644 --- a/packages/astro/src/core/routing/rewrite.ts +++ b/packages/astro/src/core/routing/rewrite.ts @@ -5,7 +5,7 @@ import type { RouteData } from '../../types/public/internal.js'; import { shouldAppendForwardSlash } from '../build/util.js'; import { originPathnameSymbol } from '../constants.js'; import { AstroError, AstroErrorData } from '../errors/index.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import { appendForwardSlash, joinPaths, @@ -139,7 +139,7 @@ export function copyRequest( newUrl: URL, oldRequest: Request, isPrerendered: boolean, - logger: Logger, + logger: AstroLogger, routePattern: string, ): Request { if (oldRequest.bodyUsed) { diff --git a/packages/astro/src/core/sync/index.ts b/packages/astro/src/core/sync/index.ts index 629eb0c9bac5..cfcf14852c26 100644 --- a/packages/astro/src/core/sync/index.ts +++ b/packages/astro/src/core/sync/index.ts @@ -30,7 +30,7 @@ import { type ErrorWithMetadata, isAstroError, } from '../errors/index.js'; -import type { Logger } from '../logger/core.js'; +import type { AstroLogger } from '../logger/core.js'; import { createRoutesList } from '../routing/create-manifest.js'; import { ensureProcessNodeEnv } from '../util.js'; import { normalizePath } from '../viteUtils.js'; @@ -41,7 +41,7 @@ type SyncOptions = { * @internal only used for testing */ fs?: typeof fsMod; - logger: Logger; + logger: AstroLogger; settings: AstroSettings; force?: boolean; skip?: { @@ -92,7 +92,7 @@ export async function clearContentLayerCache({ isDev, }: { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; fs?: typeof fsMod; isDev: boolean; }) { @@ -292,7 +292,7 @@ async function createTempViteServer( */ async function syncContentCollections( settings: AstroSettings, - { logger, fs, viteServer }: { logger: Logger; fs: typeof fsMod; viteServer: ViteDevServer }, + { logger, fs, viteServer }: { logger: AstroLogger; fs: typeof fsMod; viteServer: ViteDevServer }, ): Promise { try { const contentTypesGenerator = await createContentTypesGenerator({ diff --git a/packages/astro/src/integrations/features-validation.ts b/packages/astro/src/integrations/features-validation.ts index 0534c6f43f79..87a8ac689fac 100644 --- a/packages/astro/src/integrations/features-validation.ts +++ b/packages/astro/src/integrations/features-validation.ts @@ -1,4 +1,4 @@ -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { AstroSettings } from '../types/astro.js'; import type { AdapterSupport, @@ -29,7 +29,7 @@ export function validateSupportedFeatures( adapterName: string, featureMap: AstroAdapterFeatureMap, settings: AstroSettings, - logger: Logger, + logger: AstroLogger, ): ValidationResult { const { serverOutput = AdapterFeatureStability.UNSUPPORTED, @@ -115,7 +115,7 @@ function getSupportMessageSuppression(supportKind: AdapterSupport): 'all' | 'def function validateSupportKind( supportKind: AdapterSupport, adapterName: string, - logger: Logger, + logger: AstroLogger, featureName: string, hasCorrectConfig: () => boolean, ): boolean { @@ -139,7 +139,7 @@ function validateSupportKind( function logFeatureSupport( adapterName: string, - logger: Logger, + logger: AstroLogger, featureName: string, supportKind: AdapterSupport, adapterMessage?: string, diff --git a/packages/astro/src/integrations/hooks.ts b/packages/astro/src/integrations/hooks.ts index 91cfa39988d8..2740011ab3d8 100644 --- a/packages/astro/src/integrations/hooks.ts +++ b/packages/astro/src/integrations/hooks.ts @@ -15,7 +15,7 @@ import { buildClientDirectiveEntrypoint } from '../core/client-directive/index.j import { mergeConfig } from '../core/config/merge.js'; import { validateConfigRefined } from '../core/config/validate.js'; import { validateSetAdapter } from '../core/dev/adapter-validation.js'; -import type { AstroIntegrationLogger, Logger } from '../core/logger/core.js'; +import type { AstroIntegrationLogger, AstroLogger } from '../core/logger/core.js'; import { getRouteGenerator } from '../core/routing/generator.js'; import { getClientOutputDirectory } from '../prerender/utils.js'; import type { AstroSettings } from '../types/astro.js'; @@ -47,7 +47,7 @@ async function withTakingALongTimeMsg({ name: string; hookName: keyof BaseIntegrationHooks; hookFn: () => T | Promise; - logger: Logger; + logger: AstroLogger; integrationLogger: AstroIntegrationLogger; }): Promise { const timeout = setTimeout(() => { @@ -79,7 +79,7 @@ async function runHookInternal({ }: { integration: AstroIntegration; hookName: THook; - logger: Logger; + logger: AstroLogger; params: () => Omit>, 'logger'>; }) { const hook = integration?.hooks?.[hookName]; @@ -99,7 +99,7 @@ async function runHookInternal({ // Used internally to store instances of loggers. const Loggers = new WeakMap(); -function getLogger(integration: AstroIntegration, logger: Logger) { +function getLogger(integration: AstroIntegration, logger: AstroLogger) { if (Loggers.has(integration)) { // SAFETY: we check the existence in the if block return Loggers.get(integration)!; @@ -167,7 +167,7 @@ export function normalizeInjectedTypeFilename(filename: string, integrationName: interface RunHookConfigSetup { settings: AstroSettings; command: 'dev' | 'build' | 'preview' | 'sync'; - logger: Logger; + logger: AstroLogger; isRestart?: boolean; fs?: typeof fsMod; } @@ -365,7 +365,7 @@ export async function runHookConfigDone({ command, }: { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; command?: 'dev' | 'build' | 'preview' | 'sync'; }) { for (const integration of settings.config.integrations) { @@ -426,7 +426,7 @@ export async function runHookServerSetup({ }: { config: AstroConfig; server: ViteDevServer; - logger: Logger; + logger: AstroLogger; }) { let refreshContent: undefined | ((options: RefreshContentOptions) => Promise); refreshContent = async (options: RefreshContentOptions) => { @@ -465,7 +465,7 @@ export async function runHookServerStart({ }: { config: AstroConfig; address: AddressInfo; - logger: Logger; + logger: AstroLogger; }) { for (const integration of config.integrations) { await runHookInternal({ @@ -482,7 +482,7 @@ export async function runHookServerDone({ logger, }: { config: AstroConfig; - logger: Logger; + logger: AstroLogger; }) { for (const integration of config.integrations) { await runHookInternal({ @@ -499,7 +499,7 @@ export async function runHookBuildStart({ logger, }: { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; }) { for (const integration of settings.config.integrations) { await runHookInternal({ @@ -526,7 +526,7 @@ export async function runHookBuildSetup({ vite: InlineConfig; pages: Map; target: 'server' | 'client'; - logger: Logger; + logger: AstroLogger; }): Promise { let updatedConfig = vite; @@ -553,7 +553,7 @@ export async function runHookBuildSetup({ type RunHookBuildSsr = { config: AstroConfig; manifest: SerializedSSRManifest; - logger: Logger; + logger: AstroLogger; middlewareEntryPoint: URL | undefined; }; @@ -582,7 +582,7 @@ export async function runHookBuildGenerated({ routeToHeaders, }: { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; routeToHeaders: RouteToHeaders; }) { const preserveStructure = settings.adapter?.adapterFeatures?.preserveBuildClientDir; @@ -605,7 +605,7 @@ type RunHookBuildDone = { settings: AstroSettings; pages: string[]; routes: RouteData[]; - logger: Logger; + logger: AstroLogger; }; export async function runHookBuildDone({ settings, pages, routes, logger }: RunHookBuildDone) { @@ -635,7 +635,7 @@ export async function runHookRouteSetup({ }: { route: RouteOptions; settings: AstroSettings; - logger: Logger; + logger: AstroLogger; }) { const prerenderChangeLogs: { integrationName: string; value: boolean | undefined }[] = []; @@ -668,7 +668,7 @@ export async function runHookRoutesResolved({ }: { routes: Array; settings: AstroSettings; - logger: Logger; + logger: AstroLogger; }) { for (const integration of settings.config.integrations) { await runHookInternal({ diff --git a/packages/astro/src/runtime/server/endpoint.ts b/packages/astro/src/runtime/server/endpoint.ts index a54d218361e8..d3d99f954004 100644 --- a/packages/astro/src/runtime/server/endpoint.ts +++ b/packages/astro/src/runtime/server/endpoint.ts @@ -2,7 +2,7 @@ import colors from 'piccolore'; import { REROUTABLE_STATUS_CODES, REROUTE_DIRECTIVE_HEADER } from '../../core/constants.js'; import { AstroError } from '../../core/errors/errors.js'; import { EndpointDidNotReturnAResponse } from '../../core/errors/errors-data.js'; -import type { Logger } from '../../core/logger/core.js'; +import type { AstroLogger } from '../../core/logger/core.js'; import type { APIRoute } from '../../types/public/common.js'; import type { APIContext } from '../../types/public/context.js'; @@ -13,7 +13,7 @@ export async function renderEndpoint( }, context: APIContext, isPrerendered: boolean, - logger: Logger, + logger: AstroLogger, ) { const { request, url } = context; diff --git a/packages/astro/src/types/astro.ts b/packages/astro/src/types/astro.ts index 9b52b340ef82..2a676571a4bd 100644 --- a/packages/astro/src/types/astro.ts +++ b/packages/astro/src/types/astro.ts @@ -1,6 +1,6 @@ import type { AstroTimer } from '../core/config/timer.js'; import type { TSConfig } from '../core/config/tsconfig.js'; -import type { Logger, LoggerLevel } from '../core/logger/core.js'; +import type { AstroLogger, AstroLoggerLevel } from '../core/logger/core.js'; import type { AstroPreferences } from '../preferences/index.js'; import type { AstroComponentFactory } from '../runtime/server/index.js'; import type { GetStaticPaths } from './public/common.js'; @@ -78,7 +78,7 @@ export interface AstroSettings { fontResources: Set; styleHashes: Required['hashes']; }; - logLevel: LoggerLevel; + logLevel: AstroLoggerLevel; } /** Generic interface for a component (Astro, Svelte, React, etc.) */ @@ -96,7 +96,7 @@ export interface RoutesList { export interface AstroPluginOptions { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; } export interface ImportedDevStyle { diff --git a/packages/astro/src/types/public/config.ts b/packages/astro/src/types/public/config.ts index 7c06f63ca188..57029eaf177c 100644 --- a/packages/astro/src/types/public/config.ts +++ b/packages/astro/src/types/public/config.ts @@ -17,7 +17,7 @@ import type { CacheProviderConfig, RouteRules } from '../../core/cache/types.js' import type { AstroConfigType } from '../../core/config/schemas/index.js'; import type { REDIRECT_STATUS_CODES } from '../../core/constants.js'; import type { CspAlgorithm, CspDirective, CspHash } from '../../core/csp/config.js'; -import type { Logger, LoggerLevel } from '../../core/logger/core.js'; +import type { AstroLogger, AstroLoggerLevel } from '../../core/logger/core.js'; import type { SessionConfig, SessionDriverConfig, @@ -3109,7 +3109,7 @@ export interface AstroInlineOnlyConfig { * * @default "info" */ - logLevel?: LoggerLevel; + logLevel?: AstroLoggerLevel; /** * Clear the content layer cache, forcing a rebuild of all content entries. */ @@ -3117,5 +3117,5 @@ export interface AstroInlineOnlyConfig { /** * @internal for testing only, use `logLevel` instead. */ - logger?: Logger; + logger?: AstroLogger; } diff --git a/packages/astro/src/types/public/logger.ts b/packages/astro/src/types/public/logger.ts new file mode 100644 index 000000000000..cc626aeb1118 --- /dev/null +++ b/packages/astro/src/types/public/logger.ts @@ -0,0 +1,7 @@ +import type { AstroLogMessage, AstroLoggerLevel } from '../../core/logger/core.js'; + +export type { AstroLogMessage, AstroLoggerLevel }; + +export type AstroLoggerDestination = { + write: (chunk: D | AstroLogMessage) => void; +}; diff --git a/packages/astro/src/vite-plugin-app/app.ts b/packages/astro/src/vite-plugin-app/app.ts index 69c59646ed7b..ac958214e9d6 100644 --- a/packages/astro/src/vite-plugin-app/app.ts +++ b/packages/astro/src/vite-plugin-app/app.ts @@ -9,7 +9,7 @@ import { MiddlewareNotAResponse, } from '../core/errors/errors-data.js'; import { type AstroError, createSafeError, isAstroError } from '../core/errors/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { ModuleLoader } from '../core/module-loader/index.js'; import type { CreateRenderContext, RenderContext } from '../core/render-context.js'; import { createRequest } from '../core/request.js'; @@ -28,14 +28,14 @@ import { req } from '../core/messages/runtime.js'; export class AstroServerApp extends BaseApp { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; loader: ModuleLoader; manifestData: RoutesList; currentRenderContext: RenderContext | undefined = undefined; constructor( manifest: SSRManifest, streaming = true, - logger: Logger, + logger: AstroLogger, manifestData: RoutesList, loader: ModuleLoader, settings: AstroSettings, @@ -98,7 +98,7 @@ export class AstroServerApp extends BaseApp { static async create( manifest: SSRManifest, routesList: RoutesList, - logger: Logger, + logger: AstroLogger, loader: ModuleLoader, settings: AstroSettings, getDebugInfo: () => Promise, @@ -110,7 +110,7 @@ export class AstroServerApp extends BaseApp { _streaming: boolean, manifest: SSRManifest, settings: AstroSettings, - logger: Logger, + logger: AstroLogger, loader: ModuleLoader, manifestData: RoutesList, getDebugInfo: () => Promise, diff --git a/packages/astro/src/vite-plugin-app/createAstroServerApp.ts b/packages/astro/src/vite-plugin-app/createAstroServerApp.ts index a471389d27fc..c6abffe9b37f 100644 --- a/packages/astro/src/vite-plugin-app/createAstroServerApp.ts +++ b/packages/astro/src/vite-plugin-app/createAstroServerApp.ts @@ -11,7 +11,7 @@ import { PassthroughTextStyler } from '../cli/infra/passthrough-text-styler.js'; import { ProcessOperatingSystemProvider } from '../cli/infra/process-operating-system-provider.js'; import { TinyexecCommandExecutor } from '../cli/infra/tinyexec-command-executor.js'; import type { RouteInfo } from '../core/app/types.js'; -import { Logger } from '../core/logger/core.js'; +import { AstroLogger } from '../core/logger/core.js'; import { nodeLogDestination } from '../core/logger/node.js'; import type { ModuleLoader } from '../core/module-loader/index.js'; import type { AstroSettings, RoutesList } from '../types/astro.js'; @@ -22,13 +22,14 @@ export default async function createAstroServerApp( controller: DevServerController, settings: AstroSettings, loader: ModuleLoader, - logger?: Logger, + logger?: AstroLogger, ) { const actualLogger = logger ?? - new Logger({ - dest: nodeLogDestination, + new AstroLogger({ + destination: nodeLogDestination, level: settings.logLevel, + format: 'default', }); const routesList: RoutesList = { routes: routes.map((r: RouteInfo) => r.routeData) }; diff --git a/packages/astro/src/vite-plugin-app/pipeline.ts b/packages/astro/src/vite-plugin-app/pipeline.ts index f26fbe6a167c..983ff392b6cb 100644 --- a/packages/astro/src/vite-plugin-app/pipeline.ts +++ b/packages/astro/src/vite-plugin-app/pipeline.ts @@ -3,7 +3,7 @@ import { type HeadElements, Pipeline, type TryRewriteResult } from '../core/base import { ASTRO_VERSION } from '../core/constants.js'; import { enhanceViteSSRError } from '../core/errors/dev/index.js'; import { AggregateError, CSSError, MarkdownError } from '../core/errors/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { ModuleLoader } from '../core/module-loader/index.js'; import { RedirectComponentInstance } from '../core/redirects/index.js'; import { loadRenderer } from '../core/render/index.js'; @@ -52,7 +52,7 @@ export class RunnablePipeline extends Pipeline { private constructor( loader: ModuleLoader, - logger: Logger, + logger: AstroLogger, manifest: SSRManifest, settings: AstroSettings, getDebugInfo: () => Promise, diff --git a/packages/astro/src/vite-plugin-astro-server/base.ts b/packages/astro/src/vite-plugin-astro-server/base.ts index 93d46f775145..80dc9b2a326e 100644 --- a/packages/astro/src/vite-plugin-astro-server/base.ts +++ b/packages/astro/src/vite-plugin-astro-server/base.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import { appendForwardSlash, prependForwardSlash } from '@astrojs/internal-helpers/path'; import colors from 'piccolore'; import type * as vite from 'vite'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { notFoundTemplate, subpathNotUsedTemplate } from '../template/4xx.js'; import type { AstroSettings } from '../types/astro.js'; import { writeHtmlResponse } from './response.js'; @@ -83,7 +83,7 @@ export function evaluateBaseRewrite( export function baseMiddleware( settings: AstroSettings, - logger: Logger, + logger: AstroLogger, ): vite.Connect.NextHandleFunction { const { config } = settings; const { devRoot, devRootReplacement } = resolveDevRoot(config.base, config.site); diff --git a/packages/astro/src/vite-plugin-astro-server/error.ts b/packages/astro/src/vite-plugin-astro-server/error.ts index ca726d852e98..ce42a24d3d58 100644 --- a/packages/astro/src/vite-plugin-astro-server/error.ts +++ b/packages/astro/src/vite-plugin-astro-server/error.ts @@ -1,13 +1,13 @@ import type { SSRManifest } from '../core/app/types.js'; import { collectErrorMetadata } from '../core/errors/dev/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { formatErrorMessage } from '../core/messages/runtime.js'; import type { ModuleLoader } from '../core/module-loader/index.js'; export function recordServerError( loader: ModuleLoader, manifest: SSRManifest, - logger: Logger, + logger: AstroLogger, err: Error, ) { // This could be a runtime error from Vite's SSR module, so try to fix it here diff --git a/packages/astro/src/vite-plugin-astro-server/plugin.ts b/packages/astro/src/vite-plugin-astro-server/plugin.ts index 81bc6ac19a10..a236e1e03c05 100644 --- a/packages/astro/src/vite-plugin-astro-server/plugin.ts +++ b/packages/astro/src/vite-plugin-astro-server/plugin.ts @@ -6,7 +6,7 @@ import type { SSRManifest } from '../core/app/types.js'; import { ASTRO_VITE_ENVIRONMENT_NAMES, devPrerenderMiddlewareSymbol } from '../core/constants.js'; import { getViteErrorPayload } from '../core/errors/dev/index.js'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { createViteLoader } from '../core/module-loader/index.js'; import { matchAllRoutes } from '../core/routing/match.js'; import { SERIALIZED_MANIFEST_ID } from '../manifest/serialized.js'; @@ -22,7 +22,7 @@ import { trailingSlashMiddleware } from './trailing-slash.js'; interface AstroPluginOptions { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; } export default function createVitePluginAstroServer({ diff --git a/packages/astro/src/vite-plugin-astro-server/sec-fetch.ts b/packages/astro/src/vite-plugin-astro-server/sec-fetch.ts index aa1630fd4640..6354092c006a 100644 --- a/packages/astro/src/vite-plugin-astro-server/sec-fetch.ts +++ b/packages/astro/src/vite-plugin-astro-server/sec-fetch.ts @@ -1,7 +1,7 @@ import type { RemotePattern } from '@astrojs/internal-helpers/remote'; import type * as vite from 'vite'; import { BaseApp } from '../core/app/base.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; /** * Middleware that validates Sec-Fetch metadata headers on incoming requests @@ -21,7 +21,7 @@ import type { Logger } from '../core/logger/core.js'; * different origin than the dev server itself. */ export function secFetchMiddleware( - logger: Logger, + logger: AstroLogger, allowedDomains?: Partial[], ): vite.Connect.NextHandleFunction { return function devSecFetch(req, res, next) { diff --git a/packages/astro/src/vite-plugin-astro/compile.ts b/packages/astro/src/vite-plugin-astro/compile.ts index ebd7760d4048..c1c62efbe695 100644 --- a/packages/astro/src/vite-plugin-astro/compile.ts +++ b/packages/astro/src/vite-plugin-astro/compile.ts @@ -1,6 +1,6 @@ import { type ESBuildTransformResult, transformWithEsbuild } from 'vite'; import { type CompileProps, type CompileResult, compile } from '../core/compile/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { AstroConfig } from '../types/public/config.js'; import { getFileInfo } from '../vite-plugin-utils/index.js'; import type { CompileMetadata } from './types.js'; @@ -10,7 +10,7 @@ import type { SourceMapInput } from 'rollup'; interface CompileAstroOption { compileProps: CompileProps; astroFileToCompileMetadata: Map; - logger: Logger; + logger: AstroLogger; } export interface CompileAstroResult extends Omit { @@ -22,7 +22,7 @@ interface EnhanceCompilerErrorOptions { id: string; source: string; config: AstroConfig; - logger: Logger; + logger: AstroLogger; } export async function compileAstro({ diff --git a/packages/astro/src/vite-plugin-astro/hmr.ts b/packages/astro/src/vite-plugin-astro/hmr.ts index 3af57edc920e..52553c998cbe 100644 --- a/packages/astro/src/vite-plugin-astro/hmr.ts +++ b/packages/astro/src/vite-plugin-astro/hmr.ts @@ -1,12 +1,12 @@ import type { HmrContext } from 'vite'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import type { CompileAstroResult } from './compile.js'; import { parseAstroRequest } from './query.js'; import type { CompileMetadata } from './types.js'; import { frontmatterRE } from './utils.js'; interface HandleHotUpdateOptions { - logger: Logger; + logger: AstroLogger; compile: (code: string, filename: string) => Promise; astroFileToCompileMetadata: Map; } diff --git a/packages/astro/src/vite-plugin-astro/index.ts b/packages/astro/src/vite-plugin-astro/index.ts index 73692dd576a3..95635c8c444a 100644 --- a/packages/astro/src/vite-plugin-astro/index.ts +++ b/packages/astro/src/vite-plugin-astro/index.ts @@ -3,7 +3,7 @@ import type { SourceDescription } from 'rollup'; import type * as vite from 'vite'; import { defaultClientConditions, defaultServerConditions, normalizePath } from 'vite'; import { ASTRO_VITE_ENVIRONMENT_NAMES } from '../core/constants.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { isAstroServerEnvironment } from '../environments.js'; import type { AstroSettings } from '../types/astro.js'; import type { AstroConfig } from '../types/public/config.js'; @@ -20,7 +20,7 @@ export type { AstroPluginMetadata }; interface AstroPluginOptions { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; } const astroFileToCompileMetadataWeakMap = new WeakMap>(); diff --git a/packages/astro/src/vite-plugin-integrations-container/index.ts b/packages/astro/src/vite-plugin-integrations-container/index.ts index 263cef22c1aa..f984dcd9aa7f 100644 --- a/packages/astro/src/vite-plugin-integrations-container/index.ts +++ b/packages/astro/src/vite-plugin-integrations-container/index.ts @@ -1,7 +1,7 @@ import type { PluginContext } from 'rollup'; import type { Plugin as VitePlugin } from 'vite'; import { normalizePath } from 'vite'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { runHookServerSetup } from '../integrations/hooks.js'; import type { AstroSettings } from '../types/astro.js'; import type { InternalInjectedRoute, ResolvedInjectedRoute } from '../types/public/internal.js'; @@ -12,7 +12,7 @@ export default function astroIntegrationsContainerPlugin({ logger, }: { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; }): VitePlugin { return { name: 'astro:integration-container', diff --git a/packages/astro/src/vite-plugin-markdown/index.ts b/packages/astro/src/vite-plugin-markdown/index.ts index a3710a36f5c2..6a939af8b192 100644 --- a/packages/astro/src/vite-plugin-markdown/index.ts +++ b/packages/astro/src/vite-plugin-markdown/index.ts @@ -8,7 +8,7 @@ import { import type { Plugin } from 'vite'; import { safeParseFrontmatter } from '../content/utils.js'; import { AstroError, AstroErrorData } from '../core/errors/index.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { isMarkdownFile, isPage } from '../core/util.js'; import { normalizePath } from '../core/viteUtils.js'; import { shorthash } from '../runtime/server/shorthash.js'; @@ -20,7 +20,7 @@ import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from '../core/constants.js'; interface AstroPluginOptions { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; } const astroServerRuntimeModulePath = normalizePath( diff --git a/packages/astro/src/vite-plugin-routes/index.ts b/packages/astro/src/vite-plugin-routes/index.ts index ca8c889470aa..5e1603c856c8 100644 --- a/packages/astro/src/vite-plugin-routes/index.ts +++ b/packages/astro/src/vite-plugin-routes/index.ts @@ -6,7 +6,7 @@ import { normalizePath, type Plugin, type ViteDevServer } from 'vite'; import { serializeRouteData } from '../core/app/entrypoints/index.js'; import type { SerializedRouteInfo } from '../core/app/types.js'; import { warnMissingAdapter } from '../core/dev/adapter-validation.js'; -import type { Logger } from '../core/logger/core.js'; +import type { AstroLogger } from '../core/logger/core.js'; import { createRoutesList } from '../core/routing/create-manifest.js'; import { getRoutePrerenderOption } from '../core/routing/prerender.js'; import { isEndpoint, isPage } from '../core/util.js'; @@ -21,7 +21,7 @@ import { PAGE_SCRIPT_ID } from '../vite-plugin-scripts/index.js'; type Payload = { settings: AstroSettings; - logger: Logger; + logger: AstroLogger; fsMod?: typeof fsMod; routesList: RoutesList; command: 'dev' | 'build'; diff --git a/packages/astro/test/units/logger/destination.test.ts b/packages/astro/test/units/logger/destination.test.ts new file mode 100644 index 000000000000..6fb3e33c9d63 --- /dev/null +++ b/packages/astro/test/units/logger/destination.test.ts @@ -0,0 +1,127 @@ +import * as assert from 'node:assert/strict'; +import { beforeEach, describe, it } from 'node:test'; +import type { AstroLogMessage, LogWritable } from '../../../src/core/logger/core.js'; +import { Logger } from '../../../dist/core/logger/core.js'; + +let logs: AstroLogMessage[] = []; + +const testDestination: LogWritable = { + write(event: AstroLogMessage) { + logs.push(event); + return true; + }, +}; + +describe('log destination', () => { + beforeEach(() => { + logs = []; + }); + + describe('event shape', () => { + const logger = new Logger({ + destination: testDestination, + level: 'info', + format: 'default', + }); + + it('info() pushes an event with level info', () => { + logger.info('build', 'server started'); + assert.equal(logs.length, 1); + assert.equal(logs[0].level, 'info'); + assert.equal(logs[0].label, 'build'); + assert.equal(logs[0].message, 'server started'); + assert.equal(logs[0].newLine, true); + }); + + it('warn() pushes an event with level warn', () => { + logger.warn('build', 'deprecation notice'); + assert.equal(logs.length, 1); + assert.equal(logs[0].level, 'warn'); + assert.equal(logs[0].label, 'build'); + assert.equal(logs[0].message, 'deprecation notice'); + }); + + it('error() pushes an event with level error', () => { + logger.error('build', 'build failed'); + assert.equal(logs.length, 1); + assert.equal(logs[0].level, 'error'); + assert.equal(logs[0].message, 'build failed'); + }); + + it('supports null label', () => { + logger.info(null, 'no label'); + assert.equal(logs[0].label, null); + }); + + it('respects newLine parameter', () => { + logger.info('build', 'no trailing newline', false); + assert.equal(logs[0].newLine, false); + }); + }); + + describe('format propagation', () => { + it('propagates default format to events', () => { + const logger = new Logger({ + destination: testDestination, + level: 'info', + format: 'default', + }); + logger.info('build', 'test'); + assert.equal(logs[0].format, 'default'); + }); + + it('propagates json format to events', () => { + const logger = new Logger({ + destination: testDestination, + level: 'info', + format: 'json', + }); + logger.info('build', 'test'); + assert.equal(logs[0].format, 'json'); + }); + }); + + describe('level filtering', () => { + it('filters out info when level is warn', () => { + const logger = new Logger({ + destination: testDestination, + level: 'warn', + format: 'default', + }); + logger.info('build', 'should be filtered'); + assert.equal(logs.length, 0); + }); + + it('allows warn when level is warn', () => { + const logger = new Logger({ + destination: testDestination, + level: 'warn', + format: 'default', + }); + logger.warn('build', 'should pass'); + assert.equal(logs.length, 1); + }); + + it('allows error when level is warn', () => { + const logger = new Logger({ + destination: testDestination, + level: 'warn', + format: 'default', + }); + logger.error('build', 'should pass'); + assert.equal(logs.length, 1); + }); + + it('filters everything when level is silent', () => { + const logger = new Logger({ + destination: testDestination, + level: 'silent', + format: 'default', + }); + logger.info('build', 'nope'); + logger.warn('build', 'nope'); + logger.error('build', 'nope'); + assert.equal(logs.length, 0); + }); + }); +}); diff --git a/packages/astro/test/units/routing/manifest.test.js b/packages/astro/test/units/routing/manifest.test.js index e1a7514a9a0b..a1d5cda5f11e 100644 --- a/packages/astro/test/units/routing/manifest.test.js +++ b/packages/astro/test/units/routing/manifest.test.js @@ -364,6 +364,7 @@ describe('routing - createRoutesList', () => { assert.deepEqual(logs, [ { + format: 'default', label: 'router', level: 'warn', message: @@ -371,6 +372,7 @@ describe('routing - createRoutesList', () => { newLine: true, }, { + format: 'default', label: 'router', level: 'warn', message: 'A collision will result in a hard error in following versions of Astro.', @@ -403,6 +405,7 @@ describe('routing - createRoutesList', () => { assert.deepEqual(logs, [ { + format: 'default', label: 'router', level: 'warn', message: @@ -410,6 +413,7 @@ describe('routing - createRoutesList', () => { newLine: true, }, { + format: 'default', label: 'router', level: 'warn', message: 'A collision will result in a hard error in following versions of Astro.', From a9e17d7168c78d8cf071754e70437c794ae933eb Mon Sep 17 00:00:00 2001 From: ematipico Date: Thu, 9 Apr 2026 11:01:43 +0100 Subject: [PATCH 2/7] chore: hide format --- packages/astro/src/cli/flags.ts | 1 - packages/astro/src/container/index.ts | 1 - packages/astro/src/core/app/base.ts | 1 - packages/astro/src/core/app/logging.ts | 1 - packages/astro/src/core/logger/console.ts | 4 +- packages/astro/src/core/logger/core.ts | 23 +++++-- packages/astro/src/core/logger/node.ts | 9 +-- packages/astro/src/core/logger/public.ts | 10 --- .../vite-plugin-app/createAstroServerApp.ts | 1 - .../test/units/logger/destination.test.ts | 69 +++++++++++++++---- 10 files changed, 80 insertions(+), 40 deletions(-) delete mode 100644 packages/astro/src/core/logger/public.ts diff --git a/packages/astro/src/cli/flags.ts b/packages/astro/src/cli/flags.ts index 4941ad6075c5..37689c0e0e0a 100644 --- a/packages/astro/src/cli/flags.ts +++ b/packages/astro/src/cli/flags.ts @@ -44,7 +44,6 @@ export function createLoggerFromFlags(flags: Flags): AstroLogger { const logging: LogOptions = { destination: nodeLogDestination, level: 'info', - format: 'default', }; if (flags.verbose) { diff --git a/packages/astro/src/container/index.ts b/packages/astro/src/container/index.ts index c1dafb265ac8..caed810a1876 100644 --- a/packages/astro/src/container/index.ts +++ b/packages/astro/src/container/index.ts @@ -304,7 +304,6 @@ export class experimental_AstroContainer { logger: new AstroLogger({ level: 'info', destination: nodeLogDestination, - format: 'default', }), manifest: createManifest(manifest, renderers), streaming, diff --git a/packages/astro/src/core/app/base.ts b/packages/astro/src/core/app/base.ts index 35f3435e1b31..7101a4fe1f50 100644 --- a/packages/astro/src/core/app/base.ts +++ b/packages/astro/src/core/app/base.ts @@ -141,7 +141,6 @@ export abstract class BaseApp

{ this.logger = new AstroLogger({ destination: consoleLogDestination, level: manifest.logLevel, - format: 'default', }); this.adapterLogger = new AstroIntegrationLogger(this.logger.options, manifest.adapterName); // This is necessary to allow running middlewares for 404 in SSR. There's special handling diff --git a/packages/astro/src/core/app/logging.ts b/packages/astro/src/core/app/logging.ts index b61378b29b20..36b229a042d5 100644 --- a/packages/astro/src/core/app/logging.ts +++ b/packages/astro/src/core/app/logging.ts @@ -6,6 +6,5 @@ export function createConsoleLogger(level: AstroInlineConfig['logLevel']): Astro return new AstroLogger({ destination: consoleLogDestination, level: level ?? 'info', - format: 'default', }); } diff --git a/packages/astro/src/core/logger/console.ts b/packages/astro/src/core/logger/console.ts index b59b52484a21..b34e1fb106c1 100644 --- a/packages/astro/src/core/logger/console.ts +++ b/packages/astro/src/core/logger/console.ts @@ -1,6 +1,6 @@ -import { getEventPrefix, type AstroLogMessage, type LogWritable, levels } from './core.js'; +import { getEventPrefix, type AstroLogMessage, type LoggerDestination, levels } from './core.js'; -export const consoleLogDestination: LogWritable = { +export const consoleLogDestination: LoggerDestination = { write(event: AstroLogMessage) { let dest = console.error; if (levels[event.level] < levels['error']) { diff --git a/packages/astro/src/core/logger/core.ts b/packages/astro/src/core/logger/core.ts index f63890dd231f..3c44d351673b 100644 --- a/packages/astro/src/core/logger/core.ts +++ b/packages/astro/src/core/logger/core.ts @@ -1,6 +1,6 @@ import colors from 'piccolore'; -export interface LogWritable { +export interface LoggerDestination { write: (chunk: T) => boolean; } @@ -60,9 +60,14 @@ type LoggerLabel = | 'SKIP_FORMAT'; export interface LogOptions { - destination: LogWritable; + destination: LoggerDestination; level: AstroLoggerLevel; - format: AstroLoggerFormat; + // Intentionally optional so we don't leak to public code. It will be public and non-optional + // once we expose to users + /** + * @internal + */ + _format?: AstroLoggerFormat; } // Hey, locales are pretty complicated! Be careful modifying this logic... @@ -101,7 +106,11 @@ export interface AstroLogMessage { */ newLine: boolean; - format: AstroLoggerFormat; + /** + * @internal + * How the log should be formatted when printed inside the destination + */ + _format?: AstroLoggerFormat; } export const levels: Record = { @@ -127,7 +136,7 @@ function log( level, message, newLine, - format: opts.format, + _format: opts._format, }; // test if this level is enabled or not @@ -203,8 +212,8 @@ export function timerMessage(message: string, startTime: number = Date.now()) { export class AstroLogger { options: LogOptions; constructor(options: LogOptions) { - if (!options.format) { - options.format = 'default'; + if (!options._format) { + options._format = 'default'; } this.options = options; } diff --git a/packages/astro/src/core/logger/node.ts b/packages/astro/src/core/logger/node.ts index afdafc579318..97b9c7b5cf2e 100644 --- a/packages/astro/src/core/logger/node.ts +++ b/packages/astro/src/core/logger/node.ts @@ -2,21 +2,23 @@ import type { Writable } from 'node:stream'; import { createDebug, enable as obugEnable } from 'obug'; import type { AstroInlineConfig } from '../../types/public/config.js'; import { AstroLogger } from './core.js'; -import { getEventPrefix, type AstroLogMessage, type LogWritable, levels } from './core.js'; +import { getEventPrefix, type AstroLogMessage, type LoggerDestination, levels } from './core.js'; type ConsoleStream = Writable & { fd: 1 | 2; }; -export const nodeLogDestination: LogWritable = { +export const nodeLogDestination: LoggerDestination = { write(event: AstroLogMessage) { let dest: ConsoleStream = process.stderr; if (levels[event.level] < levels['error']) { dest = process.stdout; } + let format = event._format ?? 'default'; + let trailingLine = event.newLine ? '\n' : ''; - switch (event.format) { + switch (format) { case 'json': { dest.write(JSON.stringify({ message: event.message, label: event.label }) + trailingLine); return true; @@ -67,6 +69,5 @@ export function createNodeLogger(inlineConfig: AstroInlineConfig): AstroLogger { return new AstroLogger({ destination: nodeLogDestination, level: inlineConfig.logLevel ?? 'info', - format: 'default', }); } diff --git a/packages/astro/src/core/logger/public.ts b/packages/astro/src/core/logger/public.ts deleted file mode 100644 index 000afa583f49..000000000000 --- a/packages/astro/src/core/logger/public.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { AstroLoggerDestination } from '../../types/public/logger.js'; -import type { AstroLogger } from './core.js'; - -export function defineDestination(fn: AstroLoggerDestination) { - return fn; -} - -export function defineAstroLogger(fn: AstroLogger) { - return fn; -} diff --git a/packages/astro/src/vite-plugin-app/createAstroServerApp.ts b/packages/astro/src/vite-plugin-app/createAstroServerApp.ts index c6abffe9b37f..47811591cc15 100644 --- a/packages/astro/src/vite-plugin-app/createAstroServerApp.ts +++ b/packages/astro/src/vite-plugin-app/createAstroServerApp.ts @@ -29,7 +29,6 @@ export default async function createAstroServerApp( new AstroLogger({ destination: nodeLogDestination, level: settings.logLevel, - format: 'default', }); const routesList: RoutesList = { routes: routes.map((r: RouteInfo) => r.routeData) }; diff --git a/packages/astro/test/units/logger/destination.test.ts b/packages/astro/test/units/logger/destination.test.ts index 6fb3e33c9d63..71585fbc464f 100644 --- a/packages/astro/test/units/logger/destination.test.ts +++ b/packages/astro/test/units/logger/destination.test.ts @@ -1,24 +1,35 @@ import * as assert from 'node:assert/strict'; import { beforeEach, describe, it } from 'node:test'; -import type { AstroLogMessage, LogWritable } from '../../../src/core/logger/core.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import type { AstroLogMessage, LoggerDestination } from '../../../src/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; let logs: AstroLogMessage[] = []; +let jsonLogs: string[] = []; -const testDestination: LogWritable = { +const testDestination: LoggerDestination = { write(event: AstroLogMessage) { logs.push(event); return true; }, }; +const jsonDestination: LoggerDestination = { + write(event: AstroLogMessage) { + if (event._format === 'json') { + jsonLogs.push(JSON.stringify({ message: event.message, label: event.label })); + } + return true; + }, +}; + describe('log destination', () => { beforeEach(() => { logs = []; + jsonLogs = []; }); describe('event shape', () => { - const logger = new Logger({ + const logger = new AstroLogger({ destination: testDestination, level: 'info', format: 'default', @@ -61,29 +72,63 @@ describe('log destination', () => { describe('format propagation', () => { it('propagates default format to events', () => { - const logger = new Logger({ + const logger = new AstroLogger({ destination: testDestination, level: 'info', format: 'default', }); logger.info('build', 'test'); - assert.equal(logs[0].format, 'default'); + assert.equal(logs[0]._format, 'default'); }); it('propagates json format to events', () => { - const logger = new Logger({ + const logger = new AstroLogger({ destination: testDestination, level: 'info', format: 'json', }); logger.info('build', 'test'); - assert.equal(logs[0].format, 'json'); + assert.equal(logs[0]._format, 'json'); + }); + }); + + describe('json formatting', () => { + const logger = new AstroLogger({ + destination: jsonDestination, + level: 'info', + format: 'json', + }); + + it('serializes message and label as JSON', () => { + logger.info('build', 'compiled successfully'); + assert.equal(jsonLogs.length, 1); + assert.equal(jsonLogs[0], '{"message":"compiled successfully","label":"build"}'); + }); + + it('serializes null label', () => { + logger.info(null, 'no label message'); + assert.equal(jsonLogs[0], '{"message":"no label message","label":null}'); + }); + + it('only includes message and label', () => { + logger.warn('build', 'a warning'); + assert.equal(jsonLogs[0], '{"message":"a warning","label":"build"}'); + }); + + it('does not write when format is not json', () => { + const defaultLogger = new AstroLogger({ + destination: jsonDestination, + level: 'info', + format: 'default', + }); + defaultLogger.info('build', 'should not appear'); + assert.equal(jsonLogs.length, 0); }); }); describe('level filtering', () => { it('filters out info when level is warn', () => { - const logger = new Logger({ + const logger = new AstroLogger({ destination: testDestination, level: 'warn', format: 'default', @@ -93,7 +138,7 @@ describe('log destination', () => { }); it('allows warn when level is warn', () => { - const logger = new Logger({ + const logger = new AstroLogger({ destination: testDestination, level: 'warn', format: 'default', @@ -103,7 +148,7 @@ describe('log destination', () => { }); it('allows error when level is warn', () => { - const logger = new Logger({ + const logger = new AstroLogger({ destination: testDestination, level: 'warn', format: 'default', @@ -113,7 +158,7 @@ describe('log destination', () => { }); it('filters everything when level is silent', () => { - const logger = new Logger({ + const logger = new AstroLogger({ destination: testDestination, level: 'silent', format: 'default', From eda0b44b7e8db47daae5deab754e6f434c84217e Mon Sep 17 00:00:00 2001 From: ematipico Date: Thu, 9 Apr 2026 11:02:33 +0100 Subject: [PATCH 3/7] better naming convention --- packages/astro/package.json | 1 - packages/astro/src/cli/flags.ts | 4 +-- packages/astro/src/core/logger/console.ts | 9 ++++-- packages/astro/src/core/logger/core.ts | 32 +++++++++---------- packages/astro/src/core/logger/node.ts | 9 ++++-- .../test/units/logger/destination.test.ts | 6 ++-- 6 files changed, 35 insertions(+), 26 deletions(-) diff --git a/packages/astro/package.json b/packages/astro/package.json index daeffb1266d6..7c7c9bf16b53 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -81,7 +81,6 @@ "./zod": "./dist/zod.js", "./errors": "./dist/core/errors/userError.js", "./middleware": "./dist/core/middleware/index.js", - "./logger": "./disto/core/logger/public.js", "./virtual-modules/*": "./dist/virtual-modules/*" }, "bin": { diff --git a/packages/astro/src/cli/flags.ts b/packages/astro/src/cli/flags.ts index 37689c0e0e0a..ba91134961e7 100644 --- a/packages/astro/src/cli/flags.ts +++ b/packages/astro/src/cli/flags.ts @@ -1,5 +1,5 @@ import type { Arguments } from 'yargs-parser'; -import type { AstroLogger, LogOptions } from '../core/logger/core.js'; +import type { AstroLogger, AstroLogOptions } from '../core/logger/core.js'; import { createNodeLogger, nodeLogDestination } from '../core/logger/node.js'; import type { AstroInlineConfig } from '../types/public/config.js'; @@ -41,7 +41,7 @@ export function flagsToAstroInlineConfig(flags: Flags): AstroInlineConfig { * doesn't read the AstroConfig directly, so we create a `logging` object from the CLI flags instead. */ export function createLoggerFromFlags(flags: Flags): AstroLogger { - const logging: LogOptions = { + const logging: AstroLogOptions = { destination: nodeLogDestination, level: 'info', }; diff --git a/packages/astro/src/core/logger/console.ts b/packages/astro/src/core/logger/console.ts index b34e1fb106c1..a20e108f9704 100644 --- a/packages/astro/src/core/logger/console.ts +++ b/packages/astro/src/core/logger/console.ts @@ -1,6 +1,11 @@ -import { getEventPrefix, type AstroLogMessage, type LoggerDestination, levels } from './core.js'; +import { + getEventPrefix, + type AstroLogMessage, + type AstroLoggerDestination, + levels, +} from './core.js'; -export const consoleLogDestination: LoggerDestination = { +export const consoleLogDestination: AstroLoggerDestination = { write(event: AstroLogMessage) { let dest = console.error; if (levels[event.level] < levels['error']) { diff --git a/packages/astro/src/core/logger/core.ts b/packages/astro/src/core/logger/core.ts index 3c44d351673b..e011c965e19e 100644 --- a/packages/astro/src/core/logger/core.ts +++ b/packages/astro/src/core/logger/core.ts @@ -1,6 +1,6 @@ import colors from 'piccolore'; -export interface LoggerDestination { +export interface AstroLoggerDestination { write: (chunk: T) => boolean; } @@ -29,7 +29,7 @@ export type AstroLoggerLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'; / * rather than specific to a single command, function, use, etc. The label will be * shown in the log message to the user, so it should be relevant. */ -type LoggerLabel = +type AstroLoggerLabel = | 'add' | 'build' | 'check' @@ -59,8 +59,8 @@ type LoggerLabel = // Useful for messages that are already formatted, like the server start message. | 'SKIP_FORMAT'; -export interface LogOptions { - destination: LoggerDestination; +export interface AstroLogOptions { + destination: AstroLoggerDestination; level: AstroLoggerLevel; // Intentionally optional so we don't leak to public code. It will be public and non-optional // once we expose to users @@ -123,7 +123,7 @@ export const levels: Record = { /** Full logging API */ function log( - opts: LogOptions, + opts: AstroLogOptions, level: AstroLoggerLevel, label: string | null, message: string, @@ -152,17 +152,17 @@ export function isLogLevelEnabled(configuredLogLevel: AstroLoggerLevel, level: A } /** Emit a user-facing message. Useful for UI and other console messages. */ -function info(opts: LogOptions, label: string | null, message: string, newLine = true) { +function info(opts: AstroLogOptions, label: string | null, message: string, newLine = true) { return log(opts, 'info', label, message, newLine); } /** Emit a warning message. Useful for high-priority messages that aren't necessarily errors. */ -function warn(opts: LogOptions, label: string | null, message: string, newLine = true) { +function warn(opts: AstroLogOptions, label: string | null, message: string, newLine = true) { return log(opts, 'warn', label, message, newLine); } /** Emit an error message, Useful when Astro can't recover from some error. */ -function error(opts: LogOptions, label: string | null, message: string, newLine = true) { +function error(opts: AstroLogOptions, label: string | null, message: string, newLine = true) { return log(opts, 'error', label, message, newLine); } @@ -210,24 +210,24 @@ export function timerMessage(message: string, startTime: number = Date.now()) { } export class AstroLogger { - options: LogOptions; - constructor(options: LogOptions) { + options: AstroLogOptions; + constructor(options: AstroLogOptions) { if (!options._format) { options._format = 'default'; } this.options = options; } - info(label: LoggerLabel | null, message: string, newLine = true) { + info(label: AstroLoggerLabel | null, message: string, newLine = true) { info(this.options, label, message, newLine); } - warn(label: LoggerLabel | null, message: string, newLine = true) { + warn(label: AstroLoggerLabel | null, message: string, newLine = true) { warn(this.options, label, message, newLine); } - error(label: LoggerLabel | null, message: string, newLine = true) { + error(label: AstroLoggerLabel | null, message: string, newLine = true) { error(this.options, label, message, newLine); } - debug(label: LoggerLabel, ...messages: any[]) { + debug(label: AstroLoggerLabel, ...messages: any[]) { debug(label, ...messages); } @@ -241,10 +241,10 @@ export class AstroLogger { } export class AstroIntegrationLogger { - options: LogOptions; + options: AstroLogOptions; label: string; - constructor(logging: LogOptions, label: string) { + constructor(logging: AstroLogOptions, label: string) { this.options = logging; this.label = label; } diff --git a/packages/astro/src/core/logger/node.ts b/packages/astro/src/core/logger/node.ts index 97b9c7b5cf2e..abd75da80fca 100644 --- a/packages/astro/src/core/logger/node.ts +++ b/packages/astro/src/core/logger/node.ts @@ -2,13 +2,18 @@ import type { Writable } from 'node:stream'; import { createDebug, enable as obugEnable } from 'obug'; import type { AstroInlineConfig } from '../../types/public/config.js'; import { AstroLogger } from './core.js'; -import { getEventPrefix, type AstroLogMessage, type LoggerDestination, levels } from './core.js'; +import { + getEventPrefix, + type AstroLogMessage, + type AstroLoggerDestination, + levels, +} from './core.js'; type ConsoleStream = Writable & { fd: 1 | 2; }; -export const nodeLogDestination: LoggerDestination = { +export const nodeLogDestination: AstroLoggerDestination = { write(event: AstroLogMessage) { let dest: ConsoleStream = process.stderr; if (levels[event.level] < levels['error']) { diff --git a/packages/astro/test/units/logger/destination.test.ts b/packages/astro/test/units/logger/destination.test.ts index 71585fbc464f..3281acd24515 100644 --- a/packages/astro/test/units/logger/destination.test.ts +++ b/packages/astro/test/units/logger/destination.test.ts @@ -1,19 +1,19 @@ import * as assert from 'node:assert/strict'; import { beforeEach, describe, it } from 'node:test'; -import type { AstroLogMessage, LoggerDestination } from '../../../src/core/logger/core.js'; +import type { AstroLogMessage, AstroLoggerDestination } from '../../../src/core/logger/core.js'; import { AstroLogger } from '../../../dist/core/logger/core.js'; let logs: AstroLogMessage[] = []; let jsonLogs: string[] = []; -const testDestination: LoggerDestination = { +const testDestination: AstroLoggerDestination = { write(event: AstroLogMessage) { logs.push(event); return true; }, }; -const jsonDestination: LoggerDestination = { +const jsonDestination: AstroLoggerDestination = { write(event: AstroLogMessage) { if (event._format === 'json') { jsonLogs.push(JSON.stringify({ message: event.message, label: event.label })); From c1a6cd493c0be286b53b167be67c6a0d5fecef50 Mon Sep 17 00:00:00 2001 From: ematipico Date: Thu, 9 Apr 2026 11:49:17 +0100 Subject: [PATCH 4/7] update types --- packages/astro/test/astro-public.test.js | 6 +-- packages/astro/test/astro-sync.test.js | 8 ++-- packages/astro/test/cli.test.js | 2 +- .../astro/test/core-image-infersize.test.js | 6 +-- packages/astro/test/core-image-layout.test.js | 6 +-- .../test/core-image-remark-imgattr.test.js | 6 +-- packages/astro/test/core-image-svg.test.js | 6 +-- packages/astro/test/core-image.test.js | 20 +++++---- packages/astro/test/live-loaders.test.js | 6 +-- .../astro/test/prerender-conflict.test.js | 10 ++--- packages/astro/test/react-jsx-export.test.js | 10 +++-- packages/astro/test/static-build.test.js | 12 +++--- .../astro/test/units/assets/fonts/e2e.test.js | 6 +-- packages/astro/test/units/cli/utils.ts | 6 +-- .../test/units/compile/css-base-path.test.ts | 4 +- .../units/content-layer/core-loader.test.ts | 6 +-- .../content-layer/data-transforms.test.ts | 34 +++++++-------- .../units/content-layer/file-loader.test.ts | 30 ++++++------- .../units/content-layer/glob-loader.test.ts | 34 +++++++-------- .../units/content-layer/live-loaders.test.ts | 30 ++++++------- .../content-layer/loader-warnings.test.ts | 26 ++++++------ .../content-layer/markdown-rendering.test.ts | 42 +++++++++---------- .../content-layer/schema-validation.test.ts | 30 ++++++------- .../test/units/logger/destination.test.ts | 18 ++++---- .../routing/getstaticpaths-cache.test.ts | 6 +-- .../astro/test/units/routing/manifest.test.js | 6 +-- .../units/routing/params-validation.test.ts | 8 ++-- packages/astro/test/units/test-utils.js | 16 +++---- .../cloudflare/test/ssr-deps.test.js | 6 +-- .../cloudflare/test/top-level-return.test.js | 6 +-- .../cloudflare/test/with-base.test.js | 6 +-- .../cloudflare/test/with-react.test.js | 6 +-- 32 files changed, 214 insertions(+), 210 deletions(-) diff --git a/packages/astro/test/astro-public.test.js b/packages/astro/test/astro-public.test.js index 80837df7ba7b..e2c4150a423c 100644 --- a/packages/astro/test/astro-public.test.js +++ b/packages/astro/test/astro-public.test.js @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { loadFixture } from './test-utils.js'; describe('Public', () => { @@ -14,9 +14,9 @@ describe('Public', () => { vite: { logLevel: 'info', }, - logger: new Logger({ + logger: new AstroLogger({ level: 'info', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { buildLogs.push(event); diff --git a/packages/astro/test/astro-sync.test.js b/packages/astro/test/astro-sync.test.js index 162a3ba612cd..eaf1f75bbc46 100644 --- a/packages/astro/test/astro-sync.test.js +++ b/packages/astro/test/astro-sync.test.js @@ -4,7 +4,7 @@ import * as fs from 'node:fs'; import { beforeEach, describe, it } from 'node:test'; import { fileURLToPath } from 'node:url'; import ts from 'typescript'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { loadFixture } from './test-utils.js'; const createFixture = () => { @@ -270,12 +270,12 @@ describe('astro sync', () => { describe('No content config', () => { it('Syncs silently without error when content config does not exist', async () => { /** - * @type {import("../dist/core/logger/core.js").LogMessage[]} + * @type {import("../dist/core/logger/core.js").AstroLogMessage[]} */ const logs = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'debug', - dest: { + destination: { write(chunk) { logs.push(chunk); return true; diff --git a/packages/astro/test/cli.test.js b/packages/astro/test/cli.test.js index ed3765558da6..b0992657d008 100644 --- a/packages/astro/test/cli.test.js +++ b/packages/astro/test/cli.test.js @@ -33,7 +33,7 @@ describe('astro cli', () => { flags: { watch: true }, logging: { level: 'info', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push({ ...event, message: stripVTControlCharacters(event.message) }); diff --git a/packages/astro/test/core-image-infersize.test.js b/packages/astro/test/core-image-infersize.test.js index a64508dda5e2..474b8d4dc925 100644 --- a/packages/astro/test/core-image-infersize.test.js +++ b/packages/astro/test/core-image-infersize.test.js @@ -3,7 +3,7 @@ import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { testImageService } from './test-image-service.js'; import { loadFixture } from './test-utils.js'; @@ -24,9 +24,9 @@ describe('astro:image:infersize', () => { }); devServer = await fixture.startDevServer({ - logger: new Logger({ + logger: new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); diff --git a/packages/astro/test/core-image-layout.test.js b/packages/astro/test/core-image-layout.test.js index 86bef7439c9d..f24e0eb07b7a 100755 --- a/packages/astro/test/core-image-layout.test.js +++ b/packages/astro/test/core-image-layout.test.js @@ -3,7 +3,7 @@ import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; import parseSrcset from 'parse-srcset'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { testImageService } from './test-image-service.js'; import { testRemoteImageService } from './test-remote-image-service.js'; import { loadFixture } from './test-utils.js'; @@ -354,9 +354,9 @@ describe('astro:image:layout', () => { }); devServer = await fixture.startDevServer({ - logger: new Logger({ + logger: new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); diff --git a/packages/astro/test/core-image-remark-imgattr.test.js b/packages/astro/test/core-image-remark-imgattr.test.js index f62123942189..792507226403 100644 --- a/packages/astro/test/core-image-remark-imgattr.test.js +++ b/packages/astro/test/core-image-remark-imgattr.test.js @@ -3,7 +3,7 @@ import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { loadFixture } from './test-utils.js'; describe('astro:image', () => { @@ -22,9 +22,9 @@ describe('astro:image', () => { }); devServer = await fixture.startDevServer({ - logger: new Logger({ + logger: new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); diff --git a/packages/astro/test/core-image-svg.test.js b/packages/astro/test/core-image-svg.test.js index bbaede3a6ad3..b7cad2f1a4a8 100644 --- a/packages/astro/test/core-image-svg.test.js +++ b/packages/astro/test/core-image-svg.test.js @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { loadFixture } from './test-utils.js'; describe('astro:assets - SVG Components', () => { @@ -21,9 +21,9 @@ describe('astro:assets - SVG Components', () => { }); devServer = await fixture.startDevServer({ - logger: new Logger({ + logger: new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js index 01aa68b9434b..49a252d78b44 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.test.js @@ -6,7 +6,7 @@ import { after, afterEach, before, describe, it } from 'node:test'; import { removeDir } from '@astrojs/internal-helpers/fs'; import * as cheerio from 'cheerio'; import parseSrcset from 'parse-srcset'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import testAdapter from './test-adapter.js'; import { testImageService } from './test-image-service.js'; import { loadFixture } from './test-utils.js'; @@ -67,9 +67,9 @@ describe('astro:image', () => { }); devServer = await fixture.startDevServer({ - logger: new Logger({ + logger: new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); @@ -799,9 +799,9 @@ describe('astro:image', () => { }); devServer = await fixture.startDevServer({ - logger: new Logger({ + logger: new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); @@ -1155,15 +1155,17 @@ describe('astro:image', () => { it('uses cache entries', async () => { const logs = []; - const logging = { - dest: { + const logger = new AstroLogger({ + destination: { write(chunk) { logs.push(chunk); + return true; }, }, - }; + level: 'info', + }); - await fixture.build({ logging }); + await fixture.build({ logger }); const generatingImageIndex = logs.findIndex((logLine) => logLine.message.includes('generating optimized images'), ); diff --git a/packages/astro/test/live-loaders.test.js b/packages/astro/test/live-loaders.test.js index 4e217117ba6e..0659c17e7e0e 100644 --- a/packages/astro/test/live-loaders.test.js +++ b/packages/astro/test/live-loaders.test.js @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import testAdapter from './test-adapter.js'; import { loadFixture } from './test-utils.js'; @@ -20,9 +20,9 @@ describe('Live content collections', () => { const logs = []; before(async () => { devServer = await fixture.startDevServer({ - logger: new Logger({ + logger: new AstroLogger({ level: 'info', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); diff --git a/packages/astro/test/prerender-conflict.test.js b/packages/astro/test/prerender-conflict.test.js index 0199f0d0f821..57bf223d60bf 100644 --- a/packages/astro/test/prerender-conflict.test.js +++ b/packages/astro/test/prerender-conflict.test.js @@ -1,6 +1,6 @@ import { strict as assert } from 'node:assert'; import { before, describe, it } from 'node:test'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { loadFixture } from './test-utils.js'; /** @@ -20,9 +20,9 @@ describe('Prerender conflicts', () => { it('warns by default and succeeds', async () => { const logs = []; await fixture.build({ - logger: new Logger({ + logger: new AstroLogger({ level: 'warn', - dest: { + destination: { write(chunk) { logs.push(chunk); }, @@ -68,9 +68,9 @@ describe('Prerender conflicts', () => { it('warns by default and succeeds', async () => { const logs = []; await fixture.build({ - logger: new Logger({ + logger: new AstroLogger({ level: 'warn', - dest: { + destination: { write(chunk) { logs.push(chunk); }, diff --git a/packages/astro/test/react-jsx-export.test.js b/packages/astro/test/react-jsx-export.test.js index 66bc073cca9b..51b17e72454a 100644 --- a/packages/astro/test/react-jsx-export.test.js +++ b/packages/astro/test/react-jsx-export.test.js @@ -1,6 +1,7 @@ import assert from 'node:assert/strict'; import { before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { loadFixture } from './test-utils.js'; describe('react-jsx-export', () => { @@ -25,18 +26,19 @@ describe('react-jsx-export', () => { const reactInvalidHookWarning = 'Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons'; before(async () => { - const logging = { - dest: { + const logger = new AstroLogger({ + destination: { write(chunk) { logs.push(chunk); + return true; }, }, level: 'warn', - }; + }); fixture = await loadFixture({ root: './fixtures/react-jsx-export/', }); - await fixture.build({ logging }); + await fixture.build({ logger }); }); it('Can load all JSX components', async () => { diff --git a/packages/astro/test/static-build.test.js b/packages/astro/test/static-build.test.js index e94c0af65bee..370dcd6449ee 100644 --- a/packages/astro/test/static-build.test.js +++ b/packages/astro/test/static-build.test.js @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { before, describe, it } from 'node:test'; import { load as cheerioLoad } from 'cheerio'; -import { Logger } from '../dist/core/logger/core.js'; +import { AstroLogger } from '../dist/core/logger/core.js'; import { loadFixture } from './test-utils.js'; function addLeadingSlash(path) { @@ -14,19 +14,19 @@ function removeBasePath(path) { } /** - * @typedef {import('../src/core/logger/core').LogMessage} LogMessage + * @typedef {import('../src/core/logger/core').AstroLogMessage} AstroLogMessage */ describe('Static build', () => { /** @type {import('./test-utils').Fixture} */ let fixture; - /** @type {LogMessage[]} */ + /** @type {AstroLogMessage[]} */ let logs = []; before(async () => { - /** @type {import('../src/core/logger/core').Logger} */ - const logger = new Logger({ - dest: { + /** @type {import('../src/core/logger/core').AstroLogger} */ + const logger = new AstroLogger({ + destination: { write(chunk) { logs.push(chunk); }, diff --git a/packages/astro/test/units/assets/fonts/e2e.test.js b/packages/astro/test/units/assets/fonts/e2e.test.js index 7b848f51955a..ed6a696e1173 100644 --- a/packages/astro/test/units/assets/fonts/e2e.test.js +++ b/packages/astro/test/units/assets/fonts/e2e.test.js @@ -27,7 +27,7 @@ import { UnifontFontResolver } from '../../../../dist/assets/fonts/infra/unifont import { UnstorageFsStorage } from '../../../../dist/assets/fonts/infra/unstorage-fs-storage.js'; import { XxhashHasher } from '../../../../dist/assets/fonts/infra/xxhash-hasher.js'; import { fontProviders } from '../../../../dist/assets/fonts/providers/index.js'; -import { Logger } from '../../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../../dist/core/logger/core.js'; import { nodeLogDestination } from '../../../../dist/core/logger/node.js'; /** @@ -38,9 +38,9 @@ async function run({ fonts: _fonts }) { const resolvedFamilies = _fonts.map((family) => resolveFamily({ family, hasher })); const defaults = DEFAULTS; const { bold } = colors; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'silent', - dest: nodeLogDestination, + destination: nodeLogDestination, }); const stringMatcher = new LevenshteinStringMatcher(); const base = new URL('./data/cache/', import.meta.url); diff --git a/packages/astro/test/units/cli/utils.ts b/packages/astro/test/units/cli/utils.ts index 8b1ec1b7ebe0..201d4a0301fb 100644 --- a/packages/astro/test/units/cli/utils.ts +++ b/packages/astro/test/units/cli/utils.ts @@ -1,5 +1,5 @@ import { AstroIntegrationLogger } from '../../../dist/core/logger/core.js'; -import type { LogOptions } from '../../../dist/core/logger/core.js'; +import type { AstroLogOptions } from '../../../dist/core/logger/core.js'; import type { CloudIde } from '../../../dist/cli/docs/domain/cloud-ide.js'; import type { CloudIdeProvider } from '../../../dist/cli/docs/definitions.js'; import type { AnyCommand } from '../../../dist/cli/domain/command.js'; @@ -207,8 +207,8 @@ export class SpyLogger { this.#logs.push({ type: 'warn', label, message }); } - options: LogOptions = { - dest: { write: () => true }, + options: AstroLogOptions = { + destination: { write: () => true }, level: 'silent', }; diff --git a/packages/astro/test/units/compile/css-base-path.test.ts b/packages/astro/test/units/compile/css-base-path.test.ts index 065f1f14364e..5cb41c56d66f 100644 --- a/packages/astro/test/units/compile/css-base-path.test.ts +++ b/packages/astro/test/units/compile/css-base-path.test.ts @@ -5,10 +5,10 @@ import { resolveConfig } from 'vite'; import { compileAstro } from '../../../dist/vite-plugin-astro/compile.js'; import type { AstroConfig } from '../../../dist/types/public/config.js'; import type { CompileProps } from '../../../dist/core/compile/compile.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { nodeLogDestination } from '../../../dist/core/logger/node.js'; -const logger = new Logger({ dest: nodeLogDestination, level: 'silent' }); +const logger = new AstroLogger({ destination: nodeLogDestination, level: 'silent' }); /** Compile Astro source with a given base path. */ async function compileWithBase(source: string, base = '/') { diff --git a/packages/astro/test/units/content-layer/core-loader.test.ts b/packages/astro/test/units/content-layer/core-loader.test.ts index bcda945ca703..2ec54e1c55fa 100644 --- a/packages/astro/test/units/content-layer/core-loader.test.ts +++ b/packages/astro/test/units/content-layer/core-loader.test.ts @@ -4,7 +4,7 @@ import { z } from 'zod'; import { defineCollection } from '../../../dist/content/config.js'; import { ContentLayer } from '../../../dist/content/content-layer.js'; import { MutableDataStore } from '../../../dist/content/mutable-data-store.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createTempDir, createTestConfigObserver, createMinimalSettings } from './test-helpers.ts'; @@ -13,8 +13,8 @@ describe('Core Content Layer loader', () => { const root = createTempDir(); before(() => { - logger = new Logger({ - dest: { write: () => true }, + logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); }); diff --git a/packages/astro/test/units/content-layer/data-transforms.test.ts b/packages/astro/test/units/content-layer/data-transforms.test.ts index c6a83e19c756..2b1e8392b51a 100644 --- a/packages/astro/test/units/content-layer/data-transforms.test.ts +++ b/packages/astro/test/units/content-layer/data-transforms.test.ts @@ -5,7 +5,7 @@ import { defineCollection } from '../../../dist/content/config.js'; import { createReference } from '../../../dist/content/runtime.js'; import { ContentLayer } from '../../../dist/content/content-layer.js'; import { MutableDataStore } from '../../../dist/content/mutable-data-store.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createTempDir, createTestConfigObserver, createMinimalSettings } from './test-helpers.ts'; describe('Content Layer - Data Transforms', () => { @@ -15,8 +15,8 @@ describe('Content Layer - Data Transforms', () => { it('transforms reference strings to reference objects', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -72,8 +72,8 @@ describe('Content Layer - Data Transforms', () => { it('transforms dates correctly', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -131,8 +131,8 @@ describe('Content Layer - Data Transforms', () => { it('applies schema defaults', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -189,8 +189,8 @@ describe('Content Layer - Data Transforms', () => { it('handles array of references', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -246,8 +246,8 @@ describe('Content Layer - Data Transforms', () => { it('validates and rejects invalid data', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -319,8 +319,8 @@ describe('Content Layer - Data Transforms', () => { it('handles nested schemas with mixed transforms', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -393,8 +393,8 @@ describe('Content Layer - Data Transforms', () => { it('handles optional fields correctly', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -451,8 +451,8 @@ describe('Content Layer - Data Transforms', () => { it('transforms reference with default value', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); diff --git a/packages/astro/test/units/content-layer/file-loader.test.ts b/packages/astro/test/units/content-layer/file-loader.test.ts index ac84dc376a0b..d1d13df21cfb 100644 --- a/packages/astro/test/units/content-layer/file-loader.test.ts +++ b/packages/astro/test/units/content-layer/file-loader.test.ts @@ -5,7 +5,7 @@ import { file } from '../../../dist/content/loaders/file.js'; import { defineCollection } from '../../../dist/content/config.js'; import { ContentLayer } from '../../../dist/content/content-layer.js'; import { MutableDataStore } from '../../../dist/content/mutable-data-store.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createTestConfigObserver, createMinimalSettings } from './test-helpers.ts'; describe('File Loader', () => { @@ -14,8 +14,8 @@ describe('File Loader', () => { it('loads entries from JSON file', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -57,8 +57,8 @@ describe('File Loader', () => { it('loads entries from YAML file', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -95,8 +95,8 @@ describe('File Loader', () => { it('loads entries from TOML file', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -127,8 +127,8 @@ describe('File Loader', () => { it('loads entries from CSV file with custom parser', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -173,8 +173,8 @@ describe('File Loader', () => { it('loads nested JSON with custom parser', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -214,8 +214,8 @@ describe('File Loader', () => { it('uses async parser', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -250,8 +250,8 @@ describe('File Loader', () => { // Create a custom logger to capture warnings const warnings: string[] = []; - const logger = new Logger({ - dest: { + const logger = new AstroLogger({ + destination: { write: (msg: any) => { if (msg.level === 'warn') { warnings.push(msg.message); diff --git a/packages/astro/test/units/content-layer/glob-loader.test.ts b/packages/astro/test/units/content-layer/glob-loader.test.ts index c360d9e2608f..a3114781c4a0 100644 --- a/packages/astro/test/units/content-layer/glob-loader.test.ts +++ b/packages/astro/test/units/content-layer/glob-loader.test.ts @@ -4,7 +4,7 @@ import { glob } from '../../../dist/content/loaders/glob.js'; import { defineCollection } from '../../../dist/content/config.js'; import { ContentLayer } from '../../../dist/content/content-layer.js'; import { MutableDataStore } from '../../../dist/content/mutable-data-store.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createTestConfigObserver, createMinimalSettings, @@ -19,8 +19,8 @@ describe('Glob Loader', () => { const settings = createMinimalSettings(root, { contentEntryTypes: [createMarkdownEntryType()], }); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -55,8 +55,8 @@ describe('Glob Loader', () => { const settings = createMinimalSettings(root, { contentEntryTypes: [createMarkdownEntryType()], }); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -91,8 +91,8 @@ describe('Glob Loader', () => { const settings = createMinimalSettings(root, { contentEntryTypes: [createMarkdownEntryType()], }); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -124,8 +124,8 @@ describe('Glob Loader', () => { const settings = createMinimalSettings(root, { contentEntryTypes: [createMarkdownEntryType()], }); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -183,8 +183,8 @@ describe('Glob Loader', () => { }, dataEntryTypes: [yamlEntryType], }); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -247,8 +247,8 @@ describe('Glob Loader', () => { }, dataEntryTypes: [tomlEntryType], }); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -282,8 +282,8 @@ describe('Glob Loader', () => { it('warns about missing directory', async () => { const store = new MutableDataStore(); const warnings: string[] = []; - const logger = new Logger({ - dest: { + const logger = new AstroLogger({ + destination: { write: (msg: any) => { if (msg.level === 'warn') { warnings.push(msg.message); @@ -317,8 +317,8 @@ describe('Glob Loader', () => { it('warns about no matching files', async () => { const store = new MutableDataStore(); const warnings: string[] = []; - const logger = new Logger({ - dest: { + const logger = new AstroLogger({ + destination: { write: (msg: any) => { if (msg.level === 'warn') { warnings.push(msg.message); diff --git a/packages/astro/test/units/content-layer/live-loaders.test.ts b/packages/astro/test/units/content-layer/live-loaders.test.ts index a6657ee1fed1..ca1c6498134c 100644 --- a/packages/astro/test/units/content-layer/live-loaders.test.ts +++ b/packages/astro/test/units/content-layer/live-loaders.test.ts @@ -4,7 +4,7 @@ import { z } from 'zod'; import { defineCollection } from '../../../dist/content/config.js'; import { ContentLayer } from '../../../dist/content/content-layer.js'; import { MutableDataStore } from '../../../dist/content/mutable-data-store.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createTempDir, createTestConfigObserver, createMinimalSettings } from './test-helpers.ts'; describe('Content Layer - Live Loaders', () => { @@ -13,8 +13,8 @@ describe('Content Layer - Live Loaders', () => { it('loads initial data through sync', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -101,8 +101,8 @@ describe('Content Layer - Live Loaders', () => { it('simulates live loader with loadEntry functionality', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -179,8 +179,8 @@ describe('Content Layer - Live Loaders', () => { it('demonstrates dynamic data transformation', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -255,8 +255,8 @@ describe('Content Layer - Live Loaders', () => { it('handles loader errors gracefully', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -333,8 +333,8 @@ describe('Content Layer - Live Loaders', () => { it('supports complex rendered content', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -434,8 +434,8 @@ describe('Content Layer - Live Loaders', () => { it('demonstrates cache metadata patterns', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -553,8 +553,8 @@ describe('Content Layer - Live Loaders', () => { it('validates schema during data loading', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); diff --git a/packages/astro/test/units/content-layer/loader-warnings.test.ts b/packages/astro/test/units/content-layer/loader-warnings.test.ts index bbc43f3f0e25..7be355b1269d 100644 --- a/packages/astro/test/units/content-layer/loader-warnings.test.ts +++ b/packages/astro/test/units/content-layer/loader-warnings.test.ts @@ -4,7 +4,7 @@ import { z } from 'zod'; import { defineCollection } from '../../../dist/content/config.js'; import { ContentLayer } from '../../../dist/content/content-layer.js'; import { MutableDataStore } from '../../../dist/content/mutable-data-store.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createTempDir, createTestConfigObserver, createMinimalSettings } from './test-helpers.ts'; import { Writable } from 'node:stream'; import fs from 'node:fs/promises'; @@ -15,9 +15,9 @@ describe('Content Layer - Loader Warnings', () => { const store = new MutableDataStore(); const logs: any[] = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'warn', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event: any, _: any, callback: any) { logs.push(event); @@ -106,9 +106,9 @@ describe('Content Layer - Loader Warnings', () => { const store = new MutableDataStore(); const logs: any[] = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'warn', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event: any, _: any, callback: any) { logs.push(event); @@ -184,9 +184,9 @@ describe('Content Layer - Loader Warnings', () => { const store = new MutableDataStore(); const logs: any[] = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event: any, _: any, callback: any) { logs.push(event); @@ -292,9 +292,9 @@ describe('Content Layer - Loader Warnings', () => { const store = new MutableDataStore(); const logs: any[] = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event: any, _: any, callback: any) { logs.push(event); @@ -386,9 +386,9 @@ describe('Content Layer - Loader Warnings', () => { const store = new MutableDataStore(); const logs: any[] = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'warn', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event: any, _: any, callback: any) { logs.push(event); @@ -488,9 +488,9 @@ describe('Content Layer - Loader Warnings', () => { const store = new MutableDataStore(); const logs: any[] = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event: any, _: any, callback: any) { logs.push(event); diff --git a/packages/astro/test/units/content-layer/markdown-rendering.test.ts b/packages/astro/test/units/content-layer/markdown-rendering.test.ts index f688c5b086df..0bbc45d4d5c2 100644 --- a/packages/astro/test/units/content-layer/markdown-rendering.test.ts +++ b/packages/astro/test/units/content-layer/markdown-rendering.test.ts @@ -2,7 +2,7 @@ import { strict as assert } from 'node:assert'; import { describe, it } from 'node:test'; import { ContentLayer } from '../../../dist/content/content-layer.js'; import { MutableDataStore } from '../../../dist/content/mutable-data-store.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { defineCollection } from '../../../dist/content/config.js'; import { z } from 'zod'; import { @@ -83,8 +83,8 @@ Content with [a link](https://astro.build).`, }; const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -168,8 +168,8 @@ This content is processed by the loader using renderMarkdown. const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -243,8 +243,8 @@ Section 2 content.`; const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -304,8 +304,8 @@ This file has no frontmatter, just content.`; }; const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -377,8 +377,8 @@ And some inline code: \`const x = 42\`.`; }, }); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -404,8 +404,8 @@ And some inline code: \`const x = 42\`.`; it('renderMarkdown parses frontmatter correctly through loader', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -480,8 +480,8 @@ More content here.`; it('renderMarkdown excludes frontmatter from HTML output through loader', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -541,8 +541,8 @@ title: Test Post it('renderMarkdown extracts headings correctly through loader', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -618,8 +618,8 @@ Even more text it('renderMarkdown resolves relative image paths through loader', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -678,8 +678,8 @@ Even more text it('renderMarkdown populates combined imagePaths in metadata', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); diff --git a/packages/astro/test/units/content-layer/schema-validation.test.ts b/packages/astro/test/units/content-layer/schema-validation.test.ts index a6724777c365..a45f1dd7e575 100644 --- a/packages/astro/test/units/content-layer/schema-validation.test.ts +++ b/packages/astro/test/units/content-layer/schema-validation.test.ts @@ -4,7 +4,7 @@ import { z } from 'zod'; import { defineCollection } from '../../../dist/content/config.js'; import { ContentLayer } from '../../../dist/content/content-layer.js'; import { MutableDataStore } from '../../../dist/content/mutable-data-store.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createTempDir, createTestConfigObserver, createMinimalSettings } from './test-helpers.ts'; describe('Content Layer - Schema Validation', () => { @@ -13,8 +13,8 @@ describe('Content Layer - Schema Validation', () => { it('parses and coerces Date objects in schemas', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -117,8 +117,8 @@ describe('Content Layer - Schema Validation', () => { it('handles custom IDs and slugs', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -191,8 +191,8 @@ describe('Content Layer - Schema Validation', () => { it('supports union schemas (discriminated unions)', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -300,9 +300,9 @@ describe('Content Layer - Schema Validation', () => { const settings = createMinimalSettings(root); const logs: any[] = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'error', - dest: { + destination: { write: (event: any) => { logs.push(event); return true; @@ -404,9 +404,9 @@ describe('Content Layer - Schema Validation', () => { const settings = createMinimalSettings(root); const logs: any[] = []; - const logger = new Logger({ + const logger = new AstroLogger({ level: 'error', - dest: { + destination: { write: (event: any) => { logs.push(event); return true; @@ -496,8 +496,8 @@ describe('Content Layer - Schema Validation', () => { it('handles empty collections gracefully', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); @@ -541,8 +541,8 @@ describe('Content Layer - Schema Validation', () => { it('handles optional fields with defaults', async () => { const store = new MutableDataStore(); const settings = createMinimalSettings(root); - const logger = new Logger({ - dest: { write: () => true }, + const logger = new AstroLogger({ + destination: { write: () => true }, level: 'silent', }); diff --git a/packages/astro/test/units/logger/destination.test.ts b/packages/astro/test/units/logger/destination.test.ts index 3281acd24515..2a6bccb35060 100644 --- a/packages/astro/test/units/logger/destination.test.ts +++ b/packages/astro/test/units/logger/destination.test.ts @@ -32,7 +32,7 @@ describe('log destination', () => { const logger = new AstroLogger({ destination: testDestination, level: 'info', - format: 'default', + _format: 'default', }); it('info() pushes an event with level info', () => { @@ -75,7 +75,7 @@ describe('log destination', () => { const logger = new AstroLogger({ destination: testDestination, level: 'info', - format: 'default', + _format: 'default', }); logger.info('build', 'test'); assert.equal(logs[0]._format, 'default'); @@ -85,7 +85,7 @@ describe('log destination', () => { const logger = new AstroLogger({ destination: testDestination, level: 'info', - format: 'json', + _format: 'json', }); logger.info('build', 'test'); assert.equal(logs[0]._format, 'json'); @@ -96,7 +96,7 @@ describe('log destination', () => { const logger = new AstroLogger({ destination: jsonDestination, level: 'info', - format: 'json', + _format: 'json', }); it('serializes message and label as JSON', () => { @@ -119,7 +119,7 @@ describe('log destination', () => { const defaultLogger = new AstroLogger({ destination: jsonDestination, level: 'info', - format: 'default', + _format: 'default', }); defaultLogger.info('build', 'should not appear'); assert.equal(jsonLogs.length, 0); @@ -131,7 +131,7 @@ describe('log destination', () => { const logger = new AstroLogger({ destination: testDestination, level: 'warn', - format: 'default', + _format: 'default', }); logger.info('build', 'should be filtered'); assert.equal(logs.length, 0); @@ -141,7 +141,7 @@ describe('log destination', () => { const logger = new AstroLogger({ destination: testDestination, level: 'warn', - format: 'default', + _format: 'default', }); logger.warn('build', 'should pass'); assert.equal(logs.length, 1); @@ -151,7 +151,7 @@ describe('log destination', () => { const logger = new AstroLogger({ destination: testDestination, level: 'warn', - format: 'default', + _format: 'default', }); logger.error('build', 'should pass'); assert.equal(logs.length, 1); @@ -161,7 +161,7 @@ describe('log destination', () => { const logger = new AstroLogger({ destination: testDestination, level: 'silent', - format: 'default', + _format: 'default', }); logger.info('build', 'nope'); logger.warn('build', 'nope'); diff --git a/packages/astro/test/units/routing/getstaticpaths-cache.test.ts b/packages/astro/test/units/routing/getstaticpaths-cache.test.ts index d0dcca84cb49..7799c7eee7fb 100644 --- a/packages/astro/test/units/routing/getstaticpaths-cache.test.ts +++ b/packages/astro/test/units/routing/getstaticpaths-cache.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { describe, it, before, beforeEach } from 'node:test'; import type { ComponentInstance } from '../../../dist/types/astro.js'; import type { LogMessage, LogWritable } from '../../../dist/core/logger/core.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { RouteCache, callGetStaticPaths } from '../../../dist/core/render/route-cache.js'; import { dynamicPart, makeRoute } from './test-helpers.js'; @@ -15,12 +15,12 @@ describe('getStaticPaths caching behavior', () => { let logger: Logger; let callCount: number; - const dest: LogWritable = { + const destination: LogWritable = { write: () => true, }; before(() => { - logger = new Logger({ dest, level: 'error' }); + logger = new Logger({ destination, level: 'error' }); }); beforeEach(() => { diff --git a/packages/astro/test/units/routing/manifest.test.js b/packages/astro/test/units/routing/manifest.test.js index a1d5cda5f11e..f6edbbbc3bb2 100644 --- a/packages/astro/test/units/routing/manifest.test.js +++ b/packages/astro/test/units/routing/manifest.test.js @@ -1,6 +1,6 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createRoutesList } from '../../../dist/core/routing/create-manifest.js'; import { createBasicSettings, createFixture } from '../test-utils.js'; @@ -15,8 +15,8 @@ function getLogger() { const logs = []; return { - logger: new Logger({ - dest: { write: (msg) => logs.push(msg) }, + logger: new AstroLogger({ + destination: { write: (msg) => logs.push(msg) }, level: 'debug', }), logs, diff --git a/packages/astro/test/units/routing/params-validation.test.ts b/packages/astro/test/units/routing/params-validation.test.ts index 21425543ff7c..5e523306d222 100644 --- a/packages/astro/test/units/routing/params-validation.test.ts +++ b/packages/astro/test/units/routing/params-validation.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { describe, it, before } from 'node:test'; import type { ComponentInstance } from '../../../dist/types/astro.js'; import type { LogMessage, LogWritable } from '../../../dist/core/logger/core.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { RouteCache, callGetStaticPaths } from '../../../dist/core/render/route-cache.js'; import { makeRoute } from './test-helpers.js'; @@ -12,14 +12,14 @@ function mod(overrides: Partial): ComponentInstance { describe('getStaticPaths param validation', () => { let routeCache: RouteCache; - let logger: Logger; + let logger: AstroLogger; - const dest: LogWritable = { + const destination: LogWritable = { write: () => true, }; before(() => { - logger = new Logger({ dest, level: 'error' }); + logger = new AstroLogger({ destination, level: 'error' }); routeCache = new RouteCache(logger, 'production'); }); diff --git a/packages/astro/test/units/test-utils.js b/packages/astro/test/units/test-utils.js index b1b42dd0d898..afcf8617351e 100644 --- a/packages/astro/test/units/test-utils.js +++ b/packages/astro/test/units/test-utils.js @@ -7,15 +7,15 @@ import { getDefaultClientDirectives } from '../../dist/core/client-directive/ind import { resolveConfig } from '../../dist/core/config/index.js'; import { createBaseSettings } from '../../dist/core/config/settings.js'; import { createContainer } from '../../dist/core/dev/container.js'; -import { AstroIntegrationLogger, Logger } from '../../dist/core/logger/core.js'; +import { AstroIntegrationLogger, AstroLogger } from '../../dist/core/logger/core.js'; import { nodeLogDestination } from '../../dist/core/logger/node.js'; import { NOOP_MIDDLEWARE_FN } from '../../dist/core/middleware/noop-middleware.js'; import { Pipeline } from '../../dist/core/render/index.js'; import { RouteCache } from '../../dist/core/render/route-cache.js'; -/** @type {import('../../src/core/logger/core').Logger} */ -export const defaultLogger = new Logger({ - dest: nodeLogDestination, +/** @type {import('../../src/core/logger/core').AstroLogger} */ +export const defaultLogger = new AstroLogger({ + destination: nodeLogDestination, level: 'error', }); @@ -147,7 +147,7 @@ export async function createBasicSettings(inlineConfig = {}) { * @typedef {{ * fs?: typeof realFS, * inlineConfig?: import('../../src/types/public/config.js').AstroInlineConfig, - * logging?: import('../../src/core/logger/core').LogOptions, + * logging?: import('../../src/core/logger/core').AstroLogOptions, * }} RunInContainerOptions */ @@ -171,10 +171,10 @@ export async function runInContainer(options = {}, callback) { } /** - * @import {Logger} from '../../dist/core/logger/core' + * @import {AstroLogger} from '../../dist/core/logger/core' */ -/** @implements {Logger} */ +/** @implements {AstroLogger} */ export class SpyLogger { /** @type {Array<{ type: string; label: string | null; message: string }>} */ #logs = []; @@ -195,7 +195,7 @@ export class SpyLogger { this.#logs.push({ type: 'warn', label, message }); } options = { - dest: { + destination: { write: () => true, }, level: /** @type {const} */ ('silent'), diff --git a/packages/integrations/cloudflare/test/ssr-deps.test.js b/packages/integrations/cloudflare/test/ssr-deps.test.js index 92d2973e2f01..3f8b472b4b42 100644 --- a/packages/integrations/cloudflare/test/ssr-deps.test.js +++ b/packages/integrations/cloudflare/test/ssr-deps.test.js @@ -3,7 +3,7 @@ import { rmSync } from 'node:fs'; import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; import { fileURLToPath } from 'node:url'; -import { Logger } from '../../../astro/dist/core/logger/core.js'; +import { AstroLogger } from '../../../astro/dist/core/logger/core.js'; import { loadFixture } from './_test-utils.js'; describe('SSR dependencies', () => { @@ -21,9 +21,9 @@ describe('SSR dependencies', () => { rmSync(fileURLToPath(viteCacheDir), { recursive: true, force: true }); devServer = await fixture.startDevServer({ - logger: new Logger({ + logger: new AstroLogger({ level: 'info', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); diff --git a/packages/integrations/cloudflare/test/top-level-return.test.js b/packages/integrations/cloudflare/test/top-level-return.test.js index c801eef880bc..4726bfa1f3d3 100644 --- a/packages/integrations/cloudflare/test/top-level-return.test.js +++ b/packages/integrations/cloudflare/test/top-level-return.test.js @@ -4,7 +4,7 @@ import { Writable } from 'node:stream'; import { loadFixture } from './_test-utils.js'; import assert from 'node:assert/strict'; import { fileURLToPath } from 'node:url'; -import { Logger } from '../../../astro/dist/core/logger/core.js'; +import { AstroLogger } from '../../../astro/dist/core/logger/core.js'; describe('Top-level Return', () => { /** @type {import('../../../astro/test/test-utils').Fixture} */ @@ -23,9 +23,9 @@ describe('Top-level Return', () => { await fixture.build({ vite: { logLevel: 'error' }, - logger: new Logger({ + logger: new AstroLogger({ level: 'error', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); diff --git a/packages/integrations/cloudflare/test/with-base.test.js b/packages/integrations/cloudflare/test/with-base.test.js index 998d630dfc96..1a71a9a90f57 100644 --- a/packages/integrations/cloudflare/test/with-base.test.js +++ b/packages/integrations/cloudflare/test/with-base.test.js @@ -3,7 +3,7 @@ import { rmSync } from 'node:fs'; import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; import { loadFixture } from './_test-utils.js'; -import { Logger } from '../../../astro/dist/core/logger/core.js'; +import { AstroLogger } from '../../../astro/dist/core/logger/core.js'; import { fileURLToPath } from 'node:url'; describe('base', () => { @@ -22,9 +22,9 @@ describe('base', () => { await fixture.build({ vite: { logLevel: 'debug' }, - logger: new Logger({ + logger: new AstroLogger({ level: 'debug', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); diff --git a/packages/integrations/cloudflare/test/with-react.test.js b/packages/integrations/cloudflare/test/with-react.test.js index e57388c36897..7987a0f98516 100644 --- a/packages/integrations/cloudflare/test/with-react.test.js +++ b/packages/integrations/cloudflare/test/with-react.test.js @@ -4,7 +4,7 @@ import { Writable } from 'node:stream'; import { after, before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; import { loadFixture } from './_test-utils.js'; -import { Logger } from '../../../astro/dist/core/logger/core.js'; +import { AstroLogger } from '../../../astro/dist/core/logger/core.js'; import { fileURLToPath } from 'node:url'; describe('React', () => { @@ -24,9 +24,9 @@ describe('React', () => { await fixture.build({ vite: { logLevel: 'debug' }, - logger: new Logger({ + logger: new AstroLogger({ level: 'debug', - dest: new Writable({ + destination: new Writable({ objectMode: true, write(event, _, callback) { logs.push(event); From 1e806bd306a7cbc372cdc1d5a7d635ef379f7b93 Mon Sep 17 00:00:00 2001 From: ematipico Date: Thu, 9 Apr 2026 12:58:36 +0100 Subject: [PATCH 5/7] rebase --- packages/astro/e2e/test-utils.js | 4 ++-- packages/astro/src/core/base-pipeline.ts | 2 +- packages/astro/src/core/logger/core.ts | 3 --- .../astro/test/units/routing/getstaticpaths-cache.test.ts | 8 ++++---- .../astro/test/units/routing/params-validation.test.ts | 4 ++-- packages/astro/test/units/routing/route-manifest.test.ts | 8 ++++---- 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/packages/astro/e2e/test-utils.js b/packages/astro/e2e/test-utils.js index 4ca3d17825dd..170d73ed751b 100644 --- a/packages/astro/e2e/test-utils.js +++ b/packages/astro/e2e/test-utils.js @@ -113,7 +113,7 @@ export async function scrollToElement(el) { /** * Create a spy logger that captures log messages into provided arrays * @param {{info?: Array, warn?: Array, error?: Array, debug?: Array}} options - Optional arrays to push messages into - * @returns {import('../dist/core/logger/core').Logger} + * @returns {import('../dist/core/logger/core').AstroLogger} */ export function createLoggerSpy(options = {}) { const infoLogs = options.info || []; @@ -135,7 +135,7 @@ export function createLoggerSpy(options = {}) { debugLogs.push(...messages.map((message) => ({ label, message }))); }, options: { - dest: { write: () => true }, + destination: { write: () => true }, level: 'info', }, level: () => 'info', diff --git a/packages/astro/src/core/base-pipeline.ts b/packages/astro/src/core/base-pipeline.ts index c6fbf8507df3..e470a0e51330 100644 --- a/packages/astro/src/core/base-pipeline.ts +++ b/packages/astro/src/core/base-pipeline.ts @@ -45,7 +45,7 @@ export abstract class Pipeline { nodePool: NodePool | undefined; htmlStringCache: HTMLStringCache | undefined; - readonly logger: Logger; + readonly logger: AstroLogger; readonly manifest: SSRManifest; /** * "development" or "production" only diff --git a/packages/astro/src/core/logger/core.ts b/packages/astro/src/core/logger/core.ts index e011c965e19e..a3c527851728 100644 --- a/packages/astro/src/core/logger/core.ts +++ b/packages/astro/src/core/logger/core.ts @@ -64,9 +64,6 @@ export interface AstroLogOptions { level: AstroLoggerLevel; // Intentionally optional so we don't leak to public code. It will be public and non-optional // once we expose to users - /** - * @internal - */ _format?: AstroLoggerFormat; } diff --git a/packages/astro/test/units/routing/getstaticpaths-cache.test.ts b/packages/astro/test/units/routing/getstaticpaths-cache.test.ts index 7799c7eee7fb..e04bd60bd623 100644 --- a/packages/astro/test/units/routing/getstaticpaths-cache.test.ts +++ b/packages/astro/test/units/routing/getstaticpaths-cache.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { describe, it, before, beforeEach } from 'node:test'; import type { ComponentInstance } from '../../../dist/types/astro.js'; -import type { LogMessage, LogWritable } from '../../../dist/core/logger/core.js'; +import type { AstroLogMessage, AstroLoggerDestination } from '../../../dist/core/logger/core.js'; import { AstroLogger } from '../../../dist/core/logger/core.js'; import { RouteCache, callGetStaticPaths } from '../../../dist/core/render/route-cache.js'; import { dynamicPart, makeRoute } from './test-helpers.js'; @@ -12,15 +12,15 @@ function mod(overrides: Partial): ComponentInstance { describe('getStaticPaths caching behavior', () => { let routeCache: RouteCache; - let logger: Logger; + let logger: AstroLogger; let callCount: number; - const destination: LogWritable = { + const destination: AstroLoggerDestination = { write: () => true, }; before(() => { - logger = new Logger({ destination, level: 'error' }); + logger = new AstroLogger({ destination, level: 'error' }); }); beforeEach(() => { diff --git a/packages/astro/test/units/routing/params-validation.test.ts b/packages/astro/test/units/routing/params-validation.test.ts index 5e523306d222..ebfdbef7029b 100644 --- a/packages/astro/test/units/routing/params-validation.test.ts +++ b/packages/astro/test/units/routing/params-validation.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { describe, it, before } from 'node:test'; import type { ComponentInstance } from '../../../dist/types/astro.js'; -import type { LogMessage, LogWritable } from '../../../dist/core/logger/core.js'; +import type { AstroLogMessage, AstroLoggerDestination } from '../../../dist/core/logger/core.js'; import { AstroLogger } from '../../../dist/core/logger/core.js'; import { RouteCache, callGetStaticPaths } from '../../../dist/core/render/route-cache.js'; import { makeRoute } from './test-helpers.js'; @@ -14,7 +14,7 @@ describe('getStaticPaths param validation', () => { let routeCache: RouteCache; let logger: AstroLogger; - const destination: LogWritable = { + const destination: AstroLoggerDestination = { write: () => true, }; diff --git a/packages/astro/test/units/routing/route-manifest.test.ts b/packages/astro/test/units/routing/route-manifest.test.ts index 18a0b8bcf0f3..75896bf2606e 100644 --- a/packages/astro/test/units/routing/route-manifest.test.ts +++ b/packages/astro/test/units/routing/route-manifest.test.ts @@ -2,12 +2,12 @@ import assert from 'node:assert/strict'; import { describe, it } from 'node:test'; import type { AstroConfig } from '../../../dist/types/public/config.js'; import type { RouteData } from '../../../dist/types/public/internal.js'; -import type { LogMessage, LogWritable } from '../../../dist/core/logger/core.js'; -import { Logger } from '../../../dist/core/logger/core.js'; +import type { AstroLogMessage, AstroLoggerDestination } from '../../../dist/core/logger/core.js'; +import { AstroLogger } from '../../../dist/core/logger/core.js'; import { createRoutesFromEntries } from '../../../dist/core/routing/create-manifest.js'; -const dest: LogWritable = { write: () => true }; -const logger = new Logger({ dest, level: 'silent' }); +const destination: AstroLoggerDestination = { write: () => true }; +const logger = new AstroLogger({ destination, level: 'silent' }); type RoutingSettings = Parameters[1]; From 1a68d8f8eb23a16fd1784c0690caef78f2f8c4e1 Mon Sep 17 00:00:00 2001 From: ematipico Date: Thu, 9 Apr 2026 13:57:05 +0100 Subject: [PATCH 6/7] fix linting and test --- packages/astro/src/types/public/logger.ts | 7 ------- packages/astro/test/units/routing/manifest.test.js | 8 ++++---- 2 files changed, 4 insertions(+), 11 deletions(-) delete mode 100644 packages/astro/src/types/public/logger.ts diff --git a/packages/astro/src/types/public/logger.ts b/packages/astro/src/types/public/logger.ts deleted file mode 100644 index cc626aeb1118..000000000000 --- a/packages/astro/src/types/public/logger.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { AstroLogMessage, AstroLoggerLevel } from '../../core/logger/core.js'; - -export type { AstroLogMessage, AstroLoggerLevel }; - -export type AstroLoggerDestination = { - write: (chunk: D | AstroLogMessage) => void; -}; diff --git a/packages/astro/test/units/routing/manifest.test.js b/packages/astro/test/units/routing/manifest.test.js index f6edbbbc3bb2..0f8ec1e95b7a 100644 --- a/packages/astro/test/units/routing/manifest.test.js +++ b/packages/astro/test/units/routing/manifest.test.js @@ -364,7 +364,7 @@ describe('routing - createRoutesList', () => { assert.deepEqual(logs, [ { - format: 'default', + _format: 'default', label: 'router', level: 'warn', message: @@ -372,7 +372,7 @@ describe('routing - createRoutesList', () => { newLine: true, }, { - format: 'default', + _format: 'default', label: 'router', level: 'warn', message: 'A collision will result in a hard error in following versions of Astro.', @@ -405,7 +405,7 @@ describe('routing - createRoutesList', () => { assert.deepEqual(logs, [ { - format: 'default', + _format: 'default', label: 'router', level: 'warn', message: @@ -413,7 +413,7 @@ describe('routing - createRoutesList', () => { newLine: true, }, { - format: 'default', + _format: 'default', label: 'router', level: 'warn', message: 'A collision will result in a hard error in following versions of Astro.', From d5e7ba1fdbcb0fc03324f824818c392bbb449a91 Mon Sep 17 00:00:00 2001 From: ematipico Date: Thu, 9 Apr 2026 14:53:00 +0100 Subject: [PATCH 7/7] fix logging --- packages/astro/test/core-image.test.js | 30 +++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/astro/test/core-image.test.js b/packages/astro/test/core-image.test.js index 49a252d78b44..314ad9ba14d5 100644 --- a/packages/astro/test/core-image.test.js +++ b/packages/astro/test/core-image.test.js @@ -1155,23 +1155,27 @@ describe('astro:image', () => { it('uses cache entries', async () => { const logs = []; - const logger = new AstroLogger({ - destination: { - write(chunk) { - logs.push(chunk); - return true; + + await fixture.build({ + logger: new AstroLogger({ + destination: { + write(chunk) { + logs.push(chunk); + return true; + }, }, - }, - level: 'info', + level: 'info', + }), }); - - await fixture.build({ logger }); const generatingImageIndex = logs.findIndex((logLine) => - logLine.message.includes('generating optimized images'), + logLine.message?.includes('generating optimized images'), ); - const relevantLogs = logs.slice(generatingImageIndex + 1, -1); - const isReusingCache = relevantLogs.every((logLine) => - logLine.message.includes('(reused cache entry)'), + const imageLogs = logs + .slice(generatingImageIndex + 1) + .filter((logLine) => logLine.message?.includes('/_astro/')); + assert.ok(imageLogs.length > 0, 'Expected at least one image log entry'); + const isReusingCache = imageLogs.every((logLine) => + logLine.message?.includes('cache entry)'), ); assert.equal(isReusingCache, true);