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
@@ -1,3 +1,4 @@
1
+ import { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { VINEXT_ORIGINAL_STACK_TRACE_ENDPOINT } from "../utils/dev-stack-sourcemap-endpoint.js";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import { fileURLToPath, pathToFileURL } from "node:url";
@@ -184,7 +185,7 @@ function extractV8ParenMethodName(prefix) {
184
185
  }
185
186
  function normalizeProjectRoot(root) {
186
187
  if (!root) return void 0;
187
- return root.replaceAll("\\", "/").replace(/\/+$/, "") || (root.startsWith("/") ? "/" : void 0);
188
+ return toSlash(root).replace(/\/+$/, "") || (root.startsWith("/") ? "/" : void 0);
188
189
  }
189
190
  function stripTrailingSlash(value) {
190
191
  return value?.replace(/[\\/]+$/, "");
@@ -240,7 +241,7 @@ function isWindowsAbsolutePath(value) {
240
241
  return /^[A-Za-z]:[\\/]/.test(value);
241
242
  }
242
243
  function normalizeLocalPathForCompare(value) {
243
- const normalized = (stripTrailingSlash(value.replaceAll("\\", "/")) ?? "").replace(/\/+/g, "/");
244
+ const normalized = (stripTrailingSlash(toSlash(value)) ?? "").replace(/\/+/g, "/");
244
245
  return /^[A-Za-z]:\//.test(normalized) ? normalized.toLowerCase() : normalized;
245
246
  }
246
247
  function normalizeIgnoreListPath(value) {
@@ -255,7 +256,7 @@ function normalizeIgnoreListPath(value) {
255
256
  try {
256
257
  path = decodeURIComponent(path);
257
258
  } catch {}
258
- return path.replaceAll("\\", "/").toLowerCase();
259
+ return toSlash(path).toLowerCase();
259
260
  }
260
261
  function isExternalHttpFrame(file, requestHost) {
261
262
  if (!/^https?:\/\//i.test(file) || !requestHost) return false;
@@ -56,6 +56,8 @@ declare const VINEXT_CLIENT_REUSE_MANIFEST_HEADER = "X-Vinext-Client-Reuse-Manif
56
56
  * cheap way to detect the redirect ahead of stream decode.
57
57
  */
58
58
  declare const VINEXT_RSC_REDIRECT_HEADER = "X-Vinext-Rsc-Redirect";
59
+ /** History update mode encoded by a streamed RSC redirect. */
60
+ declare const VINEXT_RSC_REDIRECT_TYPE_HEADER = "X-Vinext-Rsc-Redirect-Type";
59
61
  /** Standard RSC header — value "1" indicates an RSC payload request. */
60
62
  declare const RSC_HEADER = "RSC";
61
63
  /** Server Action invocation header (vinext/vite-rsc protocol). */
@@ -105,4 +107,4 @@ declare const INTERNAL_HEADERS: string[];
105
107
  /** Vinext-only internal headers stripped alongside Next.js protocol internals. */
106
108
  declare const VINEXT_INTERNAL_HEADERS: string[];
107
109
  //#endregion
108
- export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, MIDDLEWARE_SKIP_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_CACHE_LIFE_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
110
+ export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, MIDDLEWARE_SKIP_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_CACHE_LIFE_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_REDIRECT_TYPE_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
@@ -55,6 +55,8 @@ const VINEXT_CLIENT_REUSE_MANIFEST_HEADER = "X-Vinext-Client-Reuse-Manifest";
55
55
  * cheap way to detect the redirect ahead of stream decode.
56
56
  */
57
57
  const VINEXT_RSC_REDIRECT_HEADER = "X-Vinext-Rsc-Redirect";
58
+ /** History update mode encoded by a streamed RSC redirect. */
59
+ const VINEXT_RSC_REDIRECT_TYPE_HEADER = "X-Vinext-Rsc-Redirect-Type";
58
60
  /** Standard RSC header — value "1" indicates an RSC payload request. */
59
61
  const RSC_HEADER = "RSC";
60
62
  /** Server Action invocation header (vinext/vite-rsc protocol). */
@@ -128,4 +130,4 @@ const VINEXT_INTERNAL_HEADERS = [
128
130
  VINEXT_PRERENDER_CACHE_LIFE_HEADER
129
131
  ];
130
132
  //#endregion
131
- export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, MIDDLEWARE_SKIP_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_CACHE_LIFE_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
133
+ export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, MIDDLEWARE_SKIP_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_HTML_REQUEST_ID_HEADER, NEXT_REQUEST_ID_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_CACHE_LIFE_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_REDIRECT_TYPE_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
@@ -26,7 +26,18 @@ declare const IMAGE_OPTIMIZATION_PATH = "/_next/image";
26
26
  * for any newly generated URLs.
27
27
  */
28
28
  declare const VINEXT_IMAGE_OPTIMIZATION_PATH = "/_vinext/image";
29
- /** Returns true when `pathname` is either supported image optimization endpoint. */
29
+ /**
30
+ * Returns true when `pathname` is either supported image optimization
31
+ * endpoint.
32
+ *
33
+ * A single trailing slash is accepted (`/_next/image/`): with
34
+ * `trailingSlash: true`, Next.js 308-redirects `/_next/image?url=...` to
35
+ * `/_next/image/?url=...` and then serves the slashed form — its route
36
+ * matching strips a trailing slash before matching internal paths (see
37
+ * getItem in packages/next/src/server/lib/router-utils/filesystem.ts).
38
+ * Rejecting the slashed form 404'd every dev-mode next/image request under
39
+ * `trailingSlash: true`.
40
+ */
30
41
  declare function isImageOptimizationPath(pathname: string): boolean;
31
42
  /**
32
43
  * Image security configuration from next.config.js `images` section.
@@ -27,8 +27,20 @@ const IMAGE_OPTIMIZATION_PATH = "/_next/image";
27
27
  * for any newly generated URLs.
28
28
  */
29
29
  const VINEXT_IMAGE_OPTIMIZATION_PATH = "/_vinext/image";
30
- /** Returns true when `pathname` is either supported image optimization endpoint. */
30
+ /**
31
+ * Returns true when `pathname` is either supported image optimization
32
+ * endpoint.
33
+ *
34
+ * A single trailing slash is accepted (`/_next/image/`): with
35
+ * `trailingSlash: true`, Next.js 308-redirects `/_next/image?url=...` to
36
+ * `/_next/image/?url=...` and then serves the slashed form — its route
37
+ * matching strips a trailing slash before matching internal paths (see
38
+ * getItem in packages/next/src/server/lib/router-utils/filesystem.ts).
39
+ * Rejecting the slashed form 404'd every dev-mode next/image request under
40
+ * `trailingSlash: true`.
41
+ */
31
42
  function isImageOptimizationPath(pathname) {
43
+ if (pathname.length > 1 && pathname.endsWith("/")) pathname = pathname.slice(0, -1);
32
44
  return pathname === "/_next/image" || pathname === "/_vinext/image";
33
45
  }
34
46
  /**
@@ -75,7 +87,7 @@ function resolveDevImageRedirect(requestUrl, allowedWidths = [...DEFAULT_DEVICE_
75
87
  * https://github.com/vercel/next.js/blob/canary/test/integration/image-optimizer/test/index.test.ts
76
88
  */
77
89
  function parseImageParams(url, allowedWidths = [...DEFAULT_DEVICE_SIZES, ...DEFAULT_IMAGE_SIZES], allowedQualities, options = {}) {
78
- const allowedParamNames = new Set([
90
+ const allowedParamNames = /* @__PURE__ */ new Set([
79
91
  "url",
80
92
  "w",
81
93
  "q",
@@ -138,7 +150,7 @@ const IMAGE_CONTENT_SECURITY_POLICY = "script-src 'none'; frame-src 'none'; sand
138
150
  * SVG is intentionally excluded — it can contain embedded JavaScript and is
139
151
  * essentially an XML document, not a safe raster image format.
140
152
  */
141
- const SAFE_IMAGE_CONTENT_TYPES = new Set([
153
+ const SAFE_IMAGE_CONTENT_TYPES = /* @__PURE__ */ new Set([
142
154
  "image/jpeg",
143
155
  "image/png",
144
156
  "image/gif",
@@ -33,7 +33,8 @@ function buildAppPageTags(cleanPathname, extraTags, routeSegments) {
33
33
  return buildPageCacheTags(cleanPathname, extraTags, [...routeSegments], "page");
34
34
  }
35
35
  function buildPageCacheTags(pathname, extraTags, routeSegments, leafKind) {
36
- const tags = [pathname, `${NEXT_CACHE_IMPLICIT_TAG_ID}${pathname.length > 1 && pathname.endsWith("/") ? pathname.slice(0, -1) : pathname}`];
36
+ const normalizedPathname = pathname.length > 1 && pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
37
+ const tags = [pathname, `${NEXT_CACHE_IMPLICIT_TAG_ID}${normalizedPathname}`];
37
38
  if (pathname === "/") appendUnique(tags, `${NEXT_CACHE_IMPLICIT_TAG_ID}/index`);
38
39
  if (pathname === "/index") appendUnique(tags, `${NEXT_CACHE_IMPLICIT_TAG_ID}/`);
39
40
  appendDerivedTags(tags, buildRouteCachePath(routeSegments, leafKind));
@@ -1,6 +1,6 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { getRequestExecutionContext } from "../shims/request-context.js";
2
3
  import fs from "node:fs";
3
- import path from "node:path";
4
4
  //#region src/server/instrumentation.ts
5
5
  /**
6
6
  * instrumentation.ts support
@@ -51,7 +51,7 @@ async function importModule(runner, id) {
51
51
  const INSTRUMENTATION_LOCATIONS = ["", "src/"];
52
52
  function findInstrumentationHookFile(root, basename, fileMatcher) {
53
53
  for (const dir of INSTRUMENTATION_LOCATIONS) for (const ext of fileMatcher.dottedExtensions) {
54
- const fullPath = path.posix.join(root, dir, `${basename}${ext}`);
54
+ const fullPath = path.join(root, dir, `${basename}${ext}`);
55
55
  if (fs.existsSync(fullPath)) return fullPath;
56
56
  }
57
57
  return null;
@@ -1,7 +1,7 @@
1
- import { RenderObservation } from "./cache-proof.js";
2
- import { CacheHandlerValue, CachedAppPageValue, CachedPagesValue, IncrementalCacheValue } from "../shims/cache-handler.js";
3
1
  import { OnRequestErrorContext } from "./instrumentation.js";
2
+ import { RenderObservation } from "./cache-proof.js";
4
3
  import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
4
+ import { CacheHandlerValue, CachedAppPageValue, CachedPagesValue, IncrementalCacheValue } from "../shims/cache-handler.js";
5
5
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
6
6
 
7
7
  //#region src/server/isr-cache.d.ts
@@ -102,13 +102,21 @@ declare function buildAppPageCacheValue(html: string, rscData?: ArrayBuffer, sta
102
102
  * Long pathnames are hashed to stay within KV key-length limits (512 bytes).
103
103
  */
104
104
  declare function isrCacheKey(router: string, pathname: string, buildId?: string): string;
105
+ /**
106
+ * Compute an App Router ISR key for one cache artifact.
107
+ *
108
+ * App pages store HTML, RSC payloads, and route-handler responses separately.
109
+ * The suffix mirrors Next.js's separate on-disk app artifacts while keeping the
110
+ * Cloudflare KV key under its 512-byte limit for long pathnames.
111
+ */
112
+ declare function appIsrCacheKey(pathname: string, suffix: string, buildId?: string | undefined): string;
105
113
  declare function appIsrHtmlKey(pathname: string): string;
106
114
  /**
107
115
  * Build the ISR cache key for an RSC payload.
108
116
  *
109
117
  * Variants are sequenced in order: `source:<hash>` (intercepted source context,
110
118
  * only when an interception context is present), `slots:<hash>` (mounted parallel
111
- * route slots), and optionally `<render-mode-variant>` (e.g. `preserve-ui` or
119
+ * route slots), and optionally `<render-mode-variant>` (for example,
112
120
  * `prefetch-loading-shell`). Existing cached entries under the old format will
113
121
  * become unreachable after deployment. This is acceptable because ISR entries
114
122
  * have TTLs and will be regenerated on the next request.
@@ -125,4 +133,4 @@ declare function setRevalidateDuration(key: string, seconds: number): void;
125
133
  */
126
134
  declare function getRevalidateDuration(key: string): number | undefined;
127
135
  //#endregion
128
- export { ISRCacheEntry, PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, getRevalidateSecret, isOnDemandRevalidateRequest, isRevalidateSecret, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
136
+ export { ISRCacheEntry, PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, appIsrCacheKey, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, getRevalidateSecret, isOnDemandRevalidateRequest, isRevalidateSecret, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
@@ -62,7 +62,7 @@ function getRevalidateSecret() {
62
62
  const baked = process.env.__VINEXT_REVALIDATE_SECRET;
63
63
  if (baked) return baked;
64
64
  if (devRevalidateSecret === void 0) {
65
- const bytes = new Uint8Array(32);
65
+ const bytes = /* @__PURE__ */ new Uint8Array(32);
66
66
  crypto.getRandomValues(bytes);
67
67
  devRevalidateSecret = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
68
68
  }
@@ -242,7 +242,7 @@ function normalizeInterceptionContextForCacheKey(interceptionContext) {
242
242
  *
243
243
  * Variants are sequenced in order: `source:<hash>` (intercepted source context,
244
244
  * only when an interception context is present), `slots:<hash>` (mounted parallel
245
- * route slots), and optionally `<render-mode-variant>` (e.g. `preserve-ui` or
245
+ * route slots), and optionally `<render-mode-variant>` (for example,
246
246
  * `prefetch-loading-shell`). Existing cached entries under the old format will
247
247
  * become unreachable after deployment. This is acceptable because ISR entries
248
248
  * have TTLs and will be regenerated on the next request.
@@ -283,4 +283,4 @@ function getRevalidateDuration(key) {
283
283
  return revalidateDurations.get(key);
284
284
  }
285
285
  //#endregion
286
- export { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, getRevalidateSecret, isOnDemandRevalidateRequest, isRevalidateSecret, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
286
+ export { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, appIsrCacheKey, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, getRevalidateSecret, isOnDemandRevalidateRequest, isRevalidateSecret, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
@@ -1,6 +1,6 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { matchRoutePattern } from "../routing/route-pattern.js";
2
3
  import fs from "node:fs";
3
- import path from "node:path";
4
4
  //#region src/server/metadata-routes.ts
5
5
  /**
6
6
  * File-based metadata route handling.
@@ -292,7 +292,7 @@ function computeMetadataRouteSuffix(appDirPath, leafName) {
292
292
  };
293
293
  }
294
294
  function getMetadataRouteFilename(appDirPath, lastSegment) {
295
- const ext = path.posix.extname(lastSegment);
295
+ const ext = path.extname(lastSegment);
296
296
  const name = lastSegment.slice(0, -ext.length || void 0);
297
297
  const { suffix } = computeMetadataRouteSuffix(appDirPath, name);
298
298
  return `${name}${suffix ? `-${suffix}` : ""}${ext}`;
@@ -339,8 +339,8 @@ function metadataRouteSuffix(parentSegments, metaType) {
339
339
  }
340
340
  function withMetadataSuffix(urlPath, suffix) {
341
341
  if (!suffix) return urlPath;
342
- const parsed = path.posix.parse(urlPath);
343
- return path.posix.join(parsed.dir || "/", `${parsed.name}-${suffix}${parsed.ext}`);
342
+ const parsed = path.parse(urlPath);
343
+ return path.join(parsed.dir || "/", `${parsed.name}-${suffix}${parsed.ext}`);
344
344
  }
345
345
  function getMetadataServedUrl(metaType, config, ext, isDynamic, suffix, routeBaseName) {
346
346
  if (isDynamic && (metaType === "icon" || metaType === "apple-icon" || metaType === "opengraph-image" || metaType === "twitter-image")) return withMetadataSuffix(`/${routeBaseName}`, suffix);
@@ -1,5 +1,5 @@
1
1
  //#region src/server/middleware-response-headers.ts
2
- const ADDITIVE_RESPONSE_HEADER_NAMES = new Set(["set-cookie", "vary"]);
2
+ const ADDITIVE_RESPONSE_HEADER_NAMES = /* @__PURE__ */ new Set(["set-cookie", "vary"]);
3
3
  function mergeVaryHeader(target, value) {
4
4
  const existing = target.get("Vary");
5
5
  const tokens = (existing ? `${existing}, ${value}` : value).split(",").map((token) => token.trim()).filter((token) => token.length > 0);
@@ -1,3 +1,4 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
2
3
  import { addBasePathToPathname, hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
3
4
  import "./server-globals.js";
@@ -10,7 +11,6 @@ import { normalizePath } from "./normalize-path.js";
10
11
  import { matchesMiddleware } from "./middleware-matcher.js";
11
12
  import { badRequestResponse, internalServerErrorResponse } from "./http-error-responses.js";
12
13
  import { processMiddlewareHeaders } from "./request-pipeline.js";
13
- import path from "node:path";
14
14
  //#region src/server/middleware-runtime.ts
15
15
  function isMiddlewareHandler(value) {
16
16
  return typeof value === "function";
@@ -1,5 +1,6 @@
1
1
  import { NextI18nConfig } from "../config/next-config.js";
2
2
  import { ValidFileMatcher } from "../routing/file-matcher.js";
3
+ import { NextFetchEvent, NextRequest } from "../shims/server.js";
3
4
  import { MiddlewareModule, MiddlewareResult } from "./middleware-runtime.js";
4
5
  import { matchPattern, matchesMiddleware } from "./middleware-matcher.js";
5
6
  import { ModuleRunner } from "vite/module-runner";
@@ -1,7 +1,7 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
1
2
  import { matchPattern, matchesMiddleware } from "./middleware-matcher.js";
2
3
  import { resolveMiddlewareModuleHandler, runGeneratedMiddleware } from "./middleware-runtime.js";
3
4
  import fs from "node:fs";
4
- import path from "node:path";
5
5
  //#region src/server/middleware.ts
6
6
  /**
7
7
  * Determine whether a middleware/proxy file path refers to a proxy file.
@@ -121,6 +121,7 @@ type RscFetchResultFacts = {
121
121
  compatibilityIdHeader: string | null;
122
122
  responseUrl: string | null;
123
123
  streamedRedirectTarget: string | null;
124
+ streamedRedirectType?: "push" | "replace" | null;
124
125
  };
125
126
  type RscRedirectFollow = {
126
127
  href: string;
@@ -142,6 +143,7 @@ type RscFetchResultDecision = {
142
143
  kind: "hardNavigate";
143
144
  discardBody: boolean;
144
145
  url: string;
146
+ hardNavigationMode?: "assign" | "replace";
145
147
  reason: RscFetchResultHardNavReason;
146
148
  trace: NavigationTrace;
147
149
  };
@@ -8,6 +8,9 @@ import { resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop
8
8
  import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
9
9
  import { verifyOperationTokenForCacheReuse } from "./operation-token.js";
10
10
  //#region src/server/navigation-planner.ts
11
+ function mergeRscRedirectHistoryMode(navigationMode, redirectType) {
12
+ return navigationMode === "push" || redirectType === "push" ? "push" : "replace";
13
+ }
11
14
  const ROUTE_INTERCEPTION_CONTEXT_SEPARATOR = "\0";
12
15
  const CACHE_ENTRY_PROOF_MISSING_CODE = "CP_CACHE_ENTRY_PROOF_MISSING";
13
16
  function createRequestWorkDecision(options) {
@@ -41,6 +44,7 @@ function createRscFetchResultHardNavigationDecision(options) {
41
44
  return {
42
45
  discardBody: options.discardBody,
43
46
  kind: "hardNavigate",
47
+ ...options.hardNavigationMode !== void 0 ? { hardNavigationMode: options.hardNavigationMode } : {},
44
48
  reason: options.reason,
45
49
  trace: createNavigationTrace(options.reasonCode, createRscFetchResultTraceFields(options.facts, {
46
50
  ...options.redirectSignal !== void 0 ? { redirectSignal: options.redirectSignal } : {},
@@ -133,9 +137,10 @@ function classifyRscFetchResult(facts) {
133
137
  });
134
138
  }
135
139
  if (facts.streamedRedirectTarget !== null) {
140
+ const streamedHistoryMode = mergeRscRedirectHistoryMode(facts.effectiveHistoryUpdateMode, facts.streamedRedirectType);
136
141
  const redirectDecision = resolveStreamedRscRedirectLifecycleHop({
137
142
  currentHref: facts.currentHref,
138
- historyUpdateMode: facts.effectiveHistoryUpdateMode,
143
+ historyUpdateMode: streamedHistoryMode,
139
144
  origin: facts.origin,
140
145
  redirectDepth: facts.redirectDepth,
141
146
  requestPreviousNextUrl: facts.requestPreviousNextUrl,
@@ -149,6 +154,7 @@ function classifyRscFetchResult(facts) {
149
154
  reason: terminalReason.hardNavigationReason,
150
155
  reasonCode: terminalReason.traceReasonCode,
151
156
  redirectSignal: "streamed-header",
157
+ hardNavigationMode: streamedHistoryMode === "push" ? "assign" : "replace",
152
158
  url: redirectDecision.href
153
159
  });
154
160
  }
@@ -157,7 +163,7 @@ function classifyRscFetchResult(facts) {
157
163
  facts,
158
164
  redirect: {
159
165
  href: redirectDecision.href,
160
- historyUpdateMode: facts.effectiveHistoryUpdateMode,
166
+ historyUpdateMode: streamedHistoryMode,
161
167
  previousNextUrl: redirectDecision.previousNextUrl,
162
168
  redirectDepth: redirectDecision.redirectDepth
163
169
  },
@@ -1,23 +1,7 @@
1
+ import { RedirectDigest } from "../utils/redirect-digest.js";
2
+
1
3
  //#region src/server/next-error-digest.d.ts
2
- /**
3
- * Helpers for parsing Next.js error `digest` strings shared across the App
4
- * Router execution paths (server actions, page renders, route handlers).
5
- *
6
- * Next.js encodes special control flow as thrown errors carrying a `digest`
7
- * field with one of these formats:
8
- * - `NEXT_REDIRECT;<type>;<encodedUrl>;<status>` — `redirect()` / `permanentRedirect()`
9
- * - `NEXT_NOT_FOUND` — `notFound()`
10
- * - `NEXT_HTTP_ERROR_FALLBACK;<status>` — `forbidden()` / `unauthorized()` / etc.
11
- *
12
- * Each call site needs slightly different post-processing (URL resolution
13
- * against the request, 303-vs-307 status overrides for actions, etc.), so
14
- * these helpers only handle the parsing — callers shape the result.
15
- */
16
- type NextRedirectDigest = {
17
- status: number;
18
- type: string | null;
19
- url: string;
20
- };
4
+ type NextRedirectDigest = RedirectDigest;
21
5
  type NextHttpErrorDigest = {
22
6
  status: number;
23
7
  };
@@ -27,11 +11,12 @@ type NextHttpErrorDigest = {
27
11
  */
28
12
  declare function getNextErrorDigest(error: unknown): string | null;
29
13
  /**
30
- * Parses a `NEXT_REDIRECT;<type>;<encodedUrl>;<status>` digest. Returns null
31
- * when the digest is not a redirect digest or the encoded URL segment is
32
- * missing. The `url` is decoded with `decodeURIComponent`; the `status`
33
- * defaults to 307 when omitted; an omitted `type` is left as null so the
34
- * caller can apply the correct context-sensitive default.
14
+ * Parses redirect digests from vinext's encoded three-part form and Next.js's
15
+ * raw, semicolon-terminated form. Returns null when the digest is not a
16
+ * redirect digest. Vinext's encoded URL is decoded with `decodeURIComponent`;
17
+ * Next.js's canonical raw URL is preserved verbatim. The `status` defaults to
18
+ * 307 when omitted; an omitted `type` is left as null so the caller can apply
19
+ * the correct context-sensitive default.
35
20
  */
36
21
  declare function parseNextRedirectDigest(digest: string): NextRedirectDigest | null;
37
22
  /**
@@ -1,5 +1,21 @@
1
+ import { parseRedirectDigest } from "../utils/redirect-digest.js";
1
2
  //#region src/server/next-error-digest.ts
2
3
  /**
4
+ * Helpers for parsing Next.js error `digest` strings shared across the App
5
+ * Router execution paths (server actions, page renders, route handlers).
6
+ *
7
+ * Special control flow is encoded as thrown errors carrying a `digest` field.
8
+ * Redirect digests may appear as vinext's encoded three-part form or Next.js's
9
+ * raw, semicolon-terminated form:
10
+ * - `NEXT_REDIRECT;<type>;<url>[;<status>[;]]` — `redirect()` / `permanentRedirect()`
11
+ * - `NEXT_NOT_FOUND` — `notFound()`
12
+ * - `NEXT_HTTP_ERROR_FALLBACK;<status>` — `forbidden()` / `unauthorized()` / etc.
13
+ *
14
+ * Each call site needs slightly different post-processing (URL resolution
15
+ * against the request, 303-vs-307 status overrides for actions, etc.), so
16
+ * these helpers only handle the parsing — callers shape the result.
17
+ */
18
+ /**
3
19
  * Pulls a stringified `digest` off an unknown thrown value, or returns null
4
20
  * when the value is not a digest-bearing error.
5
21
  */
@@ -8,23 +24,15 @@ function getNextErrorDigest(error) {
8
24
  return String(error.digest);
9
25
  }
10
26
  /**
11
- * Parses a `NEXT_REDIRECT;<type>;<encodedUrl>;<status>` digest. Returns null
12
- * when the digest is not a redirect digest or the encoded URL segment is
13
- * missing. The `url` is decoded with `decodeURIComponent`; the `status`
14
- * defaults to 307 when omitted; an omitted `type` is left as null so the
15
- * caller can apply the correct context-sensitive default.
27
+ * Parses redirect digests from vinext's encoded three-part form and Next.js's
28
+ * raw, semicolon-terminated form. Returns null when the digest is not a
29
+ * redirect digest. Vinext's encoded URL is decoded with `decodeURIComponent`;
30
+ * Next.js's canonical raw URL is preserved verbatim. The `status` defaults to
31
+ * 307 when omitted; an omitted `type` is left as null so the caller can apply
32
+ * the correct context-sensitive default.
16
33
  */
17
34
  function parseNextRedirectDigest(digest) {
18
- if (!digest.startsWith("NEXT_REDIRECT;")) return null;
19
- const parts = digest.split(";");
20
- const encodedUrl = parts[2];
21
- if (!encodedUrl) return null;
22
- const type = parts[1];
23
- return {
24
- status: parts[3] ? parseInt(parts[3], 10) : 307,
25
- type: type || null,
26
- url: decodeURIComponent(encodedUrl)
27
- };
35
+ return parseRedirectDigest(digest);
28
36
  }
29
37
  /**
30
38
  * Parses a `NEXT_NOT_FOUND` or `NEXT_HTTP_ERROR_FALLBACK;<status>` digest.
@@ -41,7 +41,7 @@ function evaluateDimension(dimension, token, authority) {
41
41
  }
42
42
  function verifyOperationToken(token, authority, policy) {
43
43
  const required = new Set(policy.require);
44
- const evaluated = new Set([...policy.check, ...policy.require]);
44
+ const evaluated = /* @__PURE__ */ new Set([...policy.check, ...policy.require]);
45
45
  for (const dimension of DIMENSION_ORDER) {
46
46
  if (!evaluated.has(dimension)) continue;
47
47
  const status = evaluateDimension(dimension, token, authority);
@@ -49,7 +49,8 @@ function parseSizeLimit(value) {
49
49
  if (!match) return void 0;
50
50
  const amount = Number.parseFloat(match[1]);
51
51
  if (!Number.isFinite(amount) || amount < 0) return void 0;
52
- const multiplier = SIZE_UNITS[match[2] ?? "b"];
52
+ const unit = match[2] ?? "b";
53
+ const multiplier = SIZE_UNITS[unit];
53
54
  if (multiplier === void 0) return void 0;
54
55
  return Math.floor(amount * multiplier);
55
56
  }
@@ -0,0 +1,14 @@
1
+ //#region src/server/pages-dev-hydration.d.ts
2
+ type PagesDevHydrationOptions = {
3
+ appModuleSource: string | null;
4
+ forceRouterReady?: boolean;
5
+ normalizePageProps?: boolean;
6
+ pageModuleSource: string;
7
+ reactStrictMode: boolean;
8
+ replaceFallbackRoute?: boolean;
9
+ scriptNonce?: string;
10
+ setPagePatternsFromNextData?: boolean;
11
+ };
12
+ declare function createPagesDevHydrationScript(options: PagesDevHydrationOptions): string;
13
+ //#endregion
14
+ export { PagesDevHydrationOptions, createPagesDevHydrationScript };
@@ -0,0 +1,83 @@
1
+ import { createNonceAttribute } from "./html.js";
2
+ //#region src/server/pages-dev-hydration.ts
3
+ function createPagesDevHydrationScript(options) {
4
+ const nonceAttr = createNonceAttribute(options.scriptNonce);
5
+ const initializeRouter = options.forceRouterReady ? "_initializePagesRouterReadyFromNextData(nextData, true);" : "_initializePagesRouterReadyFromNextData(nextData);";
6
+ const pagePatterns = options.setPagePatternsFromNextData ? "window.__VINEXT_PAGE_PATTERNS__ = [nextData.page];" : "";
7
+ const pageProps = options.normalizePageProps === false ? "const pageProps = rawPageProps ?? {};" : "const pageProps = rawPageProps && typeof rawPageProps === \"object\" ? rawPageProps : {};";
8
+ const fallbackReplacement = options.replaceFallbackRoute ? `
9
+ if (nextData.isFallback) {
10
+ await Router.replace(window.location.pathname + window.location.search + window.location.hash, undefined, { _h: 1, scroll: false });
11
+ }` : "";
12
+ const createElement = options.appModuleSource ? `
13
+ const appModule = await import(${JSON.stringify(options.appModuleSource)});
14
+ const AppComponent = appModule.default;
15
+ window.__VINEXT_APP__ = AppComponent;
16
+ const appRouter = ${options.forceRouterReady ? "{ ...Router, isReady: true }" : "Router"};
17
+ element = React.createElement(AppComponent, {
18
+ ...props,
19
+ Component: PageComponent,
20
+ pageProps: rawPageProps,
21
+ router: appRouter,
22
+ });
23
+ ` : `
24
+ element = React.createElement(PageComponent, pageProps);
25
+ `;
26
+ return `
27
+ <script type="module"${nonceAttr}>
28
+ import "vinext/instrumentation-client";
29
+ import React from "react";
30
+ import { hydrateRoot } from "react-dom/client";
31
+ import Router, { wrapWithRouterContext, _initializePagesRouterReadyFromNextData } from "next/router";
32
+
33
+ const nextDataElement = document.getElementById("__NEXT_DATA__");
34
+ if (nextDataElement?.textContent) {
35
+ window.__NEXT_DATA__ = JSON.parse(nextDataElement.textContent);
36
+ window.__VINEXT_LOCALE__ = window.__NEXT_DATA__.locale;
37
+ window.__VINEXT_LOCALES__ = window.__NEXT_DATA__.locales;
38
+ window.__VINEXT_DEFAULT_LOCALE__ = window.__NEXT_DATA__.defaultLocale;
39
+ }
40
+ const nextData = window.__NEXT_DATA__;
41
+ ${initializeRouter}
42
+ const props = nextData.props && typeof nextData.props === "object" ? nextData.props : {};
43
+ const rawPageProps = props.pageProps;
44
+ ${pageProps}
45
+ window.__VINEXT_PAGE_LOADERS__ = { [nextData.page]: () => import(${JSON.stringify(options.pageModuleSource)}) };
46
+ ${pagePatterns}
47
+ window.__VINEXT_APP_LOADER__ = ${options.appModuleSource ? `() => import(${JSON.stringify(options.appModuleSource)})` : "undefined"};
48
+ window.__VINEXT_REACT_STRICT_MODE__ = ${JSON.stringify(options.reactStrictMode)};
49
+
50
+ async function hydrate() {
51
+ let hydrateRootOptions;
52
+ if (import.meta.env.DEV) {
53
+ const overlay = await import("vinext/dev-error-overlay");
54
+ overlay.installDevErrorOverlay();
55
+ overlay.installViteHmrErrorHandler(import.meta.hot);
56
+ overlay.reportInitialDevServerErrors();
57
+ hydrateRootOptions = {
58
+ onCaughtError: overlay.devOnCaughtError,
59
+ onUncaughtError: overlay.devOnUncaughtError,
60
+ };
61
+ }
62
+
63
+ const pageModule = await import(${JSON.stringify(options.pageModuleSource)});
64
+ const PageComponent = pageModule.default;
65
+ let element;
66
+ ${createElement}
67
+ let resolveHydrationCommit;
68
+ const hydrationCommitted = new Promise((resolve) => { resolveHydrationCommit = resolve; });
69
+ element = wrapWithRouterContext(element, resolveHydrationCommit);
70
+ const root = hydrateRoot(document.getElementById("__next"), element, hydrateRootOptions);
71
+ window.__VINEXT_ROOT__ = root;
72
+ await hydrationCommitted;
73
+ const hydratedAt = performance.now();
74
+ window.__VINEXT_HYDRATED_AT = hydratedAt;
75
+ window.__NEXT_HYDRATED = true;
76
+ window.__NEXT_HYDRATED_AT = hydratedAt;
77
+ window.__NEXT_HYDRATED_CB?.();${fallbackReplacement}
78
+ }
79
+ hydrate();
80
+ <\/script>`;
81
+ }
82
+ //#endregion
83
+ export { createPagesDevHydrationScript };
@@ -1,4 +1,4 @@
1
- import path from "node:path";
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
2
  //#region src/server/pages-dev-module-url.ts
3
3
  function normalizeBase(base) {
4
4
  if (!base || base === "/") return "/";
@@ -11,7 +11,7 @@ function createPagesDevAssetUrl(assetPath) {
11
11
  return "/" + encodePagesDevModulePath(assetPath.replace(/^\/+/, ""));
12
12
  }
13
13
  function createPagesDevModuleUrl(viteRoot, moduleFilePath, viteBase) {
14
- const relativePath = (/^[A-Za-z]:[\\/]/.test(viteRoot) ? path.win32 : path).relative(viteRoot, moduleFilePath).replace(/\\/g, "/");
14
+ const relativePath = (/^[A-Za-z]:[\\/]/.test(viteRoot) ? path.win32 : path).relative(viteRoot, moduleFilePath);
15
15
  return normalizeBase(viteBase) + encodePagesDevModulePath(relativePath);
16
16
  }
17
17
  //#endregion