@analogjs/vite-plugin-nitro 3.0.0-alpha.19 → 3.0.0-alpha.20
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.
|
|
3
|
+
"version": "3.0.0-alpha.20",
|
|
4
4
|
"description": "A Vite plugin for adding a nitro API server",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Brandon Roberts <robertsbt@gmail.com>",
|
|
@@ -29,6 +29,14 @@
|
|
|
29
29
|
"type": "github",
|
|
30
30
|
"url": "https://github.com/sponsors/brandonroberts"
|
|
31
31
|
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"sharp": ">=0.32.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependenciesMeta": {
|
|
36
|
+
"sharp": {
|
|
37
|
+
"optional": true
|
|
38
|
+
}
|
|
39
|
+
},
|
|
32
40
|
"dependencies": {
|
|
33
41
|
"defu": "^6.1.4",
|
|
34
42
|
"nitro": "3.0.260311-beta",
|
|
@@ -463,7 +463,7 @@ function nitro(options, nitroOptions) {
|
|
|
463
463
|
}
|
|
464
464
|
if (ssrBuild || options?.ssr || nitroConfig.prerender?.routes?.length) {
|
|
465
465
|
if (process.platform === "win32") nitroConfig.noExternals = appendNoExternals(nitroConfig.noExternals, "std-env");
|
|
466
|
-
rollupExternalEntries.push("rxjs", "node-fetch-native/dist/polyfill");
|
|
466
|
+
rollupExternalEntries.push("rxjs", "node-fetch-native/dist/polyfill", "sharp");
|
|
467
467
|
nitroConfig = {
|
|
468
468
|
...nitroConfig,
|
|
469
469
|
moduleSideEffects: ["zone.js/node", "zone.js/fesm2015/zone-node"],
|
|
@@ -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';\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 debugLog('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 debugLog('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 debugLog('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 debugLog('resolveBuiltClientOutputPath using environment outDir', () => ({\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n resolvedPath,\n }));\n return resolvedPath;\n }\n\n debugLog(\n 'resolveBuiltClientOutputPath falling back to shared resolver',\n () => ({\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n }),\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\nconst DEBUG_NAMESPACE = 'analog:vite-plugin-nitro';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[|\\\\{}()[\\]^$+?.*]/g, '\\\\$&');\n}\n\n// Keep DEBUG matching local to this package so CI can opt into verbose traces\n// with familiar patterns like `analog:*` without adding a runtime dependency.\nfunction isDebugEnabled(namespace: string) {\n const debugValue = process.env['DEBUG'];\n if (!debugValue) {\n return false;\n }\n\n return debugValue\n .split(/[\\s,]+/)\n .filter(Boolean)\n .some((pattern) => {\n const matcher = new RegExp(\n `^${escapeRegExp(pattern).replace(/\\\\\\*/g, '.*')}$`,\n );\n return matcher.test(namespace);\n });\n}\n\nfunction debugLog(\n label: string,\n details?: Record<string, unknown> | (() => Record<string, unknown>),\n) {\n if (!isDebugEnabled(DEBUG_NAMESPACE)) {\n return;\n }\n\n const resolvedDetails = typeof details === 'function' ? details() : details;\n if (resolvedDetails && Object.keys(resolvedDetails).length > 0) {\n console.log(`DEBUG: ${label}`, resolvedDetails);\n return;\n }\n\n console.log(`DEBUG: ${label}`);\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 debugLog(`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 debugLog(`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 debugLog('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 debugLog('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 debugLog('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 })\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 debugLog('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 debugLog(\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 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 );\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 debugLog('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 debugLog('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 debugLog('builder.buildApp starting SSR build', () => ({\n ssrEnabled: options?.ssr,\n prerenderRoutes: nitroConfig.prerender?.routes,\n }));\n await builder.build(builder.environments['ssr']);\n debugLog('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 debugLog(\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({ 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 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 debugLog(\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 debugLog(\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 debugLog('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 debugLog(\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 },\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';\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 debugLog('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 debugLog('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 debugLog('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 debugLog('resolveBuiltClientOutputPath using environment outDir', () => ({\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n resolvedPath,\n }));\n return resolvedPath;\n }\n\n debugLog(\n 'resolveBuiltClientOutputPath falling back to shared resolver',\n () => ({\n cachedPath,\n workspaceRoot,\n rootDir,\n configuredOutDir,\n environmentOutDir,\n }),\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\nconst DEBUG_NAMESPACE = 'analog:vite-plugin-nitro';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[|\\\\{}()[\\]^$+?.*]/g, '\\\\$&');\n}\n\n// Keep DEBUG matching local to this package so CI can opt into verbose traces\n// with familiar patterns like `analog:*` without adding a runtime dependency.\nfunction isDebugEnabled(namespace: string) {\n const debugValue = process.env['DEBUG'];\n if (!debugValue) {\n return false;\n }\n\n return debugValue\n .split(/[\\s,]+/)\n .filter(Boolean)\n .some((pattern) => {\n const matcher = new RegExp(\n `^${escapeRegExp(pattern).replace(/\\\\\\*/g, '.*')}$`,\n );\n return matcher.test(namespace);\n });\n}\n\nfunction debugLog(\n label: string,\n details?: Record<string, unknown> | (() => Record<string, unknown>),\n) {\n if (!isDebugEnabled(DEBUG_NAMESPACE)) {\n return;\n }\n\n const resolvedDetails = typeof details === 'function' ? details() : details;\n if (resolvedDetails && Object.keys(resolvedDetails).length > 0) {\n console.log(`DEBUG: ${label}`, resolvedDetails);\n return;\n }\n\n console.log(`DEBUG: ${label}`);\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 debugLog(`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 debugLog(`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 debugLog('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 debugLog('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 debugLog('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 })\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 debugLog('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 debugLog(\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 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 debugLog('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 debugLog('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 debugLog('builder.buildApp starting SSR build', () => ({\n ssrEnabled: options?.ssr,\n prerenderRoutes: nitroConfig.prerender?.routes,\n }));\n await builder.build(builder.environments['ssr']);\n debugLog('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 debugLog(\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({ 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 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 debugLog(\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 debugLog(\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 debugLog('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 debugLog(\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 },\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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"}
|