@analogjs/vite-plugin-nitro 3.0.0-alpha.33 → 3.0.0-alpha.35

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@analogjs/vite-plugin-nitro",
3
- "version": "3.0.0-alpha.33",
3
+ "version": "3.0.0-alpha.35",
4
4
  "description": "A Vite plugin for adding a nitro API server",
5
5
  "type": "module",
6
6
  "author": "Brandon Roberts <robertsbt@gmail.com>",
@@ -1 +1 @@
1
- {"version":3,"file":"build-ssr.js","names":[],"sources":["../../../src/lib/build-ssr.ts"],"sourcesContent":["import { build, mergeConfig, UserConfig } from 'vite';\nimport { relative, resolve } from 'node:path';\n\nimport { Options } from './options.js';\nimport { getBundleOptionsKey } from './utils/rolldown.js';\n\nexport async function buildClientApp(\n config: UserConfig,\n options?: Options,\n): Promise<void> {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n const rootDir = relative(workspaceRoot, config.root || '.') || '.';\n const clientBuildConfig = mergeConfig(config, <UserConfig>{\n build: {\n ssr: false,\n outDir:\n config.build?.outDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n emptyOutDir: true,\n },\n });\n\n await build(clientBuildConfig);\n}\n\nexport async function buildSSRApp(\n config: UserConfig,\n options?: Options,\n): Promise<void> {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n const sourceRoot = options?.sourceRoot ?? 'src';\n const rootDir = relative(workspaceRoot, config.root || '.') || '.';\n const bundleOptionsKey = getBundleOptionsKey();\n const ssrBuildConfig = mergeConfig(config, <UserConfig>{\n build: {\n ssr: true,\n [bundleOptionsKey]: {\n input:\n options?.entryServer ||\n resolve(workspaceRoot, rootDir, `${sourceRoot}/main.server.ts`),\n },\n outDir:\n options?.ssrBuildDir || resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n // Preserve the client build output. The client pass already handled its\n // own cleanup, and on Windows this nested SSR build can otherwise remove\n // sibling artifacts that Nitro needs to read immediately afterward.\n emptyOutDir: false,\n },\n });\n\n await build(ssrBuildConfig);\n}\n"],"mappings":";;;;AAMA,eAAsB,eACpB,QACA,SACe;CACf,MAAM,gBAAgB,SAAS,iBAAiB,QAAQ,KAAK;CAC7D,MAAM,UAAU,SAAS,eAAe,OAAO,QAAQ,IAAI,IAAI;AAW/D,OAAM,MAVoB,YAAY,QAAoB,EACxD,OAAO;EACL,KAAK;EACL,QACE,OAAO,OAAO,UACd,QAAQ,eAAe,QAAQ,SAAS,SAAS;EACnD,aAAa;EACd,EACF,CAAC,CAE4B;;AAGhC,eAAsB,YACpB,QACA,SACe;CACf,MAAM,gBAAgB,SAAS,iBAAiB,QAAQ,KAAK;CAC7D,MAAM,aAAa,SAAS,cAAc;CAC1C,MAAM,UAAU,SAAS,eAAe,OAAO,QAAQ,IAAI,IAAI;AAmB/D,OAAM,MAjBiB,YAAY,QAAoB,EACrD,OAAO;EACL,KAAK;GAHgB,qBAAqB,GAItB,EAClB,OACE,SAAS,eACT,QAAQ,eAAe,SAAS,GAAG,WAAW,iBAAiB,EAClE;EACD,QACE,SAAS,eAAe,QAAQ,eAAe,QAAQ,SAAS,MAAM;EAIxE,aAAa;EACd,EACF,CAAC,CAEyB"}
1
+ {"version":3,"file":"build-ssr.js","names":[],"sources":["../../../src/lib/build-ssr.ts"],"sourcesContent":["import { build, mergeConfig, UserConfig } from 'vite';\nimport { relative, resolve } from 'node:path';\n\nimport { Options } from './options.js';\nimport { getBundleOptionsKey } from './utils/rolldown.js';\n\nexport async function buildClientApp(\n config: UserConfig,\n options?: Options,\n): Promise<void> {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n const rootDir = relative(workspaceRoot, config.root || '.') || '.';\n const clientBuildConfig = mergeConfig(config, <UserConfig>{\n build: {\n ssr: false,\n outDir:\n config.build?.outDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n emptyOutDir: true,\n },\n });\n\n await build(clientBuildConfig);\n}\n\nexport async function buildSSRApp(\n config: UserConfig,\n options?: Options,\n): Promise<void> {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n const sourceRoot = options?.sourceRoot ?? 'src';\n const rootDir = relative(workspaceRoot, config.root || '.') || '.';\n const bundleOptionsKey = getBundleOptionsKey();\n\n /**\n * SSR is built as a second pass from the already prepared Analog/Vite config.\n *\n * That means we intentionally start from the same base config used for the\n * client build and then merge only the SSR-specific overrides (entry, outDir,\n * `build.ssr`, etc).\n *\n * A side effect of this design is that the resolved SSR config can expose the\n * same high-level Analog plugin chain more than once when Vite/Nitro replays\n * shared plugins for the server environment. In particular,\n * `@analogjs/vite-plugin-angular` may appear twice in `config.plugins` during\n * SSR resolution:\n * - once from the normal Analog platform plugin expansion\n * - once from the reused/shared plugin graph for the SSR pass\n *\n * That does NOT imply the client build has two competing style registries.\n * The client-side duplicate-registration guard in `vite-plugin-angular`\n * therefore explicitly ignores `build.ssr === true` to avoid treating this\n * valid SSR orchestration detail as a style-map bug.\n */\n const ssrBuildConfig = mergeConfig(config, <UserConfig>{\n build: {\n ssr: true,\n [bundleOptionsKey]: {\n input:\n options?.entryServer ||\n resolve(workspaceRoot, rootDir, `${sourceRoot}/main.server.ts`),\n },\n outDir:\n options?.ssrBuildDir || resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n // Preserve the client build output. The client pass already handled its\n // own cleanup, and on Windows this nested SSR build can otherwise remove\n // sibling artifacts that Nitro needs to read immediately afterward.\n emptyOutDir: false,\n },\n });\n\n await build(ssrBuildConfig);\n}\n"],"mappings":";;;;AAMA,eAAsB,eACpB,QACA,SACe;CACf,MAAM,gBAAgB,SAAS,iBAAiB,QAAQ,KAAK;CAC7D,MAAM,UAAU,SAAS,eAAe,OAAO,QAAQ,IAAI,IAAI;AAW/D,OAAM,MAVoB,YAAY,QAAoB,EACxD,OAAO;EACL,KAAK;EACL,QACE,OAAO,OAAO,UACd,QAAQ,eAAe,QAAQ,SAAS,SAAS;EACnD,aAAa;EACd,EACF,CAAC,CAE4B;;AAGhC,eAAsB,YACpB,QACA,SACe;CACf,MAAM,gBAAgB,SAAS,iBAAiB,QAAQ,KAAK;CAC7D,MAAM,aAAa,SAAS,cAAc;CAC1C,MAAM,UAAU,SAAS,eAAe,OAAO,QAAQ,IAAI,IAAI;AAwC/D,OAAM,MAjBiB,YAAY,QAAoB,EACrD,OAAO;EACL,KAAK;GAxBgB,qBAAqB,GAyBtB,EAClB,OACE,SAAS,eACT,QAAQ,eAAe,SAAS,GAAG,WAAW,iBAAiB,EAClE;EACD,QACE,SAAS,eAAe,QAAQ,eAAe,QAAQ,SAAS,MAAM;EAIxE,aAAa;EACd,EACF,CAAC,CAEyB"}
@@ -15,6 +15,50 @@ import { relative, resolve } from "node:path";
15
15
  import { pathToFileURL } from "node:url";
16
16
  import { existsSync, readFileSync, readdirSync } from "node:fs";
17
17
  //#region packages/vite-plugin-nitro/src/lib/vite-plugin-nitro.ts
18
+ function isObjectHook(value) {
19
+ return !!value && typeof value === "object" && "handler" in value;
20
+ }
21
+ function cloneObjectHook(hook) {
22
+ if (!isObjectHook(hook)) return hook;
23
+ return {
24
+ ...hook,
25
+ handler: hook.handler
26
+ };
27
+ }
28
+ function cloneUserPlugin(plugin) {
29
+ if (!plugin || typeof plugin !== "object") return plugin;
30
+ const pluginRecord = plugin;
31
+ const clone = Object.assign(Object.create(Object.getPrototypeOf(plugin)), pluginRecord);
32
+ for (const key of Object.keys(pluginRecord)) clone[key] = cloneObjectHook(pluginRecord[key]);
33
+ return clone;
34
+ }
35
+ function cloneEnvironmentEntries(environments) {
36
+ if (!environments || typeof environments !== "object") return environments;
37
+ return Object.fromEntries(Object.entries(environments).map(([name, environment]) => {
38
+ if (!environment || typeof environment !== "object") return [name, environment];
39
+ const environmentRecord = environment;
40
+ return [name, {
41
+ ...environmentRecord,
42
+ build: environmentRecord["build"] && typeof environmentRecord["build"] === "object" ? { ...environmentRecord["build"] } : environmentRecord["build"]
43
+ }];
44
+ }));
45
+ }
46
+ function cloneUserConfig(userConfig) {
47
+ const { environments, resolve, build, server, plugins } = userConfig;
48
+ const test = userConfig.test;
49
+ return {
50
+ ...userConfig,
51
+ plugins: plugins?.map(cloneUserPlugin),
52
+ build: build && { ...build },
53
+ environments: cloneEnvironmentEntries(environments),
54
+ server: server && { ...server },
55
+ test: test && { ...test },
56
+ resolve: resolve && {
57
+ ...resolve,
58
+ alias: Array.isArray(resolve.alias) ? [...resolve.alias] : resolve.alias && typeof resolve.alias === "object" ? { ...resolve.alias } : resolve.alias
59
+ }
60
+ };
61
+ }
18
62
  function createNitroMiddlewareHandler(handler) {
19
63
  return {
20
64
  route: "/**",
@@ -307,7 +351,7 @@ function nitro(options, nitroOptions) {
307
351
  isServe = command === "serve";
308
352
  isBuild = command === "build";
309
353
  ssrBuild = userConfig.build?.ssr === true;
310
- config = userConfig;
354
+ config = cloneUserConfig(userConfig);
311
355
  isTest = isTest ? isTest : mode === "test";
312
356
  rollupExternalEntries.length = 0;
313
357
  clientIndexHtml = void 0;
@@ -508,6 +552,18 @@ function nitro(options, nitroOptions) {
508
552
  ssrEnabled: options?.ssr,
509
553
  prerenderRoutes: nitroConfig.prerender?.routes
510
554
  });
555
+ /**
556
+ * This launches the SSR environment as a second build from the
557
+ * shared plugin graph above. When debugging an apparent
558
+ * duplicate `@analogjs/vite-plugin-angular` registration, this
559
+ * is the handoff to inspect: the SSR builder replays the shared
560
+ * plugins for the server pass and may therefore expose multiple
561
+ * Angular-plugin entries in the SSR resolved config.
562
+ *
563
+ * That is expected for this orchestration path and should not
564
+ * be treated the same as a duplicated client build, where two
565
+ * Angular plugin instances would maintain separate style maps.
566
+ */
511
567
  await builder.build(builder.environments["ssr"]);
512
568
  debugSsr("builder.buildApp completed SSR build", { ssrOutputPath: options?.ssrBuildDir || resolve(workspaceRoot, "dist", rootDir, "ssr") });
513
569
  }
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-nitro.js","names":[],"sources":["../../../src/lib/vite-plugin-nitro.ts"],"sourcesContent":["import type { NitroConfig, NitroEventHandler, RollupConfig } from 'nitro/types';\nimport { build, createDevServer, createNitro } from 'nitro/builder';\nimport * as vite from 'vite';\nimport type { Plugin, UserConfig, ViteDevServer } from 'vite';\nimport { mergeConfig, normalizePath } from 'vite';\nimport { relative, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nimport { buildServer, isVercelPreset } from './build-server.js';\nimport { buildClientApp, buildSSRApp } from './build-ssr.js';\nimport {\n Options,\n PrerenderContentDir,\n PrerenderContentFile,\n PrerenderRouteConfig,\n PrerenderSitemapConfig,\n} from './options.js';\nimport { pageEndpointsPlugin } from './plugins/page-endpoints.js';\nimport { getPageHandlers } from './utils/get-page-handlers.js';\nimport { buildSitemap } from './build-sitemap.js';\nimport { devServerPlugin } from './plugins/dev-server-plugin.js';\nimport {\n toWebRequest,\n writeWebResponseToNode,\n} from './utils/node-web-bridge.js';\nimport { getMatchingContentFilesWithFrontMatter } from './utils/get-content-files.js';\nimport {\n ssrRenderer,\n clientRenderer,\n apiMiddleware,\n} from './utils/renderers.js';\nimport { getBundleOptionsKey, isRolldown } from './utils/rolldown.js';\nimport { debugNitro, debugSsr } from './utils/debug.js';\n\nfunction createNitroMiddlewareHandler(handler: string): NitroEventHandler {\n return {\n route: '/**',\n handler,\n middleware: true,\n };\n}\n\n/**\n * Creates a `rollup:before` hook that marks specified packages as external\n * in Nitro's bundler config (applied to both the server build and the\n * prerender build).\n *\n * ## Subpath matching (Rolldown compatibility)\n *\n * When `bundlerConfig.external` is an **array**, Rollup automatically\n * prefix-matches entries — `'rxjs'` in the array will also externalise\n * `'rxjs/operators'`, `'rxjs/internal/Observable'`, etc.\n *\n * Rolldown (the default bundler in Nitro v3) does **not** do this. It\n * treats array entries as exact strings. To keep behaviour consistent\n * across both bundlers, the **function** branch already needed explicit\n * subpath matching. We now use the same `isExternal` helper for all\n * branches so that `'rxjs'` reliably matches `'rxjs/operators'`\n * regardless of whether the existing `external` value is a function,\n * array, or absent.\n *\n * Without this, the Nitro prerender build fails on Windows CI with:\n *\n * [RESOLVE_ERROR] Could not resolve 'rxjs/operators'\n */\nfunction createRollupBeforeHook(externalEntries: string[]) {\n const isExternal = (source: string) =>\n externalEntries.some(\n (entry) => source === entry || source.startsWith(entry + '/'),\n );\n\n return (_nitro: unknown, bundlerConfig: RollupConfig) => {\n sanitizeNitroBundlerConfig(_nitro, bundlerConfig);\n\n if (externalEntries.length === 0) {\n return;\n }\n\n const existing = bundlerConfig.external;\n if (!existing) {\n bundlerConfig.external = externalEntries;\n } else if (typeof existing === 'function') {\n bundlerConfig.external = (\n source: string,\n importer: string | undefined,\n isResolved: boolean,\n ) => existing(source, importer, isResolved) || isExternal(source);\n } else if (Array.isArray(existing)) {\n bundlerConfig.external = [...existing, ...externalEntries];\n } else {\n bundlerConfig.external = [existing as string, ...externalEntries];\n }\n };\n}\n\nfunction appendNoExternals(\n noExternals: NitroConfig['noExternals'],\n ...entries: string[]\n): NitroConfig['noExternals'] {\n if (!noExternals) {\n return entries;\n }\n\n return Array.isArray(noExternals)\n ? [...noExternals, ...entries]\n : noExternals;\n}\n\n/**\n * Patches Nitro's internal Rollup/Rolldown bundler config to work around\n * incompatibilities in the Nitro v3 alpha series.\n *\n * Called from the `rollup:before` hook, this function runs against the *final*\n * bundler config that Nitro assembles for its server/prerender builds — it\n * does NOT touch the normal Vite client or SSR environment configs.\n *\n * Each workaround is narrowly scoped and safe to remove once the corresponding\n * upstream Nitro issue is resolved.\n */\nfunction sanitizeNitroBundlerConfig(\n _nitro: unknown,\n bundlerConfig: RollupConfig,\n) {\n const output = bundlerConfig['output'];\n if (!output || Array.isArray(output) || typeof output !== 'object') {\n return;\n }\n\n // ── 1. Remove invalid `output.codeSplitting` ────────────────────────\n //\n // Nitro 3.0.1-alpha.2 adds `output.codeSplitting` to its internal bundler\n // config, but Rolldown rejects it as an unknown key:\n //\n // Warning: Invalid output options (1 issue found)\n // - For the \"codeSplitting\". Invalid key: Expected never but received \"codeSplitting\".\n //\n // Analog never sets this option. Removing it restores default bundler\n // behavior without changing any Analog semantics.\n if ('codeSplitting' in output) {\n delete (output as Record<string, unknown>)['codeSplitting'];\n }\n\n // ── 2. Remove invalid `output.manualChunks` ─────────────────────────\n //\n // Nitro's default config enables manual chunking for node_modules. Under\n // Nitro v3 alpha + Rollup 4.59 this crashes during the prerender rebundle:\n //\n // Cannot read properties of undefined (reading 'included')\n //\n // A single server bundle is acceptable for Analog's use case, so we strip\n // `manualChunks` until the upstream bug is fixed.\n if ('manualChunks' in output) {\n delete (output as Record<string, unknown>)['manualChunks'];\n }\n\n // ── 3. Escape route params in `output.chunkFileNames` ───────────────\n //\n // Nitro's `getChunkName()` derives chunk filenames from route patterns,\n // using its internal `routeToFsPath()` helper to convert route params\n // (`:productId` → `[productId]`) and catch-alls (`**` → `[...]`).\n //\n // Rollup/Rolldown interprets *any* `[token]` in the string returned by a\n // `chunkFileNames` function as a placeholder. Only a handful are valid —\n // `[name]`, `[hash]`, `[format]`, `[ext]` — so route-derived tokens like\n // `[productId]` or `[...]` trigger a build error:\n //\n // \"[productId]\" is not a valid placeholder in the \"output.chunkFileNames\" pattern.\n //\n // We wrap the original function to replace non-standard `[token]` patterns\n // with `_token_`, preserving the intended filename while avoiding the\n // placeholder validation error.\n //\n // Example: `_routes/products/[productId].mjs` → `_routes/products/_productId_.mjs`\n const VALID_ROLLUP_PLACEHOLDER = /^\\[(?:name|hash|format|ext)\\]$/;\n const chunkFileNames = (output as Record<string, unknown>)['chunkFileNames'];\n if (typeof chunkFileNames === 'function') {\n const originalFn = chunkFileNames as (...args: unknown[]) => unknown;\n (output as Record<string, unknown>)['chunkFileNames'] = (\n ...args: unknown[]\n ) => {\n const result = originalFn(...args);\n if (typeof result !== 'string') return result;\n return result.replace(/\\[[^\\]]+\\]/g, (match: string) =>\n VALID_ROLLUP_PLACEHOLDER.test(match)\n ? match\n : `_${match.slice(1, -1)}_`,\n );\n };\n }\n}\n\nfunction resolveClientOutputPath(\n cachedPath: string,\n workspaceRoot: string,\n rootDir: string,\n configuredOutDir: string | undefined,\n) {\n if (cachedPath) {\n debugNitro('resolveClientOutputPath using cached path', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n });\n return cachedPath;\n }\n\n if (configuredOutDir) {\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, rootDir, configuredOutDir),\n );\n debugNitro('resolveClientOutputPath using configured build.outDir', {\n workspaceRoot,\n rootDir,\n configuredOutDir,\n resolvedPath,\n });\n return resolvedPath;\n }\n\n // When no explicit build.outDir is set, the environment build config defaults\n // to `<workspace>/dist/<root>/client` for the client build. The non-SSR\n // (client) and SSR paths must agree on this so that registerIndexHtmlVirtual()\n // and publicAssets read from the directory the client build actually wrote to.\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n );\n debugNitro('resolveClientOutputPath using default dist client path', {\n workspaceRoot,\n rootDir,\n configuredOutDir,\n resolvedPath,\n });\n return resolvedPath;\n}\n\nfunction getEnvironmentBuildOutDir(environment: unknown): string | undefined {\n if (!environment || typeof environment !== 'object') {\n return undefined;\n }\n\n const environmentConfig = environment as {\n config?: {\n build?: {\n outDir?: string;\n };\n };\n build?: {\n outDir?: string;\n };\n };\n\n return (\n environmentConfig.config?.build?.outDir ?? environmentConfig.build?.outDir\n );\n}\n\nfunction resolveBuiltClientOutputPath(\n cachedPath: string,\n workspaceRoot: string,\n rootDir: string,\n configuredOutDir: string | undefined,\n environment?: unknown,\n) {\n const environmentOutDir = getEnvironmentBuildOutDir(environment);\n if (environmentOutDir) {\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, rootDir, environmentOutDir),\n );\n debugNitro('resolveBuiltClientOutputPath using environment outDir', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n resolvedPath,\n });\n return resolvedPath;\n }\n\n debugNitro('resolveBuiltClientOutputPath falling back to shared resolver', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n });\n return resolveClientOutputPath(\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n );\n}\n\nfunction getNitroPublicOutputDir(nitroConfig: NitroConfig): string {\n const publicDir = nitroConfig.output?.publicDir;\n if (!publicDir) {\n throw new Error(\n 'Nitro public output directory is required to build the sitemap.',\n );\n }\n\n return publicDir;\n}\n\nfunction readDirectoryEntries(path: string): string[] {\n try {\n return readdirSync(path).sort();\n } catch (error) {\n return [\n `<<unable to read directory: ${error instanceof Error ? error.message : String(error)}>>`,\n ];\n }\n}\n\nfunction getPathDebugInfo(path: string) {\n return {\n rawPath: path,\n normalizedPath: normalizePath(path),\n exists: existsSync(path),\n entries: existsSync(path) ? readDirectoryEntries(path) : [],\n };\n}\n\nfunction assetSourceToString(source: string | Uint8Array) {\n return typeof source === 'string'\n ? source\n : Buffer.from(source).toString('utf8');\n}\n\nfunction captureClientIndexHtmlFromBundle(\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n hook: 'generateBundle' | 'writeBundle',\n) {\n const indexHtmlAsset = Object.values(bundle).find(\n (chunk) =>\n chunk.type === 'asset' &&\n chunk.fileName === 'index.html' &&\n typeof chunk.source !== 'undefined',\n );\n\n if (!indexHtmlAsset?.source) {\n debugNitro(`client bundle did not expose index.html during ${hook}`, {\n hook,\n bundleKeys: Object.keys(bundle).sort(),\n assetFileNames: Object.values(bundle)\n .filter((chunk) => chunk.type === 'asset')\n .map((chunk) => chunk.fileName)\n .filter(Boolean),\n });\n return undefined;\n }\n\n const indexHtml = assetSourceToString(indexHtmlAsset.source);\n debugNitro(`captured client bundle index.html asset during ${hook}`, {\n hook,\n fileName: indexHtmlAsset.fileName,\n htmlLength: indexHtml.length,\n });\n return indexHtml;\n}\n\n// Nitro only needs the HTML template string. Prefer the on-disk file when it\n// exists, but allow the captured client asset to cover build flows where the\n// client output directory disappears before Nitro assembles its virtual modules.\nfunction registerIndexHtmlVirtual(\n nitroConfig: NitroConfig,\n clientOutputPath: string,\n inlineIndexHtml?: string,\n) {\n const indexHtmlPath = resolve(clientOutputPath, 'index.html');\n debugNitro('registerIndexHtmlVirtual inspecting client output', {\n platform: process.platform,\n cwd: process.cwd(),\n clientOutputPath,\n clientOutputPathInfo: getPathDebugInfo(clientOutputPath),\n indexHtmlPath,\n indexHtmlExists: existsSync(indexHtmlPath),\n hasInlineIndexHtml: typeof inlineIndexHtml === 'string',\n });\n if (!existsSync(indexHtmlPath) && typeof inlineIndexHtml !== 'string') {\n debugNitro('registerIndexHtmlVirtual missing index.html', {\n platform: process.platform,\n cwd: process.cwd(),\n clientOutputPath,\n clientOutputPathInfo: getPathDebugInfo(clientOutputPath),\n indexHtmlPath,\n hasInlineIndexHtml: typeof inlineIndexHtml === 'string',\n nitroOutput: nitroConfig.output,\n nitroPublicAssets: nitroConfig.publicAssets,\n });\n throw new Error(\n `[analog] Client build output not found at ${indexHtmlPath}.\\n` +\n `Ensure the client environment build completed successfully before the server build.`,\n );\n }\n const indexHtml =\n typeof inlineIndexHtml === 'string'\n ? inlineIndexHtml\n : readFileSync(indexHtmlPath, 'utf8');\n debugNitro('registerIndexHtmlVirtual using HTML template source', {\n source:\n typeof inlineIndexHtml === 'string'\n ? 'captured client bundle asset'\n : 'client output index.html file',\n indexHtmlPath,\n });\n nitroConfig.virtual = {\n ...nitroConfig.virtual,\n '#analog/index': `export default ${JSON.stringify(indexHtml)};`,\n };\n}\n\n/**\n * Converts the built SSR entry path into a specifier that Nitro's bundler\n * can resolve, including all relative `./assets/*` chunk imports inside\n * the entry.\n *\n * The returned path **must** be an absolute filesystem path with forward\n * slashes (e.g. `D:/a/analog/dist/apps/blog-app/ssr/main.server.js`).\n * This lets Rollup/Rolldown determine the entry's directory and resolve\n * sibling chunk imports like `./assets/core-DTazUigR.js` correctly.\n *\n * ## Why not pathToFileURL() on Windows?\n *\n * Earlier versions converted the path to a `file:///D:/a/...` URL on\n * Windows, which worked with Nitro v2 + Rollup. Nitro v3 switched its\n * default bundler to Rolldown, and Rolldown does **not** extract the\n * importer directory from `file://` URLs. This caused every relative\n * import inside the SSR entry to fail during the prerender build:\n *\n * [RESOLVE_ERROR] Could not resolve './assets/core-DTazUigR.js'\n * in ../../dist/apps/blog-app/ssr/main.server.js\n *\n * `normalizePath()` (from Vite) simply converts backslashes to forward\n * slashes, which both Rollup and Rolldown handle correctly on all\n * platforms.\n */\nfunction toNitroSsrEntrypointSpecifier(ssrEntryPath: string) {\n return normalizePath(ssrEntryPath);\n}\n\nfunction applySsrEntryAlias(\n nitroConfig: NitroConfig,\n options: Options | undefined,\n workspaceRoot: string,\n rootDir: string,\n): void {\n const ssrOutDir =\n options?.ssrBuildDir || resolve(workspaceRoot, 'dist', rootDir, 'ssr');\n if (options?.ssr || nitroConfig.prerender?.routes?.length) {\n const ssrEntryPath = resolveBuiltSsrEntryPath(ssrOutDir);\n const ssrEntry = toNitroSsrEntrypointSpecifier(ssrEntryPath);\n nitroConfig.alias = {\n ...nitroConfig.alias,\n '#analog/ssr': ssrEntry,\n };\n }\n}\n\nfunction resolveBuiltSsrEntryPath(ssrOutDir: string) {\n const candidatePaths = [\n resolve(ssrOutDir, 'main.server.mjs'),\n resolve(ssrOutDir, 'main.server.js'),\n resolve(ssrOutDir, 'main.server'),\n ];\n\n const ssrEntryPath = candidatePaths.find((candidatePath) =>\n existsSync(candidatePath),\n );\n\n if (!ssrEntryPath) {\n throw new Error(\n `Unable to locate the built SSR entry in \"${ssrOutDir}\". Expected one of: ${candidatePaths.join(\n ', ',\n )}`,\n );\n }\n\n return ssrEntryPath;\n}\n\nexport function nitro(options?: Options, nitroOptions?: NitroConfig): Plugin[] {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n const sourceRoot = options?.sourceRoot ?? 'src';\n let isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const baseURL = process.env['NITRO_APP_BASE_URL'] || '';\n const prefix = baseURL ? baseURL.substring(0, baseURL.length - 1) : '';\n const apiPrefix = `/${options?.apiPrefix || 'api'}`;\n const useAPIMiddleware =\n typeof options?.useAPIMiddleware !== 'undefined'\n ? options?.useAPIMiddleware\n : true;\n const viteRolldownOutput = options?.vite?.build?.rolldownOptions?.output;\n // Vite's native build typing allows `output` to be either a single object or\n // an array. Analog only forwards `codeSplitting` into the client environment\n // when there is a single output object to merge into.\n const viteRolldownOutputConfig =\n viteRolldownOutput && !Array.isArray(viteRolldownOutput)\n ? viteRolldownOutput\n : undefined;\n const codeSplitting = viteRolldownOutputConfig?.codeSplitting;\n\n let isBuild = false;\n let isServe = false;\n let ssrBuild = false;\n let config: UserConfig;\n let nitroConfig: NitroConfig;\n let environmentBuild = false;\n let hasAPIDir = false;\n let clientOutputPath = '';\n let clientIndexHtml: string | undefined;\n let legacyClientSubBuild = false;\n const rollupExternalEntries: string[] = [];\n const sitemapRoutes: string[] = [];\n const routeSitemaps: Record<\n string,\n PrerenderSitemapConfig | (() => PrerenderSitemapConfig)\n > = {};\n const routeSourceFiles: Record<string, string> = {};\n let rootDir = workspaceRoot;\n\n return [\n (options?.ssr\n ? devServerPlugin({\n entryServer: options?.entryServer,\n index: options?.index,\n routeRules: nitroOptions?.routeRules,\n i18n: options?.i18n,\n })\n : false) as Plugin,\n {\n name: '@analogjs/vite-plugin-nitro',\n async config(userConfig, { mode, command }) {\n isServe = command === 'serve';\n isBuild = command === 'build';\n ssrBuild = userConfig.build?.ssr === true;\n config = userConfig;\n isTest = isTest ? isTest : mode === 'test';\n rollupExternalEntries.length = 0;\n clientIndexHtml = undefined;\n sitemapRoutes.length = 0;\n for (const key of Object.keys(routeSitemaps)) {\n delete routeSitemaps[key];\n }\n for (const key of Object.keys(routeSourceFiles)) {\n delete routeSourceFiles[key];\n }\n\n const resolvedConfigRoot = config.root\n ? resolve(workspaceRoot, config.root)\n : workspaceRoot;\n rootDir = relative(workspaceRoot, resolvedConfigRoot) || '.';\n hasAPIDir = existsSync(\n resolve(\n workspaceRoot,\n rootDir,\n `${sourceRoot}/server/routes/${options?.apiPrefix || 'api'}`,\n ),\n );\n const buildPreset =\n process.env['BUILD_PRESET'] ??\n (nitroOptions?.preset as string | undefined) ??\n (process.env['VERCEL'] ? 'vercel' : undefined);\n\n const pageHandlers = getPageHandlers({\n workspaceRoot,\n sourceRoot,\n rootDir,\n additionalPagesDirs: options?.additionalPagesDirs,\n hasAPIDir,\n });\n const resolvedClientOutputPath = resolveClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n );\n debugNitro('nitro config resolved client output path', {\n platform: process.platform,\n workspaceRoot,\n configRoot: config.root,\n resolvedConfigRoot,\n rootDir,\n buildOutDir: config.build?.outDir,\n clientOutputPath,\n resolvedClientOutputPath,\n hasEnvironmentConfig: !!config.environments,\n clientEnvironmentOutDir:\n config.environments?.['client'] &&\n typeof config.environments['client'] === 'object' &&\n 'build' in config.environments['client']\n ? (\n config.environments['client'] as {\n build?: { outDir?: string };\n }\n ).build?.outDir\n : undefined,\n });\n\n nitroConfig = {\n rootDir: normalizePath(rootDir),\n preset: buildPreset,\n compatibilityDate: '2025-11-19',\n logLevel: nitroOptions?.logLevel || 0,\n serverDir: normalizePath(`${sourceRoot}/server`),\n scanDirs: [\n normalizePath(`${rootDir}/${sourceRoot}/server`),\n ...(options?.additionalAPIDirs || []).map((dir) =>\n normalizePath(`${workspaceRoot}${dir}`),\n ),\n ],\n output: {\n dir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'analog'),\n ),\n publicDir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'analog/public'),\n ),\n },\n buildDir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, '.nitro'),\n ),\n typescript: {\n generateTsConfig: false,\n },\n runtimeConfig: {\n apiPrefix: apiPrefix.substring(1),\n prefix,\n },\n // Analog provides its own renderer handler; prevent Nitro v3 from\n // auto-detecting index.html in rootDir and adding a conflicting one.\n renderer: false,\n imports: {\n autoImport: false,\n },\n hooks: {\n 'rollup:before': createRollupBeforeHook(rollupExternalEntries),\n },\n rollupConfig: {\n onwarn(warning) {\n if (\n warning.message.includes('empty chunk') &&\n warning.message.endsWith('.server')\n ) {\n return;\n }\n },\n plugins: [pageEndpointsPlugin()],\n },\n handlers: [\n ...(hasAPIDir\n ? []\n : useAPIMiddleware\n ? [createNitroMiddlewareHandler('#ANALOG_API_MIDDLEWARE')]\n : []),\n ...pageHandlers,\n ],\n routeRules: hasAPIDir\n ? undefined\n : useAPIMiddleware\n ? undefined\n : {\n [`${prefix}${apiPrefix}/**`]: {\n proxy: { to: '/**' },\n },\n },\n virtual: {\n '#ANALOG_SSR_RENDERER': ssrRenderer(),\n '#ANALOG_CLIENT_RENDERER': clientRenderer(),\n ...(hasAPIDir ? {} : { '#ANALOG_API_MIDDLEWARE': apiMiddleware }),\n },\n };\n\n if (isVercelPreset(buildPreset)) {\n nitroConfig = withVercelOutputAPI(nitroConfig, workspaceRoot);\n }\n\n if (isCloudflarePreset(buildPreset)) {\n nitroConfig = withCloudflareOutput(nitroConfig);\n }\n\n if (\n isNetlifyPreset(buildPreset) &&\n rootDir === '.' &&\n !existsSync(resolve(workspaceRoot, 'netlify.toml'))\n ) {\n nitroConfig = withNetlifyOutputAPI(nitroConfig, workspaceRoot);\n }\n\n if (isFirebaseAppHosting()) {\n nitroConfig = withAppHostingOutput(nitroConfig);\n }\n\n if (!ssrBuild && !isTest) {\n // store the client output path for the SSR build config\n clientOutputPath = resolvedClientOutputPath;\n debugNitro(\n 'nitro config cached client output path for later SSR/Nitro build',\n {\n ssrBuild,\n isTest,\n clientOutputPath,\n },\n );\n }\n\n // Start with a clean alias map. #analog/index is registered as a Nitro\n // virtual module after the client build, inlining the HTML template so\n // the server bundle imports it instead of using readFileSync with an\n // absolute path.\n nitroConfig.alias = {};\n\n if (isBuild) {\n nitroConfig.publicAssets = [\n { dir: normalizePath(resolvedClientOutputPath), maxAge: 0 },\n ];\n\n // In Nitro v3, renderer.entry is resolved via resolveModulePath()\n // during options normalization, which requires a real filesystem path.\n // Virtual modules (prefixed with #) can't survive this resolution.\n // Instead, we add the renderer as a catch-all handler directly —\n // this is functionally equivalent to what Nitro does internally\n // (it converts renderer.entry into a { route: '/**', lazy: true }\n // handler), but avoids the filesystem resolution step.\n const rendererHandler = options?.ssr\n ? '#ANALOG_SSR_RENDERER'\n : '#ANALOG_CLIENT_RENDERER';\n nitroConfig.handlers = [\n ...(nitroConfig.handlers || []),\n {\n handler: rendererHandler,\n route: '/**',\n lazy: true,\n },\n ];\n\n if (isEmptyPrerenderRoutes(options)) {\n nitroConfig.prerender = {};\n nitroConfig.prerender.routes = ['/'];\n }\n\n if (options?.prerender) {\n nitroConfig.prerender = nitroConfig.prerender ?? {};\n nitroConfig.prerender.crawlLinks = options?.prerender?.discover;\n\n let routes: (\n | string\n | PrerenderContentDir\n | PrerenderRouteConfig\n | undefined\n )[] = [];\n\n const prerenderRoutes = options?.prerender?.routes;\n const hasExplicitPrerenderRoutes =\n typeof prerenderRoutes === 'function' ||\n Array.isArray(prerenderRoutes);\n if (\n isArrayWithElements<string | PrerenderContentDir>(prerenderRoutes)\n ) {\n routes = prerenderRoutes;\n } else if (typeof prerenderRoutes === 'function') {\n routes = await prerenderRoutes();\n }\n\n const resolvedPrerenderRoutes = routes.reduce<string[]>(\n (prev, current) => {\n if (!current) {\n return prev;\n }\n if (typeof current === 'string') {\n prev.push(current);\n sitemapRoutes.push(current);\n return prev;\n }\n\n if ('route' in current) {\n if (current.sitemap) {\n routeSitemaps[current.route] = current.sitemap;\n }\n\n if (current.outputSourceFile) {\n const sourcePath = resolve(\n workspaceRoot,\n rootDir,\n current.outputSourceFile,\n );\n routeSourceFiles[current.route] = readFileSync(\n sourcePath,\n 'utf8',\n );\n }\n\n prev.push(current.route);\n sitemapRoutes.push(current.route);\n\n // Add the server-side data fetching endpoint URL\n if ('staticData' in current) {\n prev.push(`${apiPrefix}/_analog/pages/${current.route}`);\n }\n\n return prev;\n }\n\n const affectedFiles: PrerenderContentFile[] =\n getMatchingContentFilesWithFrontMatter(\n workspaceRoot,\n rootDir,\n current.contentDir,\n );\n\n affectedFiles.forEach((f) => {\n const result = current.transform(f);\n\n if (result) {\n if (current.sitemap) {\n routeSitemaps[result] =\n current.sitemap && typeof current.sitemap === 'function'\n ? current.sitemap?.(f)\n : current.sitemap;\n }\n\n if (current.outputSourceFile) {\n const sourceContent = current.outputSourceFile(f);\n if (sourceContent) {\n routeSourceFiles[result] = sourceContent;\n }\n }\n\n prev.push(result);\n sitemapRoutes.push(result);\n\n // Add the server-side data fetching endpoint URL\n if ('staticData' in current) {\n prev.push(`${apiPrefix}/_analog/pages/${result}`);\n }\n }\n });\n\n return prev;\n },\n [],\n );\n\n nitroConfig.prerender.routes =\n hasExplicitPrerenderRoutes || resolvedPrerenderRoutes.length\n ? resolvedPrerenderRoutes\n : (nitroConfig.prerender.routes ?? []);\n }\n\n // ── SSR / prerender Nitro config ─────────────────────────────\n //\n // This block configures Nitro for builds that rebundle the SSR\n // entry (main.server.{js,mjs}). That happens in two cases:\n //\n // 1. Full SSR apps — `options.ssr === true`\n // 2. Prerender-only — no runtime SSR, but the prerender build\n // still imports the SSR entry to render static pages.\n //\n // The original gate was `if (ssrBuild)`, which checks the Vite\n // top-level `build.ssr` flag. That works for SSR-only builds but\n // misses two Vite 6+ paths:\n //\n // a. **Vite Environment API (Vite 6+)** — SSR config lives in\n // `environments.ssr.build.ssr`, not `build.ssr`, so\n // `ssrBuild` is always `false`.\n // b. **Prerender-only apps** (e.g. blog-app) — `options.ssr`\n // is `false`, but prerender routes exist and the prerender\n // build still processes the SSR entry.\n //\n // Without this block:\n // - `rxjs` is never externalised → RESOLVE_ERROR in the\n // Nitro prerender build (especially on Windows CI).\n // - `moduleSideEffects` for zone.js is never set → zone.js\n // side-effects may be tree-shaken.\n // - The handlers list is not reassembled with page endpoints\n // + the renderer catch-all.\n //\n // The widened condition covers all supported build paths:\n // - `ssrBuild` → SSR-only build\n // - `options?.ssr` → Environment API SSR\n // - `nitroConfig.prerender?.routes?.length` → prerender-only\n if (\n ssrBuild ||\n options?.ssr ||\n nitroConfig.prerender?.routes?.length\n ) {\n nitroConfig.noExternals = appendNoExternals(\n nitroConfig.noExternals,\n 'es-toolkit',\n );\n\n if (process.platform === 'win32') {\n nitroConfig.noExternals = appendNoExternals(\n nitroConfig.noExternals,\n 'std-env',\n );\n }\n\n rollupExternalEntries.push(\n 'rxjs',\n 'node-fetch-native/dist/polyfill',\n // sharp is a native module with platform-specific binaries\n // (e.g. @img/sharp-darwin-arm64). pnpm creates symlinks for\n // ALL optional platform deps but only installs the matching\n // one — leaving broken symlinks that crash Nitro's bundler\n // with ENOENT during realpath(). Externalizing sharp avoids\n // bundling it entirely; it resolves from node_modules at\n // runtime instead.\n 'sharp',\n );\n\n nitroConfig = {\n ...nitroConfig,\n moduleSideEffects: ['zone.js/node', 'zone.js/fesm2015/zone-node'],\n handlers: [\n ...(hasAPIDir\n ? []\n : useAPIMiddleware\n ? [createNitroMiddlewareHandler('#ANALOG_API_MIDDLEWARE')]\n : []),\n ...pageHandlers,\n // Preserve the renderer catch-all handler added above\n {\n handler: rendererHandler,\n route: '/**',\n lazy: true,\n },\n ],\n };\n }\n }\n\n nitroConfig = mergeConfig(\n nitroConfig,\n nitroOptions as Record<string, any>,\n );\n\n // Only configure Vite 8 environments + builder on the top-level\n // build invocation. When buildApp's builder.build() calls re-enter\n // the config hook, returning environments/builder again would create\n // recursive buildApp invocations — each nesting another client build\n // that re-triggers config, producing an infinite loop of\n // \"building client environment... ✓ 1 modules transformed\".\n //\n // environmentBuild — already inside a buildApp call (recursion guard)\n // ssrBuild — legacy SSR-only sub-build\n // isServe — dev server / Vitest test runner (command: 'serve')\n if (environmentBuild || ssrBuild || isServe) {\n return {};\n }\n\n return {\n environments: {\n client: {\n build: {\n outDir:\n config?.build?.outDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n emptyOutDir: true,\n // Forward code-splitting config to Rolldown when running\n // under Vite 8+. `false` disables splitting (inlines all\n // dynamic imports); an object configures chunk groups.\n // The `!== undefined` check ensures `codeSplitting: false`\n // is forwarded correctly (a truthy check would swallow it).\n ...(isRolldown() && codeSplitting !== undefined\n ? {\n rolldownOptions: {\n output: {\n // Preserve any sibling Rolldown output options while\n // overriding just `codeSplitting` for the client build.\n ...viteRolldownOutputConfig,\n codeSplitting,\n },\n },\n }\n : {}),\n },\n },\n ssr: {\n build: {\n ssr: true,\n [getBundleOptionsKey()]: {\n input:\n options?.entryServer ||\n resolve(\n workspaceRoot,\n rootDir,\n `${sourceRoot}/main.server.ts`,\n ),\n },\n outDir:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n // Preserve the client build output. The client environment is\n // built first and Nitro reads its index.html after SSR finishes.\n emptyOutDir: false,\n },\n },\n },\n builder: {\n sharedPlugins: true,\n buildApp: async (builder) => {\n environmentBuild = true;\n debugNitro('builder.buildApp starting', {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n clientEnvironmentOutDir: getEnvironmentBuildOutDir(\n builder.environments['client'],\n ),\n ssrEnvironmentOutDir: getEnvironmentBuildOutDir(\n builder.environments['ssr'],\n ),\n });\n\n // Client must complete before SSR — the server build reads the\n // client's index.html via registerIndexHtmlVirtual(). Running\n // them in parallel caused a race on Windows where emptyOutDir\n // could delete client output before the server read it.\n await builder.build(builder.environments['client']);\n const postClientBuildOutputPath = resolveBuiltClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n builder.environments['client'],\n );\n // Capture the client template before any SSR/prerender work runs.\n // On Windows, later phases can leave the client output directory\n // unavailable even though the client build itself succeeded.\n registerIndexHtmlVirtual(\n nitroConfig,\n postClientBuildOutputPath,\n clientIndexHtml,\n );\n debugNitro('builder.buildApp completed client build', {\n postClientBuildOutputPath,\n postClientBuildOutputInfo: getPathDebugInfo(\n postClientBuildOutputPath,\n ),\n postClientBuildIndexHtmlPath: resolve(\n postClientBuildOutputPath,\n 'index.html',\n ),\n postClientBuildIndexHtmlExists: existsSync(\n resolve(postClientBuildOutputPath, 'index.html'),\n ),\n });\n\n if (options?.ssr || nitroConfig.prerender?.routes?.length) {\n debugSsr('builder.buildApp starting SSR build', {\n ssrEnabled: options?.ssr,\n prerenderRoutes: nitroConfig.prerender?.routes,\n });\n await builder.build(builder.environments['ssr']);\n debugSsr('builder.buildApp completed SSR build', {\n ssrOutputPath:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n });\n }\n\n applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);\n\n const resolvedClientOutputPath = resolveBuiltClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n builder.environments['client'],\n );\n\n nitroConfig.publicAssets = [\n { dir: normalizePath(resolvedClientOutputPath), maxAge: 0 },\n ];\n debugNitro(\n 'builder.buildApp resolved final client output path before Nitro build',\n {\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n nitroPublicAssets: nitroConfig.publicAssets,\n },\n );\n\n await buildServer(options, nitroConfig, routeSourceFiles);\n\n if (\n nitroConfig.prerender?.routes?.length &&\n options?.prerender?.sitemap\n ) {\n console.log('Building Sitemap...');\n // sitemap needs to be built after all directories are built\n await buildSitemap(\n config,\n options.prerender.sitemap,\n sitemapRoutes.length\n ? sitemapRoutes\n : nitroConfig.prerender.routes,\n getNitroPublicOutputDir(nitroConfig),\n routeSitemaps,\n { apiPrefix: options?.apiPrefix || 'api' },\n );\n }\n\n console.log(\n `\\n\\nThe '@analogjs/platform' server has been successfully built.`,\n );\n },\n },\n };\n },\n generateBundle(\n _options,\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n ) {\n if (!isBuild || ssrBuild) {\n return;\n }\n\n clientIndexHtml =\n captureClientIndexHtmlFromBundle(bundle, 'generateBundle') ??\n clientIndexHtml;\n },\n writeBundle(\n _options,\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n ) {\n if (!isBuild || ssrBuild) {\n return;\n }\n\n clientIndexHtml =\n captureClientIndexHtmlFromBundle(bundle, 'writeBundle') ??\n clientIndexHtml;\n },\n async configureServer(viteServer: ViteDevServer) {\n if (isServe && !isTest) {\n const nitro = await createNitro({\n dev: true,\n // Nitro's Vite builder now rejects `build()` in dev mode, but Analog's\n // dev integration still relies on the builder-driven reload hooks.\n // Force the server worker onto Rollup for this dev-only path.\n builder: 'rollup',\n ...nitroConfig,\n });\n const server = createDevServer(nitro);\n await build(nitro);\n const nitroSourceRoots = [\n normalizePath(\n resolve(workspaceRoot, rootDir, `${sourceRoot}/server`),\n ),\n ...(options?.additionalAPIDirs || []).map((dir) =>\n normalizePath(`${workspaceRoot}${dir}`),\n ),\n ];\n const isNitroSourceFile = (path: string) => {\n const normalizedPath = normalizePath(path);\n return nitroSourceRoots.some(\n (root) =>\n normalizedPath === root ||\n normalizedPath.startsWith(`${root}/`),\n );\n };\n let nitroRebuildPromise: Promise<void> | undefined;\n let nitroRebuildPending = false;\n const rebuildNitroServer = () => {\n if (nitroRebuildPromise) {\n // Coalesce rapid file events so a save that touches multiple server\n // route files results in one follow-up rebuild instead of many.\n nitroRebuildPending = true;\n return nitroRebuildPromise;\n }\n\n nitroRebuildPromise = (async () => {\n do {\n nitroRebuildPending = false;\n // Nitro API routes are not part of Vite's normal client HMR graph,\n // so rebuild the Nitro dev server to pick up handler edits.\n await build(nitro);\n } while (nitroRebuildPending);\n\n // Reload the page after the server rebuild completes so the next\n // request observes the updated API route implementation.\n viteServer.ws.send('analog:debug-full-reload', {\n plugin: 'vite-plugin-nitro',\n reason: 'nitro-server-rebuilt',\n });\n viteServer.ws.send({ type: 'full-reload' });\n })()\n .catch((error: unknown) => {\n viteServer.config.logger.error(\n `[analog] Failed to rebuild Nitro dev server.\\n${error instanceof Error ? error.stack || error.message : String(error)}`,\n );\n })\n .finally(() => {\n nitroRebuildPromise = undefined;\n });\n\n return nitroRebuildPromise;\n };\n const onNitroSourceChange = (path: string) => {\n if (!isNitroSourceFile(path)) {\n return;\n }\n\n void rebuildNitroServer();\n };\n\n // Watch the full Nitro source roots instead of only the API route\n // directory. API handlers often read helper modules, shared data, or\n // middleware from elsewhere under `src/server`, and those edits should\n // still rebuild the Nitro dev server and refresh connected browsers.\n viteServer.watcher.on('add', onNitroSourceChange);\n viteServer.watcher.on('change', onNitroSourceChange);\n viteServer.watcher.on('unlink', onNitroSourceChange);\n\n const apiHandler = async (\n req: IncomingMessage,\n res: ServerResponse,\n ) => {\n // Nitro v3's dev server is fetch-first, so adapt Vite's Node\n // request once and let Nitro respond with a standard Web Response.\n const response = await server.fetch(toWebRequest(req));\n await writeWebResponseToNode(res, response);\n };\n\n if (hasAPIDir) {\n viteServer.middlewares.use(\n (\n req: IncomingMessage,\n res: ServerResponse,\n next: (error?: unknown) => void,\n ) => {\n if (req.url?.startsWith(`${prefix}${apiPrefix}`)) {\n void apiHandler(req, res).catch((error) => next(error));\n return;\n }\n\n next();\n },\n );\n } else {\n viteServer.middlewares.use(\n apiPrefix,\n (\n req: IncomingMessage,\n res: ServerResponse,\n next: (error?: unknown) => void,\n ) => {\n void apiHandler(req, res).catch((error) => next(error));\n },\n );\n }\n\n viteServer.httpServer?.once('listening', () => {\n process.env['ANALOG_HOST'] = !viteServer.config.server.host\n ? 'localhost'\n : (viteServer.config.server.host as string);\n process.env['ANALOG_PORT'] = `${viteServer.config.server.port}`;\n });\n\n // handle upgrades if websockets are enabled\n if (nitroOptions?.experimental?.websocket) {\n debugNitro('experimental websocket upgrade handler enabled');\n viteServer.httpServer?.on('upgrade', server.upgrade);\n }\n\n console.log(\n `\\n\\nThe server endpoints are accessible under the \"${prefix}${apiPrefix}\" path.`,\n );\n }\n },\n\n async closeBundle() {\n if (legacyClientSubBuild) {\n return;\n }\n\n // When builder.buildApp ran, it already handled the full\n // client → SSR → Nitro pipeline. Skip to avoid double work.\n if (environmentBuild) {\n return;\n }\n\n // SSR sub-build — Vite re-enters the plugin with build.ssr;\n // Nitro server assembly happens only after the client pass.\n if (ssrBuild) {\n return;\n }\n\n // Nx executors (and any caller that runs `vite build` without\n // the Environment API) never trigger builder.buildApp, so\n // closeBundle is the only place to drive the SSR + Nitro build.\n if (isBuild) {\n const resolvedClientOutputPath = resolveClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n );\n debugNitro(\n 'closeBundle resolved client output path before legacy SSR build',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n },\n );\n const indexHtmlPath = resolve(resolvedClientOutputPath, 'index.html');\n if (\n !existsSync(indexHtmlPath) &&\n typeof clientIndexHtml !== 'string'\n ) {\n debugNitro(\n 'closeBundle rebuilding missing client output before SSR/Nitro',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n indexHtmlPath,\n },\n );\n legacyClientSubBuild = true;\n try {\n await buildClientApp(config, options);\n } finally {\n legacyClientSubBuild = false;\n }\n }\n // Capture the client HTML before kicking off the standalone SSR build.\n // This mirrors the successful sequencing from before the closeBundle\n // refactor and avoids depending on the client directory surviving the\n // nested SSR build on Windows.\n registerIndexHtmlVirtual(\n nitroConfig,\n resolvedClientOutputPath,\n clientIndexHtml,\n );\n\n if (options?.ssr) {\n console.log('Building SSR application...');\n await buildSSRApp(config, options);\n debugSsr('closeBundle completed standalone SSR build', {\n ssrBuildDir:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n clientOutputPathInfo: clientOutputPath\n ? getPathDebugInfo(clientOutputPath)\n : null,\n });\n }\n\n applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);\n debugNitro(\n 'closeBundle resolved client output path before Nitro build',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n },\n );\n registerIndexHtmlVirtual(\n nitroConfig,\n resolvedClientOutputPath,\n clientIndexHtml,\n );\n\n await buildServer(options, nitroConfig, routeSourceFiles);\n\n if (\n nitroConfig.prerender?.routes?.length &&\n options?.prerender?.sitemap\n ) {\n console.log('Building Sitemap...');\n await buildSitemap(\n config,\n options.prerender.sitemap,\n sitemapRoutes.length\n ? sitemapRoutes\n : nitroConfig.prerender.routes,\n getNitroPublicOutputDir(nitroConfig),\n routeSitemaps,\n { apiPrefix: options?.apiPrefix || 'api' },\n );\n }\n\n console.log(\n `\\n\\nThe '@analogjs/platform' server has been successfully built.`,\n );\n }\n },\n },\n {\n name: '@analogjs/vite-plugin-nitro-api-prefix',\n config() {\n return {\n define: {\n ANALOG_API_PREFIX: `\"${baseURL.substring(1)}${apiPrefix.substring(1)}\"`,\n ...(options?.i18n\n ? {\n ANALOG_I18N_DEFAULT_LOCALE: JSON.stringify(\n options.i18n.defaultLocale,\n ),\n ANALOG_I18N_LOCALES: JSON.stringify(options.i18n.locales),\n }\n : {}),\n },\n };\n },\n },\n ];\n}\n\nfunction isEmptyPrerenderRoutes(options?: Options): boolean {\n if (!options || isArrayWithElements(options?.prerender?.routes)) {\n return false;\n }\n return !options.prerender?.routes;\n}\n\nfunction isArrayWithElements<T>(arr: unknown): arr is [T, ...T[]] {\n return !!(Array.isArray(arr) && arr.length);\n}\n\nconst VERCEL_PRESET = 'vercel';\n// Nitro v3 consolidates the old `vercel-edge` preset into `vercel` with\n// fluid compute enabled by default, so a single preset covers both\n// serverless and edge deployments.\nconst withVercelOutputAPI = (\n nitroConfig: NitroConfig | undefined,\n workspaceRoot: string,\n) => ({\n ...nitroConfig,\n preset: nitroConfig?.preset ?? 'vercel',\n vercel: {\n ...nitroConfig?.vercel,\n entryFormat: nitroConfig?.vercel?.entryFormat ?? 'node',\n functions: {\n runtime: nitroConfig?.vercel?.functions?.runtime ?? 'nodejs24.x',\n ...nitroConfig?.vercel?.functions,\n },\n },\n output: {\n ...nitroConfig?.output,\n dir: normalizePath(resolve(workspaceRoot, '.vercel', 'output')),\n publicDir: normalizePath(\n resolve(workspaceRoot, '.vercel', 'output/static'),\n ),\n },\n});\n\n// Nitro v3 uses underscore-separated preset names (e.g. `cloudflare_pages`),\n// but we accept both hyphen and underscore forms for backwards compatibility.\nconst isCloudflarePreset = (buildPreset: string | undefined) =>\n process.env['CF_PAGES'] ||\n (buildPreset &&\n (buildPreset.toLowerCase().includes('cloudflare-pages') ||\n buildPreset.toLowerCase().includes('cloudflare_pages')));\n\nconst withCloudflareOutput = (nitroConfig: NitroConfig | undefined) => ({\n ...nitroConfig,\n output: {\n ...nitroConfig?.output,\n serverDir: '{{ output.publicDir }}/_worker.js',\n },\n});\n\nconst isFirebaseAppHosting = () => !!process.env['NG_BUILD_LOGS_JSON'];\nconst withAppHostingOutput = (nitroConfig: NitroConfig) => {\n let hasOutput = false;\n\n return <NitroConfig>{\n ...nitroConfig,\n serveStatic: true,\n rollupConfig: {\n ...nitroConfig.rollupConfig,\n output: {\n ...nitroConfig.rollupConfig?.output,\n entryFileNames: 'server.mjs',\n },\n },\n hooks: {\n ...nitroConfig.hooks,\n compiled: () => {\n if (!hasOutput) {\n const buildOutput = {\n errors: [],\n warnings: [],\n outputPaths: {\n root: pathToFileURL(`${nitroConfig.output?.dir}`),\n browser: pathToFileURL(`${nitroConfig.output?.publicDir}`),\n server: pathToFileURL(`${nitroConfig.output?.dir}/server`),\n },\n };\n\n // Log the build output for Firebase App Hosting to pick up\n console.log(JSON.stringify(buildOutput, null, 2));\n hasOutput = true;\n }\n },\n },\n };\n};\n\nconst isNetlifyPreset = (buildPreset: string | undefined) =>\n process.env['NETLIFY'] ||\n (buildPreset && buildPreset.toLowerCase().includes('netlify'));\n\nconst withNetlifyOutputAPI = (\n nitroConfig: NitroConfig | undefined,\n workspaceRoot: string,\n) => ({\n ...nitroConfig,\n output: {\n ...nitroConfig?.output,\n dir: normalizePath(resolve(workspaceRoot, 'netlify/functions')),\n },\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"vite-plugin-nitro.js","names":[],"sources":["../../../src/lib/vite-plugin-nitro.ts"],"sourcesContent":["import type { NitroConfig, NitroEventHandler, RollupConfig } from 'nitro/types';\nimport { build, createDevServer, createNitro } from 'nitro/builder';\nimport * as vite from 'vite';\nimport type { Plugin, UserConfig, ViteDevServer } from 'vite';\nimport { mergeConfig, normalizePath } from 'vite';\nimport { relative, resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { existsSync, readFileSync, readdirSync } from 'node:fs';\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\nimport { buildServer, isVercelPreset } from './build-server.js';\nimport { buildClientApp, buildSSRApp } from './build-ssr.js';\nimport {\n Options,\n PrerenderContentDir,\n PrerenderContentFile,\n PrerenderRouteConfig,\n PrerenderSitemapConfig,\n} from './options.js';\nimport { pageEndpointsPlugin } from './plugins/page-endpoints.js';\nimport { getPageHandlers } from './utils/get-page-handlers.js';\nimport { buildSitemap } from './build-sitemap.js';\nimport { devServerPlugin } from './plugins/dev-server-plugin.js';\nimport {\n toWebRequest,\n writeWebResponseToNode,\n} from './utils/node-web-bridge.js';\nimport { getMatchingContentFilesWithFrontMatter } from './utils/get-content-files.js';\nimport {\n ssrRenderer,\n clientRenderer,\n apiMiddleware,\n} from './utils/renderers.js';\nimport { getBundleOptionsKey, isRolldown } from './utils/rolldown.js';\nimport { debugNitro, debugSsr } from './utils/debug.js';\n\n// Snapshot the caller-owned Vite config once so the client build, SSR handoff,\n// and closeBundle all read the same view of the app.\n//\n// Guards against:\n// - `build.outDir` can change after capture, sending the client sub-build to a\n// different directory than the one Nitro later probes for `index.html`.\n// - a plugin can replace `{ handler, order }` with a new wrapper object, which\n// changes hook ordering for Nitro even though Nitro already \"captured\" config.\n// - `resolve.alias` can be rewritten between the client and SSR passes, causing\n// the two environments to build against different module graphs.\ntype ObjectHook<T> = { handler: T; [key: string]: unknown };\n\nfunction isObjectHook(value: unknown): value is ObjectHook<unknown> {\n return !!value && typeof value === 'object' && 'handler' in value;\n}\n\n// Freeze hook-wrapper metadata without changing the executable handler.\n// Value: Nitro keeps the same hook ordering and flags it captured at config()\n// time, while still invoking the original plugin behavior.\n//\n// Guards against: a caller swapping `{ handler, order: 'pre' }` for a fresh\n// `{ handler, order: 'post' }` object after Nitro's `config()` hook ran. Nitro\n// should keep the captured ordering metadata instead of silently retargeting\n// when the outer wrapper object changes.\nfunction cloneObjectHook<T>(hook: T): T {\n if (!isObjectHook(hook)) {\n return hook;\n }\n\n return {\n ...hook,\n handler: hook.handler,\n } as T;\n}\n\nfunction cloneUserPlugin<T>(plugin: T): T {\n if (!plugin || typeof plugin !== 'object') return plugin;\n const pluginRecord = plugin as Record<string, unknown>;\n // Preserve the original prototype because some plugins hang metadata or\n // behavior off the instance instead of plain object fields.\n const clone = Object.assign(\n Object.create(Object.getPrototypeOf(plugin)),\n pluginRecord,\n ) as Record<string, unknown>;\n\n for (const key of Object.keys(pluginRecord)) {\n clone[key] = cloneObjectHook(pluginRecord[key]);\n }\n\n return clone as T;\n}\n\nfunction cloneEnvironmentEntries(\n environments: UserConfig['environments'],\n): UserConfig['environments'] {\n if (!environments || typeof environments !== 'object') {\n return environments;\n }\n\n // Snapshot the per-environment overrides Nitro reads later.\n // Value: environment-specific output paths and diagnostics stay aligned with\n // the build Nitro already started coordinating.\n //\n // Guards against: a late write like\n // `environments.client.build.outDir = ...` does not redirect follow-up\n // diagnostics or asset lookups away from the client build Nitro already\n // started coordinating.\n return Object.fromEntries(\n Object.entries(environments).map(([name, environment]) => {\n if (!environment || typeof environment !== 'object') {\n return [name, environment];\n }\n\n const environmentRecord = environment as Record<string, unknown>;\n return [\n name,\n {\n ...environmentRecord,\n build:\n environmentRecord['build'] &&\n typeof environmentRecord['build'] === 'object'\n ? { ...(environmentRecord['build'] as Record<string, unknown>) }\n : environmentRecord['build'],\n },\n ];\n }),\n ) as UserConfig['environments'];\n}\n\n// Take a selective snapshot of the mutable config branches Nitro re-reads\n// after `config()` returns: plugin entries, build/server/test options, resolve\n// aliases, and environment overrides.\n//\n// Value: Nitro can coordinate multiple build phases from one stable config\n// view without breaking plugin identity or executable behavior.\n//\n// Guards against:\n// - a later write to `config.build.outDir` can desynchronize where the client\n// build writes files vs where Nitro tries to read them back.\n// - plugin array edits after capture can add/remove behavior from one sub-build\n// but not the other, which makes client and SSR resolution diverge.\n// - alias rewrites after capture can make the SSR environment import different\n// files than the client environment even though Nitro is orchestrating one app.\n// - environment-specific build overrides can drift after capture, which makes\n// diagnostics and any environment-aware follow-up logic observe the wrong\n// client/SSR shape.\n//\n// We do not deep-clone functions or plugin instances because Nitro still needs\n// the original executable behavior and plugin shape. The problem here is\n// mutable container objects, not function identity.\nfunction cloneUserConfig(userConfig: UserConfig): UserConfig {\n const { environments, resolve, build, server, plugins } = userConfig;\n const test = (userConfig as UserConfig & { test?: Record<string, unknown> })\n .test;\n return {\n ...userConfig,\n plugins: plugins?.map(cloneUserPlugin),\n build: build && { ...build },\n environments: cloneEnvironmentEntries(environments),\n server: server && { ...server },\n test: test && { ...test },\n resolve: resolve && {\n ...resolve,\n alias: Array.isArray(resolve.alias)\n ? [...resolve.alias]\n : resolve.alias && typeof resolve.alias === 'object'\n ? { ...resolve.alias }\n : resolve.alias,\n },\n } as UserConfig;\n}\n\nfunction createNitroMiddlewareHandler(handler: string): NitroEventHandler {\n return {\n route: '/**',\n handler,\n middleware: true,\n };\n}\n\n/**\n * Creates a `rollup:before` hook that marks specified packages as external\n * in Nitro's bundler config (applied to both the server build and the\n * prerender build).\n *\n * ## Subpath matching (Rolldown compatibility)\n *\n * When `bundlerConfig.external` is an **array**, Rollup automatically\n * prefix-matches entries — `'rxjs'` in the array will also externalise\n * `'rxjs/operators'`, `'rxjs/internal/Observable'`, etc.\n *\n * Rolldown (the default bundler in Nitro v3) does **not** do this. It\n * treats array entries as exact strings. To keep behaviour consistent\n * across both bundlers, the **function** branch already needed explicit\n * subpath matching. We now use the same `isExternal` helper for all\n * branches so that `'rxjs'` reliably matches `'rxjs/operators'`\n * regardless of whether the existing `external` value is a function,\n * array, or absent.\n *\n * Without this, the Nitro prerender build fails on Windows CI with:\n *\n * [RESOLVE_ERROR] Could not resolve 'rxjs/operators'\n */\nfunction createRollupBeforeHook(externalEntries: string[]) {\n const isExternal = (source: string) =>\n externalEntries.some(\n (entry) => source === entry || source.startsWith(entry + '/'),\n );\n\n return (_nitro: unknown, bundlerConfig: RollupConfig) => {\n sanitizeNitroBundlerConfig(_nitro, bundlerConfig);\n\n if (externalEntries.length === 0) {\n return;\n }\n\n const existing = bundlerConfig.external;\n if (!existing) {\n bundlerConfig.external = externalEntries;\n } else if (typeof existing === 'function') {\n bundlerConfig.external = (\n source: string,\n importer: string | undefined,\n isResolved: boolean,\n ) => existing(source, importer, isResolved) || isExternal(source);\n } else if (Array.isArray(existing)) {\n bundlerConfig.external = [...existing, ...externalEntries];\n } else {\n bundlerConfig.external = [existing as string, ...externalEntries];\n }\n };\n}\n\nfunction appendNoExternals(\n noExternals: NitroConfig['noExternals'],\n ...entries: string[]\n): NitroConfig['noExternals'] {\n if (!noExternals) {\n return entries;\n }\n\n return Array.isArray(noExternals)\n ? [...noExternals, ...entries]\n : noExternals;\n}\n\n/**\n * Patches Nitro's internal Rollup/Rolldown bundler config to work around\n * incompatibilities in the Nitro v3 alpha series.\n *\n * Called from the `rollup:before` hook, this function runs against the *final*\n * bundler config that Nitro assembles for its server/prerender builds — it\n * does NOT touch the normal Vite client or SSR environment configs.\n *\n * Each workaround is narrowly scoped and safe to remove once the corresponding\n * upstream Nitro issue is resolved.\n */\nfunction sanitizeNitroBundlerConfig(\n _nitro: unknown,\n bundlerConfig: RollupConfig,\n) {\n const output = bundlerConfig['output'];\n if (!output || Array.isArray(output) || typeof output !== 'object') {\n return;\n }\n\n // ── 1. Remove invalid `output.codeSplitting` ────────────────────────\n //\n // Nitro 3.0.1-alpha.2 adds `output.codeSplitting` to its internal bundler\n // config, but Rolldown rejects it as an unknown key:\n //\n // Warning: Invalid output options (1 issue found)\n // - For the \"codeSplitting\". Invalid key: Expected never but received \"codeSplitting\".\n //\n // Analog never sets this option. Removing it restores default bundler\n // behavior without changing any Analog semantics.\n if ('codeSplitting' in output) {\n delete (output as Record<string, unknown>)['codeSplitting'];\n }\n\n // ── 2. Remove invalid `output.manualChunks` ─────────────────────────\n //\n // Nitro's default config enables manual chunking for node_modules. Under\n // Nitro v3 alpha + Rollup 4.59 this crashes during the prerender rebundle:\n //\n // Cannot read properties of undefined (reading 'included')\n //\n // A single server bundle is acceptable for Analog's use case, so we strip\n // `manualChunks` until the upstream bug is fixed.\n if ('manualChunks' in output) {\n delete (output as Record<string, unknown>)['manualChunks'];\n }\n\n // ── 3. Escape route params in `output.chunkFileNames` ───────────────\n //\n // Nitro's `getChunkName()` derives chunk filenames from route patterns,\n // using its internal `routeToFsPath()` helper to convert route params\n // (`:productId` → `[productId]`) and catch-alls (`**` → `[...]`).\n //\n // Rollup/Rolldown interprets *any* `[token]` in the string returned by a\n // `chunkFileNames` function as a placeholder. Only a handful are valid —\n // `[name]`, `[hash]`, `[format]`, `[ext]` — so route-derived tokens like\n // `[productId]` or `[...]` trigger a build error:\n //\n // \"[productId]\" is not a valid placeholder in the \"output.chunkFileNames\" pattern.\n //\n // We wrap the original function to replace non-standard `[token]` patterns\n // with `_token_`, preserving the intended filename while avoiding the\n // placeholder validation error.\n //\n // Example: `_routes/products/[productId].mjs` → `_routes/products/_productId_.mjs`\n const VALID_ROLLUP_PLACEHOLDER = /^\\[(?:name|hash|format|ext)\\]$/;\n const chunkFileNames = (output as Record<string, unknown>)['chunkFileNames'];\n if (typeof chunkFileNames === 'function') {\n const originalFn = chunkFileNames as (...args: unknown[]) => unknown;\n (output as Record<string, unknown>)['chunkFileNames'] = (\n ...args: unknown[]\n ) => {\n const result = originalFn(...args);\n if (typeof result !== 'string') return result;\n return result.replace(/\\[[^\\]]+\\]/g, (match: string) =>\n VALID_ROLLUP_PLACEHOLDER.test(match)\n ? match\n : `_${match.slice(1, -1)}_`,\n );\n };\n }\n}\n\nfunction resolveClientOutputPath(\n cachedPath: string,\n workspaceRoot: string,\n rootDir: string,\n configuredOutDir: string | undefined,\n) {\n if (cachedPath) {\n debugNitro('resolveClientOutputPath using cached path', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n });\n return cachedPath;\n }\n\n if (configuredOutDir) {\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, rootDir, configuredOutDir),\n );\n debugNitro('resolveClientOutputPath using configured build.outDir', {\n workspaceRoot,\n rootDir,\n configuredOutDir,\n resolvedPath,\n });\n return resolvedPath;\n }\n\n // When no explicit build.outDir is set, the environment build config defaults\n // to `<workspace>/dist/<root>/client` for the client build. The non-SSR\n // (client) and SSR paths must agree on this so that registerIndexHtmlVirtual()\n // and publicAssets read from the directory the client build actually wrote to.\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n );\n debugNitro('resolveClientOutputPath using default dist client path', {\n workspaceRoot,\n rootDir,\n configuredOutDir,\n resolvedPath,\n });\n return resolvedPath;\n}\n\nfunction getEnvironmentBuildOutDir(environment: unknown): string | undefined {\n if (!environment || typeof environment !== 'object') {\n return undefined;\n }\n\n const environmentConfig = environment as {\n config?: {\n build?: {\n outDir?: string;\n };\n };\n build?: {\n outDir?: string;\n };\n };\n\n return (\n environmentConfig.config?.build?.outDir ?? environmentConfig.build?.outDir\n );\n}\n\nfunction resolveBuiltClientOutputPath(\n cachedPath: string,\n workspaceRoot: string,\n rootDir: string,\n configuredOutDir: string | undefined,\n environment?: unknown,\n) {\n const environmentOutDir = getEnvironmentBuildOutDir(environment);\n if (environmentOutDir) {\n const resolvedPath = normalizePath(\n resolve(workspaceRoot, rootDir, environmentOutDir),\n );\n debugNitro('resolveBuiltClientOutputPath using environment outDir', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n resolvedPath,\n });\n return resolvedPath;\n }\n\n debugNitro('resolveBuiltClientOutputPath falling back to shared resolver', {\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n });\n return resolveClientOutputPath(\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n );\n}\n\nfunction getNitroPublicOutputDir(nitroConfig: NitroConfig): string {\n const publicDir = nitroConfig.output?.publicDir;\n if (!publicDir) {\n throw new Error(\n 'Nitro public output directory is required to build the sitemap.',\n );\n }\n\n return publicDir;\n}\n\nfunction readDirectoryEntries(path: string): string[] {\n try {\n return readdirSync(path).sort();\n } catch (error) {\n return [\n `<<unable to read directory: ${error instanceof Error ? error.message : String(error)}>>`,\n ];\n }\n}\n\nfunction getPathDebugInfo(path: string) {\n return {\n rawPath: path,\n normalizedPath: normalizePath(path),\n exists: existsSync(path),\n entries: existsSync(path) ? readDirectoryEntries(path) : [],\n };\n}\n\nfunction assetSourceToString(source: string | Uint8Array) {\n return typeof source === 'string'\n ? source\n : Buffer.from(source).toString('utf8');\n}\n\nfunction captureClientIndexHtmlFromBundle(\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n hook: 'generateBundle' | 'writeBundle',\n) {\n const indexHtmlAsset = Object.values(bundle).find(\n (chunk) =>\n chunk.type === 'asset' &&\n chunk.fileName === 'index.html' &&\n typeof chunk.source !== 'undefined',\n );\n\n if (!indexHtmlAsset?.source) {\n debugNitro(`client bundle did not expose index.html during ${hook}`, {\n hook,\n bundleKeys: Object.keys(bundle).sort(),\n assetFileNames: Object.values(bundle)\n .filter((chunk) => chunk.type === 'asset')\n .map((chunk) => chunk.fileName)\n .filter(Boolean),\n });\n return undefined;\n }\n\n const indexHtml = assetSourceToString(indexHtmlAsset.source);\n debugNitro(`captured client bundle index.html asset during ${hook}`, {\n hook,\n fileName: indexHtmlAsset.fileName,\n htmlLength: indexHtml.length,\n });\n return indexHtml;\n}\n\n// Nitro only needs the HTML template string. Prefer the on-disk file when it\n// exists, but allow the captured client asset to cover build flows where the\n// client output directory disappears before Nitro assembles its virtual modules.\nfunction registerIndexHtmlVirtual(\n nitroConfig: NitroConfig,\n clientOutputPath: string,\n inlineIndexHtml?: string,\n) {\n const indexHtmlPath = resolve(clientOutputPath, 'index.html');\n debugNitro('registerIndexHtmlVirtual inspecting client output', {\n platform: process.platform,\n cwd: process.cwd(),\n clientOutputPath,\n clientOutputPathInfo: getPathDebugInfo(clientOutputPath),\n indexHtmlPath,\n indexHtmlExists: existsSync(indexHtmlPath),\n hasInlineIndexHtml: typeof inlineIndexHtml === 'string',\n });\n if (!existsSync(indexHtmlPath) && typeof inlineIndexHtml !== 'string') {\n debugNitro('registerIndexHtmlVirtual missing index.html', {\n platform: process.platform,\n cwd: process.cwd(),\n clientOutputPath,\n clientOutputPathInfo: getPathDebugInfo(clientOutputPath),\n indexHtmlPath,\n hasInlineIndexHtml: typeof inlineIndexHtml === 'string',\n nitroOutput: nitroConfig.output,\n nitroPublicAssets: nitroConfig.publicAssets,\n });\n throw new Error(\n `[analog] Client build output not found at ${indexHtmlPath}.\\n` +\n `Ensure the client environment build completed successfully before the server build.`,\n );\n }\n const indexHtml =\n typeof inlineIndexHtml === 'string'\n ? inlineIndexHtml\n : readFileSync(indexHtmlPath, 'utf8');\n debugNitro('registerIndexHtmlVirtual using HTML template source', {\n source:\n typeof inlineIndexHtml === 'string'\n ? 'captured client bundle asset'\n : 'client output index.html file',\n indexHtmlPath,\n });\n nitroConfig.virtual = {\n ...nitroConfig.virtual,\n '#analog/index': `export default ${JSON.stringify(indexHtml)};`,\n };\n}\n\n/**\n * Converts the built SSR entry path into a specifier that Nitro's bundler\n * can resolve, including all relative `./assets/*` chunk imports inside\n * the entry.\n *\n * The returned path **must** be an absolute filesystem path with forward\n * slashes (e.g. `D:/a/analog/dist/apps/blog-app/ssr/main.server.js`).\n * This lets Rollup/Rolldown determine the entry's directory and resolve\n * sibling chunk imports like `./assets/core-DTazUigR.js` correctly.\n *\n * ## Why not pathToFileURL() on Windows?\n *\n * Earlier versions converted the path to a `file:///D:/a/...` URL on\n * Windows, which worked with Nitro v2 + Rollup. Nitro v3 switched its\n * default bundler to Rolldown, and Rolldown does **not** extract the\n * importer directory from `file://` URLs. This caused every relative\n * import inside the SSR entry to fail during the prerender build:\n *\n * [RESOLVE_ERROR] Could not resolve './assets/core-DTazUigR.js'\n * in ../../dist/apps/blog-app/ssr/main.server.js\n *\n * `normalizePath()` (from Vite) simply converts backslashes to forward\n * slashes, which both Rollup and Rolldown handle correctly on all\n * platforms.\n */\nfunction toNitroSsrEntrypointSpecifier(ssrEntryPath: string) {\n return normalizePath(ssrEntryPath);\n}\n\nfunction applySsrEntryAlias(\n nitroConfig: NitroConfig,\n options: Options | undefined,\n workspaceRoot: string,\n rootDir: string,\n): void {\n const ssrOutDir =\n options?.ssrBuildDir || resolve(workspaceRoot, 'dist', rootDir, 'ssr');\n if (options?.ssr || nitroConfig.prerender?.routes?.length) {\n const ssrEntryPath = resolveBuiltSsrEntryPath(ssrOutDir);\n const ssrEntry = toNitroSsrEntrypointSpecifier(ssrEntryPath);\n nitroConfig.alias = {\n ...nitroConfig.alias,\n '#analog/ssr': ssrEntry,\n };\n }\n}\n\nfunction resolveBuiltSsrEntryPath(ssrOutDir: string) {\n const candidatePaths = [\n resolve(ssrOutDir, 'main.server.mjs'),\n resolve(ssrOutDir, 'main.server.js'),\n resolve(ssrOutDir, 'main.server'),\n ];\n\n const ssrEntryPath = candidatePaths.find((candidatePath) =>\n existsSync(candidatePath),\n );\n\n if (!ssrEntryPath) {\n throw new Error(\n `Unable to locate the built SSR entry in \"${ssrOutDir}\". Expected one of: ${candidatePaths.join(\n ', ',\n )}`,\n );\n }\n\n return ssrEntryPath;\n}\n\nexport function nitro(options?: Options, nitroOptions?: NitroConfig): Plugin[] {\n const workspaceRoot = options?.workspaceRoot ?? process.cwd();\n const sourceRoot = options?.sourceRoot ?? 'src';\n let isTest = process.env['NODE_ENV'] === 'test' || !!process.env['VITEST'];\n const baseURL = process.env['NITRO_APP_BASE_URL'] || '';\n const prefix = baseURL ? baseURL.substring(0, baseURL.length - 1) : '';\n const apiPrefix = `/${options?.apiPrefix || 'api'}`;\n const useAPIMiddleware =\n typeof options?.useAPIMiddleware !== 'undefined'\n ? options?.useAPIMiddleware\n : true;\n const viteRolldownOutput = options?.vite?.build?.rolldownOptions?.output;\n // Vite's native build typing allows `output` to be either a single object or\n // an array. Analog only forwards `codeSplitting` into the client environment\n // when there is a single output object to merge into.\n const viteRolldownOutputConfig =\n viteRolldownOutput && !Array.isArray(viteRolldownOutput)\n ? viteRolldownOutput\n : undefined;\n const codeSplitting = viteRolldownOutputConfig?.codeSplitting;\n\n let isBuild = false;\n let isServe = false;\n let ssrBuild = false;\n let config: UserConfig;\n let nitroConfig: NitroConfig;\n let environmentBuild = false;\n let hasAPIDir = false;\n let clientOutputPath = '';\n let clientIndexHtml: string | undefined;\n let legacyClientSubBuild = false;\n const rollupExternalEntries: string[] = [];\n const sitemapRoutes: string[] = [];\n const routeSitemaps: Record<\n string,\n PrerenderSitemapConfig | (() => PrerenderSitemapConfig)\n > = {};\n const routeSourceFiles: Record<string, string> = {};\n let rootDir = workspaceRoot;\n\n return [\n (options?.ssr\n ? devServerPlugin({\n entryServer: options?.entryServer,\n index: options?.index,\n routeRules: nitroOptions?.routeRules,\n i18n: options?.i18n,\n })\n : false) as Plugin,\n {\n name: '@analogjs/vite-plugin-nitro',\n async config(userConfig, { mode, command }) {\n isServe = command === 'serve';\n isBuild = command === 'build';\n ssrBuild = userConfig.build?.ssr === true;\n // Capture the incoming config at the `config()` boundary so every later\n // Nitro phase reads the same settings the build started with.\n //\n // Guards against: Nitro capturing `userConfig`, then another\n // hook rewrites `build.outDir` or replaces a plugin hook wrapper. If\n // we keep the live object, `closeBundle()` and the SSR handoff can end\n // up reading a different config than the one the client pass started\n // with.\n config = cloneUserConfig(userConfig);\n isTest = isTest ? isTest : mode === 'test';\n rollupExternalEntries.length = 0;\n clientIndexHtml = undefined;\n sitemapRoutes.length = 0;\n for (const key of Object.keys(routeSitemaps)) {\n delete routeSitemaps[key];\n }\n for (const key of Object.keys(routeSourceFiles)) {\n delete routeSourceFiles[key];\n }\n\n const resolvedConfigRoot = config.root\n ? resolve(workspaceRoot, config.root)\n : workspaceRoot;\n rootDir = relative(workspaceRoot, resolvedConfigRoot) || '.';\n hasAPIDir = existsSync(\n resolve(\n workspaceRoot,\n rootDir,\n `${sourceRoot}/server/routes/${options?.apiPrefix || 'api'}`,\n ),\n );\n const buildPreset =\n process.env['BUILD_PRESET'] ??\n (nitroOptions?.preset as string | undefined) ??\n (process.env['VERCEL'] ? 'vercel' : undefined);\n\n const pageHandlers = getPageHandlers({\n workspaceRoot,\n sourceRoot,\n rootDir,\n additionalPagesDirs: options?.additionalPagesDirs,\n hasAPIDir,\n });\n const resolvedClientOutputPath = resolveClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n );\n debugNitro('nitro config resolved client output path', {\n platform: process.platform,\n workspaceRoot,\n configRoot: config.root,\n resolvedConfigRoot,\n rootDir,\n buildOutDir: config.build?.outDir,\n clientOutputPath,\n resolvedClientOutputPath,\n hasEnvironmentConfig: !!config.environments,\n clientEnvironmentOutDir:\n config.environments?.['client'] &&\n typeof config.environments['client'] === 'object' &&\n 'build' in config.environments['client']\n ? (\n config.environments['client'] as {\n build?: { outDir?: string };\n }\n ).build?.outDir\n : undefined,\n });\n\n nitroConfig = {\n rootDir: normalizePath(rootDir),\n preset: buildPreset,\n compatibilityDate: '2025-11-19',\n logLevel: nitroOptions?.logLevel || 0,\n serverDir: normalizePath(`${sourceRoot}/server`),\n scanDirs: [\n normalizePath(`${rootDir}/${sourceRoot}/server`),\n ...(options?.additionalAPIDirs || []).map((dir) =>\n normalizePath(`${workspaceRoot}${dir}`),\n ),\n ],\n output: {\n dir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'analog'),\n ),\n publicDir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, 'analog/public'),\n ),\n },\n buildDir: normalizePath(\n resolve(workspaceRoot, 'dist', rootDir, '.nitro'),\n ),\n typescript: {\n generateTsConfig: false,\n },\n runtimeConfig: {\n apiPrefix: apiPrefix.substring(1),\n prefix,\n },\n // Analog provides its own renderer handler; prevent Nitro v3 from\n // auto-detecting index.html in rootDir and adding a conflicting one.\n renderer: false,\n imports: {\n autoImport: false,\n },\n hooks: {\n 'rollup:before': createRollupBeforeHook(rollupExternalEntries),\n },\n rollupConfig: {\n onwarn(warning) {\n if (\n warning.message.includes('empty chunk') &&\n warning.message.endsWith('.server')\n ) {\n return;\n }\n },\n plugins: [pageEndpointsPlugin()],\n },\n handlers: [\n ...(hasAPIDir\n ? []\n : useAPIMiddleware\n ? [createNitroMiddlewareHandler('#ANALOG_API_MIDDLEWARE')]\n : []),\n ...pageHandlers,\n ],\n routeRules: hasAPIDir\n ? undefined\n : useAPIMiddleware\n ? undefined\n : {\n [`${prefix}${apiPrefix}/**`]: {\n proxy: { to: '/**' },\n },\n },\n virtual: {\n '#ANALOG_SSR_RENDERER': ssrRenderer(),\n '#ANALOG_CLIENT_RENDERER': clientRenderer(),\n ...(hasAPIDir ? {} : { '#ANALOG_API_MIDDLEWARE': apiMiddleware }),\n },\n };\n\n if (isVercelPreset(buildPreset)) {\n nitroConfig = withVercelOutputAPI(nitroConfig, workspaceRoot);\n }\n\n if (isCloudflarePreset(buildPreset)) {\n nitroConfig = withCloudflareOutput(nitroConfig);\n }\n\n if (\n isNetlifyPreset(buildPreset) &&\n rootDir === '.' &&\n !existsSync(resolve(workspaceRoot, 'netlify.toml'))\n ) {\n nitroConfig = withNetlifyOutputAPI(nitroConfig, workspaceRoot);\n }\n\n if (isFirebaseAppHosting()) {\n nitroConfig = withAppHostingOutput(nitroConfig);\n }\n\n if (!ssrBuild && !isTest) {\n // store the client output path for the SSR build config\n clientOutputPath = resolvedClientOutputPath;\n debugNitro(\n 'nitro config cached client output path for later SSR/Nitro build',\n {\n ssrBuild,\n isTest,\n clientOutputPath,\n },\n );\n }\n\n // Start with a clean alias map. #analog/index is registered as a Nitro\n // virtual module after the client build, inlining the HTML template so\n // the server bundle imports it instead of using readFileSync with an\n // absolute path.\n nitroConfig.alias = {};\n\n if (isBuild) {\n nitroConfig.publicAssets = [\n { dir: normalizePath(resolvedClientOutputPath), maxAge: 0 },\n ];\n\n // In Nitro v3, renderer.entry is resolved via resolveModulePath()\n // during options normalization, which requires a real filesystem path.\n // Virtual modules (prefixed with #) can't survive this resolution.\n // Instead, we add the renderer as a catch-all handler directly —\n // this is functionally equivalent to what Nitro does internally\n // (it converts renderer.entry into a { route: '/**', lazy: true }\n // handler), but avoids the filesystem resolution step.\n const rendererHandler = options?.ssr\n ? '#ANALOG_SSR_RENDERER'\n : '#ANALOG_CLIENT_RENDERER';\n nitroConfig.handlers = [\n ...(nitroConfig.handlers || []),\n {\n handler: rendererHandler,\n route: '/**',\n lazy: true,\n },\n ];\n\n if (isEmptyPrerenderRoutes(options)) {\n nitroConfig.prerender = {};\n nitroConfig.prerender.routes = ['/'];\n }\n\n if (options?.prerender) {\n nitroConfig.prerender = nitroConfig.prerender ?? {};\n nitroConfig.prerender.crawlLinks = options?.prerender?.discover;\n\n let routes: (\n | string\n | PrerenderContentDir\n | PrerenderRouteConfig\n | undefined\n )[] = [];\n\n const prerenderRoutes = options?.prerender?.routes;\n const hasExplicitPrerenderRoutes =\n typeof prerenderRoutes === 'function' ||\n Array.isArray(prerenderRoutes);\n if (\n isArrayWithElements<string | PrerenderContentDir>(prerenderRoutes)\n ) {\n routes = prerenderRoutes;\n } else if (typeof prerenderRoutes === 'function') {\n routes = await prerenderRoutes();\n }\n\n const resolvedPrerenderRoutes = routes.reduce<string[]>(\n (prev, current) => {\n if (!current) {\n return prev;\n }\n if (typeof current === 'string') {\n prev.push(current);\n sitemapRoutes.push(current);\n return prev;\n }\n\n if ('route' in current) {\n if (current.sitemap) {\n routeSitemaps[current.route] = current.sitemap;\n }\n\n if (current.outputSourceFile) {\n const sourcePath = resolve(\n workspaceRoot,\n rootDir,\n current.outputSourceFile,\n );\n routeSourceFiles[current.route] = readFileSync(\n sourcePath,\n 'utf8',\n );\n }\n\n prev.push(current.route);\n sitemapRoutes.push(current.route);\n\n // Add the server-side data fetching endpoint URL\n if ('staticData' in current) {\n prev.push(`${apiPrefix}/_analog/pages/${current.route}`);\n }\n\n return prev;\n }\n\n const affectedFiles: PrerenderContentFile[] =\n getMatchingContentFilesWithFrontMatter(\n workspaceRoot,\n rootDir,\n current.contentDir,\n );\n\n affectedFiles.forEach((f) => {\n const result = current.transform(f);\n\n if (result) {\n if (current.sitemap) {\n routeSitemaps[result] =\n current.sitemap && typeof current.sitemap === 'function'\n ? current.sitemap?.(f)\n : current.sitemap;\n }\n\n if (current.outputSourceFile) {\n const sourceContent = current.outputSourceFile(f);\n if (sourceContent) {\n routeSourceFiles[result] = sourceContent;\n }\n }\n\n prev.push(result);\n sitemapRoutes.push(result);\n\n // Add the server-side data fetching endpoint URL\n if ('staticData' in current) {\n prev.push(`${apiPrefix}/_analog/pages/${result}`);\n }\n }\n });\n\n return prev;\n },\n [],\n );\n\n nitroConfig.prerender.routes =\n hasExplicitPrerenderRoutes || resolvedPrerenderRoutes.length\n ? resolvedPrerenderRoutes\n : (nitroConfig.prerender.routes ?? []);\n }\n\n // ── SSR / prerender Nitro config ─────────────────────────────\n //\n // This block configures Nitro for builds that rebundle the SSR\n // entry (main.server.{js,mjs}). That happens in two cases:\n //\n // 1. Full SSR apps — `options.ssr === true`\n // 2. Prerender-only — no runtime SSR, but the prerender build\n // still imports the SSR entry to render static pages.\n //\n // The original gate was `if (ssrBuild)`, which checks the Vite\n // top-level `build.ssr` flag. That works for SSR-only builds but\n // misses two Vite 6+ paths:\n //\n // a. **Vite Environment API (Vite 6+)** — SSR config lives in\n // `environments.ssr.build.ssr`, not `build.ssr`, so\n // `ssrBuild` is always `false`.\n // b. **Prerender-only apps** (e.g. blog-app) — `options.ssr`\n // is `false`, but prerender routes exist and the prerender\n // build still processes the SSR entry.\n //\n // Without this block:\n // - `rxjs` is never externalised → RESOLVE_ERROR in the\n // Nitro prerender build (especially on Windows CI).\n // - `moduleSideEffects` for zone.js is never set → zone.js\n // side-effects may be tree-shaken.\n // - The handlers list is not reassembled with page endpoints\n // + the renderer catch-all.\n //\n // The widened condition covers all supported build paths:\n // - `ssrBuild` → SSR-only build\n // - `options?.ssr` → Environment API SSR\n // - `nitroConfig.prerender?.routes?.length` → prerender-only\n if (\n ssrBuild ||\n options?.ssr ||\n nitroConfig.prerender?.routes?.length\n ) {\n nitroConfig.noExternals = appendNoExternals(\n nitroConfig.noExternals,\n 'es-toolkit',\n );\n\n if (process.platform === 'win32') {\n nitroConfig.noExternals = appendNoExternals(\n nitroConfig.noExternals,\n 'std-env',\n );\n }\n\n rollupExternalEntries.push(\n 'rxjs',\n 'node-fetch-native/dist/polyfill',\n // sharp is a native module with platform-specific binaries\n // (e.g. @img/sharp-darwin-arm64). pnpm creates symlinks for\n // ALL optional platform deps but only installs the matching\n // one — leaving broken symlinks that crash Nitro's bundler\n // with ENOENT during realpath(). Externalizing sharp avoids\n // bundling it entirely; it resolves from node_modules at\n // runtime instead.\n 'sharp',\n );\n\n nitroConfig = {\n ...nitroConfig,\n moduleSideEffects: ['zone.js/node', 'zone.js/fesm2015/zone-node'],\n handlers: [\n ...(hasAPIDir\n ? []\n : useAPIMiddleware\n ? [createNitroMiddlewareHandler('#ANALOG_API_MIDDLEWARE')]\n : []),\n ...pageHandlers,\n // Preserve the renderer catch-all handler added above\n {\n handler: rendererHandler,\n route: '/**',\n lazy: true,\n },\n ],\n };\n }\n }\n\n nitroConfig = mergeConfig(\n nitroConfig,\n nitroOptions as Record<string, any>,\n );\n\n // Only configure Vite 8 environments + builder on the top-level\n // build invocation. When buildApp's builder.build() calls re-enter\n // the config hook, returning environments/builder again would create\n // recursive buildApp invocations — each nesting another client build\n // that re-triggers config, producing an infinite loop of\n // \"building client environment... ✓ 1 modules transformed\".\n //\n // environmentBuild — already inside a buildApp call (recursion guard)\n // ssrBuild — legacy SSR-only sub-build\n // isServe — dev server / Vitest test runner (command: 'serve')\n if (environmentBuild || ssrBuild || isServe) {\n return {};\n }\n\n return {\n environments: {\n client: {\n build: {\n outDir:\n config?.build?.outDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'client'),\n emptyOutDir: true,\n // Forward code-splitting config to Rolldown when running\n // under Vite 8+. `false` disables splitting (inlines all\n // dynamic imports); an object configures chunk groups.\n // The `!== undefined` check ensures `codeSplitting: false`\n // is forwarded correctly (a truthy check would swallow it).\n ...(isRolldown() && codeSplitting !== undefined\n ? {\n rolldownOptions: {\n output: {\n // Preserve any sibling Rolldown output options while\n // overriding just `codeSplitting` for the client build.\n ...viteRolldownOutputConfig,\n codeSplitting,\n },\n },\n }\n : {}),\n },\n },\n ssr: {\n build: {\n ssr: true,\n [getBundleOptionsKey()]: {\n input:\n options?.entryServer ||\n resolve(\n workspaceRoot,\n rootDir,\n `${sourceRoot}/main.server.ts`,\n ),\n },\n outDir:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n // Preserve the client build output. The client environment is\n // built first and Nitro reads its index.html after SSR finishes.\n emptyOutDir: false,\n },\n },\n },\n builder: {\n /**\n * Reuse the already resolved Analog/Vite plugin graph across the\n * client and SSR environments.\n *\n * This keeps both builds behaviorally aligned: route generation,\n * content discovery, Angular transforms, Tailwind integration, and\n * other Analog-specific config stay consistent between the browser\n * bundle and the server bundle.\n *\n * The tradeoff is that the SSR environment can observe repeated\n * plugin entries when Vite materializes the environment-specific\n * build. Most notably, `@analogjs/vite-plugin-angular` can appear\n * twice in the SSR resolved plugin list even though the app only\n * configured `analog(...)` once.\n *\n * That duplicated name during SSR is an artifact of the shared\n * plugin graph, not evidence of a broken client build. The\n * duplicate-registration check in `vite-plugin-angular` therefore\n * throws only for non-SSR builds, where duplicate Angular plugin\n * instances would actually split the component style registries.\n */\n sharedPlugins: true,\n buildApp: async (builder) => {\n environmentBuild = true;\n debugNitro('builder.buildApp starting', {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n clientEnvironmentOutDir: getEnvironmentBuildOutDir(\n builder.environments['client'],\n ),\n ssrEnvironmentOutDir: getEnvironmentBuildOutDir(\n builder.environments['ssr'],\n ),\n });\n\n // Client must complete before SSR — the server build reads the\n // client's index.html via registerIndexHtmlVirtual(). Running\n // them in parallel caused a race on Windows where emptyOutDir\n // could delete client output before the server read it.\n await builder.build(builder.environments['client']);\n const postClientBuildOutputPath = resolveBuiltClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n builder.environments['client'],\n );\n // Capture the client template before any SSR/prerender work runs.\n // On Windows, later phases can leave the client output directory\n // unavailable even though the client build itself succeeded.\n registerIndexHtmlVirtual(\n nitroConfig,\n postClientBuildOutputPath,\n clientIndexHtml,\n );\n debugNitro('builder.buildApp completed client build', {\n postClientBuildOutputPath,\n postClientBuildOutputInfo: getPathDebugInfo(\n postClientBuildOutputPath,\n ),\n postClientBuildIndexHtmlPath: resolve(\n postClientBuildOutputPath,\n 'index.html',\n ),\n postClientBuildIndexHtmlExists: existsSync(\n resolve(postClientBuildOutputPath, 'index.html'),\n ),\n });\n\n if (options?.ssr || nitroConfig.prerender?.routes?.length) {\n debugSsr('builder.buildApp starting SSR build', {\n ssrEnabled: options?.ssr,\n prerenderRoutes: nitroConfig.prerender?.routes,\n });\n\n /**\n * This launches the SSR environment as a second build from the\n * shared plugin graph above. When debugging an apparent\n * duplicate `@analogjs/vite-plugin-angular` registration, this\n * is the handoff to inspect: the SSR builder replays the shared\n * plugins for the server pass and may therefore expose multiple\n * Angular-plugin entries in the SSR resolved config.\n *\n * That is expected for this orchestration path and should not\n * be treated the same as a duplicated client build, where two\n * Angular plugin instances would maintain separate style maps.\n */\n await builder.build(builder.environments['ssr']);\n debugSsr('builder.buildApp completed SSR build', {\n ssrOutputPath:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n });\n }\n\n applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);\n\n const resolvedClientOutputPath = resolveBuiltClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n builder.environments['client'],\n );\n\n nitroConfig.publicAssets = [\n { dir: normalizePath(resolvedClientOutputPath), maxAge: 0 },\n ];\n debugNitro(\n 'builder.buildApp resolved final client output path before Nitro build',\n {\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n nitroPublicAssets: nitroConfig.publicAssets,\n },\n );\n\n await buildServer(options, nitroConfig, routeSourceFiles);\n\n if (\n nitroConfig.prerender?.routes?.length &&\n options?.prerender?.sitemap\n ) {\n console.log('Building Sitemap...');\n // sitemap needs to be built after all directories are built\n await buildSitemap(\n config,\n options.prerender.sitemap,\n sitemapRoutes.length\n ? sitemapRoutes\n : nitroConfig.prerender.routes,\n getNitroPublicOutputDir(nitroConfig),\n routeSitemaps,\n { apiPrefix: options?.apiPrefix || 'api' },\n );\n }\n\n console.log(\n `\\n\\nThe '@analogjs/platform' server has been successfully built.`,\n );\n },\n },\n };\n },\n generateBundle(\n _options,\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n ) {\n if (!isBuild || ssrBuild) {\n return;\n }\n\n clientIndexHtml =\n captureClientIndexHtmlFromBundle(bundle, 'generateBundle') ??\n clientIndexHtml;\n },\n writeBundle(\n _options,\n bundle: Record<\n string,\n {\n type?: string;\n fileName?: string;\n source?: string | Uint8Array;\n }\n >,\n ) {\n if (!isBuild || ssrBuild) {\n return;\n }\n\n clientIndexHtml =\n captureClientIndexHtmlFromBundle(bundle, 'writeBundle') ??\n clientIndexHtml;\n },\n async configureServer(viteServer: ViteDevServer) {\n if (isServe && !isTest) {\n const nitro = await createNitro({\n dev: true,\n // Nitro's Vite builder now rejects `build()` in dev mode, but Analog's\n // dev integration still relies on the builder-driven reload hooks.\n // Force the server worker onto Rollup for this dev-only path.\n builder: 'rollup',\n ...nitroConfig,\n });\n const server = createDevServer(nitro);\n await build(nitro);\n const nitroSourceRoots = [\n normalizePath(\n resolve(workspaceRoot, rootDir, `${sourceRoot}/server`),\n ),\n ...(options?.additionalAPIDirs || []).map((dir) =>\n normalizePath(`${workspaceRoot}${dir}`),\n ),\n ];\n const isNitroSourceFile = (path: string) => {\n const normalizedPath = normalizePath(path);\n return nitroSourceRoots.some(\n (root) =>\n normalizedPath === root ||\n normalizedPath.startsWith(`${root}/`),\n );\n };\n let nitroRebuildPromise: Promise<void> | undefined;\n let nitroRebuildPending = false;\n const rebuildNitroServer = () => {\n if (nitroRebuildPromise) {\n // Coalesce rapid file events so a save that touches multiple server\n // route files results in one follow-up rebuild instead of many.\n nitroRebuildPending = true;\n return nitroRebuildPromise;\n }\n\n nitroRebuildPromise = (async () => {\n do {\n nitroRebuildPending = false;\n // Nitro API routes are not part of Vite's normal client HMR graph,\n // so rebuild the Nitro dev server to pick up handler edits.\n await build(nitro);\n } while (nitroRebuildPending);\n\n // Reload the page after the server rebuild completes so the next\n // request observes the updated API route implementation.\n viteServer.ws.send('analog:debug-full-reload', {\n plugin: 'vite-plugin-nitro',\n reason: 'nitro-server-rebuilt',\n });\n viteServer.ws.send({ type: 'full-reload' });\n })()\n .catch((error: unknown) => {\n viteServer.config.logger.error(\n `[analog] Failed to rebuild Nitro dev server.\\n${error instanceof Error ? error.stack || error.message : String(error)}`,\n );\n })\n .finally(() => {\n nitroRebuildPromise = undefined;\n });\n\n return nitroRebuildPromise;\n };\n const onNitroSourceChange = (path: string) => {\n if (!isNitroSourceFile(path)) {\n return;\n }\n\n void rebuildNitroServer();\n };\n\n // Watch the full Nitro source roots instead of only the API route\n // directory. API handlers often read helper modules, shared data, or\n // middleware from elsewhere under `src/server`, and those edits should\n // still rebuild the Nitro dev server and refresh connected browsers.\n viteServer.watcher.on('add', onNitroSourceChange);\n viteServer.watcher.on('change', onNitroSourceChange);\n viteServer.watcher.on('unlink', onNitroSourceChange);\n\n const apiHandler = async (\n req: IncomingMessage,\n res: ServerResponse,\n ) => {\n // Nitro v3's dev server is fetch-first, so adapt Vite's Node\n // request once and let Nitro respond with a standard Web Response.\n const response = await server.fetch(toWebRequest(req));\n await writeWebResponseToNode(res, response);\n };\n\n if (hasAPIDir) {\n viteServer.middlewares.use(\n (\n req: IncomingMessage,\n res: ServerResponse,\n next: (error?: unknown) => void,\n ) => {\n if (req.url?.startsWith(`${prefix}${apiPrefix}`)) {\n void apiHandler(req, res).catch((error) => next(error));\n return;\n }\n\n next();\n },\n );\n } else {\n viteServer.middlewares.use(\n apiPrefix,\n (\n req: IncomingMessage,\n res: ServerResponse,\n next: (error?: unknown) => void,\n ) => {\n void apiHandler(req, res).catch((error) => next(error));\n },\n );\n }\n\n viteServer.httpServer?.once('listening', () => {\n process.env['ANALOG_HOST'] = !viteServer.config.server.host\n ? 'localhost'\n : (viteServer.config.server.host as string);\n process.env['ANALOG_PORT'] = `${viteServer.config.server.port}`;\n });\n\n // handle upgrades if websockets are enabled\n if (nitroOptions?.experimental?.websocket) {\n debugNitro('experimental websocket upgrade handler enabled');\n viteServer.httpServer?.on('upgrade', server.upgrade);\n }\n\n console.log(\n `\\n\\nThe server endpoints are accessible under the \"${prefix}${apiPrefix}\" path.`,\n );\n }\n },\n\n async closeBundle() {\n if (legacyClientSubBuild) {\n return;\n }\n\n // When builder.buildApp ran, it already handled the full\n // client → SSR → Nitro pipeline. Skip to avoid double work.\n if (environmentBuild) {\n return;\n }\n\n // SSR sub-build — Vite re-enters the plugin with build.ssr;\n // Nitro server assembly happens only after the client pass.\n if (ssrBuild) {\n return;\n }\n\n // Nx executors (and any caller that runs `vite build` without\n // the Environment API) never trigger builder.buildApp, so\n // closeBundle is the only place to drive the SSR + Nitro build.\n if (isBuild) {\n const resolvedClientOutputPath = resolveClientOutputPath(\n clientOutputPath,\n workspaceRoot,\n rootDir,\n config.build?.outDir,\n );\n debugNitro(\n 'closeBundle resolved client output path before legacy SSR build',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n },\n );\n const indexHtmlPath = resolve(resolvedClientOutputPath, 'index.html');\n if (\n !existsSync(indexHtmlPath) &&\n typeof clientIndexHtml !== 'string'\n ) {\n debugNitro(\n 'closeBundle rebuilding missing client output before SSR/Nitro',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n indexHtmlPath,\n },\n );\n legacyClientSubBuild = true;\n try {\n await buildClientApp(config, options);\n } finally {\n legacyClientSubBuild = false;\n }\n }\n // Capture the client HTML before kicking off the standalone SSR build.\n // This mirrors the successful sequencing from before the closeBundle\n // refactor and avoids depending on the client directory surviving the\n // nested SSR build on Windows.\n registerIndexHtmlVirtual(\n nitroConfig,\n resolvedClientOutputPath,\n clientIndexHtml,\n );\n\n if (options?.ssr) {\n console.log('Building SSR application...');\n await buildSSRApp(config, options);\n debugSsr('closeBundle completed standalone SSR build', {\n ssrBuildDir:\n options?.ssrBuildDir ||\n resolve(workspaceRoot, 'dist', rootDir, 'ssr'),\n clientOutputPathInfo: clientOutputPath\n ? getPathDebugInfo(clientOutputPath)\n : null,\n });\n }\n\n applySsrEntryAlias(nitroConfig, options, workspaceRoot, rootDir);\n debugNitro(\n 'closeBundle resolved client output path before Nitro build',\n {\n platform: process.platform,\n workspaceRoot,\n rootDir,\n cachedClientOutputPath: clientOutputPath,\n configuredBuildOutDir: config.build?.outDir,\n resolvedClientOutputPath,\n resolvedClientOutputInfo: getPathDebugInfo(\n resolvedClientOutputPath,\n ),\n },\n );\n registerIndexHtmlVirtual(\n nitroConfig,\n resolvedClientOutputPath,\n clientIndexHtml,\n );\n\n await buildServer(options, nitroConfig, routeSourceFiles);\n\n if (\n nitroConfig.prerender?.routes?.length &&\n options?.prerender?.sitemap\n ) {\n console.log('Building Sitemap...');\n await buildSitemap(\n config,\n options.prerender.sitemap,\n sitemapRoutes.length\n ? sitemapRoutes\n : nitroConfig.prerender.routes,\n getNitroPublicOutputDir(nitroConfig),\n routeSitemaps,\n { apiPrefix: options?.apiPrefix || 'api' },\n );\n }\n\n console.log(\n `\\n\\nThe '@analogjs/platform' server has been successfully built.`,\n );\n }\n },\n },\n {\n name: '@analogjs/vite-plugin-nitro-api-prefix',\n config() {\n return {\n define: {\n ANALOG_API_PREFIX: `\"${baseURL.substring(1)}${apiPrefix.substring(1)}\"`,\n ...(options?.i18n\n ? {\n ANALOG_I18N_DEFAULT_LOCALE: JSON.stringify(\n options.i18n.defaultLocale,\n ),\n ANALOG_I18N_LOCALES: JSON.stringify(options.i18n.locales),\n }\n : {}),\n },\n };\n },\n },\n ];\n}\n\nfunction isEmptyPrerenderRoutes(options?: Options): boolean {\n if (!options || isArrayWithElements(options?.prerender?.routes)) {\n return false;\n }\n return !options.prerender?.routes;\n}\n\nfunction isArrayWithElements<T>(arr: unknown): arr is [T, ...T[]] {\n return !!(Array.isArray(arr) && arr.length);\n}\n\nconst VERCEL_PRESET = 'vercel';\n// Nitro v3 consolidates the old `vercel-edge` preset into `vercel` with\n// fluid compute enabled by default, so a single preset covers both\n// serverless and edge deployments.\nconst withVercelOutputAPI = (\n nitroConfig: NitroConfig | undefined,\n workspaceRoot: string,\n) => ({\n ...nitroConfig,\n preset: nitroConfig?.preset ?? 'vercel',\n vercel: {\n ...nitroConfig?.vercel,\n entryFormat: nitroConfig?.vercel?.entryFormat ?? 'node',\n functions: {\n runtime: nitroConfig?.vercel?.functions?.runtime ?? 'nodejs24.x',\n ...nitroConfig?.vercel?.functions,\n },\n },\n output: {\n ...nitroConfig?.output,\n dir: normalizePath(resolve(workspaceRoot, '.vercel', 'output')),\n publicDir: normalizePath(\n resolve(workspaceRoot, '.vercel', 'output/static'),\n ),\n },\n});\n\n// Nitro v3 uses underscore-separated preset names (e.g. `cloudflare_pages`),\n// but we accept both hyphen and underscore forms for backwards compatibility.\nconst isCloudflarePreset = (buildPreset: string | undefined) =>\n process.env['CF_PAGES'] ||\n (buildPreset &&\n (buildPreset.toLowerCase().includes('cloudflare-pages') ||\n buildPreset.toLowerCase().includes('cloudflare_pages')));\n\nconst withCloudflareOutput = (nitroConfig: NitroConfig | undefined) => ({\n ...nitroConfig,\n output: {\n ...nitroConfig?.output,\n serverDir: '{{ output.publicDir }}/_worker.js',\n },\n});\n\nconst isFirebaseAppHosting = () => !!process.env['NG_BUILD_LOGS_JSON'];\nconst withAppHostingOutput = (nitroConfig: NitroConfig) => {\n let hasOutput = false;\n\n return <NitroConfig>{\n ...nitroConfig,\n serveStatic: true,\n rollupConfig: {\n ...nitroConfig.rollupConfig,\n output: {\n ...nitroConfig.rollupConfig?.output,\n entryFileNames: 'server.mjs',\n },\n },\n hooks: {\n ...nitroConfig.hooks,\n compiled: () => {\n if (!hasOutput) {\n const buildOutput = {\n errors: [],\n warnings: [],\n outputPaths: {\n root: pathToFileURL(`${nitroConfig.output?.dir}`),\n browser: pathToFileURL(`${nitroConfig.output?.publicDir}`),\n server: pathToFileURL(`${nitroConfig.output?.dir}/server`),\n },\n };\n\n // Log the build output for Firebase App Hosting to pick up\n console.log(JSON.stringify(buildOutput, null, 2));\n hasOutput = true;\n }\n },\n },\n };\n};\n\nconst isNetlifyPreset = (buildPreset: string | undefined) =>\n process.env['NETLIFY'] ||\n (buildPreset && buildPreset.toLowerCase().includes('netlify'));\n\nconst withNetlifyOutputAPI = (\n nitroConfig: NitroConfig | undefined,\n workspaceRoot: string,\n) => ({\n ...nitroConfig,\n output: {\n ...nitroConfig?.output,\n dir: normalizePath(resolve(workspaceRoot, 'netlify/functions')),\n },\n});\n"],"mappings":"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"}