vinext 0.1.1 → 0.1.3

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 (266) hide show
  1. package/README.md +2 -5
  2. package/dist/build/client-build-config.d.ts +7 -1
  3. package/dist/build/client-build-config.js +9 -1
  4. package/dist/build/prerender.d.ts +9 -1
  5. package/dist/build/prerender.js +41 -12
  6. package/dist/build/run-prerender.d.ts +10 -2
  7. package/dist/build/run-prerender.js +15 -1
  8. package/dist/check.js +4 -3
  9. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  10. package/dist/client/app-nav-failure-handler.js +44 -0
  11. package/dist/client/navigation-runtime.d.ts +3 -2
  12. package/dist/client/vinext-next-data.d.ts +18 -1
  13. package/dist/client/window-next.d.ts +8 -5
  14. package/dist/client/window-next.js +12 -1
  15. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  16. package/dist/config/config-matchers.d.ts +11 -4
  17. package/dist/config/config-matchers.js +88 -16
  18. package/dist/config/next-config.d.ts +59 -4
  19. package/dist/config/next-config.js +149 -48
  20. package/dist/deploy.d.ts +30 -11
  21. package/dist/deploy.js +189 -101
  22. package/dist/entries/app-browser-entry.d.ts +9 -3
  23. package/dist/entries/app-browser-entry.js +21 -3
  24. package/dist/entries/app-rsc-entry.d.ts +2 -0
  25. package/dist/entries/app-rsc-entry.js +71 -6
  26. package/dist/entries/app-rsc-manifest.js +2 -0
  27. package/dist/entries/app-ssr-entry.js +1 -1
  28. package/dist/entries/pages-client-entry.js +54 -9
  29. package/dist/entries/pages-server-entry.js +48 -11
  30. package/dist/index.d.ts +0 -2
  31. package/dist/index.js +285 -139
  32. package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
  33. package/dist/plugins/dynamic-preload-metadata.js +415 -0
  34. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  35. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  36. package/dist/plugins/og-assets.js +2 -2
  37. package/dist/plugins/optimize-imports.d.ts +10 -5
  38. package/dist/plugins/optimize-imports.js +27 -21
  39. package/dist/plugins/postcss.js +7 -7
  40. package/dist/plugins/sass.d.ts +53 -24
  41. package/dist/plugins/sass.js +249 -1
  42. package/dist/plugins/typeof-window.d.ts +14 -0
  43. package/dist/plugins/typeof-window.js +150 -0
  44. package/dist/plugins/wasm-module-import.d.ts +15 -0
  45. package/dist/plugins/wasm-module-import.js +50 -0
  46. package/dist/routing/app-route-graph.d.ts +25 -2
  47. package/dist/routing/app-route-graph.js +91 -22
  48. package/dist/routing/file-matcher.d.ts +10 -1
  49. package/dist/routing/file-matcher.js +23 -2
  50. package/dist/routing/pages-router.js +3 -3
  51. package/dist/routing/utils.d.ts +35 -6
  52. package/dist/routing/utils.js +59 -7
  53. package/dist/server/api-handler.d.ts +6 -1
  54. package/dist/server/api-handler.js +21 -15
  55. package/dist/server/app-browser-action-result.d.ts +19 -6
  56. package/dist/server/app-browser-action-result.js +19 -10
  57. package/dist/server/app-browser-entry.js +269 -297
  58. package/dist/server/app-browser-error.d.ts +10 -3
  59. package/dist/server/app-browser-error.js +47 -6
  60. package/dist/server/app-browser-history-controller.d.ts +104 -0
  61. package/dist/server/app-browser-history-controller.js +210 -0
  62. package/dist/server/app-browser-hydration.d.ts +2 -0
  63. package/dist/server/app-browser-hydration.js +1 -0
  64. package/dist/server/app-browser-navigation-controller.d.ts +7 -4
  65. package/dist/server/app-browser-navigation-controller.js +33 -9
  66. package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
  67. package/dist/server/app-browser-rsc-redirect.js +30 -8
  68. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  69. package/dist/server/app-browser-server-action-navigation.js +9 -0
  70. package/dist/server/app-browser-state.js +4 -7
  71. package/dist/server/app-browser-stream.js +86 -43
  72. package/dist/server/app-browser-visible-commit.js +1 -1
  73. package/dist/server/app-elements-wire.d.ts +6 -1
  74. package/dist/server/app-elements-wire.js +14 -4
  75. package/dist/server/app-elements.d.ts +2 -2
  76. package/dist/server/app-elements.js +2 -2
  77. package/dist/server/app-fallback-renderer.d.ts +3 -1
  78. package/dist/server/app-fallback-renderer.js +6 -2
  79. package/dist/server/app-middleware.js +1 -0
  80. package/dist/server/app-optimistic-routing.js +24 -3
  81. package/dist/server/app-page-boundary-render.d.ts +3 -1
  82. package/dist/server/app-page-boundary-render.js +31 -16
  83. package/dist/server/app-page-cache-render.d.ts +53 -0
  84. package/dist/server/app-page-cache-render.js +91 -0
  85. package/dist/server/app-page-cache.d.ts +16 -2
  86. package/dist/server/app-page-cache.js +71 -8
  87. package/dist/server/app-page-dispatch.d.ts +34 -0
  88. package/dist/server/app-page-dispatch.js +167 -97
  89. package/dist/server/app-page-element-builder.d.ts +23 -2
  90. package/dist/server/app-page-element-builder.js +42 -10
  91. package/dist/server/app-page-execution.d.ts +7 -2
  92. package/dist/server/app-page-execution.js +53 -18
  93. package/dist/server/app-page-probe.d.ts +1 -0
  94. package/dist/server/app-page-probe.js +4 -0
  95. package/dist/server/app-page-render-observation.d.ts +3 -1
  96. package/dist/server/app-page-render-observation.js +17 -1
  97. package/dist/server/app-page-render.d.ts +13 -2
  98. package/dist/server/app-page-render.js +48 -17
  99. package/dist/server/app-page-request.d.ts +3 -0
  100. package/dist/server/app-page-request.js +5 -3
  101. package/dist/server/app-page-response.js +1 -1
  102. package/dist/server/app-page-route-wiring.d.ts +5 -1
  103. package/dist/server/app-page-route-wiring.js +21 -11
  104. package/dist/server/app-page-stream.d.ts +16 -9
  105. package/dist/server/app-page-stream.js +12 -9
  106. package/dist/server/app-pages-bridge.d.ts +18 -0
  107. package/dist/server/app-pages-bridge.js +22 -5
  108. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  109. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  110. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  111. package/dist/server/app-ppr-fallback-shell.js +8 -1
  112. package/dist/server/app-route-handler-dispatch.js +9 -2
  113. package/dist/server/app-route-handler-policy.d.ts +1 -0
  114. package/dist/server/app-route-handler-response.js +11 -10
  115. package/dist/server/app-route-handler-runtime.js +12 -1
  116. package/dist/server/app-router-entry.js +5 -0
  117. package/dist/server/app-rsc-cache-busting.js +2 -0
  118. package/dist/server/app-rsc-handler.d.ts +25 -0
  119. package/dist/server/app-rsc-handler.js +153 -53
  120. package/dist/server/app-rsc-response-finalizer.js +1 -1
  121. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  122. package/dist/server/app-rsc-route-matching.js +2 -0
  123. package/dist/server/app-segment-config.d.ts +9 -1
  124. package/dist/server/app-segment-config.js +12 -3
  125. package/dist/server/app-server-action-execution.d.ts +12 -0
  126. package/dist/server/app-server-action-execution.js +47 -15
  127. package/dist/server/app-ssr-entry.d.ts +2 -0
  128. package/dist/server/app-ssr-entry.js +81 -8
  129. package/dist/server/app-ssr-stream.js +9 -1
  130. package/dist/server/cache-control.js +4 -0
  131. package/dist/server/dev-lockfile.js +2 -1
  132. package/dist/server/dev-server.d.ts +2 -2
  133. package/dist/server/dev-server.js +287 -63
  134. package/dist/server/headers.d.ts +8 -1
  135. package/dist/server/headers.js +8 -1
  136. package/dist/server/hybrid-route-priority.d.ts +22 -0
  137. package/dist/server/hybrid-route-priority.js +33 -0
  138. package/dist/server/image-optimization.d.ts +18 -9
  139. package/dist/server/image-optimization.js +37 -23
  140. package/dist/server/implicit-tags.d.ts +2 -1
  141. package/dist/server/implicit-tags.js +4 -1
  142. package/dist/server/instrumentation-runtime.d.ts +6 -0
  143. package/dist/server/instrumentation-runtime.js +8 -0
  144. package/dist/server/isr-decision.d.ts +79 -0
  145. package/dist/server/isr-decision.js +70 -0
  146. package/dist/server/metadata-route-response.js +5 -3
  147. package/dist/server/middleware-runtime.d.ts +13 -0
  148. package/dist/server/middleware-runtime.js +11 -7
  149. package/dist/server/middleware.js +1 -0
  150. package/dist/server/navigation-planner.d.ts +186 -22
  151. package/dist/server/navigation-planner.js +302 -0
  152. package/dist/server/navigation-trace.d.ts +18 -1
  153. package/dist/server/navigation-trace.js +18 -1
  154. package/dist/server/normalize-path.d.ts +0 -8
  155. package/dist/server/normalize-path.js +3 -1
  156. package/dist/server/otel-tracer-extension.d.ts +45 -0
  157. package/dist/server/otel-tracer-extension.js +89 -0
  158. package/dist/server/pages-api-route.d.ts +20 -3
  159. package/dist/server/pages-api-route.js +19 -3
  160. package/dist/server/pages-asset-tags.d.ts +16 -4
  161. package/dist/server/pages-asset-tags.js +22 -12
  162. package/dist/server/pages-data-route.d.ts +8 -1
  163. package/dist/server/pages-data-route.js +16 -3
  164. package/dist/server/pages-get-initial-props.d.ts +54 -4
  165. package/dist/server/pages-get-initial-props.js +43 -1
  166. package/dist/server/pages-node-compat.d.ts +3 -11
  167. package/dist/server/pages-node-compat.js +175 -122
  168. package/dist/server/pages-page-data.d.ts +39 -2
  169. package/dist/server/pages-page-data.js +261 -46
  170. package/dist/server/pages-page-handler.d.ts +5 -2
  171. package/dist/server/pages-page-handler.js +78 -25
  172. package/dist/server/pages-page-response.d.ts +47 -2
  173. package/dist/server/pages-page-response.js +73 -9
  174. package/dist/server/pages-readiness.d.ts +1 -1
  175. package/dist/server/pages-request-pipeline.d.ts +16 -1
  176. package/dist/server/pages-request-pipeline.js +96 -38
  177. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  178. package/dist/server/pregenerated-concrete-paths.js +2 -19
  179. package/dist/server/prerender-manifest.d.ts +33 -0
  180. package/dist/server/prerender-manifest.js +54 -0
  181. package/dist/server/prerender-route-params.d.ts +1 -2
  182. package/dist/server/prod-server.d.ts +39 -1
  183. package/dist/server/prod-server.js +107 -37
  184. package/dist/server/request-pipeline.d.ts +3 -15
  185. package/dist/server/request-pipeline.js +58 -47
  186. package/dist/server/rsc-stream-hints.d.ts +5 -1
  187. package/dist/server/rsc-stream-hints.js +6 -1
  188. package/dist/server/seed-cache.js +10 -18
  189. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  190. package/dist/shims/app-router-scroll-state.js +14 -2
  191. package/dist/shims/app-router-scroll.d.ts +3 -0
  192. package/dist/shims/app-router-scroll.js +28 -18
  193. package/dist/shims/cache-runtime.js +12 -4
  194. package/dist/shims/cache.d.ts +1 -0
  195. package/dist/shims/cache.js +1 -1
  196. package/dist/shims/cdn-cache.d.ts +5 -5
  197. package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
  198. package/dist/shims/dynamic-preload-chunks.js +79 -0
  199. package/dist/shims/dynamic.d.ts +4 -0
  200. package/dist/shims/dynamic.js +4 -2
  201. package/dist/shims/error-boundary.d.ts +6 -4
  202. package/dist/shims/error-boundary.js +7 -0
  203. package/dist/shims/error.js +38 -11
  204. package/dist/shims/error.react-server.d.ts +9 -0
  205. package/dist/shims/error.react-server.js +6 -0
  206. package/dist/shims/fetch-cache.d.ts +11 -1
  207. package/dist/shims/fetch-cache.js +55 -20
  208. package/dist/shims/hash-scroll.js +6 -1
  209. package/dist/shims/head.js +6 -1
  210. package/dist/shims/headers.d.ts +16 -2
  211. package/dist/shims/headers.js +66 -5
  212. package/dist/shims/image-config.js +7 -1
  213. package/dist/shims/internal/als-registry.js +28 -1
  214. package/dist/shims/internal/app-route-detection.d.ts +6 -3
  215. package/dist/shims/internal/app-route-detection.js +18 -23
  216. package/dist/shims/internal/app-router-context.d.ts +5 -0
  217. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  218. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  219. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  220. package/dist/shims/internal/navigation-untracked.js +55 -0
  221. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  222. package/dist/shims/internal/pages-data-target.js +17 -8
  223. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  224. package/dist/shims/internal/pages-router-accessor.js +13 -0
  225. package/dist/shims/internal/router-context.d.ts +2 -1
  226. package/dist/shims/internal/router-context.js +3 -1
  227. package/dist/shims/link.js +12 -5
  228. package/dist/shims/metadata.d.ts +6 -2
  229. package/dist/shims/metadata.js +32 -14
  230. package/dist/shims/navigation.d.ts +14 -17
  231. package/dist/shims/navigation.js +93 -46
  232. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  233. package/dist/shims/ppr-fallback-shell.js +28 -7
  234. package/dist/shims/router.d.ts +13 -2
  235. package/dist/shims/router.js +434 -116
  236. package/dist/shims/script-nonce-context.d.ts +1 -1
  237. package/dist/shims/script-nonce-context.js +11 -3
  238. package/dist/shims/server.d.ts +33 -2
  239. package/dist/shims/server.js +75 -18
  240. package/dist/shims/slot.js +1 -1
  241. package/dist/shims/unified-request-context.js +2 -0
  242. package/dist/typegen.js +1 -0
  243. package/dist/utils/built-asset-url.d.ts +4 -0
  244. package/dist/utils/built-asset-url.js +11 -0
  245. package/dist/utils/client-build-manifest.js +15 -5
  246. package/dist/utils/client-runtime-metadata.d.ts +45 -0
  247. package/dist/utils/client-runtime-metadata.js +63 -0
  248. package/dist/utils/commonjs-loader.d.ts +16 -0
  249. package/dist/utils/commonjs-loader.js +100 -0
  250. package/dist/utils/deployment-id.d.ts +8 -0
  251. package/dist/utils/deployment-id.js +22 -0
  252. package/dist/utils/hash.d.ts +17 -1
  253. package/dist/utils/hash.js +36 -1
  254. package/dist/utils/html-limited-bots.d.ts +18 -1
  255. package/dist/utils/html-limited-bots.js +23 -1
  256. package/dist/utils/lazy-chunks.d.ts +27 -1
  257. package/dist/utils/lazy-chunks.js +65 -1
  258. package/dist/utils/manifest-paths.d.ts +20 -2
  259. package/dist/utils/manifest-paths.js +38 -3
  260. package/dist/utils/parse-cookie.d.ts +13 -0
  261. package/dist/utils/parse-cookie.js +52 -0
  262. package/dist/utils/path.d.ts +8 -1
  263. package/dist/utils/path.js +13 -1
  264. package/package.json +2 -2
  265. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  266. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -44,14 +44,66 @@ function routePrecedence(pattern) {
44
44
  return score;
45
45
  }
46
46
  /**
47
- * Sort comparator for routes — lower precedence score sorts first (higher priority).
48
- * Lexicographic tiebreaker on pattern for determinism.
47
+ * Sort routes by precedence — lower score sorts first (higher priority), with a
48
+ * lexicographic tiebreaker on the pattern for determinism. Sorts in place and
49
+ * returns the same array (mirrors `Array.prototype.sort`).
49
50
  *
50
- * Usage: routes.sort(compareRoutes)
51
+ * `routePrecedence` is a pure function of the pattern, so each pattern's score
52
+ * is computed exactly once up front (decorate-sort) instead of ~2·log n times
53
+ * by a comparator that re-parses on every comparison. The `localeCompare`
54
+ * tiebreaker already guarantees a total order, so the result is byte-identical
55
+ * to comparing precedence inline.
56
+ *
57
+ * Usage: sortRoutes(routes)
58
+ */
59
+ function sortRoutes(routes) {
60
+ const scores = /* @__PURE__ */ new Map();
61
+ for (const route of routes) if (!scores.has(route.pattern)) scores.set(route.pattern, routePrecedence(route.pattern));
62
+ return routes.sort((a, b) => {
63
+ const diff = (scores.get(a.pattern) ?? 0) - (scores.get(b.pattern) ?? 0);
64
+ return diff !== 0 ? diff : a.pattern.localeCompare(b.pattern);
65
+ });
66
+ }
67
+ /**
68
+ * Single source of truth for hybrid App/Pages route ownership.
69
+ *
70
+ * Mirrors Next.js's DefaultRouteMatcherManager ordering: Pages providers
71
+ * are registered before App providers, then merged dynamic matchers sort
72
+ * together. Returns the router that should own a request/navigation to
73
+ * a URL that matched BOTH routers.
74
+ *
75
+ * Centralised so the server's request handling and the client's link /
76
+ * prefetch / programmatic-navigation paths all reach the same owner for
77
+ * the same (pages pattern, app pattern) pair. This intentionally implements
78
+ * Next.js's segment-tree ordering directly instead of vinext's broader
79
+ * `sortRoutes()` score heuristic. It only arbitrates two routes that already
80
+ * matched the same URL; each router's own trie ordering remains unchanged.
81
+ *
82
+ * Usage:
83
+ * compareHybridRoutePatterns("/:slug", true, "/:slug", true) // → "pages"
84
+ * compareHybridRoutePatterns("/_sites/:slug*", true, "/:slug*", true) // → "pages"
85
+ * compareHybridRoutePatterns("/:path+", true, "/dashboard", false) // → "app"
86
+ * compareHybridRoutePatterns("/", false, "/", false) // → "app"
51
87
  */
52
- function compareRoutes(a, b) {
53
- const diff = routePrecedence(a.pattern) - routePrecedence(b.pattern);
54
- return diff !== 0 ? diff : a.pattern.localeCompare(b.pattern);
88
+ function compareHybridRoutePatterns(pagesPattern, pagesIsDynamic, appPattern, appIsDynamic) {
89
+ if (pagesPattern === appPattern) throw new Error(`Conflicting app and page routes found for "${pagesPattern}"`);
90
+ if (!pagesIsDynamic) return appIsDynamic ? "pages" : "app";
91
+ if (!appIsDynamic) return "app";
92
+ const pagesSegments = pagesPattern.split("/").filter(Boolean);
93
+ const appSegments = appPattern.split("/").filter(Boolean);
94
+ const segmentRank = (segment) => {
95
+ if (!segment.startsWith(":")) return 0;
96
+ if (segment.endsWith("*")) return 3;
97
+ if (segment.endsWith("+")) return 2;
98
+ return 1;
99
+ };
100
+ for (let index = 0; index < Math.min(pagesSegments.length, appSegments.length); index++) {
101
+ const pagesRank = segmentRank(pagesSegments[index]);
102
+ const appRank = segmentRank(appSegments[index]);
103
+ if (pagesRank !== appRank) return pagesRank < appRank ? "pages" : "app";
104
+ }
105
+ if (pagesSegments.length !== appSegments.length) return pagesSegments.length < appSegments.length ? "pages" : "app";
106
+ return "pages";
55
107
  }
56
108
  const PATH_DELIMITER_REGEX = /([/#?\\]|%(2f|23|3f|5c))/gi;
57
109
  function encodePathDelimiters(segment) {
@@ -187,4 +239,4 @@ function countConsumedPathnameSegments(visibleTreePathSegments, pathnameSegmentC
187
239
  return consumed;
188
240
  }
189
241
  //#endregion
190
- export { buildParams, compareRoutes, countConsumedPathnameSegments, decodeMatchedParams, decodeRouteSegment, isCatchAllSegment, isInvisibleSegment, isOptionalCatchAllSegment, normalizePathnameForRouteMatch, normalizePathnameForRouteMatchStrict, splitPathSegments, splitPathnameForRouteMatch };
242
+ export { buildParams, compareHybridRoutePatterns, countConsumedPathnameSegments, decodeMatchedParams, decodeRouteSegment, isCatchAllSegment, isInvisibleSegment, isOptionalCatchAllSegment, normalizePathnameForRouteMatch, normalizePathnameForRouteMatchStrict, sortRoutes, splitPathSegments, splitPathnameForRouteMatch };
@@ -1,3 +1,4 @@
1
+ import { NextI18nConfig } from "../config/next-config.js";
1
2
  import { Route } from "../routing/pages-router.js";
2
3
  import { ModuleImporter } from "./instrumentation.js";
3
4
  import { IncomingMessage, ServerResponse } from "node:http";
@@ -7,6 +8,10 @@ import { IncomingMessage, ServerResponse } from "node:http";
7
8
  * Handle an API route request.
8
9
  * Returns true if the request was handled, false if no API route matched.
9
10
  */
10
- declare function handleApiRoute(runner: ModuleImporter, req: IncomingMessage, res: ServerResponse, url: string, apiRoutes: Route[]): Promise<boolean>;
11
+ declare function handleApiRoute(runner: ModuleImporter, req: IncomingMessage, res: ServerResponse, url: string, apiRoutes: Route[], nextConfig?: {
12
+ basePath?: string;
13
+ i18n?: NextI18nConfig | null;
14
+ trailingSlash?: boolean;
15
+ }): Promise<boolean>;
11
16
  //#endregion
12
17
  export { handleApiRoute };
@@ -1,8 +1,10 @@
1
+ import { hasBasePath } from "../utils/base-path.js";
1
2
  import { matchRoute } from "../routing/pages-router.js";
2
3
  import "./server-globals.js";
4
+ import { parseCookieHeader } from "../utils/parse-cookie.js";
3
5
  import { NextRequest } from "../shims/server.js";
4
6
  import { importModule, reportRequestError } from "./instrumentation.js";
5
- import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
7
+ import { mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
6
8
  import { PagesBodyParseError, getMediaType, isJsonMediaType } from "./pages-media-type.js";
7
9
  import { isEdgeApiRuntime } from "./edge-api-runtime.js";
8
10
  import { DEFAULT_PAGES_API_BODY_SIZE_LIMIT, resolveBodyParserConfig } from "./pages-body-parser-config.js";
@@ -71,13 +73,7 @@ async function parseBody(req, sizeLimit = MAX_BODY_SIZE) {
71
73
  * Parse cookies from the Cookie header.
72
74
  */
73
75
  function parseCookies(req) {
74
- const header = req.headers.cookie ?? "";
75
- const cookies = {};
76
- for (const part of header.split(";")) {
77
- const [key, ...rest] = part.split("=");
78
- if (key) cookies[key.trim()] = rest.join("=").trim();
79
- }
80
- return cookies;
76
+ return parseCookieHeader(req.headers.cookie);
81
77
  }
82
78
  function isEdgeApiRouteModule(module) {
83
79
  if (typeof module.default !== "function") return false;
@@ -98,13 +94,19 @@ function readEdgeRequestBody(req) {
98
94
  req.on("error", (error) => controller.error(error));
99
95
  } });
100
96
  }
101
- function createEdgeApiRequest(req, url) {
97
+ function createEdgeApiRequest(req, url, params, nextConfig) {
102
98
  const headers = new Headers();
103
- for (const [name, value] of Object.entries(req.headers)) if (Array.isArray(value)) for (const item of value) headers.append(name, item);
104
- else if (value !== void 0) headers.set(name, value);
99
+ for (const [name, value] of Object.entries(req.headers)) {
100
+ if (name.startsWith(":")) continue;
101
+ if (Array.isArray(value)) for (const item of value) headers.append(name, item);
102
+ else if (value !== void 0) headers.set(name, value);
103
+ }
105
104
  const proto = resolveRequestProtocol(req);
106
105
  const host = resolveRequestHost(req, "localhost");
107
- const requestUrl = new URL(url, `${proto}://${host}`);
106
+ const requestUrl = new URL(req.url ?? url, `${proto}://${host}`);
107
+ const basePath = nextConfig?.basePath;
108
+ if (basePath && !hasBasePath(requestUrl.pathname, basePath)) requestUrl.pathname = `${basePath}${requestUrl.pathname}`;
109
+ requestUrl.search = urlQueryToSearchParams(mergeRouteParamsIntoQuery(parseQueryString(url), params)).toString();
108
110
  const body = readEdgeRequestBody(req);
109
111
  const init = {
110
112
  headers,
@@ -210,14 +212,18 @@ function enhanceApiObjects(req, res, query, body) {
210
212
  * Handle an API route request.
211
213
  * Returns true if the request was handled, false if no API route matched.
212
214
  */
213
- async function handleApiRoute(runner, req, res, url, apiRoutes) {
215
+ async function handleApiRoute(runner, req, res, url, apiRoutes, nextConfig) {
214
216
  const match = matchRoute(url, apiRoutes);
215
217
  if (!match) return false;
216
218
  const { route, params } = match;
217
219
  try {
218
220
  const apiModule = await importModule(runner, route.filePath);
219
221
  if (isEdgeApiRouteModule(apiModule)) {
220
- const nextRequest = new NextRequest(createEdgeApiRequest(req, url));
222
+ const nextRequest = new NextRequest(createEdgeApiRequest(req, url, params, nextConfig), nextConfig ? { nextConfig: {
223
+ basePath: nextConfig.basePath,
224
+ i18n: nextConfig.i18n ?? void 0,
225
+ trailingSlash: nextConfig.trailingSlash
226
+ } } : void 0);
221
227
  const response = await apiModule.default(nextRequest);
222
228
  if (!(response instanceof Response)) throw new Error("Edge API route did not return a Response");
223
229
  res.statusCode = response.status;
@@ -253,7 +259,7 @@ async function handleApiRoute(runner, req, res, url, apiRoutes) {
253
259
  reportRequestError(e instanceof Error ? e : new Error(String(e)), {
254
260
  path: url,
255
261
  method: req.method ?? "GET",
256
- headers: Object.fromEntries(Object.entries(req.headers).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : String(v ?? "")]))
262
+ headers: Object.fromEntries(Object.entries(req.headers).filter(([k]) => !k.startsWith(":")).map(([k, v]) => [k, Array.isArray(v) ? v.join(", ") : String(v ?? "")]))
257
263
  }, {
258
264
  routerKind: "Pages Router",
259
265
  routePath: match.route.pattern,
@@ -1,3 +1,5 @@
1
+ import { ServerActionResultFacts } from "./navigation-planner.js";
2
+
1
3
  //#region src/server/app-browser-action-result.d.ts
2
4
  type AppBrowserServerActionResult<TRoot> = {
3
5
  root?: TRoot;
@@ -24,12 +26,23 @@ declare function shouldClearClientNavigationCachesForServerActionResult<TRoot>(r
24
26
  declare function parseServerActionRevalidationHeader(headers: Pick<Headers, "get">): ServerActionRevalidationKind;
25
27
  declare function normalizeServerActionThrownValue(data: unknown, responseStatus: number): unknown;
26
28
  declare function readInvalidServerActionResponseError(response: Pick<Response, "headers" | "status" | "text">, hasRedirectLocation: boolean): Promise<Error | null>;
27
- declare function shouldCheckRscCompatibilityForServerActionResponse(response: Pick<Response, "headers">): boolean;
28
- declare function resolveServerActionRedirectCompatibilityHardNavigationTarget(options: {
29
+ type ServerActionResultResponseFactsInput = {
29
30
  actionRedirectHref: string | null;
30
- clientCompatibilityId: string | null | undefined;
31
- response: Pick<Response, "headers">;
32
- }): string | null;
31
+ actionRedirectType: string | null;
32
+ clientCompatibilityId: string | null;
33
+ contentTypeHeader: string | null;
34
+ compatibilityIdHeader: string | null;
35
+ currentHref: string;
36
+ origin: string;
37
+ responseUrl: string | null;
38
+ };
39
+ /**
40
+ * Converts raw browser response data into the narrow facts expected by the
41
+ * navigation planner. This is the single place where redirect-type
42
+ * normalisation and RSC content-type detection happen for server-action
43
+ * compatibility checks.
44
+ */
45
+ declare function createServerActionResultFacts(input: ServerActionResultResponseFactsInput): ServerActionResultFacts;
33
46
  declare function shouldScheduleRefreshForDiscardedServerAction(revalidation: ServerActionRevalidationKind): boolean;
34
47
  declare function createServerActionInitiationSnapshot<TRouterState>(options: {
35
48
  href: string;
@@ -48,4 +61,4 @@ type DiscardedServerActionRefreshSchedulerOptions = {
48
61
  };
49
62
  declare function createDiscardedServerActionRefreshScheduler(options: DiscardedServerActionRefreshSchedulerOptions): DiscardedServerActionRefreshScheduler;
50
63
  //#endregion
51
- export { AppBrowserServerActionResult, ServerActionRevalidationKind, createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, resolveServerActionRedirectCompatibilityHardNavigationTarget, shouldCheckRscCompatibilityForServerActionResponse, shouldClearClientNavigationCachesForServerActionResult, shouldScheduleRefreshForDiscardedServerAction };
64
+ export { AppBrowserServerActionResult, ServerActionResultResponseFactsInput, ServerActionRevalidationKind, createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult, shouldScheduleRefreshForDiscardedServerAction };
@@ -1,5 +1,5 @@
1
1
  import { ACTION_REVALIDATED_HEADER } from "./headers.js";
2
- import { VINEXT_RSC_CONTENT_TYPE, isRscCompatibilityIdCompatible } from "./app-rsc-cache-busting.js";
2
+ import { VINEXT_RSC_CONTENT_TYPE } from "./app-rsc-cache-busting.js";
3
3
  //#region src/server/app-browser-action-result.ts
4
4
  const ACTION_DID_REVALIDATE_STATIC_AND_DYNAMIC = 1;
5
5
  const ACTION_DID_REVALIDATE_DYNAMIC_ONLY = 2;
@@ -47,14 +47,23 @@ async function readInvalidServerActionResponseError(response, hasRedirectLocatio
47
47
  const message = response.status >= 400 && contentType.toLowerCase().startsWith("text/plain") ? await response.text() : "An unexpected response was received from the server.";
48
48
  return new Error(message || "An unexpected response was received from the server.");
49
49
  }
50
- function shouldCheckRscCompatibilityForServerActionResponse(response) {
51
- return (response.headers.get("content-type") ?? "").startsWith(VINEXT_RSC_CONTENT_TYPE);
52
- }
53
- function resolveServerActionRedirectCompatibilityHardNavigationTarget(options) {
54
- if (!options.actionRedirectHref) return null;
55
- if (!shouldCheckRscCompatibilityForServerActionResponse(options.response)) return null;
56
- if (isRscCompatibilityIdCompatible(options.response.headers.get("X-Vinext-RSC-Compatibility-Id"), options.clientCompatibilityId)) return null;
57
- return options.actionRedirectHref;
50
+ /**
51
+ * Converts raw browser response data into the narrow facts expected by the
52
+ * navigation planner. This is the single place where redirect-type
53
+ * normalisation and RSC content-type detection happen for server-action
54
+ * compatibility checks.
55
+ */
56
+ function createServerActionResultFacts(input) {
57
+ return {
58
+ actionRedirectHref: input.actionRedirectHref,
59
+ actionRedirectType: input.actionRedirectType === "push" ? "push" : "replace",
60
+ clientCompatibilityId: input.clientCompatibilityId,
61
+ compatibilityIdHeader: input.compatibilityIdHeader,
62
+ currentHref: input.currentHref,
63
+ isRscContentType: (input.contentTypeHeader ?? "").startsWith(VINEXT_RSC_CONTENT_TYPE),
64
+ origin: input.origin,
65
+ responseUrl: input.responseUrl
66
+ };
58
67
  }
59
68
  function shouldScheduleRefreshForDiscardedServerAction(revalidation) {
60
69
  return revalidation !== "none";
@@ -99,4 +108,4 @@ function createDiscardedServerActionRefreshScheduler(options) {
99
108
  };
100
109
  }
101
110
  //#endregion
102
- export { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, resolveServerActionRedirectCompatibilityHardNavigationTarget, shouldCheckRscCompatibilityForServerActionResponse, shouldClearClientNavigationCachesForServerActionResult, shouldScheduleRefreshForDiscardedServerAction };
111
+ export { createDiscardedServerActionRefreshScheduler, createServerActionInitiationSnapshot, createServerActionResultFacts, isServerActionResult, normalizeServerActionThrownValue, parseServerActionRevalidationHeader, readInvalidServerActionResponseError, shouldClearClientNavigationCachesForServerActionResult, shouldScheduleRefreshForDiscardedServerAction };