diff --git a/packages/astro/src/core/config/config.ts b/packages/astro/src/core/config/config.ts index 08d48e430c54..bf9b21bbc2f0 100644 --- a/packages/astro/src/core/config/config.ts +++ b/packages/astro/src/core/config/config.ts @@ -17,6 +17,11 @@ import { mergeConfig } from './merge.js'; import { validateConfig } from './validate.js'; import { loadConfigWithVite } from './vite-load.js'; +/** + * Resolve the project root directory to an absolute path. + * Falls back to `process.cwd()` when no directory is given. + * @param cwd A relative or absolute path, or a `file://` URL. + */ export function resolveRoot(cwd?: string | URL): string { if (cwd instanceof URL) { cwd = fileURLToPath(cwd); diff --git a/packages/astro/src/core/config/merge.ts b/packages/astro/src/core/config/merge.ts index e9f22a256b99..de7c48215eb6 100644 --- a/packages/astro/src/core/config/merge.ts +++ b/packages/astro/src/core/config/merge.ts @@ -80,6 +80,13 @@ function mergeConfigRecursively( return merged; } +/** + * Deep-merge two Astro config objects. Arrays are concatenated, objects are + * recursed, and special keys (`vite`, `server`, `markdown.processor`) receive + * bespoke handling so that overrides behave predictably. + * @param defaults The base config (typically from the user's config file). + * @param overrides Partial overrides (e.g. from integrations or inline config). + */ export function mergeConfig( defaults: C, overrides: DeepPartial, diff --git a/packages/astro/src/core/config/schemas/base.ts b/packages/astro/src/core/config/schemas/base.ts index 68aa9e62410e..df4f0268404f 100644 --- a/packages/astro/src/core/config/schemas/base.ts +++ b/packages/astro/src/core/config/schemas/base.ts @@ -58,6 +58,7 @@ export type RemarkRehype = ComplexifyWithOmit<_RemarkRehype>; /** @lintignore */ export type Smartypants = ComplexifyWithOmit<_Smartypants>; +/** Default values for every Astro config field, used as fallbacks during validation. */ export const ASTRO_CONFIG_DEFAULTS = { root: '.', srcDir: './src', @@ -152,6 +153,7 @@ const smartypantsOptionsSchema: z.ZodType = z.object({ quotes: z.boolean().default(true), }); +/** Base Zod schema for the full Astro user configuration. Paths are raw strings at this stage; the relative schema applies file-system transforms. */ export const AstroConfigSchema = z.object({ root: z .string() @@ -610,4 +612,5 @@ export const AstroConfigSchema = z.object({ .prefault({}), }); +/** Inferred TypeScript type produced by parsing `AstroConfigSchema`. */ export type AstroConfigType = z.infer; diff --git a/packages/astro/src/core/config/schemas/refined.ts b/packages/astro/src/core/config/schemas/refined.ts index 98ed6968ef4c..db67e91d455f 100644 --- a/packages/astro/src/core/config/schemas/refined.ts +++ b/packages/astro/src/core/config/schemas/refined.ts @@ -12,6 +12,12 @@ import { validateRemotePatterns, } from './refined-validators.js'; +/** + * Second-pass validation schema that runs cross-field semantic checks on a + * fully-parsed `AstroConfig` (e.g. i18n consistency, asset prefix shape, + * font CSS variable format). Used after the base schema and the relative + * transforms have both completed. + */ export const AstroConfigRefinedSchema = z.custom().superRefine((config, ctx) => { let issues: ConfigValidationIssue[] = []; issues = issues.concat( diff --git a/packages/astro/src/core/config/schemas/relative.ts b/packages/astro/src/core/config/schemas/relative.ts index c108b7d3793a..713f17290fa5 100644 --- a/packages/astro/src/core/config/schemas/relative.ts +++ b/packages/astro/src/core/config/schemas/relative.ts @@ -13,6 +13,15 @@ function resolveDirAsUrl(dir: string, root: string) { return pathToFileURL(resolvedDir); } +/** + * Extend the base `AstroConfigSchema` with path transforms that resolve + * directory strings (`root`, `srcDir`, `publicDir`, `outDir`, `cacheDir`, + * `build.client`, `build.server`) relative to a given filesystem root. + * Also normalizes `base` and `image.endpoint.route` according to + * `trailingSlash` and handles `server` as a function-or-object union. + * @param cmd The running Astro command (e.g. `'dev'`, `'build'`). + * @param fileProtocolRoot Absolute filesystem root used for path resolution. + */ export function createRelativeSchema(cmd: string, fileProtocolRoot: string) { let originalBuildClient: string; let originalBuildServer: string; diff --git a/packages/astro/src/core/config/settings.ts b/packages/astro/src/core/config/settings.ts index cefb5a332d4c..4f6e83ccac65 100644 --- a/packages/astro/src/core/config/settings.ts +++ b/packages/astro/src/core/config/settings.ts @@ -19,6 +19,13 @@ import { import { AstroTimer } from './timer.js'; import { loadTSConfig } from './tsconfig.js'; +/** + * Create an `AstroSettings` object from a fully-resolved `AstroConfig`, + * populating default content-entry types, client directives, and other + * runtime bookkeeping without loading a tsconfig. + * @param config Resolved Astro configuration. + * @param logLevel Logging verbosity for the current session. + */ export function createBaseSettings( config: AstroConfig, logLevel: AstroInlineConfig['logLevel'], @@ -165,6 +172,13 @@ export function createBaseSettings( }; } +/** + * Create an `AstroSettings` object from a fully-resolved `AstroConfig`, + * including tsconfig loading and watch-file registration. + * @param config Resolved Astro configuration. + * @param logLevel Logging verbosity for the current session. + * @param cwd Optional working directory used to locate `tsconfig.json`. + */ export async function createSettings( config: AstroConfig, logLevel: AstroInlineConfig['logLevel'], diff --git a/packages/astro/src/core/config/tsconfig.ts b/packages/astro/src/core/config/tsconfig.ts index 0e29495c135e..1bd2a2fa9f80 100644 --- a/packages/astro/src/core/config/tsconfig.ts +++ b/packages/astro/src/core/config/tsconfig.ts @@ -4,11 +4,17 @@ import { readTsconfig, type TsconfigResult } from 'get-tsconfig'; import { parse as parseJsonc, type ParseError } from 'jsonc-parser'; import type { CompilerOptions, TypeAcquisition } from 'typescript'; +/** Default tsconfig that extends Astro's base configuration. */ export const defaultTSConfig: TSConfig = { extends: 'astro/tsconfigs/base' }; +/** Frameworks that require custom TypeScript compiler settings for JSX support. */ export type frameworkWithTSSettings = 'vue' | 'react' | 'preact' | 'solid-js'; // The following presets unfortunately cannot be inside the specific integrations, as we need // them even in cases where the integrations are not installed +/** + * Per-framework tsconfig presets merged when a framework integration is detected. + * Each entry maps to compiler options needed for that framework's JSX transform. + */ export const presets = new Map([ [ 'vue', // Settings needed for template intellisense when using Volar @@ -47,6 +53,7 @@ export const presets = new Map([ ], ]); +/** Result of successfully loading and resolving a tsconfig/jsconfig file. */ export interface TSConfigLoadedResult { error?: undefined; /** Absolute path of the root tsconfig/jsconfig file that was loaded. */ @@ -62,6 +69,7 @@ export interface TSConfigLoadedResult { sources: string[]; } +/** Discriminated union of tsconfig load outcomes: success, parse error, or missing file. */ export type TSConfigResult = | TSConfigLoadedResult | { error: 'invalid-config'; message: string } @@ -137,6 +145,12 @@ export async function loadTSConfig(root: string | undefined): Promise> = { : any; }; +/** Subset of `tsconfig.json` fields that Astro reads and manipulates. */ export interface TSConfig { compilerOptions?: StripEnums; compileOnSave?: boolean; diff --git a/packages/astro/src/core/config/vite-load.ts b/packages/astro/src/core/config/vite-load.ts index 91540a09475e..0785a3e620d6 100644 --- a/packages/astro/src/core/config/vite-load.ts +++ b/packages/astro/src/core/config/vite-load.ts @@ -12,6 +12,14 @@ interface LoadConfigWithViteOptions { fs: typeof fsType; } +/** + * Load an Astro config file using Vite's module runner as a fallback when + * native Node.js `import()` fails (e.g. for `.ts` files). Closes the + * temporary Vite dev server after loading. + * @param options.root Project root directory. + * @param options.configPath Absolute path to the config file. + * @param options.fs Filesystem module to use for file operations. + */ export async function loadConfigWithVite({ configPath, fs,