vinext 0.2.1 → 1.0.0-beta.1

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 (236) hide show
  1. package/README.md +67 -30
  2. package/dist/build/assets-ignore.js +1 -1
  3. package/dist/build/clean-output.js +1 -1
  4. package/dist/build/client-build-config.d.ts +13 -92
  5. package/dist/build/client-build-config.js +23 -99
  6. package/dist/build/css-url-assets.js +3 -3
  7. package/dist/build/google-fonts/fallback-metrics.js +1 -1
  8. package/dist/build/google-fonts/font-metadata.js +1 -1
  9. package/dist/build/inject-pregenerated-paths.js +1 -1
  10. package/dist/build/inline-css.js +2 -5
  11. package/dist/build/module-dependency-cache.d.ts +4 -0
  12. package/dist/build/module-dependency-cache.js +13 -0
  13. package/dist/build/next-client-runtime-manifests.js +1 -1
  14. package/dist/build/pages-client-assets-module.js +1 -1
  15. package/dist/build/precompress.js +7 -7
  16. package/dist/build/prerender-paths.d.ts +23 -0
  17. package/dist/build/prerender-paths.js +291 -0
  18. package/dist/build/prerender-server-pool.js +2 -2
  19. package/dist/build/prerender.d.ts +12 -1
  20. package/dist/build/prerender.js +2 -2
  21. package/dist/build/preview-credentials.d.ts +11 -0
  22. package/dist/build/preview-credentials.js +19 -0
  23. package/dist/build/report.d.ts +0 -3
  24. package/dist/build/report.js +2 -4
  25. package/dist/build/run-prerender.d.ts +2 -11
  26. package/dist/build/run-prerender.js +2 -10
  27. package/dist/build/server-manifest.js +1 -1
  28. package/dist/build/ssr-manifest.d.ts +4 -0
  29. package/dist/build/ssr-manifest.js +10 -6
  30. package/dist/build/standalone.js +37 -37
  31. package/dist/cache/cache-adapters-virtual.d.ts +7 -17
  32. package/dist/cache/cache-adapters-virtual.js +35 -2
  33. package/dist/check.d.ts +0 -16
  34. package/dist/check.js +17 -34
  35. package/dist/cli.js +86 -101
  36. package/dist/client/instrumentation-client-inject.js +1 -1
  37. package/dist/client/pages-router-link-navigation.js +1 -1
  38. package/dist/config/config-matchers.js +2 -2
  39. package/dist/config/dotenv.js +1 -1
  40. package/dist/config/next-config.d.ts +4 -1
  41. package/dist/config/next-config.js +82 -16
  42. package/dist/config/prerender.d.ts +12 -2
  43. package/dist/config/prerender.js +22 -12
  44. package/dist/config/server-external-packages.js +1 -1
  45. package/dist/config/tsconfig-paths.js +7 -3
  46. package/dist/{node_modules/.pnpm/am-i-vibing@0.5.0/node_modules → deps/.pnpm/am-i-vibing@0.5.0/deps}/am-i-vibing/dist/detector-1yx2Hoe0.js +2 -2
  47. package/dist/deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js +50 -0
  48. package/dist/entries/app-rsc-entry.js +12 -5
  49. package/dist/entries/app-rsc-manifest.js +4 -4
  50. package/dist/entries/pages-client-entry.js +6 -5
  51. package/dist/entries/pages-server-entry.js +15 -26
  52. package/dist/entries/runtime-entry-module.js +2 -2
  53. package/dist/image/image-adapters-virtual.js +1 -0
  54. package/dist/index.d.ts +1 -1
  55. package/dist/index.js +500 -338
  56. package/dist/init-cloudflare.js +13 -4
  57. package/dist/init-platform.d.ts +10 -1
  58. package/dist/init-platform.js +79 -13
  59. package/dist/init.d.ts +11 -3
  60. package/dist/init.js +133 -35
  61. package/dist/plugins/ast-utils.js +1 -1
  62. package/dist/plugins/dynamic-preload-metadata.js +7 -7
  63. package/dist/plugins/extensionless-dynamic-import.js +1 -1
  64. package/dist/plugins/fonts.js +3 -3
  65. package/dist/plugins/ignore-dynamic-requests.js +13 -8
  66. package/dist/plugins/import-meta-url.js +16 -17
  67. package/dist/plugins/middleware-export-validation.js +1 -1
  68. package/dist/plugins/middleware-server-only.js +2 -2
  69. package/dist/plugins/og-asset-ownership.js +7 -6
  70. package/dist/plugins/og-assets.js +4 -5
  71. package/dist/plugins/optimize-imports.js +12 -13
  72. package/dist/plugins/postcss.js +1 -1
  73. package/dist/plugins/remove-console.js +1 -1
  74. package/dist/plugins/require-context.js +1 -1
  75. package/dist/plugins/sass.js +2 -2
  76. package/dist/plugins/server-externals-manifest.js +1 -1
  77. package/dist/plugins/strip-server-exports.js +1 -1
  78. package/dist/plugins/styled-jsx.js +3 -2
  79. package/dist/plugins/typeof-window.js +1 -1
  80. package/dist/routing/app-route-graph.d.ts +3 -10
  81. package/dist/routing/app-route-graph.js +28 -76
  82. package/dist/routing/app-router.d.ts +0 -5
  83. package/dist/routing/app-router.js +0 -5
  84. package/dist/routing/file-matcher.d.ts +2 -6
  85. package/dist/routing/file-matcher.js +10 -11
  86. package/dist/routing/pages-router.js +3 -3
  87. package/dist/server/api-handler.js +41 -33
  88. package/dist/server/app-browser-entry.js +15 -11
  89. package/dist/server/app-browser-navigation-controller.js +9 -4
  90. package/dist/server/app-browser-server-action-client.js +1 -1
  91. package/dist/server/app-elements-wire.d.ts +2 -1
  92. package/dist/server/app-fallback-renderer.d.ts +8 -0
  93. package/dist/server/app-fallback-renderer.js +13 -1
  94. package/dist/server/app-layout-param-observation.d.ts +1 -1
  95. package/dist/server/app-page-boundary-render.d.ts +14 -1
  96. package/dist/server/app-page-boundary-render.js +107 -54
  97. package/dist/server/app-page-cache-render.d.ts +1 -1
  98. package/dist/server/app-page-dispatch.d.ts +2 -1
  99. package/dist/server/app-page-dispatch.js +29 -40
  100. package/dist/server/app-page-element-builder.d.ts +2 -1
  101. package/dist/server/app-page-element-builder.js +3 -3
  102. package/dist/server/app-page-execution.d.ts +3 -1
  103. package/dist/server/app-page-execution.js +31 -39
  104. package/dist/server/app-page-render.d.ts +1 -1
  105. package/dist/server/app-page-request.js +1 -1
  106. package/dist/server/app-page-route-wiring.js +4 -4
  107. package/dist/server/app-route-handler-execution.d.ts +1 -1
  108. package/dist/server/app-route-tree-prefetch.js +1 -1
  109. package/dist/server/app-rsc-cache-busting.js +1 -2
  110. package/dist/server/app-rsc-handler.js +2 -2
  111. package/dist/server/app-rsc-redirect-flight.d.ts +66 -0
  112. package/dist/server/app-rsc-redirect-flight.js +71 -0
  113. package/dist/server/app-rsc-render-mode.d.ts +2 -5
  114. package/dist/server/app-rsc-render-mode.js +2 -12
  115. package/dist/server/app-segment-config.js +2 -2
  116. package/dist/server/app-server-action-execution.js +3 -3
  117. package/dist/server/app-ssr-entry.js +4 -1
  118. package/dist/server/app-ssr-stream.d.ts +2 -1
  119. package/dist/server/app-ssr-stream.js +4 -1
  120. package/dist/server/cache-proof.js +1 -1
  121. package/dist/server/default-global-error-module.d.ts +3 -1
  122. package/dist/server/default-not-found-module.d.ts +3 -1
  123. package/dist/server/dev-lockfile.js +2 -3
  124. package/dist/server/dev-module-runner.js +1 -1
  125. package/dist/server/dev-origin-check.d.ts +2 -2
  126. package/dist/server/dev-origin-check.js +2 -2
  127. package/dist/server/dev-route-files.js +1 -1
  128. package/dist/server/dev-server.js +256 -164
  129. package/dist/server/dev-stack-sourcemap.js +4 -3
  130. package/dist/server/headers.d.ts +3 -1
  131. package/dist/server/headers.js +3 -1
  132. package/dist/server/image-optimization.d.ts +12 -1
  133. package/dist/server/image-optimization.js +15 -3
  134. package/dist/server/implicit-tags.js +2 -1
  135. package/dist/server/instrumentation.js +2 -2
  136. package/dist/server/isr-cache.d.ts +12 -4
  137. package/dist/server/isr-cache.js +3 -3
  138. package/dist/server/metadata-routes.js +4 -4
  139. package/dist/server/middleware-response-headers.js +1 -1
  140. package/dist/server/middleware-runtime.js +1 -1
  141. package/dist/server/middleware.d.ts +1 -0
  142. package/dist/server/middleware.js +1 -1
  143. package/dist/server/navigation-planner.d.ts +2 -0
  144. package/dist/server/navigation-planner.js +8 -2
  145. package/dist/server/next-error-digest.d.ts +9 -24
  146. package/dist/server/next-error-digest.js +23 -15
  147. package/dist/server/operation-token.js +1 -1
  148. package/dist/server/pages-body-parser-config.js +2 -1
  149. package/dist/server/pages-dev-hydration.d.ts +14 -0
  150. package/dist/server/pages-dev-hydration.js +83 -0
  151. package/dist/server/pages-dev-module-url.js +2 -2
  152. package/dist/server/pages-node-compat.d.ts +13 -6
  153. package/dist/server/pages-node-compat.js +44 -45
  154. package/dist/server/pages-page-data.d.ts +1 -1
  155. package/dist/server/pages-page-data.js +5 -4
  156. package/dist/server/pages-page-handler.js +61 -29
  157. package/dist/server/pages-page-response.d.ts +2 -2
  158. package/dist/server/pages-page-response.js +2 -2
  159. package/dist/server/pages-preview.d.ts +26 -0
  160. package/dist/server/pages-preview.js +165 -0
  161. package/dist/server/pages-readiness.d.ts +2 -1
  162. package/dist/server/pages-readiness.js +4 -2
  163. package/dist/server/pages-request-pipeline.js +1 -1
  164. package/dist/server/prerender-manifest.d.ts +15 -1
  165. package/dist/server/prerender-manifest.js +29 -1
  166. package/dist/server/prod-server.d.ts +6 -5
  167. package/dist/server/prod-server.js +15 -15
  168. package/dist/server/request-pipeline.js +1 -1
  169. package/dist/server/seed-cache.js +1 -1
  170. package/dist/server/socket-error-backstop.js +1 -1
  171. package/dist/server/static-file-cache.js +8 -9
  172. package/dist/server/worker-utils.js +1 -1
  173. package/dist/shims/cache.d.ts +1 -1
  174. package/dist/shims/cache.js +2 -1
  175. package/dist/shims/cdn-cache.d.ts +2 -7
  176. package/dist/shims/cdn-cache.js +2 -14
  177. package/dist/shims/constants.js +1 -1
  178. package/dist/shims/error-boundary.d.ts +4 -4
  179. package/dist/shims/error.d.ts +21 -5
  180. package/dist/shims/error.js +52 -14
  181. package/dist/shims/fetch-cache.js +1 -1
  182. package/dist/shims/font-utils.js +1 -1
  183. package/dist/shims/form.d.ts +1 -1
  184. package/dist/shims/head.js +3 -3
  185. package/dist/shims/headers.js +6 -4
  186. package/dist/shims/internal/pages-data-fetch-dedup.js +5 -3
  187. package/dist/shims/layout-segment-context.d.ts +1 -1
  188. package/dist/shims/link.d.ts +3 -1
  189. package/dist/shims/link.js +6 -3
  190. package/dist/shims/navigation-errors.d.ts +2 -1
  191. package/dist/shims/navigation-errors.js +9 -13
  192. package/dist/shims/navigation.d.ts +1 -1
  193. package/dist/shims/navigation.js +5 -5
  194. package/dist/shims/request-state-types.d.ts +2 -2
  195. package/dist/shims/router-state.d.ts +1 -0
  196. package/dist/shims/router.d.ts +2 -1
  197. package/dist/shims/router.js +18 -11
  198. package/dist/shims/script.js +1 -1
  199. package/dist/shims/server.js +2 -2
  200. package/dist/shims/slot.d.ts +1 -1
  201. package/dist/shims/thenable-params.js +1 -1
  202. package/dist/shims/unified-request-context.d.ts +1 -1
  203. package/dist/typegen.js +9 -11
  204. package/dist/utils/client-build-manifest.js +2 -2
  205. package/dist/utils/client-entry-manifest.js +1 -1
  206. package/dist/utils/client-runtime-metadata.js +1 -1
  207. package/dist/utils/commonjs-loader.js +3 -3
  208. package/dist/utils/mdx-scan.js +1 -1
  209. package/dist/utils/path.d.ts +1 -13
  210. package/dist/utils/path.js +1 -15
  211. package/dist/utils/plugin-options.d.ts +4 -0
  212. package/dist/utils/plugin-options.js +8 -0
  213. package/dist/utils/project.d.ts +1 -7
  214. package/dist/utils/project.js +2 -8
  215. package/dist/utils/public-routes.js +2 -2
  216. package/dist/utils/react-version.js +1 -1
  217. package/dist/utils/redirect-digest.d.ts +9 -0
  218. package/dist/utils/redirect-digest.js +25 -0
  219. package/dist/utils/vinext-root.js +1 -1
  220. package/dist/utils/vite-version.d.ts +6 -13
  221. package/dist/utils/vite-version.js +68 -34
  222. package/package.json +33 -14
  223. package/dist/cloudflare/index.d.ts +0 -3
  224. package/dist/cloudflare/index.js +0 -3
  225. package/dist/packages/cloudflare/src/cache/cdn-adapter.runtime.js +0 -102
  226. package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +0 -126
  227. package/dist/packages/cloudflare/src/cache/kv-data-adapter.runtime.js +0 -442
  228. package/dist/packages/cloudflare/src/deploy-config.js +0 -150
  229. package/dist/packages/cloudflare/src/deploy-help.js +0 -55
  230. package/dist/packages/cloudflare/src/deploy.js +0 -272
  231. package/dist/packages/cloudflare/src/tpr.d.ts +0 -45
  232. package/dist/packages/cloudflare/src/tpr.js +0 -582
  233. package/dist/packages/cloudflare/src/utils/cache-control-metadata.js +0 -20
  234. /package/dist/build/google-fonts/{fallback-metrics-data.js → fallback-metrics-data.json.js} +0 -0
  235. /package/dist/build/google-fonts/{font-data.js → font-data.json.js} +0 -0
  236. /package/dist/{node_modules/.pnpm/process-ancestry@0.1.0/node_modules → deps/.pnpm/process-ancestry@0.1.0/deps}/process-ancestry/dist/index.js +0 -0
@@ -0,0 +1,13 @@
1
+ //#region src/build/module-dependency-cache.ts
2
+ function createModuleDependencyCache(collect) {
3
+ const cache = /* @__PURE__ */ new Map();
4
+ return function getModuleDependencies(moduleId) {
5
+ const cached = cache.get(moduleId);
6
+ if (cached) return cached;
7
+ const pending = collect(moduleId);
8
+ cache.set(moduleId, pending);
9
+ return pending;
10
+ };
11
+ }
12
+ //#endregion
13
+ export { createModuleDependencyCache };
@@ -1,5 +1,5 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import fs from "node:fs";
2
- import path from "node:path";
3
3
  //#region src/build/next-client-runtime-manifests.ts
4
4
  function normalizeRewriteForClientManifest(rewrite) {
5
5
  if (rewrite.destination.startsWith("/")) return {
@@ -1,5 +1,5 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import fs from "node:fs";
2
- import path from "node:path";
3
3
  //#region src/build/pages-client-assets-module.ts
4
4
  const PAGES_CLIENT_ASSETS_MODULE = "vinext-client-assets.js";
5
5
  const pagesClientAssetsByBuildSession = /* @__PURE__ */ new Map();
@@ -1,6 +1,6 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { ASSET_PREFIX_URL_DIR } from "../utils/asset-prefix.js";
2
- import path from "node:path";
3
- import fs from "node:fs/promises";
3
+ import fsp from "node:fs/promises";
4
4
  import os from "node:os";
5
5
  import zlib from "node:zlib";
6
6
  import { promisify } from "node:util";
@@ -20,7 +20,7 @@ const brotliCompress = promisify(zlib.brotliCompress);
20
20
  const gzip = promisify(zlib.gzip);
21
21
  const zstdCompress = typeof zlib.zstdCompress === "function" ? promisify(zlib.zstdCompress) : null;
22
22
  /** File extensions worth compressing (text-based, not already compressed). */
23
- const COMPRESSIBLE_EXTENSIONS = new Set([
23
+ const COMPRESSIBLE_EXTENSIONS = /* @__PURE__ */ new Set([
24
24
  ".js",
25
25
  ".mjs",
26
26
  ".css",
@@ -46,7 +46,7 @@ const CONCURRENCY = Math.min(os.availableParallelism(), 8);
46
46
  async function* walkFiles(dir, base = dir) {
47
47
  let entries;
48
48
  try {
49
- entries = await fs.readdir(dir, { withFileTypes: true });
49
+ entries = await fsp.readdir(dir, { withFileTypes: true });
50
50
  } catch {
51
51
  return;
52
52
  }
@@ -89,13 +89,13 @@ async function precompressAssets(clientDir, options = {}) {
89
89
  for (let i = 0; i < filePaths.length; i += CONCURRENCY) {
90
90
  const chunk = filePaths.slice(i, i + CONCURRENCY);
91
91
  await Promise.all(chunk.map(async (fullPath) => {
92
- const content = await fs.readFile(fullPath);
92
+ const content = await fsp.readFile(fullPath);
93
93
  if (content.length < MIN_SIZE) return;
94
94
  const compressions = [brotliCompress(content, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 5 } }), gzip(content, { level: 8 })];
95
95
  if (zstdCompress) compressions.push(zstdCompress(content, { params: { [zlib.constants.ZSTD_c_compressionLevel]: 8 } }));
96
96
  const [brContent, gzContent, zstdContent] = await Promise.all(compressions);
97
- const writes = [fs.writeFile(fullPath + ".br", brContent), fs.writeFile(fullPath + ".gz", gzContent)];
98
- if (zstdContent) writes.push(fs.writeFile(fullPath + ".zst", zstdContent));
97
+ const writes = [fsp.writeFile(fullPath + ".br", brContent), fsp.writeFile(fullPath + ".gz", gzContent)];
98
+ if (zstdContent) writes.push(fsp.writeFile(fullPath + ".zst", zstdContent));
99
99
  await Promise.all(writes);
100
100
  result.filesCompressed++;
101
101
  result.totalOriginalBytes += content.length;
@@ -0,0 +1,23 @@
1
+ import { ResolvedNextConfig } from "../config/next-config.js";
2
+ import { VinextRouteRootConfig } from "../config/prerender.js";
3
+
4
+ //#region src/build/prerender-paths.d.ts
5
+ type PrerenderPathManifest = {
6
+ buildId?: string;
7
+ trailingSlash?: boolean;
8
+ paths: string[];
9
+ };
10
+ declare const PRERENDER_PATH_DISCOVERY_ENV = "__VINEXT_PRERENDER_PATH_DISCOVERY";
11
+ declare const PRERENDER_PATHS_MANIFEST = "vinext-prerender-paths.json";
12
+ type EmitPrerenderPathManifestOptions = {
13
+ root: string; /** Fully resolved Next.js config. Loaded from disk when omitted. */
14
+ nextConfig?: ResolvedNextConfig;
15
+ appDir?: string | null;
16
+ pagesDir?: string | null;
17
+ routeRootConfig?: VinextRouteRootConfig | null;
18
+ pagesBundlePath?: string;
19
+ rscBundlePath?: string;
20
+ };
21
+ declare function emitPrerenderPathManifest(options: EmitPrerenderPathManifestOptions): Promise<PrerenderPathManifest | null>;
22
+ //#endregion
23
+ export { PRERENDER_PATHS_MANIFEST, PRERENDER_PATH_DISCOVERY_ENV, PrerenderPathManifest, emitPrerenderPathManifest };
@@ -0,0 +1,291 @@
1
+ import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { findDir } from "../utils/project.js";
3
+ import { apiRouter, pagesRouter } from "../routing/pages-router.js";
4
+ import { VINEXT_PRERENDER_SECRET_HEADER } from "../utils/protocol-headers.js";
5
+ import { classifyAppRoute, classifyPagesRoute, getAppRouteRenderEntryPath, hasNamedExport } from "./report.js";
6
+ import { appRouter } from "../routing/app-router.js";
7
+ import { normalizeStaticPathsEntry } from "../routing/route-pattern.js";
8
+ import { BLOCKED_PAGES, PHASE_PRODUCTION_BUILD } from "../shims/constants.js";
9
+ import { loadNextConfig, resolveNextConfig } from "../config/next-config.js";
10
+ import { readPrerenderSecret } from "./server-manifest.js";
11
+ import { startProdServer } from "../server/prod-server.js";
12
+ import { buildUrlFromParams, resolveParentParams } from "./prerender.js";
13
+ import fs from "node:fs";
14
+ //#region src/build/prerender-paths.ts
15
+ const PRERENDER_PATH_DISCOVERY_ENV = "__VINEXT_PRERENDER_PATH_DISCOVERY";
16
+ const PRERENDER_PATHS_MANIFEST = "vinext-prerender-paths.json";
17
+ const PATH_DISCOVERY_FETCH_TIMEOUT_MS = 3e4;
18
+ function readBuiltBuildId(serverDir) {
19
+ try {
20
+ const buildId = fs.readFileSync(path.join(serverDir, "BUILD_ID"), "utf-8").trim();
21
+ return buildId.length > 0 ? buildId : null;
22
+ } catch (error) {
23
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") return null;
24
+ throw error;
25
+ }
26
+ }
27
+ function addPath(paths, seen, pathname) {
28
+ if (seen.has(pathname)) return;
29
+ seen.add(pathname);
30
+ paths.push(pathname);
31
+ }
32
+ function warnDiscoveryFailure(route, error) {
33
+ const message = error instanceof Error ? error.message : String(error);
34
+ console.warn(`[vinext] Warning: failed to discover warmup path(s) for ${route}: ${message}`);
35
+ }
36
+ async function fetchDiscoveryEndpoint(url, headers) {
37
+ const controller = new AbortController();
38
+ const timeout = setTimeout(() => controller.abort(), PATH_DISCOVERY_FETCH_TIMEOUT_MS);
39
+ try {
40
+ const res = await fetch(url, {
41
+ headers,
42
+ signal: controller.signal
43
+ });
44
+ const text = await res.text();
45
+ if (!res.ok || text === "null") return null;
46
+ return text;
47
+ } catch (error) {
48
+ if (error instanceof Error && error.name === "AbortError") throw new Error(`path discovery timed out after ${PATH_DISCOVERY_FETCH_TIMEOUT_MS}ms`);
49
+ throw error;
50
+ } finally {
51
+ clearTimeout(timeout);
52
+ }
53
+ }
54
+ function fileHasNamedExport(filePath, name) {
55
+ if (!filePath) return false;
56
+ try {
57
+ return hasNamedExport(fs.readFileSync(filePath, "utf-8"), name);
58
+ } catch {
59
+ return false;
60
+ }
61
+ }
62
+ function resolveConfiguredRouteDirs(root, routeRootConfig) {
63
+ if (!routeRootConfig) return {
64
+ appDir: findDir(root, "app", "src/app"),
65
+ pagesDir: findDir(root, "pages", "src/pages")
66
+ };
67
+ let baseDir;
68
+ if (routeRootConfig.appDir) {
69
+ baseDir = path.isAbsolute(routeRootConfig.appDir) ? routeRootConfig.appDir : path.resolve(root, routeRootConfig.appDir);
70
+ baseDir = toSlash(baseDir);
71
+ } else {
72
+ const hasRootApp = fs.existsSync(path.join(root, "app"));
73
+ const hasRootPages = fs.existsSync(path.join(root, "pages"));
74
+ const hasSrcApp = fs.existsSync(path.join(root, "src", "app"));
75
+ const hasSrcPages = fs.existsSync(path.join(root, "src", "pages"));
76
+ baseDir = hasRootApp || hasRootPages ? root : hasSrcApp || hasSrcPages ? path.join(root, "src") : root;
77
+ }
78
+ const appDir = path.join(baseDir, "app");
79
+ const pagesDir = path.join(baseDir, "pages");
80
+ return {
81
+ appDir: !routeRootConfig.disableAppRouter && fs.existsSync(appDir) ? appDir : null,
82
+ pagesDir: fs.existsSync(pagesDir) ? pagesDir : null
83
+ };
84
+ }
85
+ function appRouteMayHaveGenerateStaticParams(route) {
86
+ if (fileHasNamedExport(route.pagePath, "generateStaticParams")) return true;
87
+ return route.layouts.some((layoutPath) => fileHasNamedExport(layoutPath, "generateStaticParams"));
88
+ }
89
+ async function shouldStartPathDiscoveryServer(options) {
90
+ if (options.appDir) {
91
+ if ((await appRouter(options.appDir, options.pageExtensions)).some((route) => route.isDynamic && appRouteMayHaveGenerateStaticParams(route))) return true;
92
+ }
93
+ if (options.pagesDir) {
94
+ if ((await pagesRouter(options.pagesDir, options.pageExtensions)).some((route) => route.isDynamic && fileHasNamedExport(route.filePath, "getStaticPaths"))) return true;
95
+ }
96
+ return false;
97
+ }
98
+ async function withPrerenderEndpoints(fn) {
99
+ const previousPrerenderFlag = process.env.VINEXT_PRERENDER;
100
+ const previousPathDiscoveryFlag = process.env[PRERENDER_PATH_DISCOVERY_ENV];
101
+ process.env.VINEXT_PRERENDER = "1";
102
+ process.env[PRERENDER_PATH_DISCOVERY_ENV] = "1";
103
+ try {
104
+ return await fn();
105
+ } finally {
106
+ if (previousPrerenderFlag === void 0) delete process.env.VINEXT_PRERENDER;
107
+ else process.env.VINEXT_PRERENDER = previousPrerenderFlag;
108
+ if (previousPathDiscoveryFlag === void 0) delete process.env[PRERENDER_PATH_DISCOVERY_ENV];
109
+ else process.env[PRERENDER_PATH_DISCOVERY_ENV] = previousPathDiscoveryFlag;
110
+ }
111
+ }
112
+ async function collectPagesPaths(options) {
113
+ const [pageRoutes, apiRoutes] = await Promise.all([pagesRouter(options.pagesDir, options.pageExtensions), apiRouter(options.pagesDir, options.pageExtensions)]);
114
+ const apiPatterns = new Set(apiRoutes.map((route) => route.pattern));
115
+ const paths = [];
116
+ const seen = /* @__PURE__ */ new Set();
117
+ for (const route of pageRoutes) {
118
+ if (apiPatterns.has(route.pattern)) continue;
119
+ if (BLOCKED_PAGES.includes(route.pattern)) continue;
120
+ if (route.pattern === "/404" || route.pattern === "/500" || route.pattern === "/_error") continue;
121
+ const { type } = classifyPagesRoute(route.filePath);
122
+ if (type === "api" || type === "ssr") continue;
123
+ if (!route.isDynamic) {
124
+ addPath(paths, seen, route.pattern);
125
+ continue;
126
+ }
127
+ if (!fileHasNamedExport(route.filePath, "getStaticPaths")) continue;
128
+ if (!options.baseUrl) continue;
129
+ try {
130
+ const search = new URLSearchParams({ pattern: route.pattern });
131
+ const text = await fetchDiscoveryEndpoint(`${options.baseUrl}/__vinext/prerender/pages-static-paths?${search}`, options.secretHeaders);
132
+ if (text === null) continue;
133
+ const pathsResult = JSON.parse(text);
134
+ for (const item of pathsResult.paths ?? []) {
135
+ const normalized = normalizeStaticPathsEntry(item, route.pattern);
136
+ if ("error" in normalized) throw new Error(normalized.error);
137
+ addPath(paths, seen, buildUrlFromParams(route.pattern, normalized.params));
138
+ }
139
+ } catch (error) {
140
+ warnDiscoveryFailure(route.pattern, error);
141
+ }
142
+ }
143
+ return paths;
144
+ }
145
+ async function collectAppPaths(options) {
146
+ const routes = await appRouter(options.appDir, options.pageExtensions);
147
+ const paths = [];
148
+ const seen = /* @__PURE__ */ new Set();
149
+ const staticParamsCache = /* @__PURE__ */ new Map();
150
+ const staticParamsMap = new Proxy({}, {
151
+ get(_target, pattern) {
152
+ return async ({ params }) => {
153
+ if (!options.baseUrl) return null;
154
+ const cacheKey = `${pattern}\0${JSON.stringify(params)}`;
155
+ const cached = staticParamsCache.get(cacheKey);
156
+ if (cached !== void 0) return cached;
157
+ const request = (async () => {
158
+ const search = new URLSearchParams({ pattern });
159
+ if (Object.keys(params).length > 0) search.set("parentParams", JSON.stringify(params));
160
+ const text = await fetchDiscoveryEndpoint(`${options.baseUrl}/__vinext/prerender/static-params?${search}`, options.secretHeaders);
161
+ if (text === null) return null;
162
+ return JSON.parse(text);
163
+ })();
164
+ request.catch(() => staticParamsCache.delete(cacheKey));
165
+ staticParamsCache.set(cacheKey, request);
166
+ return request;
167
+ };
168
+ },
169
+ has() {
170
+ return false;
171
+ }
172
+ });
173
+ for (const route of routes) {
174
+ const renderEntryPath = getAppRouteRenderEntryPath(route);
175
+ if (!renderEntryPath) continue;
176
+ const { type } = classifyAppRoute(renderEntryPath, route.routePath, route.isDynamic);
177
+ if (type === "api") continue;
178
+ if (type === "ssr" && !route.isDynamic) continue;
179
+ if (!route.isDynamic) {
180
+ addPath(paths, seen, route.pattern);
181
+ continue;
182
+ }
183
+ if (!appRouteMayHaveGenerateStaticParams(route)) continue;
184
+ try {
185
+ const generateStaticParams = staticParamsMap[route.pattern];
186
+ if (typeof generateStaticParams !== "function") continue;
187
+ const parentParamSets = await resolveParentParams(route, staticParamsMap);
188
+ let paramSets;
189
+ if (parentParamSets.length > 0) {
190
+ paramSets = [];
191
+ for (const parentParams of parentParamSets) {
192
+ const childResults = await generateStaticParams({ params: parentParams });
193
+ if (childResults === null) {
194
+ paramSets = null;
195
+ break;
196
+ }
197
+ if (Array.isArray(childResults)) for (const childParams of childResults) paramSets.push({
198
+ ...parentParams,
199
+ ...childParams
200
+ });
201
+ }
202
+ } else {
203
+ const results = await generateStaticParams({ params: {} });
204
+ paramSets = Array.isArray(results) || results === null ? results : [];
205
+ }
206
+ if (!paramSets?.length) continue;
207
+ for (const params of paramSets) {
208
+ if (params === null || params === void 0) continue;
209
+ addPath(paths, seen, buildUrlFromParams(route.pattern, params));
210
+ }
211
+ } catch (error) {
212
+ warnDiscoveryFailure(route.pattern, error);
213
+ }
214
+ }
215
+ return paths;
216
+ }
217
+ async function startPathDiscoveryServer(options) {
218
+ return startProdServer({
219
+ port: 0,
220
+ host: "127.0.0.1",
221
+ outDir: options.pagesBundlePath ? path.dirname(path.dirname(options.pagesBundlePath)) : path.dirname(options.serverDir),
222
+ rscEntryPath: options.rscBundlePath,
223
+ serverEntryPath: options.pagesBundlePath,
224
+ noCompression: true,
225
+ purpose: "prerender"
226
+ });
227
+ }
228
+ async function emitPrerenderPathManifest(options) {
229
+ const { root } = options;
230
+ const configuredRouteDirs = resolveConfiguredRouteDirs(root, options.routeRootConfig);
231
+ const appDir = options.appDir !== void 0 ? options.appDir : configuredRouteDirs.appDir;
232
+ const pagesDir = options.pagesDir !== void 0 ? options.pagesDir : configuredRouteDirs.pagesDir;
233
+ if (!appDir && !pagesDir) return null;
234
+ const defaultRscBundlePath = options.routeRootConfig?.rscOutDir ? path.join(path.resolve(root, options.routeRootConfig.rscOutDir), "index.js") : path.join(root, "dist", "server", "index.js");
235
+ const rscBundlePath = options.rscBundlePath ?? defaultRscBundlePath;
236
+ const pagesBundlePath = options.pagesBundlePath ?? path.join(root, "dist", "server", "entry.js");
237
+ const bundleServerDir = fs.existsSync(rscBundlePath) ? path.dirname(rscBundlePath) : path.dirname(pagesBundlePath);
238
+ const manifestDir = path.join(root, "dist", "server");
239
+ const config = options.nextConfig ? { ...options.nextConfig } : { ...await resolveNextConfig(await loadNextConfig(root, PHASE_PRODUCTION_BUILD), root) };
240
+ const builtBuildId = readBuiltBuildId(manifestDir) ?? readBuiltBuildId(bundleServerDir);
241
+ if (builtBuildId) config.buildId = builtBuildId;
242
+ const paths = [];
243
+ const seen = /* @__PURE__ */ new Set();
244
+ await withPrerenderEndpoints(async () => {
245
+ let prodServer = null;
246
+ if (await shouldStartPathDiscoveryServer({
247
+ appDir,
248
+ pagesDir,
249
+ pageExtensions: config.pageExtensions
250
+ })) try {
251
+ prodServer = await startPathDiscoveryServer({
252
+ serverDir: bundleServerDir,
253
+ pagesBundlePath: !appDir && pagesDir ? pagesBundlePath : void 0,
254
+ rscBundlePath: appDir ? rscBundlePath : void 0
255
+ });
256
+ } catch (error) {
257
+ const message = error instanceof Error ? error.message : String(error);
258
+ console.warn(`[vinext] Warning: failed to start prerender path discovery server: ${message}`);
259
+ }
260
+ const baseUrl = prodServer ? `http://127.0.0.1:${prodServer.port}` : null;
261
+ const prerenderSecret = readPrerenderSecret(bundleServerDir) ?? readPrerenderSecret(manifestDir);
262
+ const secretHeaders = prerenderSecret ? { [VINEXT_PRERENDER_SECRET_HEADER]: prerenderSecret } : {};
263
+ try {
264
+ if (appDir) for (const pathname of await collectAppPaths({
265
+ appDir,
266
+ baseUrl,
267
+ pageExtensions: config.pageExtensions,
268
+ secretHeaders
269
+ })) addPath(paths, seen, pathname);
270
+ if (pagesDir) for (const pathname of await collectPagesPaths({
271
+ baseUrl,
272
+ pagesDir,
273
+ pageExtensions: config.pageExtensions,
274
+ secretHeaders
275
+ })) addPath(paths, seen, pathname);
276
+ } finally {
277
+ if (prodServer) await new Promise((resolve) => prodServer.server.close(() => resolve()));
278
+ }
279
+ });
280
+ const manifest = {
281
+ buildId: config.buildId,
282
+ trailingSlash: config.trailingSlash,
283
+ paths
284
+ };
285
+ fs.mkdirSync(manifestDir, { recursive: true });
286
+ fs.writeFileSync(path.join(manifestDir, PRERENDER_PATHS_MANIFEST), JSON.stringify(manifest, null, 2) + "\n", "utf-8");
287
+ console.log(` Discovered ${paths.length} CDN warmup path(s).`);
288
+ return manifest;
289
+ }
290
+ //#endregion
291
+ export { PRERENDER_PATHS_MANIFEST, PRERENDER_PATH_DISCOVERY_ENV, emitPrerenderPathManifest };
@@ -1,5 +1,5 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import fs from "node:fs";
2
- import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import os from "node:os";
5
5
  import { fork } from "node:child_process";
@@ -50,7 +50,7 @@ const APPROX_BYTES_PER_WORKER = 768 * 1024 * 1024;
50
50
  const WORKER_READY_TIMEOUT_MS = 6e4;
51
51
  /** Best-effort close timeout so build cleanup is not blocked forever by a wedged child. */
52
52
  const WORKER_CLOSE_TIMEOUT_MS = 5e3;
53
- const PRERENDER_WORKER_TRANSPORT_ERROR_CODES = new Set([
53
+ const PRERENDER_WORKER_TRANSPORT_ERROR_CODES = /* @__PURE__ */ new Set([
54
54
  "ECONNREFUSED",
55
55
  "ECONNRESET",
56
56
  "EPIPE",
@@ -135,6 +135,17 @@ type PrerenderAppOptionsInternal = PrerenderAppOptions & {
135
135
  * all '<' and '>' in the embedded JSON, preventing false </script> matches.
136
136
  */
137
137
  declare function extractRscPayloadFromPrerenderedHtml(html: string): Uint8Array | null;
138
+ /**
139
+ * Build a URL path from a route pattern and params.
140
+ * "/posts/:id" + { id: "42" } → "/posts/42"
141
+ * "/docs/:slug+" + { slug: ["a", "b"] } → "/docs/a/b"
142
+ *
143
+ * Throws a descriptive error rather than a cryptic `Cannot read properties of
144
+ * undefined` if `params` itself is missing or required keys are absent — the
145
+ * caller (prerenderPages / prerenderApp) catches this and surfaces it as a
146
+ * per-route error result.
147
+ */
148
+ declare function buildUrlFromParams(pattern: string, params: Record<string, string | string[]> | undefined | null): string;
138
149
  /** Map of route patterns to generateStaticParams functions (or null/undefined). */
139
150
  type StaticParamsMap = Record<string, ((opts: {
140
151
  params: Record<string, string | string[]>;
@@ -207,4 +218,4 @@ declare function writePrerenderIndex(routes: PrerenderRouteResult[], outDir: str
207
218
  trailingSlash?: boolean;
208
219
  }): void;
209
220
  //#endregion
210
- export { PrerenderResult, PrerenderRouteResult, StaticParamsMap, extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
221
+ export { PrerenderResult, PrerenderRouteResult, StaticParamsMap, buildUrlFromParams, extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
@@ -1,3 +1,4 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { createValidFileMatcher, findFileWithExtensions } from "../routing/file-matcher.js";
2
3
  import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
3
4
  import { VINEXT_PRERENDER_CACHE_LIFE_HEADER } from "../server/headers.js";
@@ -17,7 +18,6 @@ import { getOutputPath, getRscOutputPath } from "../utils/prerender-output-paths
17
18
  import { startProdServer } from "../server/prod-server.js";
18
19
  import { prerenderPoolAvailable, resolvePrerenderPoolSize, startPrerenderServerPool } from "./prerender-server-pool.js";
19
20
  import fs from "node:fs";
20
- import path from "node:path";
21
21
  import os from "node:os";
22
22
  //#region src/build/prerender.ts
23
23
  /**
@@ -1000,4 +1000,4 @@ function writePrerenderIndex(routes, outDir, options) {
1000
1000
  fs.writeFileSync(path.join(outDir, "vinext-prerender.json"), JSON.stringify(index, null, 2), "utf-8");
1001
1001
  }
1002
1002
  //#endregion
1003
- export { extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
1003
+ export { buildUrlFromParams, extractRscPayloadFromPrerenderedHtml, prerenderApp, prerenderPages, readPrerenderSecret, resolveParentParams, writePrerenderIndex };
@@ -0,0 +1,11 @@
1
+ //#region src/build/preview-credentials.d.ts
2
+ type PreviewBuildCredentials = {
3
+ id: string;
4
+ signingKey: string;
5
+ encryptionKey: string;
6
+ };
7
+ declare function createPreviewBuildCredentials(): PreviewBuildCredentials;
8
+ declare function getPreviewBuildCredentials(): PreviewBuildCredentials | undefined;
9
+ declare function runWithPreviewBuildCredentials<T>(callback: () => T): T;
10
+ //#endregion
11
+ export { PreviewBuildCredentials, createPreviewBuildCredentials, getPreviewBuildCredentials, runWithPreviewBuildCredentials };
@@ -0,0 +1,19 @@
1
+ import { AsyncLocalStorage } from "node:async_hooks";
2
+ import { randomBytes } from "node:crypto";
3
+ //#region src/build/preview-credentials.ts
4
+ const previewBuildCredentialsStorage = new AsyncLocalStorage();
5
+ function createPreviewBuildCredentials() {
6
+ return {
7
+ id: randomBytes(16).toString("hex"),
8
+ signingKey: randomBytes(32).toString("hex"),
9
+ encryptionKey: randomBytes(32).toString("hex")
10
+ };
11
+ }
12
+ function getPreviewBuildCredentials() {
13
+ return previewBuildCredentialsStorage.getStore();
14
+ }
15
+ function runWithPreviewBuildCredentials(callback) {
16
+ return previewBuildCredentialsStorage.run(createPreviewBuildCredentials(), callback);
17
+ }
18
+ //#endregion
19
+ export { createPreviewBuildCredentials, getPreviewBuildCredentials, runWithPreviewBuildCredentials };
@@ -130,9 +130,6 @@ declare function formatBuildReport(rows: RouteRow[], routerLabel?: string): stri
130
130
  /**
131
131
  * Scans the project at `root`, classifies all routes, and prints the
132
132
  * Next.js-style build report to stdout.
133
- *
134
- * `root` must be forward-slash — it is passed to `findDir`. The caller (the
135
- * `vinext build` entry in cli.ts) normalizes it.
136
133
  */
137
134
  declare function printBuildReport(options: {
138
135
  root: string;
@@ -1,3 +1,4 @@
1
+ import { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { findDir } from "../utils/project.js";
2
3
  import fs from "node:fs";
3
4
  import { parseSync } from "vite";
@@ -415,7 +416,7 @@ function classifyLayoutSegmentConfig(code) {
415
416
  * API routes (files under pages/api/) are always `api`.
416
417
  */
417
418
  function classifyPagesRoute(filePath) {
418
- if (filePath.replace(/\\/g, "/").includes("/pages/api/")) return { type: "api" };
419
+ if (toSlash(filePath).includes("/pages/api/")) return { type: "api" };
419
420
  let code;
420
421
  try {
421
422
  code = fs.readFileSync(filePath, "utf8");
@@ -569,9 +570,6 @@ function formatBuildReport(rows, routerLabel = "app") {
569
570
  /**
570
571
  * Scans the project at `root`, classifies all routes, and prints the
571
572
  * Next.js-style build report to stdout.
572
- *
573
- * `root` must be forward-slash — it is passed to `findDir`. The caller (the
574
- * `vinext build` entry in cli.ts) normalizes it.
575
573
  */
576
574
  async function printBuildReport(options) {
577
575
  const { root } = options;
@@ -3,13 +3,8 @@ import { PrerenderResult, PrerenderRouteResult } from "./prerender.js";
3
3
 
4
4
  //#region src/build/run-prerender.d.ts
5
5
  type RunPrerenderOptions = {
6
- /** Project root directory. */root: string;
7
- /**
8
- * Override next.config values. Merged on top of the config loaded from disk.
9
- * Intended for tests that need to exercise a specific config (e.g. output: 'export')
10
- * without writing a next.config file.
11
- */
12
- nextConfigOverride?: Partial<ResolvedNextConfig>;
6
+ /** Project root directory. */root: string; /** Fully resolved Next.js config. Loaded from disk when omitted. */
7
+ nextConfig?: ResolvedNextConfig;
13
8
  /**
14
9
  * Override the path to the Pages Router server bundle.
15
10
  * Defaults to `<root>/dist/server/entry.js`.
@@ -58,10 +53,6 @@ type RunPrerenderOptions = {
58
53
  declare function assertNoFatalPrerenderRoutes(routes: readonly PrerenderRouteResult[]): void;
59
54
  /**
60
55
  * Statically generate routes and return the prerender result.
61
- *
62
- * `options.root` must be forward-slash — it is passed to `findDir` and flows
63
- * into the route model. The caller (the `vinext build` entry in cli.ts)
64
- * normalizes it.
65
56
  */
66
57
  declare function runPrerender(options: RunPrerenderOptions): Promise<PrerenderResult | null>;
67
58
  //#endregion
@@ -1,3 +1,4 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { findDir } from "../utils/project.js";
2
3
  import { apiRouter, pagesRouter } from "../routing/pages-router.js";
3
4
  import { appRouter } from "../routing/app-router.js";
@@ -8,7 +9,6 @@ import { rememberCurrentServerEntryImportMtime, startProdServer } from "../serve
8
9
  import { prerenderApp, prerenderPages, writePrerenderIndex } from "./prerender.js";
9
10
  import { injectPregeneratedConcretePaths } from "./inject-pregenerated-paths.js";
10
11
  import fs from "node:fs";
11
- import path from "node:path";
12
12
  //#region src/build/run-prerender.ts
13
13
  /**
14
14
  * Shared prerender runner used by both `vinext build` (cli.ts) and
@@ -98,10 +98,6 @@ function assertNoFatalPrerenderRoutes(routes) {
98
98
  }
99
99
  /**
100
100
  * Statically generate routes and return the prerender result.
101
- *
102
- * `options.root` must be forward-slash — it is passed to `findDir` and flows
103
- * into the route model. The caller (the `vinext build` entry in cli.ts)
104
- * normalizes it.
105
101
  */
106
102
  async function runPrerender(options) {
107
103
  const { root } = options;
@@ -113,11 +109,7 @@ async function runPrerender(options) {
113
109
  const manifestDir = path.join(root, "dist", "server");
114
110
  const rscBundlePath = options.rscBundlePath ?? path.join(root, "dist", "server", "index.js");
115
111
  const serverDir = path.dirname(rscBundlePath);
116
- const loadedConfig = await resolveNextConfig(await loadNextConfig(root), root);
117
- const config = options.nextConfigOverride ? {
118
- ...loadedConfig,
119
- ...options.nextConfigOverride
120
- } : { ...loadedConfig };
112
+ const config = options.nextConfig ? { ...options.nextConfig } : { ...await resolveNextConfig(await loadNextConfig(root), root) };
121
113
  const builtBuildId = readBuiltBuildId(serverDir);
122
114
  if (builtBuildId) config.buildId = builtBuildId;
123
115
  const mode = config.output === "export" ? "export" : "default";
@@ -1,5 +1,5 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { readJsonFile } from "../utils/safe-json-file.js";
2
- import path from "node:path";
3
3
  //#region src/build/server-manifest.ts
4
4
  /**
5
5
  * Shared utilities for reading/writing vinext-server.json.
@@ -9,6 +9,10 @@ type BundleBackfillChunk = {
9
9
  importedAssets?: Set<string>;
10
10
  };
11
11
  };
12
+ /**
13
+ * Realpath with NATIVE separators (backslashes on Windows). Callers apply
14
+ * `toSlash` where the result becomes a module id / manifest key.
15
+ */
12
16
  declare function tryRealpathSync(candidate: string): string | null;
13
17
  declare function relativeWithinRoot(root: string, moduleId: string): string | null;
14
18
  declare function augmentSsrManifestFromBundle(ssrManifest: Record<string, string[]>, bundle: Record<string, BundleBackfillChunk | {
@@ -1,7 +1,11 @@
1
+ import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { collapseDuplicateBase, manifestFileWithBase } from "../utils/manifest-paths.js";
2
3
  import fs from "node:fs";
3
- import path from "node:path";
4
4
  //#region src/build/ssr-manifest.ts
5
+ /**
6
+ * Realpath with NATIVE separators (backslashes on Windows). Callers apply
7
+ * `toSlash` where the result becomes a module id / manifest key.
8
+ */
5
9
  function tryRealpathSync(candidate) {
6
10
  try {
7
11
  return fs.realpathSync.native(candidate);
@@ -13,26 +17,26 @@ function isWindowsAbsolutePath(candidate) {
13
17
  return /^[a-zA-Z]:[\\/]/.test(candidate) || candidate.startsWith("\\\\");
14
18
  }
15
19
  function relativeWithinRoot(root, moduleId) {
16
- const relativeId = (isWindowsAbsolutePath(root) || isWindowsAbsolutePath(moduleId) ? path.win32.relative(root, moduleId) : path.relative(root, moduleId)).replace(/\\/g, "/");
20
+ const relativeId = isWindowsAbsolutePath(root) || isWindowsAbsolutePath(moduleId) ? path.win32.relative(root, moduleId) : path.relative(root, moduleId);
17
21
  if (!relativeId || relativeId === ".." || relativeId.startsWith("../")) return null;
18
22
  return relativeId;
19
23
  }
20
24
  function normalizeManifestModuleId(moduleId, root) {
21
- const normalizedId = moduleId.replace(/\\/g, "/");
25
+ const normalizedId = toSlash(moduleId);
22
26
  if (normalizedId.startsWith("\0")) return normalizedId;
23
27
  if (normalizedId.startsWith("node_modules/") || normalizedId.includes("/node_modules/")) return normalizedId;
24
28
  if (!isWindowsAbsolutePath(moduleId) && !path.isAbsolute(moduleId)) {
25
29
  if (!normalizedId.startsWith(".") && !normalizedId.includes("../")) return normalizedId;
26
30
  }
27
- const rootCandidates = new Set([root]);
31
+ const rootCandidates = /* @__PURE__ */ new Set([root]);
28
32
  const realRoot = tryRealpathSync(root);
29
- if (realRoot) rootCandidates.add(realRoot);
33
+ if (realRoot) rootCandidates.add(toSlash(realRoot));
30
34
  const moduleCandidates = /* @__PURE__ */ new Set();
31
35
  if (isWindowsAbsolutePath(moduleId) || path.isAbsolute(moduleId)) moduleCandidates.add(moduleId);
32
36
  else moduleCandidates.add(path.resolve(root, moduleId));
33
37
  for (const candidate of moduleCandidates) {
34
38
  const realCandidate = tryRealpathSync(candidate);
35
- if (realCandidate) moduleCandidates.add(realCandidate);
39
+ if (realCandidate) moduleCandidates.add(toSlash(realCandidate));
36
40
  }
37
41
  for (const rootCandidate of rootCandidates) for (const moduleCandidate of moduleCandidates) {
38
42
  const relativeId = relativeWithinRoot(rootCandidate, moduleCandidate);