@demiurgejs/core 0.2.0-beta.5 → 0.2.0-beta.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +14 -0
  2. package/bin/demiurge.mjs +6 -0
  3. package/dist/chunks/{document-shell-9GPwtcTt.js → document-shell-C0aPrkhd.js} +2 -2
  4. package/dist/chunks/{document-shell-9GPwtcTt.js.map → document-shell-C0aPrkhd.js.map} +1 -1
  5. package/dist/chunks/image-CRerJ5BY.js +145 -0
  6. package/dist/chunks/image-CRerJ5BY.js.map +1 -0
  7. package/dist/chunks/{image-codec-Dh1POFhE.js → image-codec-CQ8Cwxwb.js} +2 -2
  8. package/dist/chunks/{image-codec-Dh1POFhE.js.map → image-codec-CQ8Cwxwb.js.map} +1 -1
  9. package/dist/chunks/{images-CG7ZzayG.js → images-QgdmLyQ3.js} +11 -11
  10. package/dist/chunks/{images-CG7ZzayG.js.map → images-QgdmLyQ3.js.map} +1 -1
  11. package/dist/chunks/{index-0MNiR_wo.js → index-LYve1rQp.js} +286 -351
  12. package/dist/chunks/index-LYve1rQp.js.map +1 -0
  13. package/dist/chunks/links-iU22QkCE.js +68 -0
  14. package/dist/chunks/links-iU22QkCE.js.map +1 -0
  15. package/dist/chunks/{plugin-BZauDxRY.js → plugin-bkP6WwrS.js} +13 -12
  16. package/dist/chunks/{plugin-BZauDxRY.js.map → plugin-bkP6WwrS.js.map} +1 -1
  17. package/dist/chunks/runtime-BH519j2t.js +294 -0
  18. package/dist/chunks/runtime-BH519j2t.js.map +1 -0
  19. package/dist/chunks/streaming-BlKlC3nw.js +427 -0
  20. package/dist/chunks/streaming-BlKlC3nw.js.map +1 -0
  21. package/dist/chunks/{testing-CUwGj2ie.js → testing-BEW1nchS.js} +645 -630
  22. package/dist/chunks/testing-BEW1nchS.js.map +1 -0
  23. package/dist/chunks/{vite-QoqrGl6f.js → vite-BADZA8Fl.js} +73 -70
  24. package/dist/chunks/vite-BADZA8Fl.js.map +1 -0
  25. package/dist/cli.d.ts +8 -2
  26. package/dist/cli.d.ts.map +1 -1
  27. package/dist/cli.js +186 -122
  28. package/dist/cli.js.map +1 -1
  29. package/dist/config/index.js +2 -2
  30. package/dist/config/types.d.ts +3 -1
  31. package/dist/config/types.d.ts.map +1 -1
  32. package/dist/config/validate.d.ts.map +1 -1
  33. package/dist/data/cache.d.ts +5 -0
  34. package/dist/data/cache.d.ts.map +1 -1
  35. package/dist/data/index.d.ts +1 -1
  36. package/dist/data/index.d.ts.map +1 -1
  37. package/dist/data/testing.d.ts.map +1 -1
  38. package/dist/data/testing.js +101 -67
  39. package/dist/data/testing.js.map +1 -1
  40. package/dist/data/tiered.d.ts.map +1 -1
  41. package/dist/edge/index.js +27 -26
  42. package/dist/edge/index.js.map +1 -1
  43. package/dist/edge/stores.d.ts.map +1 -1
  44. package/dist/index.d.ts +1 -1
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +126 -125
  47. package/dist/index.js.map +1 -1
  48. package/dist/internal/testing.js +2 -2
  49. package/dist/kv/index.js +7 -6
  50. package/dist/kv/index.js.map +1 -1
  51. package/dist/kv/store.d.ts.map +1 -1
  52. package/dist/node/http.d.ts +2 -0
  53. package/dist/node/http.d.ts.map +1 -1
  54. package/dist/node/index.d.ts +1 -1
  55. package/dist/node/index.d.ts.map +1 -1
  56. package/dist/node/index.js +12 -11
  57. package/dist/node/index.js.map +1 -1
  58. package/dist/node/serve.d.ts +4 -0
  59. package/dist/node/serve.d.ts.map +1 -1
  60. package/dist/redis/index.js +29 -28
  61. package/dist/redis/index.js.map +1 -1
  62. package/dist/redis/store.d.ts.map +1 -1
  63. package/dist/route/serialization.d.ts +4 -4
  64. package/dist/route/serialization.d.ts.map +1 -1
  65. package/dist/static/index.d.ts.map +1 -1
  66. package/dist/static/index.js +255 -255
  67. package/dist/static/index.js.map +1 -1
  68. package/dist/static/testing.d.ts +26 -0
  69. package/dist/static/testing.d.ts.map +1 -0
  70. package/dist/static/testing.js +76 -0
  71. package/dist/static/testing.js.map +1 -0
  72. package/dist/testing/index.d.ts +47 -0
  73. package/dist/testing/index.d.ts.map +1 -0
  74. package/dist/testing/index.js +99 -0
  75. package/dist/testing/index.js.map +1 -0
  76. package/dist/vercel/build.d.ts +31 -0
  77. package/dist/vercel/build.d.ts.map +1 -0
  78. package/dist/vercel/config.d.ts +15 -0
  79. package/dist/vercel/config.d.ts.map +1 -0
  80. package/dist/vercel/index.d.ts +7 -0
  81. package/dist/vercel/index.d.ts.map +1 -0
  82. package/dist/vercel/index.js +11 -0
  83. package/dist/vercel/index.js.map +1 -0
  84. package/dist/vercel/runtime.d.ts +29 -0
  85. package/dist/vercel/runtime.d.ts.map +1 -0
  86. package/dist/vite/index.js +1 -1
  87. package/package.json +13 -1
  88. package/dist/chunks/index-0MNiR_wo.js.map +0 -1
  89. package/dist/chunks/streaming-GYIsVTQH.js +0 -560
  90. package/dist/chunks/streaming-GYIsVTQH.js.map +0 -1
  91. package/dist/chunks/testing-CUwGj2ie.js.map +0 -1
  92. package/dist/chunks/vite-QoqrGl6f.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-BZauDxRY.js","sources":["../../src/package-name.ts","../../src/routing/generate.ts","../../src/vite/env-boundary.ts","../../src/vite/server-only-boundary.ts","../../src/vite/policy-verification.ts","../../src/inspect/redact.ts","../../src/vite/route-audit.ts","../../src/vite/plugin.ts"],"sourcesContent":["// The package name is the specifier that user code imports. Generated client\n// entries, server entries, and route type declarations use it. Page route\n// detection also compares application source with it. A mismatch then breaks\n// resolution in the consumer build.\n//\n// This is deliberately not the same thing as the many internal `demiurge`\n// strings elsewhere in the source. `__demiurge_data`, `virtual:demiurge/*`,\n// `demiurge-manifest.json`, and friends name the framework, not the package,\n// and they stay put if the registry name ever changes.\nexport const PACKAGE_NAME = \"@demiurgejs/core\";\n","import { mkdir, readdir, writeFile } from \"node:fs/promises\";\nimport { dirname, relative, resolve, sep } from \"node:path\";\nimport { PACKAGE_NAME } from \"../package-name\";\n\nexport type GenerateRoutesOptions = {\n locales?: readonly string[];\n localeNamespaces?: readonly string[];\n outputFile: string;\n routesDir: string;\n};\n\ntype RouteInfo = {\n contextMiddleware: number[];\n fileSegments: string[];\n importPath: string;\n pathVars: string[];\n pattern: string;\n};\n\ntype MiddlewareInfo = {\n file: string;\n fileSegments: string[];\n importPath: string;\n};\n\nexport async function generateRoutes(options: GenerateRoutesOptions) {\n const routeFiles = await findRouteFiles(options.routesDir);\n const middleware = routeFiles\n .map((file) => toMiddlewareInfo(options, file))\n .filter((value): value is MiddlewareInfo => Boolean(value));\n const routes = routeFiles\n .map((file) => toRouteInfo(options, file, middleware))\n .filter((route): route is RouteInfo => Boolean(route))\n .sort((a, b) => a.pattern.localeCompare(b.pattern));\n assertLocaleNamespaceCollisions(routes, options.localeNamespaces ?? []);\n\n const source = renderRoutesModule(routes, middleware, options.locales);\n\n await mkdir(dirname(options.outputFile), { recursive: true });\n await writeFile(options.outputFile, source);\n\n return {\n routes,\n source,\n };\n}\n\nfunction assertLocaleNamespaceCollisions(routes: RouteInfo[], namespaces: readonly string[]) {\n const localeSegments = new Set(namespaces.map((value) => value.toLowerCase()));\n for (const route of routes) {\n const [segment] = route.pattern.slice(1).split(\"/\");\n if (segment && !segment.startsWith(\"[\") && localeSegments.has(segment.toLowerCase())) {\n throw new Error(\n `Route \"${route.pattern}\" conflicts with the locale URL namespace \"${segment}\". Move the route or change the locale label.`,\n );\n }\n }\n}\n\nasync function findRouteFiles(directory: string) {\n const entries = await readdir(directory, {\n recursive: true,\n withFileTypes: true,\n });\n\n return entries\n .filter((entry) => entry.isFile() && /\\.tsx?$/.test(entry.name))\n .map((entry) => resolve(entry.parentPath, entry.name));\n}\n\nfunction toRouteInfo(\n options: GenerateRoutesOptions,\n file: string,\n middleware: MiddlewareInfo[],\n) {\n const relativePath = relative(options.routesDir, file).split(sep).join(\"/\");\n const fileSegments = relativePath.replace(/\\.tsx?$/, \"\").split(\"/\");\n const basename = fileSegments.at(-1);\n\n if (basename?.startsWith(\"@\")) {\n return null;\n }\n\n const urlSegments = fileSegments.flatMap((segment) => {\n if (isRouteGroupSegment(segment)) {\n return [];\n }\n\n if (segment === \"index\") {\n return [];\n }\n\n if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n return [segment];\n }\n\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n return [segment];\n }\n\n return [segment];\n });\n\n const pathVars = fileSegments.flatMap((segment) => {\n if (isRouteGroupSegment(segment)) {\n return [];\n }\n\n if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n return [segment.slice(4, -1)];\n }\n\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n return [segment.slice(1, -1)];\n }\n\n return [];\n });\n\n return {\n contextMiddleware: middleware\n .filter((entry) => isAttachedFileForRoute(entry.fileSegments, fileSegments))\n .map((entry) => middleware.indexOf(entry)),\n fileSegments,\n importPath: toImportPath(options.outputFile, file),\n pathVars,\n pattern: `/${urlSegments.join(\"/\")}`.replace(/\\/$/, \"\") || \"/\",\n };\n}\n\nfunction toMiddlewareInfo(\n options: GenerateRoutesOptions,\n file: string,\n): MiddlewareInfo | null {\n const relativePath = relative(options.routesDir, file).split(sep).join(\"/\");\n const fileSegments = relativePath.replace(/\\.tsx?$/, \"\").split(\"/\");\n\n if (fileSegments.at(-1) !== \"@middleware\") {\n return null;\n }\n\n return {\n file,\n fileSegments: fileSegments.slice(0, -1),\n importPath: toImportPath(options.outputFile, file),\n };\n}\n\nfunction toImportPath(outputFile: string, file: string) {\n let importPath = relative(dirname(outputFile), file)\n .split(sep)\n .join(\"/\")\n .replace(/\\.tsx?$/, \"\");\n\n if (!importPath.startsWith(\".\")) importPath = `./${importPath}`;\n return importPath;\n}\n\nfunction isAttachedFileForRoute(\n attachedFileSegments: string[],\n routeFileSegments: string[],\n) {\n return attachedFileSegments.every(\n (segment, index) => routeFileSegments[index] === segment,\n );\n}\n\nfunction isRouteGroupSegment(segment: string) {\n return segment.startsWith(\"(\") && segment.endsWith(\")\");\n}\n\nfunction renderRoutesModule(routes: RouteInfo[], middleware: MiddlewareInfo[], locales: readonly string[] = []) {\n return `// Generated by Demiurge. Do not edit by hand.\nimport \"${PACKAGE_NAME}\";\nimport type { MiddlewareContextOf, MutationMethodsOf, PathValue } from \"${PACKAGE_NAME}\";\n${middleware.map(renderMiddlewareImport).join(\"\\n\")}\n\n${middleware.map((_entry, index) => renderMiddlewareContextAlias(index)).join(\"\\n\")}\n\ndeclare module \"${PACKAGE_NAME}\" {\n interface RouteLocales {\n${locales.map((locale) => ` ${JSON.stringify(locale)}: true;`).join(\"\\n\")}\n }\n\n interface RoutePathVars {\n${routes.map(renderPathVarsEntry).join(\"\\n\")}\n }\n\n interface RouteConcretePaths {\n${routes.map(renderConcretePathEntry).join(\"\\n\")}\n }\n\n interface RouteRequestContexts {\n${routes.map(renderRequestContextEntry).join(\"\\n\")}\n }\n\n interface RouteMutationMethods {\n${routes.map(renderMutationMethodsEntry).join(\"\\n\")}\n }\n}\n\nexport {};\n`;\n}\n\nfunction renderMiddlewareImport(entry: MiddlewareInfo, index: number) {\n return `type __DemiurgeMiddleware${index} = typeof import(${JSON.stringify(entry.importPath)}) extends { middleware?: infer T } ? T : never;`;\n}\n\nfunction renderMiddlewareContextAlias(index: number) {\n return `type __DemiurgeMiddlewareContext${index} = MiddlewareContextOf<__DemiurgeMiddleware${index}>;`;\n}\n\nfunction renderPathVarsEntry(route: RouteInfo) {\n if (route.pathVars.length === 0) {\n return ` ${JSON.stringify(route.pattern)}: {};`;\n }\n\n const pathType = route.pathVars\n .map((name) => `${name}: PathValue`)\n .join(\"; \");\n\n return ` ${JSON.stringify(route.pattern)}: { ${pathType} };`;\n}\n\nfunction renderConcretePathEntry(route: RouteInfo) {\n return ` ${JSON.stringify(route.pattern)}: ${toConcretePathType(route.pattern)};`;\n}\n\nfunction renderRequestContextEntry(route: RouteInfo) {\n const contexts = route.contextMiddleware\n .map((index) => `__DemiurgeMiddlewareContext${index}`);\n const context = contexts.length > 0\n ? contexts.join(\" & \")\n : \"Record<never, never>\";\n\n return ` ${JSON.stringify(route.pattern)}: ${context};`;\n}\n\nfunction renderMutationMethodsEntry(route: RouteInfo) {\n return ` ${JSON.stringify(route.pattern)}: MutationMethodsOf<typeof import(${JSON.stringify(route.importPath)})>;`;\n}\n\nfunction toConcretePathType(pattern: string) {\n if (!pattern.includes(\"[\")) {\n return JSON.stringify(pattern);\n }\n\n const parts = pattern.split(/(\\[\\.\\.\\.[^\\]]+\\]|\\[[^\\]]+\\])/g).filter(Boolean);\n return `\\`${parts.map((part) => (part.startsWith(\"[\") ? \"${PathValue}\" : escapeTemplate(part))).join(\"\")}\\``;\n}\n\nfunction escapeTemplate(value: string) {\n return value.replace(/[`$\\\\]/g, \"\\\\$&\");\n}\n","import { parseAst } from \"vite\";\nimport type { EnvSchema } from \"../security/env\";\n\ntype AstNode = {\n [key: string]: unknown;\n end: number;\n start: number;\n type: string;\n};\n\nexport type EnvBoundaryFinding = {\n code: \"client-secret\" | \"client-server-only\";\n importPath: string[];\n key: string;\n module: string;\n};\n\n// The build inlines a client variable in the browser bundle. Every other\n// declared variable stays on the server. This module finds the modules that\n// the client entry reaches and that read a variable of the second group.\nexport function findServerEnvKeys(schema: EnvSchema | undefined) {\n const keys = new Map<string, { sensitive: boolean }>();\n\n for (const [key, variable] of Object.entries(schema ?? {})) {\n if (variable.client) continue;\n keys.set(key, { sensitive: variable.sensitive });\n }\n\n return keys;\n}\n\n// A module reads a variable when it names the variable in a position that\n// gives a value. An object key that declares the schema is not such a\n// position, and neither is the local name of an import.\nexport function findEnvKeyReferences(\n code: string,\n keys: Iterable<string>,\n): string[] {\n const names = new Set(keys);\n const found = new Set<string>();\n\n if (!names.size) return [];\n // A text test keeps the build away from a parse that finds nothing.\n if (![...names].some((name) => code.includes(name))) return [];\n\n visitNode(asAstNode(parseAst(code)), names, found);\n\n return [...found].sort();\n}\n\n// The diagnostic gives the path that makes the module part of the browser\n// bundle. The search returns the shortest such path.\nexport function findImportPath(\n entry: string,\n target: string,\n importsOf: (id: string) => readonly string[],\n): string[] | undefined {\n if (entry === target) return [entry];\n\n const visited = new Set([entry]);\n const queue: string[][] = [[entry]];\n\n while (queue.length) {\n // TYPE-EVIDENCE: the loop condition proves the queue holds a path. The assertion reads that path.\n const path = queue.shift() as string[];\n\n for (const next of importsOf(path[path.length - 1])) {\n if (visited.has(next)) continue;\n if (next === target) return [...path, next];\n visited.add(next);\n queue.push([...path, next]);\n }\n }\n\n return undefined;\n}\n\nexport function formatEnvBoundaryFindings(findings: EnvBoundaryFinding[]) {\n return [\n \"Demiurge stopped the build. Client code reads an environment variable that stays on the server.\",\n \"\",\n ...findings.flatMap(formatEnvBoundaryFinding),\n ].join(\"\\n\");\n}\n\nfunction formatEnvBoundaryFinding(finding: EnvBoundaryFinding) {\n return [\n ` variable: ${finding.key}`,\n ` module: ${finding.module}`,\n ` import path: ${finding.importPath.join(\" -> \")}`,\n finding.code === \"client-secret\"\n ? \" A secret variable never reaches the browser. Read the value on the server, then send the result through route data.\"\n : \" Declare the variable with client: true to put the value in the browser bundle.\",\n \"\",\n ];\n}\n\nfunction visitNode(node: AstNode, names: Set<string>, found: Set<string>) {\n if (node.type === \"ImportDeclaration\") return;\n if (node.type === \"ExportNamedDeclaration\" && !node.declaration) return;\n if (node.type === \"ExportAllDeclaration\") return;\n\n if (node.type === \"Identifier\") {\n match(node.name, names, found);\n return;\n }\n\n if (node.type === \"MemberExpression\") {\n visitValue(node.object, names, found);\n visitKey(node.property, Boolean(node.computed), names, found);\n return;\n }\n\n if (node.type === \"Property\" || node.type === \"PropertyDefinition\") {\n // A destructured name reads the value. An object key declares a name.\n if (node.computed || isPatternProperty(node)) {\n visitKey(node.key, Boolean(node.computed), names, found);\n }\n visitValue(node.value, names, found);\n return;\n }\n\n visitOwnChildren(node, names, found);\n}\n\n// A pattern property holds a read of the value. The parser gives such a\n// property a pattern node or an identifier as its value.\nfunction isPatternProperty(node: AstNode) {\n const value = asNode(node.value);\n return value?.type === \"Identifier\" || value?.type === \"ObjectPattern\" ||\n value?.type === \"ArrayPattern\" || value?.type === \"AssignmentPattern\";\n}\n\nfunction visitKey(\n value: unknown,\n computed: boolean,\n names: Set<string>,\n found: Set<string>,\n) {\n const key = asNode(value);\n if (!key) return;\n\n if (key.type === \"Literal\") {\n match(key.value, names, found);\n return;\n }\n\n if (!computed) {\n if (key.type === \"Identifier\") match(key.name, names, found);\n return;\n }\n\n visitValue(key, names, found);\n}\n\nfunction match(value: unknown, names: Set<string>, found: Set<string>) {\n if (typeof value === \"string\" && names.has(value)) found.add(value);\n}\n\nfunction visitOwnChildren(\n node: AstNode,\n names: Set<string>,\n found: Set<string>,\n) {\n for (const [key, child] of Object.entries(node)) {\n if (key === \"end\" || key === \"loc\" || key === \"start\" || key === \"type\") {\n continue;\n }\n visitValue(child, names, found);\n }\n}\n\nfunction visitValue(value: unknown, names: Set<string>, found: Set<string>) {\n if (!value || typeof value !== \"object\") return;\n\n if (Array.isArray(value)) {\n for (const item of value) visitValue(item, names, found);\n return;\n }\n\n const node = asNode(value);\n if (node) {\n visitNode(node, names, found);\n return;\n }\n\n // TYPE-EVIDENCE: the value was checked to be an object without a node type. The cast reads its members.\n for (const child of Object.values(value as Record<string, unknown>)) {\n visitValue(child, names, found);\n }\n}\n\nfunction asNode(value: unknown) {\n // TYPE-EVIDENCE: the type in value check confirms the value is an AST node. The cast asserts that node shape.\n return value && typeof value === \"object\" && \"type\" in value &&\n typeof (value as { type: unknown }).type === \"string\"\n ? value as AstNode\n : undefined;\n}\n\n// TYPE-EVIDENCE: rollup returns a generic program node. The local type is a loose access shape.\nfunction asAstNode(value: unknown): AstNode {\n // TYPE-EVIDENCE: the caller passes a rollup program node. The cast labels it with the loose access shape.\n return value as AstNode;\n}\n","import { parseAst } from \"vite\";\n\ntype AstNode = {\n [key: string]: unknown;\n end: number;\n start: number;\n type: string;\n};\n\nexport type ServerOnlyBoundaryFinding = {\n importPath: string[];\n module: string;\n};\n\n// A module that imports one of these specifiers declares that a build must\n// keep it off the browser. The community package server-only uses the same\n// bare specifier, so an application that already uses that package keeps the\n// same protection under Demiurge.\nconst serverOnlyMarkerSpecifiers = new Set([\n \"@demiurgejs/core/server-only\",\n \"server-only\",\n]);\n\n// A module imports the marker through a static import, a re-export, or a\n// dynamic import. A text test keeps the build away from a parse that finds\n// nothing.\nexport function importsServerOnlyMarker(code: string): boolean {\n if (!code.includes(\"server-only\")) return false;\n\n return findsMarkerImport(asAstNode(parseAst(code)));\n}\n\nexport function formatServerOnlyBoundaryFindings(\n findings: ServerOnlyBoundaryFinding[],\n) {\n return [\n \"Demiurge stopped the build. A browser bundle reaches a module marked server-only.\",\n \"\",\n ...findings.flatMap(formatServerOnlyBoundaryFinding),\n ].join(\"\\n\");\n}\n\n// The development server transforms a browser request before it can find the\n// import path from a client entry. The message names the module and the\n// repair instead.\nexport function formatServerOnlyDevError(module: string) {\n return `Demiurge stopped the development server. The browser requested ${module}, and this module is marked server-only.\n\nKeep this module out of client code. Move the server logic to a module that no client module imports.`;\n}\n\nfunction formatServerOnlyBoundaryFinding(finding: ServerOnlyBoundaryFinding) {\n return [\n ` module: ${finding.module}`,\n ` import path: ${finding.importPath.join(\" -> \")}`,\n \" Keep this module out of client code. Move the server logic to a module that no client module imports.\",\n \"\",\n ];\n}\n\nfunction findsMarkerImport(ast: AstNode): boolean {\n let found = false;\n\n walkAst(ast, (node) => {\n if (found) return;\n\n if (\n (node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportAllDeclaration\" ||\n node.type === \"ImportExpression\") &&\n isMarkerSource(node.source)\n ) {\n found = true;\n }\n });\n\n return found;\n}\n\nfunction isMarkerSource(value: unknown): boolean {\n const node = asNode(value);\n return node?.type === \"Literal\" &&\n typeof node.value === \"string\" &&\n serverOnlyMarkerSpecifiers.has(node.value);\n}\n\nfunction walkAst(value: unknown, visit: (node: AstNode) => void) {\n if (!value || typeof value !== \"object\") return;\n if (Array.isArray(value)) {\n for (const item of value) walkAst(item, visit);\n return;\n }\n\n // TYPE-EVIDENCE: the value was checked to be an object. The cast adds the loose AST node shape.\n const node = value as Partial<AstNode>;\n if (typeof node.type !== \"string\") return;\n // TYPE-EVIDENCE: the type field check above confirms the value is an AST node. The cast asserts that node shape.\n visit(node as AstNode);\n for (const [key, child] of Object.entries(node)) {\n if (!new Set([\"end\", \"loc\", \"start\", \"type\"]).has(key)) {\n walkAst(child, visit);\n }\n }\n}\n\nfunction asNode(value: unknown) {\n // TYPE-EVIDENCE: the type in value check confirms the value is an AST node. The cast asserts that node shape.\n return value && typeof value === \"object\" && \"type\" in value\n ? value as AstNode\n : undefined;\n}\n\n// TYPE-EVIDENCE: rollup returns a generic program node. The local type is a loose access shape.\nfunction asAstNode(value: unknown): AstNode {\n // TYPE-EVIDENCE: the caller passes a rollup program node. The cast labels it with the loose access shape.\n return value as AstNode;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename, dirname, join, relative, sep } from \"node:path\";\nimport { parseAst, transformWithEsbuild } from \"vite\";\nimport type { HttpMethod } from \"../route\";\nimport {\n createSecurityHeaders,\n getBodySizeException,\n isSecurityException,\n resolveCsp,\n resolveMaxBodySize,\n security,\n validateCorsPolicy,\n validateRateLimitPolicy,\n DEFAULT_MAX_BODY_SIZE,\n parseBodySize,\n type ContentSecurityPolicy,\n type CorsPolicy,\n type RoutePolicy,\n type RouteSecurityPolicy,\n type SecurityPolicy,\n type StaticPolicyFindingCode,\n} from \"../security\";\nimport { PACKAGE_NAME } from \"../package-name\";\nimport { isPlainObject } from \"../type-guards\";\n\ntype AstNode = {\n [key: string]: unknown;\n end: number;\n start: number;\n type: string;\n};\n\n// TYPE-EVIDENCE: rollup returns a generic program node. The local type is a loose access shape.\nfunction asAstNode(value: unknown): AstNode {\n // TYPE-EVIDENCE: the caller passes a rollup program node. The cast labels it with the loose access shape.\n return value as AstNode;\n}\n\nexport type StaticPolicyFinding = {\n code: StaticPolicyFindingCode;\n exportName?: string;\n file: string;\n message: string;\n severity: \"error\" | \"warning\";\n};\n\nexport type RouteFileInspection = {\n /** The statically provable access state of the route policy. */\n accessState: RouteAccessState;\n /** `true` when the file exports at least one HTTP method capability. */\n declaresRoute: boolean;\n /**\n * `true` when the file declares a document policy, and also when the policy\n * expression is not statically readable. An unreadable expression is not\n * evidence of an absent policy.\n */\n declaresDocumentPolicy: boolean;\n /** The statically provable CSP state of the route policy. */\n documentCspState: DocumentCspState;\n declaresPageRoute: boolean;\n file: string;\n findings: StaticPolicyFinding[];\n /** The HTTP methods that the file exports, in a stable order. */\n methods: HttpMethod[];\n};\n\nexport type DocumentCspState = \"present\" | \"false\" | \"absent\" | \"unknown\";\n\n/**\n * `declared` means the file states access. `unknown` means the expression is\n * not statically readable, which is not evidence of an absent declaration.\n */\nexport type RouteAccessState = \"declared\" | \"absent\" | \"unknown\";\n\ntype ExtractedCapability = {\n cors?: CorsPolicy;\n security?: RouteSecurityPolicy;\n};\n\ntype ExtractedRouteModule = {\n accessState: RouteAccessState;\n capabilities: Partial<Record<HttpMethod, ExtractedCapability>>;\n declaredMethods: Set<HttpMethod>;\n declaresDocumentPolicy: boolean;\n documentCspState: DocumentCspState;\n policy?: RoutePolicy;\n};\n\nconst httpMethods = [\n \"GET\",\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\",\n \"OPTIONS\",\n \"HEAD\",\n] as const satisfies readonly HttpMethod[];\nconst responseHelpers = new Set([\n \"mutation\",\n \"html\",\n \"json\",\n \"jsonl\",\n \"notFound\",\n \"redirect\",\n \"response\",\n \"sse\",\n \"stream\",\n \"text\",\n]);\n\nexport async function verifyRoutePolicyFile(file: string) {\n return (await inspectRouteFile(file)).findings;\n}\n\nexport async function inspectRouteFile(\n file: string,\n): Promise<RouteFileInspection> {\n const source = await readFile(file, \"utf8\");\n const extracted = await extractRouteModuleSource(source, file);\n\n const attached = basename(file).startsWith(\"@\");\n\n return {\n accessState: extracted.accessState,\n declaresDocumentPolicy: extracted.declaresDocumentPolicy,\n documentCspState: extracted.documentCspState,\n // An attached file owns no address, so it never declares a route.\n declaresRoute: !attached && extracted.declaredMethods.size > 0,\n declaresPageRoute: !attached && declaresPageRoute(source),\n file,\n findings: validateExtractedRouteModule(extracted, file),\n methods: attached\n ? []\n : httpMethods.filter((method) => extracted.declaredMethods.has(method)),\n };\n}\n\nexport async function verifyRoutePolicySource(source: string, file: string) {\n return validateExtractedRouteModule(\n await extractRouteModuleSource(source, file),\n file,\n );\n}\n\nasync function extractRouteModuleSource(source: string, file: string) {\n const loader = file.endsWith(\".tsx\") ? \"tsx\" : \"ts\";\n const transformed = await transformWithEsbuild(source, file, {\n format: \"esm\",\n loader,\n target: \"esnext\",\n });\n\n return extractRouteModule(transformed.code);\n}\n\n// A route with no document policy sends no security headers. The application\n// still works, so nothing else reports the gap. This check reads the policy\n// cascade of the route tree and names each route that no document policy\n// covers. A page route and an application-owned fallback document, `@not-\n// found.tsx` and the route error document, both render HTML, so both need an\n// inherited policy.\nexport function auditDocumentPolicyCoverage(\n routesDir: string,\n inspections: readonly RouteFileInspection[],\n): StaticPolicyFinding[] {\n const policies = inspections.filter((inspection) => isPolicyFile(inspection.file));\n\n const findings: StaticPolicyFinding[] = [];\n\n for (const inspection of inspections) {\n if (\n !inspection.declaresPageRoute &&\n !isFallbackDocumentFile(inspection.file)\n ) {\n continue;\n }\n const applicable = applicablePolicies(\n routesDir,\n dirname(inspection.file),\n policies,\n );\n const state = resolveDocumentCspState(\n applicable,\n inspection.documentCspState,\n );\n if (state !== \"absent\") {\n continue;\n }\n\n findings.push({\n code: \"document-policy-missing\",\n file: inspection.file,\n message: describeMissingDocumentPolicy(routesDir, applicable),\n severity: \"error\",\n });\n }\n\n return findings;\n}\n\n// A route that inherits no access declaration is denied at request time. The\n// build finds the gap where the policy cascade is statically readable, so a\n// developer sees the missing declaration before the application runs.\nexport function auditRouteAccessCoverage(\n routesDir: string,\n inspections: readonly RouteFileInspection[],\n): StaticPolicyFinding[] {\n const policies = inspections.filter((inspection) =>\n isPolicyFile(inspection.file)\n );\n const findings: StaticPolicyFinding[] = [];\n\n for (const inspection of inspections) {\n if (!inspection.declaresRoute) {\n continue;\n }\n\n const state = resolveRouteAccessState(\n routesDir,\n dirname(inspection.file),\n inspection.accessState,\n policies,\n );\n\n if (state !== \"absent\") {\n continue;\n }\n\n findings.push({\n code: \"access-declaration-missing\",\n file: inspection.file,\n message:\n \"This route inherits no access declaration, so the request pipeline denies each request. Add access: { public: true } for a public route, or access: { authorize } to this route or an ancestor @policy.ts file.\",\n severity: \"error\",\n });\n }\n\n return findings;\n}\n\nfunction resolveRouteAccessState(\n routesDir: string,\n routeDirectory: string,\n routeState: RouteAccessState,\n policies: readonly RouteFileInspection[],\n) {\n const applicable = policies.filter((inspection) =>\n isSameOrAbove(dirname(inspection.file), routeDirectory) &&\n isSameOrAbove(routesDir, dirname(inspection.file))\n );\n\n let state: RouteAccessState = routeState;\n\n for (const policy of applicable) {\n if (policy.accessState !== \"absent\") {\n state = policy.accessState;\n }\n }\n\n return state;\n}\n\n// `@not-found.tsx` and `@error.tsx` are application-owned fallback documents.\n// Each renders an HTML response the same way a page route does, so the build\n// requires the same document policy coverage for both.\nfunction isFallbackDocumentFile(file: string) {\n return /^@(?:not-found|error)\\.tsx?$/.test(basename(file));\n}\n\nfunction describeMissingDocumentPolicy(\n routesDir: string,\n applicable: readonly RouteFileInspection[],\n): string {\n const exception =\n \"To accept a document without a Content-Security-Policy, declare csp \" +\n \"with a value of false and a reason.\";\n const nearest = applicable.at(-1);\n\n if (nearest) {\n return `This route inherits no document policy. ${nearest.file} does not declare one. Add document: security.strict() to ${nearest.file}. ${exception}`;\n }\n\n const rootPolicyFile = join(routesDir, \"@policy.ts\");\n return `This route inherits no document policy. No @policy.ts file exists above it. Create ${rootPolicyFile} with document: security.strict(). ${exception}`;\n}\n\nfunction applicablePolicies(\n routesDir: string,\n routeDirectory: string,\n policies: readonly RouteFileInspection[],\n) {\n return policies\n .filter((inspection) =>\n isSameOrAbove(dirname(inspection.file), routeDirectory) &&\n isSameOrAbove(routesDir, dirname(inspection.file)),\n )\n .sort((left, right) =>\n dirname(left.file).length - dirname(right.file).length ||\n left.file.localeCompare(right.file)\n );\n}\n\nfunction resolveDocumentCspState(\n applicable: readonly RouteFileInspection[],\n routeState: DocumentCspState,\n) {\n let state: DocumentCspState = \"absent\";\n for (const policy of applicable) {\n state = mergeDocumentCspState(state, policy.documentCspState);\n }\n return mergeDocumentCspState(state, routeState);\n}\n\nfunction mergeDocumentCspState(\n base: DocumentCspState,\n override: DocumentCspState,\n): DocumentCspState {\n if (override === \"absent\") return base;\n return override;\n}\n\nfunction isPolicyFile(file: string) {\n return /^@policy\\.tsx?$/.test(basename(file));\n}\n\nfunction isSameOrAbove(directory: string, routesDir: string) {\n const distance = relative(directory, routesDir);\n return distance === \"\" ||\n (distance !== \"..\" && !distance.startsWith(`..${sep}`) &&\n !distance.startsWith(sep));\n}\n\n// Escaped because a package name may contain `.`, which the regex would\n// otherwise read as a wildcard.\nconst PACKAGE_NAME_PATTERN = PACKAGE_NAME.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nconst DEMIURGE_NAMED_IMPORT = new RegExp(\n `import\\\\s*\\\\{([^}]*)\\\\}\\\\s*from\\\\s*[\"']${PACKAGE_NAME_PATTERN}[\"']`,\n \"g\",\n);\n\n// The plugin cannot evaluate route modules during the build. Therefore, page\n// detection reads the source. It checks the import, not only the word. An API\n// application can call `db.users.page(2)` without serving an HTML document.\n// Only a page route imports `page` from the framework package.\nexport function declaresPageRoute(source: string) {\n const locals = [...source.matchAll(DEMIURGE_NAMED_IMPORT)].flatMap((match) =>\n match[1].split(\",\").flatMap((binding) => {\n const [imported, local] = binding.trim().split(/\\s+as\\s+/);\n\n // `import type { page }` cannot be called, and an alias renames what the\n // call site looks like.\n return imported.replace(/^type\\s+/, \"\") === \"page\"\n ? [local ?? imported]\n : [];\n }),\n );\n\n if (locals.length === 0) {\n return false;\n }\n\n // Strip the import statements first so the binding list is not itself\n // mistaken for a call.\n const body = source.replace(DEMIURGE_NAMED_IMPORT, \"\");\n\n return locals.some((local) => new RegExp(`\\\\b${local}\\\\s*\\\\(`).test(body));\n}\n\nfunction extractRouteModule(code: string): ExtractedRouteModule {\n const ast = asAstNode(parseAst(code));\n const imports = collectCoreImports(ast);\n const constants = collectConstants(ast);\n const declarations = collectVariableInitializers(ast);\n const exports = collectNamedExports(ast);\n const capabilities: ExtractedRouteModule[\"capabilities\"] = {};\n const declaredMethods = new Set<HttpMethod>();\n let accessState: RouteAccessState = \"absent\";\n let declaresDocumentPolicy = false;\n let documentCspState: DocumentCspState = \"absent\";\n let policy: RoutePolicy | undefined;\n\n for (const [exportName, localName] of exports) {\n const initializer = declarations.get(localName);\n\n if (exportName === \"policy\") {\n accessState = initializer\n ? extractAccessState(initializer, imports, constants)\n : \"unknown\";\n documentCspState = initializer\n ? extractDocumentCspState(initializer, imports, constants)\n : \"unknown\";\n declaresDocumentPolicy = documentCspState !== \"absent\";\n if (initializer) {\n policy = extractRoutePolicy(initializer, imports, constants);\n }\n continue;\n }\n if (!isHttpMethod(exportName)) continue;\n declaredMethods.add(exportName);\n if (!initializer) continue;\n\n const capability = extractCapability(initializer, imports, constants);\n if (capability) capabilities[exportName] = capability;\n }\n\n return {\n accessState,\n capabilities,\n declaredMethods,\n declaresDocumentPolicy,\n documentCspState,\n policy,\n };\n}\n\n// The access declaration holds a function, so the build cannot evaluate it.\n// The check therefore proves only that the `access` property is present.\nfunction extractAccessState(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): RouteAccessState {\n if (node.type === \"Identifier\") {\n if (node.name === \"undefined\") return \"absent\";\n const value = constants.get(String(node.name));\n if (value === undefined && !constants.has(String(node.name))) {\n return \"unknown\";\n }\n if (!isPlainObject(value)) return \"unknown\";\n return Object.prototype.hasOwnProperty.call(value, \"access\")\n ? \"declared\"\n : \"absent\";\n }\n\n if (node.type === \"CallExpression\") {\n const localName = identifierName(node.callee);\n if (localName && imports.get(localName) === \"defineRoutePolicy\") {\n const argument = asNodeArray(node.arguments)[0];\n return argument\n ? extractAccessState(argument, imports, constants)\n : \"unknown\";\n }\n return \"unknown\";\n }\n\n if (node.type !== \"ObjectExpression\") return \"unknown\";\n\n for (const property of asNodeArray(node.properties)) {\n if (property.type === \"SpreadElement\") return \"unknown\";\n if (property.type !== \"Property\") continue;\n if (property.computed) return \"unknown\";\n if (propertyName(property.key) !== \"access\") continue;\n const value = asNode(property.value);\n if (value?.type === \"Identifier\" && value.name === \"undefined\") {\n return \"absent\";\n }\n return \"declared\";\n }\n\n return \"absent\";\n}\n\nfunction extractDocumentCspState(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): DocumentCspState {\n if (node.type === \"Identifier\") {\n if (node.name === \"undefined\") return \"absent\";\n const value = constants.get(String(node.name));\n return value === undefined && !constants.has(String(node.name))\n ? \"unknown\"\n : extractDocumentCspStateFromValue(value);\n }\n\n if (node.type === \"CallExpression\") {\n const localName = identifierName(node.callee);\n if (localName && imports.get(localName) === \"defineRoutePolicy\") {\n const argument = asNodeArray(node.arguments)[0];\n return argument\n ? extractDocumentCspState(argument, imports, constants)\n : \"unknown\";\n }\n\n const callee = asNode(node.callee);\n if (callee?.type === \"MemberExpression\") {\n const objectName = identifierName(callee.object);\n const preset = propertyName(callee.property);\n if (objectName && imports.get(objectName) === \"security\" && preset) {\n return extractPresetCspState(preset, asNodeArray(node.arguments)[0], constants);\n }\n }\n return \"unknown\";\n }\n\n if (node.type !== \"ObjectExpression\") return \"unknown\";\n\n for (const property of asNodeArray(node.properties)) {\n if (property.type === \"SpreadElement\") return \"unknown\";\n if (property.type !== \"Property\") continue;\n if (property.computed) return \"unknown\";\n if (propertyName(property.key) !== \"document\") continue;\n return extractDocumentSecurityCspState(\n asNode(property.value),\n imports,\n constants,\n );\n }\n\n return \"absent\";\n}\n\nfunction extractDocumentSecurityCspState(\n node: AstNode | undefined,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): DocumentCspState {\n if (!node) return \"unknown\";\n if (node.type === \"UnaryExpression\" && node.operator === \"void\") {\n return \"absent\";\n }\n if (node.type === \"Identifier\") {\n if (node.name === \"undefined\") return \"absent\";\n const value = constants.get(String(node.name));\n return value === undefined && !constants.has(String(node.name))\n ? \"unknown\"\n : extractDocumentCspStateFromValue(value);\n }\n if (node.type === \"CallExpression\") {\n const callee = asNode(node.callee);\n if (callee?.type !== \"MemberExpression\") return \"unknown\";\n const objectName = identifierName(callee.object);\n const preset = propertyName(callee.property);\n if (!objectName || imports.get(objectName) !== \"security\" || !preset) {\n return \"unknown\";\n }\n return extractPresetCspState(preset, asNodeArray(node.arguments)[0], constants);\n }\n if (node.type !== \"ObjectExpression\") return \"unknown\";\n\n for (const property of asNodeArray(node.properties)) {\n if (property.type === \"SpreadElement\" || property.computed) return \"unknown\";\n if (property.type !== \"Property\") continue;\n if (propertyName(property.key) !== \"csp\") continue;\n const value = asNode(property.value);\n if (!value) return \"unknown\";\n if (value.type === \"Literal\") {\n if (value.value === false) return \"false\";\n if (value.value === undefined || value.value === null) return \"absent\";\n return \"present\";\n }\n if (value.type === \"Identifier\") {\n const literal = evaluateLiteral(value, constants);\n if (literal === unresolved) return \"unknown\";\n return extractCspValueState(literal);\n }\n if (value.type === \"ObjectExpression\") {\n const literal = evaluateLiteral(value, constants);\n if (literal === unresolved) return \"unknown\";\n return extractCspValueState(literal);\n }\n if (value.type === \"ArrayExpression\") {\n return \"present\";\n }\n return \"unknown\";\n }\n\n return \"absent\";\n}\n\nfunction extractPresetCspState(\n preset: string,\n optionsNode: AstNode | undefined,\n constants: Map<string, unknown>,\n): DocumentCspState {\n const defaultState = preset === \"api\" ? \"absent\" :\n preset === \"strict\" || preset === \"static\" || preset === \"crossOriginIsolated\"\n ? \"present\"\n : \"unknown\";\n if (!optionsNode) return defaultState;\n if (optionsNode.type === \"Identifier\") {\n const options = evaluateLiteral(optionsNode, constants);\n if (options === unresolved) return \"unknown\";\n return mergePresetCspState(defaultState, extractCspOptionState(options));\n }\n if (optionsNode.type !== \"ObjectExpression\") return \"unknown\";\n for (const property of asNodeArray(optionsNode.properties)) {\n if (property.type === \"SpreadElement\" || property.computed) return \"unknown\";\n if (property.type !== \"Property\") continue;\n if (propertyName(property.key) !== \"csp\") continue;\n const value = evaluateLiteral(asNode(property.value), constants);\n if (value === unresolved) return \"unknown\";\n return mergePresetCspState(defaultState, extractCspValueState(value));\n }\n return defaultState;\n}\n\nfunction extractCspOptionState(value: unknown): DocumentCspState {\n if (!isPlainObject(value)) return value === undefined ? \"absent\" : \"unknown\";\n if (!Object.prototype.hasOwnProperty.call(value, \"csp\")) return \"absent\";\n return extractCspValueState(value.csp);\n}\n\nfunction extractCspValueState(value: unknown): DocumentCspState {\n if (value === false) return \"false\";\n if (isSecurityException(value)) return value.value === false ? \"false\" : \"unknown\";\n if (value === undefined || value === null) return \"absent\";\n if (isPlainObject(value) || Array.isArray(value)) return \"present\";\n return \"unknown\";\n}\n\nfunction mergePresetCspState(\n preset: DocumentCspState,\n override: DocumentCspState,\n): DocumentCspState {\n if (override === \"absent\") return preset;\n return override;\n}\n\nfunction extractDocumentCspStateFromValue(value: unknown): DocumentCspState {\n if (value === undefined) return \"absent\";\n if (!isPlainObject(value)) return \"unknown\";\n if (!Object.prototype.hasOwnProperty.call(value, \"document\")) return \"absent\";\n return extractCspOptionState(value.document);\n}\n\nfunction collectVariableInitializers(ast: AstNode) {\n const declarations = new Map<string, AstNode>();\n for (const statement of asNodeArray(ast.body)) {\n const declaration = statement.type === \"ExportNamedDeclaration\"\n ? asNode(statement.declaration)\n : statement;\n if (declaration?.type !== \"VariableDeclaration\") continue;\n for (const declarator of asNodeArray(declaration.declarations)) {\n const name = identifierName(declarator.id);\n const initializer = asNode(declarator.init);\n if (name && initializer) declarations.set(name, initializer);\n }\n }\n return declarations;\n}\n\nfunction collectNamedExports(ast: AstNode) {\n const exports = new Map<string, string>();\n for (const statement of asNodeArray(ast.body)) {\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n const declaration = asNode(statement.declaration);\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of asNodeArray(declaration.declarations)) {\n const name = identifierName(declarator.id);\n if (name) exports.set(name, name);\n }\n }\n for (const specifier of asNodeArray(statement.specifiers)) {\n const exported = propertyName(specifier.exported);\n const local = propertyName(specifier.local);\n if (exported && local) exports.set(exported, local);\n }\n }\n return exports;\n}\n\nfunction extractCapability(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n) {\n if (node.type !== \"CallExpression\") return undefined;\n const localName = identifierName(node.callee);\n const helper = localName ? imports.get(localName) : undefined;\n\n if (!helper || !responseHelpers.has(helper)) return undefined;\n const arguments_ = asNodeArray(node.arguments);\n const optionsNode = helper === \"mutation\" ? arguments_[0] : arguments_[1];\n if (!optionsNode) return {};\n const cors = evaluateObjectProperty(optionsNode, \"cors\", constants);\n const securityPolicy = evaluateObjectProperty(\n optionsNode,\n \"security\",\n constants,\n );\n\n // TYPE-EVIDENCE: the isPlainObject checks confirm the values are plain objects. The casts label them as the capability policy types.\n return {\n cors: isPlainObject(cors) ? cors as CorsPolicy : undefined,\n security: isPlainObject(securityPolicy)\n ? securityPolicy as RouteSecurityPolicy\n : undefined,\n } satisfies ExtractedCapability;\n}\n\nfunction evaluateObjectProperty(\n node: AstNode,\n property: string,\n constants: Map<string, unknown>,\n) {\n if (node.type === \"Identifier\") {\n const value = constants.get(String(node.name));\n return isPlainObject(value) ? value[property] : unresolved;\n }\n if (node.type !== \"ObjectExpression\") return unresolved;\n\n let value: unknown = undefined;\n for (const item of asNodeArray(node.properties)) {\n if (item.type !== \"Property\" || item.computed) return unresolved;\n if (propertyName(item.key) !== property) continue;\n value = evaluateLiteral(asNode(item.value), constants);\n }\n\n return value;\n}\n\nfunction extractRoutePolicy(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): RoutePolicy | undefined {\n if (node.type === \"CallExpression\") {\n const localName = identifierName(node.callee);\n if (localName && imports.get(localName) === \"defineRoutePolicy\") {\n const argument = asNodeArray(node.arguments)[0];\n return argument\n ? extractRoutePolicy(argument, imports, constants)\n : undefined;\n }\n }\n\n if (node.type !== \"ObjectExpression\") {\n const value = evaluateLiteral(node, constants);\n // TYPE-EVIDENCE: the isPlainObject check confirms the value is a plain object. The cast labels it as a route policy.\n return isPlainObject(value) ? value as RoutePolicy : undefined;\n }\n\n const result: Record<string, unknown> = {};\n for (const property of asNodeArray(node.properties)) {\n if (property.type !== \"Property\" || property.computed) return undefined;\n const name = propertyName(property.key);\n const valueNode = asNode(property.value);\n if (!name || !valueNode) return undefined;\n\n if (name === \"document\") {\n const document = extractSecurityPolicy(valueNode, imports, constants);\n if (!document) return undefined;\n result.document = document;\n continue;\n }\n\n const value = evaluateLiteral(valueNode, constants);\n if (value === unresolved) return undefined;\n result[name] = value;\n }\n\n // TYPE-EVIDENCE: the loop above copied each property from the object expression. The cast labels the accumulated record as a route policy.\n return result as RoutePolicy;\n}\n\nfunction extractSecurityPolicy(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): SecurityPolicy | undefined {\n if (node.type !== \"CallExpression\") {\n const value = evaluateLiteral(node, constants);\n // TYPE-EVIDENCE: the isPlainObject check confirms the value is a plain object. The cast labels it as a security policy.\n return isPlainObject(value) ? value as SecurityPolicy : undefined;\n }\n\n const callee = asNode(node.callee);\n if (callee?.type !== \"MemberExpression\") return undefined;\n const objectName = identifierName(callee.object);\n const preset = propertyName(callee.property);\n if (!objectName || imports.get(objectName) !== \"security\" || !preset) {\n return undefined;\n }\n\n const options = evaluateLiteral(asNodeArray(node.arguments)[0], constants);\n // The options expression could not be statically evaluated (it depends on\n // a runtime value). The `unresolved` sentinel must not pass through to a\n // security preset because it would verify a policy that was never computed.\n // Treat this call as unverifiable, matching `unresolved` handling in\n // extractRoutePolicy above.\n if (options === unresolved) return undefined;\n if (options !== undefined && !isPlainObject(options)) {\n return undefined;\n }\n\n if (preset === \"api\") {\n // TYPE-EVIDENCE: the guards above return undefined unless options is a plain object or undefined. The cast labels the record as a security policy for the preset helper.\n return security.api(options as SecurityPolicy | undefined);\n }\n if (preset === \"crossOriginIsolated\") {\n // TYPE-EVIDENCE: the guards above return undefined unless options is a plain object or undefined. The cast labels the record as a security policy for the preset helper.\n return security.crossOriginIsolated(options as SecurityPolicy | undefined);\n }\n if (preset === \"static\") {\n // TYPE-EVIDENCE: the guards above return undefined unless options is a plain object or undefined. The cast labels the record as a security policy for the preset helper.\n return security.static(options as SecurityPolicy | undefined);\n }\n if (preset === \"strict\") {\n // TYPE-EVIDENCE: the guards above return undefined unless options is a plain object or undefined. The cast labels the record as a security policy for the preset helper.\n return security.strict(options as SecurityPolicy | undefined);\n }\n return undefined;\n}\n\nfunction validateExtractedRouteModule(\n routeModule: ExtractedRouteModule,\n file: string,\n) {\n const findings: StaticPolicyFinding[] = [];\n const availableMethods = new Set(routeModule.declaredMethods);\n if (availableMethods.has(\"GET\")) availableMethods.add(\"HEAD\");\n // Demiurge answers preflight itself, so a route never exports an OPTIONS\n // capability to serve one. Listing OPTIONS is a habit carried in from other\n // CORS configuration, and rejecting it would fail a build over nothing.\n availableMethods.add(\"OPTIONS\");\n\n // TYPE-EVIDENCE: Object.entries returns the capability map entries as string keyed pairs. The cast narrows the keys to HTTP methods and the values to capability types.\n for (const [exportName, capability] of Object.entries(\n routeModule.capabilities,\n ) as Array<[HttpMethod, ExtractedCapability]>) {\n if (capability.cors) {\n try {\n validateCorsPolicy(capability.cors);\n } catch (error) {\n findings.push(finding(\n \"cors-invalid\",\n file,\n errorMessage(error, \"The CORS policy is invalid.\"),\n exportName,\n ));\n }\n\n for (const method of capability.cors.methods ?? []) {\n if (!availableMethods.has(method)) {\n findings.push(finding(\n \"cors-method-unavailable\",\n file,\n `CORS method ${method} is not available from this route.`,\n exportName,\n ));\n }\n }\n }\n\n validateRateLimit(capability.security, file, exportName, findings);\n validateExceptionReasons(\n undefined,\n capability.security,\n file,\n exportName,\n findings,\n );\n }\n\n validateRateLimit(routeModule.policy?.security, file, undefined, findings);\n validateExceptionReasons(\n routeModule.policy?.document,\n routeModule.policy?.security,\n file,\n undefined,\n findings,\n );\n if (routeModule.policy?.document) {\n try {\n createSecurityHeaders(toFragmentDocument(routeModule.policy.document), {\n nonce: \"build-verification-nonce\",\n });\n } catch (error) {\n findings.push(finding(\n \"security-header-render-failed\",\n file,\n errorMessage(error, \"The security headers are invalid.\"),\n ));\n }\n }\n\n return findings;\n}\n\n// A build reads one file at a time, but policy cascades. A file declaring no\n// reporting endpoints of its own inherits them. Its `csp.reportTo` therefore\n// names a group only the merged policy resolves, which\n// `validateRouteModules(...)` checks during startup. A file declaring its own\n// endpoint map is self-contained. A name outside that map stays a build\n// error, because that is the typo worth catching early.\nfunction toFragmentDocument(document: SecurityPolicy): SecurityPolicy {\n const endpoints = document.headers?.reportingEndpoints;\n const declaresEndpoints = Boolean(\n endpoints && Object.keys(endpoints).length,\n );\n const declaredCsp = resolveCsp(document.csp);\n const reportTo = declaredCsp ? declaredCsp.reportTo : undefined;\n\n if (declaresEndpoints || !reportTo) {\n return document;\n }\n\n // TYPE-EVIDENCE: the guard above returns early when the csp field is false or missing. The remaining value is therefore a policy object.\n return {\n ...document,\n csp: { ...declaredCsp as ContentSecurityPolicy, reportTo: undefined },\n headers: endpoints\n ? { ...document.headers, reportingEndpoints: undefined }\n : document.headers,\n };\n}\n\n// ADR 0018 gives every typed security exception a mandatory reason. The type\n// system refuses a bare `csp: false` and a bare `csrf: false`. A raised body\n// limit is a valid value. The build therefore compares the declared limit with\n// the default limit. It refuses a raised limit that states no reason.\nfunction validateExceptionReasons(\n document: SecurityPolicy | undefined,\n securityPolicy: RouteSecurityPolicy | undefined,\n file: string,\n exportName: string | undefined,\n findings: StaticPolicyFinding[],\n) {\n if (document && statesNoReason(document.csp)) {\n findings.push(finding(\n \"security-exception-reason-missing\",\n file,\n \"This document policy accepts no Content-Security-Policy and states no reason. Declare csp with a value of false and a reason.\",\n exportName,\n ));\n }\n\n if (securityPolicy && statesNoReason(securityPolicy.csrf)) {\n findings.push(finding(\n \"security-exception-reason-missing\",\n file,\n \"This route runs no CSRF check and states no reason. Declare csrf with a value of false and a reason.\",\n exportName,\n ));\n }\n\n validateRaisedBodyLimit(securityPolicy, file, exportName, findings);\n}\n\n// The build reads a JavaScript route file as well as a TypeScript route file.\n// A bare `false` and an object without a reason therefore both reach here.\nfunction statesNoReason(declaration: unknown) {\n if (declaration === false) {\n return true;\n }\n\n return (\n isPlainObject(declaration) &&\n \"value\" in declaration &&\n typeof declaration.reason !== \"string\"\n );\n}\n\nfunction validateRaisedBodyLimit(\n securityPolicy: RouteSecurityPolicy | undefined,\n file: string,\n exportName: string | undefined,\n findings: StaticPolicyFinding[],\n) {\n const declared = securityPolicy?.request?.maxBodySize;\n\n if (declared === undefined || getBodySizeException(declared)) {\n return;\n }\n\n let declaredBytes: number;\n let defaultBytes: number;\n\n try {\n // TYPE-EVIDENCE: the exception guard above leaves a body size value. The cast labels the resolved value for the parser.\n declaredBytes = parseBodySize(resolveMaxBodySize(declared) as number | string);\n defaultBytes = parseBodySize(DEFAULT_MAX_BODY_SIZE);\n } catch {\n // An invalid value fails at request time with a typed error. The build\n // does not repeat that failure here.\n return;\n }\n\n if (declaredBytes <= defaultBytes) {\n return;\n }\n\n findings.push(finding(\n \"security-exception-reason-missing\",\n file,\n `This route raises the request body limit to ${\n String(declared)\n } and states no reason. Declare maxBodySize with a limit value and a reason.`,\n exportName,\n ));\n}\n\nfunction validateRateLimit(\n securityPolicy: RouteSecurityPolicy | undefined,\n file: string,\n exportName: string | undefined,\n findings: StaticPolicyFinding[],\n) {\n if (!securityPolicy?.rateLimit) return;\n try {\n validateRateLimitPolicy(securityPolicy.rateLimit);\n } catch (error) {\n findings.push(finding(\n \"rate-limit-invalid\",\n file,\n errorMessage(error, \"The rate limit policy is invalid.\"),\n exportName,\n ));\n }\n}\n\nfunction finding(\n code: StaticPolicyFinding[\"code\"],\n file: string,\n message: string,\n exportName?: string,\n): StaticPolicyFinding {\n return { code, exportName, file, message, severity: \"error\" };\n}\n\nfunction collectCoreImports(ast: AstNode) {\n const imports = new Map<string, string>();\n for (const statement of asNodeArray(ast.body)) {\n if (\n statement.type !== \"ImportDeclaration\" ||\n asNode(statement.source)?.value !== \"@demiurgejs/core\"\n ) continue;\n for (const specifier of asNodeArray(statement.specifiers)) {\n if (specifier.type !== \"ImportSpecifier\") continue;\n const local = identifierName(specifier.local);\n const imported = propertyName(specifier.imported);\n if (local && imported) imports.set(local, imported);\n }\n }\n return imports;\n}\n\nfunction collectConstants(ast: AstNode) {\n const constants = new Map<string, unknown>();\n for (const statement of asNodeArray(ast.body)) {\n const declaration = statement.type === \"ExportNamedDeclaration\"\n ? asNode(statement.declaration)\n : statement;\n if (declaration?.type !== \"VariableDeclaration\") continue;\n for (const declarator of asNodeArray(declaration.declarations)) {\n const name = identifierName(declarator.id);\n const initializer = asNode(declarator.init);\n if (!name || !initializer) continue;\n const value = evaluateLiteral(initializer, constants);\n if (value !== unresolved) constants.set(name, value);\n }\n }\n return constants;\n}\n\nconst unresolved = Symbol(\"unresolved\");\n\nfunction evaluateLiteral(\n node: AstNode | undefined,\n constants: Map<string, unknown>,\n): unknown | typeof unresolved {\n if (!node) return undefined;\n if (node.type === \"Literal\") return node.value;\n if (node.type === \"Identifier\") {\n if (node.name === \"undefined\") return undefined;\n return constants.has(String(node.name))\n ? constants.get(String(node.name))\n : unresolved;\n }\n if (node.type === \"TemplateLiteral\") {\n if (asNodeArray(node.expressions).length) return unresolved;\n return asNodeArray(node.quasis)\n .map((quasi) => asNode(quasi.value)?.cooked ?? \"\")\n .join(\"\");\n }\n if (node.type === \"UnaryExpression\") {\n const value = evaluateLiteral(asNode(node.argument), constants);\n if (typeof value !== \"number\") return unresolved;\n if (node.operator === \"-\") return -value;\n if (node.operator === \"+\") return value;\n return unresolved;\n }\n if (node.type === \"ArrayExpression\") {\n const values: unknown[] = [];\n for (const element of asNodeArray(node.elements)) {\n const value = evaluateLiteral(element, constants);\n if (value === unresolved) return unresolved;\n values.push(value);\n }\n return values;\n }\n if (node.type === \"ObjectExpression\") {\n const value: Record<string, unknown> = {};\n for (const property of asNodeArray(node.properties)) {\n if (property.type !== \"Property\" || property.computed) return unresolved;\n const name = propertyName(property.key);\n const child = evaluateLiteral(asNode(property.value), constants);\n if (!name || child === unresolved) return unresolved;\n value[name] = child;\n }\n return value;\n }\n return unresolved;\n}\n\nfunction isHttpMethod(value: string): value is HttpMethod {\n // TYPE-EVIDENCE: the value is a string that the includes check tests against the HTTP methods tuple. The cast narrows it for the check.\n return httpMethods.includes(value as HttpMethod);\n}\n\nfunction errorMessage(error: unknown, fallback: string) {\n return error instanceof Error ? error.message : fallback;\n}\n\nfunction asNode(value: unknown) {\n // TYPE-EVIDENCE: the type in value check confirms the value is an AST node. The cast asserts that node shape.\n return value && typeof value === \"object\" && \"type\" in value\n ? value as AstNode\n : undefined;\n}\n\nfunction asNodeArray(value: unknown) {\n return Array.isArray(value)\n ? value.map(asNode).filter((node): node is AstNode => Boolean(node))\n : [];\n}\n\nfunction identifierName(value: unknown) {\n const node = asNode(value);\n return node?.type === \"Identifier\" ? String(node.name) : undefined;\n}\n\nfunction propertyName(value: unknown) {\n const node = asNode(value);\n return node?.type === \"Identifier\" || node?.type === \"Literal\"\n ? String(node.name ?? node.value)\n : undefined;\n}\n","import { isPlainObject } from \"../type-guards\";\nimport type {\n InspectionRedaction,\n InspectionRedactionReason,\n} from \"./types\";\n\n/**\n * The text that replaces a removed value. A reader sees this marker in place\n * of the value, and the `redactions` section names the field and the reason.\n */\nexport const REDACTED_VALUE = \"[redacted]\";\n\nexport type InspectionSerializeOptions = {\n /**\n * The names of the environment variables that an `env.secret(...)`\n * declaration produced.\n */\n secretEnvKeys?: Iterable<string>;\n /** The indentation of the JSON output. The default value is 2. */\n space?: number;\n};\n\nexport type InspectionRedactionResult = {\n /** The values that this module removed, sorted by path. */\n redactions: InspectionRedaction[];\n /** The report without the removed values. */\n value: unknown;\n};\n\n// ADR 0019 gives the framework one place that removes a secret value. Every\n// report reaches its output through this module, so no other code repeats the\n// rule. A field name identifies a cookie or a session, and the environment\n// schema identifies a secret variable.\nconst cookieFieldNames = new Set([\n \"cookie\",\n \"cookies\",\n \"setcookie\",\n \"setcookies\",\n]);\nconst sessionFieldNames = new Set([\n \"session\",\n \"sessiondata\",\n \"sessionrecord\",\n \"sessions\",\n]);\n// A cookie declaration holds its payload in one field. The name and the other\n// attributes stay in the report, because they carry no secret.\nconst cookieValueFieldNames = new Set([\"value\"]);\n// A session record holds the application data and the identifier of the\n// session. The expiry timestamps stay in the report.\nconst sessionValueFieldNames = new Set([\"data\", \"id\"]);\n\ntype WalkContext = {\n inCookie: boolean;\n inSession: boolean;\n secretEnvKeys: ReadonlySet<string>;\n};\n\n/**\n * Serializes a report and removes each secret value. This function is the one\n * choke point of ADR 0019.\n *\n * The function writes the collected redactions into the `redactions` field of\n * the report when the report declares that field.\n */\nexport function serializeInspectionReport(\n report: unknown,\n options: InspectionSerializeOptions = {},\n): string {\n const result = redactSecrets(report, options);\n const value = attachRedactions(result);\n\n return JSON.stringify(value, undefined, options.space ?? 2);\n}\n\n/**\n * Removes each secret value from a report and returns the removed names. The\n * function does not change the report that the caller supplied.\n */\nexport function redactSecrets(\n report: unknown,\n options: InspectionSerializeOptions = {},\n): InspectionRedactionResult {\n const redactions: InspectionRedaction[] = [];\n const context: WalkContext = {\n inCookie: false,\n inSession: false,\n secretEnvKeys: new Set(options.secretEnvKeys ?? []),\n };\n const value = walk(report, \"\", context, redactions);\n\n redactions.sort((left, right) => left.path.localeCompare(right.path));\n\n return { redactions, value };\n}\n\nfunction attachRedactions(result: InspectionRedactionResult) {\n if (!isRecord(result.value)) return result.value;\n if (!Array.isArray(result.value.redactions)) return result.value;\n\n return { ...result.value, redactions: result.redactions };\n}\n\nfunction walk(\n value: unknown,\n path: string,\n context: WalkContext,\n redactions: InspectionRedaction[],\n): unknown {\n if (Array.isArray(value)) {\n return value.map((item, index) =>\n walk(item, `${path}[${index}]`, context, redactions)\n );\n }\n\n if (!isRecord(value)) return value;\n\n const scope: WalkContext = isSessionRecord(value)\n ? { ...context, inSession: true }\n : context;\n const result: Record<string, unknown> = {};\n\n for (const [name, item] of Object.entries(value)) {\n const itemPath = path ? `${path}.${name}` : name;\n const reason = classifyField(name, item, scope);\n\n if (reason) {\n redactions.push({ name, path: itemPath, reason });\n result[name] = REDACTED_VALUE;\n continue;\n }\n\n result[name] = walk(item, itemPath, descend(name, scope), redactions);\n }\n\n return result;\n}\n\nfunction classifyField(\n name: string,\n value: unknown,\n context: WalkContext,\n): InspectionRedactionReason | undefined {\n if (context.secretEnvKeys.has(name)) return \"environment-secret\";\n\n const normalized = normalizeFieldName(name);\n\n if (context.inCookie && cookieValueFieldNames.has(normalized)) {\n return \"cookie-value\";\n }\n\n if (context.inSession && sessionValueFieldNames.has(normalized)) {\n return \"session-record\";\n }\n\n if (typeof value !== \"string\") return undefined;\n if (cookieFieldNames.has(normalized)) return \"cookie-value\";\n if (sessionFieldNames.has(normalized)) return \"session-record\";\n\n return undefined;\n}\n\nfunction descend(name: string, context: WalkContext): WalkContext {\n const normalized = normalizeFieldName(name);\n\n if (cookieFieldNames.has(normalized)) return { ...context, inCookie: true };\n if (sessionFieldNames.has(normalized)) return { ...context, inSession: true };\n\n return context;\n}\n\n// A header name uses a hyphen and a property name uses camel case. One\n// normalized form matches both spellings of the same field.\nfunction normalizeFieldName(name: string) {\n return name.toLowerCase().replaceAll(\"-\", \"\").replaceAll(\"_\", \"\");\n}\n\n// A class instance such as `Date` carries no own enumerable field, so a walk\n// of its entries would replace it with an empty object. The walker returns it\n// without a change and lets `JSON.stringify` serialize it.\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n if (!isPlainObject(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n\n return prototype === Object.prototype || prototype === null;\n}\n\n// A session record reaches a report through a field that carries another name.\n// The shape of `SessionRecord` identifies it without that name.\nfunction isSessionRecord(value: Record<string, unknown>) {\n return typeof value.id === \"string\" &&\n typeof value.createdAt === \"number\" &&\n typeof value.expiresAt === \"number\" &&\n typeof value.version === \"number\" &&\n \"data\" in value;\n}\n","import {\n createMemoryCache,\n serializeCacheKey,\n serializeCacheTag,\n type Cache,\n type CacheScope,\n} from \"../data\";\nimport type { ResolvedMetadata, ScriptTag } from \"../document\";\nimport {\n findRouteMatch,\n isAttachedFileForRoute,\n isRouteGroupSegment,\n loadPageRoute,\n MalformedPathnameError,\n toRoutePattern,\n type RouteManifest,\n} from \"../router\";\nimport type {\n HttpMethod,\n PageRenderMode,\n PathVars,\n RouteModule,\n} from \"../route\";\nimport { loadInheritedRoutePolicy } from \"../server\";\nimport {\n createSecurityAudit,\n type CorsPolicy,\n type MergedRoutePolicy,\n type SecurityAudit,\n type SecurityAuditFinding,\n} from \"../security\";\nimport { createCspNonce, securityPolicyRequiresNonce } from \"../security/policy\";\nimport { serializeInspectionReport } from \"../inspect/redact\";\nimport type { InspectionResolution } from \"../inspect/types\";\n\n/**\n * The version of the route report. ADR 0019 raises this integer when the\n * framework removes a field or changes the meaning of a field.\n */\nexport const ROUTE_AUDIT_VERSION = 1;\n\n// The development server reserves this path. The name matches the image\n// optimizer path, so every framework endpoint keeps one prefix.\nexport const ROUTE_AUDIT_PATH = \"/_demiurge/audit\";\n\nconst supportedMethods = [\n \"GET\",\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\",\n \"OPTIONS\",\n \"HEAD\",\n] as const satisfies readonly HttpMethod[];\n\nexport type RouteAuditCacheRead = {\n key: string;\n scope: CacheScope;\n staleWhileRevalidate?: string;\n tags: string[];\n ttl?: string;\n};\n\nexport type RouteAuditScript = {\n findings: SecurityAuditFinding[];\n integrity?: string;\n nonce?: string;\n purpose?: string;\n src: string;\n strategy: string;\n};\n\nexport type RouteAuditRoute = {\n file: string;\n groups: string[];\n layouts: string[];\n methods: HttpMethod[];\n middlewares: string[];\n params: PathVars;\n pattern: string;\n policies: string[];\n render?: PageRenderMode;\n};\n\n/** The named sections of the route report. */\nexport type RouteAuditSection =\n | \"audit\"\n | \"cacheReads\"\n | \"metadata\"\n | \"policy\"\n | \"route\"\n | \"scripts\";\n\n// The route report answers for one request. The route section and the policy\n// section come from the route tree, so a build knows them. Each other section\n// needs the request.\nconst routeAuditResolutions: Record<RouteAuditSection, InspectionResolution> = {\n audit: \"request\",\n cacheReads: \"request\",\n metadata: \"request\",\n policy: \"static\",\n route: \"static\",\n scripts: \"request\",\n};\n\nexport type RouteAudit = {\n audit: SecurityAudit;\n cacheControl?: string;\n cacheReads: RouteAuditCacheRead[];\n kind: \"page\" | \"resource\" | \"unmatched\";\n metadata?: ResolvedMetadata;\n method: HttpMethod;\n nonce?: string;\n pathname: string;\n policy: MergedRoutePolicy;\n /** The resolution of each section of the report. */\n resolutions: Record<RouteAuditSection, InspectionResolution>;\n route?: RouteAuditRoute;\n scripts: RouteAuditScript[];\n /** The version of this report shape. */\n version: number;\n};\n\nexport function isRouteAuditRequest(request: Request) {\n return new URL(request.url).pathname === ROUTE_AUDIT_PATH;\n}\n\nexport async function createRouteAuditResponse(\n manifest: RouteManifest,\n request: Request,\n) {\n const url = new URL(request.url);\n const report = await createRouteAudit(\n manifest,\n url.searchParams.get(\"path\") || \"/\",\n request,\n );\n const json = url.searchParams.get(\"format\") === \"json\";\n\n return new Response(\n json\n ? serializeInspectionReport(report)\n : renderRouteAuditDocument(report),\n {\n headers: {\n \"cache-control\": \"no-store\",\n // The panel is a side channel. It declares its own policy, so the\n // policy of the application stays unchanged. The panel runs no script.\n \"content-security-policy\":\n \"default-src 'none'; base-uri 'none'; form-action 'self'; style-src 'unsafe-inline'\",\n \"content-type\": json\n ? \"application/json; charset=utf-8\"\n : \"text/html; charset=utf-8\",\n \"x-robots-tag\": \"noindex\",\n },\n },\n );\n}\n\nexport async function createRouteAudit(\n manifest: RouteManifest,\n target: string,\n request: Request,\n): Promise<RouteAudit> {\n const origin = new URL(request.url).origin;\n const url = new URL(target, origin);\n const pathname = url.pathname;\n const routeRequest = new Request(url, { headers: request.headers });\n const routeMatch = matchRoute(manifest, pathname);\n\n if (!routeMatch) {\n const policy = await loadInheritedRoutePolicy(\n manifest,\n { fileSegments: [] },\n {},\n undefined,\n );\n\n return finishRouteAudit({\n cacheReads: [],\n kind: \"unmatched\",\n method: \"GET\",\n pathname,\n policy,\n request: routeRequest,\n scripts: [],\n });\n }\n\n const routeModule = await routeMatch.route.load();\n const method = selectMethod(routeModule);\n const capability = routeModule[method];\n const policy = await loadInheritedRoutePolicy(\n manifest,\n routeMatch.route,\n routeModule,\n capability,\n );\n const cacheReads: RouteAuditCacheRead[] = [];\n const page = capability?.kind === \"page\"\n ? await loadPageRoute(\n manifest,\n pathname,\n routeRequest,\n undefined,\n createRecordingCache(cacheReads),\n )\n : undefined;\n const match = page?.status === \"ready\" ? page.match : undefined;\n\n return finishRouteAudit({\n cacheReads,\n cors: capability && capability.kind !== \"page\"\n ? capability.cors\n : undefined,\n kind: capability?.kind === \"page\" ? \"page\" : \"resource\",\n metadata: match?.metadata,\n method,\n pathname,\n policy,\n request: routeRequest,\n route: {\n file: routeMatch.route.file,\n groups: routeMatch.route.fileSegments.filter(isRouteGroupSegment),\n layouts: manifest.layouts\n .filter((layout) => isAttachedFileForRoute(layout.fileSegments, routeMatch.route.fileSegments))\n .map((layout) => layout.file),\n methods: supportedMethods.filter((name) => routeModule[name]),\n middlewares: manifest.middlewares\n .filter((item) => isAttachedFileForRoute(item.fileSegments, routeMatch.route.fileSegments))\n .map((item) => item.file),\n params: routeMatch.path,\n pattern: toRoutePattern(routeMatch.route.segments),\n policies: manifest.policies\n .filter((item) => isAttachedFileForRoute(item.fileSegments, routeMatch.route.fileSegments))\n .map((item) => item.file),\n render: match?.render.mode,\n },\n scripts: match?.scripts ?? [],\n });\n}\n\nfunction finishRouteAudit(input: {\n cacheReads: RouteAuditCacheRead[];\n cors?: CorsPolicy;\n kind: RouteAudit[\"kind\"];\n metadata?: ResolvedMetadata;\n method: HttpMethod;\n pathname: string;\n policy: MergedRoutePolicy;\n request: Request;\n route?: RouteAuditRoute;\n scripts: readonly ScriptTag[];\n}): RouteAudit {\n // The request handler renders the document policy for a page response only.\n // A resource route and an unmatched path therefore get no document headers\n // and no nonce.\n const document = input.kind === \"page\";\n // The document renderer gives each script the nonce of the document. The\n // audit reads the same values that the response carries.\n const nonce = document && securityPolicyRequiresNonce(input.policy.document)\n ? createCspNonce()\n : undefined;\n const scripts = input.scripts.map((script) => ({\n ...script,\n nonce: script.nonce ?? nonce,\n }));\n const auditOptions = {\n headers: { nonce, request: input.request },\n policy: input.policy.document ?? {},\n scriptDependencies: true,\n };\n const audit = createSecurityAudit({\n document: document ? { ...auditOptions, scripts } : undefined,\n route: {\n // A path that matches no route file has no access declaration to\n // report, so the audit says nothing about its authorization.\n access: input.kind === \"unmatched\" ? undefined : input.policy.access,\n cors: input.cors,\n method: input.method,\n security: input.policy.security,\n },\n });\n\n return {\n audit,\n // A nonce makes a document unique for each response. The request handler\n // therefore replaces the cache directives of the application.\n cacheControl: nonce ? \"private, no-store\" : undefined,\n cacheReads: input.cacheReads,\n kind: input.kind,\n metadata: input.metadata,\n method: input.method,\n nonce,\n pathname: input.pathname,\n policy: input.policy,\n resolutions: routeAuditResolutions,\n route: input.route,\n scripts: scripts.map((script) => ({\n // One audit for each script gives the status of that script alone. The\n // panel reads the same code path that the complete audit reads.\n findings: createSecurityAudit({\n document: { ...auditOptions, scripts: [script] },\n }).findings,\n integrity: script.integrity,\n nonce: script.nonce,\n purpose: script.purpose,\n src: script.src,\n strategy: script.strategy,\n })),\n version: ROUTE_AUDIT_VERSION,\n };\n}\n\nfunction matchRoute(manifest: RouteManifest, pathname: string) {\n try {\n return findRouteMatch(manifest.routes, pathname);\n } catch (error) {\n if (error instanceof MalformedPathnameError) {\n return null;\n }\n\n throw error;\n }\n}\n\nfunction selectMethod(routeModule: RouteModule) {\n return supportedMethods.find((method) => routeModule[method]) ?? \"GET\";\n}\n\nfunction createRecordingCache(reads: RouteAuditCacheRead[]): Cache {\n const cache = createMemoryCache();\n\n return {\n get: async (request) => {\n reads.push({\n key: serializeCacheKey(request.key),\n scope: request.scope ?? \"request\",\n staleWhileRevalidate: formatDuration(request.staleWhileRevalidate),\n tags: (request.tags ?? []).map(serializeCacheTag),\n ttl: formatDuration(request.ttl),\n });\n\n return await cache.get(request);\n },\n invalidateKey: cache.invalidateKey,\n invalidateTags: cache.invalidateTags,\n };\n}\n\nfunction formatDuration(duration: number | string | undefined) {\n return duration === undefined ? undefined : String(duration);\n}\n\nexport function renderRouteAuditDocument(report: RouteAudit) {\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Demiurge route audit</title>\n <style>${panelStyles}</style>\n </head>\n <body>\n <h1>Demiurge route audit</h1>\n <form method=\"get\" action=\"${ROUTE_AUDIT_PATH}\">\n <label for=\"path\">Path</label>\n <input id=\"path\" name=\"path\" value=\"${escapeHtml(report.pathname)}\" />\n <button type=\"submit\">Audit</button>\n </form>\n${renderRouteSection(report)}\n${renderFindingsSection(report.audit.findings)}\n${renderHeadersSection(report.audit.headers)}\n${renderPolicySection(report)}\n${renderMetadataSection(report.metadata)}\n${renderScriptsSection(report.scripts)}\n${renderCacheSection(report)}\n <p class=\"footer\">\n The development server serves this panel. A production build and a static\n export do not contain it.\n </p>\n </body>\n</html>\n`;\n}\n\nconst panelStyles = `\n :root { color-scheme: light dark; }\n body {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n line-height: 1.5;\n margin: 0 auto;\n max-width: 60rem;\n padding: 2rem 1rem;\n }\n h1 { font-size: 1.25rem; }\n h2 { font-size: 1rem; margin-bottom: 0.25rem; }\n form { display: flex; gap: 0.5rem; margin-bottom: 1.5rem; }\n input { flex: 1; padding: 0.25rem 0.5rem; }\n section { border-top: 1px solid currentColor; padding: 0.75rem 0; }\n table { border-collapse: collapse; width: 100%; }\n td, th { padding: 0.25rem 0.5rem 0.25rem 0; text-align: left; vertical-align: top; }\n th { white-space: nowrap; width: 12rem; }\n ul { margin: 0; padding-left: 1.25rem; }\n .empty { opacity: 0.7; }\n .error { font-weight: 700; }\n .footer { opacity: 0.7; }\n`;\n\nfunction renderRouteSection(report: RouteAudit) {\n if (!report.route) {\n return section(\n \"Route\",\n `<p class=\"empty\">No route matches ${escapeHtml(report.pathname)}.</p>`,\n );\n }\n\n const route = report.route;\n\n return section(\n \"Route\",\n table([\n [\"Pathname\", escapeHtml(report.pathname)],\n [\"Pattern\", escapeHtml(route.pattern)],\n [\"File\", escapeHtml(route.file)],\n [\"Kind\", escapeHtml(report.kind)],\n [\"Method\", escapeHtml(report.method)],\n [\"Methods\", escapeHtml(route.methods.join(\", \"))],\n [\"Render mode\", route.render ? escapeHtml(route.render) : none()],\n [\"Path values\", entries(route.params)],\n [\"Route groups\", list(route.groups)],\n [\"Layouts\", list(route.layouts)],\n [\"Policies\", list(route.policies)],\n [\"Middleware\", list(route.middlewares)],\n ]),\n );\n}\n\nfunction renderFindingsSection(findings: SecurityAuditFinding[]) {\n if (findings.length === 0) {\n return section(\"Findings\", `<p class=\"empty\">No findings.</p>`);\n }\n\n return section(\n \"Findings\",\n `<ul>${findings.map(renderFinding).join(\"\")}</ul>`,\n );\n}\n\nfunction renderFinding(finding: SecurityAuditFinding) {\n const className = finding.severity === \"error\" ? ' class=\"error\"' : \"\";\n\n return `<li${className}>${escapeHtml(finding.severity)}: ${\n escapeHtml(finding.message)\n } <code>${escapeHtml(finding.code)}</code></li>`;\n}\n\nfunction renderHeadersSection(headers: Record<string, string>) {\n const names = Object.keys(headers).sort();\n\n if (names.length === 0) {\n return section(\n \"Response headers\",\n `<p class=\"empty\">The response carries no document header.</p>`,\n );\n }\n\n return section(\n \"Response headers\",\n table(names.map((name) => [name, escapeHtml(headers[name])])),\n );\n}\n\nfunction renderPolicySection(report: RouteAudit) {\n const policy = {\n cors: report.audit.route?.cors,\n document: report.policy.document,\n security: report.policy.security,\n };\n\n return section(\n \"Effective policy\",\n `<pre>${\n escapeHtml(JSON.stringify(policy, null, 2))\n }</pre>`,\n );\n}\n\nfunction renderMetadataSection(metadata: ResolvedMetadata | undefined) {\n if (!metadata) {\n return section(\"Metadata\", `<p class=\"empty\">No document metadata.</p>`);\n }\n\n return section(\n \"Metadata\",\n `<pre>${\n escapeHtml(JSON.stringify(metadata, null, 2))\n }</pre>`,\n );\n}\n\nfunction renderScriptsSection(scripts: RouteAuditScript[]) {\n if (scripts.length === 0) {\n return section(\"Scripts\", `<p class=\"empty\">No contributed scripts.</p>`);\n }\n\n return section(\n \"Scripts\",\n scripts.map((script) =>\n table([\n [\"Source\", escapeHtml(script.src)],\n [\"Strategy\", escapeHtml(script.strategy)],\n [\"Purpose\", script.purpose ? escapeHtml(script.purpose) : none()],\n [\"Integrity\", script.integrity ? escapeHtml(script.integrity) : none()],\n [\"Nonce\", script.nonce ? \"applied\" : none()],\n [\n \"Policy status\",\n script.findings.length === 0\n ? \"allowed\"\n : `<ul>${script.findings.map(renderFinding).join(\"\")}</ul>`,\n ],\n ])\n ).join(\"\"),\n );\n}\n\nfunction renderCacheSection(report: RouteAudit) {\n const rows: Array<[string, string]> = [\n [\n \"Response cache-control\",\n report.cacheControl ? escapeHtml(report.cacheControl) : none(),\n ],\n [\"Nonce\", report.nonce ? \"required\" : none()],\n ];\n\n if (report.cacheReads.length === 0) {\n return section(\n \"Cache behavior\",\n `${table(rows)}<p class=\"empty\">The request read no cache entry.</p>`,\n );\n }\n\n return section(\n \"Cache behavior\",\n `${table(rows)}${\n report.cacheReads.map((read) =>\n table([\n [\"Key\", escapeHtml(read.key)],\n [\"Scope\", escapeHtml(read.scope)],\n [\"Time to live\", read.ttl ? escapeHtml(read.ttl) : none()],\n [\n \"Stale while revalidate\",\n read.staleWhileRevalidate\n ? escapeHtml(read.staleWhileRevalidate)\n : none(),\n ],\n [\"Tags\", list(read.tags)],\n ])\n ).join(\"\")\n }`,\n );\n}\n\nfunction section(title: string, body: string) {\n return ` <section>\n <h2>${escapeHtml(title)}</h2>\n ${body}\n </section>`;\n}\n\nfunction table(rows: Array<[string, string]>) {\n return `<table><tbody>${\n rows.map(([name, value]) =>\n `<tr><th scope=\"row\">${escapeHtml(name)}</th><td>${value}</td></tr>`\n ).join(\"\")\n }</tbody></table>`;\n}\n\nfunction list(values: readonly string[]) {\n if (values.length === 0) {\n return none();\n }\n\n return `<ul>${\n values.map((value) => `<li>${escapeHtml(value)}</li>`).join(\"\")\n }</ul>`;\n}\n\nfunction entries(values: PathVars) {\n return list(\n Object.entries(values).map(([name, value]) => `${name} = ${String(value)}`),\n );\n}\n\nfunction none() {\n return `<span class=\"empty\">none</span>`;\n}\n\nfunction escapeHtml(value: string) {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll(\"\\\"\", \"&quot;\")\n .replaceAll(\"'\", \"&#39;\");\n}\n","import { existsSync } from \"node:fs\";\nimport type { IncomingMessage } from \"node:http\";\nimport { readFile, readdir } from \"node:fs/promises\";\nimport { dirname, join, resolve, relative, sep } from \"node:path\";\nimport MagicString from \"magic-string\";\nimport {\n type ConfigEnv,\n parseAst,\n type Plugin,\n type UserConfig,\n type ViteDevServer,\n} from \"vite\";\nimport { renderDocument } from \"../document\";\nimport type {\n LinkTag,\n ResolvedMetadata,\n ScriptTag,\n} from \"../document\";\nimport { PACKAGE_NAME } from \"../package-name\";\nimport { generateRoutes } from \"../routing/generate\";\nimport {\n createRouteManifest,\n findRouteMatch,\n type RouteManifest,\n} from \"../router\";\nimport {\n handleRequestWithManifest,\n renderNotFoundResponse,\n renderPageDocument,\n type PageRenderer,\n} from \"../server\";\nimport {\n type RouteImporter,\n type RouteModule,\n} from \"../route\";\nimport {\n UnsupportedMethodError,\n toWebRequest,\n writeNotImplemented,\n writeWebResponse,\n} from \"../node/http\";\nimport { createFontAssetHandler } from \"../node/font\";\nimport { createImageOptimizer } from \"../node/image\";\nimport { renderStreamingPageResponse } from \"../node/streaming\";\nimport type { FontContribution } from \"../platform/fonts\";\nimport { parseImageVariantPath } from \"../platform/image-url\";\nimport type { ImagePolicy } from \"../platform/images\";\nimport { createCspNonce } from \"../security/policy\";\nimport type { EnvSchema, EnvSource } from \"../security/env\";\nimport { serializeEnvSchema, startEnvironment } from \"../security/env-startup\";\nimport {\n findEnvKeyReferences,\n findImportPath,\n findServerEnvKeys,\n formatEnvBoundaryFindings,\n type EnvBoundaryFinding,\n} from \"./env-boundary\";\nimport {\n formatServerOnlyBoundaryFindings,\n formatServerOnlyDevError,\n importsServerOnlyMarker,\n type ServerOnlyBoundaryFinding,\n} from \"./server-only-boundary\";\nimport {\n auditDocumentPolicyCoverage,\n auditRouteAccessCoverage,\n declaresPageRoute,\n inspectRouteFile,\n type RouteFileInspection,\n type StaticPolicyFinding,\n} from \"./policy-verification\";\nimport {\n createRouteAuditResponse,\n isRouteAuditRequest,\n} from \"./route-audit\";\nimport type {\n StaticFileHeaderPatternRule,\n VercelStaticDeployment,\n} from \"../static\";\nimport { defineLocales, type LocaleConfiguration } from \"../routing\";\n\nexport type DemiurgeVitePluginOptions = {\n // The route audit panel of the development server. The panel is available by\n // default. Set this option to false to remove the endpoint.\n devtools?: boolean;\n document?: {\n lang?: string;\n title?: string;\n };\n // The environment schema of the application. The generated server entry\n // validates it when the server starts.\n env?: EnvSchema;\n // The fonts that the application self-hosts. The development server serves\n // the same URLs that the build publishes.\n fonts?: FontContribution;\n // The image policy that the application passes to `planImageTransform` and\n // to `Image`. The development server serves the optimizer path from it.\n images?: ImagePolicy;\n locales?: LocaleConfiguration;\n routesDir?: string;\n static?: {\n deployment?: VercelStaticDeployment;\n headers?: readonly StaticFileHeaderPatternRule[];\n };\n styles?: false | string;\n typedRoutes?: boolean | {\n outputFile?: string;\n };\n};\n\nexport type DemiurgeVitePluginApi = {\n demiurge: true;\n fonts?: FontContribution;\n images?: ImagePolicy;\n staticDeployment?: VercelStaticDeployment;\n staticFileHeaders?: readonly StaticFileHeaderPatternRule[];\n};\n\nconst CLIENT_ENTRY_ID = \"virtual:demiurge/client-entry\";\nconst DEV_CLIENT_ENTRY_PATH = `/@id/${CLIENT_ENTRY_ID}`;\nconst RESOLVED_CLIENT_ENTRY_ID = `\\0${CLIENT_ENTRY_ID}`;\nconst SERVER_ENTRY_ID = \"virtual:demiurge/server-entry\";\nconst RESOLVED_SERVER_ENTRY_ID = `\\0${SERVER_ENTRY_ID}`;\nconst DEFAULT_TYPED_ROUTES_OUTPUT = \".demiurge/route-manifest.d.ts\";\nexport function demiurge(options: DemiurgeVitePluginOptions = {}): Plugin {\n if (options.locales) options = { ...options, locales: defineLocales(options.locales) };\n let root = process.cwd();\n let isBuild = false;\n // The build refuses a browser bundle that reads a variable of the server.\n // The transform hook records a reference. The buildEnd hook then keeps the\n // references of the modules that a client entry reaches.\n const serverEnvKeys = findServerEnvKeys(options.env);\n const clientEnvReferences = new Map<string, string[]>();\n // The build refuses a browser bundle that reaches a module marked\n // server-only. The transform hook records the module id. The buildEnd hook\n // then finds the import path from a client entry.\n const serverOnlyMarkers = new Set<string>();\n const viteNoncePlaceholder = `demiurge-${createCspNonce()}`;\n\n return {\n api: {\n demiurge: true,\n fonts: options.fonts,\n images: options.images,\n staticDeployment: options.static?.deployment,\n staticFileHeaders: options.static?.headers,\n } satisfies DemiurgeVitePluginApi,\n enforce: \"post\",\n name: \"demiurge\",\n config(config, environment) {\n return createViteConfig(config, environment, viteNoncePlaceholder);\n },\n configResolved(config) {\n root = config.root;\n isBuild = config.command === \"build\";\n\n if (!isBuild) {\n startDevEnvironment(options);\n }\n },\n resolveId(id) {\n if (id === CLIENT_ENTRY_ID) {\n return RESOLVED_CLIENT_ENTRY_ID;\n }\n\n if (id === SERVER_ENTRY_ID) {\n return RESOLVED_SERVER_ENTRY_ID;\n }\n\n return null;\n },\n load(id) {\n if (id === RESOLVED_CLIENT_ENTRY_ID) {\n return createClientEntrySource(root, options);\n }\n\n if (id === RESOLVED_SERVER_ENTRY_ID) {\n return createServerEntrySource(root, options);\n }\n\n return null;\n },\n transform: {\n order: \"post\",\n handler(code, id, transformOptions) {\n if (!transformOptions?.ssr) {\n checkServerOnlyBoundary(serverOnlyMarkers, isBuild, root, code, id);\n }\n\n if (isBuild && !transformOptions?.ssr) {\n recordClientEnvReferences(clientEnvReferences, serverEnvKeys, code, id);\n }\n\n if (!isRouteSource(root, options, id)) {\n return null;\n }\n\n if (transformOptions?.ssr) {\n return isBuild ? null : protectSsrImportMeta(code, id);\n }\n\n const transformed = stripClientPageData(code);\n return transformed === code ? null : { code: transformed, map: null };\n },\n },\n generateBundle(_outputOptions, bundle) {\n const entry = Object.values(bundle).find(\n (item) =>\n item.type === \"chunk\" &&\n item.isEntry &&\n item.facadeModuleId === RESOLVED_CLIENT_ENTRY_ID,\n );\n\n if (!entry) {\n return;\n }\n\n const styles = Object.values(bundle)\n .filter(\n (asset): asset is Extract<(typeof bundle)[string], { type: \"asset\" }> =>\n asset.type === \"asset\" && asset.fileName.endsWith(\".css\"),\n )\n .map((asset) => `/${asset.fileName}`);\n const clientEntry = `/${entry.fileName}`;\n\n this.emitFile({\n fileName: \"index.html\",\n source: createDocumentHtml({\n entrySrc: clientEntry,\n lang: options.document?.lang,\n styles,\n title: options.document?.title,\n }),\n type: \"asset\",\n });\n this.emitFile({\n fileName: \"demiurge-manifest.json\",\n source: JSON.stringify({ clientEntry, styles }, null, 2),\n type: \"asset\",\n });\n },\n buildEnd() {\n const findings = collectEnvBoundaryFindings({\n moduleIds: [...this.getModuleIds()],\n moduleInfo: (id) => this.getModuleInfo(id),\n references: clientEnvReferences,\n root,\n serverEnvKeys,\n });\n\n if (findings.length) {\n this.error(formatEnvBoundaryFindings(findings));\n }\n\n const serverOnlyFindings = collectServerOnlyBoundaryFindings({\n markers: serverOnlyMarkers,\n moduleIds: [...this.getModuleIds()],\n moduleInfo: (id) => this.getModuleInfo(id),\n root,\n });\n\n if (serverOnlyFindings.length) {\n this.error(formatServerOnlyBoundaryFindings(serverOnlyFindings));\n }\n },\n async buildStart() {\n clientEnvReferences.clear();\n serverOnlyMarkers.clear();\n\n if (isBuild) {\n await assertRootNotFoundRoute(root, options);\n const findings = await verifyRoutePolicies(root, options);\n const errors = findings.filter(\n (finding) => finding.severity === \"error\",\n );\n\n for (const finding of findings) {\n if (finding.severity === \"error\") continue;\n this.warn(formatStaticPolicyFinding(finding));\n }\n\n if (errors.length) {\n throw new Error(formatStaticPolicyFindings(errors));\n }\n }\n\n if (!options.typedRoutes) {\n return;\n }\n\n await generateTypedRoutes(root, options);\n },\n configureServer(server) {\n const reportPolicyFindings = async () => {\n const findings = await verifyRoutePolicies(server.config.root, options);\n\n for (const finding of findings) {\n server.config.logger.warn(formatStaticPolicyFinding(finding));\n }\n };\n // A single editor save can fire several watcher events, and a branch\n // switch fires one per route file. Collapse a burst into one scan, and\n // chain scans so two never walk the route tree at the same time.\n let policyVerificationTimer: ReturnType<typeof setTimeout> | undefined;\n let policyVerificationRun = Promise.resolve();\n const runPolicyVerification = () => {\n policyVerificationRun = policyVerificationRun\n .then(reportPolicyFindings)\n .catch(() => {\n // Vite reports route read and syntax errors through its module pipeline.\n });\n };\n const startPolicyVerification = () => {\n if (policyVerificationTimer) {\n clearTimeout(policyVerificationTimer);\n }\n\n policyVerificationTimer = setTimeout(() => {\n policyVerificationTimer = undefined;\n runPolicyVerification();\n }, policyVerificationDebounceMs);\n policyVerificationTimer.unref?.();\n };\n\n server.httpServer?.once(\"close\", () => {\n if (policyVerificationTimer) {\n clearTimeout(policyVerificationTimer);\n policyVerificationTimer = undefined;\n }\n });\n\n runPolicyVerification();\n if (options.typedRoutes) {\n const routesDir = resolve(\n server.config.root,\n options.routesDir ?? \"src/routes\",\n );\n const runGenerateTypedRoutes = () => {\n void generateTypedRoutes(server.config.root, options).catch(\n (error: unknown) => {\n server.config.logger.error(\n error instanceof Error ? error.message : String(error),\n );\n },\n );\n };\n\n runGenerateTypedRoutes();\n server.watcher.add(routesDir);\n server.watcher.on(\"add\", (file) => {\n if (isRouteFile(routesDir, file)) {\n runGenerateTypedRoutes();\n startPolicyVerification();\n }\n });\n server.watcher.on(\"change\", (file) => {\n if (isRouteFile(routesDir, file)) {\n runGenerateTypedRoutes();\n startPolicyVerification();\n }\n });\n server.watcher.on(\"unlink\", (file) => {\n if (isRouteFile(routesDir, file)) {\n runGenerateTypedRoutes();\n startPolicyVerification();\n }\n });\n } else {\n const routesDir = resolve(\n server.config.root,\n options.routesDir ?? \"src/routes\",\n );\n server.watcher.add(routesDir);\n for (const event of [\"add\", \"change\", \"unlink\"] as const) {\n server.watcher.on(event, (file) => {\n if (isRouteFile(routesDir, file)) startPolicyVerification();\n });\n }\n }\n\n const routeAuditEnabled = isRouteAuditEnabled(options);\n const optimizeImage = createDevImageOptimizer(server, options);\n const serveFont = createFontAssetHandler({\n fonts: options.fonts,\n root: server.config.root,\n });\n\n // Vite's Connect middleware type is void-returning. The handler below\n // is deliberately async so tests can await its returned promise and\n // know when a request has finished. Vite itself never touches that\n // return value, so async is safe here even though the declared type\n // says otherwise.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n server.middlewares.use(async (request, response, next) => {\n try {\n let webRequest: Request;\n\n try {\n webRequest = toWebRequest(request, {\n // Vite performs its own configured host allowlist check before\n // Demiurge's middleware runs. Production Node listeners require\n // an explicit application allowlist instead.\n allowedHosts: [request.headers.host ?? \"localhost\"],\n });\n } catch (error) {\n if (error instanceof UnsupportedMethodError) {\n writeNotImplemented(response);\n return;\n }\n\n throw error;\n }\n\n if (routeAuditEnabled && isRouteAuditRequest(webRequest)) {\n const manifest = await loadDevManifest(\n server,\n request,\n resolve(server.config.root, options.routesDir ?? \"src/routes\"),\n );\n\n await writeWebResponse(\n response,\n await createRouteAuditResponse(manifest, webRequest),\n );\n return;\n }\n\n const font = await serveFont(webRequest);\n\n if (font) {\n await writeWebResponse(response, font);\n return;\n }\n\n const image = await optimizeImage(webRequest);\n\n if (image) {\n await writeWebResponse(response, image);\n return;\n }\n\n const routesDir = resolve(\n server.config.root,\n options.routesDir ?? \"src/routes\",\n );\n const manifest = await loadDevManifest(server, request, routesDir);\n const documentSecurity = createDevDocumentSecurity(\n server,\n viteNoncePlaceholder,\n );\n const result = await handleDevRequest(\n manifest,\n webRequest,\n createDevRuntimeOptions(options, documentSecurity.transform),\n );\n\n if (result === \"next\") {\n // Vite owns its own asset URLs, so an unmatched request still\n // falls through. The post middleware below is what turns whatever\n // Vite could not serve into the same negotiated not-found\n // production returns.\n next();\n return;\n }\n\n applyDevDocumentSecurity(result, documentSecurity.nonce);\n await writeWebResponse(response, result);\n } catch (error) {\n next(error);\n }\n });\n\n // The returned hook registers this after the Vite middleware. It sees\n // only requests that Vite cannot serve. `appType` is \"custom\", so no SPA\n // fallback intercepts these requests. Development and production render\n // the same negotiated not-found response for an unmatched path.\n return () => {\n // See the note above the earlier `server.middlewares.use` call. This\n // handler is deliberately async so tests can await the returned\n // promise. Vite itself never inspects that return value.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n server.middlewares.use(async (request, response, next) => {\n try {\n let webRequest: Request;\n\n try {\n webRequest = toWebRequest(request, {\n allowedHosts: [request.headers.host ?? \"localhost\"],\n });\n } catch (error) {\n if (error instanceof UnsupportedMethodError) {\n writeNotImplemented(response);\n return;\n }\n\n throw error;\n }\n\n const routesDir = resolve(\n server.config.root,\n options.routesDir ?? \"src/routes\",\n );\n const manifest = await loadDevManifest(server, request, routesDir);\n\n warnMissingRootNotFound(manifest, routesDir);\n\n const documentSecurity = createDevDocumentSecurity(\n server,\n viteNoncePlaceholder,\n );\n const notFoundResponse = await renderNotFoundResponse(\n manifest,\n webRequest,\n createDevFallbackOptions(options, documentSecurity.transform),\n );\n applyDevDocumentSecurity(\n notFoundResponse,\n documentSecurity.nonce,\n );\n await writeWebResponse(response, notFoundResponse);\n } catch (error) {\n next(error);\n }\n });\n };\n },\n };\n}\n\ntype AstNode = {\n [key: string]: unknown;\n end: number;\n start: number;\n type: string;\n};\n\n// TYPE-EVIDENCE: rollup returns a generic program node. The local type is a loose access shape.\nfunction asAstNode(value: unknown): AstNode {\n // TYPE-EVIDENCE: the caller passes a rollup program node. The cast labels it with the loose access shape.\n return value as AstNode;\n}\n\n// Vite 6 treats the `meta` token in `import.meta` as an imported reference.\n// Give an imported `meta` binding a private name before development SSR runs.\nfunction protectSsrImportMeta(code: string, id: string) {\n if (!code.includes(\"import.meta\")) {\n return null;\n }\n\n const ast = asAstNode(parseAst(code));\n const declaration = asNodeArray(ast.body).find((node) =>\n node.type === \"ImportDeclaration\" &&\n asNodeArray(node.specifiers).some((specifier) =>\n asNode(specifier.local)?.type === \"Identifier\" &&\n asNode(specifier.local)?.name === \"meta\"\n )\n );\n const specifier = declaration &&\n asNodeArray(declaration.specifiers).find((candidate) =>\n asNode(candidate.local)?.type === \"Identifier\" &&\n asNode(candidate.local)?.name === \"meta\"\n );\n const local = specifier && asNode(specifier.local);\n\n if (!declaration || !specifier || !local) {\n return null;\n }\n\n let alias = \"__demiurge_imported_meta__\";\n while (new RegExp(`\\\\b${alias}\\\\b`).test(code)) {\n alias += \"_\";\n }\n\n const editor = new MagicString(code);\n const imported = asNode(specifier.imported);\n editor.overwrite(\n local.start,\n local.end,\n imported?.start === local.start ? `meta as ${alias}` : alias,\n );\n editor.appendLeft(declaration.end, `\\nconst meta = ${alias};`);\n\n return {\n code: editor.toString(),\n map: editor.generateMap({\n hires: \"boundary\",\n includeContent: true,\n source: id,\n }),\n };\n}\n\n// Page data and document contributions are server capabilities. Vite and React\n// first parse TypeScript and JSX. The plugin then removes these capabilities\n// before Rollup follows the final client graph. This sequence excludes request\n// code and server-only imports from browser chunks. The exported document\n// bindings remain as `undefined` so the\n// route module keeps a stable shape without evaluating their initializers.\nexport function stripClientPageData(code: string) {\n const ast = asAstNode(parseAst(code));\n const dataRanges: Array<{ end: number; start: number }> = [];\n const documentRanges = findDocumentContributionRanges(ast);\n const mutationRanges = findUnsafeMethodRanges(ast);\n const mutationReexportRanges = findUnsafeMethodReexportRanges(ast);\n const serverImports: AstNode[] = [];\n\n walkAst(ast, (node) => {\n if (node.type === \"ImportDeclaration\" && isServerOnlyImport(node)) {\n serverImports.push(node);\n return;\n }\n\n if (node.type !== \"CallExpression\" || !isPageCallee(node.callee)) {\n return;\n }\n\n const argument = asNodeArray(node.arguments)[0];\n if (argument?.type !== \"ObjectExpression\") {\n return;\n }\n\n for (const property of asNodeArray(argument.properties)) {\n if (property.type === \"Property\" && propertyName(property.key) === \"data\") {\n dataRanges.push({ end: property.end, start: property.start });\n }\n }\n });\n\n const serverRanges = [\n ...dataRanges,\n ...documentRanges,\n ...mutationRanges,\n ...mutationReexportRanges,\n ];\n\n if (serverRanges.length === 0) {\n return code;\n }\n\n const removalRanges = [...serverRanges];\n for (const declaration of serverImports) {\n const localNames = asNodeArray(declaration.specifiers)\n .map((specifier) => asNode(specifier.local))\n .filter((local): local is AstNode => local?.type === \"Identifier\")\n .map((local) => String(local.name));\n const masked = maskRanges(code, [\n ...serverRanges,\n { end: declaration.end, start: declaration.start },\n ]);\n const leakedName = localNames.find((name) =>\n new RegExp(`\\\\b${escapeRegExp(name)}\\\\b`).test(masked)\n );\n\n if (leakedName) {\n throw new Error(\n `Server-only import ${JSON.stringify(leakedName)} is used by client route code. Move that use into page data, a document contribution, or a client-safe module.`,\n );\n }\n\n removalRanges.push({ end: declaration.end, start: declaration.start });\n }\n\n return replaceRanges(code, removalRanges, (range) => {\n if (dataRanges.includes(range)) return \"data: undefined\";\n if (documentRanges.includes(range) || mutationRanges.includes(range)) {\n return \"undefined\";\n }\n return mutationReexportRanges.find((entry) => entry === range)\n ?.replacement ?? \"\";\n });\n}\n\nconst unsafeMethodNames = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\nfunction findUnsafeMethodRanges(ast: AstNode) {\n const ranges: Array<{ end: number; start: number }> = [];\n const exportedLocals = new Set<string>();\n\n for (const statement of asNodeArray(ast.body)) {\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n const declaration = asNode(statement.declaration);\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of asNodeArray(declaration.declarations)) {\n const id = asNode(declarator.id);\n if (\n id?.type === \"Identifier\" &&\n unsafeMethodNames.has(String(id.name))\n ) {\n exportedLocals.add(String(id.name));\n }\n }\n }\n\n for (const specifier of asNodeArray(statement.specifiers)) {\n const exported = propertyName(specifier.exported);\n const local = propertyName(specifier.local);\n if (exported && local && unsafeMethodNames.has(exported)) {\n exportedLocals.add(local);\n }\n }\n }\n\n walkAst(ast, (node) => {\n if (node.type !== \"VariableDeclarator\") return;\n const id = asNode(node.id);\n const init = asNode(node.init);\n if (\n id?.type === \"Identifier\" &&\n exportedLocals.has(String(id.name)) &&\n init\n ) {\n ranges.push({ end: init.end, start: init.start });\n }\n });\n\n return ranges;\n}\n\nfunction findUnsafeMethodReexportRanges(ast: AstNode) {\n const ranges: Array<{ end: number; replacement: string; start: number }> = [];\n\n for (const statement of asNodeArray(ast.body)) {\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n const source = asNode(statement.source)?.value;\n if (typeof source !== \"string\") continue;\n\n const safe: string[] = [];\n const unsafe: string[] = [];\n for (const specifier of asNodeArray(statement.specifiers)) {\n const exported = propertyName(specifier.exported);\n const local = propertyName(specifier.local);\n if (!exported || !local) continue;\n if (unsafeMethodNames.has(exported)) {\n unsafe.push(exported);\n } else {\n safe.push(local === exported ? local : `${local} as ${exported}`);\n }\n }\n\n if (unsafe.length === 0) continue;\n const safeExport = safe.length > 0\n ? `export { ${safe.join(\", \")} } from ${JSON.stringify(source)};\\n`\n : \"\";\n const removedExports = unsafe\n .map((name) => `export const ${name} = undefined;`)\n .join(\"\\n\");\n ranges.push({\n end: statement.end,\n replacement: `${safeExport}${removedExports}`,\n start: statement.start,\n });\n }\n\n return ranges;\n}\n\nconst documentContributionNames = new Set([\"links\", \"metadata\", \"scripts\"]);\n\nfunction findDocumentContributionRanges(ast: AstNode) {\n const exportedLocals = new Set<string>();\n\n for (const statement of asNodeArray(ast.body)) {\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n\n const declaration = asNode(statement.declaration);\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of asNodeArray(declaration.declarations)) {\n const id = asNode(declarator.id);\n if (\n id?.type === \"Identifier\" &&\n documentContributionNames.has(String(id.name))\n ) {\n exportedLocals.add(String(id.name));\n }\n }\n }\n\n for (const specifier of asNodeArray(statement.specifiers)) {\n const exported = propertyName(specifier.exported);\n const local = propertyName(specifier.local);\n if (exported && local && documentContributionNames.has(exported)) {\n exportedLocals.add(local);\n }\n }\n }\n\n const ranges: Array<{ end: number; start: number }> = [];\n walkAst(ast, (node) => {\n if (node.type !== \"VariableDeclarator\") return;\n const id = asNode(node.id);\n const init = asNode(node.init);\n if (\n id?.type === \"Identifier\" &&\n exportedLocals.has(String(id.name)) &&\n init\n ) {\n ranges.push({ end: init.end, start: init.start });\n }\n });\n\n return ranges;\n}\n\nfunction isRouteSource(\n root: string,\n options: DemiurgeVitePluginOptions,\n id: string,\n) {\n const file = id.split(\"?\", 1)[0] ?? id;\n const routesRoot = resolve(root, options.routesDir ?? \"src/routes\");\n const pathFromRoutes = relative(routesRoot, file);\n return pathFromRoutes !== \"\" &&\n pathFromRoutes !== \"..\" &&\n !pathFromRoutes.startsWith(`..${sep}`);\n}\n\nfunction walkAst(value: unknown, visit: (node: AstNode) => void) {\n if (!value || typeof value !== \"object\") return;\n if (Array.isArray(value)) {\n for (const item of value) walkAst(item, visit);\n return;\n }\n\n // TYPE-EVIDENCE: the value was checked to be an object. The cast adds the loose AST node shape.\n const node = value as Partial<AstNode>;\n if (typeof node.type !== \"string\") return;\n // TYPE-EVIDENCE: the type field check above confirms the value is an AST node. The cast asserts that node shape.\n visit(node as AstNode);\n for (const [key, child] of Object.entries(node)) {\n if (!new Set([\"end\", \"loc\", \"start\", \"type\"]).has(key)) {\n walkAst(child, visit);\n }\n }\n}\n\nfunction asNode(value: unknown) {\n // TYPE-EVIDENCE: the type in value check confirms the value is an AST node. The cast asserts that node shape.\n return value && typeof value === \"object\" && \"type\" in value\n ? value as AstNode\n : undefined;\n}\n\nfunction asNodeArray(value: unknown) {\n return Array.isArray(value)\n ? value.map(asNode).filter((node): node is AstNode => Boolean(node))\n : [];\n}\n\nfunction isPageCallee(value: unknown) {\n const callee = asNode(value);\n if (callee?.type === \"Identifier\") return callee.name === \"page\";\n return callee?.type === \"MemberExpression\" &&\n propertyName(callee.property) === \"page\";\n}\n\nfunction propertyName(value: unknown) {\n const property = asNode(value);\n return property?.type === \"Identifier\" || property?.type === \"Literal\"\n ? String(property.name ?? property.value)\n : undefined;\n}\n\nfunction isServerOnlyImport(node: AstNode) {\n const source = asNode(node.source)?.value;\n return typeof source === \"string\" &&\n /(?:^|[/.-])server(?:[/.-]|$)/.test(source);\n}\n\nfunction maskRanges(code: string, ranges: Array<{ end: number; start: number }>) {\n const characters = [...code];\n for (const { end, start } of ranges) {\n characters.fill(\" \", start, end);\n }\n return characters.join(\"\");\n}\n\nfunction replaceRanges(\n code: string,\n ranges: Array<{ end: number; start: number }>,\n replacement: (range: { end: number; start: number }) => string,\n) {\n return [...ranges]\n .sort((left, right) => right.start - left.start)\n .reduce(\n (result, range) =>\n `${result.slice(0, range.start)}${replacement(range)}${result.slice(range.end)}`,\n code,\n );\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction createViteConfig(\n config: UserConfig,\n environment: ConfigEnv,\n viteNoncePlaceholder: string,\n): UserConfig {\n return {\n appType: \"custom\",\n build: {\n assetsInlineLimit: config.build?.assetsInlineLimit ?? 0,\n ...(environment.isSsrBuild &&\n config.build?.target === undefined &&\n config.ssr?.target !== \"webworker\"\n ? { target: \"node22.13\" }\n : {}),\n rollupOptions: {\n input: config.build?.rollupOptions?.input ?? CLIENT_ENTRY_ID,\n },\n },\n ...(environment.command === \"serve\"\n ? {\n html: { cspNonce: viteNoncePlaceholder },\n ssr: { external: [PACKAGE_NAME] },\n }\n : {}),\n };\n}\n\ntype EnvModuleInfo = {\n dynamicallyImportedIds: readonly string[];\n importedIds: readonly string[];\n isEntry: boolean;\n} | null;\n\n// A module of a dependency reads the environment of its own process. The scan\n// stays inside the source of the application, where a declared variable is.\nfunction recordClientEnvReferences(\n references: Map<string, string[]>,\n serverEnvKeys: Map<string, { sensitive: boolean }>,\n code: string,\n id: string,\n) {\n if (!serverEnvKeys.size) return;\n if (id.includes(\"/node_modules/\") || id.startsWith(\"\\0\")) return;\n\n const keys = findEnvKeyReferences(code, serverEnvKeys.keys());\n if (keys.length) references.set(id, keys);\n}\n\n// A reference is a defect only when the browser bundle holds the module. The\n// search starts at each entry of the client build and gives the import path.\nfunction collectEnvBoundaryFindings(options: {\n moduleIds: string[];\n moduleInfo: (id: string) => EnvModuleInfo;\n references: Map<string, string[]>;\n root: string;\n serverEnvKeys: Map<string, { sensitive: boolean }>;\n}): EnvBoundaryFinding[] {\n const { moduleIds, moduleInfo, references, root, serverEnvKeys } = options;\n if (!references.size) return [];\n\n const entries = moduleIds.filter((id) => moduleInfo(id)?.isEntry);\n const importsOf = (id: string) => {\n const info = moduleInfo(id);\n return info ? [...info.importedIds, ...info.dynamicallyImportedIds] : [];\n };\n const findings: EnvBoundaryFinding[] = [];\n\n for (const id of [...references.keys()].sort()) {\n const paths = entries\n .map((entry) => findImportPath(entry, id, importsOf))\n .filter((path): path is string[] => Boolean(path))\n .sort((first, second) => first.length - second.length);\n const importPath = paths[0];\n if (!importPath) continue;\n\n for (const key of references.get(id) ?? []) {\n findings.push({\n code: serverEnvKeys.get(key)?.sensitive\n ? \"client-secret\"\n : \"client-server-only\",\n importPath: importPath.map((item) => toDisplayModule(root, item)),\n key,\n module: toDisplayModule(root, id),\n });\n }\n }\n\n return findings;\n}\n\nfunction toDisplayModule(root: string, id: string) {\n const name = id.startsWith(\"\\0\") ? id.slice(1) : id;\n return name.startsWith(root) ? relative(root, name) || name : name;\n}\n\n// A route module loaded only on the server, and a dependency of the framework\n// itself, never enter this check. The build reads only application source,\n// the same rule that the environment boundary check applies.\nfunction checkServerOnlyBoundary(\n markers: Set<string>,\n isBuild: boolean,\n root: string,\n code: string,\n id: string,\n) {\n if (id.includes(\"/node_modules/\") || id.startsWith(\"\\0\")) return;\n if (!importsServerOnlyMarker(code)) return;\n\n if (isBuild) {\n markers.add(id);\n return;\n }\n\n // The development server transforms a module for the browser the same way\n // the build does. There is no client entry graph to search yet, so the\n // error names the module and stops the request immediately.\n throw new Error(formatServerOnlyDevError(toDisplayModule(root, id)));\n}\n\n// A reference is a defect only when the browser bundle holds the module. The\n// search starts at each entry of the client build and gives the import path.\nfunction collectServerOnlyBoundaryFindings(options: {\n markers: Set<string>;\n moduleIds: string[];\n moduleInfo: (id: string) => EnvModuleInfo;\n root: string;\n}): ServerOnlyBoundaryFinding[] {\n const { markers, moduleIds, moduleInfo, root } = options;\n if (!markers.size) return [];\n\n const entries = moduleIds.filter((id) => moduleInfo(id)?.isEntry);\n const importsOf = (id: string) => {\n const info = moduleInfo(id);\n return info ? [...info.importedIds, ...info.dynamicallyImportedIds] : [];\n };\n const findings: ServerOnlyBoundaryFinding[] = [];\n\n for (const id of [...markers].sort()) {\n const paths = entries\n .map((entry) => findImportPath(entry, id, importsOf))\n .filter((path): path is string[] => Boolean(path))\n .sort((first, second) => first.length - second.length);\n const importPath = paths[0];\n if (!importPath) continue;\n\n findings.push({\n importPath: importPath.map((item) => toDisplayModule(root, item)),\n module: toDisplayModule(root, id),\n });\n }\n\n return findings;\n}\n\n// The build inlines the value of each client variable. The browser then\n// validates the values with the schema that the configuration file declares.\nexport function createClientEnvSource(\n options: DemiurgeVitePluginOptions = {},\n source: EnvSource = process.env,\n) {\n const clientVariables = Object.entries(options.env ?? {})\n .filter(([, variable]) => variable.client);\n\n if (!clientVariables.length) return \"\";\n\n const absent = clientVariables.filter(([key, variable]) =>\n !variable.optional && !source[key]\n );\n\n if (absent.length) {\n throw new Error(\n [\n \"Demiurge stopped the build. The environment of the build does not have a required client variable.\",\n ...absent.map(([key]) => ` variable: ${key}`),\n \" The build inlines the value of a client variable. Give the value to the build.\",\n ].join(\"\\n\"),\n );\n }\n\n // The build inlines the value of a client variable, so the build validates\n // the value here. A deferred client variable does not exist, because the\n // type of the builder refuses that combination.\n const invalid = clientVariables\n .filter(([key]) => source[key] !== undefined)\n .flatMap(([key, variable]) => {\n // TYPE-EVIDENCE: the filter above proves the source has a value for this key.\n const rawValue = source[key] as string;\n try {\n variable.parse(key, rawValue);\n return [];\n } catch (error) {\n return [{\n key,\n message: error instanceof Error\n ? error.message\n : `Environment variable ${key} is invalid.`,\n }];\n }\n });\n\n if (invalid.length) {\n throw new Error(\n [\n \"Demiurge stopped the build. The environment of the build has an invalid client variable.\",\n ...invalid.map(({ key, message }) => ` variable: ${key}\\n ${message}`),\n ].join(\"\\n\"),\n );\n }\n\n const descriptor = serializeEnvSchema(Object.fromEntries(clientVariables));\n const values = Object.fromEntries(\n clientVariables\n .map(([key]) => [key, source[key]])\n .filter(([, value]) => value !== undefined),\n );\n\n return `\n// The build put these values in the browser bundle. The schema declares each\n// one as a client variable.\nunstable_startEnvironment(${JSON.stringify(descriptor)}, { source: ${\n JSON.stringify(values)\n } });\n`;\n}\n\nexport function createClientEntrySource(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n source: EnvSource = process.env,\n) {\n const routesDir = options.routesDir ?? \"src/routes\";\n const stylesImport = createStylesImport(root, options);\n const environmentSource = createClientEnvSource(options, source);\n const environmentImport = environmentSource\n ? \", unstable_startEnvironment\"\n : \"\";\n\n return `import { hydrateFileRouter${environmentImport} } from \"${PACKAGE_NAME}\";\n${stylesImport}\n${environmentSource}\n${createRouteMapSource(routesDir, {\n exportRoutes: false,\n includeServerOnly: false,\n })}\n\nvoid hydrateFileRouter({ routes${options.locales ? `, locales: ${JSON.stringify(options.locales)}` : \"\"} });\n`;\n}\n\nexport function createServerEntrySource(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n) {\n const routesDir = options.routesDir ?? \"src/routes\";\n const hasEnv = Boolean(options.env && Object.keys(options.env).length);\n const environmentImport = hasEnv ? \", unstable_startEnvironment\" : \"\";\n const environmentSource = hasEnv\n ? `\n// The framework validates the declared environment before the server accepts\n// traffic. A required variable that is absent or invalid stops the start. A\n// deferred variable validates on its first server access.\nexport const env = unstable_startEnvironment(${\n JSON.stringify(serializeEnvSchema(options.env ?? {}))\n }).values;\n`\n : \"\";\n\n return `import { createRequestHandler${environmentImport} } from \"${PACKAGE_NAME}\";\n${environmentSource}\n${createRouteMapSource(routesDir, {\n exportRoutes: true,\n includeServerOnly: true,\n eagerModules: true,\n })}\n\nexport function createHandler(options = {}) {\n const { clientEntry, lang, locales, styles, title, ...handlerOptions } = options;\n\n return createRequestHandler({\n ...handlerOptions,\n routes,\n routeModules,\n locales: locales ?? ${JSON.stringify(options.locales)},\n ssr: {\n clientEntry,\n lang: lang ?? ${JSON.stringify(options.document?.lang)},\n styles,\n title: title ?? ${JSON.stringify(options.document?.title)},\n },\n });\n}\n`;\n}\n\n// The development server does not load the generated server entry, so it\n// starts the declared environment here instead. A required variable that is\n// absent or invalid stops the start of the development server. Vite resolves\n// the configuration before it creates the file watcher, so a failure in this\n// hook rejects `createServer` and leaves no open handle. A failure in\n// `configureServer` would instead hold the process open after the diagnostic.\nfunction startDevEnvironment(options: DemiurgeVitePluginOptions) {\n if (!options.env || !Object.keys(options.env).length) return;\n\n startEnvironment(options.env);\n}\n\n// Both virtual entries use this function. Therefore, their prefix removal and\n// route-key formats stay equal. The server entry requires framework-attached\n// `.ts` files such as `@policy.ts` and `@middleware.ts`. Previously, a\n// `.tsx`-only glob omitted these files from production. Development still found\n// and applied them.\nfunction createRouteMapSource(\n routesDir: string,\n {\n exportRoutes,\n eagerModules = false,\n includeServerOnly,\n }: {\n eagerModules?: boolean;\n exportRoutes: boolean;\n includeServerOnly: boolean;\n },\n) {\n const routesGlobs = toRootAbsoluteGlobs(routesDir, includeServerOnly);\n const routesPrefix = toRootAbsolutePrefix(routesDir);\n\n return eagerModules\n ? `const eagerRouteModules = import.meta.glob(${JSON.stringify(routesGlobs)}, { eager: true });\nconst routePrefix = ${JSON.stringify(routesPrefix)};\nexport const routeModules = Object.fromEntries(\n Object.entries(eagerRouteModules).map(([file, module]) => [\n \\`./routes/\\${file.slice(routePrefix.length)}\\`,\n module,\n ]),\n);\n${exportRoutes ? \"export \" : \"\"}const routes = Object.fromEntries(\n Object.entries(routeModules).map(([file, module]) => [\n file,\n async () => module,\n ]),\n);`\n : `const routeModules = import.meta.glob(${JSON.stringify(routesGlobs)});\nconst routePrefix = ${JSON.stringify(routesPrefix)};\n${exportRoutes ? \"export \" : \"\"}const routes = Object.fromEntries(\n Object.entries(routeModules).map(([file, load]) => [\n \\`./routes/\\${file.slice(routePrefix.length)}\\`,\n load,\n ]),\n);`;\n}\n\n// These two files run only on the server. They control a request before the\n// route runs and do not render. A client glob would create public chunks in\n// `dist/client`. These chunks could expose credentials, authorization logic, or\n// internal host names from a middleware or policy closure.\nconst serverOnlyRouteFiles = [\"@middleware.ts\", \"@policy.ts\"];\n\nfunction toRootAbsoluteGlobs(routesDir: string, includeServerOnly: boolean) {\n const base = `/${routesDir.replace(/^\\/|\\/$/g, \"\")}`;\n const globs = [`${base}/**/*.{ts,tsx}`];\n\n if (!includeServerOnly) {\n globs.push(\n ...serverOnlyRouteFiles.flatMap((fileName) => [\n `!${base}/${fileName}`,\n `!${base}/**/${fileName}`,\n ]),\n );\n }\n\n return globs;\n}\n\nfunction toRootAbsolutePrefix(routesDir: string) {\n return `/${routesDir.replace(/^\\/|\\/$/g, \"\")}/`;\n}\n\nfunction createStylesImport(\n root: string,\n options: DemiurgeVitePluginOptions,\n) {\n if (options.styles === false) {\n return \"\";\n }\n\n const stylesFile = options.styles ?? \"src/styles.css\";\n const resolvedStylesFile = resolve(root, stylesFile);\n\n return existsSync(resolvedStylesFile)\n ? `import ${JSON.stringify(`/${stylesFile.replace(/^\\/+/, \"\")}`)};`\n : \"\";\n}\n\n// Development serves the same image URLs that production serves. A static\n// loader path describes its own transform, so the same optimizer answers\n// both loaders without any build output.\n// Only `configureServer` registers the route audit panel, and Vite runs that\n// hook for the development server alone. A production environment removes the\n// panel as well, because a build or a start script can set that environment.\nexport function isRouteAuditEnabled(options: DemiurgeVitePluginOptions) {\n return options.devtools !== false && process.env.NODE_ENV !== \"production\";\n}\n\nexport function createDevImageOptimizer(\n server: ViteDevServer,\n options: DemiurgeVitePluginOptions,\n) {\n const publicDir = server.config.publicDir;\n const optimizerPath = options.images?.optimizerPath ?? \"/_demiurge/image\";\n\n if (!publicDir) {\n return async () => null;\n }\n\n return createImageOptimizer({\n policy: options.images,\n resolveVariant: (pathname) =>\n parseImageVariantPath(pathname, optimizerPath),\n root: publicDir,\n });\n}\n\n// Development renders through the production pipeline. It adds the virtual\n// client entry, the Vite HTML transform, and a development flag for stack\n// traces. The shared handler makes all security and routing decisions.\nfunction createDevRuntimeOptions(\n options: DemiurgeVitePluginOptions,\n transformDocument: (html: string) => Promise<string>,\n) {\n return {\n dev: true,\n ssr: createDevSsrOptions(options),\n transformDocument,\n renderPage: async (\n match: Parameters<PageRenderer>[0],\n renderOptions: Parameters<PageRenderer>[1],\n ) => {\n if (match.render.mode === \"streaming\") {\n return await renderStreamingPageResponse(match, {\n ...renderOptions,\n clientEntry: DEV_CLIENT_ENTRY_PATH,\n transformDocument,\n });\n }\n\n const html = await transformDocument(\n renderPageDocument(match, {\n ...renderOptions,\n clientEntry: DEV_CLIENT_ENTRY_PATH,\n }),\n );\n\n return new Response(html, {\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n });\n },\n };\n}\n\nfunction createDevDocumentSecurity(\n server: ViteDevServer,\n viteNoncePlaceholder: string,\n) {\n const nonce = createCspNonce();\n const shieldNonce = createCspNonce();\n\n return {\n nonce,\n transform: async (html: string) => {\n const shielded = shieldViteNonceTargets(html, shieldNonce);\n const transformed = await server.transformIndexHtml(\"/\", shielded);\n\n return replaceNonceAttribute(\n replaceNonceAttribute(transformed, shieldNonce),\n viteNoncePlaceholder,\n nonce,\n );\n },\n };\n}\n\nfunction shieldViteNonceTargets(html: string, nonce: string) {\n const lowerHtml = html.toLowerCase();\n let cursor = 0;\n let output = \"\";\n\n while (cursor < html.length) {\n const tagStart = html.indexOf(\"<\", cursor);\n\n if (tagStart === -1) {\n return output + html.slice(cursor);\n }\n\n output += html.slice(cursor, tagStart);\n\n if (lowerHtml.startsWith(\"<!--\", tagStart)) {\n const commentEnd = lowerHtml.indexOf(\"-->\", tagStart + 4);\n const end = commentEnd === -1 ? html.length : commentEnd + 3;\n output += html.slice(tagStart, end);\n cursor = end;\n continue;\n }\n\n const name = lowerHtml.slice(tagStart).match(/^<\\s*(script|style|link)\\b/)?.[1];\n\n if (!name) {\n output += \"<\";\n cursor = tagStart + 1;\n continue;\n }\n\n const tagEnd = findHtmlTagEnd(html, tagStart);\n\n if (tagEnd === -1) {\n return output + html.slice(tagStart);\n }\n\n const openingTag = html.slice(tagStart, tagEnd + 1);\n output += /(?:^|\\s)nonce(?:\\s|=|>)/i.test(openingTag)\n ? openingTag\n : addNonceAttribute(openingTag, nonce);\n cursor = tagEnd + 1;\n\n if (name === \"script\" || name === \"style\") {\n const closeStart = lowerHtml.indexOf(`</${name}`, cursor);\n\n if (closeStart === -1) {\n return output + html.slice(cursor);\n }\n\n output += html.slice(cursor, closeStart);\n cursor = closeStart;\n }\n }\n\n return output;\n}\n\nfunction findHtmlTagEnd(html: string, start: number) {\n let quote: \"\\\"\" | \"'\" | undefined;\n\n for (let index = start + 1; index < html.length; index++) {\n const character = html[index];\n\n if (quote) {\n if (character === quote) quote = undefined;\n continue;\n }\n\n if (character === \"\\\"\" || character === \"'\") {\n quote = character;\n } else if (character === \">\") {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction addNonceAttribute(openingTag: string, nonce: string) {\n const insertion = /\\/\\s*>$/.test(openingTag)\n ? openingTag.lastIndexOf(\"/\")\n : openingTag.length - 1;\n\n return `${openingTag.slice(0, insertion)} nonce=\"${nonce}\"${openingTag.slice(insertion)}`;\n}\n\nfunction replaceNonceAttribute(\n html: string,\n current: string,\n replacement?: string,\n) {\n const pattern = new RegExp(\n `(\\\\snonce\\\\s*=\\\\s*)([\"'])${escapeRegExp(current)}\\\\2`,\n \"g\",\n );\n\n return html.replace(\n pattern,\n replacement ? `$1\"${replacement}\"` : \"\",\n );\n}\n\nfunction applyDevDocumentSecurity(response: Response, nonce: string) {\n const contentType = response.headers.get(\"content-type\");\n const csp = response.headers.get(\"content-security-policy\");\n\n if (!contentType?.toLowerCase().startsWith(\"text/html\") || !csp) {\n return;\n }\n\n const source = `'nonce-${nonce}'`;\n const withScriptNonce = addCspSource(\n csp,\n [\"script-src-elem\", \"script-src\"],\n \"script-src\",\n source,\n );\n const withStyleNonce = allowsUnsafeInline(\n withScriptNonce,\n [\"style-src-elem\", \"style-src\"],\n )\n ? withScriptNonce\n : addCspSource(\n withScriptNonce,\n [\"style-src-elem\", \"style-src\"],\n \"style-src\",\n source,\n );\n\n response.headers.set(\"content-security-policy\", withStyleNonce);\n response.headers.set(\"cache-control\", \"private, no-store\");\n}\n\nfunction addCspSource(\n csp: string,\n directiveNames: readonly string[],\n fallbackDirectiveName: \"script-src\" | \"style-src\",\n source: string,\n) {\n const directives = csp.split(\";\").map((directive) => directive.trim());\n const directiveIndex = findCspDirectiveIndex(directives, directiveNames);\n\n const defaultDirective = directives.find((directive) =>\n directive.split(/\\s+/, 1)[0]?.toLowerCase() === \"default-src\"\n );\n\n if (directiveIndex === -1 && !defaultDirective) return csp;\n\n const [currentName, ...currentSources] =\n (directiveIndex === -1 ? defaultDirective! : directives[directiveIndex]!)\n .split(/\\s+/);\n const updatedDirective = [\n directiveIndex === -1 ? fallbackDirectiveName : currentName!,\n ...new Set([\n ...currentSources.filter((current) => current !== \"'none'\"),\n source,\n ]),\n ].join(\" \");\n\n if (directiveIndex === -1) {\n directives.push(updatedDirective);\n } else {\n directives[directiveIndex] = updatedDirective;\n }\n\n return directives.join(\"; \");\n}\n\nfunction allowsUnsafeInline(\n csp: string,\n directiveNames: readonly string[],\n) {\n const directives = csp.split(\";\").map((directive) => directive.trim());\n const directiveIndex = findCspDirectiveIndex(directives, directiveNames);\n const effectiveDirective = directiveIndex === -1\n ? directives.find((directive) =>\n directive.split(/\\s+/, 1)[0]?.toLowerCase() === \"default-src\"\n )\n : directives[directiveIndex];\n const sources = effectiveDirective?.split(/\\s+/).slice(1) ?? [];\n\n return sources.includes(\"'unsafe-inline'\") &&\n !sources.some((source) => /^'(?:nonce-|sha(?:256|384|512)-)/i.test(source));\n}\n\nfunction findCspDirectiveIndex(\n directives: readonly string[],\n directiveNames: readonly string[],\n) {\n for (const name of directiveNames) {\n const index = directives.findIndex((directive) =>\n directive.split(/\\s+/, 1)[0]?.toLowerCase() === name\n );\n\n if (index !== -1) return index;\n }\n\n return -1;\n}\n\n// Both dev middlewares need the manifest for the same request, and building\n// it walks the routes directory. The pre middleware always runs, so the post\n// middleware reuses what it already produced rather than scanning twice on\n// every unmatched request.\nconst DEV_MANIFEST = Symbol.for(\"demiurge.devManifest\");\n\ntype DevManifestCarrier = { [DEV_MANIFEST]?: RouteManifest };\n\nasync function loadDevManifest(\n server: ViteDevServer,\n request: IncomingMessage,\n routesDir: string,\n) {\n // TYPE-EVIDENCE: the cast adds the symbol-keyed manifest carrier field used for request-local caching.\n const carrier = request as IncomingMessage & DevManifestCarrier;\n const cached = carrier[DEV_MANIFEST];\n\n if (cached) {\n return cached;\n }\n\n const manifest = createRouteManifest(\n await createDevRouteImporters(server, routesDir),\n );\n\n carrier[DEV_MANIFEST] = manifest;\n\n return manifest;\n}\n\nfunction createDevSsrOptions(options: DemiurgeVitePluginOptions) {\n return {\n clientEntry: DEV_CLIENT_ENTRY_PATH,\n lang: options.document?.lang,\n title: options.document?.title,\n };\n}\n\nfunction createDevFallbackOptions(\n options: DemiurgeVitePluginOptions,\n transformDocument: (html: string) => Promise<string>,\n) {\n return {\n ...createDevSsrOptions(options),\n dev: true,\n transformDocument,\n };\n}\n\nconst warnedRoots = new Set<string>();\n\n// The framework built-in is a temporary fallback, not a production 404. The\n// build gate enforces this rule. This warning gives the same message earlier.\nfunction warnMissingRootNotFound(manifest: RouteManifest, routesDir: string) {\n if (\n warnedRoots.has(routesDir) ||\n manifest.fallbacks.notFound.some(\n (fallback) => fallback.fileSegments.length === 0,\n )\n ) {\n return;\n }\n\n warnedRoots.add(routesDir);\n console.warn(missingRootNotFoundMessage(join(routesDir, \"@not-found.tsx\")));\n}\n\n// The framework ships a working 404 so nothing is ever blank, and refuses to\n// let an app reach production still rendering it. A generic framework page in\n// front of real users is a failure of the framework, not of the app that never\n// got around to it.\nexport async function assertRootNotFoundRoute(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n) {\n const routesDirOption = options.routesDir ?? \"src/routes\";\n const routesDir = resolve(root, routesDirOption);\n\n if (!existsSync(routesDir)) {\n return;\n }\n\n const files = await findRouteFiles(routesDir);\n const names = files.map((file) =>\n relative(routesDir, file).split(sep).join(\"/\"),\n );\n\n if (names.some((name) => /^@not-found\\.tsx?$/.test(name))) {\n return;\n }\n\n const pageRoute = await findPageRouteFile(files);\n\n // An API-only app never wants an HTML not-found document, and nagging it\n // would be user hostile. It builds clean and gets problem+json.\n if (!pageRoute) {\n return;\n }\n\n throw new Error(\n missingRootNotFoundBuildMessage(\n routesDirOption,\n relative(routesDir, pageRoute).split(sep).join(\"/\"),\n ),\n );\n}\n\n// Page detection is a source scan rather than a module evaluation: the plugin\n// cannot execute route modules at build time. A page route is a file that\n// calls `page(...)`, which is the only way to declare one.\nasync function findPageRouteFile(files: string[]) {\n for (const file of files) {\n // Framework-attached files own no address, so they are never page routes.\n if (relative(dirname(file), file).startsWith(\"@\")) {\n continue;\n }\n\n if (declaresPageRoute(await readFile(file, \"utf8\"))) {\n return file;\n }\n }\n\n return undefined;\n}\n\nexport function missingRootNotFoundBuildMessage(\n routesDir: string,\n pageRoute: string,\n) {\n return `Demiurge will not build an app with page routes and no ${routesDir}/@not-found.tsx.\n\n\"${pageRoute}\" declares a page, so a browser can reach a path this app does not serve. Decide what that looks like rather than shipping the framework built-in.\n\nCreate ${routesDir}/@not-found.tsx:\n\n export default function NotFound({ pathname }: { pathname: string }) {\n return <h1>Nothing at {pathname}</h1>;\n }\n\nIt renders inside the layouts above the requested path. Opt out with \"export const layout = false\".`;\n}\n\nexport function missingRootNotFoundMessage(notFoundFile: string) {\n return `Demiurge is serving its built-in 404 because ${notFoundFile} does not exist.\n\nCreate it before building for production:\n\n export default function NotFound({ pathname }: { pathname: string }) {\n return <h1>Nothing at {pathname}</h1>;\n }\n`;\n}\n\nexport function createDocumentHtml({\n entrySrc,\n lang,\n links,\n metadata,\n nonce,\n scripts,\n styles,\n title,\n}: {\n entrySrc: string;\n lang?: string;\n links?: LinkTag[];\n metadata?: ResolvedMetadata;\n nonce?: string;\n scripts?: ScriptTag[];\n styles?: string[];\n title?: string;\n}) {\n return renderDocument({\n entrySrc,\n lang,\n links,\n metadata,\n nonce,\n scripts,\n styles,\n title,\n });\n}\n\nasync function generateTypedRoutes(\n root: string,\n options: DemiurgeVitePluginOptions,\n) {\n const routesDir = resolve(root, options.routesDir ?? \"src/routes\");\n const outputFile = resolve(\n root,\n typeof options.typedRoutes === \"object\"\n ? options.typedRoutes.outputFile ?? DEFAULT_TYPED_ROUTES_OUTPUT\n : DEFAULT_TYPED_ROUTES_OUTPUT,\n );\n\n await generateRoutes({\n outputFile,\n routesDir,\n locales: options.locales?.supportedLocales,\n localeNamespaces: [\n ...Object.values(options.locales?.path?.labels ?? {}),\n ...Object.keys(options.locales?.aliases ?? {}),\n ...(options.locales?.path?.reserved ?? []),\n ],\n });\n}\n\nfunction isRouteFile(routesDir: string, file: string) {\n return (\n file.startsWith(routesDir) &&\n /\\.tsx?$/.test(file)\n );\n}\n\nexport async function createDevRouteImporters(\n server: ViteDevServer,\n routesDir: string,\n) {\n const files = await findRouteFiles(routesDir);\n const routes: Record<string, RouteImporter> = {};\n\n for (const file of files) {\n const routeKey = toRouteKey(routesDir, file);\n // TYPE-EVIDENCE: the SSR loader returns a module record for a route file. The cast labels it as a route module.\n routes[routeKey] = async () =>\n (await server.ssrLoadModule(file)) as RouteModule;\n }\n\n return routes;\n}\n\nexport async function handleDevRequest(\n manifest: RouteManifest,\n request: Request,\n options: Parameters<typeof handleRequestWithManifest>[2] = {},\n) {\n const url = new URL(request.url);\n const routeMatch = findRouteMatch(manifest.routes, url.pathname);\n\n if (!routeMatch) {\n return \"next\" as const;\n }\n\n return await handleRequestWithManifest(manifest, request, options);\n}\n\nasync function findRouteFiles(directory: string) {\n const entries = await readdir(directory, {\n recursive: true,\n withFileTypes: true,\n });\n\n return entries\n .filter((entry) => entry.isFile() && /\\.tsx?$/.test(entry.name))\n .map((entry) => resolve(entry.parentPath, entry.name));\n}\n\n// Every route file is read and parsed. Without a cap, a large route tree opens\n// one descriptor per file at once, which is how this hits EMFILE rather than a\n// CPU limit.\nconst policyVerificationConcurrency = 8;\nconst policyVerificationDebounceMs = 50;\n\nasync function mapWithConcurrency<Item, Result>(\n items: readonly Item[],\n limit: number,\n task: (item: Item) => Promise<Result>,\n) {\n const results = new Array<Result>(items.length);\n let next = 0;\n\n const workers = Array.from(\n { length: Math.min(limit, items.length) },\n async () => {\n while (next < items.length) {\n const index = next++;\n results[index] = await task(items[index]!);\n }\n },\n );\n\n await Promise.all(workers);\n\n return results;\n}\n\n/** The result of one static pass over the route tree. */\nexport type RoutePolicyInspection = {\n /** Every finding of the pass, in a stable order. */\n findings: StaticPolicyFinding[];\n /** The inspection of each route file, in the order that the walk found. */\n inspections: RouteFileInspection[];\n /** The absolute path of the route directory. */\n routesDir: string;\n};\n\n/**\n * Reads the route tree once and returns the findings and the inspections.\n *\n * The build verifier and the `demiurge inspect` command both call this\n * function, so one pass gives one answer for the route tree.\n */\nexport async function inspectRoutePolicies(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n): Promise<RoutePolicyInspection> {\n const routesDir = resolve(root, options.routesDir ?? \"src/routes\");\n\n if (!existsSync(routesDir)) {\n return { findings: [], inspections: [], routesDir };\n }\n\n const inspections = await mapWithConcurrency(\n await findRouteFiles(routesDir),\n policyVerificationConcurrency,\n inspectRouteFile,\n );\n const findings = [\n ...inspections.flatMap((inspection) => inspection.findings),\n ...auditDocumentPolicyCoverage(routesDir, inspections),\n ...auditRouteAccessCoverage(routesDir, inspections),\n ];\n\n findings.sort((left, right) =>\n left.file.localeCompare(right.file) ||\n (left.exportName ?? \"\").localeCompare(right.exportName ?? \"\") ||\n left.code.localeCompare(right.code)\n );\n\n return { findings, inspections, routesDir };\n}\n\nexport async function verifyRoutePolicies(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n) {\n return (await inspectRoutePolicies(root, options)).findings;\n}\n\nexport function formatStaticPolicyFindings(findings: StaticPolicyFinding[]) {\n return [\n \"Demiurge found invalid static route policy:\",\n ...findings.map(formatStaticPolicyFinding),\n ].join(\"\\n\");\n}\n\nexport function formatStaticPolicyFinding(finding: StaticPolicyFinding) {\n const source = finding.exportName\n ? `${finding.file} export ${finding.exportName}`\n : finding.file;\n return `${source}: [${finding.code}] ${finding.message}`;\n}\n\nfunction toRouteKey(routesDir: string, file: string) {\n const relativePath = relative(routesDir, file).split(sep).join(\"/\");\n return `./routes/${relativePath}`;\n}\n"],"names":["PACKAGE_NAME","generateRoutes","options","routeFiles","findRouteFiles","middleware","file","toMiddlewareInfo","value","routes","toRouteInfo","route","a","b","assertLocaleNamespaceCollisions","source","renderRoutesModule","mkdir","dirname","writeFile","namespaces","localeSegments","segment","directory","readdir","entry","resolve","fileSegments","relative","sep","urlSegments","isRouteGroupSegment","pathVars","isAttachedFileForRoute","toImportPath","outputFile","importPath","attachedFileSegments","routeFileSegments","index","locales","renderMiddlewareImport","_entry","renderMiddlewareContextAlias","locale","renderPathVarsEntry","renderConcretePathEntry","renderRequestContextEntry","renderMutationMethodsEntry","pathType","name","toConcretePathType","contexts","context","pattern","part","escapeTemplate","findServerEnvKeys","schema","keys","key","variable","findEnvKeyReferences","code","names","found","visitNode","parseAst","findImportPath","target","importsOf","visited","queue","path","next","formatEnvBoundaryFindings","findings","formatEnvBoundaryFinding","finding","node","match","visitValue","visitKey","isPatternProperty","visitOwnChildren","asNode","computed","child","item","serverOnlyMarkerSpecifiers","importsServerOnlyMarker","findsMarkerImport","formatServerOnlyBoundaryFindings","formatServerOnlyBoundaryFinding","formatServerOnlyDevError","module","ast","walkAst","isMarkerSource","visit","httpMethods","responseHelpers","inspectRouteFile","readFile","extracted","extractRouteModuleSource","attached","basename","declaresPageRoute","validateExtractedRouteModule","method","verifyRoutePolicySource","loader","transformed","transformWithEsbuild","extractRouteModule","auditDocumentPolicyCoverage","routesDir","inspections","policies","inspection","isPolicyFile","isFallbackDocumentFile","applicable","applicablePolicies","resolveDocumentCspState","describeMissingDocumentPolicy","auditRouteAccessCoverage","resolveRouteAccessState","routeDirectory","routeState","isSameOrAbove","state","policy","exception","nearest","join","left","right","mergeDocumentCspState","base","override","distance","PACKAGE_NAME_PATTERN","DEMIURGE_NAMED_IMPORT","locals","binding","imported","local","body","imports","collectCoreImports","constants","collectConstants","declarations","collectVariableInitializers","exports","collectNamedExports","capabilities","declaredMethods","accessState","declaresDocumentPolicy","documentCspState","exportName","localName","initializer","extractAccessState","extractDocumentCspState","extractRoutePolicy","isHttpMethod","capability","extractCapability","isPlainObject","identifierName","argument","asNodeArray","property","propertyName","extractDocumentCspStateFromValue","callee","objectName","preset","extractPresetCspState","extractDocumentSecurityCspState","literal","evaluateLiteral","unresolved","extractCspValueState","optionsNode","defaultState","mergePresetCspState","extractCspOptionState","isSecurityException","statement","declaration","declarator","specifier","exported","helper","arguments_","cors","evaluateObjectProperty","securityPolicy","result","valueNode","document","extractSecurityPolicy","security","routeModule","availableMethods","validateCorsPolicy","error","errorMessage","validateRateLimit","validateExceptionReasons","createSecurityHeaders","toFragmentDocument","endpoints","declaresEndpoints","declaredCsp","resolveCsp","reportTo","statesNoReason","validateRaisedBodyLimit","declared","getBodySizeException","declaredBytes","defaultBytes","parseBodySize","resolveMaxBodySize","DEFAULT_MAX_BODY_SIZE","validateRateLimitPolicy","message","quasi","values","element","fallback","REDACTED_VALUE","cookieFieldNames","sessionFieldNames","cookieValueFieldNames","sessionValueFieldNames","serializeInspectionReport","report","redactSecrets","attachRedactions","redactions","walk","isRecord","scope","isSessionRecord","itemPath","reason","classifyField","descend","normalized","normalizeFieldName","prototype","ROUTE_AUDIT_VERSION","ROUTE_AUDIT_PATH","supportedMethods","routeAuditResolutions","isRouteAuditRequest","request","createRouteAuditResponse","manifest","url","createRouteAudit","json","renderRouteAuditDocument","origin","pathname","routeRequest","routeMatch","matchRoute","loadInheritedRoutePolicy","finishRouteAudit","selectMethod","cacheReads","page","loadPageRoute","createRecordingCache","layout","toRoutePattern","input","nonce","securityPolicyRequiresNonce","createCspNonce","scripts","script","auditOptions","createSecurityAudit","findRouteMatch","MalformedPathnameError","reads","cache","createMemoryCache","serializeCacheKey","formatDuration","serializeCacheTag","duration","panelStyles","escapeHtml","renderRouteSection","renderFindingsSection","renderHeadersSection","renderPolicySection","renderMetadataSection","renderScriptsSection","renderCacheSection","section","table","none","entries","list","renderFinding","headers","metadata","rows","read","title","CLIENT_ENTRY_ID","DEV_CLIENT_ENTRY_PATH","RESOLVED_CLIENT_ENTRY_ID","SERVER_ENTRY_ID","RESOLVED_SERVER_ENTRY_ID","DEFAULT_TYPED_ROUTES_OUTPUT","demiurge","defineLocales","root","isBuild","serverEnvKeys","clientEnvReferences","serverOnlyMarkers","viteNoncePlaceholder","config","environment","createViteConfig","startDevEnvironment","id","createClientEntrySource","createServerEntrySource","transformOptions","checkServerOnlyBoundary","recordClientEnvReferences","isRouteSource","protectSsrImportMeta","stripClientPageData","_outputOptions","bundle","styles","asset","clientEntry","createDocumentHtml","collectEnvBoundaryFindings","serverOnlyFindings","collectServerOnlyBoundaryFindings","assertRootNotFoundRoute","verifyRoutePolicies","errors","formatStaticPolicyFinding","formatStaticPolicyFindings","generateTypedRoutes","server","reportPolicyFindings","policyVerificationTimer","policyVerificationRun","runPolicyVerification","startPolicyVerification","policyVerificationDebounceMs","runGenerateTypedRoutes","isRouteFile","event","routeAuditEnabled","isRouteAuditEnabled","optimizeImage","createDevImageOptimizer","serveFont","createFontAssetHandler","response","webRequest","toWebRequest","UnsupportedMethodError","writeNotImplemented","loadDevManifest","writeWebResponse","font","image","documentSecurity","createDevDocumentSecurity","handleDevRequest","createDevRuntimeOptions","applyDevDocumentSecurity","warnMissingRootNotFound","notFoundResponse","renderNotFoundResponse","createDevFallbackOptions","candidate","alias","editor","MagicString","dataRanges","documentRanges","findDocumentContributionRanges","mutationRanges","findUnsafeMethodRanges","mutationReexportRanges","findUnsafeMethodReexportRanges","serverImports","isServerOnlyImport","isPageCallee","serverRanges","removalRanges","localNames","masked","maskRanges","leakedName","escapeRegExp","replaceRanges","range","unsafeMethodNames","ranges","exportedLocals","init","safe","unsafe","safeExport","removedExports","documentContributionNames","routesRoot","pathFromRoutes","characters","end","start","replacement","references","moduleIds","moduleInfo","info","first","second","toDisplayModule","markers","createClientEnvSource","clientVariables","absent","invalid","rawValue","descriptor","serializeEnvSchema","stylesImport","createStylesImport","environmentSource","createRouteMapSource","hasEnv","environmentImport","startEnvironment","exportRoutes","eagerModules","includeServerOnly","routesGlobs","toRootAbsoluteGlobs","routesPrefix","toRootAbsolutePrefix","serverOnlyRouteFiles","globs","fileName","stylesFile","resolvedStylesFile","existsSync","publicDir","optimizerPath","createImageOptimizer","parseImageVariantPath","transformDocument","createDevSsrOptions","renderOptions","renderStreamingPageResponse","html","renderPageDocument","shieldNonce","shielded","shieldViteNonceTargets","replaceNonceAttribute","lowerHtml","cursor","output","tagStart","commentEnd","tagEnd","findHtmlTagEnd","openingTag","addNonceAttribute","closeStart","quote","character","insertion","current","contentType","csp","withScriptNonce","addCspSource","withStyleNonce","allowsUnsafeInline","directiveNames","fallbackDirectiveName","directives","directive","directiveIndex","findCspDirectiveIndex","defaultDirective","currentName","currentSources","updatedDirective","sources","DEV_MANIFEST","carrier","cached","createRouteManifest","createDevRouteImporters","warnedRoots","missingRootNotFoundMessage","routesDirOption","files","pageRoute","findPageRouteFile","missingRootNotFoundBuildMessage","notFoundFile","entrySrc","lang","links","renderDocument","routeKey","toRouteKey","handleRequestWithManifest","policyVerificationConcurrency","mapWithConcurrency","items","limit","task","results","workers","inspectRoutePolicies"],"mappings":"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"}
1
+ {"version":3,"file":"plugin-bkP6WwrS.js","sources":["../../src/package-name.ts","../../src/routing/generate.ts","../../src/vite/env-boundary.ts","../../src/vite/server-only-boundary.ts","../../src/vite/policy-verification.ts","../../src/inspect/redact.ts","../../src/vite/route-audit.ts","../../src/vite/plugin.ts"],"sourcesContent":["// The package name is the specifier that user code imports. Generated client\n// entries, server entries, and route type declarations use it. Page route\n// detection also compares application source with it. A mismatch then breaks\n// resolution in the consumer build.\n//\n// This is deliberately not the same thing as the many internal `demiurge`\n// strings elsewhere in the source. `__demiurge_data`, `virtual:demiurge/*`,\n// `demiurge-manifest.json`, and friends name the framework, not the package,\n// and they stay put if the registry name ever changes.\nexport const PACKAGE_NAME = \"@demiurgejs/core\";\n","import { mkdir, readdir, writeFile } from \"node:fs/promises\";\nimport { dirname, relative, resolve, sep } from \"node:path\";\nimport { PACKAGE_NAME } from \"../package-name\";\n\nexport type GenerateRoutesOptions = {\n locales?: readonly string[];\n localeNamespaces?: readonly string[];\n outputFile: string;\n routesDir: string;\n};\n\ntype RouteInfo = {\n contextMiddleware: number[];\n fileSegments: string[];\n importPath: string;\n pathVars: string[];\n pattern: string;\n};\n\ntype MiddlewareInfo = {\n file: string;\n fileSegments: string[];\n importPath: string;\n};\n\nexport async function generateRoutes(options: GenerateRoutesOptions) {\n const routeFiles = await findRouteFiles(options.routesDir);\n const middleware = routeFiles\n .map((file) => toMiddlewareInfo(options, file))\n .filter((value): value is MiddlewareInfo => Boolean(value));\n const routes = routeFiles\n .map((file) => toRouteInfo(options, file, middleware))\n .filter((route): route is RouteInfo => Boolean(route))\n .sort((a, b) => a.pattern.localeCompare(b.pattern));\n assertLocaleNamespaceCollisions(routes, options.localeNamespaces ?? []);\n\n const source = renderRoutesModule(routes, middleware, options.locales);\n\n await mkdir(dirname(options.outputFile), { recursive: true });\n await writeFile(options.outputFile, source);\n\n return {\n routes,\n source,\n };\n}\n\nfunction assertLocaleNamespaceCollisions(routes: RouteInfo[], namespaces: readonly string[]) {\n const localeSegments = new Set(namespaces.map((value) => value.toLowerCase()));\n for (const route of routes) {\n const [segment] = route.pattern.slice(1).split(\"/\");\n if (segment && !segment.startsWith(\"[\") && localeSegments.has(segment.toLowerCase())) {\n throw new Error(\n `Route \"${route.pattern}\" conflicts with the locale URL namespace \"${segment}\". Move the route or change the locale label.`,\n );\n }\n }\n}\n\nasync function findRouteFiles(directory: string) {\n const entries = await readdir(directory, {\n recursive: true,\n withFileTypes: true,\n });\n\n return entries\n .filter((entry) => entry.isFile() && /\\.tsx?$/.test(entry.name))\n .map((entry) => resolve(entry.parentPath, entry.name));\n}\n\nfunction toRouteInfo(\n options: GenerateRoutesOptions,\n file: string,\n middleware: MiddlewareInfo[],\n) {\n const relativePath = relative(options.routesDir, file).split(sep).join(\"/\");\n const fileSegments = relativePath.replace(/\\.tsx?$/, \"\").split(\"/\");\n const basename = fileSegments.at(-1);\n\n if (basename?.startsWith(\"@\")) {\n return null;\n }\n\n const urlSegments = fileSegments.flatMap((segment) => {\n if (isRouteGroupSegment(segment)) {\n return [];\n }\n\n if (segment === \"index\") {\n return [];\n }\n\n if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n return [segment];\n }\n\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n return [segment];\n }\n\n return [segment];\n });\n\n const pathVars = fileSegments.flatMap((segment) => {\n if (isRouteGroupSegment(segment)) {\n return [];\n }\n\n if (segment.startsWith(\"[...\") && segment.endsWith(\"]\")) {\n return [segment.slice(4, -1)];\n }\n\n if (segment.startsWith(\"[\") && segment.endsWith(\"]\")) {\n return [segment.slice(1, -1)];\n }\n\n return [];\n });\n\n return {\n contextMiddleware: middleware\n .filter((entry) => isAttachedFileForRoute(entry.fileSegments, fileSegments))\n .map((entry) => middleware.indexOf(entry)),\n fileSegments,\n importPath: toImportPath(options.outputFile, file),\n pathVars,\n pattern: `/${urlSegments.join(\"/\")}`.replace(/\\/$/, \"\") || \"/\",\n };\n}\n\nfunction toMiddlewareInfo(\n options: GenerateRoutesOptions,\n file: string,\n): MiddlewareInfo | null {\n const relativePath = relative(options.routesDir, file).split(sep).join(\"/\");\n const fileSegments = relativePath.replace(/\\.tsx?$/, \"\").split(\"/\");\n\n if (fileSegments.at(-1) !== \"@middleware\") {\n return null;\n }\n\n return {\n file,\n fileSegments: fileSegments.slice(0, -1),\n importPath: toImportPath(options.outputFile, file),\n };\n}\n\nfunction toImportPath(outputFile: string, file: string) {\n let importPath = relative(dirname(outputFile), file)\n .split(sep)\n .join(\"/\")\n .replace(/\\.tsx?$/, \"\");\n\n if (!importPath.startsWith(\".\")) importPath = `./${importPath}`;\n return importPath;\n}\n\nfunction isAttachedFileForRoute(\n attachedFileSegments: string[],\n routeFileSegments: string[],\n) {\n return attachedFileSegments.every(\n (segment, index) => routeFileSegments[index] === segment,\n );\n}\n\nfunction isRouteGroupSegment(segment: string) {\n return segment.startsWith(\"(\") && segment.endsWith(\")\");\n}\n\nfunction renderRoutesModule(routes: RouteInfo[], middleware: MiddlewareInfo[], locales: readonly string[] = []) {\n return `// Generated by Demiurge. Do not edit by hand.\nimport \"${PACKAGE_NAME}\";\nimport type { MiddlewareContextOf, MutationMethodsOf, PathValue } from \"${PACKAGE_NAME}\";\n${middleware.map(renderMiddlewareImport).join(\"\\n\")}\n\n${middleware.map((_entry, index) => renderMiddlewareContextAlias(index)).join(\"\\n\")}\n\ndeclare module \"${PACKAGE_NAME}\" {\n interface RouteLocales {\n${locales.map((locale) => ` ${JSON.stringify(locale)}: true;`).join(\"\\n\")}\n }\n\n interface RoutePathVars {\n${routes.map(renderPathVarsEntry).join(\"\\n\")}\n }\n\n interface RouteConcretePaths {\n${routes.map(renderConcretePathEntry).join(\"\\n\")}\n }\n\n interface RouteRequestContexts {\n${routes.map(renderRequestContextEntry).join(\"\\n\")}\n }\n\n interface RouteMutationMethods {\n${routes.map(renderMutationMethodsEntry).join(\"\\n\")}\n }\n}\n\nexport {};\n`;\n}\n\nfunction renderMiddlewareImport(entry: MiddlewareInfo, index: number) {\n return `type __DemiurgeMiddleware${index} = typeof import(${JSON.stringify(entry.importPath)}) extends { middleware?: infer T } ? T : never;`;\n}\n\nfunction renderMiddlewareContextAlias(index: number) {\n return `type __DemiurgeMiddlewareContext${index} = MiddlewareContextOf<__DemiurgeMiddleware${index}>;`;\n}\n\nfunction renderPathVarsEntry(route: RouteInfo) {\n if (route.pathVars.length === 0) {\n return ` ${JSON.stringify(route.pattern)}: {};`;\n }\n\n const pathType = route.pathVars\n .map((name) => `${name}: PathValue`)\n .join(\"; \");\n\n return ` ${JSON.stringify(route.pattern)}: { ${pathType} };`;\n}\n\nfunction renderConcretePathEntry(route: RouteInfo) {\n return ` ${JSON.stringify(route.pattern)}: ${toConcretePathType(route.pattern)};`;\n}\n\nfunction renderRequestContextEntry(route: RouteInfo) {\n const contexts = route.contextMiddleware\n .map((index) => `__DemiurgeMiddlewareContext${index}`);\n const context = contexts.length > 0\n ? contexts.join(\" & \")\n : \"Record<never, never>\";\n\n return ` ${JSON.stringify(route.pattern)}: ${context};`;\n}\n\nfunction renderMutationMethodsEntry(route: RouteInfo) {\n return ` ${JSON.stringify(route.pattern)}: MutationMethodsOf<typeof import(${JSON.stringify(route.importPath)})>;`;\n}\n\nfunction toConcretePathType(pattern: string) {\n if (!pattern.includes(\"[\")) {\n return JSON.stringify(pattern);\n }\n\n const parts = pattern.split(/(\\[\\.\\.\\.[^\\]]+\\]|\\[[^\\]]+\\])/g).filter(Boolean);\n return `\\`${parts.map((part) => (part.startsWith(\"[\") ? \"${PathValue}\" : escapeTemplate(part))).join(\"\")}\\``;\n}\n\nfunction escapeTemplate(value: string) {\n return value.replace(/[`$\\\\]/g, \"\\\\$&\");\n}\n","import { parseAst } from \"vite\";\nimport type { EnvSchema } from \"../security/env\";\n\ntype AstNode = {\n [key: string]: unknown;\n end: number;\n start: number;\n type: string;\n};\n\nexport type EnvBoundaryFinding = {\n code: \"client-secret\" | \"client-server-only\";\n importPath: string[];\n key: string;\n module: string;\n};\n\n// The build inlines a client variable in the browser bundle. Every other\n// declared variable stays on the server. This module finds the modules that\n// the client entry reaches and that read a variable of the second group.\nexport function findServerEnvKeys(schema: EnvSchema | undefined) {\n const keys = new Map<string, { sensitive: boolean }>();\n\n for (const [key, variable] of Object.entries(schema ?? {})) {\n if (variable.client) continue;\n keys.set(key, { sensitive: variable.sensitive });\n }\n\n return keys;\n}\n\n// A module reads a variable when it names the variable in a position that\n// gives a value. An object key that declares the schema is not such a\n// position, and neither is the local name of an import.\nexport function findEnvKeyReferences(\n code: string,\n keys: Iterable<string>,\n): string[] {\n const names = new Set(keys);\n const found = new Set<string>();\n\n if (!names.size) return [];\n // A text test keeps the build away from a parse that finds nothing.\n if (![...names].some((name) => code.includes(name))) return [];\n\n visitNode(asAstNode(parseAst(code)), names, found);\n\n return [...found].sort();\n}\n\n// The diagnostic gives the path that makes the module part of the browser\n// bundle. The search returns the shortest such path.\nexport function findImportPath(\n entry: string,\n target: string,\n importsOf: (id: string) => readonly string[],\n): string[] | undefined {\n if (entry === target) return [entry];\n\n const visited = new Set([entry]);\n const queue: string[][] = [[entry]];\n\n while (queue.length) {\n // TYPE-EVIDENCE: the loop condition proves the queue holds a path. The assertion reads that path.\n const path = queue.shift() as string[];\n\n for (const next of importsOf(path[path.length - 1])) {\n if (visited.has(next)) continue;\n if (next === target) return [...path, next];\n visited.add(next);\n queue.push([...path, next]);\n }\n }\n\n return undefined;\n}\n\nexport function formatEnvBoundaryFindings(findings: EnvBoundaryFinding[]) {\n return [\n \"Demiurge stopped the build. Client code reads an environment variable that stays on the server.\",\n \"\",\n ...findings.flatMap(formatEnvBoundaryFinding),\n ].join(\"\\n\");\n}\n\nfunction formatEnvBoundaryFinding(finding: EnvBoundaryFinding) {\n return [\n ` variable: ${finding.key}`,\n ` module: ${finding.module}`,\n ` import path: ${finding.importPath.join(\" -> \")}`,\n finding.code === \"client-secret\"\n ? \" A secret variable never reaches the browser. Read the value on the server, then send the result through route data.\"\n : \" Declare the variable with client: true to put the value in the browser bundle.\",\n \"\",\n ];\n}\n\nfunction visitNode(node: AstNode, names: Set<string>, found: Set<string>) {\n if (node.type === \"ImportDeclaration\") return;\n if (node.type === \"ExportNamedDeclaration\" && !node.declaration) return;\n if (node.type === \"ExportAllDeclaration\") return;\n\n if (node.type === \"Identifier\") {\n match(node.name, names, found);\n return;\n }\n\n if (node.type === \"MemberExpression\") {\n visitValue(node.object, names, found);\n visitKey(node.property, Boolean(node.computed), names, found);\n return;\n }\n\n if (node.type === \"Property\" || node.type === \"PropertyDefinition\") {\n // A destructured name reads the value. An object key declares a name.\n if (node.computed || isPatternProperty(node)) {\n visitKey(node.key, Boolean(node.computed), names, found);\n }\n visitValue(node.value, names, found);\n return;\n }\n\n visitOwnChildren(node, names, found);\n}\n\n// A pattern property holds a read of the value. The parser gives such a\n// property a pattern node or an identifier as its value.\nfunction isPatternProperty(node: AstNode) {\n const value = asNode(node.value);\n return value?.type === \"Identifier\" || value?.type === \"ObjectPattern\" ||\n value?.type === \"ArrayPattern\" || value?.type === \"AssignmentPattern\";\n}\n\nfunction visitKey(\n value: unknown,\n computed: boolean,\n names: Set<string>,\n found: Set<string>,\n) {\n const key = asNode(value);\n if (!key) return;\n\n if (key.type === \"Literal\") {\n match(key.value, names, found);\n return;\n }\n\n if (!computed) {\n if (key.type === \"Identifier\") match(key.name, names, found);\n return;\n }\n\n visitValue(key, names, found);\n}\n\nfunction match(value: unknown, names: Set<string>, found: Set<string>) {\n if (typeof value === \"string\" && names.has(value)) found.add(value);\n}\n\nfunction visitOwnChildren(\n node: AstNode,\n names: Set<string>,\n found: Set<string>,\n) {\n for (const [key, child] of Object.entries(node)) {\n if (key === \"end\" || key === \"loc\" || key === \"start\" || key === \"type\") {\n continue;\n }\n visitValue(child, names, found);\n }\n}\n\nfunction visitValue(value: unknown, names: Set<string>, found: Set<string>) {\n if (!value || typeof value !== \"object\") return;\n\n if (Array.isArray(value)) {\n for (const item of value) visitValue(item, names, found);\n return;\n }\n\n const node = asNode(value);\n if (node) {\n visitNode(node, names, found);\n return;\n }\n\n // TYPE-EVIDENCE: the value was checked to be an object without a node type. The cast reads its members.\n for (const child of Object.values(value as Record<string, unknown>)) {\n visitValue(child, names, found);\n }\n}\n\nfunction asNode(value: unknown) {\n // TYPE-EVIDENCE: the type in value check confirms the value is an AST node. The cast asserts that node shape.\n return value && typeof value === \"object\" && \"type\" in value &&\n typeof (value as { type: unknown }).type === \"string\"\n ? value as AstNode\n : undefined;\n}\n\n// TYPE-EVIDENCE: rollup returns a generic program node. The local type is a loose access shape.\nfunction asAstNode(value: unknown): AstNode {\n // TYPE-EVIDENCE: the caller passes a rollup program node. The cast labels it with the loose access shape.\n return value as AstNode;\n}\n","import { parseAst } from \"vite\";\n\ntype AstNode = {\n [key: string]: unknown;\n end: number;\n start: number;\n type: string;\n};\n\nexport type ServerOnlyBoundaryFinding = {\n importPath: string[];\n module: string;\n};\n\n// A module that imports one of these specifiers declares that a build must\n// keep it off the browser. The community package server-only uses the same\n// bare specifier, so an application that already uses that package keeps the\n// same protection under Demiurge.\nconst serverOnlyMarkerSpecifiers = new Set([\n \"@demiurgejs/core/server-only\",\n \"server-only\",\n]);\n\n// A module imports the marker through a static import, a re-export, or a\n// dynamic import. A text test keeps the build away from a parse that finds\n// nothing.\nexport function importsServerOnlyMarker(code: string): boolean {\n if (!code.includes(\"server-only\")) return false;\n\n return findsMarkerImport(asAstNode(parseAst(code)));\n}\n\nexport function formatServerOnlyBoundaryFindings(\n findings: ServerOnlyBoundaryFinding[],\n) {\n return [\n \"Demiurge stopped the build. A browser bundle reaches a module marked server-only.\",\n \"\",\n ...findings.flatMap(formatServerOnlyBoundaryFinding),\n ].join(\"\\n\");\n}\n\n// The development server transforms a browser request before it can find the\n// import path from a client entry. The message names the module and the\n// repair instead.\nexport function formatServerOnlyDevError(module: string) {\n return `Demiurge stopped the development server. The browser requested ${module}, and this module is marked server-only.\n\nKeep this module out of client code. Move the server logic to a module that no client module imports.`;\n}\n\nfunction formatServerOnlyBoundaryFinding(finding: ServerOnlyBoundaryFinding) {\n return [\n ` module: ${finding.module}`,\n ` import path: ${finding.importPath.join(\" -> \")}`,\n \" Keep this module out of client code. Move the server logic to a module that no client module imports.\",\n \"\",\n ];\n}\n\nfunction findsMarkerImport(ast: AstNode): boolean {\n let found = false;\n\n walkAst(ast, (node) => {\n if (found) return;\n\n if (\n (node.type === \"ImportDeclaration\" ||\n node.type === \"ExportNamedDeclaration\" ||\n node.type === \"ExportAllDeclaration\" ||\n node.type === \"ImportExpression\") &&\n isMarkerSource(node.source)\n ) {\n found = true;\n }\n });\n\n return found;\n}\n\nfunction isMarkerSource(value: unknown): boolean {\n const node = asNode(value);\n return node?.type === \"Literal\" &&\n typeof node.value === \"string\" &&\n serverOnlyMarkerSpecifiers.has(node.value);\n}\n\nfunction walkAst(value: unknown, visit: (node: AstNode) => void) {\n if (!value || typeof value !== \"object\") return;\n if (Array.isArray(value)) {\n for (const item of value) walkAst(item, visit);\n return;\n }\n\n // TYPE-EVIDENCE: the value was checked to be an object. The cast adds the loose AST node shape.\n const node = value as Partial<AstNode>;\n if (typeof node.type !== \"string\") return;\n // TYPE-EVIDENCE: the type field check above confirms the value is an AST node. The cast asserts that node shape.\n visit(node as AstNode);\n for (const [key, child] of Object.entries(node)) {\n if (!new Set([\"end\", \"loc\", \"start\", \"type\"]).has(key)) {\n walkAst(child, visit);\n }\n }\n}\n\nfunction asNode(value: unknown) {\n // TYPE-EVIDENCE: the type in value check confirms the value is an AST node. The cast asserts that node shape.\n return value && typeof value === \"object\" && \"type\" in value\n ? value as AstNode\n : undefined;\n}\n\n// TYPE-EVIDENCE: rollup returns a generic program node. The local type is a loose access shape.\nfunction asAstNode(value: unknown): AstNode {\n // TYPE-EVIDENCE: the caller passes a rollup program node. The cast labels it with the loose access shape.\n return value as AstNode;\n}\n","import { readFile } from \"node:fs/promises\";\nimport { basename, dirname, join, relative, sep } from \"node:path\";\nimport { parseAst, transformWithEsbuild } from \"vite\";\nimport type { HttpMethod } from \"../route\";\nimport {\n createSecurityHeaders,\n getBodySizeException,\n isSecurityException,\n resolveCsp,\n resolveMaxBodySize,\n security,\n validateCorsPolicy,\n validateRateLimitPolicy,\n DEFAULT_MAX_BODY_SIZE,\n parseBodySize,\n type ContentSecurityPolicy,\n type CorsPolicy,\n type RoutePolicy,\n type RouteSecurityPolicy,\n type SecurityPolicy,\n type StaticPolicyFindingCode,\n} from \"../security\";\nimport { PACKAGE_NAME } from \"../package-name\";\nimport { isPlainObject } from \"../type-guards\";\n\ntype AstNode = {\n [key: string]: unknown;\n end: number;\n start: number;\n type: string;\n};\n\n// TYPE-EVIDENCE: rollup returns a generic program node. The local type is a loose access shape.\nfunction asAstNode(value: unknown): AstNode {\n // TYPE-EVIDENCE: the caller passes a rollup program node. The cast labels it with the loose access shape.\n return value as AstNode;\n}\n\nexport type StaticPolicyFinding = {\n code: StaticPolicyFindingCode;\n exportName?: string;\n file: string;\n message: string;\n severity: \"error\" | \"warning\";\n};\n\nexport type RouteFileInspection = {\n /** The statically provable access state of the route policy. */\n accessState: RouteAccessState;\n /** `true` when the file exports at least one HTTP method capability. */\n declaresRoute: boolean;\n /**\n * `true` when the file declares a document policy, and also when the policy\n * expression is not statically readable. An unreadable expression is not\n * evidence of an absent policy.\n */\n declaresDocumentPolicy: boolean;\n /** The statically provable CSP state of the route policy. */\n documentCspState: DocumentCspState;\n declaresPageRoute: boolean;\n file: string;\n findings: StaticPolicyFinding[];\n /** The HTTP methods that the file exports, in a stable order. */\n methods: HttpMethod[];\n};\n\nexport type DocumentCspState = \"present\" | \"false\" | \"absent\" | \"unknown\";\n\n/**\n * `declared` means the file states access. `unknown` means the expression is\n * not statically readable, which is not evidence of an absent declaration.\n */\nexport type RouteAccessState = \"declared\" | \"absent\" | \"unknown\";\n\ntype ExtractedCapability = {\n cors?: CorsPolicy;\n security?: RouteSecurityPolicy;\n};\n\ntype ExtractedRouteModule = {\n accessState: RouteAccessState;\n capabilities: Partial<Record<HttpMethod, ExtractedCapability>>;\n declaredMethods: Set<HttpMethod>;\n declaresDocumentPolicy: boolean;\n documentCspState: DocumentCspState;\n policy?: RoutePolicy;\n};\n\nconst httpMethods = [\n \"GET\",\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\",\n \"OPTIONS\",\n \"HEAD\",\n] as const satisfies readonly HttpMethod[];\nconst responseHelpers = new Set([\n \"mutation\",\n \"html\",\n \"json\",\n \"jsonl\",\n \"notFound\",\n \"redirect\",\n \"response\",\n \"sse\",\n \"stream\",\n \"text\",\n]);\n\nexport async function verifyRoutePolicyFile(file: string) {\n return (await inspectRouteFile(file)).findings;\n}\n\nexport async function inspectRouteFile(\n file: string,\n): Promise<RouteFileInspection> {\n const source = await readFile(file, \"utf8\");\n const extracted = await extractRouteModuleSource(source, file);\n\n const attached = basename(file).startsWith(\"@\");\n\n return {\n accessState: extracted.accessState,\n declaresDocumentPolicy: extracted.declaresDocumentPolicy,\n documentCspState: extracted.documentCspState,\n // An attached file owns no address, so it never declares a route.\n declaresRoute: !attached && extracted.declaredMethods.size > 0,\n declaresPageRoute: !attached && declaresPageRoute(source),\n file,\n findings: validateExtractedRouteModule(extracted, file),\n methods: attached\n ? []\n : httpMethods.filter((method) => extracted.declaredMethods.has(method)),\n };\n}\n\nexport async function verifyRoutePolicySource(source: string, file: string) {\n return validateExtractedRouteModule(\n await extractRouteModuleSource(source, file),\n file,\n );\n}\n\nasync function extractRouteModuleSource(source: string, file: string) {\n const loader = file.endsWith(\".tsx\") ? \"tsx\" : \"ts\";\n const transformed = await transformWithEsbuild(source, file, {\n format: \"esm\",\n loader,\n target: \"esnext\",\n });\n\n return extractRouteModule(transformed.code);\n}\n\n// A route with no document policy sends no security headers. The application\n// still works, so nothing else reports the gap. This check reads the policy\n// cascade of the route tree and names each route that no document policy\n// covers. A page route and an application-owned fallback document, `@not-\n// found.tsx` and the route error document, both render HTML, so both need an\n// inherited policy.\nexport function auditDocumentPolicyCoverage(\n routesDir: string,\n inspections: readonly RouteFileInspection[],\n): StaticPolicyFinding[] {\n const policies = inspections.filter((inspection) => isPolicyFile(inspection.file));\n\n const findings: StaticPolicyFinding[] = [];\n\n for (const inspection of inspections) {\n if (\n !inspection.declaresPageRoute &&\n !isFallbackDocumentFile(inspection.file)\n ) {\n continue;\n }\n const applicable = applicablePolicies(\n routesDir,\n dirname(inspection.file),\n policies,\n );\n const state = resolveDocumentCspState(\n applicable,\n inspection.documentCspState,\n );\n if (state !== \"absent\") {\n continue;\n }\n\n findings.push({\n code: \"document-policy-missing\",\n file: inspection.file,\n message: describeMissingDocumentPolicy(routesDir, applicable),\n severity: \"error\",\n });\n }\n\n return findings;\n}\n\n// A route that inherits no access declaration is denied at request time. The\n// build finds the gap where the policy cascade is statically readable, so a\n// developer sees the missing declaration before the application runs.\nexport function auditRouteAccessCoverage(\n routesDir: string,\n inspections: readonly RouteFileInspection[],\n): StaticPolicyFinding[] {\n const policies = inspections.filter((inspection) =>\n isPolicyFile(inspection.file)\n );\n const findings: StaticPolicyFinding[] = [];\n\n for (const inspection of inspections) {\n if (!inspection.declaresRoute) {\n continue;\n }\n\n const state = resolveRouteAccessState(\n routesDir,\n dirname(inspection.file),\n inspection.accessState,\n policies,\n );\n\n if (state !== \"absent\") {\n continue;\n }\n\n findings.push({\n code: \"access-declaration-missing\",\n file: inspection.file,\n message:\n \"This route inherits no access declaration, so the request pipeline denies each request. Add access: { public: true } for a public route, or access: { authorize } to this route or an ancestor @policy.ts file.\",\n severity: \"error\",\n });\n }\n\n return findings;\n}\n\nfunction resolveRouteAccessState(\n routesDir: string,\n routeDirectory: string,\n routeState: RouteAccessState,\n policies: readonly RouteFileInspection[],\n) {\n const applicable = policies.filter((inspection) =>\n isSameOrAbove(dirname(inspection.file), routeDirectory) &&\n isSameOrAbove(routesDir, dirname(inspection.file))\n );\n\n let state: RouteAccessState = routeState;\n\n for (const policy of applicable) {\n if (policy.accessState !== \"absent\") {\n state = policy.accessState;\n }\n }\n\n return state;\n}\n\n// `@not-found.tsx` and `@error.tsx` are application-owned fallback documents.\n// Each renders an HTML response the same way a page route does, so the build\n// requires the same document policy coverage for both.\nfunction isFallbackDocumentFile(file: string) {\n return /^@(?:not-found|error)\\.tsx?$/.test(basename(file));\n}\n\nfunction describeMissingDocumentPolicy(\n routesDir: string,\n applicable: readonly RouteFileInspection[],\n): string {\n const exception =\n \"To accept a document without a Content-Security-Policy, declare csp \" +\n \"with a value of false and a reason.\";\n const nearest = applicable.at(-1);\n\n if (nearest) {\n return `This route inherits no document policy. ${nearest.file} does not declare one. Add document: security.strict() to ${nearest.file}. ${exception}`;\n }\n\n const rootPolicyFile = join(routesDir, \"@policy.ts\");\n return `This route inherits no document policy. No @policy.ts file exists above it. Create ${rootPolicyFile} with document: security.strict(). ${exception}`;\n}\n\nfunction applicablePolicies(\n routesDir: string,\n routeDirectory: string,\n policies: readonly RouteFileInspection[],\n) {\n return policies\n .filter((inspection) =>\n isSameOrAbove(dirname(inspection.file), routeDirectory) &&\n isSameOrAbove(routesDir, dirname(inspection.file)),\n )\n .sort((left, right) =>\n dirname(left.file).length - dirname(right.file).length ||\n left.file.localeCompare(right.file)\n );\n}\n\nfunction resolveDocumentCspState(\n applicable: readonly RouteFileInspection[],\n routeState: DocumentCspState,\n) {\n let state: DocumentCspState = \"absent\";\n for (const policy of applicable) {\n state = mergeDocumentCspState(state, policy.documentCspState);\n }\n return mergeDocumentCspState(state, routeState);\n}\n\nfunction mergeDocumentCspState(\n base: DocumentCspState,\n override: DocumentCspState,\n): DocumentCspState {\n if (override === \"absent\") return base;\n return override;\n}\n\nfunction isPolicyFile(file: string) {\n return /^@policy\\.tsx?$/.test(basename(file));\n}\n\nfunction isSameOrAbove(directory: string, routesDir: string) {\n const distance = relative(directory, routesDir);\n return distance === \"\" ||\n (distance !== \"..\" && !distance.startsWith(`..${sep}`) &&\n !distance.startsWith(sep));\n}\n\n// Escaped because a package name may contain `.`, which the regex would\n// otherwise read as a wildcard.\nconst PACKAGE_NAME_PATTERN = PACKAGE_NAME.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\nconst DEMIURGE_NAMED_IMPORT = new RegExp(\n `import\\\\s*\\\\{([^}]*)\\\\}\\\\s*from\\\\s*[\"']${PACKAGE_NAME_PATTERN}[\"']`,\n \"g\",\n);\n\n// The plugin cannot evaluate route modules during the build. Therefore, page\n// detection reads the source. It checks the import, not only the word. An API\n// application can call `db.users.page(2)` without serving an HTML document.\n// Only a page route imports `page` from the framework package.\nexport function declaresPageRoute(source: string) {\n const locals = [...source.matchAll(DEMIURGE_NAMED_IMPORT)].flatMap((match) =>\n match[1].split(\",\").flatMap((binding) => {\n const [imported, local] = binding.trim().split(/\\s+as\\s+/);\n\n // `import type { page }` cannot be called, and an alias renames what the\n // call site looks like.\n return imported.replace(/^type\\s+/, \"\") === \"page\"\n ? [local ?? imported]\n : [];\n }),\n );\n\n if (locals.length === 0) {\n return false;\n }\n\n // Strip the import statements first so the binding list is not itself\n // mistaken for a call.\n const body = source.replace(DEMIURGE_NAMED_IMPORT, \"\");\n\n return locals.some((local) => new RegExp(`\\\\b${local}\\\\s*\\\\(`).test(body));\n}\n\nfunction extractRouteModule(code: string): ExtractedRouteModule {\n const ast = asAstNode(parseAst(code));\n const imports = collectCoreImports(ast);\n const constants = collectConstants(ast);\n const declarations = collectVariableInitializers(ast);\n const exports = collectNamedExports(ast);\n const capabilities: ExtractedRouteModule[\"capabilities\"] = {};\n const declaredMethods = new Set<HttpMethod>();\n let accessState: RouteAccessState = \"absent\";\n let declaresDocumentPolicy = false;\n let documentCspState: DocumentCspState = \"absent\";\n let policy: RoutePolicy | undefined;\n\n for (const [exportName, localName] of exports) {\n const initializer = declarations.get(localName);\n\n if (exportName === \"policy\") {\n accessState = initializer\n ? extractAccessState(initializer, imports, constants)\n : \"unknown\";\n documentCspState = initializer\n ? extractDocumentCspState(initializer, imports, constants)\n : \"unknown\";\n declaresDocumentPolicy = documentCspState !== \"absent\";\n if (initializer) {\n policy = extractRoutePolicy(initializer, imports, constants);\n }\n continue;\n }\n if (!isHttpMethod(exportName)) continue;\n declaredMethods.add(exportName);\n if (!initializer) continue;\n\n const capability = extractCapability(initializer, imports, constants);\n if (capability) capabilities[exportName] = capability;\n }\n\n return {\n accessState,\n capabilities,\n declaredMethods,\n declaresDocumentPolicy,\n documentCspState,\n policy,\n };\n}\n\n// The access declaration holds a function, so the build cannot evaluate it.\n// The check therefore proves only that the `access` property is present.\nfunction extractAccessState(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): RouteAccessState {\n if (node.type === \"Identifier\") {\n if (node.name === \"undefined\") return \"absent\";\n const value = constants.get(String(node.name));\n if (value === undefined && !constants.has(String(node.name))) {\n return \"unknown\";\n }\n if (!isPlainObject(value)) return \"unknown\";\n return Object.prototype.hasOwnProperty.call(value, \"access\")\n ? \"declared\"\n : \"absent\";\n }\n\n if (node.type === \"CallExpression\") {\n const localName = identifierName(node.callee);\n if (localName && imports.get(localName) === \"defineRoutePolicy\") {\n const argument = asNodeArray(node.arguments)[0];\n return argument\n ? extractAccessState(argument, imports, constants)\n : \"unknown\";\n }\n return \"unknown\";\n }\n\n if (node.type !== \"ObjectExpression\") return \"unknown\";\n\n for (const property of asNodeArray(node.properties)) {\n if (property.type === \"SpreadElement\") return \"unknown\";\n if (property.type !== \"Property\") continue;\n if (property.computed) return \"unknown\";\n if (propertyName(property.key) !== \"access\") continue;\n const value = asNode(property.value);\n if (value?.type === \"Identifier\" && value.name === \"undefined\") {\n return \"absent\";\n }\n return \"declared\";\n }\n\n return \"absent\";\n}\n\nfunction extractDocumentCspState(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): DocumentCspState {\n if (node.type === \"Identifier\") {\n if (node.name === \"undefined\") return \"absent\";\n const value = constants.get(String(node.name));\n return value === undefined && !constants.has(String(node.name))\n ? \"unknown\"\n : extractDocumentCspStateFromValue(value);\n }\n\n if (node.type === \"CallExpression\") {\n const localName = identifierName(node.callee);\n if (localName && imports.get(localName) === \"defineRoutePolicy\") {\n const argument = asNodeArray(node.arguments)[0];\n return argument\n ? extractDocumentCspState(argument, imports, constants)\n : \"unknown\";\n }\n\n const callee = asNode(node.callee);\n if (callee?.type === \"MemberExpression\") {\n const objectName = identifierName(callee.object);\n const preset = propertyName(callee.property);\n if (objectName && imports.get(objectName) === \"security\" && preset) {\n return extractPresetCspState(preset, asNodeArray(node.arguments)[0], constants);\n }\n }\n return \"unknown\";\n }\n\n if (node.type !== \"ObjectExpression\") return \"unknown\";\n\n for (const property of asNodeArray(node.properties)) {\n if (property.type === \"SpreadElement\") return \"unknown\";\n if (property.type !== \"Property\") continue;\n if (property.computed) return \"unknown\";\n if (propertyName(property.key) !== \"document\") continue;\n return extractDocumentSecurityCspState(\n asNode(property.value),\n imports,\n constants,\n );\n }\n\n return \"absent\";\n}\n\nfunction extractDocumentSecurityCspState(\n node: AstNode | undefined,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): DocumentCspState {\n if (!node) return \"unknown\";\n if (node.type === \"UnaryExpression\" && node.operator === \"void\") {\n return \"absent\";\n }\n if (node.type === \"Identifier\") {\n if (node.name === \"undefined\") return \"absent\";\n const value = constants.get(String(node.name));\n return value === undefined && !constants.has(String(node.name))\n ? \"unknown\"\n : extractDocumentCspStateFromValue(value);\n }\n if (node.type === \"CallExpression\") {\n const callee = asNode(node.callee);\n if (callee?.type !== \"MemberExpression\") return \"unknown\";\n const objectName = identifierName(callee.object);\n const preset = propertyName(callee.property);\n if (!objectName || imports.get(objectName) !== \"security\" || !preset) {\n return \"unknown\";\n }\n return extractPresetCspState(preset, asNodeArray(node.arguments)[0], constants);\n }\n if (node.type !== \"ObjectExpression\") return \"unknown\";\n\n for (const property of asNodeArray(node.properties)) {\n if (property.type === \"SpreadElement\" || property.computed) return \"unknown\";\n if (property.type !== \"Property\") continue;\n if (propertyName(property.key) !== \"csp\") continue;\n const value = asNode(property.value);\n if (!value) return \"unknown\";\n if (value.type === \"Literal\") {\n if (value.value === false) return \"false\";\n if (value.value === undefined || value.value === null) return \"absent\";\n return \"present\";\n }\n if (value.type === \"Identifier\") {\n const literal = evaluateLiteral(value, constants);\n if (literal === unresolved) return \"unknown\";\n return extractCspValueState(literal);\n }\n if (value.type === \"ObjectExpression\") {\n const literal = evaluateLiteral(value, constants);\n if (literal === unresolved) return \"unknown\";\n return extractCspValueState(literal);\n }\n if (value.type === \"ArrayExpression\") {\n return \"present\";\n }\n return \"unknown\";\n }\n\n return \"absent\";\n}\n\nfunction extractPresetCspState(\n preset: string,\n optionsNode: AstNode | undefined,\n constants: Map<string, unknown>,\n): DocumentCspState {\n const defaultState = preset === \"api\" ? \"absent\" :\n preset === \"strict\" || preset === \"static\" || preset === \"crossOriginIsolated\"\n ? \"present\"\n : \"unknown\";\n if (!optionsNode) return defaultState;\n if (optionsNode.type === \"Identifier\") {\n const options = evaluateLiteral(optionsNode, constants);\n if (options === unresolved) return \"unknown\";\n return mergePresetCspState(defaultState, extractCspOptionState(options));\n }\n if (optionsNode.type !== \"ObjectExpression\") return \"unknown\";\n for (const property of asNodeArray(optionsNode.properties)) {\n if (property.type === \"SpreadElement\" || property.computed) return \"unknown\";\n if (property.type !== \"Property\") continue;\n if (propertyName(property.key) !== \"csp\") continue;\n const value = evaluateLiteral(asNode(property.value), constants);\n if (value === unresolved) return \"unknown\";\n return mergePresetCspState(defaultState, extractCspValueState(value));\n }\n return defaultState;\n}\n\nfunction extractCspOptionState(value: unknown): DocumentCspState {\n if (!isPlainObject(value)) return value === undefined ? \"absent\" : \"unknown\";\n if (!Object.prototype.hasOwnProperty.call(value, \"csp\")) return \"absent\";\n return extractCspValueState(value.csp);\n}\n\nfunction extractCspValueState(value: unknown): DocumentCspState {\n if (value === false) return \"false\";\n if (isSecurityException(value)) return value.value === false ? \"false\" : \"unknown\";\n if (value === undefined || value === null) return \"absent\";\n if (isPlainObject(value) || Array.isArray(value)) return \"present\";\n return \"unknown\";\n}\n\nfunction mergePresetCspState(\n preset: DocumentCspState,\n override: DocumentCspState,\n): DocumentCspState {\n if (override === \"absent\") return preset;\n return override;\n}\n\nfunction extractDocumentCspStateFromValue(value: unknown): DocumentCspState {\n if (value === undefined) return \"absent\";\n if (!isPlainObject(value)) return \"unknown\";\n if (!Object.prototype.hasOwnProperty.call(value, \"document\")) return \"absent\";\n return extractCspOptionState(value.document);\n}\n\nfunction collectVariableInitializers(ast: AstNode) {\n const declarations = new Map<string, AstNode>();\n for (const statement of asNodeArray(ast.body)) {\n const declaration = statement.type === \"ExportNamedDeclaration\"\n ? asNode(statement.declaration)\n : statement;\n if (declaration?.type !== \"VariableDeclaration\") continue;\n for (const declarator of asNodeArray(declaration.declarations)) {\n const name = identifierName(declarator.id);\n const initializer = asNode(declarator.init);\n if (name && initializer) declarations.set(name, initializer);\n }\n }\n return declarations;\n}\n\nfunction collectNamedExports(ast: AstNode) {\n const exports = new Map<string, string>();\n for (const statement of asNodeArray(ast.body)) {\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n const declaration = asNode(statement.declaration);\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of asNodeArray(declaration.declarations)) {\n const name = identifierName(declarator.id);\n if (name) exports.set(name, name);\n }\n }\n for (const specifier of asNodeArray(statement.specifiers)) {\n const exported = propertyName(specifier.exported);\n const local = propertyName(specifier.local);\n if (exported && local) exports.set(exported, local);\n }\n }\n return exports;\n}\n\nfunction extractCapability(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n) {\n if (node.type !== \"CallExpression\") return undefined;\n const localName = identifierName(node.callee);\n const helper = localName ? imports.get(localName) : undefined;\n\n if (!helper || !responseHelpers.has(helper)) return undefined;\n const arguments_ = asNodeArray(node.arguments);\n const optionsNode = helper === \"mutation\" ? arguments_[0] : arguments_[1];\n if (!optionsNode) return {};\n const cors = evaluateObjectProperty(optionsNode, \"cors\", constants);\n const securityPolicy = evaluateObjectProperty(\n optionsNode,\n \"security\",\n constants,\n );\n\n // TYPE-EVIDENCE: the isPlainObject checks confirm the values are plain objects. The casts label them as the capability policy types.\n return {\n cors: isPlainObject(cors) ? cors as CorsPolicy : undefined,\n security: isPlainObject(securityPolicy)\n ? securityPolicy as RouteSecurityPolicy\n : undefined,\n } satisfies ExtractedCapability;\n}\n\nfunction evaluateObjectProperty(\n node: AstNode,\n property: string,\n constants: Map<string, unknown>,\n) {\n if (node.type === \"Identifier\") {\n const value = constants.get(String(node.name));\n return isPlainObject(value) ? value[property] : unresolved;\n }\n if (node.type !== \"ObjectExpression\") return unresolved;\n\n let value: unknown = undefined;\n for (const item of asNodeArray(node.properties)) {\n if (item.type !== \"Property\" || item.computed) return unresolved;\n if (propertyName(item.key) !== property) continue;\n value = evaluateLiteral(asNode(item.value), constants);\n }\n\n return value;\n}\n\nfunction extractRoutePolicy(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): RoutePolicy | undefined {\n if (node.type === \"CallExpression\") {\n const localName = identifierName(node.callee);\n if (localName && imports.get(localName) === \"defineRoutePolicy\") {\n const argument = asNodeArray(node.arguments)[0];\n return argument\n ? extractRoutePolicy(argument, imports, constants)\n : undefined;\n }\n }\n\n if (node.type !== \"ObjectExpression\") {\n const value = evaluateLiteral(node, constants);\n // TYPE-EVIDENCE: the isPlainObject check confirms the value is a plain object. The cast labels it as a route policy.\n return isPlainObject(value) ? value as RoutePolicy : undefined;\n }\n\n const result: Record<string, unknown> = {};\n for (const property of asNodeArray(node.properties)) {\n if (property.type !== \"Property\" || property.computed) return undefined;\n const name = propertyName(property.key);\n const valueNode = asNode(property.value);\n if (!name || !valueNode) return undefined;\n\n if (name === \"document\") {\n const document = extractSecurityPolicy(valueNode, imports, constants);\n if (!document) return undefined;\n result.document = document;\n continue;\n }\n\n const value = evaluateLiteral(valueNode, constants);\n if (value === unresolved) return undefined;\n result[name] = value;\n }\n\n // TYPE-EVIDENCE: the loop above copied each property from the object expression. The cast labels the accumulated record as a route policy.\n return result as RoutePolicy;\n}\n\nfunction extractSecurityPolicy(\n node: AstNode,\n imports: Map<string, string>,\n constants: Map<string, unknown>,\n): SecurityPolicy | undefined {\n if (node.type !== \"CallExpression\") {\n const value = evaluateLiteral(node, constants);\n // TYPE-EVIDENCE: the isPlainObject check confirms the value is a plain object. The cast labels it as a security policy.\n return isPlainObject(value) ? value as SecurityPolicy : undefined;\n }\n\n const callee = asNode(node.callee);\n if (callee?.type !== \"MemberExpression\") return undefined;\n const objectName = identifierName(callee.object);\n const preset = propertyName(callee.property);\n if (!objectName || imports.get(objectName) !== \"security\" || !preset) {\n return undefined;\n }\n\n const options = evaluateLiteral(asNodeArray(node.arguments)[0], constants);\n // The options expression could not be statically evaluated (it depends on\n // a runtime value). The `unresolved` sentinel must not pass through to a\n // security preset because it would verify a policy that was never computed.\n // Treat this call as unverifiable, matching `unresolved` handling in\n // extractRoutePolicy above.\n if (options === unresolved) return undefined;\n if (options !== undefined && !isPlainObject(options)) {\n return undefined;\n }\n\n if (preset === \"api\") {\n // TYPE-EVIDENCE: the guards above return undefined unless options is a plain object or undefined. The cast labels the record as a security policy for the preset helper.\n return security.api(options as SecurityPolicy | undefined);\n }\n if (preset === \"crossOriginIsolated\") {\n // TYPE-EVIDENCE: the guards above return undefined unless options is a plain object or undefined. The cast labels the record as a security policy for the preset helper.\n return security.crossOriginIsolated(options as SecurityPolicy | undefined);\n }\n if (preset === \"static\") {\n // TYPE-EVIDENCE: the guards above return undefined unless options is a plain object or undefined. The cast labels the record as a security policy for the preset helper.\n return security.static(options as SecurityPolicy | undefined);\n }\n if (preset === \"strict\") {\n // TYPE-EVIDENCE: the guards above return undefined unless options is a plain object or undefined. The cast labels the record as a security policy for the preset helper.\n return security.strict(options as SecurityPolicy | undefined);\n }\n return undefined;\n}\n\nfunction validateExtractedRouteModule(\n routeModule: ExtractedRouteModule,\n file: string,\n) {\n const findings: StaticPolicyFinding[] = [];\n const availableMethods = new Set(routeModule.declaredMethods);\n if (availableMethods.has(\"GET\")) availableMethods.add(\"HEAD\");\n // Demiurge answers preflight itself, so a route never exports an OPTIONS\n // capability to serve one. Listing OPTIONS is a habit carried in from other\n // CORS configuration, and rejecting it would fail a build over nothing.\n availableMethods.add(\"OPTIONS\");\n\n // TYPE-EVIDENCE: Object.entries returns the capability map entries as string keyed pairs. The cast narrows the keys to HTTP methods and the values to capability types.\n for (const [exportName, capability] of Object.entries(\n routeModule.capabilities,\n ) as Array<[HttpMethod, ExtractedCapability]>) {\n if (capability.cors) {\n try {\n validateCorsPolicy(capability.cors);\n } catch (error) {\n findings.push(finding(\n \"cors-invalid\",\n file,\n errorMessage(error, \"The CORS policy is invalid.\"),\n exportName,\n ));\n }\n\n for (const method of capability.cors.methods ?? []) {\n if (!availableMethods.has(method)) {\n findings.push(finding(\n \"cors-method-unavailable\",\n file,\n `CORS method ${method} is not available from this route.`,\n exportName,\n ));\n }\n }\n }\n\n validateRateLimit(capability.security, file, exportName, findings);\n validateExceptionReasons(\n undefined,\n capability.security,\n file,\n exportName,\n findings,\n );\n }\n\n validateRateLimit(routeModule.policy?.security, file, undefined, findings);\n validateExceptionReasons(\n routeModule.policy?.document,\n routeModule.policy?.security,\n file,\n undefined,\n findings,\n );\n if (routeModule.policy?.document) {\n try {\n createSecurityHeaders(toFragmentDocument(routeModule.policy.document), {\n nonce: \"build-verification-nonce\",\n });\n } catch (error) {\n findings.push(finding(\n \"security-header-render-failed\",\n file,\n errorMessage(error, \"The security headers are invalid.\"),\n ));\n }\n }\n\n return findings;\n}\n\n// A build reads one file at a time, but policy cascades. A file declaring no\n// reporting endpoints of its own inherits them. Its `csp.reportTo` therefore\n// names a group only the merged policy resolves, which\n// `validateRouteModules(...)` checks during startup. A file declaring its own\n// endpoint map is self-contained. A name outside that map stays a build\n// error, because that is the typo worth catching early.\nfunction toFragmentDocument(document: SecurityPolicy): SecurityPolicy {\n const endpoints = document.headers?.reportingEndpoints;\n const declaresEndpoints = Boolean(\n endpoints && Object.keys(endpoints).length,\n );\n const declaredCsp = resolveCsp(document.csp);\n const reportTo = declaredCsp ? declaredCsp.reportTo : undefined;\n\n if (declaresEndpoints || !reportTo) {\n return document;\n }\n\n // TYPE-EVIDENCE: the guard above returns early when the csp field is false or missing. The remaining value is therefore a policy object.\n return {\n ...document,\n csp: { ...declaredCsp as ContentSecurityPolicy, reportTo: undefined },\n headers: endpoints\n ? { ...document.headers, reportingEndpoints: undefined }\n : document.headers,\n };\n}\n\n// ADR 0018 gives every typed security exception a mandatory reason. The type\n// system refuses a bare `csp: false` and a bare `csrf: false`. A raised body\n// limit is a valid value. The build therefore compares the declared limit with\n// the default limit. It refuses a raised limit that states no reason.\nfunction validateExceptionReasons(\n document: SecurityPolicy | undefined,\n securityPolicy: RouteSecurityPolicy | undefined,\n file: string,\n exportName: string | undefined,\n findings: StaticPolicyFinding[],\n) {\n if (document && statesNoReason(document.csp)) {\n findings.push(finding(\n \"security-exception-reason-missing\",\n file,\n \"This document policy accepts no Content-Security-Policy and states no reason. Declare csp with a value of false and a reason.\",\n exportName,\n ));\n }\n\n if (securityPolicy && statesNoReason(securityPolicy.csrf)) {\n findings.push(finding(\n \"security-exception-reason-missing\",\n file,\n \"This route runs no CSRF check and states no reason. Declare csrf with a value of false and a reason.\",\n exportName,\n ));\n }\n\n validateRaisedBodyLimit(securityPolicy, file, exportName, findings);\n}\n\n// The build reads a JavaScript route file as well as a TypeScript route file.\n// A bare `false` and an object without a reason therefore both reach here.\nfunction statesNoReason(declaration: unknown) {\n if (declaration === false) {\n return true;\n }\n\n return (\n isPlainObject(declaration) &&\n \"value\" in declaration &&\n typeof declaration.reason !== \"string\"\n );\n}\n\nfunction validateRaisedBodyLimit(\n securityPolicy: RouteSecurityPolicy | undefined,\n file: string,\n exportName: string | undefined,\n findings: StaticPolicyFinding[],\n) {\n const declared = securityPolicy?.request?.maxBodySize;\n\n if (declared === undefined || getBodySizeException(declared)) {\n return;\n }\n\n let declaredBytes: number;\n let defaultBytes: number;\n\n try {\n // TYPE-EVIDENCE: the exception guard above leaves a body size value. The cast labels the resolved value for the parser.\n declaredBytes = parseBodySize(resolveMaxBodySize(declared) as number | string);\n defaultBytes = parseBodySize(DEFAULT_MAX_BODY_SIZE);\n } catch {\n // An invalid value fails at request time with a typed error. The build\n // does not repeat that failure here.\n return;\n }\n\n if (declaredBytes <= defaultBytes) {\n return;\n }\n\n findings.push(finding(\n \"security-exception-reason-missing\",\n file,\n `This route raises the request body limit to ${\n String(declared)\n } and states no reason. Declare maxBodySize with a limit value and a reason.`,\n exportName,\n ));\n}\n\nfunction validateRateLimit(\n securityPolicy: RouteSecurityPolicy | undefined,\n file: string,\n exportName: string | undefined,\n findings: StaticPolicyFinding[],\n) {\n if (!securityPolicy?.rateLimit) return;\n try {\n validateRateLimitPolicy(securityPolicy.rateLimit);\n } catch (error) {\n findings.push(finding(\n \"rate-limit-invalid\",\n file,\n errorMessage(error, \"The rate limit policy is invalid.\"),\n exportName,\n ));\n }\n}\n\nfunction finding(\n code: StaticPolicyFinding[\"code\"],\n file: string,\n message: string,\n exportName?: string,\n): StaticPolicyFinding {\n return { code, exportName, file, message, severity: \"error\" };\n}\n\nfunction collectCoreImports(ast: AstNode) {\n const imports = new Map<string, string>();\n for (const statement of asNodeArray(ast.body)) {\n if (\n statement.type !== \"ImportDeclaration\" ||\n asNode(statement.source)?.value !== \"@demiurgejs/core\"\n ) continue;\n for (const specifier of asNodeArray(statement.specifiers)) {\n if (specifier.type !== \"ImportSpecifier\") continue;\n const local = identifierName(specifier.local);\n const imported = propertyName(specifier.imported);\n if (local && imported) imports.set(local, imported);\n }\n }\n return imports;\n}\n\nfunction collectConstants(ast: AstNode) {\n const constants = new Map<string, unknown>();\n for (const statement of asNodeArray(ast.body)) {\n const declaration = statement.type === \"ExportNamedDeclaration\"\n ? asNode(statement.declaration)\n : statement;\n if (declaration?.type !== \"VariableDeclaration\") continue;\n for (const declarator of asNodeArray(declaration.declarations)) {\n const name = identifierName(declarator.id);\n const initializer = asNode(declarator.init);\n if (!name || !initializer) continue;\n const value = evaluateLiteral(initializer, constants);\n if (value !== unresolved) constants.set(name, value);\n }\n }\n return constants;\n}\n\nconst unresolved = Symbol(\"unresolved\");\n\nfunction evaluateLiteral(\n node: AstNode | undefined,\n constants: Map<string, unknown>,\n): unknown | typeof unresolved {\n if (!node) return undefined;\n if (node.type === \"Literal\") return node.value;\n if (node.type === \"Identifier\") {\n if (node.name === \"undefined\") return undefined;\n return constants.has(String(node.name))\n ? constants.get(String(node.name))\n : unresolved;\n }\n if (node.type === \"TemplateLiteral\") {\n if (asNodeArray(node.expressions).length) return unresolved;\n return asNodeArray(node.quasis)\n .map((quasi) => asNode(quasi.value)?.cooked ?? \"\")\n .join(\"\");\n }\n if (node.type === \"UnaryExpression\") {\n const value = evaluateLiteral(asNode(node.argument), constants);\n if (typeof value !== \"number\") return unresolved;\n if (node.operator === \"-\") return -value;\n if (node.operator === \"+\") return value;\n return unresolved;\n }\n if (node.type === \"ArrayExpression\") {\n const values: unknown[] = [];\n for (const element of asNodeArray(node.elements)) {\n const value = evaluateLiteral(element, constants);\n if (value === unresolved) return unresolved;\n values.push(value);\n }\n return values;\n }\n if (node.type === \"ObjectExpression\") {\n const value: Record<string, unknown> = {};\n for (const property of asNodeArray(node.properties)) {\n if (property.type !== \"Property\" || property.computed) return unresolved;\n const name = propertyName(property.key);\n const child = evaluateLiteral(asNode(property.value), constants);\n if (!name || child === unresolved) return unresolved;\n value[name] = child;\n }\n return value;\n }\n return unresolved;\n}\n\nfunction isHttpMethod(value: string): value is HttpMethod {\n // TYPE-EVIDENCE: the value is a string that the includes check tests against the HTTP methods tuple. The cast narrows it for the check.\n return httpMethods.includes(value as HttpMethod);\n}\n\nfunction errorMessage(error: unknown, fallback: string) {\n return error instanceof Error ? error.message : fallback;\n}\n\nfunction asNode(value: unknown) {\n // TYPE-EVIDENCE: the type in value check confirms the value is an AST node. The cast asserts that node shape.\n return value && typeof value === \"object\" && \"type\" in value\n ? value as AstNode\n : undefined;\n}\n\nfunction asNodeArray(value: unknown) {\n return Array.isArray(value)\n ? value.map(asNode).filter((node): node is AstNode => Boolean(node))\n : [];\n}\n\nfunction identifierName(value: unknown) {\n const node = asNode(value);\n return node?.type === \"Identifier\" ? String(node.name) : undefined;\n}\n\nfunction propertyName(value: unknown) {\n const node = asNode(value);\n return node?.type === \"Identifier\" || node?.type === \"Literal\"\n ? String(node.name ?? node.value)\n : undefined;\n}\n","import { isPlainObject } from \"../type-guards\";\nimport type {\n InspectionRedaction,\n InspectionRedactionReason,\n} from \"./types\";\n\n/**\n * The text that replaces a removed value. A reader sees this marker in place\n * of the value, and the `redactions` section names the field and the reason.\n */\nexport const REDACTED_VALUE = \"[redacted]\";\n\nexport type InspectionSerializeOptions = {\n /**\n * The names of the environment variables that an `env.secret(...)`\n * declaration produced.\n */\n secretEnvKeys?: Iterable<string>;\n /** The indentation of the JSON output. The default value is 2. */\n space?: number;\n};\n\nexport type InspectionRedactionResult = {\n /** The values that this module removed, sorted by path. */\n redactions: InspectionRedaction[];\n /** The report without the removed values. */\n value: unknown;\n};\n\n// ADR 0019 gives the framework one place that removes a secret value. Every\n// report reaches its output through this module, so no other code repeats the\n// rule. A field name identifies a cookie or a session, and the environment\n// schema identifies a secret variable.\nconst cookieFieldNames = new Set([\n \"cookie\",\n \"cookies\",\n \"setcookie\",\n \"setcookies\",\n]);\nconst sessionFieldNames = new Set([\n \"session\",\n \"sessiondata\",\n \"sessionrecord\",\n \"sessions\",\n]);\n// A cookie declaration holds its payload in one field. The name and the other\n// attributes stay in the report, because they carry no secret.\nconst cookieValueFieldNames = new Set([\"value\"]);\n// A session record holds the application data and the identifier of the\n// session. The expiry timestamps stay in the report.\nconst sessionValueFieldNames = new Set([\"data\", \"id\"]);\n\ntype WalkContext = {\n inCookie: boolean;\n inSession: boolean;\n secretEnvKeys: ReadonlySet<string>;\n};\n\n/**\n * Serializes a report and removes each secret value. This function is the one\n * choke point of ADR 0019.\n *\n * The function writes the collected redactions into the `redactions` field of\n * the report when the report declares that field.\n */\nexport function serializeInspectionReport(\n report: unknown,\n options: InspectionSerializeOptions = {},\n): string {\n const result = redactSecrets(report, options);\n const value = attachRedactions(result);\n\n return JSON.stringify(value, undefined, options.space ?? 2);\n}\n\n/**\n * Removes each secret value from a report and returns the removed names. The\n * function does not change the report that the caller supplied.\n */\nexport function redactSecrets(\n report: unknown,\n options: InspectionSerializeOptions = {},\n): InspectionRedactionResult {\n const redactions: InspectionRedaction[] = [];\n const context: WalkContext = {\n inCookie: false,\n inSession: false,\n secretEnvKeys: new Set(options.secretEnvKeys ?? []),\n };\n const value = walk(report, \"\", context, redactions);\n\n redactions.sort((left, right) => left.path.localeCompare(right.path));\n\n return { redactions, value };\n}\n\nfunction attachRedactions(result: InspectionRedactionResult) {\n if (!isRecord(result.value)) return result.value;\n if (!Array.isArray(result.value.redactions)) return result.value;\n\n return { ...result.value, redactions: result.redactions };\n}\n\nfunction walk(\n value: unknown,\n path: string,\n context: WalkContext,\n redactions: InspectionRedaction[],\n): unknown {\n if (Array.isArray(value)) {\n return value.map((item, index) =>\n walk(item, `${path}[${index}]`, context, redactions)\n );\n }\n\n if (!isRecord(value)) return value;\n\n const scope: WalkContext = isSessionRecord(value)\n ? { ...context, inSession: true }\n : context;\n const result: Record<string, unknown> = {};\n\n for (const [name, item] of Object.entries(value)) {\n const itemPath = path ? `${path}.${name}` : name;\n const reason = classifyField(name, item, scope);\n\n if (reason) {\n redactions.push({ name, path: itemPath, reason });\n result[name] = REDACTED_VALUE;\n continue;\n }\n\n result[name] = walk(item, itemPath, descend(name, scope), redactions);\n }\n\n return result;\n}\n\nfunction classifyField(\n name: string,\n value: unknown,\n context: WalkContext,\n): InspectionRedactionReason | undefined {\n if (context.secretEnvKeys.has(name)) return \"environment-secret\";\n\n const normalized = normalizeFieldName(name);\n\n if (context.inCookie && cookieValueFieldNames.has(normalized)) {\n return \"cookie-value\";\n }\n\n if (context.inSession && sessionValueFieldNames.has(normalized)) {\n return \"session-record\";\n }\n\n if (typeof value !== \"string\") return undefined;\n if (cookieFieldNames.has(normalized)) return \"cookie-value\";\n if (sessionFieldNames.has(normalized)) return \"session-record\";\n\n return undefined;\n}\n\nfunction descend(name: string, context: WalkContext): WalkContext {\n const normalized = normalizeFieldName(name);\n\n if (cookieFieldNames.has(normalized)) return { ...context, inCookie: true };\n if (sessionFieldNames.has(normalized)) return { ...context, inSession: true };\n\n return context;\n}\n\n// A header name uses a hyphen and a property name uses camel case. One\n// normalized form matches both spellings of the same field.\nfunction normalizeFieldName(name: string) {\n return name.toLowerCase().replaceAll(\"-\", \"\").replaceAll(\"_\", \"\");\n}\n\n// A class instance such as `Date` carries no own enumerable field, so a walk\n// of its entries would replace it with an empty object. The walker returns it\n// without a change and lets `JSON.stringify` serialize it.\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n if (!isPlainObject(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n\n return prototype === Object.prototype || prototype === null;\n}\n\n// A session record reaches a report through a field that carries another name.\n// The shape of `SessionRecord` identifies it without that name.\nfunction isSessionRecord(value: Record<string, unknown>) {\n return typeof value.id === \"string\" &&\n typeof value.createdAt === \"number\" &&\n typeof value.expiresAt === \"number\" &&\n typeof value.version === \"number\" &&\n \"data\" in value;\n}\n","import {\n createMemoryCache,\n serializeCacheKey,\n serializeCacheTag,\n type Cache,\n type CacheScope,\n} from \"../data\";\nimport type { ResolvedMetadata, ScriptTag } from \"../document\";\nimport {\n findRouteMatch,\n isAttachedFileForRoute,\n isRouteGroupSegment,\n loadPageRoute,\n MalformedPathnameError,\n toRoutePattern,\n type RouteManifest,\n} from \"../router\";\nimport type {\n HttpMethod,\n PageRenderMode,\n PathVars,\n RouteModule,\n} from \"../route\";\nimport { loadInheritedRoutePolicy } from \"../server\";\nimport {\n createSecurityAudit,\n type CorsPolicy,\n type MergedRoutePolicy,\n type SecurityAudit,\n type SecurityAuditFinding,\n} from \"../security\";\nimport { createCspNonce, securityPolicyRequiresNonce } from \"../security/policy\";\nimport { serializeInspectionReport } from \"../inspect/redact\";\nimport type { InspectionResolution } from \"../inspect/types\";\n\n/**\n * The version of the route report. ADR 0019 raises this integer when the\n * framework removes a field or changes the meaning of a field.\n */\nexport const ROUTE_AUDIT_VERSION = 1;\n\n// The development server reserves this path. The name matches the image\n// optimizer path, so every framework endpoint keeps one prefix.\nexport const ROUTE_AUDIT_PATH = \"/_demiurge/audit\";\n\nconst supportedMethods = [\n \"GET\",\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\",\n \"OPTIONS\",\n \"HEAD\",\n] as const satisfies readonly HttpMethod[];\n\nexport type RouteAuditCacheRead = {\n key: string;\n scope: CacheScope;\n staleWhileRevalidate?: string;\n tags: string[];\n ttl?: string;\n};\n\nexport type RouteAuditScript = {\n findings: SecurityAuditFinding[];\n integrity?: string;\n nonce?: string;\n purpose?: string;\n src: string;\n strategy: string;\n};\n\nexport type RouteAuditRoute = {\n file: string;\n groups: string[];\n layouts: string[];\n methods: HttpMethod[];\n middlewares: string[];\n params: PathVars;\n pattern: string;\n policies: string[];\n render?: PageRenderMode;\n};\n\n/** The named sections of the route report. */\nexport type RouteAuditSection =\n | \"audit\"\n | \"cacheReads\"\n | \"metadata\"\n | \"policy\"\n | \"route\"\n | \"scripts\";\n\n// The route report answers for one request. The route section and the policy\n// section come from the route tree, so a build knows them. Each other section\n// needs the request.\nconst routeAuditResolutions: Record<RouteAuditSection, InspectionResolution> = {\n audit: \"request\",\n cacheReads: \"request\",\n metadata: \"request\",\n policy: \"static\",\n route: \"static\",\n scripts: \"request\",\n};\n\nexport type RouteAudit = {\n audit: SecurityAudit;\n cacheControl?: string;\n cacheReads: RouteAuditCacheRead[];\n kind: \"page\" | \"resource\" | \"unmatched\";\n metadata?: ResolvedMetadata;\n method: HttpMethod;\n nonce?: string;\n pathname: string;\n policy: MergedRoutePolicy;\n /** The resolution of each section of the report. */\n resolutions: Record<RouteAuditSection, InspectionResolution>;\n route?: RouteAuditRoute;\n scripts: RouteAuditScript[];\n /** The version of this report shape. */\n version: number;\n};\n\nexport function isRouteAuditRequest(request: Request) {\n return new URL(request.url).pathname === ROUTE_AUDIT_PATH;\n}\n\nexport async function createRouteAuditResponse(\n manifest: RouteManifest,\n request: Request,\n) {\n const url = new URL(request.url);\n const report = await createRouteAudit(\n manifest,\n url.searchParams.get(\"path\") || \"/\",\n request,\n );\n const json = url.searchParams.get(\"format\") === \"json\";\n\n return new Response(\n json\n ? serializeInspectionReport(report)\n : renderRouteAuditDocument(report),\n {\n headers: {\n \"cache-control\": \"no-store\",\n // The panel is a side channel. It declares its own policy, so the\n // policy of the application stays unchanged. The panel runs no script.\n \"content-security-policy\":\n \"default-src 'none'; base-uri 'none'; form-action 'self'; style-src 'unsafe-inline'\",\n \"content-type\": json\n ? \"application/json; charset=utf-8\"\n : \"text/html; charset=utf-8\",\n \"x-robots-tag\": \"noindex\",\n },\n },\n );\n}\n\nexport async function createRouteAudit(\n manifest: RouteManifest,\n target: string,\n request: Request,\n): Promise<RouteAudit> {\n const origin = new URL(request.url).origin;\n const url = new URL(target, origin);\n const pathname = url.pathname;\n const routeRequest = new Request(url, { headers: request.headers });\n const routeMatch = matchRoute(manifest, pathname);\n\n if (!routeMatch) {\n const policy = await loadInheritedRoutePolicy(\n manifest,\n { fileSegments: [] },\n {},\n undefined,\n );\n\n return finishRouteAudit({\n cacheReads: [],\n kind: \"unmatched\",\n method: \"GET\",\n pathname,\n policy,\n request: routeRequest,\n scripts: [],\n });\n }\n\n const routeModule = await routeMatch.route.load();\n const method = selectMethod(routeModule);\n const capability = routeModule[method];\n const policy = await loadInheritedRoutePolicy(\n manifest,\n routeMatch.route,\n routeModule,\n capability,\n );\n const cacheReads: RouteAuditCacheRead[] = [];\n const page = capability?.kind === \"page\"\n ? await loadPageRoute(\n manifest,\n pathname,\n routeRequest,\n undefined,\n createRecordingCache(cacheReads),\n )\n : undefined;\n const match = page?.status === \"ready\" ? page.match : undefined;\n\n return finishRouteAudit({\n cacheReads,\n cors: capability && capability.kind !== \"page\"\n ? capability.cors\n : undefined,\n kind: capability?.kind === \"page\" ? \"page\" : \"resource\",\n metadata: match?.metadata,\n method,\n pathname,\n policy,\n request: routeRequest,\n route: {\n file: routeMatch.route.file,\n groups: routeMatch.route.fileSegments.filter(isRouteGroupSegment),\n layouts: manifest.layouts\n .filter((layout) => isAttachedFileForRoute(layout.fileSegments, routeMatch.route.fileSegments))\n .map((layout) => layout.file),\n methods: supportedMethods.filter((name) => routeModule[name]),\n middlewares: manifest.middlewares\n .filter((item) => isAttachedFileForRoute(item.fileSegments, routeMatch.route.fileSegments))\n .map((item) => item.file),\n params: routeMatch.path,\n pattern: toRoutePattern(routeMatch.route.segments),\n policies: manifest.policies\n .filter((item) => isAttachedFileForRoute(item.fileSegments, routeMatch.route.fileSegments))\n .map((item) => item.file),\n render: match?.render.mode,\n },\n scripts: match?.scripts ?? [],\n });\n}\n\nfunction finishRouteAudit(input: {\n cacheReads: RouteAuditCacheRead[];\n cors?: CorsPolicy;\n kind: RouteAudit[\"kind\"];\n metadata?: ResolvedMetadata;\n method: HttpMethod;\n pathname: string;\n policy: MergedRoutePolicy;\n request: Request;\n route?: RouteAuditRoute;\n scripts: readonly ScriptTag[];\n}): RouteAudit {\n // The request handler renders the document policy for a page response only.\n // A resource route and an unmatched path therefore get no document headers\n // and no nonce.\n const document = input.kind === \"page\";\n // The document renderer gives each script the nonce of the document. The\n // audit reads the same values that the response carries.\n const nonce = document && securityPolicyRequiresNonce(input.policy.document)\n ? createCspNonce()\n : undefined;\n const scripts = input.scripts.map((script) => ({\n ...script,\n nonce: script.nonce ?? nonce,\n }));\n const auditOptions = {\n headers: { nonce, request: input.request },\n policy: input.policy.document ?? {},\n scriptDependencies: true,\n };\n const audit = createSecurityAudit({\n document: document ? { ...auditOptions, scripts } : undefined,\n route: {\n // A path that matches no route file has no access declaration to\n // report, so the audit says nothing about its authorization.\n access: input.kind === \"unmatched\" ? undefined : input.policy.access,\n cors: input.cors,\n method: input.method,\n security: input.policy.security,\n },\n });\n\n return {\n audit,\n // A nonce makes a document unique for each response. The request handler\n // therefore replaces the cache directives of the application.\n cacheControl: nonce ? \"private, no-store\" : undefined,\n cacheReads: input.cacheReads,\n kind: input.kind,\n metadata: input.metadata,\n method: input.method,\n nonce,\n pathname: input.pathname,\n policy: input.policy,\n resolutions: routeAuditResolutions,\n route: input.route,\n scripts: scripts.map((script) => ({\n // One audit for each script gives the status of that script alone. The\n // panel reads the same code path that the complete audit reads.\n findings: createSecurityAudit({\n document: { ...auditOptions, scripts: [script] },\n }).findings,\n integrity: script.integrity,\n nonce: script.nonce,\n purpose: script.purpose,\n src: script.src,\n strategy: script.strategy,\n })),\n version: ROUTE_AUDIT_VERSION,\n };\n}\n\nfunction matchRoute(manifest: RouteManifest, pathname: string) {\n try {\n return findRouteMatch(manifest.routes, pathname);\n } catch (error) {\n if (error instanceof MalformedPathnameError) {\n return null;\n }\n\n throw error;\n }\n}\n\nfunction selectMethod(routeModule: RouteModule) {\n return supportedMethods.find((method) => routeModule[method]) ?? \"GET\";\n}\n\nfunction createRecordingCache(reads: RouteAuditCacheRead[]): Cache {\n const cache = createMemoryCache();\n\n return {\n get: async (request) => {\n reads.push({\n key: serializeCacheKey(request.key),\n scope: request.scope ?? \"request\",\n staleWhileRevalidate: formatDuration(request.staleWhileRevalidate),\n tags: (request.tags ?? []).map(serializeCacheTag),\n ttl: formatDuration(request.ttl),\n });\n\n return await cache.get(request);\n },\n invalidateKey: cache.invalidateKey,\n invalidateTags: cache.invalidateTags,\n };\n}\n\nfunction formatDuration(duration: number | string | undefined) {\n return duration === undefined ? undefined : String(duration);\n}\n\nexport function renderRouteAuditDocument(report: RouteAudit) {\n return `<!doctype html>\n<html lang=\"en\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Demiurge route audit</title>\n <style>${panelStyles}</style>\n </head>\n <body>\n <h1>Demiurge route audit</h1>\n <form method=\"get\" action=\"${ROUTE_AUDIT_PATH}\">\n <label for=\"path\">Path</label>\n <input id=\"path\" name=\"path\" value=\"${escapeHtml(report.pathname)}\" />\n <button type=\"submit\">Audit</button>\n </form>\n${renderRouteSection(report)}\n${renderFindingsSection(report.audit.findings)}\n${renderHeadersSection(report.audit.headers)}\n${renderPolicySection(report)}\n${renderMetadataSection(report.metadata)}\n${renderScriptsSection(report.scripts)}\n${renderCacheSection(report)}\n <p class=\"footer\">\n The development server serves this panel. A production build and a static\n export do not contain it.\n </p>\n </body>\n</html>\n`;\n}\n\nconst panelStyles = `\n :root { color-scheme: light dark; }\n body {\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n line-height: 1.5;\n margin: 0 auto;\n max-width: 60rem;\n padding: 2rem 1rem;\n }\n h1 { font-size: 1.25rem; }\n h2 { font-size: 1rem; margin-bottom: 0.25rem; }\n form { display: flex; gap: 0.5rem; margin-bottom: 1.5rem; }\n input { flex: 1; padding: 0.25rem 0.5rem; }\n section { border-top: 1px solid currentColor; padding: 0.75rem 0; }\n table { border-collapse: collapse; width: 100%; }\n td, th { padding: 0.25rem 0.5rem 0.25rem 0; text-align: left; vertical-align: top; }\n th { white-space: nowrap; width: 12rem; }\n ul { margin: 0; padding-left: 1.25rem; }\n .empty { opacity: 0.7; }\n .error { font-weight: 700; }\n .footer { opacity: 0.7; }\n`;\n\nfunction renderRouteSection(report: RouteAudit) {\n if (!report.route) {\n return section(\n \"Route\",\n `<p class=\"empty\">No route matches ${escapeHtml(report.pathname)}.</p>`,\n );\n }\n\n const route = report.route;\n\n return section(\n \"Route\",\n table([\n [\"Pathname\", escapeHtml(report.pathname)],\n [\"Pattern\", escapeHtml(route.pattern)],\n [\"File\", escapeHtml(route.file)],\n [\"Kind\", escapeHtml(report.kind)],\n [\"Method\", escapeHtml(report.method)],\n [\"Methods\", escapeHtml(route.methods.join(\", \"))],\n [\"Render mode\", route.render ? escapeHtml(route.render) : none()],\n [\"Path values\", entries(route.params)],\n [\"Route groups\", list(route.groups)],\n [\"Layouts\", list(route.layouts)],\n [\"Policies\", list(route.policies)],\n [\"Middleware\", list(route.middlewares)],\n ]),\n );\n}\n\nfunction renderFindingsSection(findings: SecurityAuditFinding[]) {\n if (findings.length === 0) {\n return section(\"Findings\", `<p class=\"empty\">No findings.</p>`);\n }\n\n return section(\n \"Findings\",\n `<ul>${findings.map(renderFinding).join(\"\")}</ul>`,\n );\n}\n\nfunction renderFinding(finding: SecurityAuditFinding) {\n const className = finding.severity === \"error\" ? ' class=\"error\"' : \"\";\n\n return `<li${className}>${escapeHtml(finding.severity)}: ${\n escapeHtml(finding.message)\n } <code>${escapeHtml(finding.code)}</code></li>`;\n}\n\nfunction renderHeadersSection(headers: Record<string, string>) {\n const names = Object.keys(headers).sort();\n\n if (names.length === 0) {\n return section(\n \"Response headers\",\n `<p class=\"empty\">The response carries no document header.</p>`,\n );\n }\n\n return section(\n \"Response headers\",\n table(names.map((name) => [name, escapeHtml(headers[name])])),\n );\n}\n\nfunction renderPolicySection(report: RouteAudit) {\n const policy = {\n cors: report.audit.route?.cors,\n document: report.policy.document,\n security: report.policy.security,\n };\n\n return section(\n \"Effective policy\",\n `<pre>${\n escapeHtml(JSON.stringify(policy, null, 2))\n }</pre>`,\n );\n}\n\nfunction renderMetadataSection(metadata: ResolvedMetadata | undefined) {\n if (!metadata) {\n return section(\"Metadata\", `<p class=\"empty\">No document metadata.</p>`);\n }\n\n return section(\n \"Metadata\",\n `<pre>${\n escapeHtml(JSON.stringify(metadata, null, 2))\n }</pre>`,\n );\n}\n\nfunction renderScriptsSection(scripts: RouteAuditScript[]) {\n if (scripts.length === 0) {\n return section(\"Scripts\", `<p class=\"empty\">No contributed scripts.</p>`);\n }\n\n return section(\n \"Scripts\",\n scripts.map((script) =>\n table([\n [\"Source\", escapeHtml(script.src)],\n [\"Strategy\", escapeHtml(script.strategy)],\n [\"Purpose\", script.purpose ? escapeHtml(script.purpose) : none()],\n [\"Integrity\", script.integrity ? escapeHtml(script.integrity) : none()],\n [\"Nonce\", script.nonce ? \"applied\" : none()],\n [\n \"Policy status\",\n script.findings.length === 0\n ? \"allowed\"\n : `<ul>${script.findings.map(renderFinding).join(\"\")}</ul>`,\n ],\n ])\n ).join(\"\"),\n );\n}\n\nfunction renderCacheSection(report: RouteAudit) {\n const rows: Array<[string, string]> = [\n [\n \"Response cache-control\",\n report.cacheControl ? escapeHtml(report.cacheControl) : none(),\n ],\n [\"Nonce\", report.nonce ? \"required\" : none()],\n ];\n\n if (report.cacheReads.length === 0) {\n return section(\n \"Cache behavior\",\n `${table(rows)}<p class=\"empty\">The request read no cache entry.</p>`,\n );\n }\n\n return section(\n \"Cache behavior\",\n `${table(rows)}${\n report.cacheReads.map((read) =>\n table([\n [\"Key\", escapeHtml(read.key)],\n [\"Scope\", escapeHtml(read.scope)],\n [\"Time to live\", read.ttl ? escapeHtml(read.ttl) : none()],\n [\n \"Stale while revalidate\",\n read.staleWhileRevalidate\n ? escapeHtml(read.staleWhileRevalidate)\n : none(),\n ],\n [\"Tags\", list(read.tags)],\n ])\n ).join(\"\")\n }`,\n );\n}\n\nfunction section(title: string, body: string) {\n return ` <section>\n <h2>${escapeHtml(title)}</h2>\n ${body}\n </section>`;\n}\n\nfunction table(rows: Array<[string, string]>) {\n return `<table><tbody>${\n rows.map(([name, value]) =>\n `<tr><th scope=\"row\">${escapeHtml(name)}</th><td>${value}</td></tr>`\n ).join(\"\")\n }</tbody></table>`;\n}\n\nfunction list(values: readonly string[]) {\n if (values.length === 0) {\n return none();\n }\n\n return `<ul>${\n values.map((value) => `<li>${escapeHtml(value)}</li>`).join(\"\")\n }</ul>`;\n}\n\nfunction entries(values: PathVars) {\n return list(\n Object.entries(values).map(([name, value]) => `${name} = ${String(value)}`),\n );\n}\n\nfunction none() {\n return `<span class=\"empty\">none</span>`;\n}\n\nfunction escapeHtml(value: string) {\n return value\n .replaceAll(\"&\", \"&amp;\")\n .replaceAll(\"<\", \"&lt;\")\n .replaceAll(\">\", \"&gt;\")\n .replaceAll(\"\\\"\", \"&quot;\")\n .replaceAll(\"'\", \"&#39;\");\n}\n","import { existsSync } from \"node:fs\";\nimport type { IncomingMessage } from \"node:http\";\nimport { readFile, readdir } from \"node:fs/promises\";\nimport { dirname, join, resolve, relative, sep } from \"node:path\";\nimport MagicString from \"magic-string\";\nimport {\n type ConfigEnv,\n parseAst,\n type Plugin,\n type UserConfig,\n type ViteDevServer,\n} from \"vite\";\nimport { renderDocument } from \"../document\";\nimport type {\n LinkTag,\n ResolvedMetadata,\n ScriptTag,\n} from \"../document\";\nimport { PACKAGE_NAME } from \"../package-name\";\nimport { generateRoutes } from \"../routing/generate\";\nimport {\n createRouteManifest,\n findRouteMatch,\n type RouteManifest,\n} from \"../router\";\nimport {\n handleRequestWithManifest,\n renderNotFoundResponse,\n renderPageDocument,\n type PageRenderer,\n} from \"../server\";\nimport {\n type RouteImporter,\n type RouteModule,\n} from \"../route\";\nimport {\n UnsupportedMethodError,\n toWebRequest,\n writeNotImplemented,\n writeWebResponse,\n} from \"../node/http\";\nimport { createFontAssetHandler } from \"../node/font\";\nimport { createImageOptimizer } from \"../node/image\";\nimport { renderStreamingPageResponse } from \"../node/streaming\";\nimport type { FontContribution } from \"../platform/fonts\";\nimport { parseImageVariantPath } from \"../platform/image-url\";\nimport type { ImagePolicy } from \"../platform/images\";\nimport { createCspNonce } from \"../security/policy\";\nimport type { EnvSchema, EnvSource } from \"../security/env\";\nimport { serializeEnvSchema, startEnvironment } from \"../security/env-startup\";\nimport {\n findEnvKeyReferences,\n findImportPath,\n findServerEnvKeys,\n formatEnvBoundaryFindings,\n type EnvBoundaryFinding,\n} from \"./env-boundary\";\nimport {\n formatServerOnlyBoundaryFindings,\n formatServerOnlyDevError,\n importsServerOnlyMarker,\n type ServerOnlyBoundaryFinding,\n} from \"./server-only-boundary\";\nimport {\n auditDocumentPolicyCoverage,\n auditRouteAccessCoverage,\n declaresPageRoute,\n inspectRouteFile,\n type RouteFileInspection,\n type StaticPolicyFinding,\n} from \"./policy-verification\";\nimport {\n createRouteAuditResponse,\n isRouteAuditRequest,\n} from \"./route-audit\";\nimport type {\n StaticFileHeaderPatternRule,\n VercelStaticDeployment,\n} from \"../static\";\nimport { defineLocales, type LocaleConfiguration } from \"../routing\";\n\nexport type DemiurgeVitePluginOptions = {\n // The route audit panel of the development server. The panel is available by\n // default. Set this option to false to remove the endpoint.\n devtools?: boolean;\n document?: {\n lang?: string;\n title?: string;\n };\n // The environment schema of the application. The generated server entry\n // validates it when the server starts.\n env?: EnvSchema;\n // The fonts that the application self-hosts. The development server serves\n // the same URLs that the build publishes.\n fonts?: FontContribution;\n // The image policy that the application passes to `planImageTransform` and\n // to `Image`. The development server serves the optimizer path from it.\n images?: ImagePolicy;\n locales?: LocaleConfiguration;\n routesDir?: string;\n static?: {\n deployment?: VercelStaticDeployment;\n headers?: readonly StaticFileHeaderPatternRule[];\n };\n styles?: false | string;\n typedRoutes?: boolean | {\n outputFile?: string;\n };\n};\n\nexport type DemiurgeVitePluginApi = {\n demiurge: true;\n fonts?: FontContribution;\n images?: ImagePolicy;\n staticDeployment?: VercelStaticDeployment;\n staticFileHeaders?: readonly StaticFileHeaderPatternRule[];\n};\n\nconst CLIENT_ENTRY_ID = \"virtual:demiurge/client-entry\";\nconst DEV_CLIENT_ENTRY_PATH = `/@id/${CLIENT_ENTRY_ID}`;\nconst RESOLVED_CLIENT_ENTRY_ID = `\\0${CLIENT_ENTRY_ID}`;\nconst SERVER_ENTRY_ID = \"virtual:demiurge/server-entry\";\nconst RESOLVED_SERVER_ENTRY_ID = `\\0${SERVER_ENTRY_ID}`;\nconst DEFAULT_TYPED_ROUTES_OUTPUT = \".demiurge/route-manifest.d.ts\";\nexport function demiurge(options: DemiurgeVitePluginOptions = {}): Plugin {\n if (options.locales) options = { ...options, locales: defineLocales(options.locales) };\n let root = process.cwd();\n let isBuild = false;\n // The build refuses a browser bundle that reads a variable of the server.\n // The transform hook records a reference. The buildEnd hook then keeps the\n // references of the modules that a client entry reaches.\n const serverEnvKeys = findServerEnvKeys(options.env);\n const clientEnvReferences = new Map<string, string[]>();\n // The build refuses a browser bundle that reaches a module marked\n // server-only. The transform hook records the module id. The buildEnd hook\n // then finds the import path from a client entry.\n const serverOnlyMarkers = new Set<string>();\n const viteNoncePlaceholder = `demiurge-${createCspNonce()}`;\n\n return {\n api: {\n demiurge: true,\n fonts: options.fonts,\n images: options.images,\n staticDeployment: options.static?.deployment,\n staticFileHeaders: options.static?.headers,\n } satisfies DemiurgeVitePluginApi,\n enforce: \"post\",\n name: \"demiurge\",\n config(config, environment) {\n return createViteConfig(config, environment, viteNoncePlaceholder);\n },\n configResolved(config) {\n root = config.root;\n isBuild = config.command === \"build\";\n\n if (!isBuild) {\n startDevEnvironment(options);\n }\n },\n resolveId(id) {\n if (id === CLIENT_ENTRY_ID) {\n return RESOLVED_CLIENT_ENTRY_ID;\n }\n\n if (id === SERVER_ENTRY_ID) {\n return RESOLVED_SERVER_ENTRY_ID;\n }\n\n return null;\n },\n load(id) {\n if (id === RESOLVED_CLIENT_ENTRY_ID) {\n return createClientEntrySource(root, options);\n }\n\n if (id === RESOLVED_SERVER_ENTRY_ID) {\n return createServerEntrySource(root, options);\n }\n\n return null;\n },\n transform: {\n order: \"post\",\n handler(code, id, transformOptions) {\n if (!transformOptions?.ssr) {\n checkServerOnlyBoundary(serverOnlyMarkers, isBuild, root, code, id);\n }\n\n if (isBuild && !transformOptions?.ssr) {\n recordClientEnvReferences(clientEnvReferences, serverEnvKeys, code, id);\n }\n\n if (!isRouteSource(root, options, id)) {\n return null;\n }\n\n if (transformOptions?.ssr) {\n return isBuild ? null : protectSsrImportMeta(code, id);\n }\n\n const transformed = stripClientPageData(code);\n return transformed === code ? null : { code: transformed, map: null };\n },\n },\n generateBundle(_outputOptions, bundle) {\n const entry = Object.values(bundle).find(\n (item) =>\n item.type === \"chunk\" &&\n item.isEntry &&\n item.facadeModuleId === RESOLVED_CLIENT_ENTRY_ID,\n );\n\n if (!entry) {\n return;\n }\n\n const styles = Object.values(bundle)\n .filter(\n (asset): asset is Extract<(typeof bundle)[string], { type: \"asset\" }> =>\n asset.type === \"asset\" && asset.fileName.endsWith(\".css\"),\n )\n .map((asset) => `/${asset.fileName}`);\n const clientEntry = `/${entry.fileName}`;\n\n this.emitFile({\n fileName: \"index.html\",\n source: createDocumentHtml({\n entrySrc: clientEntry,\n lang: options.document?.lang,\n styles,\n title: options.document?.title,\n }),\n type: \"asset\",\n });\n this.emitFile({\n fileName: \"demiurge-manifest.json\",\n source: JSON.stringify({ clientEntry, styles }, null, 2),\n type: \"asset\",\n });\n },\n buildEnd() {\n const findings = collectEnvBoundaryFindings({\n moduleIds: [...this.getModuleIds()],\n moduleInfo: (id) => this.getModuleInfo(id),\n references: clientEnvReferences,\n root,\n serverEnvKeys,\n });\n\n if (findings.length) {\n this.error(formatEnvBoundaryFindings(findings));\n }\n\n const serverOnlyFindings = collectServerOnlyBoundaryFindings({\n markers: serverOnlyMarkers,\n moduleIds: [...this.getModuleIds()],\n moduleInfo: (id) => this.getModuleInfo(id),\n root,\n });\n\n if (serverOnlyFindings.length) {\n this.error(formatServerOnlyBoundaryFindings(serverOnlyFindings));\n }\n },\n async buildStart() {\n clientEnvReferences.clear();\n serverOnlyMarkers.clear();\n\n if (isBuild) {\n await assertRootNotFoundRoute(root, options);\n const findings = await verifyRoutePolicies(root, options);\n const errors = findings.filter(\n (finding) => finding.severity === \"error\",\n );\n\n for (const finding of findings) {\n if (finding.severity === \"error\") continue;\n this.warn(formatStaticPolicyFinding(finding));\n }\n\n if (errors.length) {\n throw new Error(formatStaticPolicyFindings(errors));\n }\n }\n\n if (!options.typedRoutes) {\n return;\n }\n\n await generateTypedRoutes(root, options);\n },\n configureServer(server) {\n const reportPolicyFindings = async () => {\n const findings = await verifyRoutePolicies(server.config.root, options);\n\n for (const finding of findings) {\n server.config.logger.warn(formatStaticPolicyFinding(finding));\n }\n };\n // A single editor save can fire several watcher events, and a branch\n // switch fires one per route file. Collapse a burst into one scan, and\n // chain scans so two never walk the route tree at the same time.\n let policyVerificationTimer: ReturnType<typeof setTimeout> | undefined;\n let policyVerificationRun = Promise.resolve();\n const runPolicyVerification = () => {\n policyVerificationRun = policyVerificationRun\n .then(reportPolicyFindings)\n .catch(() => {\n // Vite reports route read and syntax errors through its module pipeline.\n });\n };\n const startPolicyVerification = () => {\n if (policyVerificationTimer) {\n clearTimeout(policyVerificationTimer);\n }\n\n policyVerificationTimer = setTimeout(() => {\n policyVerificationTimer = undefined;\n runPolicyVerification();\n }, policyVerificationDebounceMs);\n policyVerificationTimer.unref?.();\n };\n\n server.httpServer?.once(\"close\", () => {\n if (policyVerificationTimer) {\n clearTimeout(policyVerificationTimer);\n policyVerificationTimer = undefined;\n }\n });\n\n runPolicyVerification();\n if (options.typedRoutes) {\n const routesDir = resolve(\n server.config.root,\n options.routesDir ?? \"src/routes\",\n );\n const runGenerateTypedRoutes = () => {\n void generateTypedRoutes(server.config.root, options).catch(\n (error: unknown) => {\n server.config.logger.error(\n error instanceof Error ? error.message : String(error),\n );\n },\n );\n };\n\n runGenerateTypedRoutes();\n server.watcher.add(routesDir);\n server.watcher.on(\"add\", (file) => {\n if (isRouteFile(routesDir, file)) {\n runGenerateTypedRoutes();\n startPolicyVerification();\n }\n });\n server.watcher.on(\"change\", (file) => {\n if (isRouteFile(routesDir, file)) {\n runGenerateTypedRoutes();\n startPolicyVerification();\n }\n });\n server.watcher.on(\"unlink\", (file) => {\n if (isRouteFile(routesDir, file)) {\n runGenerateTypedRoutes();\n startPolicyVerification();\n }\n });\n } else {\n const routesDir = resolve(\n server.config.root,\n options.routesDir ?? \"src/routes\",\n );\n server.watcher.add(routesDir);\n for (const event of [\"add\", \"change\", \"unlink\"] as const) {\n server.watcher.on(event, (file) => {\n if (isRouteFile(routesDir, file)) startPolicyVerification();\n });\n }\n }\n\n const routeAuditEnabled = isRouteAuditEnabled(options);\n const optimizeImage = createDevImageOptimizer(server, options);\n const serveFont = createFontAssetHandler({\n fonts: options.fonts,\n root: server.config.root,\n });\n\n // Vite's Connect middleware type is void-returning. The handler below\n // is deliberately async so tests can await its returned promise and\n // know when a request has finished. Vite itself never touches that\n // return value, so async is safe here even though the declared type\n // says otherwise.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n server.middlewares.use(async (request, response, next) => {\n try {\n let webRequest: Request;\n\n try {\n webRequest = toWebRequest(request, {\n // Vite performs its own configured host allowlist check before\n // Demiurge's middleware runs. Production Node listeners require\n // an explicit application allowlist instead.\n allowedHosts: [request.headers.host ?? \"localhost\"],\n });\n } catch (error) {\n if (error instanceof UnsupportedMethodError) {\n writeNotImplemented(response);\n return;\n }\n\n throw error;\n }\n\n if (routeAuditEnabled && isRouteAuditRequest(webRequest)) {\n const manifest = await loadDevManifest(\n server,\n request,\n resolve(server.config.root, options.routesDir ?? \"src/routes\"),\n );\n\n await writeWebResponse(\n response,\n await createRouteAuditResponse(manifest, webRequest),\n );\n return;\n }\n\n const font = await serveFont(webRequest);\n\n if (font) {\n await writeWebResponse(response, font);\n return;\n }\n\n const image = await optimizeImage(webRequest);\n\n if (image) {\n await writeWebResponse(response, image);\n return;\n }\n\n const routesDir = resolve(\n server.config.root,\n options.routesDir ?? \"src/routes\",\n );\n const manifest = await loadDevManifest(server, request, routesDir);\n const documentSecurity = createDevDocumentSecurity(\n server,\n viteNoncePlaceholder,\n );\n const result = await handleDevRequest(\n manifest,\n webRequest,\n createDevRuntimeOptions(options, documentSecurity.transform),\n );\n\n if (result === \"next\") {\n // Vite owns its own asset URLs, so an unmatched request still\n // falls through. The post middleware below is what turns whatever\n // Vite could not serve into the same negotiated not-found\n // production returns.\n next();\n return;\n }\n\n applyDevDocumentSecurity(result, documentSecurity.nonce);\n await writeWebResponse(response, result);\n } catch (error) {\n next(error);\n }\n });\n\n // The returned hook registers this after the Vite middleware. It sees\n // only requests that Vite cannot serve. `appType` is \"custom\", so no SPA\n // fallback intercepts these requests. Development and production render\n // the same negotiated not-found response for an unmatched path.\n return () => {\n // See the note above the earlier `server.middlewares.use` call. This\n // handler is deliberately async so tests can await the returned\n // promise. Vite itself never inspects that return value.\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n server.middlewares.use(async (request, response, next) => {\n try {\n let webRequest: Request;\n\n try {\n webRequest = toWebRequest(request, {\n allowedHosts: [request.headers.host ?? \"localhost\"],\n });\n } catch (error) {\n if (error instanceof UnsupportedMethodError) {\n writeNotImplemented(response);\n return;\n }\n\n throw error;\n }\n\n const routesDir = resolve(\n server.config.root,\n options.routesDir ?? \"src/routes\",\n );\n const manifest = await loadDevManifest(server, request, routesDir);\n\n warnMissingRootNotFound(manifest, routesDir);\n\n const documentSecurity = createDevDocumentSecurity(\n server,\n viteNoncePlaceholder,\n );\n const notFoundResponse = await renderNotFoundResponse(\n manifest,\n webRequest,\n createDevFallbackOptions(options, documentSecurity.transform),\n );\n applyDevDocumentSecurity(\n notFoundResponse,\n documentSecurity.nonce,\n );\n await writeWebResponse(response, notFoundResponse);\n } catch (error) {\n next(error);\n }\n });\n };\n },\n };\n}\n\ntype AstNode = {\n [key: string]: unknown;\n end: number;\n start: number;\n type: string;\n};\n\n// TYPE-EVIDENCE: rollup returns a generic program node. The local type is a loose access shape.\nfunction asAstNode(value: unknown): AstNode {\n // TYPE-EVIDENCE: the caller passes a rollup program node. The cast labels it with the loose access shape.\n return value as AstNode;\n}\n\n// Vite 6 treats the `meta` token in `import.meta` as an imported reference.\n// Give an imported `meta` binding a private name before development SSR runs.\nfunction protectSsrImportMeta(code: string, id: string) {\n if (!code.includes(\"import.meta\")) {\n return null;\n }\n\n const ast = asAstNode(parseAst(code));\n const declaration = asNodeArray(ast.body).find((node) =>\n node.type === \"ImportDeclaration\" &&\n asNodeArray(node.specifiers).some((specifier) =>\n asNode(specifier.local)?.type === \"Identifier\" &&\n asNode(specifier.local)?.name === \"meta\"\n )\n );\n const specifier = declaration &&\n asNodeArray(declaration.specifiers).find((candidate) =>\n asNode(candidate.local)?.type === \"Identifier\" &&\n asNode(candidate.local)?.name === \"meta\"\n );\n const local = specifier && asNode(specifier.local);\n\n if (!declaration || !specifier || !local) {\n return null;\n }\n\n let alias = \"__demiurge_imported_meta__\";\n while (new RegExp(`\\\\b${alias}\\\\b`).test(code)) {\n alias += \"_\";\n }\n\n const editor = new MagicString(code);\n const imported = asNode(specifier.imported);\n editor.overwrite(\n local.start,\n local.end,\n imported?.start === local.start ? `meta as ${alias}` : alias,\n );\n editor.appendLeft(declaration.end, `\\nconst meta = ${alias};`);\n\n return {\n code: editor.toString(),\n map: editor.generateMap({\n hires: \"boundary\",\n includeContent: true,\n source: id,\n }),\n };\n}\n\n// Page data and document contributions are server capabilities. Vite and React\n// first parse TypeScript and JSX. The plugin then removes these capabilities\n// before Rollup follows the final client graph. This sequence excludes request\n// code and server-only imports from browser chunks. The exported document\n// bindings remain as `undefined` so the\n// route module keeps a stable shape without evaluating their initializers.\nexport function stripClientPageData(code: string) {\n const ast = asAstNode(parseAst(code));\n const dataRanges: Array<{ end: number; start: number }> = [];\n const documentRanges = findDocumentContributionRanges(ast);\n const mutationRanges = findUnsafeMethodRanges(ast);\n const mutationReexportRanges = findUnsafeMethodReexportRanges(ast);\n const serverImports: AstNode[] = [];\n\n walkAst(ast, (node) => {\n if (node.type === \"ImportDeclaration\" && isServerOnlyImport(node)) {\n serverImports.push(node);\n return;\n }\n\n if (node.type !== \"CallExpression\" || !isPageCallee(node.callee)) {\n return;\n }\n\n const argument = asNodeArray(node.arguments)[0];\n if (argument?.type !== \"ObjectExpression\") {\n return;\n }\n\n for (const property of asNodeArray(argument.properties)) {\n if (property.type === \"Property\" && propertyName(property.key) === \"data\") {\n dataRanges.push({ end: property.end, start: property.start });\n }\n }\n });\n\n const serverRanges = [\n ...dataRanges,\n ...documentRanges,\n ...mutationRanges,\n ...mutationReexportRanges,\n ];\n\n if (serverRanges.length === 0) {\n return code;\n }\n\n const removalRanges = [...serverRanges];\n for (const declaration of serverImports) {\n const localNames = asNodeArray(declaration.specifiers)\n .map((specifier) => asNode(specifier.local))\n .filter((local): local is AstNode => local?.type === \"Identifier\")\n .map((local) => String(local.name));\n const masked = maskRanges(code, [\n ...serverRanges,\n { end: declaration.end, start: declaration.start },\n ]);\n const leakedName = localNames.find((name) =>\n new RegExp(`\\\\b${escapeRegExp(name)}\\\\b`).test(masked)\n );\n\n if (leakedName) {\n throw new Error(\n `Server-only import ${JSON.stringify(leakedName)} is used by client route code. Move that use into page data, a document contribution, or a client-safe module.`,\n );\n }\n\n removalRanges.push({ end: declaration.end, start: declaration.start });\n }\n\n return replaceRanges(code, removalRanges, (range) => {\n if (dataRanges.includes(range)) return \"data: undefined\";\n if (documentRanges.includes(range) || mutationRanges.includes(range)) {\n return \"undefined\";\n }\n return mutationReexportRanges.find((entry) => entry === range)\n ?.replacement ?? \"\";\n });\n}\n\nconst unsafeMethodNames = new Set([\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]);\n\nfunction findUnsafeMethodRanges(ast: AstNode) {\n const ranges: Array<{ end: number; start: number }> = [];\n const exportedLocals = new Set<string>();\n\n for (const statement of asNodeArray(ast.body)) {\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n const declaration = asNode(statement.declaration);\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of asNodeArray(declaration.declarations)) {\n const id = asNode(declarator.id);\n if (\n id?.type === \"Identifier\" &&\n unsafeMethodNames.has(String(id.name))\n ) {\n exportedLocals.add(String(id.name));\n }\n }\n }\n\n for (const specifier of asNodeArray(statement.specifiers)) {\n const exported = propertyName(specifier.exported);\n const local = propertyName(specifier.local);\n if (exported && local && unsafeMethodNames.has(exported)) {\n exportedLocals.add(local);\n }\n }\n }\n\n walkAst(ast, (node) => {\n if (node.type !== \"VariableDeclarator\") return;\n const id = asNode(node.id);\n const init = asNode(node.init);\n if (\n id?.type === \"Identifier\" &&\n exportedLocals.has(String(id.name)) &&\n init\n ) {\n ranges.push({ end: init.end, start: init.start });\n }\n });\n\n return ranges;\n}\n\nfunction findUnsafeMethodReexportRanges(ast: AstNode) {\n const ranges: Array<{ end: number; replacement: string; start: number }> = [];\n\n for (const statement of asNodeArray(ast.body)) {\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n const source = asNode(statement.source)?.value;\n if (typeof source !== \"string\") continue;\n\n const safe: string[] = [];\n const unsafe: string[] = [];\n for (const specifier of asNodeArray(statement.specifiers)) {\n const exported = propertyName(specifier.exported);\n const local = propertyName(specifier.local);\n if (!exported || !local) continue;\n if (unsafeMethodNames.has(exported)) {\n unsafe.push(exported);\n } else {\n safe.push(local === exported ? local : `${local} as ${exported}`);\n }\n }\n\n if (unsafe.length === 0) continue;\n const safeExport = safe.length > 0\n ? `export { ${safe.join(\", \")} } from ${JSON.stringify(source)};\\n`\n : \"\";\n const removedExports = unsafe\n .map((name) => `export const ${name} = undefined;`)\n .join(\"\\n\");\n ranges.push({\n end: statement.end,\n replacement: `${safeExport}${removedExports}`,\n start: statement.start,\n });\n }\n\n return ranges;\n}\n\nconst documentContributionNames = new Set([\"links\", \"metadata\", \"scripts\"]);\n\nfunction findDocumentContributionRanges(ast: AstNode) {\n const exportedLocals = new Set<string>();\n\n for (const statement of asNodeArray(ast.body)) {\n if (statement.type !== \"ExportNamedDeclaration\") continue;\n\n const declaration = asNode(statement.declaration);\n if (declaration?.type === \"VariableDeclaration\") {\n for (const declarator of asNodeArray(declaration.declarations)) {\n const id = asNode(declarator.id);\n if (\n id?.type === \"Identifier\" &&\n documentContributionNames.has(String(id.name))\n ) {\n exportedLocals.add(String(id.name));\n }\n }\n }\n\n for (const specifier of asNodeArray(statement.specifiers)) {\n const exported = propertyName(specifier.exported);\n const local = propertyName(specifier.local);\n if (exported && local && documentContributionNames.has(exported)) {\n exportedLocals.add(local);\n }\n }\n }\n\n const ranges: Array<{ end: number; start: number }> = [];\n walkAst(ast, (node) => {\n if (node.type !== \"VariableDeclarator\") return;\n const id = asNode(node.id);\n const init = asNode(node.init);\n if (\n id?.type === \"Identifier\" &&\n exportedLocals.has(String(id.name)) &&\n init\n ) {\n ranges.push({ end: init.end, start: init.start });\n }\n });\n\n return ranges;\n}\n\nfunction isRouteSource(\n root: string,\n options: DemiurgeVitePluginOptions,\n id: string,\n) {\n const file = id.split(\"?\", 1)[0] ?? id;\n const routesRoot = resolve(root, options.routesDir ?? \"src/routes\");\n const pathFromRoutes = relative(routesRoot, file);\n return pathFromRoutes !== \"\" &&\n pathFromRoutes !== \"..\" &&\n !pathFromRoutes.startsWith(`..${sep}`);\n}\n\nfunction walkAst(value: unknown, visit: (node: AstNode) => void) {\n if (!value || typeof value !== \"object\") return;\n if (Array.isArray(value)) {\n for (const item of value) walkAst(item, visit);\n return;\n }\n\n // TYPE-EVIDENCE: the value was checked to be an object. The cast adds the loose AST node shape.\n const node = value as Partial<AstNode>;\n if (typeof node.type !== \"string\") return;\n // TYPE-EVIDENCE: the type field check above confirms the value is an AST node. The cast asserts that node shape.\n visit(node as AstNode);\n for (const [key, child] of Object.entries(node)) {\n if (!new Set([\"end\", \"loc\", \"start\", \"type\"]).has(key)) {\n walkAst(child, visit);\n }\n }\n}\n\nfunction asNode(value: unknown) {\n // TYPE-EVIDENCE: the type in value check confirms the value is an AST node. The cast asserts that node shape.\n return value && typeof value === \"object\" && \"type\" in value\n ? value as AstNode\n : undefined;\n}\n\nfunction asNodeArray(value: unknown) {\n return Array.isArray(value)\n ? value.map(asNode).filter((node): node is AstNode => Boolean(node))\n : [];\n}\n\nfunction isPageCallee(value: unknown) {\n const callee = asNode(value);\n if (callee?.type === \"Identifier\") return callee.name === \"page\";\n return callee?.type === \"MemberExpression\" &&\n propertyName(callee.property) === \"page\";\n}\n\nfunction propertyName(value: unknown) {\n const property = asNode(value);\n return property?.type === \"Identifier\" || property?.type === \"Literal\"\n ? String(property.name ?? property.value)\n : undefined;\n}\n\nfunction isServerOnlyImport(node: AstNode) {\n const source = asNode(node.source)?.value;\n return typeof source === \"string\" &&\n /(?:^|[/.-])server(?:[/.-]|$)/.test(source);\n}\n\nfunction maskRanges(code: string, ranges: Array<{ end: number; start: number }>) {\n const characters = [...code];\n for (const { end, start } of ranges) {\n characters.fill(\" \", start, end);\n }\n return characters.join(\"\");\n}\n\nfunction replaceRanges(\n code: string,\n ranges: Array<{ end: number; start: number }>,\n replacement: (range: { end: number; start: number }) => string,\n) {\n return [...ranges]\n .sort((left, right) => right.start - left.start)\n .reduce(\n (result, range) =>\n `${result.slice(0, range.start)}${replacement(range)}${result.slice(range.end)}`,\n code,\n );\n}\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nfunction createViteConfig(\n config: UserConfig,\n environment: ConfigEnv,\n viteNoncePlaceholder: string,\n): UserConfig {\n return {\n appType: \"custom\",\n build: {\n assetsInlineLimit: config.build?.assetsInlineLimit ?? 0,\n ...(environment.isSsrBuild &&\n config.build?.target === undefined &&\n config.ssr?.target !== \"webworker\"\n ? { target: \"node22.13\" }\n : {}),\n rollupOptions: {\n input: config.build?.rollupOptions?.input ?? CLIENT_ENTRY_ID,\n },\n },\n ...(environment.command === \"serve\"\n ? {\n html: { cspNonce: viteNoncePlaceholder },\n ssr: { external: [PACKAGE_NAME] },\n }\n : {}),\n };\n}\n\ntype EnvModuleInfo = {\n dynamicallyImportedIds: readonly string[];\n importedIds: readonly string[];\n isEntry: boolean;\n} | null;\n\n// A module of a dependency reads the environment of its own process. The scan\n// stays inside the source of the application, where a declared variable is.\nfunction recordClientEnvReferences(\n references: Map<string, string[]>,\n serverEnvKeys: Map<string, { sensitive: boolean }>,\n code: string,\n id: string,\n) {\n if (!serverEnvKeys.size) return;\n if (id.includes(\"/node_modules/\") || id.startsWith(\"\\0\")) return;\n\n const keys = findEnvKeyReferences(code, serverEnvKeys.keys());\n if (keys.length) references.set(id, keys);\n}\n\n// A reference is a defect only when the browser bundle holds the module. The\n// search starts at each entry of the client build and gives the import path.\nfunction collectEnvBoundaryFindings(options: {\n moduleIds: string[];\n moduleInfo: (id: string) => EnvModuleInfo;\n references: Map<string, string[]>;\n root: string;\n serverEnvKeys: Map<string, { sensitive: boolean }>;\n}): EnvBoundaryFinding[] {\n const { moduleIds, moduleInfo, references, root, serverEnvKeys } = options;\n if (!references.size) return [];\n\n const entries = moduleIds.filter((id) => moduleInfo(id)?.isEntry);\n const importsOf = (id: string) => {\n const info = moduleInfo(id);\n return info ? [...info.importedIds, ...info.dynamicallyImportedIds] : [];\n };\n const findings: EnvBoundaryFinding[] = [];\n\n for (const id of [...references.keys()].sort()) {\n const paths = entries\n .map((entry) => findImportPath(entry, id, importsOf))\n .filter((path): path is string[] => Boolean(path))\n .sort((first, second) => first.length - second.length);\n const importPath = paths[0];\n if (!importPath) continue;\n\n for (const key of references.get(id) ?? []) {\n findings.push({\n code: serverEnvKeys.get(key)?.sensitive\n ? \"client-secret\"\n : \"client-server-only\",\n importPath: importPath.map((item) => toDisplayModule(root, item)),\n key,\n module: toDisplayModule(root, id),\n });\n }\n }\n\n return findings;\n}\n\nfunction toDisplayModule(root: string, id: string) {\n const name = id.startsWith(\"\\0\") ? id.slice(1) : id;\n return name.startsWith(root) ? relative(root, name) || name : name;\n}\n\n// A route module loaded only on the server, and a dependency of the framework\n// itself, never enter this check. The build reads only application source,\n// the same rule that the environment boundary check applies.\nfunction checkServerOnlyBoundary(\n markers: Set<string>,\n isBuild: boolean,\n root: string,\n code: string,\n id: string,\n) {\n if (id.includes(\"/node_modules/\") || id.startsWith(\"\\0\")) return;\n if (!importsServerOnlyMarker(code)) return;\n\n if (isBuild) {\n markers.add(id);\n return;\n }\n\n // The development server transforms a module for the browser the same way\n // the build does. There is no client entry graph to search yet, so the\n // error names the module and stops the request immediately.\n throw new Error(formatServerOnlyDevError(toDisplayModule(root, id)));\n}\n\n// A reference is a defect only when the browser bundle holds the module. The\n// search starts at each entry of the client build and gives the import path.\nfunction collectServerOnlyBoundaryFindings(options: {\n markers: Set<string>;\n moduleIds: string[];\n moduleInfo: (id: string) => EnvModuleInfo;\n root: string;\n}): ServerOnlyBoundaryFinding[] {\n const { markers, moduleIds, moduleInfo, root } = options;\n if (!markers.size) return [];\n\n const entries = moduleIds.filter((id) => moduleInfo(id)?.isEntry);\n const importsOf = (id: string) => {\n const info = moduleInfo(id);\n return info ? [...info.importedIds, ...info.dynamicallyImportedIds] : [];\n };\n const findings: ServerOnlyBoundaryFinding[] = [];\n\n for (const id of [...markers].sort()) {\n const paths = entries\n .map((entry) => findImportPath(entry, id, importsOf))\n .filter((path): path is string[] => Boolean(path))\n .sort((first, second) => first.length - second.length);\n const importPath = paths[0];\n if (!importPath) continue;\n\n findings.push({\n importPath: importPath.map((item) => toDisplayModule(root, item)),\n module: toDisplayModule(root, id),\n });\n }\n\n return findings;\n}\n\n// The build inlines the value of each client variable. The browser then\n// validates the values with the schema that the configuration file declares.\nexport function createClientEnvSource(\n options: DemiurgeVitePluginOptions = {},\n source: EnvSource = process.env,\n) {\n const clientVariables = Object.entries(options.env ?? {})\n .filter(([, variable]) => variable.client);\n\n if (!clientVariables.length) return \"\";\n\n const absent = clientVariables.filter(([key, variable]) =>\n !variable.optional && !source[key]\n );\n\n if (absent.length) {\n throw new Error(\n [\n \"Demiurge stopped the build. The environment of the build does not have a required client variable.\",\n ...absent.map(([key]) => ` variable: ${key}`),\n \" The build inlines the value of a client variable. Give the value to the build.\",\n ].join(\"\\n\"),\n );\n }\n\n // The build inlines the value of a client variable, so the build validates\n // the value here. A deferred client variable does not exist, because the\n // type of the builder refuses that combination.\n const invalid = clientVariables\n .filter(([key]) => source[key] !== undefined)\n .flatMap(([key, variable]) => {\n // TYPE-EVIDENCE: the filter above proves the source has a value for this key.\n const rawValue = source[key] as string;\n try {\n variable.parse(key, rawValue);\n return [];\n } catch (error) {\n return [{\n key,\n message: error instanceof Error\n ? error.message\n : `Environment variable ${key} is invalid.`,\n }];\n }\n });\n\n if (invalid.length) {\n throw new Error(\n [\n \"Demiurge stopped the build. The environment of the build has an invalid client variable.\",\n ...invalid.map(({ key, message }) => ` variable: ${key}\\n ${message}`),\n ].join(\"\\n\"),\n );\n }\n\n const descriptor = serializeEnvSchema(Object.fromEntries(clientVariables));\n const values = Object.fromEntries(\n clientVariables\n .map(([key]) => [key, source[key]])\n .filter(([, value]) => value !== undefined),\n );\n\n return `\n// The build put these values in the browser bundle. The schema declares each\n// one as a client variable.\nunstable_startEnvironment(${JSON.stringify(descriptor)}, { source: ${\n JSON.stringify(values)\n } });\n`;\n}\n\nexport function createClientEntrySource(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n source: EnvSource = process.env,\n) {\n const routesDir = options.routesDir ?? \"src/routes\";\n const stylesImport = createStylesImport(root, options);\n const environmentSource = createClientEnvSource(options, source);\n const environmentImport = environmentSource\n ? \", unstable_startEnvironment\"\n : \"\";\n\n return `import { hydrateFileRouter${environmentImport} } from \"${PACKAGE_NAME}\";\n${stylesImport}\n${environmentSource}\n${createRouteMapSource(routesDir, {\n exportRoutes: false,\n includeServerOnly: false,\n })}\n\nvoid hydrateFileRouter({ routes${options.locales ? `, locales: ${JSON.stringify(options.locales)}` : \"\"} });\n`;\n}\n\nexport function createServerEntrySource(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n) {\n const routesDir = options.routesDir ?? \"src/routes\";\n const hasEnv = Boolean(options.env && Object.keys(options.env).length);\n const environmentImport = hasEnv ? \", unstable_startEnvironment\" : \"\";\n const environmentSource = hasEnv\n ? `\n// The framework validates the declared environment before the server accepts\n// traffic. A required variable that is absent or invalid stops the start. A\n// deferred variable validates on its first server access.\nexport const env = unstable_startEnvironment(${\n JSON.stringify(serializeEnvSchema(options.env ?? {}))\n }).values;\n`\n : \"\";\n\n return `import { createRequestHandler${environmentImport} } from \"${PACKAGE_NAME}\";\n${environmentSource}\n${createRouteMapSource(routesDir, {\n exportRoutes: true,\n includeServerOnly: true,\n eagerModules: true,\n })}\n\nexport function createHandler(options = {}) {\n const { clientEntry, lang, locales, styles, title, ...handlerOptions } = options;\n\n return createRequestHandler({\n ...handlerOptions,\n routes,\n routeModules,\n locales: locales ?? ${JSON.stringify(options.locales)},\n ssr: {\n clientEntry,\n lang: lang ?? ${JSON.stringify(options.document?.lang)},\n styles,\n title: title ?? ${JSON.stringify(options.document?.title)},\n },\n });\n}\n`;\n}\n\n// The development server does not load the generated server entry, so it\n// starts the declared environment here instead. A required variable that is\n// absent or invalid stops the start of the development server. Vite resolves\n// the configuration before it creates the file watcher, so a failure in this\n// hook rejects `createServer` and leaves no open handle. A failure in\n// `configureServer` would instead hold the process open after the diagnostic.\nfunction startDevEnvironment(options: DemiurgeVitePluginOptions) {\n if (!options.env || !Object.keys(options.env).length) return;\n\n startEnvironment(options.env);\n}\n\n// Both virtual entries use this function. Therefore, their prefix removal and\n// route-key formats stay equal. The server entry requires framework-attached\n// `.ts` files such as `@policy.ts` and `@middleware.ts`. Previously, a\n// `.tsx`-only glob omitted these files from production. Development still found\n// and applied them.\nfunction createRouteMapSource(\n routesDir: string,\n {\n exportRoutes,\n eagerModules = false,\n includeServerOnly,\n }: {\n eagerModules?: boolean;\n exportRoutes: boolean;\n includeServerOnly: boolean;\n },\n) {\n const routesGlobs = toRootAbsoluteGlobs(routesDir, includeServerOnly);\n const routesPrefix = toRootAbsolutePrefix(routesDir);\n\n return eagerModules\n ? `const eagerRouteModules = import.meta.glob(${JSON.stringify(routesGlobs)}, { eager: true });\nconst routePrefix = ${JSON.stringify(routesPrefix)};\nexport const routeModules = Object.fromEntries(\n Object.entries(eagerRouteModules).map(([file, module]) => [\n \\`./routes/\\${file.slice(routePrefix.length)}\\`,\n module,\n ]),\n);\n${exportRoutes ? \"export \" : \"\"}const routes = Object.fromEntries(\n Object.entries(routeModules).map(([file, module]) => [\n file,\n async () => module,\n ]),\n);`\n : `const routeModules = import.meta.glob(${JSON.stringify(routesGlobs)});\nconst routePrefix = ${JSON.stringify(routesPrefix)};\n${exportRoutes ? \"export \" : \"\"}const routes = Object.fromEntries(\n Object.entries(routeModules).map(([file, load]) => [\n \\`./routes/\\${file.slice(routePrefix.length)}\\`,\n load,\n ]),\n);`;\n}\n\n// These two files run only on the server. They control a request before the\n// route runs and do not render. A client glob would create public chunks in\n// `dist/client`. These chunks could expose credentials, authorization logic, or\n// internal host names from a middleware or policy closure.\nconst serverOnlyRouteFiles = [\"@middleware.ts\", \"@policy.ts\"];\n\nfunction toRootAbsoluteGlobs(routesDir: string, includeServerOnly: boolean) {\n const base = `/${routesDir.replace(/^\\/|\\/$/g, \"\")}`;\n const globs = [`${base}/**/*.{ts,tsx}`];\n\n if (!includeServerOnly) {\n globs.push(\n ...serverOnlyRouteFiles.flatMap((fileName) => [\n `!${base}/${fileName}`,\n `!${base}/**/${fileName}`,\n ]),\n );\n }\n\n return globs;\n}\n\nfunction toRootAbsolutePrefix(routesDir: string) {\n return `/${routesDir.replace(/^\\/|\\/$/g, \"\")}/`;\n}\n\nfunction createStylesImport(\n root: string,\n options: DemiurgeVitePluginOptions,\n) {\n if (options.styles === false) {\n return \"\";\n }\n\n const stylesFile = options.styles ?? \"src/styles.css\";\n const resolvedStylesFile = resolve(root, stylesFile);\n\n return existsSync(resolvedStylesFile)\n ? `import ${JSON.stringify(`/${stylesFile.replace(/^\\/+/, \"\")}`)};`\n : \"\";\n}\n\n// Development serves the same image URLs that production serves. A static\n// loader path describes its own transform, so the same optimizer answers\n// both loaders without any build output.\n// Only `configureServer` registers the route audit panel, and Vite runs that\n// hook for the development server alone. A production environment removes the\n// panel as well, because a build or a start script can set that environment.\nexport function isRouteAuditEnabled(options: DemiurgeVitePluginOptions) {\n return options.devtools !== false && process.env.NODE_ENV !== \"production\";\n}\n\nexport function createDevImageOptimizer(\n server: ViteDevServer,\n options: DemiurgeVitePluginOptions,\n) {\n const publicDir = server.config.publicDir;\n const optimizerPath = options.images?.optimizerPath ?? \"/_demiurge/image\";\n\n if (!publicDir) {\n return async () => null;\n }\n\n return createImageOptimizer({\n policy: options.images,\n resolveVariant: (pathname) =>\n parseImageVariantPath(pathname, optimizerPath),\n root: publicDir,\n });\n}\n\n// Development renders through the production pipeline. It adds the virtual\n// client entry, the Vite HTML transform, and a development flag for stack\n// traces. The shared handler makes all security and routing decisions.\nfunction createDevRuntimeOptions(\n options: DemiurgeVitePluginOptions,\n transformDocument: (html: string) => Promise<string>,\n) {\n return {\n dev: true,\n ssr: createDevSsrOptions(options),\n transformDocument,\n renderPage: async (\n match: Parameters<PageRenderer>[0],\n renderOptions: Parameters<PageRenderer>[1],\n ) => {\n if (match.render.mode === \"streaming\") {\n return await renderStreamingPageResponse(match, {\n ...renderOptions,\n clientEntry: DEV_CLIENT_ENTRY_PATH,\n transformDocument,\n });\n }\n\n const html = await transformDocument(\n renderPageDocument(match, {\n ...renderOptions,\n clientEntry: DEV_CLIENT_ENTRY_PATH,\n }),\n );\n\n return new Response(html, {\n headers: { \"content-type\": \"text/html; charset=utf-8\" },\n });\n },\n };\n}\n\nfunction createDevDocumentSecurity(\n server: ViteDevServer,\n viteNoncePlaceholder: string,\n) {\n const nonce = createCspNonce();\n const shieldNonce = createCspNonce();\n\n return {\n nonce,\n transform: async (html: string) => {\n const shielded = shieldViteNonceTargets(html, shieldNonce);\n const transformed = await server.transformIndexHtml(\"/\", shielded);\n\n return replaceNonceAttribute(\n replaceNonceAttribute(transformed, shieldNonce),\n viteNoncePlaceholder,\n nonce,\n );\n },\n };\n}\n\nfunction shieldViteNonceTargets(html: string, nonce: string) {\n const lowerHtml = html.toLowerCase();\n let cursor = 0;\n let output = \"\";\n\n while (cursor < html.length) {\n const tagStart = html.indexOf(\"<\", cursor);\n\n if (tagStart === -1) {\n return output + html.slice(cursor);\n }\n\n output += html.slice(cursor, tagStart);\n\n if (lowerHtml.startsWith(\"<!--\", tagStart)) {\n const commentEnd = lowerHtml.indexOf(\"-->\", tagStart + 4);\n const end = commentEnd === -1 ? html.length : commentEnd + 3;\n output += html.slice(tagStart, end);\n cursor = end;\n continue;\n }\n\n const name = lowerHtml.slice(tagStart).match(/^<\\s*(script|style|link)\\b/)?.[1];\n\n if (!name) {\n output += \"<\";\n cursor = tagStart + 1;\n continue;\n }\n\n const tagEnd = findHtmlTagEnd(html, tagStart);\n\n if (tagEnd === -1) {\n return output + html.slice(tagStart);\n }\n\n const openingTag = html.slice(tagStart, tagEnd + 1);\n output += /(?:^|\\s)nonce(?:\\s|=|>)/i.test(openingTag)\n ? openingTag\n : addNonceAttribute(openingTag, nonce);\n cursor = tagEnd + 1;\n\n if (name === \"script\" || name === \"style\") {\n const closeStart = lowerHtml.indexOf(`</${name}`, cursor);\n\n if (closeStart === -1) {\n return output + html.slice(cursor);\n }\n\n output += html.slice(cursor, closeStart);\n cursor = closeStart;\n }\n }\n\n return output;\n}\n\nfunction findHtmlTagEnd(html: string, start: number) {\n let quote: \"\\\"\" | \"'\" | undefined;\n\n for (let index = start + 1; index < html.length; index++) {\n const character = html[index];\n\n if (quote) {\n if (character === quote) quote = undefined;\n continue;\n }\n\n if (character === \"\\\"\" || character === \"'\") {\n quote = character;\n } else if (character === \">\") {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction addNonceAttribute(openingTag: string, nonce: string) {\n const insertion = /\\/\\s*>$/.test(openingTag)\n ? openingTag.lastIndexOf(\"/\")\n : openingTag.length - 1;\n\n return `${openingTag.slice(0, insertion)} nonce=\"${nonce}\"${openingTag.slice(insertion)}`;\n}\n\nfunction replaceNonceAttribute(\n html: string,\n current: string,\n replacement?: string,\n) {\n const pattern = new RegExp(\n `(\\\\snonce\\\\s*=\\\\s*)([\"'])${escapeRegExp(current)}\\\\2`,\n \"g\",\n );\n\n return html.replace(\n pattern,\n replacement ? `$1\"${replacement}\"` : \"\",\n );\n}\n\nfunction applyDevDocumentSecurity(response: Response, nonce: string) {\n const contentType = response.headers.get(\"content-type\");\n const csp = response.headers.get(\"content-security-policy\");\n\n if (!contentType?.toLowerCase().startsWith(\"text/html\") || !csp) {\n return;\n }\n\n const source = `'nonce-${nonce}'`;\n const withScriptNonce = addCspSource(\n csp,\n [\"script-src-elem\", \"script-src\"],\n \"script-src\",\n source,\n );\n const withStyleNonce = allowsUnsafeInline(\n withScriptNonce,\n [\"style-src-elem\", \"style-src\"],\n )\n ? withScriptNonce\n : addCspSource(\n withScriptNonce,\n [\"style-src-elem\", \"style-src\"],\n \"style-src\",\n source,\n );\n\n response.headers.set(\"content-security-policy\", withStyleNonce);\n response.headers.set(\"cache-control\", \"private, no-store\");\n}\n\nfunction addCspSource(\n csp: string,\n directiveNames: readonly string[],\n fallbackDirectiveName: \"script-src\" | \"style-src\",\n source: string,\n) {\n const directives = csp.split(\";\").map((directive) => directive.trim());\n const directiveIndex = findCspDirectiveIndex(directives, directiveNames);\n\n const defaultDirective = directives.find((directive) =>\n directive.split(/\\s+/, 1)[0]?.toLowerCase() === \"default-src\"\n );\n\n if (directiveIndex === -1 && !defaultDirective) return csp;\n\n const [currentName, ...currentSources] =\n (directiveIndex === -1 ? defaultDirective! : directives[directiveIndex]!)\n .split(/\\s+/);\n const updatedDirective = [\n directiveIndex === -1 ? fallbackDirectiveName : currentName!,\n ...new Set([\n ...currentSources.filter((current) => current !== \"'none'\"),\n source,\n ]),\n ].join(\" \");\n\n if (directiveIndex === -1) {\n directives.push(updatedDirective);\n } else {\n directives[directiveIndex] = updatedDirective;\n }\n\n return directives.join(\"; \");\n}\n\nfunction allowsUnsafeInline(\n csp: string,\n directiveNames: readonly string[],\n) {\n const directives = csp.split(\";\").map((directive) => directive.trim());\n const directiveIndex = findCspDirectiveIndex(directives, directiveNames);\n const effectiveDirective = directiveIndex === -1\n ? directives.find((directive) =>\n directive.split(/\\s+/, 1)[0]?.toLowerCase() === \"default-src\"\n )\n : directives[directiveIndex];\n const sources = effectiveDirective?.split(/\\s+/).slice(1) ?? [];\n\n return sources.includes(\"'unsafe-inline'\") &&\n !sources.some((source) => /^'(?:nonce-|sha(?:256|384|512)-)/i.test(source));\n}\n\nfunction findCspDirectiveIndex(\n directives: readonly string[],\n directiveNames: readonly string[],\n) {\n for (const name of directiveNames) {\n const index = directives.findIndex((directive) =>\n directive.split(/\\s+/, 1)[0]?.toLowerCase() === name\n );\n\n if (index !== -1) return index;\n }\n\n return -1;\n}\n\n// Both dev middlewares need the manifest for the same request, and building\n// it walks the routes directory. The pre middleware always runs, so the post\n// middleware reuses what it already produced rather than scanning twice on\n// every unmatched request.\nconst DEV_MANIFEST = Symbol.for(\"demiurge.devManifest\");\n\ntype DevManifestCarrier = { [DEV_MANIFEST]?: RouteManifest };\n\nasync function loadDevManifest(\n server: ViteDevServer,\n request: IncomingMessage,\n routesDir: string,\n) {\n // TYPE-EVIDENCE: the cast adds the symbol-keyed manifest carrier field used for request-local caching.\n const carrier = request as IncomingMessage & DevManifestCarrier;\n const cached = carrier[DEV_MANIFEST];\n\n if (cached) {\n return cached;\n }\n\n const manifest = createRouteManifest(\n await createDevRouteImporters(server, routesDir),\n );\n\n carrier[DEV_MANIFEST] = manifest;\n\n return manifest;\n}\n\nfunction createDevSsrOptions(options: DemiurgeVitePluginOptions) {\n return {\n clientEntry: DEV_CLIENT_ENTRY_PATH,\n lang: options.document?.lang,\n title: options.document?.title,\n };\n}\n\nfunction createDevFallbackOptions(\n options: DemiurgeVitePluginOptions,\n transformDocument: (html: string) => Promise<string>,\n) {\n return {\n ...createDevSsrOptions(options),\n dev: true,\n transformDocument,\n };\n}\n\nconst warnedRoots = new Set<string>();\n\n// The framework built-in is a temporary fallback, not a production 404. The\n// build gate enforces this rule. This warning gives the same message earlier.\nfunction warnMissingRootNotFound(manifest: RouteManifest, routesDir: string) {\n if (\n warnedRoots.has(routesDir) ||\n manifest.fallbacks.notFound.some(\n (fallback) => fallback.fileSegments.length === 0,\n )\n ) {\n return;\n }\n\n warnedRoots.add(routesDir);\n console.warn(missingRootNotFoundMessage(join(routesDir, \"@not-found.tsx\")));\n}\n\n// The framework ships a working 404 so nothing is ever blank, and refuses to\n// let an app reach production still rendering it. A generic framework page in\n// front of real users is a failure of the framework, not of the app that never\n// got around to it.\nexport async function assertRootNotFoundRoute(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n) {\n const routesDirOption = options.routesDir ?? \"src/routes\";\n const routesDir = resolve(root, routesDirOption);\n\n if (!existsSync(routesDir)) {\n return;\n }\n\n const files = await findRouteFiles(routesDir);\n const names = files.map((file) =>\n relative(routesDir, file).split(sep).join(\"/\"),\n );\n\n if (names.some((name) => /^@not-found\\.tsx?$/.test(name))) {\n return;\n }\n\n const pageRoute = await findPageRouteFile(files);\n\n // An API-only app never wants an HTML not-found document, and nagging it\n // would be user hostile. It builds clean and gets problem+json.\n if (!pageRoute) {\n return;\n }\n\n throw new Error(\n missingRootNotFoundBuildMessage(\n routesDirOption,\n relative(routesDir, pageRoute).split(sep).join(\"/\"),\n ),\n );\n}\n\n// Page detection is a source scan rather than a module evaluation: the plugin\n// cannot execute route modules at build time. A page route is a file that\n// calls `page(...)`, which is the only way to declare one.\nasync function findPageRouteFile(files: string[]) {\n for (const file of files) {\n // Framework-attached files own no address, so they are never page routes.\n if (relative(dirname(file), file).startsWith(\"@\")) {\n continue;\n }\n\n if (declaresPageRoute(await readFile(file, \"utf8\"))) {\n return file;\n }\n }\n\n return undefined;\n}\n\nexport function missingRootNotFoundBuildMessage(\n routesDir: string,\n pageRoute: string,\n) {\n return `Demiurge will not build an app with page routes and no ${routesDir}/@not-found.tsx.\n\n\"${pageRoute}\" declares a page, so a browser can reach a path this app does not serve. Decide what that looks like rather than shipping the framework built-in.\n\nCreate ${routesDir}/@not-found.tsx:\n\n export default function NotFound({ pathname }: { pathname: string }) {\n return <h1>Nothing at {pathname}</h1>;\n }\n\nIt renders inside the layouts above the requested path. Opt out with \"export const layout = false\".`;\n}\n\nexport function missingRootNotFoundMessage(notFoundFile: string) {\n return `Demiurge is serving its built-in 404 because ${notFoundFile} does not exist.\n\nCreate it before building for production:\n\n export default function NotFound({ pathname }: { pathname: string }) {\n return <h1>Nothing at {pathname}</h1>;\n }\n`;\n}\n\nexport function createDocumentHtml({\n entrySrc,\n lang,\n links,\n metadata,\n nonce,\n scripts,\n styles,\n title,\n}: {\n entrySrc: string;\n lang?: string;\n links?: LinkTag[];\n metadata?: ResolvedMetadata;\n nonce?: string;\n scripts?: ScriptTag[];\n styles?: string[];\n title?: string;\n}) {\n return renderDocument({\n entrySrc,\n lang,\n links,\n metadata,\n nonce,\n scripts,\n styles,\n title,\n });\n}\n\nasync function generateTypedRoutes(\n root: string,\n options: DemiurgeVitePluginOptions,\n) {\n const routesDir = resolve(root, options.routesDir ?? \"src/routes\");\n const outputFile = resolve(\n root,\n typeof options.typedRoutes === \"object\"\n ? options.typedRoutes.outputFile ?? DEFAULT_TYPED_ROUTES_OUTPUT\n : DEFAULT_TYPED_ROUTES_OUTPUT,\n );\n\n await generateRoutes({\n outputFile,\n routesDir,\n locales: options.locales?.supportedLocales,\n localeNamespaces: [\n ...Object.values(options.locales?.path?.labels ?? {}),\n ...Object.keys(options.locales?.aliases ?? {}),\n ...(options.locales?.path?.reserved ?? []),\n ],\n });\n}\n\nfunction isRouteFile(routesDir: string, file: string) {\n return (\n file.startsWith(routesDir) &&\n /\\.tsx?$/.test(file)\n );\n}\n\nexport async function createDevRouteImporters(\n server: ViteDevServer,\n routesDir: string,\n) {\n const files = await findRouteFiles(routesDir);\n const routes: Record<string, RouteImporter> = {};\n\n for (const file of files) {\n const routeKey = toRouteKey(routesDir, file);\n // TYPE-EVIDENCE: the SSR loader returns a module record for a route file. The cast labels it as a route module.\n routes[routeKey] = async () =>\n (await server.ssrLoadModule(file)) as RouteModule;\n }\n\n return routes;\n}\n\nexport async function handleDevRequest(\n manifest: RouteManifest,\n request: Request,\n options: Parameters<typeof handleRequestWithManifest>[2] = {},\n) {\n const url = new URL(request.url);\n const routeMatch = findRouteMatch(manifest.routes, url.pathname);\n\n if (!routeMatch) {\n return \"next\" as const;\n }\n\n return await handleRequestWithManifest(manifest, request, options);\n}\n\nasync function findRouteFiles(directory: string) {\n const entries = await readdir(directory, {\n recursive: true,\n withFileTypes: true,\n });\n\n return entries\n .filter((entry) => entry.isFile() && /\\.tsx?$/.test(entry.name))\n .map((entry) => resolve(entry.parentPath, entry.name));\n}\n\n// Every route file is read and parsed. Without a cap, a large route tree opens\n// one descriptor per file at once, which is how this hits EMFILE rather than a\n// CPU limit.\nconst policyVerificationConcurrency = 8;\nconst policyVerificationDebounceMs = 50;\n\nasync function mapWithConcurrency<Item, Result>(\n items: readonly Item[],\n limit: number,\n task: (item: Item) => Promise<Result>,\n) {\n const results = new Array<Result>(items.length);\n let next = 0;\n\n const workers = Array.from(\n { length: Math.min(limit, items.length) },\n async () => {\n while (next < items.length) {\n const index = next++;\n results[index] = await task(items[index]!);\n }\n },\n );\n\n await Promise.all(workers);\n\n return results;\n}\n\n/** The result of one static pass over the route tree. */\nexport type RoutePolicyInspection = {\n /** Every finding of the pass, in a stable order. */\n findings: StaticPolicyFinding[];\n /** The inspection of each route file, in the order that the walk found. */\n inspections: RouteFileInspection[];\n /** The absolute path of the route directory. */\n routesDir: string;\n};\n\n/**\n * Reads the route tree once and returns the findings and the inspections.\n *\n * The build verifier and the `demiurge inspect` command both call this\n * function, so one pass gives one answer for the route tree.\n */\nexport async function inspectRoutePolicies(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n): Promise<RoutePolicyInspection> {\n const routesDir = resolve(root, options.routesDir ?? \"src/routes\");\n\n if (!existsSync(routesDir)) {\n return { findings: [], inspections: [], routesDir };\n }\n\n const inspections = await mapWithConcurrency(\n await findRouteFiles(routesDir),\n policyVerificationConcurrency,\n inspectRouteFile,\n );\n const findings = [\n ...inspections.flatMap((inspection) => inspection.findings),\n ...auditDocumentPolicyCoverage(routesDir, inspections),\n ...auditRouteAccessCoverage(routesDir, inspections),\n ];\n\n findings.sort((left, right) =>\n left.file.localeCompare(right.file) ||\n (left.exportName ?? \"\").localeCompare(right.exportName ?? \"\") ||\n left.code.localeCompare(right.code)\n );\n\n return { findings, inspections, routesDir };\n}\n\nexport async function verifyRoutePolicies(\n root: string,\n options: DemiurgeVitePluginOptions = {},\n) {\n return (await inspectRoutePolicies(root, options)).findings;\n}\n\nexport function formatStaticPolicyFindings(findings: StaticPolicyFinding[]) {\n return [\n \"Demiurge found invalid static route policy:\",\n ...findings.map(formatStaticPolicyFinding),\n ].join(\"\\n\");\n}\n\nexport function formatStaticPolicyFinding(finding: StaticPolicyFinding) {\n const source = finding.exportName\n ? `${finding.file} export ${finding.exportName}`\n : finding.file;\n return `${source}: [${finding.code}] ${finding.message}`;\n}\n\nfunction toRouteKey(routesDir: string, file: string) {\n const relativePath = relative(routesDir, file).split(sep).join(\"/\");\n return `./routes/${relativePath}`;\n}\n"],"names":["PACKAGE_NAME","generateRoutes","options","routeFiles","findRouteFiles","middleware","file","toMiddlewareInfo","value","routes","toRouteInfo","route","a","b","assertLocaleNamespaceCollisions","source","renderRoutesModule","mkdir","dirname","writeFile","namespaces","localeSegments","segment","directory","readdir","entry","resolve","fileSegments","relative","sep","urlSegments","isRouteGroupSegment","pathVars","isAttachedFileForRoute","toImportPath","outputFile","importPath","attachedFileSegments","routeFileSegments","index","locales","renderMiddlewareImport","_entry","renderMiddlewareContextAlias","locale","renderPathVarsEntry","renderConcretePathEntry","renderRequestContextEntry","renderMutationMethodsEntry","pathType","name","toConcretePathType","contexts","context","pattern","part","escapeTemplate","findServerEnvKeys","schema","keys","key","variable","findEnvKeyReferences","code","names","found","visitNode","parseAst","findImportPath","target","importsOf","visited","queue","path","next","formatEnvBoundaryFindings","findings","formatEnvBoundaryFinding","finding","node","match","visitValue","visitKey","isPatternProperty","visitOwnChildren","asNode","computed","child","item","serverOnlyMarkerSpecifiers","importsServerOnlyMarker","findsMarkerImport","formatServerOnlyBoundaryFindings","formatServerOnlyBoundaryFinding","formatServerOnlyDevError","module","ast","walkAst","isMarkerSource","visit","httpMethods","responseHelpers","inspectRouteFile","readFile","extracted","extractRouteModuleSource","attached","basename","declaresPageRoute","validateExtractedRouteModule","method","verifyRoutePolicySource","loader","transformed","transformWithEsbuild","extractRouteModule","auditDocumentPolicyCoverage","routesDir","inspections","policies","inspection","isPolicyFile","isFallbackDocumentFile","applicable","applicablePolicies","resolveDocumentCspState","describeMissingDocumentPolicy","auditRouteAccessCoverage","resolveRouteAccessState","routeDirectory","routeState","isSameOrAbove","state","policy","exception","nearest","join","left","right","mergeDocumentCspState","base","override","distance","PACKAGE_NAME_PATTERN","DEMIURGE_NAMED_IMPORT","locals","binding","imported","local","body","imports","collectCoreImports","constants","collectConstants","declarations","collectVariableInitializers","exports","collectNamedExports","capabilities","declaredMethods","accessState","declaresDocumentPolicy","documentCspState","exportName","localName","initializer","extractAccessState","extractDocumentCspState","extractRoutePolicy","isHttpMethod","capability","extractCapability","isPlainObject","identifierName","argument","asNodeArray","property","propertyName","extractDocumentCspStateFromValue","callee","objectName","preset","extractPresetCspState","extractDocumentSecurityCspState","literal","evaluateLiteral","unresolved","extractCspValueState","optionsNode","defaultState","mergePresetCspState","extractCspOptionState","isSecurityException","statement","declaration","declarator","specifier","exported","helper","arguments_","cors","evaluateObjectProperty","securityPolicy","result","valueNode","document","extractSecurityPolicy","security","routeModule","availableMethods","validateCorsPolicy","error","errorMessage","validateRateLimit","validateExceptionReasons","createSecurityHeaders","toFragmentDocument","endpoints","declaresEndpoints","declaredCsp","resolveCsp","reportTo","statesNoReason","validateRaisedBodyLimit","declared","getBodySizeException","declaredBytes","defaultBytes","parseBodySize","resolveMaxBodySize","DEFAULT_MAX_BODY_SIZE","validateRateLimitPolicy","message","quasi","values","element","fallback","REDACTED_VALUE","cookieFieldNames","sessionFieldNames","cookieValueFieldNames","sessionValueFieldNames","serializeInspectionReport","report","redactSecrets","attachRedactions","redactions","walk","isRecord","scope","isSessionRecord","itemPath","reason","classifyField","descend","normalized","normalizeFieldName","prototype","ROUTE_AUDIT_VERSION","ROUTE_AUDIT_PATH","supportedMethods","routeAuditResolutions","isRouteAuditRequest","request","createRouteAuditResponse","manifest","url","createRouteAudit","json","renderRouteAuditDocument","origin","pathname","routeRequest","routeMatch","matchRoute","loadInheritedRoutePolicy","finishRouteAudit","selectMethod","cacheReads","page","loadPageRoute","createRecordingCache","layout","toRoutePattern","input","nonce","securityPolicyRequiresNonce","createCspNonce","scripts","script","auditOptions","createSecurityAudit","findRouteMatch","MalformedPathnameError","reads","cache","createMemoryCache","serializeCacheKey","formatDuration","serializeCacheTag","duration","panelStyles","escapeHtml","renderRouteSection","renderFindingsSection","renderHeadersSection","renderPolicySection","renderMetadataSection","renderScriptsSection","renderCacheSection","section","table","none","entries","list","renderFinding","headers","metadata","rows","read","title","CLIENT_ENTRY_ID","DEV_CLIENT_ENTRY_PATH","RESOLVED_CLIENT_ENTRY_ID","SERVER_ENTRY_ID","RESOLVED_SERVER_ENTRY_ID","DEFAULT_TYPED_ROUTES_OUTPUT","demiurge","defineLocales","root","isBuild","serverEnvKeys","clientEnvReferences","serverOnlyMarkers","viteNoncePlaceholder","config","environment","createViteConfig","startDevEnvironment","id","createClientEntrySource","createServerEntrySource","transformOptions","checkServerOnlyBoundary","recordClientEnvReferences","isRouteSource","protectSsrImportMeta","stripClientPageData","_outputOptions","bundle","styles","asset","clientEntry","createDocumentHtml","collectEnvBoundaryFindings","serverOnlyFindings","collectServerOnlyBoundaryFindings","assertRootNotFoundRoute","verifyRoutePolicies","errors","formatStaticPolicyFinding","formatStaticPolicyFindings","generateTypedRoutes","server","reportPolicyFindings","policyVerificationTimer","policyVerificationRun","runPolicyVerification","startPolicyVerification","policyVerificationDebounceMs","runGenerateTypedRoutes","isRouteFile","event","routeAuditEnabled","isRouteAuditEnabled","optimizeImage","createDevImageOptimizer","serveFont","createFontAssetHandler","response","webRequest","toWebRequest","UnsupportedMethodError","writeNotImplemented","loadDevManifest","writeWebResponse","font","image","documentSecurity","createDevDocumentSecurity","handleDevRequest","createDevRuntimeOptions","applyDevDocumentSecurity","warnMissingRootNotFound","notFoundResponse","renderNotFoundResponse","createDevFallbackOptions","candidate","alias","editor","MagicString","dataRanges","documentRanges","findDocumentContributionRanges","mutationRanges","findUnsafeMethodRanges","mutationReexportRanges","findUnsafeMethodReexportRanges","serverImports","isServerOnlyImport","isPageCallee","serverRanges","removalRanges","localNames","masked","maskRanges","leakedName","escapeRegExp","replaceRanges","range","unsafeMethodNames","ranges","exportedLocals","init","safe","unsafe","safeExport","removedExports","documentContributionNames","routesRoot","pathFromRoutes","characters","end","start","replacement","references","moduleIds","moduleInfo","info","first","second","toDisplayModule","markers","createClientEnvSource","clientVariables","absent","invalid","rawValue","descriptor","serializeEnvSchema","stylesImport","createStylesImport","environmentSource","createRouteMapSource","hasEnv","environmentImport","startEnvironment","exportRoutes","eagerModules","includeServerOnly","routesGlobs","toRootAbsoluteGlobs","routesPrefix","toRootAbsolutePrefix","serverOnlyRouteFiles","globs","fileName","stylesFile","resolvedStylesFile","existsSync","publicDir","optimizerPath","createImageOptimizer","parseImageVariantPath","transformDocument","createDevSsrOptions","renderOptions","renderStreamingPageResponse","html","renderPageDocument","shieldNonce","shielded","shieldViteNonceTargets","replaceNonceAttribute","lowerHtml","cursor","output","tagStart","commentEnd","tagEnd","findHtmlTagEnd","openingTag","addNonceAttribute","closeStart","quote","character","insertion","current","contentType","csp","withScriptNonce","addCspSource","withStyleNonce","allowsUnsafeInline","directiveNames","fallbackDirectiveName","directives","directive","directiveIndex","findCspDirectiveIndex","defaultDirective","currentName","currentSources","updatedDirective","sources","DEV_MANIFEST","carrier","cached","createRouteManifest","createDevRouteImporters","warnedRoots","missingRootNotFoundMessage","routesDirOption","files","pageRoute","findPageRouteFile","missingRootNotFoundBuildMessage","notFoundFile","entrySrc","lang","links","renderDocument","routeKey","toRouteKey","handleRequestWithManifest","policyVerificationConcurrency","mapWithConcurrency","items","limit","task","results","workers","inspectRoutePolicies"],"mappings":"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"}