{"version":3,"file":"config-D3LN71YS.mjs","names":[],"sources":["../src/config/resolve.ts","../src/config/shared.ts","../src/config/validate.ts"],"sourcesContent":["import { execSync } from \"child_process\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { tmpdir } from \"os\";\nimport JSON5 from \"json5\";\nimport { basename, dirname, join, resolve } from \"path\";\nimport { loadPagesmithConfig } from \"@pagesmith/core/cli-kit\";\nimport type {\n  DocsLogLevel,\n  DocsServerPort,\n  DocsUserConfig,\n  GitOriginInfo,\n  ResolvedDocsConfig,\n} from \"./types\";\n\nconst DEFAULT_SERVER_HOST = \"127.0.0.1\";\nconst DEFAULT_DEV_PORT = 3000;\nconst DEFAULT_PREVIEW_PORT = 4000;\nconst DEFAULT_SERVER_LOG_LEVEL: DocsLogLevel = \"info\";\n\n/**\n * Validate and normalize a port value coming from user config. Accepts\n * `\"auto\"`, a number, or a numeric string and rejects everything else with a\n * helpful message that points at the offending config field.\n */\nfunction normalizePort(value: unknown, field: string): DocsServerPort {\n  if (value === \"auto\") return \"auto\";\n  if (typeof value === \"number\") {\n    if (!Number.isFinite(value) || !Number.isInteger(value) || value < 1 || value > 65535) {\n      throw new Error(\n        `${field} must be \"auto\" or an integer between 1 and 65535 (got ${JSON.stringify(value)}).`,\n      );\n    }\n    return value;\n  }\n  if (typeof value === \"string\") {\n    const parsed = Number.parseInt(value, 10);\n    if (Number.isFinite(parsed) && String(parsed) === value && parsed >= 1 && parsed <= 65535) {\n      return parsed;\n    }\n    throw new Error(\n      `${field} must be \"auto\" or an integer between 1 and 65535 (got ${JSON.stringify(value)}).`,\n    );\n  }\n  throw new Error(\n    `${field} must be \"auto\" or an integer between 1 and 65535 (got ${JSON.stringify(value)}).`,\n  );\n}\n\nexport function defineDocsConfig<T extends DocsUserConfig>(config: T): T {\n  return config;\n}\n\n/**\n * Identity helper for `pagesmith.config.ts` files. Equivalent to\n * `defineDocsConfig`; provided as the canonical name users expect from other\n * Pagesmith packages.\n */\nexport const defineConfig = defineDocsConfig;\n\n/**\n * Synchronous loader. Reads `pagesmith.config.json5` (or any explicit path\n * with a JSON5/JSON extension). Throws when handed a `.ts/.mts/.js/.mjs` path\n * because TypeScript/JS configs require asynchronous loading via `jiti` /\n * dynamic `import()`. CLI commands always go through `loadDocsConfigAsync`,\n * which handles every supported extension.\n */\nexport function loadDocsConfig(configPath?: string): DocsUserConfig {\n  const resolvedConfigPath = resolve(configPath ?? join(process.cwd(), \"pagesmith.config.json5\"));\n  if (!existsSync(resolvedConfigPath)) {\n    return {};\n  }\n\n  if (\n    resolvedConfigPath.endsWith(\".ts\") ||\n    resolvedConfigPath.endsWith(\".mts\") ||\n    resolvedConfigPath.endsWith(\".js\") ||\n    resolvedConfigPath.endsWith(\".mjs\")\n  ) {\n    throw new Error(\n      `loadDocsConfig is synchronous and only supports JSON5/JSON configs (got: ${resolvedConfigPath}).\\n` +\n        \"  Use `await loadDocsConfigAsync(path)` for TypeScript/JS configs.\",\n    );\n  }\n\n  try {\n    return JSON5.parse(readFileSync(resolvedConfigPath, \"utf-8\")) as DocsUserConfig;\n  } catch (err) {\n    const message = err instanceof Error ? err.message : String(err);\n    throw new Error(\n      `Failed to parse config file: ${resolvedConfigPath}\\n` +\n        `  ${message}\\n` +\n        `  Check that the file contains valid JSON5 syntax.`,\n    );\n  }\n}\n\n/**\n * Async loader for any supported config file extension\n * (`.ts`, `.mts`, `.js`, `.mjs`, `.json5`, `.json`).\n *\n * Used by every CLI command (init/dev/build/preview/validate/mcp) so users can\n * author their docs config in TypeScript and still get the same resolved shape.\n */\nexport async function loadDocsConfigAsync(configPath?: string): Promise<DocsUserConfig> {\n  const resolved = configPath\n    ? resolve(configPath)\n    : resolve(join(process.cwd(), \"pagesmith.config.json5\"));\n  if (!existsSync(resolved)) {\n    return {};\n  }\n  const result = await loadPagesmithConfig({ explicitPath: resolved });\n  return (result.config as DocsUserConfig | undefined) ?? {};\n}\n\n/** Detect basePath and origin from git remote URL. */\nexport function detectGitOrigin(rootDir: string): GitOriginInfo | undefined {\n  try {\n    const remoteUrl = execSync(\"git remote get-url origin\", {\n      cwd: rootDir,\n      stdio: [\"pipe\", \"pipe\", \"pipe\"],\n      encoding: \"utf-8\",\n    }).trim();\n\n    let match = remoteUrl.match(/github\\.com[:/]([^/]+)\\/([^/.]+?)(?:\\.git)?$/);\n    if (match) {\n      const [, owner, repo] = match;\n      return {\n        basePath: `/${repo}`,\n        origin: `https://${owner}.github.io`,\n        repoOwner: owner,\n        repoName: repo,\n        repoUrl: `https://github.com/${owner}/${repo}`,\n        editLinkHost: \"github\",\n      };\n    }\n\n    match = remoteUrl.match(/gitlab\\.com[:/]([^/]+)\\/([^/.]+?)(?:\\.git)?$/);\n    if (match) {\n      const [, owner, repo] = match;\n      return {\n        basePath: `/${repo}`,\n        origin: `https://${owner}.gitlab.io`,\n        repoOwner: owner,\n        repoName: repo,\n        repoUrl: `https://gitlab.com/${owner}/${repo}`,\n        editLinkHost: \"gitlab\",\n      };\n    }\n\n    match = remoteUrl.match(/bitbucket\\.org[:/]([^/]+)\\/([^/.]+?)(?:\\.git)?$/);\n    if (match) {\n      const [, owner, repo] = match;\n      return {\n        basePath: `/${repo}`,\n        repoOwner: owner,\n        repoName: repo,\n        repoUrl: `https://bitbucket.org/${owner}/${repo}`,\n        editLinkHost: \"bitbucket\",\n      };\n    }\n  } catch {\n    // Not a git repo or git not installed — skip silently\n  }\n  return undefined;\n}\n\nexport async function probeHostedOrigin(origin: string): Promise<string> {\n  try {\n    const response = await fetch(origin, {\n      redirect: \"follow\",\n      signal: AbortSignal.timeout(4000),\n    });\n\n    const finalUrl = response.url || origin;\n    return new URL(finalUrl).origin;\n  } catch {\n    return origin;\n  }\n}\n\nexport async function resolveInitOrigin(\n  rootDir: string,\n  gitInfo = detectGitOrigin(rootDir),\n): Promise<string | undefined> {\n  if (!gitInfo?.origin) return undefined;\n  if (gitInfo.editLinkHost !== \"github\") return gitInfo.origin;\n  return probeHostedOrigin(gitInfo.origin);\n}\n\nexport function detectFirstCommitYear(rootDir: string): number | undefined {\n  try {\n    const firstCommitDate = execSync(\"git log --reverse --format=%cI --max-count=1\", {\n      cwd: rootDir,\n      stdio: [\"pipe\", \"pipe\", \"pipe\"],\n      encoding: \"utf-8\",\n    }).trim();\n    if (!firstCommitDate) return undefined;\n\n    const year = new Date(firstCommitDate).getFullYear();\n    return Number.isFinite(year) ? year : undefined;\n  } catch {\n    return undefined;\n  }\n}\n\nfunction readPackageJson(rootDir: string):\n  | {\n      name?: string;\n      description?: string;\n      homepage?: string;\n      author?: string | { name?: string; url?: string };\n    }\n  | undefined {\n  const pkgPath = join(rootDir, \"package.json\");\n  if (!existsSync(pkgPath)) return undefined;\n  try {\n    return JSON.parse(readFileSync(pkgPath, \"utf-8\"));\n  } catch {\n    return undefined;\n  }\n}\n\nfunction parseMaintainer(\n  author: string | { name?: string; url?: string } | undefined,\n): ResolvedDocsConfig[\"maintainer\"] {\n  if (!author) return undefined;\n\n  if (typeof author === \"string\") {\n    const match = author.trim().match(/^([^<(]+?)\\s*(?:<[^>]*>)?\\s*(?:\\(([^)]+)\\))?$/);\n    if (!match) return undefined;\n\n    const name = match[1]?.trim();\n    const link = match[2]?.trim();\n    if (!name) return undefined;\n\n    return {\n      name,\n      ...(link ? { link } : {}),\n    };\n  }\n\n  const name = author.name?.trim();\n  if (!name) return undefined;\n\n  return {\n    name,\n    ...(author.url?.trim() ? { link: author.url.trim() } : {}),\n  };\n}\n\nfunction resolveContentDir(rootDir: string, explicit?: string): string {\n  if (explicit) return resolve(rootDir, explicit);\n  const docsDir = resolve(rootDir, \"docs\");\n  if (existsSync(docsDir)) return docsDir;\n  return resolve(rootDir, \"content\");\n}\n\nfunction generateDefaultFavicon(letter: string): string {\n  const cacheDir = join(tmpdir(), \"pagesmith-favicon\", letter);\n  const filePath = join(cacheDir, \"favicon.svg\");\n  if (!existsSync(filePath)) {\n    const svg = [\n      '<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\">',\n      '  <rect width=\"32\" height=\"32\" rx=\"6\" fill=\"#111\"/>',\n      `  <text x=\"16\" y=\"24\" text-anchor=\"middle\" fill=\"#fff\" font-family=\"system-ui\" font-size=\"20\" font-weight=\"700\">${letter}</text>`,\n      \"</svg>\",\n      \"\",\n    ].join(\"\\n\");\n    mkdirSync(cacheDir, { recursive: true });\n    writeFileSync(filePath, svg);\n  }\n  return filePath;\n}\n\nexport function resolveDocsConfig(\n  configPath?: string,\n  overrides?: { outDir?: string; basePath?: string },\n): ResolvedDocsConfig {\n  const resolvedConfigPath = resolve(configPath ?? join(process.cwd(), \"pagesmith.config.json5\"));\n  const userConfig = loadDocsConfig(resolvedConfigPath);\n  return resolveDocsConfigFromUser(resolvedConfigPath, userConfig, overrides, {\n    zeroConfig: !existsSync(resolvedConfigPath),\n  });\n}\n\n/**\n * Async equivalent of `resolveDocsConfig` that supports every config file\n * extension (`.ts`, `.mts`, `.js`, `.mjs`, `.json5`, `.json`). CLI commands\n * always use this so authors can pick whichever config format they prefer.\n */\nexport async function resolveDocsConfigAsync(\n  configPath?: string,\n  overrides?: { outDir?: string; basePath?: string },\n): Promise<ResolvedDocsConfig> {\n  const resolvedConfigPath = resolve(configPath ?? join(process.cwd(), \"pagesmith.config.json5\"));\n  const userConfig = await loadDocsConfigAsync(resolvedConfigPath);\n  return resolveDocsConfigFromUser(resolvedConfigPath, userConfig, overrides, {\n    zeroConfig: !existsSync(resolvedConfigPath),\n  });\n}\n\nfunction resolveDocsConfigFromUser(\n  resolvedConfigPath: string,\n  userConfig: DocsUserConfig,\n  overrides?: { outDir?: string; basePath?: string },\n  meta: { zeroConfig?: boolean } = {},\n): ResolvedDocsConfig {\n  const rootDir = dirname(resolvedConfigPath);\n  const packageName = basename(rootDir);\n  const pkg = readPackageJson(rootDir);\n  const pkgDisplayName = pkg?.name?.replace(/^@[^/]+\\//, \"\");\n  const gitInfo = detectGitOrigin(rootDir);\n  const rawEnvBasePath = process.env.BASE_URL?.trim();\n  const envBasePath = rawEnvBasePath && rawEnvBasePath !== \"/\" ? rawEnvBasePath : undefined;\n\n  const rawBase =\n    overrides?.basePath ?? envBasePath ?? userConfig.basePath ?? gitInfo?.basePath ?? \"/\";\n  let basePath = rawBase.replace(/\\/+$/, \"\");\n  if (basePath && !basePath.startsWith(\"/\")) {\n    basePath = \"/\" + basePath;\n  }\n  const contentDir = resolveContentDir(rootDir, userConfig.contentDir);\n  const publicDir = resolve(rootDir, userConfig.publicDir ?? \"public\");\n  const siteName = userConfig.name ?? userConfig.title ?? pkgDisplayName ?? packageName;\n  const maintainer = userConfig.maintainer ?? parseMaintainer(pkg?.author);\n  const buildYear = new Date().getFullYear();\n\n  let copyright: ResolvedDocsConfig[\"copyright\"];\n  if (userConfig.copyright) {\n    const startYear = userConfig.copyright.startYear ?? detectFirstCommitYear(rootDir) ?? buildYear;\n    const configuredEndYear = userConfig.copyright.endYear ?? undefined;\n    const normalizedEndYear =\n      configuredEndYear !== undefined ? Math.max(configuredEndYear, startYear) : undefined;\n\n    copyright = {\n      projectName: userConfig.copyright.projectName?.trim() || siteName,\n      startYear,\n      ...(normalizedEndYear !== undefined ? { endYear: normalizedEndYear } : {}),\n    };\n  }\n\n  let resolvedFavicon: string | false;\n  let resolvedFaviconFallback: string | false = false;\n  if (userConfig.favicon === false) {\n    resolvedFavicon = false;\n  } else if (typeof userConfig.favicon === \"string\") {\n    resolvedFavicon = resolve(rootDir, userConfig.favicon);\n  } else {\n    const svgPath = join(publicDir, \"favicon.svg\");\n    const icoPath = join(publicDir, \"favicon.ico\");\n    if (existsSync(svgPath)) {\n      resolvedFavicon = svgPath;\n      if (existsSync(icoPath)) {\n        resolvedFaviconFallback = icoPath;\n      }\n    } else if (existsSync(icoPath)) {\n      resolvedFavicon = icoPath;\n    } else {\n      const letter = (siteName.charAt(0) || \"P\").toUpperCase();\n      resolvedFavicon = generateDefaultFavicon(letter);\n    }\n  }\n\n  let resolvedIcon: string | false;\n  if (userConfig.icon === false) {\n    resolvedIcon = false;\n  } else if (typeof userConfig.icon === \"string\") {\n    if (userConfig.icon.trimStart().startsWith(\"<\")) {\n      resolvedIcon = userConfig.icon;\n    } else {\n      const iconPath = resolve(rootDir, userConfig.icon);\n      resolvedIcon = existsSync(iconPath) ? readFileSync(iconPath, \"utf-8\") : false;\n    }\n  } else {\n    const letter = (siteName.charAt(0) || \"P\").toUpperCase();\n    resolvedIcon = [\n      '<svg class=\"doc-default-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 32 32\" aria-hidden=\"true\">',\n      '  <rect class=\"doc-default-icon-bg\" width=\"32\" height=\"32\" rx=\"6\"/>',\n      `  <text class=\"doc-default-icon-letter\" x=\"16\" y=\"24\" text-anchor=\"middle\" font-family=\"system-ui\" font-size=\"20\" font-weight=\"700\">${letter}</text>`,\n      \"</svg>\",\n    ].join(\"\");\n  }\n\n  const appleTouchIconPath = join(publicDir, \"apple-touch-icon.png\");\n  const resolvedAppleTouchIcon = existsSync(appleTouchIconPath) ? appleTouchIconPath : false;\n\n  const assets = new Map<string, string[]>();\n  if (userConfig.assets) {\n    for (const [outputPath, sources] of Object.entries(userConfig.assets)) {\n      const resolvedSources = sources.map((source) => resolve(rootDir, source));\n      assets.set(outputPath, resolvedSources);\n    }\n  }\n\n  let socialImage: string | undefined;\n  if (userConfig.theme?.socialImage) {\n    socialImage = userConfig.theme.socialImage;\n  } else {\n    for (const ext of [\"png\", \"jpg\", \"jpeg\"]) {\n      if (existsSync(join(publicDir, `og-image.${ext}`))) {\n        socialImage = `og-image.${ext}`;\n        break;\n      }\n    }\n  }\n\n  let editLink: ResolvedDocsConfig[\"editLink\"];\n  const rawEditLink =\n    userConfig.editLink === false\n      ? undefined\n      : (userConfig.editLink ??\n        (gitInfo?.repoUrl\n          ? { repo: gitInfo.repoUrl, branch: undefined, label: undefined }\n          : undefined));\n  if (rawEditLink) {\n    const repo = rawEditLink.repo.replace(/\\/+$/, \"\");\n    const branch = rawEditLink.branch ?? \"main\";\n    const label = rawEditLink.label ?? \"Edit this page\";\n    let editPattern: string;\n    if (repo.includes(\"gitlab.com\") || repo.includes(\"gitlab.\")) {\n      editPattern = `${repo}/-/edit/${branch}`;\n    } else if (repo.includes(\"bitbucket.org\") || repo.includes(\"bitbucket.\")) {\n      editPattern = `${repo}/src/${branch}`;\n    } else {\n      editPattern = `${repo}/edit/${branch}`;\n    }\n    editLink = { repo, branch, label, editPattern };\n  }\n\n  return {\n    rootDir,\n    contentDir,\n    outDir: overrides?.outDir ?? resolve(rootDir, userConfig.outDir ?? \"gh-pages\"),\n    publicDir,\n    basePath,\n    homeLink: userConfig.homeLink,\n    trailingSlash: userConfig.trailingSlash ?? false,\n    maintainer,\n    name: siteName,\n    title: userConfig.title ?? siteName,\n    description:\n      userConfig.description ?? pkg?.description ?? \"Documentation site powered by @pagesmith/docs\",\n    origin: userConfig.origin ?? gitInfo?.origin ?? pkg?.homepage ?? \"https://example.com\",\n    language: userConfig.language ?? \"en\",\n    footerLinks: userConfig.footerLinks ?? [],\n    footerText: userConfig.footerText,\n    copyright,\n    search: {\n      enabled: userConfig.search?.enabled ?? true,\n      showImages: userConfig.search?.showImages ?? false,\n      showSubResults: userConfig.search?.showSubResults ?? true,\n      pagefindFlags: userConfig.search?.pagefindFlags ?? [],\n    },\n    sidebar: {\n      collapsible: userConfig.sidebar?.collapsible ?? true,\n    },\n    favicon: resolvedFavicon,\n    icon: resolvedIcon,\n    faviconFallback: resolvedFaviconFallback,\n    appleTouchIcon: resolvedAppleTouchIcon,\n    editLink,\n    lastUpdated: userConfig.lastUpdated ?? true,\n    sitemap: userConfig.sitemap ?? true,\n    socialImage,\n    theme: userConfig.theme,\n    analytics: userConfig.analytics,\n    markdown: userConfig.markdown,\n    homeConfigFile: userConfig.home?.configFile\n      ? resolve(rootDir, userConfig.home.configFile)\n      : resolve(rootDir, contentDir, \"home.json5\"),\n    packages: userConfig.packages,\n    server: {\n      host: userConfig.server?.host ?? DEFAULT_SERVER_HOST,\n      devPort:\n        userConfig.server?.devPort !== undefined\n          ? normalizePort(userConfig.server.devPort, \"server.devPort\")\n          : DEFAULT_DEV_PORT,\n      previewPort:\n        userConfig.server?.previewPort !== undefined\n          ? normalizePort(userConfig.server.previewPort, \"server.previewPort\")\n          : DEFAULT_PREVIEW_PORT,\n      strictPort: userConfig.server?.strictPort ?? false,\n      logLevel: userConfig.server?.logLevel ?? DEFAULT_SERVER_LOG_LEVEL,\n    },\n    assets,\n    _userConfig: userConfig,\n    _zeroConfig: meta.zeroConfig === true,\n  };\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport JSON5 from \"json5\";\nimport { dirname, resolve } from \"path\";\nimport { fileURLToPath } from \"url\";\n\nexport function readJson5File<T>(filePath: string): T | undefined {\n  if (!existsSync(filePath)) return undefined;\n  return JSON5.parse(readFileSync(filePath, \"utf-8\")) as T;\n}\n\nexport function toTitleCase(value: string): string {\n  return value.replace(/[-_]/g, \" \").replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nexport function getPackageDir(): string {\n  try {\n    // Resolve from the package entry so this remains correct after bundling.\n    const entryPath = fileURLToPath(import.meta.resolve(\"@pagesmith/docs\"));\n    return resolve(dirname(entryPath), \"..\");\n  } catch {\n    return resolve(import.meta.dirname, \"..\", \"..\");\n  }\n}\n\nexport function getThemeRoot(): string {\n  return resolve(getPackageDir(), \"theme\");\n}\n\nexport function getThemeStylesEntry(): string {\n  return resolve(getThemeRoot(), \"styles/main.css\");\n}\n\nexport function getThemeRuntimeEntry(): string {\n  return resolve(getThemeRoot(), \"runtime/main.ts\");\n}\n\n/** Prefix a path with a base path, avoiding double slashes. */\nexport function withBase(basePath: string, path: string): string {\n  const base = basePath.replace(/\\/+$/, \"\");\n  if (!base) return path;\n  if (path === base || path.startsWith(base + \"/\")) return path;\n  return `${base}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`;\n}\n","import { basename, resolve } from \"path\";\nimport { existsSync } from \"fs\";\nimport type { ConfigValidationIssue, ResolvedDocsConfig } from \"./types\";\nimport { DocsConfigSchema } from \"../schemas/index.js\";\n\n/**\n * Validate a resolved docs config. Returns issues found.\n * Checks required fields, verifies referenced directories and asset files exist.\n */\nexport function validateConfig(config: ResolvedDocsConfig): ConfigValidationIssue[] {\n  const issues: ConfigValidationIssue[] = [];\n\n  const uc = config._userConfig;\n  const schemaResult = DocsConfigSchema.safeParse(uc ?? {});\n  if (!schemaResult.success) {\n    for (const issue of schemaResult.error.issues) {\n      const field = issue.path.length > 0 ? issue.path.join(\".\") : \"config\";\n      issues.push({\n        field,\n        message: issue.message,\n        severity: \"error\",\n      });\n    }\n  }\n  // In zero-config mode (no `pagesmith.config.*` file on disk) skip the\n  // \"missing field\" warnings — the user has not opted into a config file at\n  // all, so nagging about specific fields is just noise. Real users get the\n  // warnings as soon as they create even an empty config file.\n  if (!config._zeroConfig) {\n    const hasExplicitName = uc ? !!(uc.name || uc.title) : config.name !== basename(config.rootDir);\n    const hasExplicitTitle = uc\n      ? !!(uc.title || uc.name)\n      : config.title !== basename(config.rootDir);\n\n    if (!hasExplicitName) {\n      issues.push({\n        field: \"name\",\n        message: 'Missing \"name\" in pagesmith.config.json5 — using directory name as fallback.',\n        severity: \"warn\",\n      });\n    }\n\n    if (!hasExplicitTitle) {\n      issues.push({\n        field: \"title\",\n        message: 'Missing \"title\" in pagesmith.config.json5 — using directory name as fallback.',\n        severity: \"warn\",\n      });\n    }\n\n    if (config.description === \"Documentation site powered by @pagesmith/docs\") {\n      issues.push({\n        field: \"description\",\n        message: 'Missing \"description\" in pagesmith.config.json5 — using default placeholder.',\n        severity: \"warn\",\n      });\n    }\n\n    if (config.origin === \"https://example.com\") {\n      issues.push({\n        field: \"origin\",\n        message:\n          'Missing \"origin\" in pagesmith.config.json5 — canonical URLs will use https://example.com. Set this to your production URL.',\n        severity: \"warn\",\n      });\n    }\n  }\n\n  if (!existsSync(config.contentDir)) {\n    issues.push({\n      field: \"contentDir\",\n      message: `Content directory does not exist: ${config.contentDir}`,\n      severity: \"error\",\n    });\n  }\n\n  for (const [outputPath, sources] of config.assets) {\n    for (const sourcePath of sources) {\n      if (!existsSync(sourcePath)) {\n        issues.push({\n          field: `assets[\"${outputPath}\"]`,\n          message: `Asset source does not exist: ${sourcePath}`,\n          severity: \"error\",\n        });\n      }\n    }\n  }\n\n  if (typeof config.favicon === \"string\" && !existsSync(config.favicon)) {\n    issues.push({\n      field: \"favicon\",\n      message: `Favicon file does not exist: ${config.favicon}`,\n      severity: \"warn\",\n    });\n  }\n\n  if (config.theme?.layouts) {\n    for (const [layoutName, layoutPath] of Object.entries(config.theme.layouts)) {\n      const resolvedLayout = resolve(config.rootDir, layoutPath);\n      if (!existsSync(resolvedLayout)) {\n        issues.push({\n          field: `theme.layouts.${layoutName}`,\n          message: `Layout file does not exist: ${resolvedLayout}`,\n          severity: \"error\",\n        });\n      }\n    }\n  }\n\n  return issues;\n}\n\n/**\n * Log validation issues to console. Returns true if there are any errors (severity: 'error').\n */\nexport function reportConfigIssues(issues: ConfigValidationIssue[]): boolean {\n  let hasErrors = false;\n  for (const issue of issues) {\n    if (issue.severity === \"error\") {\n      console.error(`\\x1b[31m✗ [${issue.field}]\\x1b[0m ${issue.message}`);\n      hasErrors = true;\n    } else {\n      console.warn(`\\x1b[33m⚠ [${issue.field}]\\x1b[0m ${issue.message}`);\n    }\n  }\n  return hasErrors;\n}\n"],"mappings":"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"}