vinext 0.0.39 → 0.0.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +1 -1
  2. package/dist/build/standalone.js +7 -0
  3. package/dist/build/standalone.js.map +1 -1
  4. package/dist/check.js +2 -2
  5. package/dist/check.js.map +1 -1
  6. package/dist/cli.js.map +1 -1
  7. package/dist/entries/app-rsc-entry.d.ts +2 -1
  8. package/dist/entries/app-rsc-entry.js +185 -264
  9. package/dist/entries/app-rsc-entry.js.map +1 -1
  10. package/dist/entries/pages-server-entry.js +205 -199
  11. package/dist/entries/pages-server-entry.js.map +1 -1
  12. package/dist/index.d.ts +32 -1
  13. package/dist/index.js +81 -6
  14. package/dist/index.js.map +1 -1
  15. package/dist/init.d.ts +1 -1
  16. package/dist/init.js +2 -2
  17. package/dist/init.js.map +1 -1
  18. package/dist/plugins/fonts.js +1 -0
  19. package/dist/plugins/fonts.js.map +1 -1
  20. package/dist/plugins/server-externals-manifest.d.ts +11 -1
  21. package/dist/plugins/server-externals-manifest.js +10 -3
  22. package/dist/plugins/server-externals-manifest.js.map +1 -1
  23. package/dist/routing/app-router.d.ts +10 -2
  24. package/dist/routing/app-router.js +37 -22
  25. package/dist/routing/app-router.js.map +1 -1
  26. package/dist/server/app-page-boundary-render.d.ts +1 -0
  27. package/dist/server/app-page-boundary-render.js +1 -0
  28. package/dist/server/app-page-boundary-render.js.map +1 -1
  29. package/dist/server/app-page-render.d.ts +1 -0
  30. package/dist/server/app-page-render.js +2 -0
  31. package/dist/server/app-page-render.js.map +1 -1
  32. package/dist/server/app-page-response.d.ts +4 -1
  33. package/dist/server/app-page-response.js +14 -8
  34. package/dist/server/app-page-response.js.map +1 -1
  35. package/dist/server/app-page-route-wiring.d.ts +79 -0
  36. package/dist/server/app-page-route-wiring.js +167 -0
  37. package/dist/server/app-page-route-wiring.js.map +1 -0
  38. package/dist/server/app-page-stream.d.ts +4 -1
  39. package/dist/server/app-page-stream.js +5 -1
  40. package/dist/server/app-page-stream.js.map +1 -1
  41. package/dist/server/app-route-handler-response.js +6 -2
  42. package/dist/server/app-route-handler-response.js.map +1 -1
  43. package/dist/server/app-router-entry.d.ts +6 -1
  44. package/dist/server/app-router-entry.js +9 -2
  45. package/dist/server/app-router-entry.js.map +1 -1
  46. package/dist/server/app-ssr-entry.d.ts +3 -1
  47. package/dist/server/app-ssr-entry.js +17 -17
  48. package/dist/server/app-ssr-entry.js.map +1 -1
  49. package/dist/server/app-ssr-stream.d.ts +1 -1
  50. package/dist/server/app-ssr-stream.js +4 -4
  51. package/dist/server/app-ssr-stream.js.map +1 -1
  52. package/dist/server/csp.d.ts +12 -0
  53. package/dist/server/csp.js +46 -0
  54. package/dist/server/csp.js.map +1 -0
  55. package/dist/server/dev-server.js +20 -14
  56. package/dist/server/dev-server.js.map +1 -1
  57. package/dist/server/html.d.ts +4 -1
  58. package/dist/server/html.js +11 -1
  59. package/dist/server/html.js.map +1 -1
  60. package/dist/server/middleware-response-headers.d.ts +12 -0
  61. package/dist/server/middleware-response-headers.js +23 -0
  62. package/dist/server/middleware-response-headers.js.map +1 -0
  63. package/dist/server/pages-page-data.d.ts +1 -0
  64. package/dist/server/pages-page-data.js +2 -2
  65. package/dist/server/pages-page-data.js.map +1 -1
  66. package/dist/server/pages-page-response.d.ts +2 -1
  67. package/dist/server/pages-page-response.js +16 -14
  68. package/dist/server/pages-page-response.js.map +1 -1
  69. package/dist/server/prod-server.d.ts +1 -1
  70. package/dist/server/prod-server.js +41 -14
  71. package/dist/server/prod-server.js.map +1 -1
  72. package/dist/server/request-pipeline.d.ts +14 -1
  73. package/dist/server/request-pipeline.js +55 -1
  74. package/dist/server/request-pipeline.js.map +1 -1
  75. package/dist/server/worker-utils.d.ts +4 -1
  76. package/dist/server/worker-utils.js +31 -1
  77. package/dist/server/worker-utils.js.map +1 -1
  78. package/dist/shims/error-boundary.d.ts +14 -5
  79. package/dist/shims/error-boundary.js +23 -3
  80. package/dist/shims/error-boundary.js.map +1 -1
  81. package/dist/shims/head.js.map +1 -1
  82. package/dist/shims/navigation.d.ts +16 -1
  83. package/dist/shims/navigation.js +18 -3
  84. package/dist/shims/navigation.js.map +1 -1
  85. package/dist/shims/router.js +127 -38
  86. package/dist/shims/router.js.map +1 -1
  87. package/dist/shims/script-nonce-context.d.ts +12 -0
  88. package/dist/shims/script-nonce-context.js +17 -0
  89. package/dist/shims/script-nonce-context.js.map +1 -0
  90. package/dist/shims/script.js +41 -10
  91. package/dist/shims/script.js.map +1 -1
  92. package/dist/shims/server.d.ts +17 -4
  93. package/dist/shims/server.js +97 -74
  94. package/dist/shims/server.js.map +1 -1
  95. package/dist/shims/slot.d.ts +28 -0
  96. package/dist/shims/slot.js +49 -0
  97. package/dist/shims/slot.js.map +1 -0
  98. package/dist/shims/url-safety.js +25 -4
  99. package/dist/shims/url-safety.js.map +1 -1
  100. package/package.json +7 -8
@@ -1 +1 @@
1
- {"version":3,"file":"pages-server-entry.js","names":[],"sources":["../../src/entries/pages-server-entry.ts"],"sourcesContent":["/**\n * Pages Router server entry generator.\n *\n * Generates the virtual SSR server entry module (`virtual:vinext-server-entry`).\n * This is the entry point for `vite build --ssr`. It handles SSR, API routes,\n * middleware, ISR, and i18n for the Pages Router.\n *\n * Extracted from index.ts.\n */\nimport { resolveEntryPath } from \"./runtime-entry-module.js\";\nimport { pagesRouter, apiRouter, type Route } from \"../routing/pages-router.js\";\nimport { createValidFileMatcher } from \"../routing/file-matcher.js\";\nimport { type ResolvedNextConfig } from \"../config/next-config.js\";\nimport { isProxyFile } from \"../server/middleware.js\";\nimport {\n generateSafeRegExpCode,\n generateMiddlewareMatcherCode,\n generateNormalizePathCode,\n generateRouteMatchNormalizationCode,\n} from \"../server/middleware-codegen.js\";\nimport { findFileWithExts } from \"./pages-entry-helpers.js\";\n\nconst _requestContextShimPath = resolveEntryPath(\"../shims/request-context.js\", import.meta.url);\nconst _routeTriePath = resolveEntryPath(\"../routing/route-trie.js\", import.meta.url);\nconst _pagesI18nPath = resolveEntryPath(\"../server/pages-i18n.js\", import.meta.url);\nconst _pagesPageResponsePath = resolveEntryPath(\n \"../server/pages-page-response.js\",\n import.meta.url,\n);\nconst _pagesPageDataPath = resolveEntryPath(\"../server/pages-page-data.js\", import.meta.url);\nconst _pagesNodeCompatPath = resolveEntryPath(\"../server/pages-node-compat.js\", import.meta.url);\nconst _pagesApiRoutePath = resolveEntryPath(\"../server/pages-api-route.js\", import.meta.url);\nconst _isrCachePath = resolveEntryPath(\"../server/isr-cache.js\", import.meta.url);\n\n/**\n * Generate the virtual SSR server entry module.\n * This is the entry point for `vite build --ssr`.\n */\nexport async function generateServerEntry(\n pagesDir: string,\n nextConfig: ResolvedNextConfig,\n fileMatcher: ReturnType<typeof createValidFileMatcher>,\n middlewarePath: string | null,\n instrumentationPath: string | null,\n): Promise<string> {\n const pageRoutes = await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);\n const apiRoutes = await apiRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);\n\n // Generate import statements using absolute paths since virtual\n // modules don't have a real file location for relative resolution.\n const pageImports = pageRoutes.map((r: Route, i: number) => {\n const absPath = r.filePath.replace(/\\\\/g, \"/\");\n return `import * as page_${i} from ${JSON.stringify(absPath)};`;\n });\n\n const apiImports = apiRoutes.map((r: Route, i: number) => {\n const absPath = r.filePath.replace(/\\\\/g, \"/\");\n return `import * as api_${i} from ${JSON.stringify(absPath)};`;\n });\n\n // Build the route table — include filePath for SSR manifest lookup\n const pageRouteEntries = pageRoutes.map((r: Route, i: number) => {\n const absPath = r.filePath.replace(/\\\\/g, \"/\");\n return ` { pattern: ${JSON.stringify(r.pattern)}, patternParts: ${JSON.stringify(r.patternParts)}, isDynamic: ${r.isDynamic}, params: ${JSON.stringify(r.params)}, module: page_${i}, filePath: ${JSON.stringify(absPath)} }`;\n });\n\n const apiRouteEntries = apiRoutes.map(\n (r: Route, i: number) =>\n ` { pattern: ${JSON.stringify(r.pattern)}, patternParts: ${JSON.stringify(r.patternParts)}, isDynamic: ${r.isDynamic}, params: ${JSON.stringify(r.params)}, module: api_${i} }`,\n );\n\n // Check for _app and _document\n const appFilePath = findFileWithExts(pagesDir, \"_app\", fileMatcher);\n const docFilePath = findFileWithExts(pagesDir, \"_document\", fileMatcher);\n const appImportCode =\n appFilePath !== null\n ? `import { default as AppComponent } from ${JSON.stringify(appFilePath.replace(/\\\\/g, \"/\"))};`\n : `const AppComponent = null;`;\n\n const docImportCode =\n docFilePath !== null\n ? `import { default as DocumentComponent } from ${JSON.stringify(docFilePath.replace(/\\\\/g, \"/\"))};`\n : `const DocumentComponent = null;`;\n\n // Serialize i18n config for embedding in the server entry\n const i18nConfigJson = nextConfig?.i18n\n ? JSON.stringify({\n locales: nextConfig.i18n.locales,\n defaultLocale: nextConfig.i18n.defaultLocale,\n localeDetection: nextConfig.i18n.localeDetection,\n domains: nextConfig.i18n.domains,\n })\n : \"null\";\n\n // Embed the resolved build ID at build time\n const buildIdJson = JSON.stringify(nextConfig?.buildId ?? null);\n\n // Serialize the full resolved config for the production server.\n // This embeds redirects, rewrites, headers, basePath, trailingSlash\n // so prod-server.ts can apply them without loading next.config.js at runtime.\n const vinextConfigJson = JSON.stringify({\n basePath: nextConfig?.basePath ?? \"\",\n trailingSlash: nextConfig?.trailingSlash ?? false,\n redirects: nextConfig?.redirects ?? [],\n rewrites: nextConfig?.rewrites ?? { beforeFiles: [], afterFiles: [], fallback: [] },\n headers: nextConfig?.headers ?? [],\n i18n: nextConfig?.i18n ?? null,\n images: {\n deviceSizes: nextConfig?.images?.deviceSizes,\n imageSizes: nextConfig?.images?.imageSizes,\n dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,\n contentDispositionType: nextConfig?.images?.contentDispositionType,\n contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy,\n },\n });\n\n // Generate instrumentation code if instrumentation.ts exists.\n // For production (Cloudflare Workers), instrumentation.ts is bundled into the\n // Worker and register() is called as a top-level await at module evaluation time —\n // before any request is handled. This mirrors App Router behavior (generateRscEntry)\n // and matches Next.js semantics: register() runs once on startup in the process\n // that handles requests.\n //\n // The onRequestError handler is stored on globalThis so it is visible across\n // all code within the Worker (same global scope).\n const instrumentationImportCode = instrumentationPath\n ? `import * as _instrumentation from ${JSON.stringify(instrumentationPath.replace(/\\\\/g, \"/\"))};`\n : \"\";\n\n const instrumentationInitCode = instrumentationPath\n ? `// Run instrumentation register() once at module evaluation time — before any\n// requests are handled. Matches Next.js semantics: register() is called once\n// on startup in the process that handles requests.\nif (typeof _instrumentation.register === \"function\") {\n await _instrumentation.register();\n}\n// Store the onRequestError handler on globalThis so it is visible to all\n// code within the Worker (same global scope).\nif (typeof _instrumentation.onRequestError === \"function\") {\n globalThis.__VINEXT_onRequestErrorHandler__ = _instrumentation.onRequestError;\n}`\n : \"\";\n\n // Generate middleware code if middleware.ts exists\n const middlewareImportCode = middlewarePath\n ? `import * as middlewareModule from ${JSON.stringify(middlewarePath.replace(/\\\\/g, \"/\"))};\nimport { NextRequest, NextFetchEvent } from \"next/server\";`\n : \"\";\n\n // The matcher config is read from the middleware module at import time.\n // We inline the matching + execution logic so the prod server can call it.\n const middlewareExportCode = middlewarePath\n ? `\n// --- Middleware support (generated from middleware-codegen.ts) ---\n${generateNormalizePathCode(\"es5\")}\n${generateRouteMatchNormalizationCode(\"es5\")}\n${generateSafeRegExpCode(\"es5\")}\n${generateMiddlewareMatcherCode(\"es5\")}\n\nexport async function runMiddleware(request, ctx) {\n if (ctx) return _runWithExecutionContext(ctx, () => _runMiddleware(request));\n return _runMiddleware(request);\n}\n\nasync function _runMiddleware(request) {\n var isProxy = ${middlewarePath ? JSON.stringify(isProxyFile(middlewarePath)) : \"false\"};\n var middlewareFn = isProxy\n ? (middlewareModule.proxy ?? middlewareModule.default)\n : (middlewareModule.middleware ?? middlewareModule.default);\n if (typeof middlewareFn !== \"function\") {\n var fileType = isProxy ? \"Proxy\" : \"Middleware\";\n var expectedExport = isProxy ? \"proxy\" : \"middleware\";\n throw new Error(\"The \" + fileType + \" file must export a function named \\`\" + expectedExport + \"\\` or a \\`default\\` function.\");\n }\n\n var config = middlewareModule.config;\n var matcher = config && config.matcher;\n var url = new URL(request.url);\n\n // Normalize pathname before matching to prevent path-confusion bypasses\n // (percent-encoding like /%61dmin, double slashes like /dashboard//settings).\n var decodedPathname;\n try { decodedPathname = __normalizePathnameForRouteMatchStrict(url.pathname); } catch (e) {\n return { continue: false, response: new Response(\"Bad Request\", { status: 400 }) };\n }\n var normalizedPathname = __normalizePath(decodedPathname);\n\n if (!matchesMiddleware(normalizedPathname, matcher, request, i18nConfig)) return { continue: true };\n\n // Construct a new Request with the decoded + normalized pathname so middleware\n // always sees the same canonical path that the router uses.\n var mwRequest = request;\n if (normalizedPathname !== url.pathname) {\n var mwUrl = new URL(url);\n mwUrl.pathname = normalizedPathname;\n mwRequest = new Request(mwUrl, request);\n }\n var __mwNextConfig = (vinextConfig.basePath || i18nConfig) ? { basePath: vinextConfig.basePath, i18n: i18nConfig || undefined } : undefined;\n var nextRequest = mwRequest instanceof NextRequest ? mwRequest : new NextRequest(mwRequest, __mwNextConfig ? { nextConfig: __mwNextConfig } : undefined);\n var fetchEvent = new NextFetchEvent({ page: normalizedPathname });\n var response;\n try { response = await middlewareFn(nextRequest, fetchEvent); }\n catch (e) {\n console.error(\"[vinext] Middleware error:\", e);\n var _mwCtxErr = _getRequestExecutionContext();\n if (_mwCtxErr && typeof _mwCtxErr.waitUntil === \"function\") { _mwCtxErr.waitUntil(fetchEvent.drainWaitUntil()); } else { fetchEvent.drainWaitUntil(); }\n return { continue: false, response: new Response(\"Internal Server Error\", { status: 500 }) };\n }\n var _mwCtx = _getRequestExecutionContext();\n if (_mwCtx && typeof _mwCtx.waitUntil === \"function\") { _mwCtx.waitUntil(fetchEvent.drainWaitUntil()); } else { fetchEvent.drainWaitUntil(); }\n\n if (!response) return { continue: true };\n\n if (response.headers.get(\"x-middleware-next\") === \"1\") {\n var rHeaders = new Headers();\n for (var [key, value] of response.headers) {\n // Keep x-middleware-request-* headers so the production server can\n // apply middleware-request header overrides before stripping internals\n // from the final client response.\n if (\n !key.startsWith(\"x-middleware-\") ||\n key === \"x-middleware-override-headers\" ||\n key.startsWith(\"x-middleware-request-\")\n ) rHeaders.append(key, value);\n }\n return { continue: true, responseHeaders: rHeaders };\n }\n\n if (response.status >= 300 && response.status < 400) {\n var location = response.headers.get(\"Location\") || response.headers.get(\"location\");\n if (location) {\n var rdHeaders = new Headers();\n for (var [rk, rv] of response.headers) {\n if (!rk.startsWith(\"x-middleware-\") && rk.toLowerCase() !== \"location\") rdHeaders.append(rk, rv);\n }\n return { continue: false, redirectUrl: location, redirectStatus: response.status, responseHeaders: rdHeaders };\n }\n }\n\n var rewriteUrl = response.headers.get(\"x-middleware-rewrite\");\n if (rewriteUrl) {\n var rwHeaders = new Headers();\n for (var [k, v] of response.headers) {\n if (!k.startsWith(\"x-middleware-\") || k === \"x-middleware-override-headers\" || k.startsWith(\"x-middleware-request-\")) rwHeaders.append(k, v);\n }\n var rewritePath;\n try { var parsed = new URL(rewriteUrl, request.url); rewritePath = parsed.pathname + parsed.search; }\n catch { rewritePath = rewriteUrl; }\n return { continue: true, rewriteUrl: rewritePath, rewriteStatus: response.status !== 200 ? response.status : undefined, responseHeaders: rwHeaders };\n }\n\n return { continue: false, response: response };\n}\n`\n : `\nexport async function runMiddleware() { return { continue: true }; }\n`;\n\n // The server entry is a self-contained module that uses Web-standard APIs\n // (Request/Response, renderToReadableStream) so it runs on Cloudflare Workers.\n return `\nimport React from \"react\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { resetSSRHead, getSSRHeadHTML } from \"next/head\";\nimport { flushPreloads } from \"next/dynamic\";\nimport { setSSRContext, wrapWithRouterContext } from \"next/router\";\nimport { _runWithCacheState } from \"next/cache\";\nimport { runWithPrivateCache } from \"vinext/cache-runtime\";\nimport { ensureFetchPatch, runWithFetchCache } from \"vinext/fetch-cache\";\nimport { runWithRequestContext as _runWithUnifiedCtx, createRequestContext as _createUnifiedCtx } from \"vinext/unified-request-context\";\nimport \"vinext/router-state\";\nimport { runWithServerInsertedHTMLState } from \"vinext/navigation-state\";\nimport { runWithHeadState } from \"vinext/head-state\";\nimport \"vinext/i18n-state\";\nimport { setI18nContext } from \"vinext/i18n-context\";\nimport { safeJsonStringify } from \"vinext/html\";\nimport { getSSRFontLinks as _getSSRFontLinks, getSSRFontStyles as _getSSRFontStylesGoogle, getSSRFontPreloads as _getSSRFontPreloadsGoogle } from \"next/font/google\";\nimport { getSSRFontStyles as _getSSRFontStylesLocal, getSSRFontPreloads as _getSSRFontPreloadsLocal } from \"next/font/local\";\nimport { sanitizeDestination as sanitizeDestinationLocal } from ${JSON.stringify(resolveEntryPath(\"../config/config-matchers.js\", import.meta.url))};\nimport { runWithExecutionContext as _runWithExecutionContext, getRequestExecutionContext as _getRequestExecutionContext } from ${JSON.stringify(_requestContextShimPath)};\nimport { buildRouteTrie as _buildRouteTrie, trieMatch as _trieMatch } from ${JSON.stringify(_routeTriePath)};\nimport { reportRequestError as _reportRequestError } from \"vinext/instrumentation\";\nimport { resolvePagesI18nRequest } from ${JSON.stringify(_pagesI18nPath)};\nimport { createPagesReqRes as __createPagesReqRes } from ${JSON.stringify(_pagesNodeCompatPath)};\nimport { handlePagesApiRoute as __handlePagesApiRoute } from ${JSON.stringify(_pagesApiRoutePath)};\nimport {\n isrGet as __sharedIsrGet,\n isrSet as __sharedIsrSet,\n isrCacheKey as __sharedIsrCacheKey,\n triggerBackgroundRegeneration as __sharedTriggerBackgroundRegeneration,\n} from ${JSON.stringify(_isrCachePath)};\nimport { resolvePagesPageData as __resolvePagesPageData } from ${JSON.stringify(_pagesPageDataPath)};\nimport { renderPagesPageResponse as __renderPagesPageResponse } from ${JSON.stringify(_pagesPageResponsePath)};\n${instrumentationImportCode}\n${middlewareImportCode}\n\n${instrumentationInitCode}\n\n// i18n config (embedded at build time)\nconst i18nConfig = ${i18nConfigJson};\n\n// Build ID (embedded at build time)\nconst buildId = ${buildIdJson};\n\n// Full resolved config for production server (embedded at build time)\nexport const vinextConfig = ${vinextConfigJson};\n\nfunction isrGet(key) {\n return __sharedIsrGet(key);\n}\nfunction isrSet(key, data, revalidateSeconds, tags) {\n return __sharedIsrSet(key, data, revalidateSeconds, tags);\n}\nfunction triggerBackgroundRegeneration(key, renderFn) {\n return __sharedTriggerBackgroundRegeneration(key, renderFn);\n}\nfunction isrCacheKey(router, pathname) {\n return __sharedIsrCacheKey(router, pathname, buildId || undefined);\n}\n\nasync function renderToStringAsync(element) {\n const stream = await renderToReadableStream(element);\n await stream.allReady;\n return new Response(stream).text();\n}\n\nasync function renderIsrPassToStringAsync(element) {\n // The cache-fill render is a second render pass for the same request.\n // Reset render-scoped state so it cannot leak from the streamed response\n // render or affect async work that is still draining from that stream.\n // Keep request identity state (pathname/query/locale/executionContext)\n // intact: this second pass still belongs to the same request.\n return await runWithServerInsertedHTMLState(() =>\n runWithHeadState(() =>\n _runWithCacheState(() =>\n runWithPrivateCache(() => runWithFetchCache(async () => renderToStringAsync(element))),\n ),\n ),\n );\n}\n\n${pageImports.join(\"\\n\")}\n${apiImports.join(\"\\n\")}\n\n${appImportCode}\n${docImportCode}\n\nexport const pageRoutes = [\n${pageRouteEntries.join(\",\\n\")}\n];\nconst _pageRouteTrie = _buildRouteTrie(pageRoutes);\n\nconst apiRoutes = [\n${apiRouteEntries.join(\",\\n\")}\n];\nconst _apiRouteTrie = _buildRouteTrie(apiRoutes);\n\nfunction matchRoute(url, routes) {\n const pathname = url.split(\"?\")[0];\n let normalizedUrl = pathname === \"/\" ? \"/\" : pathname.replace(/\\\\/$/, \"\");\n // NOTE: Do NOT decodeURIComponent here. The pathname is already decoded at\n // the entry point. Decoding again would create a double-decode vector.\n const urlParts = normalizedUrl.split(\"/\").filter(Boolean);\n const trie = routes === pageRoutes ? _pageRouteTrie : _apiRouteTrie;\n return _trieMatch(trie, urlParts);\n}\n\nfunction parseQuery(url) {\n const qs = url.split(\"?\")[1];\n if (!qs) return {};\n const p = new URLSearchParams(qs);\n const q = {};\n for (const [k, v] of p) {\n if (k in q) {\n q[k] = Array.isArray(q[k]) ? q[k].concat(v) : [q[k], v];\n } else {\n q[k] = v;\n }\n }\n return q;\n}\n\nfunction patternToNextFormat(pattern) {\n return pattern\n .replace(/:([\\\\w]+)\\\\*/g, \"[[...$1]]\")\n .replace(/:([\\\\w]+)\\\\+/g, \"[...$1]\")\n .replace(/:([\\\\w]+)/g, \"[$1]\");\n}\n\nfunction collectAssetTags(manifest, moduleIds) {\n // Fall back to embedded manifest (set by vinext:cloudflare-build for Workers)\n const m = (manifest && Object.keys(manifest).length > 0)\n ? manifest\n : (typeof globalThis !== \"undefined\" && globalThis.__VINEXT_SSR_MANIFEST__) || null;\n const tags = [];\n const seen = new Set();\n\n // Load the set of lazy chunk filenames (only reachable via dynamic imports).\n // These should NOT get <link rel=\"modulepreload\"> or <script type=\"module\">\n // tags — they are fetched on demand when the dynamic import() executes (e.g.\n // chunks behind React.lazy() or next/dynamic boundaries).\n var lazyChunks = (typeof globalThis !== \"undefined\" && globalThis.__VINEXT_LAZY_CHUNKS__) || null;\n var lazySet = lazyChunks && lazyChunks.length > 0 ? new Set(lazyChunks) : null;\n\n // Inject the client entry script if embedded by vinext:cloudflare-build\n if (typeof globalThis !== \"undefined\" && globalThis.__VINEXT_CLIENT_ENTRY__) {\n const entry = globalThis.__VINEXT_CLIENT_ENTRY__;\n seen.add(entry);\n tags.push('<link rel=\"modulepreload\" href=\"/' + entry + '\" />');\n tags.push('<script type=\"module\" src=\"/' + entry + '\" crossorigin></script>');\n }\n if (m) {\n // Always inject shared chunks (framework, vinext runtime, entry) and\n // page-specific chunks. The manifest maps module file paths to their\n // associated JS/CSS assets.\n //\n // For page-specific injection, the module IDs may be absolute paths\n // while the manifest uses relative paths. Try both the original ID\n // and a suffix match to find the correct manifest entry.\n var allFiles = [];\n\n if (moduleIds && moduleIds.length > 0) {\n // Collect assets for the requested page modules\n for (var mi = 0; mi < moduleIds.length; mi++) {\n var id = moduleIds[mi];\n var files = m[id];\n if (!files) {\n // Absolute path didn't match — try matching by suffix.\n // Manifest keys are relative (e.g. \"pages/about.tsx\") while\n // moduleIds may be absolute (e.g. \"/home/.../pages/about.tsx\").\n for (var mk in m) {\n if (id.endsWith(\"/\" + mk) || id === mk) {\n files = m[mk];\n break;\n }\n }\n }\n if (files) {\n for (var fi = 0; fi < files.length; fi++) allFiles.push(files[fi]);\n }\n }\n\n // Also inject shared chunks that every page needs: framework,\n // vinext runtime, and the entry bootstrap. These are identified\n // by scanning all manifest values for chunk filenames containing\n // known prefixes.\n for (var key in m) {\n var vals = m[key];\n if (!vals) continue;\n for (var vi = 0; vi < vals.length; vi++) {\n var file = vals[vi];\n var basename = file.split(\"/\").pop() || \"\";\n if (\n basename.startsWith(\"framework-\") ||\n basename.startsWith(\"vinext-\") ||\n basename.includes(\"vinext-client-entry\") ||\n basename.includes(\"vinext-app-browser-entry\")\n ) {\n allFiles.push(file);\n }\n }\n }\n } else {\n // No specific modules — include all assets from manifest\n for (var akey in m) {\n var avals = m[akey];\n if (avals) {\n for (var ai = 0; ai < avals.length; ai++) allFiles.push(avals[ai]);\n }\n }\n }\n\n for (var ti = 0; ti < allFiles.length; ti++) {\n var tf = allFiles[ti];\n // Normalize: Vite's SSR manifest values include a leading '/'\n // (from base path), but we prepend '/' ourselves when building\n // href/src attributes. Strip any existing leading slash to avoid\n // producing protocol-relative URLs like \"//assets/chunk.js\".\n // This also ensures consistent keys for the seen-set dedup and\n // lazySet.has() checks (which use values without leading slash).\n if (tf.charAt(0) === '/') tf = tf.slice(1);\n if (seen.has(tf)) continue;\n seen.add(tf);\n if (tf.endsWith(\".css\")) {\n tags.push('<link rel=\"stylesheet\" href=\"/' + tf + '\" />');\n } else if (tf.endsWith(\".js\")) {\n // Skip lazy chunks — they are behind dynamic import() boundaries\n // (React.lazy, next/dynamic) and should only be fetched on demand.\n if (lazySet && lazySet.has(tf)) continue;\n tags.push('<link rel=\"modulepreload\" href=\"/' + tf + '\" />');\n tags.push('<script type=\"module\" src=\"/' + tf + '\" crossorigin></script>');\n }\n }\n }\n return tags.join(\"\\\\n \");\n}\n\n// i18n helpers\nfunction extractLocale(url) {\n if (!i18nConfig) return { locale: undefined, url, hadPrefix: false };\n const pathname = url.split(\"?\")[0];\n const parts = pathname.split(\"/\").filter(Boolean);\n const query = url.includes(\"?\") ? url.slice(url.indexOf(\"?\")) : \"\";\n if (parts.length > 0 && i18nConfig.locales.includes(parts[0])) {\n const locale = parts[0];\n const rest = \"/\" + parts.slice(1).join(\"/\");\n return { locale, url: (rest || \"/\") + query, hadPrefix: true };\n }\n return { locale: i18nConfig.defaultLocale, url, hadPrefix: false };\n}\n\nfunction detectLocaleFromHeaders(headers) {\n if (!i18nConfig) return null;\n const acceptLang = headers.get(\"accept-language\");\n if (!acceptLang) return null;\n const langs = acceptLang.split(\",\").map(function(part) {\n const pieces = part.trim().split(\";\");\n const q = pieces[1] ? parseFloat(pieces[1].replace(\"q=\", \"\")) : 1;\n return { lang: pieces[0].trim().toLowerCase(), q: q };\n }).sort(function(a, b) { return b.q - a.q; });\n for (let k = 0; k < langs.length; k++) {\n const lang = langs[k].lang;\n for (let j = 0; j < i18nConfig.locales.length; j++) {\n if (i18nConfig.locales[j].toLowerCase() === lang) return i18nConfig.locales[j];\n }\n const prefix = lang.split(\"-\")[0];\n for (let j = 0; j < i18nConfig.locales.length; j++) {\n const loc = i18nConfig.locales[j].toLowerCase();\n if (loc === prefix || loc.startsWith(prefix + \"-\")) return i18nConfig.locales[j];\n }\n }\n return null;\n}\n\nfunction parseCookieLocaleFromHeader(cookieHeader) {\n if (!i18nConfig || !cookieHeader) return null;\n const match = cookieHeader.match(/(?:^|;\\\\s*)NEXT_LOCALE=([^;]*)/);\n if (!match) return null;\n var value;\n try { value = decodeURIComponent(match[1].trim()); } catch (e) { return null; }\n if (i18nConfig.locales.indexOf(value) !== -1) return value;\n return null;\n}\n\nexport async function renderPage(request, url, manifest, ctx) {\n if (ctx) return _runWithExecutionContext(ctx, () => _renderPage(request, url, manifest));\n return _renderPage(request, url, manifest);\n}\n\nasync function _renderPage(request, url, manifest) {\n const localeInfo = i18nConfig\n ? resolvePagesI18nRequest(\n url,\n i18nConfig,\n request.headers,\n new URL(request.url).hostname,\n vinextConfig.basePath,\n vinextConfig.trailingSlash,\n )\n : { locale: undefined, url, hadPrefix: false, domainLocale: undefined, redirectUrl: undefined };\n const locale = localeInfo.locale;\n const routeUrl = localeInfo.url;\n const currentDefaultLocale = i18nConfig\n ? (localeInfo.domainLocale ? localeInfo.domainLocale.defaultLocale : i18nConfig.defaultLocale)\n : undefined;\n const domainLocales = i18nConfig ? i18nConfig.domains : undefined;\n\n if (localeInfo.redirectUrl) {\n return new Response(null, { status: 307, headers: { Location: localeInfo.redirectUrl } });\n }\n\n const match = matchRoute(routeUrl, pageRoutes);\n if (!match) {\n return new Response(\"<!DOCTYPE html><html><body><h1>404 - Page not found</h1></body></html>\",\n { status: 404, headers: { \"Content-Type\": \"text/html\" } });\n }\n\n\t const { route, params } = match;\n\t const __uCtx = _createUnifiedCtx({\n\t executionContext: _getRequestExecutionContext(),\n\t });\n\t return _runWithUnifiedCtx(__uCtx, async () => {\n\t ensureFetchPatch();\n\t try {\n\t const routePattern = patternToNextFormat(route.pattern);\n\t if (typeof setSSRContext === \"function\") {\n\t setSSRContext({\n\t pathname: routePattern,\n\t query: { ...params, ...parseQuery(routeUrl) },\n\t asPath: routeUrl,\n\t locale: locale,\n locales: i18nConfig ? i18nConfig.locales : undefined,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n });\n }\n\n if (i18nConfig) {\n setI18nContext({\n locale: locale,\n locales: i18nConfig.locales,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n hostname: new URL(request.url).hostname,\n });\n }\n\n const pageModule = route.module;\n const PageComponent = pageModule.default;\n\t if (!PageComponent) {\n\t return new Response(\"Page has no default export\", { status: 500 });\n\t }\n\t // Build font Link header early so it's available for ISR cached responses too.\n\t // Font preloads are module-level state populated at import time and persist across requests.\n\t var _fontLinkHeader = \"\";\n\t var _allFp = [];\n try {\n var _fpGoogle = typeof _getSSRFontPreloadsGoogle === \"function\" ? _getSSRFontPreloadsGoogle() : [];\n var _fpLocal = typeof _getSSRFontPreloadsLocal === \"function\" ? _getSSRFontPreloadsLocal() : [];\n _allFp = _fpGoogle.concat(_fpLocal);\n\t if (_allFp.length > 0) {\n\t _fontLinkHeader = _allFp.map(function(p) { return \"<\" + p.href + \">; rel=preload; as=font; type=\" + p.type + \"; crossorigin\"; }).join(\", \");\n\t }\n\t } catch (e) { /* font preloads not available */ }\n\t const query = parseQuery(routeUrl);\n\t const pageDataResult = await __resolvePagesPageData({\n\t applyRequestContexts() {\n\t if (typeof setSSRContext === \"function\") {\n\t setSSRContext({\n\t pathname: routePattern,\n\t query: { ...params, ...query },\n\t asPath: routeUrl,\n\t locale: locale,\n\t locales: i18nConfig ? i18nConfig.locales : undefined,\n\t defaultLocale: currentDefaultLocale,\n\t domainLocales: domainLocales,\n\t });\n\t }\n\t if (i18nConfig) {\n\t setI18nContext({\n\t locale: locale,\n\t locales: i18nConfig.locales,\n\t defaultLocale: currentDefaultLocale,\n\t domainLocales: domainLocales,\n\t hostname: new URL(request.url).hostname,\n\t });\n\t }\n\t },\n\t buildId,\n\t createGsspReqRes() {\n\t return __createPagesReqRes({ body: undefined, query, request, url: routeUrl });\n\t },\n\t createPageElement(currentPageProps) {\n\t var currentElement = AppComponent\n\t ? React.createElement(AppComponent, { Component: PageComponent, pageProps: currentPageProps })\n\t : React.createElement(PageComponent, currentPageProps);\n\t return wrapWithRouterContext(currentElement);\n\t },\n\t fontLinkHeader: _fontLinkHeader,\n\t i18n: {\n\t locale: locale,\n\t locales: i18nConfig ? i18nConfig.locales : undefined,\n\t defaultLocale: currentDefaultLocale,\n\t domainLocales: domainLocales,\n\t },\n\t isrCacheKey,\n\t isrGet,\n\t isrSet,\n\t pageModule,\n\t params,\n\t query,\n\t renderIsrPassToStringAsync,\n\t route: {\n\t isDynamic: route.isDynamic,\n\t },\n\t routePattern,\n\t routeUrl,\n\t runInFreshUnifiedContext(callback) {\n\t var revalCtx = _createUnifiedCtx({\n\t executionContext: _getRequestExecutionContext(),\n\t });\n\t return _runWithUnifiedCtx(revalCtx, async () => {\n\t ensureFetchPatch();\n\t return callback();\n\t });\n\t },\n\t safeJsonStringify,\n\t sanitizeDestination: sanitizeDestinationLocal,\n\t triggerBackgroundRegeneration,\n\t });\n\t if (pageDataResult.kind === \"response\") {\n\t return pageDataResult.response;\n\t }\n\t let pageProps = pageDataResult.pageProps;\n\t var gsspRes = pageDataResult.gsspRes;\n\t let isrRevalidateSeconds = pageDataResult.isrRevalidateSeconds;\n\n\t const pageModuleIds = route.filePath ? [route.filePath] : [];\n\t const assetTags = collectAssetTags(manifest, pageModuleIds);\n\n return __renderPagesPageResponse({\n assetTags,\n buildId,\n clearSsrContext() {\n if (typeof setSSRContext === \"function\") setSSRContext(null);\n },\n createPageElement(currentPageProps) {\n var currentElement;\n if (AppComponent) {\n currentElement = React.createElement(AppComponent, { Component: PageComponent, pageProps: currentPageProps });\n } else {\n currentElement = React.createElement(PageComponent, currentPageProps);\n }\n return wrapWithRouterContext(currentElement);\n },\n DocumentComponent,\n flushPreloads: typeof flushPreloads === \"function\" ? flushPreloads : undefined,\n fontLinkHeader: _fontLinkHeader,\n fontPreloads: _allFp,\n getFontLinks() {\n try {\n return typeof _getSSRFontLinks === \"function\" ? _getSSRFontLinks() : [];\n } catch (e) {\n return [];\n }\n },\n getFontStyles() {\n try {\n var allFontStyles = [];\n if (typeof _getSSRFontStylesGoogle === \"function\") allFontStyles.push(..._getSSRFontStylesGoogle());\n if (typeof _getSSRFontStylesLocal === \"function\") allFontStyles.push(..._getSSRFontStylesLocal());\n return allFontStyles;\n } catch (e) {\n return [];\n }\n },\n\t getSSRHeadHTML: typeof getSSRHeadHTML === \"function\" ? getSSRHeadHTML : undefined,\n\t gsspRes,\n isrCacheKey,\n isrRevalidateSeconds,\n isrSet,\n i18n: {\n locale: locale,\n locales: i18nConfig ? i18nConfig.locales : undefined,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n },\n pageProps,\n params,\n renderDocumentToString(element) {\n return renderToStringAsync(element);\n },\n renderIsrPassToStringAsync,\n renderToReadableStream(element) {\n return renderToReadableStream(element);\n },\n resetSSRHead: typeof resetSSRHead === \"function\" ? resetSSRHead : undefined,\n\t routePattern,\n routeUrl,\n safeJsonStringify,\n });\n } catch (e) {\n console.error(\"[vinext] SSR error:\", e);\n _reportRequestError(\n e instanceof Error ? e : new Error(String(e)),\n { path: url, method: request.method, headers: Object.fromEntries(request.headers.entries()) },\n { routerKind: \"Pages Router\", routePath: route.pattern, routeType: \"render\" },\n ).catch(() => { /* ignore reporting errors */ });\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n });\n}\n\nexport async function handleApiRoute(request, url) {\n const match = matchRoute(url, apiRoutes);\n return __handlePagesApiRoute({\n match,\n request,\n url,\n reportRequestError(error, routePattern) {\n console.error(\"[vinext] API error:\", error);\n void _reportRequestError(\n error,\n { path: url, method: request.method, headers: Object.fromEntries(request.headers.entries()) },\n { routerKind: \"Pages Router\", routePath: routePattern, routeType: \"route\" },\n );\n },\n });\n}\n\n${middlewareExportCode}\n`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"pages-server-entry.js","names":[],"sources":["../../src/entries/pages-server-entry.ts"],"sourcesContent":["/**\n * Pages Router server entry generator.\n *\n * Generates the virtual SSR server entry module (`virtual:vinext-server-entry`).\n * This is the entry point for `vite build --ssr`. It handles SSR, API routes,\n * middleware, ISR, and i18n for the Pages Router.\n *\n * Extracted from index.ts.\n */\nimport { resolveEntryPath } from \"./runtime-entry-module.js\";\nimport { pagesRouter, apiRouter, type Route } from \"../routing/pages-router.js\";\nimport { createValidFileMatcher } from \"../routing/file-matcher.js\";\nimport { type ResolvedNextConfig } from \"../config/next-config.js\";\nimport { isProxyFile } from \"../server/middleware.js\";\nimport {\n generateSafeRegExpCode,\n generateMiddlewareMatcherCode,\n generateNormalizePathCode,\n generateRouteMatchNormalizationCode,\n} from \"../server/middleware-codegen.js\";\nimport { findFileWithExts } from \"./pages-entry-helpers.js\";\n\nconst _requestContextShimPath = resolveEntryPath(\"../shims/request-context.js\", import.meta.url);\nconst _routeTriePath = resolveEntryPath(\"../routing/route-trie.js\", import.meta.url);\nconst _pagesI18nPath = resolveEntryPath(\"../server/pages-i18n.js\", import.meta.url);\nconst _pagesPageResponsePath = resolveEntryPath(\n \"../server/pages-page-response.js\",\n import.meta.url,\n);\nconst _pagesPageDataPath = resolveEntryPath(\"../server/pages-page-data.js\", import.meta.url);\nconst _pagesNodeCompatPath = resolveEntryPath(\"../server/pages-node-compat.js\", import.meta.url);\nconst _pagesApiRoutePath = resolveEntryPath(\"../server/pages-api-route.js\", import.meta.url);\nconst _isrCachePath = resolveEntryPath(\"../server/isr-cache.js\", import.meta.url);\nconst _cspPath = resolveEntryPath(\"../server/csp.js\", import.meta.url);\n\n/**\n * Generate the virtual SSR server entry module.\n * This is the entry point for `vite build --ssr`.\n */\nexport async function generateServerEntry(\n pagesDir: string,\n nextConfig: ResolvedNextConfig,\n fileMatcher: ReturnType<typeof createValidFileMatcher>,\n middlewarePath: string | null,\n instrumentationPath: string | null,\n): Promise<string> {\n const pageRoutes = await pagesRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);\n const apiRoutes = await apiRouter(pagesDir, nextConfig?.pageExtensions, fileMatcher);\n\n // Generate import statements using absolute paths since virtual\n // modules don't have a real file location for relative resolution.\n const pageImports = pageRoutes.map((r: Route, i: number) => {\n const absPath = r.filePath.replace(/\\\\/g, \"/\");\n return `import * as page_${i} from ${JSON.stringify(absPath)};`;\n });\n\n const apiImports = apiRoutes.map((r: Route, i: number) => {\n const absPath = r.filePath.replace(/\\\\/g, \"/\");\n return `import * as api_${i} from ${JSON.stringify(absPath)};`;\n });\n\n // Build the route table — include filePath for SSR manifest lookup\n const pageRouteEntries = pageRoutes.map((r: Route, i: number) => {\n const absPath = r.filePath.replace(/\\\\/g, \"/\");\n return ` { pattern: ${JSON.stringify(r.pattern)}, patternParts: ${JSON.stringify(r.patternParts)}, isDynamic: ${r.isDynamic}, params: ${JSON.stringify(r.params)}, module: page_${i}, filePath: ${JSON.stringify(absPath)} }`;\n });\n\n const apiRouteEntries = apiRoutes.map(\n (r: Route, i: number) =>\n ` { pattern: ${JSON.stringify(r.pattern)}, patternParts: ${JSON.stringify(r.patternParts)}, isDynamic: ${r.isDynamic}, params: ${JSON.stringify(r.params)}, module: api_${i} }`,\n );\n\n // Check for _app and _document\n const appFilePath = findFileWithExts(pagesDir, \"_app\", fileMatcher);\n const docFilePath = findFileWithExts(pagesDir, \"_document\", fileMatcher);\n const appImportCode =\n appFilePath !== null\n ? `import { default as AppComponent } from ${JSON.stringify(appFilePath.replace(/\\\\/g, \"/\"))};`\n : `const AppComponent = null;`;\n\n const docImportCode =\n docFilePath !== null\n ? `import { default as DocumentComponent } from ${JSON.stringify(docFilePath.replace(/\\\\/g, \"/\"))};`\n : `const DocumentComponent = null;`;\n\n // Serialize i18n config for embedding in the server entry\n const i18nConfigJson = nextConfig?.i18n\n ? JSON.stringify({\n locales: nextConfig.i18n.locales,\n defaultLocale: nextConfig.i18n.defaultLocale,\n localeDetection: nextConfig.i18n.localeDetection,\n domains: nextConfig.i18n.domains,\n })\n : \"null\";\n\n // Embed the resolved build ID at build time\n const buildIdJson = JSON.stringify(nextConfig?.buildId ?? null);\n\n // Serialize the full resolved config for the production server.\n // This embeds redirects, rewrites, headers, basePath, trailingSlash\n // so prod-server.ts can apply them without loading next.config.js at runtime.\n const vinextConfigJson = JSON.stringify({\n basePath: nextConfig?.basePath ?? \"\",\n trailingSlash: nextConfig?.trailingSlash ?? false,\n redirects: nextConfig?.redirects ?? [],\n rewrites: nextConfig?.rewrites ?? { beforeFiles: [], afterFiles: [], fallback: [] },\n headers: nextConfig?.headers ?? [],\n i18n: nextConfig?.i18n ?? null,\n images: {\n deviceSizes: nextConfig?.images?.deviceSizes,\n imageSizes: nextConfig?.images?.imageSizes,\n dangerouslyAllowSVG: nextConfig?.images?.dangerouslyAllowSVG,\n contentDispositionType: nextConfig?.images?.contentDispositionType,\n contentSecurityPolicy: nextConfig?.images?.contentSecurityPolicy,\n },\n });\n\n // Generate instrumentation code if instrumentation.ts exists.\n // For production (Cloudflare Workers), instrumentation.ts is bundled into the\n // Worker and register() is called as a top-level await at module evaluation time —\n // before any request is handled. This mirrors App Router behavior (generateRscEntry)\n // and matches Next.js semantics: register() runs once on startup in the process\n // that handles requests.\n //\n // The onRequestError handler is stored on globalThis so it is visible across\n // all code within the Worker (same global scope).\n const instrumentationImportCode = instrumentationPath\n ? `import * as _instrumentation from ${JSON.stringify(instrumentationPath.replace(/\\\\/g, \"/\"))};`\n : \"\";\n\n const instrumentationInitCode = instrumentationPath\n ? `// Run instrumentation register() once at module evaluation time — before any\n// requests are handled. Matches Next.js semantics: register() is called once\n// on startup in the process that handles requests.\nif (typeof _instrumentation.register === \"function\") {\n await _instrumentation.register();\n}\n// Store the onRequestError handler on globalThis so it is visible to all\n// code within the Worker (same global scope).\nif (typeof _instrumentation.onRequestError === \"function\") {\n globalThis.__VINEXT_onRequestErrorHandler__ = _instrumentation.onRequestError;\n}`\n : \"\";\n\n // Generate middleware code if middleware.ts exists\n const middlewareImportCode = middlewarePath\n ? `import * as middlewareModule from ${JSON.stringify(middlewarePath.replace(/\\\\/g, \"/\"))};\nimport { NextRequest, NextFetchEvent } from \"next/server\";`\n : \"\";\n\n // The matcher config is read from the middleware module at import time.\n // We inline the matching + execution logic so the prod server can call it.\n const middlewareExportCode = middlewarePath\n ? `\n// --- Middleware support (generated from middleware-codegen.ts) ---\n${generateNormalizePathCode(\"es5\")}\n${generateRouteMatchNormalizationCode(\"es5\")}\n${generateSafeRegExpCode(\"es5\")}\n${generateMiddlewareMatcherCode(\"es5\")}\n\nexport async function runMiddleware(request, ctx) {\n if (ctx) return _runWithExecutionContext(ctx, () => _runMiddleware(request));\n return _runMiddleware(request);\n}\n\nasync function _runMiddleware(request) {\n var isProxy = ${middlewarePath ? JSON.stringify(isProxyFile(middlewarePath)) : \"false\"};\n var middlewareFn = isProxy\n ? (middlewareModule.proxy ?? middlewareModule.default)\n : (middlewareModule.middleware ?? middlewareModule.default);\n if (typeof middlewareFn !== \"function\") {\n var fileType = isProxy ? \"Proxy\" : \"Middleware\";\n var expectedExport = isProxy ? \"proxy\" : \"middleware\";\n throw new Error(\"The \" + fileType + \" file must export a function named \\`\" + expectedExport + \"\\` or a \\`default\\` function.\");\n }\n\n var config = middlewareModule.config;\n var matcher = config && config.matcher;\n var url = new URL(request.url);\n\n // Normalize pathname before matching to prevent path-confusion bypasses\n // (percent-encoding like /%61dmin, double slashes like /dashboard//settings).\n var decodedPathname;\n try { decodedPathname = __normalizePathnameForRouteMatchStrict(url.pathname); } catch (e) {\n return { continue: false, response: new Response(\"Bad Request\", { status: 400 }) };\n }\n var normalizedPathname = __normalizePath(decodedPathname);\n\n if (!matchesMiddleware(normalizedPathname, matcher, request, i18nConfig)) return { continue: true };\n\n // Construct a new Request with the decoded + normalized pathname so middleware\n // always sees the same canonical path that the router uses.\n var mwRequest = request;\n if (normalizedPathname !== url.pathname) {\n var mwUrl = new URL(url);\n mwUrl.pathname = normalizedPathname;\n mwRequest = new Request(mwUrl, request);\n }\n var __mwNextConfig = (vinextConfig.basePath || i18nConfig) ? { basePath: vinextConfig.basePath, i18n: i18nConfig || undefined } : undefined;\n var nextRequest = mwRequest instanceof NextRequest ? mwRequest : new NextRequest(mwRequest, __mwNextConfig ? { nextConfig: __mwNextConfig } : undefined);\n var fetchEvent = new NextFetchEvent({ page: normalizedPathname });\n var response;\n try { response = await middlewareFn(nextRequest, fetchEvent); }\n catch (e) {\n console.error(\"[vinext] Middleware error:\", e);\n var _mwCtxErr = _getRequestExecutionContext();\n if (_mwCtxErr && typeof _mwCtxErr.waitUntil === \"function\") { _mwCtxErr.waitUntil(fetchEvent.drainWaitUntil()); } else { fetchEvent.drainWaitUntil(); }\n return { continue: false, response: new Response(\"Internal Server Error\", { status: 500 }) };\n }\n var _mwCtx = _getRequestExecutionContext();\n if (_mwCtx && typeof _mwCtx.waitUntil === \"function\") { _mwCtx.waitUntil(fetchEvent.drainWaitUntil()); } else { fetchEvent.drainWaitUntil(); }\n\n if (!response) return { continue: true };\n\n if (response.headers.get(\"x-middleware-next\") === \"1\") {\n var rHeaders = new Headers();\n for (var [key, value] of response.headers) {\n // Keep x-middleware-request-* headers so the production server can\n // apply middleware-request header overrides before stripping internals\n // from the final client response.\n if (\n !key.startsWith(\"x-middleware-\") ||\n key === \"x-middleware-override-headers\" ||\n key.startsWith(\"x-middleware-request-\")\n ) rHeaders.append(key, value);\n }\n return { continue: true, responseHeaders: rHeaders };\n }\n\n if (response.status >= 300 && response.status < 400) {\n var location = response.headers.get(\"Location\") || response.headers.get(\"location\");\n if (location) {\n var rdHeaders = new Headers();\n for (var [rk, rv] of response.headers) {\n if (!rk.startsWith(\"x-middleware-\") && rk.toLowerCase() !== \"location\") rdHeaders.append(rk, rv);\n }\n return { continue: false, redirectUrl: location, redirectStatus: response.status, responseHeaders: rdHeaders };\n }\n }\n\n var rewriteUrl = response.headers.get(\"x-middleware-rewrite\");\n if (rewriteUrl) {\n var rwHeaders = new Headers();\n for (var [k, v] of response.headers) {\n if (!k.startsWith(\"x-middleware-\") || k === \"x-middleware-override-headers\" || k.startsWith(\"x-middleware-request-\")) rwHeaders.append(k, v);\n }\n var rewritePath;\n try { var parsed = new URL(rewriteUrl, request.url); rewritePath = parsed.pathname + parsed.search; }\n catch { rewritePath = rewriteUrl; }\n return { continue: true, rewriteUrl: rewritePath, rewriteStatus: response.status !== 200 ? response.status : undefined, responseHeaders: rwHeaders };\n }\n\n return { continue: false, response: response };\n}\n`\n : `\nexport async function runMiddleware() { return { continue: true }; }\n`;\n\n // The server entry is a self-contained module that uses Web-standard APIs\n // (Request/Response, renderToReadableStream) so it runs on Cloudflare Workers.\n return `\nimport React from \"react\";\nimport { renderToReadableStream } from \"react-dom/server.edge\";\nimport { resetSSRHead, getSSRHeadHTML } from \"next/head\";\nimport { flushPreloads } from \"next/dynamic\";\nimport { setSSRContext, wrapWithRouterContext } from \"next/router\";\nimport { _runWithCacheState } from \"next/cache\";\nimport { runWithPrivateCache } from \"vinext/cache-runtime\";\nimport { ensureFetchPatch, runWithFetchCache } from \"vinext/fetch-cache\";\nimport { runWithRequestContext as _runWithUnifiedCtx, createRequestContext as _createUnifiedCtx } from \"vinext/unified-request-context\";\nimport \"vinext/router-state\";\nimport { runWithServerInsertedHTMLState } from \"vinext/navigation-state\";\nimport { runWithHeadState } from \"vinext/head-state\";\nimport \"vinext/i18n-state\";\nimport { setI18nContext } from \"vinext/i18n-context\";\nimport { createNonceAttribute as __createNonceAttribute, safeJsonStringify } from \"vinext/html\";\nimport { getSSRFontLinks as _getSSRFontLinks, getSSRFontStyles as _getSSRFontStylesGoogle, getSSRFontPreloads as _getSSRFontPreloadsGoogle } from \"next/font/google\";\nimport { getSSRFontStyles as _getSSRFontStylesLocal, getSSRFontPreloads as _getSSRFontPreloadsLocal } from \"next/font/local\";\nimport { sanitizeDestination as sanitizeDestinationLocal } from ${JSON.stringify(resolveEntryPath(\"../config/config-matchers.js\", import.meta.url))};\nimport { runWithExecutionContext as _runWithExecutionContext, getRequestExecutionContext as _getRequestExecutionContext } from ${JSON.stringify(_requestContextShimPath)};\nimport { buildRouteTrie as _buildRouteTrie, trieMatch as _trieMatch } from ${JSON.stringify(_routeTriePath)};\nimport { reportRequestError as _reportRequestError } from \"vinext/instrumentation\";\nimport { resolvePagesI18nRequest } from ${JSON.stringify(_pagesI18nPath)};\nimport { createPagesReqRes as __createPagesReqRes } from ${JSON.stringify(_pagesNodeCompatPath)};\nimport { handlePagesApiRoute as __handlePagesApiRoute } from ${JSON.stringify(_pagesApiRoutePath)};\nimport {\n isrGet as __sharedIsrGet,\n isrSet as __sharedIsrSet,\n isrCacheKey as __sharedIsrCacheKey,\n triggerBackgroundRegeneration as __sharedTriggerBackgroundRegeneration,\n} from ${JSON.stringify(_isrCachePath)};\nimport { getScriptNonceFromHeaderSources as __getScriptNonceFromHeaderSources } from ${JSON.stringify(_cspPath)};\nimport { resolvePagesPageData as __resolvePagesPageData } from ${JSON.stringify(_pagesPageDataPath)};\nimport { renderPagesPageResponse as __renderPagesPageResponse } from ${JSON.stringify(_pagesPageResponsePath)};\n${instrumentationImportCode}\n${middlewareImportCode}\n\n${instrumentationInitCode}\n\n// i18n config (embedded at build time)\nconst i18nConfig = ${i18nConfigJson};\n\n// Build ID (embedded at build time)\nconst buildId = ${buildIdJson};\n\n// Full resolved config for production server (embedded at build time)\nexport const vinextConfig = ${vinextConfigJson};\n\nfunction isrGet(key) {\n return __sharedIsrGet(key);\n}\nfunction isrSet(key, data, revalidateSeconds, tags) {\n return __sharedIsrSet(key, data, revalidateSeconds, tags);\n}\nfunction triggerBackgroundRegeneration(key, renderFn) {\n return __sharedTriggerBackgroundRegeneration(key, renderFn);\n}\nfunction isrCacheKey(router, pathname) {\n return __sharedIsrCacheKey(router, pathname, buildId || undefined);\n}\n\nasync function renderToStringAsync(element) {\n const stream = await renderToReadableStream(element);\n await stream.allReady;\n return new Response(stream).text();\n}\n\nasync function renderIsrPassToStringAsync(element) {\n // The cache-fill render is a second render pass for the same request.\n // Reset render-scoped state so it cannot leak from the streamed response\n // render or affect async work that is still draining from that stream.\n // Keep request identity state (pathname/query/locale/executionContext)\n // intact: this second pass still belongs to the same request.\n return await runWithServerInsertedHTMLState(() =>\n runWithHeadState(() =>\n _runWithCacheState(() =>\n runWithPrivateCache(() => runWithFetchCache(async () => renderToStringAsync(element))),\n ),\n ),\n );\n}\n\n${pageImports.join(\"\\n\")}\n${apiImports.join(\"\\n\")}\n\n${appImportCode}\n${docImportCode}\n\nexport const pageRoutes = [\n${pageRouteEntries.join(\",\\n\")}\n];\nconst _pageRouteTrie = _buildRouteTrie(pageRoutes);\n\nconst apiRoutes = [\n${apiRouteEntries.join(\",\\n\")}\n];\nconst _apiRouteTrie = _buildRouteTrie(apiRoutes);\n\nfunction matchRoute(url, routes) {\n const pathname = url.split(\"?\")[0];\n let normalizedUrl = pathname === \"/\" ? \"/\" : pathname.replace(/\\\\/$/, \"\");\n // NOTE: Do NOT decodeURIComponent here. The pathname is already decoded at\n // the entry point. Decoding again would create a double-decode vector.\n const urlParts = normalizedUrl.split(\"/\").filter(Boolean);\n const trie = routes === pageRoutes ? _pageRouteTrie : _apiRouteTrie;\n return _trieMatch(trie, urlParts);\n}\n\nfunction parseQuery(url) {\n const qs = url.split(\"?\")[1];\n if (!qs) return {};\n const p = new URLSearchParams(qs);\n const q = {};\n for (const [k, v] of p) {\n if (k in q) {\n q[k] = Array.isArray(q[k]) ? q[k].concat(v) : [q[k], v];\n } else {\n q[k] = v;\n }\n }\n return q;\n}\n\nfunction patternToNextFormat(pattern) {\n return pattern\n .replace(/:([\\\\w]+)\\\\*/g, \"[[...$1]]\")\n .replace(/:([\\\\w]+)\\\\+/g, \"[...$1]\")\n .replace(/:([\\\\w]+)/g, \"[$1]\");\n}\n\nfunction collectAssetTags(manifest, moduleIds, scriptNonce) {\n // Fall back to embedded manifest (set by vinext:cloudflare-build for Workers)\n const m = (manifest && Object.keys(manifest).length > 0)\n ? manifest\n : (typeof globalThis !== \"undefined\" && globalThis.__VINEXT_SSR_MANIFEST__) || null;\n const tags = [];\n const seen = new Set();\n const nonceAttr = __createNonceAttribute(scriptNonce);\n\n // Load the set of lazy chunk filenames (only reachable via dynamic imports).\n // These should NOT get <link rel=\"modulepreload\"> or <script type=\"module\">\n // tags — they are fetched on demand when the dynamic import() executes (e.g.\n // chunks behind React.lazy() or next/dynamic boundaries).\n var lazyChunks = (typeof globalThis !== \"undefined\" && globalThis.__VINEXT_LAZY_CHUNKS__) || null;\n var lazySet = lazyChunks && lazyChunks.length > 0 ? new Set(lazyChunks) : null;\n\n // Inject the client entry script if embedded by vinext:cloudflare-build\n if (typeof globalThis !== \"undefined\" && globalThis.__VINEXT_CLIENT_ENTRY__) {\n const entry = globalThis.__VINEXT_CLIENT_ENTRY__;\n seen.add(entry);\n tags.push('<link rel=\"modulepreload\"' + nonceAttr + ' href=\"/' + entry + '\" />');\n tags.push('<script type=\"module\"' + nonceAttr + ' src=\"/' + entry + '\" crossorigin></script>');\n }\n if (m) {\n // Always inject shared chunks (framework, vinext runtime, entry) and\n // page-specific chunks. The manifest maps module file paths to their\n // associated JS/CSS assets.\n //\n // For page-specific injection, the module IDs may be absolute paths\n // while the manifest uses relative paths. Try both the original ID\n // and a suffix match to find the correct manifest entry.\n var allFiles = [];\n\n if (moduleIds && moduleIds.length > 0) {\n // Collect assets for the requested page modules\n for (var mi = 0; mi < moduleIds.length; mi++) {\n var id = moduleIds[mi];\n var files = m[id];\n if (!files) {\n // Absolute path didn't match — try matching by suffix.\n // Manifest keys are relative (e.g. \"pages/about.tsx\") while\n // moduleIds may be absolute (e.g. \"/home/.../pages/about.tsx\").\n for (var mk in m) {\n if (id.endsWith(\"/\" + mk) || id === mk) {\n files = m[mk];\n break;\n }\n }\n }\n if (files) {\n for (var fi = 0; fi < files.length; fi++) allFiles.push(files[fi]);\n }\n }\n\n // Also inject shared chunks that every page needs: framework,\n // vinext runtime, and the entry bootstrap. These are identified\n // by scanning all manifest values for chunk filenames containing\n // known prefixes.\n for (var key in m) {\n var vals = m[key];\n if (!vals) continue;\n for (var vi = 0; vi < vals.length; vi++) {\n var file = vals[vi];\n var basename = file.split(\"/\").pop() || \"\";\n if (\n basename.startsWith(\"framework-\") ||\n basename.startsWith(\"vinext-\") ||\n basename.includes(\"vinext-client-entry\") ||\n basename.includes(\"vinext-app-browser-entry\")\n ) {\n allFiles.push(file);\n }\n }\n }\n } else {\n // No specific modules — include all assets from manifest\n for (var akey in m) {\n var avals = m[akey];\n if (avals) {\n for (var ai = 0; ai < avals.length; ai++) allFiles.push(avals[ai]);\n }\n }\n }\n\n for (var ti = 0; ti < allFiles.length; ti++) {\n var tf = allFiles[ti];\n // Normalize: Vite's SSR manifest values include a leading '/'\n // (from base path), but we prepend '/' ourselves when building\n // href/src attributes. Strip any existing leading slash to avoid\n // producing protocol-relative URLs like \"//assets/chunk.js\".\n // This also ensures consistent keys for the seen-set dedup and\n // lazySet.has() checks (which use values without leading slash).\n if (tf.charAt(0) === '/') tf = tf.slice(1);\n if (seen.has(tf)) continue;\n seen.add(tf);\n if (tf.endsWith(\".css\")) {\n tags.push('<link rel=\"stylesheet\"' + nonceAttr + ' href=\"/' + tf + '\" />');\n } else if (tf.endsWith(\".js\")) {\n // Skip lazy chunks — they are behind dynamic import() boundaries\n // (React.lazy, next/dynamic) and should only be fetched on demand.\n if (lazySet && lazySet.has(tf)) continue;\n tags.push('<link rel=\"modulepreload\"' + nonceAttr + ' href=\"/' + tf + '\" />');\n tags.push('<script type=\"module\"' + nonceAttr + ' src=\"/' + tf + '\" crossorigin></script>');\n }\n }\n }\n return tags.join(\"\\\\n \");\n}\n\n// i18n helpers\nfunction extractLocale(url) {\n if (!i18nConfig) return { locale: undefined, url, hadPrefix: false };\n const pathname = url.split(\"?\")[0];\n const parts = pathname.split(\"/\").filter(Boolean);\n const query = url.includes(\"?\") ? url.slice(url.indexOf(\"?\")) : \"\";\n if (parts.length > 0 && i18nConfig.locales.includes(parts[0])) {\n const locale = parts[0];\n const rest = \"/\" + parts.slice(1).join(\"/\");\n return { locale, url: (rest || \"/\") + query, hadPrefix: true };\n }\n return { locale: i18nConfig.defaultLocale, url, hadPrefix: false };\n}\n\nfunction detectLocaleFromHeaders(headers) {\n if (!i18nConfig) return null;\n const acceptLang = headers.get(\"accept-language\");\n if (!acceptLang) return null;\n const langs = acceptLang.split(\",\").map(function(part) {\n const pieces = part.trim().split(\";\");\n const q = pieces[1] ? parseFloat(pieces[1].replace(\"q=\", \"\")) : 1;\n return { lang: pieces[0].trim().toLowerCase(), q: q };\n }).sort(function(a, b) { return b.q - a.q; });\n for (let k = 0; k < langs.length; k++) {\n const lang = langs[k].lang;\n for (let j = 0; j < i18nConfig.locales.length; j++) {\n if (i18nConfig.locales[j].toLowerCase() === lang) return i18nConfig.locales[j];\n }\n const prefix = lang.split(\"-\")[0];\n for (let j = 0; j < i18nConfig.locales.length; j++) {\n const loc = i18nConfig.locales[j].toLowerCase();\n if (loc === prefix || loc.startsWith(prefix + \"-\")) return i18nConfig.locales[j];\n }\n }\n return null;\n}\n\nfunction parseCookieLocaleFromHeader(cookieHeader) {\n if (!i18nConfig || !cookieHeader) return null;\n const match = cookieHeader.match(/(?:^|;\\\\s*)NEXT_LOCALE=([^;]*)/);\n if (!match) return null;\n var value;\n try { value = decodeURIComponent(match[1].trim()); } catch (e) { return null; }\n if (i18nConfig.locales.indexOf(value) !== -1) return value;\n return null;\n}\n\nexport async function renderPage(request, url, manifest, ctx, middlewareHeaders) {\n if (ctx) return _runWithExecutionContext(ctx, () => _renderPage(request, url, manifest, middlewareHeaders));\n return _renderPage(request, url, manifest, middlewareHeaders);\n}\n\nasync function _renderPage(request, url, manifest, middlewareHeaders) {\n const localeInfo = i18nConfig\n ? resolvePagesI18nRequest(\n url,\n i18nConfig,\n request.headers,\n new URL(request.url).hostname,\n vinextConfig.basePath,\n vinextConfig.trailingSlash,\n )\n : { locale: undefined, url, hadPrefix: false, domainLocale: undefined, redirectUrl: undefined };\n const locale = localeInfo.locale;\n const routeUrl = localeInfo.url;\n const currentDefaultLocale = i18nConfig\n ? (localeInfo.domainLocale ? localeInfo.domainLocale.defaultLocale : i18nConfig.defaultLocale)\n : undefined;\n const domainLocales = i18nConfig ? i18nConfig.domains : undefined;\n\n if (localeInfo.redirectUrl) {\n return new Response(null, { status: 307, headers: { Location: localeInfo.redirectUrl } });\n }\n\n const match = matchRoute(routeUrl, pageRoutes);\n if (!match) {\n return new Response(\"<!DOCTYPE html><html><body><h1>404 - Page not found</h1></body></html>\",\n { status: 404, headers: { \"Content-Type\": \"text/html\" } });\n }\n\n const { route, params } = match;\n const __uCtx = _createUnifiedCtx({\n executionContext: _getRequestExecutionContext(),\n });\n return _runWithUnifiedCtx(__uCtx, async () => {\n ensureFetchPatch();\n try {\n const routePattern = patternToNextFormat(route.pattern);\n if (typeof setSSRContext === \"function\") {\n setSSRContext({\n pathname: routePattern,\n query: { ...params, ...parseQuery(routeUrl) },\n asPath: routeUrl,\n locale: locale,\n locales: i18nConfig ? i18nConfig.locales : undefined,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n });\n }\n\n if (i18nConfig) {\n setI18nContext({\n locale: locale,\n locales: i18nConfig.locales,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n hostname: new URL(request.url).hostname,\n });\n }\n\n const pageModule = route.module;\n const PageComponent = pageModule.default;\n if (!PageComponent) {\n return new Response(\"Page has no default export\", { status: 500 });\n }\n const scriptNonce = __getScriptNonceFromHeaderSources(request.headers, middlewareHeaders);\n // Build font Link header early so it's available for ISR cached responses too.\n // Font preloads are module-level state populated at import time and persist across requests.\n var _fontLinkHeader = \"\";\n var _allFp = [];\n try {\n var _fpGoogle = typeof _getSSRFontPreloadsGoogle === \"function\" ? _getSSRFontPreloadsGoogle() : [];\n var _fpLocal = typeof _getSSRFontPreloadsLocal === \"function\" ? _getSSRFontPreloadsLocal() : [];\n _allFp = _fpGoogle.concat(_fpLocal);\n if (_allFp.length > 0) {\n _fontLinkHeader = _allFp.map(function(p) { return \"<\" + p.href + \">; rel=preload; as=font; type=\" + p.type + \"; crossorigin\"; }).join(\", \");\n }\n } catch (e) { /* font preloads not available */ }\n const query = parseQuery(routeUrl);\n const pageDataResult = await __resolvePagesPageData({\n applyRequestContexts() {\n if (typeof setSSRContext === \"function\") {\n setSSRContext({\n pathname: routePattern,\n query: { ...params, ...query },\n asPath: routeUrl,\n locale: locale,\n locales: i18nConfig ? i18nConfig.locales : undefined,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n });\n }\n if (i18nConfig) {\n setI18nContext({\n locale: locale,\n locales: i18nConfig.locales,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n hostname: new URL(request.url).hostname,\n });\n }\n },\n buildId,\n createGsspReqRes() {\n return __createPagesReqRes({ body: undefined, query, request, url: routeUrl });\n },\n createPageElement(currentPageProps) {\n var currentElement = AppComponent\n ? React.createElement(AppComponent, { Component: PageComponent, pageProps: currentPageProps })\n : React.createElement(PageComponent, currentPageProps);\n return wrapWithRouterContext(currentElement);\n },\n fontLinkHeader: _fontLinkHeader,\n i18n: {\n locale: locale,\n locales: i18nConfig ? i18nConfig.locales : undefined,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n },\n isrCacheKey,\n isrGet,\n isrSet,\n pageModule,\n params,\n query,\n renderIsrPassToStringAsync,\n route: {\n isDynamic: route.isDynamic,\n },\n routePattern,\n routeUrl,\n runInFreshUnifiedContext(callback) {\n var revalCtx = _createUnifiedCtx({\n executionContext: _getRequestExecutionContext(),\n });\n return _runWithUnifiedCtx(revalCtx, async () => {\n ensureFetchPatch();\n return callback();\n });\n },\n safeJsonStringify,\n sanitizeDestination: sanitizeDestinationLocal,\n scriptNonce,\n triggerBackgroundRegeneration,\n });\n if (pageDataResult.kind === \"response\") {\n return pageDataResult.response;\n }\n let pageProps = pageDataResult.pageProps;\n var gsspRes = pageDataResult.gsspRes;\n let isrRevalidateSeconds = pageDataResult.isrRevalidateSeconds;\n\n const pageModuleIds = route.filePath ? [route.filePath] : [];\n const assetTags = collectAssetTags(manifest, pageModuleIds, scriptNonce);\n\n return __renderPagesPageResponse({\n assetTags,\n buildId,\n clearSsrContext() {\n if (typeof setSSRContext === \"function\") setSSRContext(null);\n },\n createPageElement(currentPageProps) {\n var currentElement;\n if (AppComponent) {\n currentElement = React.createElement(AppComponent, { Component: PageComponent, pageProps: currentPageProps });\n } else {\n currentElement = React.createElement(PageComponent, currentPageProps);\n }\n return wrapWithRouterContext(currentElement);\n },\n DocumentComponent,\n flushPreloads: typeof flushPreloads === \"function\" ? flushPreloads : undefined,\n fontLinkHeader: _fontLinkHeader,\n fontPreloads: _allFp,\n getFontLinks() {\n try {\n return typeof _getSSRFontLinks === \"function\" ? _getSSRFontLinks() : [];\n } catch (e) {\n return [];\n }\n },\n getFontStyles() {\n try {\n var allFontStyles = [];\n if (typeof _getSSRFontStylesGoogle === \"function\") allFontStyles.push(..._getSSRFontStylesGoogle());\n if (typeof _getSSRFontStylesLocal === \"function\") allFontStyles.push(..._getSSRFontStylesLocal());\n return allFontStyles;\n } catch (e) {\n return [];\n }\n },\n getSSRHeadHTML: typeof getSSRHeadHTML === \"function\" ? getSSRHeadHTML : undefined,\n gsspRes,\n isrCacheKey,\n isrRevalidateSeconds,\n isrSet,\n i18n: {\n locale: locale,\n locales: i18nConfig ? i18nConfig.locales : undefined,\n defaultLocale: currentDefaultLocale,\n domainLocales: domainLocales,\n },\n pageProps,\n params,\n renderDocumentToString(element) {\n return renderToStringAsync(element);\n },\n renderIsrPassToStringAsync,\n renderToReadableStream(element) {\n return renderToReadableStream(element);\n },\n resetSSRHead: typeof resetSSRHead === \"function\" ? resetSSRHead : undefined,\n routePattern,\n routeUrl,\n safeJsonStringify,\n scriptNonce,\n });\n } catch (e) {\n console.error(\"[vinext] SSR error:\", e);\n _reportRequestError(\n e instanceof Error ? e : new Error(String(e)),\n { path: url, method: request.method, headers: Object.fromEntries(request.headers.entries()) },\n { routerKind: \"Pages Router\", routePath: route.pattern, routeType: \"render\" },\n ).catch(() => { /* ignore reporting errors */ });\n return new Response(\"Internal Server Error\", { status: 500 });\n }\n });\n}\n\nexport async function handleApiRoute(request, url) {\n const match = matchRoute(url, apiRoutes);\n return __handlePagesApiRoute({\n match,\n request,\n url,\n reportRequestError(error, routePattern) {\n console.error(\"[vinext] API error:\", error);\n void _reportRequestError(\n error,\n { path: url, method: request.method, headers: Object.fromEntries(request.headers.entries()) },\n { routerKind: \"Pages Router\", routePath: routePattern, routeType: \"route\" },\n );\n },\n });\n}\n\n${middlewareExportCode}\n`;\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -96,6 +96,9 @@ declare const clientOutputConfig: {
96
96
  * tryCatchDeoptimization: false, which can break specific libraries
97
97
  * that rely on property access side effects or try/catch for feature detection
98
98
  * - 'recommended' + 'no-external' gives most of the benefit with less risk
99
+ *
100
+ * @deprecated Use getClientTreeshakeConfigForVite(viteMajorVersion) instead
101
+ * for Vite version compatibility. Kept for backward compatibility.
99
102
  */
100
103
  declare const clientTreeshakeConfig: {
101
104
  preset: "recommended";
@@ -112,6 +115,33 @@ declare function getClientOutputConfigForVite(viteMajorVersion: number): {
112
115
  }[];
113
116
  };
114
117
  };
118
+ /**
119
+ * Returns treeshake configuration appropriate for the Vite version.
120
+ *
121
+ * Rollup (Vite 7) supports presets like "recommended" which set multiple
122
+ * treeshake options at once. Rolldown (Vite 8+) doesn't support presets,
123
+ * so we only return moduleSideEffects for Vite 8+.
124
+ *
125
+ * The Rollup "recommended" preset sets:
126
+ * - annotations: true (Rolldown default is also true)
127
+ * - manualPureFunctions: [] (Rolldown default is also [])
128
+ * - propertyReadSideEffects: true (Rolldown equivalent is 'always', the default)
129
+ * - unknownGlobalSideEffects: false (Rolldown default is true — this is a known acceptable
130
+ * divergence. Slightly less aggressive DCE on unknown globals, acceptable for client bundles)
131
+ * - correctVarValueBeforeDeclaration and tryCatchDeoptimization (Rolldown handles these differently)
132
+ *
133
+ * The key optimization is moduleSideEffects: "no-external", which is supported
134
+ * by both bundlers and provides the DCE benefits for barrel-exporting libraries.
135
+ * It treats node_modules as side-effect-free (enabling aggressive DCE) while
136
+ * preserving side effects in local code.
137
+ */
138
+ declare function getClientTreeshakeConfigForVite(viteMajorVersion: number): {
139
+ moduleSideEffects: "no-external";
140
+ preset?: undefined;
141
+ } | {
142
+ preset: "recommended";
143
+ moduleSideEffects: "no-external";
144
+ };
115
145
  type BundleBackfillChunk = {
116
146
  type: "chunk";
117
147
  fileName: string;
@@ -229,6 +259,7 @@ declare const _mdxScanCache: Map<string, boolean>;
229
259
  * Check if the project has .mdx files in app/ or pages/ directories.
230
260
  */
231
261
  declare function hasMdxFiles(root: string, appDir: string | null, pagesDir: string | null): boolean;
262
+ declare function scanPublicFileRoutes(root: string): string[];
232
263
  //#endregion
233
- export { type AppStaticExportOptions, type NextConfig, type StaticExportOptions, type StaticExportResult, VinextOptions, asyncHooksStubPlugin as _asyncHooksStubPlugin, augmentSsrManifestFromBundle as _augmentSsrManifestFromBundle, _findBalancedObject, _findCallEnd, hasMdxFiles as _hasMdxFiles, _mdxScanCache, parseStaticObjectLiteral as _parseStaticObjectLiteral, _postcssCache, resolvePostcssStringPlugins as _resolvePostcssStringPlugins, stripServerExports as _stripServerExports, clientManualChunks, clientOutputConfig, clientTreeshakeConfig, computeLazyChunks, vinext as default, getClientOutputConfigForVite, matchConfigPattern, staticExportApp, staticExportPages };
264
+ export { type AppStaticExportOptions, type NextConfig, type StaticExportOptions, type StaticExportResult, VinextOptions, asyncHooksStubPlugin as _asyncHooksStubPlugin, augmentSsrManifestFromBundle as _augmentSsrManifestFromBundle, _findBalancedObject, _findCallEnd, hasMdxFiles as _hasMdxFiles, _mdxScanCache, parseStaticObjectLiteral as _parseStaticObjectLiteral, _postcssCache, resolvePostcssStringPlugins as _resolvePostcssStringPlugins, scanPublicFileRoutes as _scanPublicFileRoutes, stripServerExports as _stripServerExports, clientManualChunks, clientOutputConfig, clientTreeshakeConfig, computeLazyChunks, vinext as default, getClientOutputConfigForVite, getClientTreeshakeConfigForVite, matchConfigPattern, staticExportApp, staticExportPages };
234
265
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -382,6 +382,9 @@ const clientCodeSplittingConfig = {
382
382
  * tryCatchDeoptimization: false, which can break specific libraries
383
383
  * that rely on property access side effects or try/catch for feature detection
384
384
  * - 'recommended' + 'no-external' gives most of the benefit with less risk
385
+ *
386
+ * @deprecated Use getClientTreeshakeConfigForVite(viteMajorVersion) instead
387
+ * for Vite version compatibility. Kept for backward compatibility.
385
388
  */
386
389
  const clientTreeshakeConfig = {
387
390
  preset: "recommended",
@@ -397,6 +400,33 @@ function withBuildBundlerOptions(viteMajorVersion, bundlerOptions) {
397
400
  function getClientOutputConfigForVite(viteMajorVersion) {
398
401
  return viteMajorVersion >= 8 ? { codeSplitting: clientCodeSplittingConfig } : clientOutputConfig;
399
402
  }
403
+ /**
404
+ * Returns treeshake configuration appropriate for the Vite version.
405
+ *
406
+ * Rollup (Vite 7) supports presets like "recommended" which set multiple
407
+ * treeshake options at once. Rolldown (Vite 8+) doesn't support presets,
408
+ * so we only return moduleSideEffects for Vite 8+.
409
+ *
410
+ * The Rollup "recommended" preset sets:
411
+ * - annotations: true (Rolldown default is also true)
412
+ * - manualPureFunctions: [] (Rolldown default is also [])
413
+ * - propertyReadSideEffects: true (Rolldown equivalent is 'always', the default)
414
+ * - unknownGlobalSideEffects: false (Rolldown default is true — this is a known acceptable
415
+ * divergence. Slightly less aggressive DCE on unknown globals, acceptable for client bundles)
416
+ * - correctVarValueBeforeDeclaration and tryCatchDeoptimization (Rolldown handles these differently)
417
+ *
418
+ * The key optimization is moduleSideEffects: "no-external", which is supported
419
+ * by both bundlers and provides the DCE benefits for barrel-exporting libraries.
420
+ * It treats node_modules as side-effect-free (enabling aggressive DCE) while
421
+ * preserving side effects in local code.
422
+ */
423
+ function getClientTreeshakeConfigForVite(viteMajorVersion) {
424
+ if (viteMajorVersion >= 8) return { moduleSideEffects: "no-external" };
425
+ return {
426
+ preset: "recommended",
427
+ moduleSideEffects: "no-external"
428
+ };
429
+ }
400
430
  function tryRealpathSync(candidate) {
401
431
  try {
402
432
  return fs.realpathSync.native(candidate);
@@ -726,11 +756,12 @@ function vinext(options = {}) {
726
756
  return (warning, defaultHandler) => {
727
757
  if (warning.code === "MODULE_LEVEL_DIRECTIVE" && (warning.message?.includes("\"use client\"") || warning.message?.includes("\"use server\""))) return;
728
758
  if (warning.code === "IMPORT_IS_UNDEFINED" && warning.message?.includes("generateStaticParams")) return;
759
+ if (warning.code === "IMPORT_IS_UNDEFINED" && /Import `(?:default|proxy|middleware)` will always be undefined/.test(warning.message ?? "") && /\b(?:proxy|middleware)\.\w+\b/.test(warning.message ?? "") && (warning.message?.includes("virtual:vinext-rsc-entry") || warning.message?.includes("virtual:vinext-server-entry"))) return;
729
760
  if (userOnwarn) userOnwarn(warning, defaultHandler);
730
761
  else defaultHandler(warning);
731
762
  };
732
763
  })(),
733
- ...!isSSR && !isMultiEnv ? { treeshake: clientTreeshakeConfig } : {},
764
+ ...!isSSR && !isMultiEnv ? { treeshake: getClientTreeshakeConfigForVite(viteMajorVersion) } : {},
734
765
  ...!isSSR && !isMultiEnv ? { output: getClientOutputConfigForVite(viteMajorVersion) } : {}
735
766
  }) },
736
767
  server: { cors: {
@@ -847,7 +878,7 @@ function vinext(options = {}) {
847
878
  ...withBuildBundlerOptions(viteMajorVersion, {
848
879
  input: { index: VIRTUAL_APP_BROWSER_ENTRY },
849
880
  output: getClientOutputConfigForVite(viteMajorVersion),
850
- treeshake: clientTreeshakeConfig
881
+ treeshake: getClientTreeshakeConfigForVite(viteMajorVersion)
851
882
  })
852
883
  }
853
884
  }
@@ -861,7 +892,7 @@ function vinext(options = {}) {
861
892
  ...withBuildBundlerOptions(viteMajorVersion, {
862
893
  input: { index: VIRTUAL_CLIENT_ENTRY },
863
894
  output: getClientOutputConfigForVite(viteMajorVersion),
864
- treeshake: clientTreeshakeConfig
895
+ treeshake: getClientTreeshakeConfigForVite(viteMajorVersion)
865
896
  })
866
897
  }
867
898
  } };
@@ -876,7 +907,7 @@ function vinext(options = {}) {
876
907
  ...withBuildBundlerOptions(viteMajorVersion, {
877
908
  input: { index: VIRTUAL_CLIENT_ENTRY },
878
909
  output: getClientOutputConfigForVite(viteMajorVersion),
879
- treeshake: clientTreeshakeConfig
910
+ treeshake: getClientTreeshakeConfigForVite(viteMajorVersion)
880
911
  })
881
912
  }
882
913
  },
@@ -957,7 +988,8 @@ function vinext(options = {}) {
957
988
  allowedDevOrigins: nextConfig?.allowedDevOrigins,
958
989
  bodySizeLimit: nextConfig?.serverActionsBodySizeLimit,
959
990
  i18n: nextConfig?.i18n,
960
- hasPagesDir
991
+ hasPagesDir,
992
+ publicFiles: scanPublicFileRoutes(root)
961
993
  }, instrumentationPath);
962
994
  }
963
995
  if (id === RESOLVED_APP_SSR_ENTRY && hasAppDir) return generateSsrEntry(hasPagesDir);
@@ -2042,7 +2074,50 @@ function scanDirForMdx(dir) {
2042
2074
  } catch {}
2043
2075
  return false;
2044
2076
  }
2077
+ function scanPublicFileRoutes(root) {
2078
+ const publicDir = path.join(root, "public");
2079
+ const routes = [];
2080
+ const visitedDirs = /* @__PURE__ */ new Set();
2081
+ function walk(dir) {
2082
+ let realDir;
2083
+ try {
2084
+ realDir = fs.realpathSync(dir);
2085
+ } catch {
2086
+ return;
2087
+ }
2088
+ if (visitedDirs.has(realDir)) return;
2089
+ visitedDirs.add(realDir);
2090
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
2091
+ for (const entry of entries) {
2092
+ const fullPath = path.join(dir, entry.name);
2093
+ if (entry.isDirectory()) {
2094
+ walk(fullPath);
2095
+ continue;
2096
+ }
2097
+ if (entry.isSymbolicLink()) {
2098
+ let stat;
2099
+ try {
2100
+ stat = fs.statSync(fullPath);
2101
+ } catch {
2102
+ continue;
2103
+ }
2104
+ if (stat.isDirectory()) {
2105
+ walk(fullPath);
2106
+ continue;
2107
+ }
2108
+ if (!stat.isFile()) continue;
2109
+ } else if (!entry.isFile()) continue;
2110
+ const relativePath = path.relative(publicDir, fullPath).split(path.sep).join("/");
2111
+ routes.push("/" + relativePath);
2112
+ }
2113
+ }
2114
+ if (fs.existsSync(publicDir)) try {
2115
+ walk(publicDir);
2116
+ } catch {}
2117
+ routes.sort();
2118
+ return routes;
2119
+ }
2045
2120
  //#endregion
2046
- export { asyncHooksStubPlugin as _asyncHooksStubPlugin, augmentSsrManifestFromBundle as _augmentSsrManifestFromBundle, _findBalancedObject, _findCallEnd, hasMdxFiles as _hasMdxFiles, _mdxScanCache, parseStaticObjectLiteral as _parseStaticObjectLiteral, _postcssCache, resolvePostcssStringPlugins as _resolvePostcssStringPlugins, stripServerExports as _stripServerExports, clientManualChunks, clientOutputConfig, clientTreeshakeConfig, computeLazyChunks, vinext as default, getClientOutputConfigForVite, matchConfigPattern, staticExportApp, staticExportPages };
2121
+ export { asyncHooksStubPlugin as _asyncHooksStubPlugin, augmentSsrManifestFromBundle as _augmentSsrManifestFromBundle, _findBalancedObject, _findCallEnd, hasMdxFiles as _hasMdxFiles, _mdxScanCache, parseStaticObjectLiteral as _parseStaticObjectLiteral, _postcssCache, resolvePostcssStringPlugins as _resolvePostcssStringPlugins, scanPublicFileRoutes as _scanPublicFileRoutes, stripServerExports as _stripServerExports, clientManualChunks, clientOutputConfig, clientTreeshakeConfig, computeLazyChunks, vinext as default, getClientOutputConfigForVite, getClientTreeshakeConfigForVite, matchConfigPattern, staticExportApp, staticExportPages };
2047
2122
 
2048
2123
  //# sourceMappingURL=index.js.map