vinext 0.0.45 → 0.0.47

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 (311) hide show
  1. package/README.md +7 -5
  2. package/dist/build/prerender.d.ts +2 -1
  3. package/dist/build/prerender.js +80 -17
  4. package/dist/build/prerender.js.map +1 -1
  5. package/dist/build/report.d.ts +1 -1
  6. package/dist/build/route-classification-injector.d.ts +35 -0
  7. package/dist/build/route-classification-injector.js +61 -0
  8. package/dist/build/route-classification-injector.js.map +1 -0
  9. package/dist/build/route-classification-manifest.d.ts +1 -1
  10. package/dist/build/standalone.js +4 -3
  11. package/dist/build/standalone.js.map +1 -1
  12. package/dist/build/static-export.d.ts +1 -1
  13. package/dist/check.js +30 -18
  14. package/dist/check.js.map +1 -1
  15. package/dist/cli-args.d.ts +31 -0
  16. package/dist/cli-args.js +104 -0
  17. package/dist/cli-args.js.map +1 -0
  18. package/dist/cli.js +6 -19
  19. package/dist/cli.js.map +1 -1
  20. package/dist/cloudflare/kv-cache-handler.js +29 -9
  21. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  22. package/dist/config/config-matchers.js +1 -0
  23. package/dist/config/config-matchers.js.map +1 -1
  24. package/dist/config/next-config.d.ts +42 -4
  25. package/dist/config/next-config.js +27 -0
  26. package/dist/config/next-config.js.map +1 -1
  27. package/dist/deploy.js +18 -23
  28. package/dist/deploy.js.map +1 -1
  29. package/dist/entries/app-rsc-entry.d.ts +4 -3
  30. package/dist/entries/app-rsc-entry.js +435 -2317
  31. package/dist/entries/app-rsc-entry.js.map +1 -1
  32. package/dist/entries/app-rsc-manifest.d.ts +24 -0
  33. package/dist/entries/app-rsc-manifest.js +155 -0
  34. package/dist/entries/app-rsc-manifest.js.map +1 -0
  35. package/dist/entries/pages-server-entry.js +18 -105
  36. package/dist/entries/pages-server-entry.js.map +1 -1
  37. package/dist/index.js +82 -85
  38. package/dist/index.js.map +1 -1
  39. package/dist/plugins/fonts.js +54 -32
  40. package/dist/plugins/fonts.js.map +1 -1
  41. package/dist/plugins/rsc-client-shim-excludes.d.ts +6 -0
  42. package/dist/plugins/rsc-client-shim-excludes.js +28 -0
  43. package/dist/plugins/rsc-client-shim-excludes.js.map +1 -0
  44. package/dist/routing/app-route-graph.d.ts +109 -0
  45. package/dist/routing/app-route-graph.js +819 -0
  46. package/dist/routing/app-route-graph.js.map +1 -0
  47. package/dist/routing/app-router.d.ts +2 -79
  48. package/dist/routing/app-router.js +7 -621
  49. package/dist/routing/app-router.js.map +1 -1
  50. package/dist/routing/route-pattern.d.ts +9 -0
  51. package/dist/routing/route-pattern.js +90 -0
  52. package/dist/routing/route-pattern.js.map +1 -0
  53. package/dist/routing/route-trie.js +10 -11
  54. package/dist/routing/route-trie.js.map +1 -1
  55. package/dist/server/app-browser-entry.js +94 -232
  56. package/dist/server/app-browser-entry.js.map +1 -1
  57. package/dist/server/app-browser-error.d.ts +3 -4
  58. package/dist/server/app-browser-error.js +8 -4
  59. package/dist/server/app-browser-error.js.map +1 -1
  60. package/dist/server/app-browser-navigation-controller.d.ts +73 -0
  61. package/dist/server/app-browser-navigation-controller.js +282 -0
  62. package/dist/server/app-browser-navigation-controller.js.map +1 -0
  63. package/dist/server/app-browser-state.d.ts +1 -1
  64. package/dist/server/app-browser-state.js.map +1 -1
  65. package/dist/server/app-elements.js +1 -5
  66. package/dist/server/app-elements.js.map +1 -1
  67. package/dist/server/app-fallback-renderer.d.ts +57 -0
  68. package/dist/server/app-fallback-renderer.js +79 -0
  69. package/dist/server/app-fallback-renderer.js.map +1 -0
  70. package/dist/server/app-hook-warning-suppression.d.ts +7 -0
  71. package/dist/server/app-hook-warning-suppression.js +12 -0
  72. package/dist/server/app-hook-warning-suppression.js.map +1 -0
  73. package/dist/server/app-middleware.d.ts +32 -0
  74. package/dist/server/app-middleware.js +147 -0
  75. package/dist/server/app-middleware.js.map +1 -0
  76. package/dist/server/app-mounted-slots-header.d.ts +17 -0
  77. package/dist/server/app-mounted-slots-header.js +21 -0
  78. package/dist/server/app-mounted-slots-header.js.map +1 -0
  79. package/dist/server/app-page-boundary-render.d.ts +4 -2
  80. package/dist/server/app-page-boundary-render.js +50 -30
  81. package/dist/server/app-page-boundary-render.js.map +1 -1
  82. package/dist/server/app-page-boundary.d.ts +12 -1
  83. package/dist/server/app-page-boundary.js +27 -12
  84. package/dist/server/app-page-boundary.js.map +1 -1
  85. package/dist/server/app-page-cache.d.ts +22 -5
  86. package/dist/server/app-page-cache.js +90 -11
  87. package/dist/server/app-page-cache.js.map +1 -1
  88. package/dist/server/app-page-dispatch.d.ts +123 -0
  89. package/dist/server/app-page-dispatch.js +348 -0
  90. package/dist/server/app-page-dispatch.js.map +1 -0
  91. package/dist/server/app-page-element-builder.d.ts +61 -0
  92. package/dist/server/app-page-element-builder.js +139 -0
  93. package/dist/server/app-page-element-builder.js.map +1 -0
  94. package/dist/server/app-page-execution.d.ts +4 -3
  95. package/dist/server/app-page-execution.js +5 -8
  96. package/dist/server/app-page-execution.js.map +1 -1
  97. package/dist/server/app-page-head.d.ts +55 -0
  98. package/dist/server/app-page-head.js +196 -0
  99. package/dist/server/app-page-head.js.map +1 -0
  100. package/dist/server/app-page-method.d.ts +16 -0
  101. package/dist/server/app-page-method.js +30 -0
  102. package/dist/server/app-page-method.js.map +1 -0
  103. package/dist/server/app-page-params.d.ts +8 -0
  104. package/dist/server/app-page-params.js +28 -0
  105. package/dist/server/app-page-params.js.map +1 -0
  106. package/dist/server/app-page-render.d.ts +7 -2
  107. package/dist/server/app-page-render.js +131 -32
  108. package/dist/server/app-page-render.js.map +1 -1
  109. package/dist/server/app-page-request.d.ts +23 -8
  110. package/dist/server/app-page-request.js +51 -6
  111. package/dist/server/app-page-request.js.map +1 -1
  112. package/dist/server/app-page-response.d.ts +1 -0
  113. package/dist/server/app-page-response.js +3 -7
  114. package/dist/server/app-page-response.js.map +1 -1
  115. package/dist/server/app-page-route-wiring.d.ts +29 -5
  116. package/dist/server/app-page-route-wiring.js +30 -8
  117. package/dist/server/app-page-route-wiring.js.map +1 -1
  118. package/dist/server/app-page-stream.d.ts +10 -0
  119. package/dist/server/app-page-stream.js +5 -1
  120. package/dist/server/app-page-stream.js.map +1 -1
  121. package/dist/server/app-post-middleware-context.d.ts +16 -0
  122. package/dist/server/app-post-middleware-context.js +28 -0
  123. package/dist/server/app-post-middleware-context.js.map +1 -0
  124. package/dist/server/app-prerender-endpoints.d.ts +19 -0
  125. package/dist/server/app-prerender-endpoints.js +96 -0
  126. package/dist/server/app-prerender-endpoints.js.map +1 -0
  127. package/dist/server/app-prerender-static-params.d.ts +16 -0
  128. package/dist/server/app-prerender-static-params.js +14 -0
  129. package/dist/server/app-prerender-static-params.js.map +1 -0
  130. package/dist/server/app-request-context.d.ts +22 -0
  131. package/dist/server/app-request-context.js +30 -0
  132. package/dist/server/app-request-context.js.map +1 -0
  133. package/dist/server/app-route-handler-cache.d.ts +4 -0
  134. package/dist/server/app-route-handler-cache.js +11 -3
  135. package/dist/server/app-route-handler-cache.js.map +1 -1
  136. package/dist/server/app-route-handler-dispatch.d.ts +43 -0
  137. package/dist/server/app-route-handler-dispatch.js +149 -0
  138. package/dist/server/app-route-handler-dispatch.js.map +1 -0
  139. package/dist/server/app-route-handler-execution.d.ts +8 -3
  140. package/dist/server/app-route-handler-execution.js +25 -4
  141. package/dist/server/app-route-handler-execution.js.map +1 -1
  142. package/dist/server/app-route-handler-response.d.ts +6 -3
  143. package/dist/server/app-route-handler-response.js +52 -11
  144. package/dist/server/app-route-handler-response.js.map +1 -1
  145. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  146. package/dist/server/app-route-handler-runtime.js +107 -1
  147. package/dist/server/app-route-handler-runtime.js.map +1 -1
  148. package/dist/server/app-router-entry.js.map +1 -1
  149. package/dist/server/app-rsc-error-handler.d.ts +21 -0
  150. package/dist/server/app-rsc-error-handler.js +30 -0
  151. package/dist/server/app-rsc-error-handler.js.map +1 -0
  152. package/dist/server/app-rsc-errors.d.ts +27 -0
  153. package/dist/server/app-rsc-errors.js +42 -0
  154. package/dist/server/app-rsc-errors.js.map +1 -0
  155. package/dist/server/app-rsc-handler.d.ts +117 -0
  156. package/dist/server/app-rsc-handler.js +260 -0
  157. package/dist/server/app-rsc-handler.js.map +1 -0
  158. package/dist/server/app-rsc-request-normalization.d.ts +40 -0
  159. package/dist/server/app-rsc-request-normalization.js +63 -0
  160. package/dist/server/app-rsc-request-normalization.js.map +1 -0
  161. package/dist/server/app-rsc-response-finalizer.d.ts +30 -0
  162. package/dist/server/app-rsc-response-finalizer.js +38 -0
  163. package/dist/server/app-rsc-response-finalizer.js.map +1 -0
  164. package/dist/server/app-rsc-route-matching.d.ts +40 -0
  165. package/dist/server/app-rsc-route-matching.js +66 -0
  166. package/dist/server/app-rsc-route-matching.js.map +1 -0
  167. package/dist/server/app-segment-config.d.ts +33 -0
  168. package/dist/server/app-segment-config.js +86 -0
  169. package/dist/server/app-segment-config.js.map +1 -0
  170. package/dist/server/app-server-action-execution.d.ts +88 -1
  171. package/dist/server/app-server-action-execution.js +257 -5
  172. package/dist/server/app-server-action-execution.js.map +1 -1
  173. package/dist/server/app-ssr-entry.d.ts +7 -0
  174. package/dist/server/app-ssr-entry.js +30 -9
  175. package/dist/server/app-ssr-entry.js.map +1 -1
  176. package/dist/server/app-ssr-stream.d.ts +4 -2
  177. package/dist/server/app-ssr-stream.js +29 -2
  178. package/dist/server/app-ssr-stream.js.map +1 -1
  179. package/dist/server/app-static-generation.d.ts +15 -0
  180. package/dist/server/app-static-generation.js +20 -0
  181. package/dist/server/app-static-generation.js.map +1 -0
  182. package/dist/server/cache-control.d.ts +24 -0
  183. package/dist/server/cache-control.js +33 -0
  184. package/dist/server/cache-control.js.map +1 -0
  185. package/dist/server/dev-error-overlay-store.d.ts +23 -0
  186. package/dist/server/dev-error-overlay-store.js +67 -0
  187. package/dist/server/dev-error-overlay-store.js.map +1 -0
  188. package/dist/server/dev-error-overlay.d.ts +15 -0
  189. package/dist/server/dev-error-overlay.js +548 -0
  190. package/dist/server/dev-error-overlay.js.map +1 -0
  191. package/dist/server/dev-route-files.d.ts +7 -0
  192. package/dist/server/dev-route-files.js +73 -0
  193. package/dist/server/dev-route-files.js.map +1 -0
  194. package/dist/server/dev-server.js +4 -0
  195. package/dist/server/dev-server.js.map +1 -1
  196. package/dist/server/file-based-metadata.d.ts +17 -0
  197. package/dist/server/file-based-metadata.js +356 -0
  198. package/dist/server/file-based-metadata.js.map +1 -0
  199. package/dist/server/implicit-tags.d.ts +6 -0
  200. package/dist/server/implicit-tags.js +42 -0
  201. package/dist/server/implicit-tags.js.map +1 -0
  202. package/dist/server/instrumentation-runtime.d.ts +44 -0
  203. package/dist/server/instrumentation-runtime.js +29 -0
  204. package/dist/server/instrumentation-runtime.js.map +1 -0
  205. package/dist/server/instrumentation.js.map +1 -1
  206. package/dist/server/isr-cache.d.ts +16 -3
  207. package/dist/server/isr-cache.js +56 -8
  208. package/dist/server/isr-cache.js.map +1 -1
  209. package/dist/server/metadata-route-build-data.d.ts +25 -0
  210. package/dist/server/metadata-route-build-data.js +150 -0
  211. package/dist/server/metadata-route-build-data.js.map +1 -0
  212. package/dist/server/metadata-route-response.d.ts +17 -0
  213. package/dist/server/metadata-route-response.js +187 -0
  214. package/dist/server/metadata-route-response.js.map +1 -0
  215. package/dist/server/metadata-routes.d.ts +42 -4
  216. package/dist/server/metadata-routes.js +127 -11
  217. package/dist/server/metadata-routes.js.map +1 -1
  218. package/dist/server/middleware-matcher.d.ts +15 -0
  219. package/dist/server/middleware-matcher.js +102 -0
  220. package/dist/server/middleware-matcher.js.map +1 -0
  221. package/dist/server/middleware-request-headers.js +2 -1
  222. package/dist/server/middleware-request-headers.js.map +1 -1
  223. package/dist/server/middleware-runtime.d.ts +39 -0
  224. package/dist/server/middleware-runtime.js +159 -0
  225. package/dist/server/middleware-runtime.js.map +1 -0
  226. package/dist/server/middleware.d.ts +4 -36
  227. package/dist/server/middleware.js +18 -228
  228. package/dist/server/middleware.js.map +1 -1
  229. package/dist/server/pages-page-data.d.ts +7 -2
  230. package/dist/server/pages-page-data.js +10 -5
  231. package/dist/server/pages-page-data.js.map +1 -1
  232. package/dist/server/pages-page-response.d.ts +2 -1
  233. package/dist/server/pages-page-response.js +5 -3
  234. package/dist/server/pages-page-response.js.map +1 -1
  235. package/dist/server/prerender-work-unit-setup.d.ts +7 -0
  236. package/dist/server/prerender-work-unit-setup.js +30 -0
  237. package/dist/server/prerender-work-unit-setup.js.map +1 -0
  238. package/dist/server/prod-server.js +10 -14
  239. package/dist/server/prod-server.js.map +1 -1
  240. package/dist/server/request-pipeline.d.ts +46 -5
  241. package/dist/server/request-pipeline.js +84 -5
  242. package/dist/server/request-pipeline.js.map +1 -1
  243. package/dist/server/rsc-stream-hints.d.ts +7 -0
  244. package/dist/server/rsc-stream-hints.js +38 -0
  245. package/dist/server/rsc-stream-hints.js.map +1 -0
  246. package/dist/server/seed-cache.js +19 -8
  247. package/dist/server/seed-cache.js.map +1 -1
  248. package/dist/server/server-action-not-found.d.ts +9 -0
  249. package/dist/server/server-action-not-found.js +40 -0
  250. package/dist/server/server-action-not-found.js.map +1 -0
  251. package/dist/shims/cache-runtime.js +28 -11
  252. package/dist/shims/cache-runtime.js.map +1 -1
  253. package/dist/shims/cache.d.ts +39 -4
  254. package/dist/shims/cache.js +93 -16
  255. package/dist/shims/cache.js.map +1 -1
  256. package/dist/shims/error-boundary.d.ts +66 -5
  257. package/dist/shims/error-boundary.js +106 -4
  258. package/dist/shims/error-boundary.js.map +1 -1
  259. package/dist/shims/fetch-cache.d.ts +4 -1
  260. package/dist/shims/fetch-cache.js +55 -13
  261. package/dist/shims/fetch-cache.js.map +1 -1
  262. package/dist/shims/font-google-base.d.ts +5 -4
  263. package/dist/shims/font-google-base.js +61 -13
  264. package/dist/shims/font-google-base.js.map +1 -1
  265. package/dist/shims/headers.d.ts +14 -2
  266. package/dist/shims/headers.js +127 -17
  267. package/dist/shims/headers.js.map +1 -1
  268. package/dist/shims/image.js +116 -10
  269. package/dist/shims/image.js.map +1 -1
  270. package/dist/shims/internal/make-hanging-promise.d.ts +16 -0
  271. package/dist/shims/internal/make-hanging-promise.js +46 -0
  272. package/dist/shims/internal/make-hanging-promise.js.map +1 -0
  273. package/dist/shims/internal/work-unit-async-storage.d.ts +26 -3
  274. package/dist/shims/internal/work-unit-async-storage.js +6 -3
  275. package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
  276. package/dist/shims/metadata.d.ts +38 -26
  277. package/dist/shims/metadata.js +75 -45
  278. package/dist/shims/metadata.js.map +1 -1
  279. package/dist/shims/navigation.d.ts +10 -1
  280. package/dist/shims/navigation.js +18 -1
  281. package/dist/shims/navigation.js.map +1 -1
  282. package/dist/shims/navigation.react-server.d.ts +2 -2
  283. package/dist/shims/navigation.react-server.js +2 -2
  284. package/dist/shims/navigation.react-server.js.map +1 -1
  285. package/dist/shims/offline.d.ts +5 -0
  286. package/dist/shims/offline.js +17 -0
  287. package/dist/shims/offline.js.map +1 -0
  288. package/dist/shims/request-state-types.d.ts +3 -2
  289. package/dist/shims/root-params.d.ts +11 -0
  290. package/dist/shims/root-params.js +24 -0
  291. package/dist/shims/root-params.js.map +1 -0
  292. package/dist/shims/router.js +1 -1
  293. package/dist/shims/server.d.ts +3 -1
  294. package/dist/shims/server.js +83 -5
  295. package/dist/shims/server.js.map +1 -1
  296. package/dist/shims/thenable-params.d.ts +5 -0
  297. package/dist/shims/thenable-params.js +37 -0
  298. package/dist/shims/thenable-params.js.map +1 -0
  299. package/dist/shims/unified-request-context.d.ts +3 -2
  300. package/dist/shims/unified-request-context.js +3 -0
  301. package/dist/shims/unified-request-context.js.map +1 -1
  302. package/dist/shims/use-merged-ref.d.ts +7 -0
  303. package/dist/shims/use-merged-ref.js +40 -0
  304. package/dist/shims/use-merged-ref.js.map +1 -0
  305. package/dist/utils/cache-control-metadata.d.ts +6 -0
  306. package/dist/utils/cache-control-metadata.js +16 -0
  307. package/dist/utils/cache-control-metadata.js.map +1 -0
  308. package/package.json +6 -1
  309. package/dist/server/middleware-codegen.d.ts +0 -54
  310. package/dist/server/middleware-codegen.js +0 -414
  311. package/dist/server/middleware-codegen.js.map +0 -1
@@ -0,0 +1,27 @@
1
+ //#region src/server/app-rsc-errors.d.ts
2
+ type RscRequestInfo = {
3
+ path: string;
4
+ method: string;
5
+ headers: Record<string, string>;
6
+ };
7
+ type RscErrorContext = {
8
+ routerKind: "App Router";
9
+ routePath: string;
10
+ routeType: "render";
11
+ };
12
+ type RscErrorReporter = (error: Error, requestInfo: RscRequestInfo, errorContext: RscErrorContext) => void;
13
+ type CreateRscOnErrorHandlerOptions = {
14
+ errorContext: RscErrorContext | null;
15
+ nodeEnv?: string;
16
+ reportRequestError: RscErrorReporter;
17
+ requestInfo: RscRequestInfo | null;
18
+ };
19
+ /**
20
+ * djb2 hash matching Next.js's string-hash package for RSC error digests.
21
+ */
22
+ declare function errorDigest(input: string): string;
23
+ declare function sanitizeErrorForClient(error: unknown, nodeEnv?: string | undefined): unknown;
24
+ declare function createRscOnErrorHandler(options: CreateRscOnErrorHandlerOptions): (error: unknown) => string | undefined;
25
+ //#endregion
26
+ export { createRscOnErrorHandler, errorDigest, sanitizeErrorForClient };
27
+ //# sourceMappingURL=app-rsc-errors.d.ts.map
@@ -0,0 +1,42 @@
1
+ import { resolveAppPageSpecialError } from "./app-page-execution.js";
2
+ //#region src/server/app-rsc-errors.ts
3
+ function hasDigest(error) {
4
+ return Boolean(error && typeof error === "object" && "digest" in error);
5
+ }
6
+ function getThrownValueMessage(error) {
7
+ return error instanceof Error ? error.message : String(error);
8
+ }
9
+ function getThrownValueStack(error) {
10
+ return error instanceof Error ? error.stack || "" : "";
11
+ }
12
+ /**
13
+ * djb2 hash matching Next.js's string-hash package for RSC error digests.
14
+ */
15
+ function errorDigest(input) {
16
+ let hash = 5381;
17
+ for (let i = input.length - 1; i >= 0; i--) hash = hash * 33 ^ input.charCodeAt(i);
18
+ return (hash >>> 0).toString();
19
+ }
20
+ function sanitizeErrorForClient(error, nodeEnv = process.env.NODE_ENV) {
21
+ if (resolveAppPageSpecialError(error)) return error;
22
+ if (nodeEnv !== "production") return error;
23
+ const sanitized = /* @__PURE__ */ new Error("An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.");
24
+ sanitized.digest = errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));
25
+ return sanitized;
26
+ }
27
+ function createRscOnErrorHandler(options) {
28
+ return (error) => {
29
+ const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV;
30
+ if (hasDigest(error)) return String(error.digest);
31
+ if (nodeEnv !== "production" && error instanceof Error && error.message.includes("Only plain objects, and a few built-ins, can be passed to Client Components")) {
32
+ console.error("[vinext] RSC serialization error: a non-plain object was passed from a Server Component to a Client Component.\n\nCommon causes:\n * Passing a module namespace (import * as X) directly as a prop.\n Unlike Next.js (webpack), Vite produces real ESM module namespace objects\n which are not serializable. Fix: pass individual values instead,\n e.g. <Comp value={module.value} />\n * Passing a class instance (new Foo()) as a prop.\n Fix: convert to a plain object, e.g. { id: foo.id, name: foo.name }\n * Passing a Date, Map, or Set. Use .toISOString(), [...map.entries()], etc.\n * Passing Object.create(null). Use { ...obj } to restore a prototype.\n\nOriginal error:", error.message);
33
+ return;
34
+ }
35
+ if (options.requestInfo && options.errorContext && error) options.reportRequestError(error instanceof Error ? error : new Error(getThrownValueMessage(error)), options.requestInfo, options.errorContext);
36
+ if (nodeEnv === "production" && error) return errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));
37
+ };
38
+ }
39
+ //#endregion
40
+ export { createRscOnErrorHandler, errorDigest, sanitizeErrorForClient };
41
+
42
+ //# sourceMappingURL=app-rsc-errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-rsc-errors.js","names":[],"sources":["../../src/server/app-rsc-errors.ts"],"sourcesContent":["import { resolveAppPageSpecialError } from \"./app-page-execution.js\";\n\ntype DigestError = Error & { digest?: string };\n\ntype RscRequestInfo = {\n path: string;\n method: string;\n headers: Record<string, string>;\n};\n\ntype RscErrorContext = {\n routerKind: \"App Router\";\n routePath: string;\n routeType: \"render\";\n};\n\ntype RscErrorReporter = (\n error: Error,\n requestInfo: RscRequestInfo,\n errorContext: RscErrorContext,\n) => void;\n\ntype CreateRscOnErrorHandlerOptions = {\n errorContext: RscErrorContext | null;\n nodeEnv?: string;\n reportRequestError: RscErrorReporter;\n requestInfo: RscRequestInfo | null;\n};\n\nfunction hasDigest(error: unknown): error is { digest: unknown } {\n return Boolean(error && typeof error === \"object\" && \"digest\" in error);\n}\n\nfunction getThrownValueMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction getThrownValueStack(error: unknown): string {\n return error instanceof Error ? error.stack || \"\" : \"\";\n}\n\n/**\n * djb2 hash matching Next.js's string-hash package for RSC error digests.\n */\nexport function errorDigest(input: string): string {\n let hash = 5381;\n for (let i = input.length - 1; i >= 0; i--) {\n hash = (hash * 33) ^ input.charCodeAt(i);\n }\n return (hash >>> 0).toString();\n}\n\nexport function sanitizeErrorForClient(error: unknown, nodeEnv = process.env.NODE_ENV): unknown {\n if (resolveAppPageSpecialError(error)) {\n return error;\n }\n\n if (nodeEnv !== \"production\") {\n return error;\n }\n\n const sanitized: DigestError = new Error(\n \"An error occurred in the Server Components render. \" +\n \"The specific message is omitted in production builds to avoid leaking sensitive details. \" +\n \"A digest property is included on this error instance which may provide additional details about the nature of the error.\",\n );\n sanitized.digest = errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));\n return sanitized;\n}\n\nexport function createRscOnErrorHandler(\n options: CreateRscOnErrorHandlerOptions,\n): (error: unknown) => string | undefined {\n return (error) => {\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV;\n\n if (hasDigest(error)) {\n return String(error.digest);\n }\n\n if (\n nodeEnv !== \"production\" &&\n error instanceof Error &&\n error.message.includes(\n \"Only plain objects, and a few built-ins, can be passed to Client Components\",\n )\n ) {\n console.error(\n \"[vinext] RSC serialization error: a non-plain object was passed from a Server Component to a Client Component.\\n\" +\n \"\\n\" +\n \"Common causes:\\n\" +\n \" * Passing a module namespace (import * as X) directly as a prop.\\n\" +\n \" Unlike Next.js (webpack), Vite produces real ESM module namespace objects\\n\" +\n \" which are not serializable. Fix: pass individual values instead,\\n\" +\n \" e.g. <Comp value={module.value} />\\n\" +\n \" * Passing a class instance (new Foo()) as a prop.\\n\" +\n \" Fix: convert to a plain object, e.g. { id: foo.id, name: foo.name }\\n\" +\n \" * Passing a Date, Map, or Set. Use .toISOString(), [...map.entries()], etc.\\n\" +\n \" * Passing Object.create(null). Use { ...obj } to restore a prototype.\\n\" +\n \"\\n\" +\n \"Original error:\",\n error.message,\n );\n return undefined;\n }\n\n if (options.requestInfo && options.errorContext && error) {\n options.reportRequestError(\n error instanceof Error ? error : new Error(getThrownValueMessage(error)),\n options.requestInfo,\n options.errorContext,\n );\n }\n\n if (nodeEnv === \"production\" && error) {\n return errorDigest(getThrownValueMessage(error) + getThrownValueStack(error));\n }\n\n return undefined;\n };\n}\n"],"mappings":";;AA6BA,SAAS,UAAU,OAA8C;AAC/D,QAAO,QAAQ,SAAS,OAAO,UAAU,YAAY,YAAY,MAAM;;AAGzE,SAAS,sBAAsB,OAAwB;AACrD,QAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;AAG/D,SAAS,oBAAoB,OAAwB;AACnD,QAAO,iBAAiB,QAAQ,MAAM,SAAS,KAAK;;;;;AAMtD,SAAgB,YAAY,OAAuB;CACjD,IAAI,OAAO;AACX,MAAK,IAAI,IAAI,MAAM,SAAS,GAAG,KAAK,GAAG,IACrC,QAAQ,OAAO,KAAM,MAAM,WAAW,EAAE;AAE1C,SAAQ,SAAS,GAAG,UAAU;;AAGhC,SAAgB,uBAAuB,OAAgB,UAAU,QAAQ,IAAI,UAAmB;AAC9F,KAAI,2BAA2B,MAAM,CACnC,QAAO;AAGT,KAAI,YAAY,aACd,QAAO;CAGT,MAAM,4BAAyB,IAAI,MACjC,uQAGD;AACD,WAAU,SAAS,YAAY,sBAAsB,MAAM,GAAG,oBAAoB,MAAM,CAAC;AACzF,QAAO;;AAGT,SAAgB,wBACd,SACwC;AACxC,SAAQ,UAAU;EAChB,MAAM,UAAU,QAAQ,WAAW,QAAQ,IAAI;AAE/C,MAAI,UAAU,MAAM,CAClB,QAAO,OAAO,MAAM,OAAO;AAG7B,MACE,YAAY,gBACZ,iBAAiB,SACjB,MAAM,QAAQ,SACZ,8EACD,EACD;AACA,WAAQ,MACN,8qBAaA,MAAM,QACP;AACD;;AAGF,MAAI,QAAQ,eAAe,QAAQ,gBAAgB,MACjD,SAAQ,mBACN,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,sBAAsB,MAAM,CAAC,EACxE,QAAQ,aACR,QAAQ,aACT;AAGH,MAAI,YAAY,gBAAgB,MAC9B,QAAO,YAAY,sBAAsB,MAAM,GAAG,oBAAoB,MAAM,CAAC"}
@@ -0,0 +1,117 @@
1
+ import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
2
+ import { MiddlewareModule } from "./middleware-runtime.js";
3
+ import { AppMiddlewareContext } from "./app-middleware.js";
4
+ import { handleAppPrerenderEndpoint } from "./app-prerender-endpoints.js";
5
+ import { handleMetadataRouteRequest } from "./metadata-route-response.js";
6
+
7
+ //#region src/server/app-rsc-handler.d.ts
8
+ type AppPageParams = Record<string, string | string[]>;
9
+ type MetadataRoutes = Parameters<typeof handleMetadataRouteRequest>[0]["metadataRoutes"];
10
+ type MakeThenableParams = Parameters<typeof handleMetadataRouteRequest>[0]["makeThenableParams"];
11
+ type StaticParamsMap = Parameters<typeof handleAppPrerenderEndpoint>[1]["staticParamsMap"];
12
+ type RootParamNamesMap = Parameters<typeof handleAppPrerenderEndpoint>[1]["rootParamNamesByPattern"];
13
+ type AppRscMiddlewareContext = AppMiddlewareContext;
14
+ type AppRscHandlerRoute = {
15
+ page?: unknown;
16
+ pattern: string;
17
+ rootParamNames?: readonly string[];
18
+ routeHandler?: unknown;
19
+ routeSegments: readonly string[];
20
+ };
21
+ type AppRscRouteMatch<TRoute> = {
22
+ params: AppPageParams;
23
+ route: TRoute;
24
+ };
25
+ type DispatchMatchedPageOptions<TRoute> = {
26
+ cleanPathname: string;
27
+ handlerStart: number;
28
+ interceptionContext: string | null;
29
+ isRscRequest: boolean;
30
+ middlewareContext: AppRscMiddlewareContext;
31
+ mountedSlotsHeader: string | null;
32
+ params: AppPageParams;
33
+ request: Request;
34
+ route: TRoute;
35
+ scriptNonce?: string;
36
+ searchParams: URLSearchParams;
37
+ };
38
+ type DispatchMatchedRouteHandlerOptions<TRoute> = {
39
+ cleanPathname: string;
40
+ middlewareContext: AppRscMiddlewareContext;
41
+ params: AppPageParams;
42
+ request: Request;
43
+ route: TRoute;
44
+ searchParams: URLSearchParams;
45
+ };
46
+ type HandleProgressiveActionRequestOptions = {
47
+ actionId: string | null;
48
+ cleanPathname: string;
49
+ contentType: string;
50
+ middlewareContext: AppRscMiddlewareContext;
51
+ request: Request;
52
+ };
53
+ type HandleServerActionRequestOptions = {
54
+ actionId: string | null;
55
+ cleanPathname: string;
56
+ contentType: string;
57
+ interceptionContext: string | null;
58
+ isRscRequest: boolean;
59
+ middlewareContext: AppRscMiddlewareContext;
60
+ mountedSlotsHeader: string | null;
61
+ request: Request;
62
+ searchParams: URLSearchParams;
63
+ };
64
+ type RenderNotFoundOptions<TRoute> = {
65
+ isRscRequest: boolean;
66
+ matchedParams?: AppPageParams;
67
+ middlewareContext: AppRscMiddlewareContext;
68
+ request: Request;
69
+ route: TRoute | null;
70
+ scriptNonce?: string;
71
+ };
72
+ type RenderPagesFallbackOptions = {
73
+ isRscRequest: boolean;
74
+ middlewareContext: AppRscMiddlewareContext;
75
+ request: Request;
76
+ url: URL;
77
+ };
78
+ type NavigationContextValue = {
79
+ params: AppPageParams;
80
+ pathname: string;
81
+ searchParams: URLSearchParams;
82
+ };
83
+ type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
84
+ basePath: string;
85
+ clearRequestContext: () => void;
86
+ configHeaders: NextHeader[];
87
+ configRedirects: NextRedirect[];
88
+ configRewrites: {
89
+ afterFiles: NextRewrite[];
90
+ beforeFiles: NextRewrite[];
91
+ fallback: NextRewrite[];
92
+ };
93
+ dispatchMatchedPage: (options: DispatchMatchedPageOptions<TRoute>) => Promise<Response>;
94
+ dispatchMatchedRouteHandler: (options: DispatchMatchedRouteHandlerOptions<TRoute>) => Promise<Response>;
95
+ ensureInstrumentation?: () => Promise<void>;
96
+ handleProgressiveActionRequest: (options: HandleProgressiveActionRequestOptions) => Promise<Response | null>;
97
+ handleServerActionRequest: (options: HandleServerActionRequestOptions) => Promise<Response | null>;
98
+ i18nConfig: NextI18nConfig | null;
99
+ isMiddlewareProxy: boolean;
100
+ loadPrerenderPagesRoutes?: () => Promise<unknown>;
101
+ makeThenableParams: MakeThenableParams;
102
+ matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;
103
+ metadataRoutes: MetadataRoutes;
104
+ middlewareModule: MiddlewareModule | null;
105
+ publicFiles: ReadonlySet<string>;
106
+ renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;
107
+ renderPagesFallback?: (options: RenderPagesFallbackOptions) => Promise<Response | null>;
108
+ rootParamNamesByPattern?: RootParamNamesMap;
109
+ setNavigationContext: (context: NavigationContextValue) => void;
110
+ staticParamsMap: StaticParamsMap;
111
+ trailingSlash: boolean;
112
+ validateDevRequestOrigin?: (request: Request) => Response | null;
113
+ };
114
+ declare function createAppRscHandler<TRoute extends AppRscHandlerRoute>(options: CreateAppRscHandlerOptions<TRoute>): (request: Request, ctx: unknown) => Promise<Response>;
115
+ //#endregion
116
+ export { createAppRscHandler };
117
+ //# sourceMappingURL=app-rsc-handler.d.ts.map
@@ -0,0 +1,260 @@
1
+ import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
2
+ import { getRequestExecutionContext } from "../shims/request-context.js";
3
+ import { isExternalUrl, matchRedirect, matchRewrite, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
4
+ import { hasBasePath } from "../utils/base-path.js";
5
+ import { normalizeTrailingSlash, resolvePublicFileRoute, validateImageUrl } from "./request-pipeline.js";
6
+ import { headersContextFromRequest } from "../shims/headers.js";
7
+ import { ensureFetchPatch, setCurrentFetchSoftTags } from "../shims/fetch-cache.js";
8
+ import { getScriptNonceFromHeaderSources } from "./csp.js";
9
+ import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
10
+ import { applyAppMiddleware } from "./app-middleware.js";
11
+ import { buildPageCacheTags } from "./implicit-tags.js";
12
+ import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
13
+ import { pickRootParams, setRootParams } from "../shims/root-params.js";
14
+ import { handleAppPrerenderEndpoint } from "./app-prerender-endpoints.js";
15
+ import { flattenErrorCauses } from "../utils/error-cause.js";
16
+ import { finalizeAppRscResponse } from "./app-rsc-response-finalizer.js";
17
+ import { normalizeRscRequest } from "./app-rsc-request-normalization.js";
18
+ import { handleMetadataRouteRequest } from "./metadata-route-response.js";
19
+ import { runWithPrerenderWorkUnit } from "./prerender-work-unit-setup.js";
20
+ //#region src/server/app-rsc-handler.ts
21
+ function hasProperty(value, key) {
22
+ return key in value;
23
+ }
24
+ function isExecutionContextLike(value) {
25
+ if (!value || typeof value !== "object") return false;
26
+ return hasProperty(value, "waitUntil") && typeof value.waitUntil === "function";
27
+ }
28
+ function redirectDestinationWithBasePath(destination, basePath) {
29
+ if (!basePath || isExternalUrl(destination) || hasBasePath(destination, basePath)) return destination;
30
+ return basePath + destination;
31
+ }
32
+ async function applyRewrite(options, cleanPathname) {
33
+ if (!options.rewrites.length) return null;
34
+ const rewritten = matchRewrite(cleanPathname, options.rewrites, options.requestContext);
35
+ if (!rewritten) return null;
36
+ if (isExternalUrl(rewritten)) {
37
+ options.clearRequestContext();
38
+ return proxyExternalRequest(options.request, rewritten);
39
+ }
40
+ return rewritten;
41
+ }
42
+ async function handleAppRscRequest(options, request, preMiddlewareRequestContext) {
43
+ const handlerStart = process.env.NODE_ENV !== "production" ? performance.now() : 0;
44
+ if (process.env.NODE_ENV !== "production") {
45
+ const originBlock = options.validateDevRequestOrigin?.(request);
46
+ if (originBlock) return originBlock;
47
+ }
48
+ const normalized = normalizeRscRequest(request, options.basePath);
49
+ if (normalized instanceof Response) return normalized;
50
+ const { url, isRscRequest, interceptionContextHeader, mountedSlotsHeader } = normalized;
51
+ let { pathname, cleanPathname } = normalized;
52
+ const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {
53
+ isPrerenderEnabled() {
54
+ return process.env.VINEXT_PRERENDER === "1";
55
+ },
56
+ loadPagesRoutes: options.loadPrerenderPagesRoutes,
57
+ pathname,
58
+ rootParamNamesByPattern: options.rootParamNamesByPattern,
59
+ staticParamsMap: options.staticParamsMap
60
+ });
61
+ if (prerenderEndpointResponse) return prerenderEndpointResponse;
62
+ const trailingSlashRedirect = normalizeTrailingSlash(pathname, options.basePath, options.trailingSlash, url.search);
63
+ if (trailingSlashRedirect) return trailingSlashRedirect;
64
+ const redirect = matchRedirect(pathname.endsWith(".rsc") ? pathname.slice(0, -4) : pathname, options.configRedirects, preMiddlewareRequestContext);
65
+ if (redirect) {
66
+ const destination = sanitizeDestination(redirectDestinationWithBasePath(redirect.destination, options.basePath));
67
+ return new Response(null, {
68
+ status: redirect.permanent ? 308 : 307,
69
+ headers: { Location: destination }
70
+ });
71
+ }
72
+ const middlewareContext = {
73
+ headers: null,
74
+ requestHeaders: null,
75
+ status: null
76
+ };
77
+ if (options.middlewareModule) {
78
+ const middlewareResult = await applyAppMiddleware({
79
+ basePath: options.basePath,
80
+ cleanPathname,
81
+ context: middlewareContext,
82
+ i18nConfig: options.i18nConfig,
83
+ isProxy: options.isMiddlewareProxy,
84
+ module: options.middlewareModule,
85
+ request
86
+ });
87
+ if (middlewareResult.kind === "response") return middlewareResult.response;
88
+ cleanPathname = middlewareResult.cleanPathname;
89
+ if (middlewareResult.search !== null) url.search = middlewareResult.search;
90
+ }
91
+ const scriptNonce = getScriptNonceFromHeaderSources(request.headers, middlewareContext.headers);
92
+ const postMiddlewareRequestContext = buildPostMwRequestContext(request);
93
+ const beforeFilesRewrite = await applyRewrite({
94
+ clearRequestContext: options.clearRequestContext,
95
+ request,
96
+ requestContext: postMiddlewareRequestContext,
97
+ rewrites: options.configRewrites.beforeFiles
98
+ }, cleanPathname);
99
+ if (beforeFilesRewrite instanceof Response) return beforeFilesRewrite;
100
+ if (beforeFilesRewrite) cleanPathname = beforeFilesRewrite;
101
+ if (cleanPathname === "/_vinext/image") {
102
+ const imageUrlResult = validateImageUrl(url.searchParams.get("url"), request.url);
103
+ if (imageUrlResult instanceof Response) return imageUrlResult;
104
+ return Response.redirect(new URL(imageUrlResult, url.origin).href, 302);
105
+ }
106
+ const metadataRouteResponse = await handleMetadataRouteRequest({
107
+ metadataRoutes: options.metadataRoutes,
108
+ cleanPathname,
109
+ makeThenableParams: options.makeThenableParams
110
+ });
111
+ if (metadataRouteResponse) return metadataRouteResponse;
112
+ const publicFileResponse = resolvePublicFileRoute({
113
+ cleanPathname,
114
+ middlewareContext,
115
+ pathname,
116
+ publicFiles: options.publicFiles,
117
+ request
118
+ });
119
+ if (publicFileResponse) {
120
+ options.clearRequestContext();
121
+ return publicFileResponse;
122
+ }
123
+ options.setNavigationContext({
124
+ pathname: cleanPathname,
125
+ searchParams: url.searchParams,
126
+ params: {}
127
+ });
128
+ const actionId = request.headers.get("x-rsc-action") ?? request.headers.get("next-action");
129
+ const contentType = request.headers.get("content-type") || "";
130
+ const progressiveActionResponse = await options.handleProgressiveActionRequest({
131
+ actionId,
132
+ cleanPathname,
133
+ contentType,
134
+ middlewareContext,
135
+ request
136
+ });
137
+ if (progressiveActionResponse) return progressiveActionResponse;
138
+ const serverActionResponse = await options.handleServerActionRequest({
139
+ actionId,
140
+ cleanPathname,
141
+ contentType,
142
+ interceptionContext: interceptionContextHeader,
143
+ isRscRequest,
144
+ middlewareContext,
145
+ mountedSlotsHeader,
146
+ request,
147
+ searchParams: url.searchParams
148
+ });
149
+ if (serverActionResponse) return serverActionResponse;
150
+ const afterFilesRewrite = await applyRewrite({
151
+ clearRequestContext: options.clearRequestContext,
152
+ request,
153
+ requestContext: postMiddlewareRequestContext,
154
+ rewrites: options.configRewrites.afterFiles
155
+ }, cleanPathname);
156
+ if (afterFilesRewrite instanceof Response) return afterFilesRewrite;
157
+ if (afterFilesRewrite) cleanPathname = afterFilesRewrite;
158
+ let match = options.matchRoute(cleanPathname);
159
+ if (!match) {
160
+ const fallbackRewrite = await applyRewrite({
161
+ clearRequestContext: options.clearRequestContext,
162
+ request,
163
+ requestContext: postMiddlewareRequestContext,
164
+ rewrites: options.configRewrites.fallback
165
+ }, cleanPathname);
166
+ if (fallbackRewrite instanceof Response) return fallbackRewrite;
167
+ if (fallbackRewrite) {
168
+ cleanPathname = fallbackRewrite;
169
+ match = options.matchRoute(cleanPathname);
170
+ }
171
+ }
172
+ if (!match) {
173
+ const pagesFallbackResponse = await options.renderPagesFallback?.({
174
+ isRscRequest,
175
+ middlewareContext,
176
+ request,
177
+ url
178
+ });
179
+ if (pagesFallbackResponse) {
180
+ options.clearRequestContext();
181
+ return pagesFallbackResponse;
182
+ }
183
+ const notFoundResponse = await options.renderNotFound({
184
+ isRscRequest,
185
+ middlewareContext,
186
+ request,
187
+ route: null,
188
+ scriptNonce
189
+ });
190
+ if (notFoundResponse) return notFoundResponse;
191
+ options.clearRequestContext();
192
+ const headers = new Headers();
193
+ mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);
194
+ return new Response("Not Found", {
195
+ status: 404,
196
+ headers
197
+ });
198
+ }
199
+ const { route, params } = match;
200
+ options.setNavigationContext({
201
+ pathname: cleanPathname,
202
+ searchParams: url.searchParams,
203
+ params
204
+ });
205
+ setRootParams(pickRootParams(params, route.rootParamNames));
206
+ if (route.routeHandler) {
207
+ setCurrentFetchSoftTags(buildPageCacheTags(cleanPathname, [], [...route.routeSegments], "route"));
208
+ return options.dispatchMatchedRouteHandler({
209
+ cleanPathname,
210
+ middlewareContext,
211
+ params,
212
+ request,
213
+ route,
214
+ searchParams: url.searchParams
215
+ });
216
+ }
217
+ return options.dispatchMatchedPage({
218
+ cleanPathname,
219
+ handlerStart,
220
+ interceptionContext: interceptionContextHeader,
221
+ isRscRequest,
222
+ middlewareContext,
223
+ mountedSlotsHeader,
224
+ params,
225
+ request,
226
+ route,
227
+ scriptNonce,
228
+ searchParams: url.searchParams
229
+ });
230
+ }
231
+ function createAppRscHandler(options) {
232
+ return async function appRscHandler(request, ctx) {
233
+ await options.ensureInstrumentation?.();
234
+ const executionContext = isExecutionContextLike(ctx) ? ctx : getRequestExecutionContext() ?? null;
235
+ return runWithRequestContext(createRequestContext({
236
+ headersContext: headersContextFromRequest(request),
237
+ executionContext,
238
+ unstableCacheRevalidation: "background"
239
+ }), () => runWithPrerenderWorkUnit(async () => {
240
+ ensureFetchPatch();
241
+ const preMiddlewareRequestContext = requestContextFromRequest(request);
242
+ let response;
243
+ try {
244
+ response = await handleAppRscRequest(options, request, preMiddlewareRequestContext);
245
+ } catch (error) {
246
+ if (process.env.NODE_ENV !== "production") flattenErrorCauses(error);
247
+ throw error;
248
+ }
249
+ return finalizeAppRscResponse(response, request, {
250
+ basePath: options.basePath,
251
+ configHeaders: options.configHeaders,
252
+ requestContext: preMiddlewareRequestContext
253
+ });
254
+ }, { route: () => new URL(request.url).pathname }));
255
+ };
256
+ }
257
+ //#endregion
258
+ export { createAppRscHandler };
259
+
260
+ //# sourceMappingURL=app-rsc-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-rsc-handler.js","names":[],"sources":["../../src/server/app-rsc-handler.ts"],"sourcesContent":["import type {\n NextHeader,\n NextI18nConfig,\n NextRedirect,\n NextRewrite,\n} from \"../config/next-config.js\";\nimport {\n isExternalUrl,\n matchRedirect,\n matchRewrite,\n proxyExternalRequest,\n requestContextFromRequest,\n sanitizeDestination,\n} from \"../config/config-matchers.js\";\nimport { headersContextFromRequest } from \"vinext/shims/headers\";\nimport { ensureFetchPatch, setCurrentFetchSoftTags } from \"vinext/shims/fetch-cache\";\nimport {\n getRequestExecutionContext,\n type ExecutionContextLike,\n} from \"vinext/shims/request-context\";\nimport { pickRootParams, setRootParams } from \"vinext/shims/root-params\";\nimport { createRequestContext, runWithRequestContext } from \"vinext/shims/unified-request-context\";\nimport { flattenErrorCauses } from \"../utils/error-cause.js\";\nimport { hasBasePath } from \"../utils/base-path.js\";\nimport { applyAppMiddleware, type AppMiddlewareContext } from \"./app-middleware.js\";\nimport { mergeMiddlewareResponseHeaders } from \"./app-page-response.js\";\nimport { handleAppPrerenderEndpoint } from \"./app-prerender-endpoints.js\";\nimport { finalizeAppRscResponse } from \"./app-rsc-response-finalizer.js\";\nimport { normalizeRscRequest } from \"./app-rsc-request-normalization.js\";\nimport { getScriptNonceFromHeaderSources } from \"./csp.js\";\nimport { buildPageCacheTags } from \"./implicit-tags.js\";\nimport { handleMetadataRouteRequest } from \"./metadata-route-response.js\";\nimport type { MiddlewareModule } from \"./middleware-runtime.js\";\nimport { runWithPrerenderWorkUnit } from \"./prerender-work-unit-setup.js\";\nimport { buildPostMwRequestContext } from \"./app-post-middleware-context.js\";\nimport {\n normalizeTrailingSlash,\n resolvePublicFileRoute,\n validateImageUrl,\n} from \"./request-pipeline.js\";\n\ntype AppPageParams = Record<string, string | string[]>;\ntype RequestContext = ReturnType<typeof requestContextFromRequest>;\ntype MetadataRoutes = Parameters<typeof handleMetadataRouteRequest>[0][\"metadataRoutes\"];\ntype MakeThenableParams = Parameters<typeof handleMetadataRouteRequest>[0][\"makeThenableParams\"];\ntype StaticParamsMap = Parameters<typeof handleAppPrerenderEndpoint>[1][\"staticParamsMap\"];\ntype RootParamNamesMap = Parameters<\n typeof handleAppPrerenderEndpoint\n>[1][\"rootParamNamesByPattern\"];\n\ntype AppRscMiddlewareContext = AppMiddlewareContext;\n\ntype AppRscHandlerRoute = {\n page?: unknown;\n pattern: string;\n rootParamNames?: readonly string[];\n routeHandler?: unknown;\n routeSegments: readonly string[];\n};\n\ntype AppRscRouteMatch<TRoute> = {\n params: AppPageParams;\n route: TRoute;\n};\n\ntype DispatchMatchedPageOptions<TRoute> = {\n cleanPathname: string;\n handlerStart: number;\n interceptionContext: string | null;\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n mountedSlotsHeader: string | null;\n params: AppPageParams;\n request: Request;\n route: TRoute;\n scriptNonce?: string;\n searchParams: URLSearchParams;\n};\n\ntype DispatchMatchedRouteHandlerOptions<TRoute> = {\n cleanPathname: string;\n middlewareContext: AppRscMiddlewareContext;\n params: AppPageParams;\n request: Request;\n route: TRoute;\n searchParams: URLSearchParams;\n};\n\ntype HandleProgressiveActionRequestOptions = {\n actionId: string | null;\n cleanPathname: string;\n contentType: string;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n};\n\ntype HandleServerActionRequestOptions = {\n actionId: string | null;\n cleanPathname: string;\n contentType: string;\n interceptionContext: string | null;\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n mountedSlotsHeader: string | null;\n request: Request;\n searchParams: URLSearchParams;\n};\n\ntype RenderNotFoundOptions<TRoute> = {\n isRscRequest: boolean;\n matchedParams?: AppPageParams;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n route: TRoute | null;\n scriptNonce?: string;\n};\n\ntype RenderPagesFallbackOptions = {\n isRscRequest: boolean;\n middlewareContext: AppRscMiddlewareContext;\n request: Request;\n url: URL;\n};\n\ntype NavigationContextValue = {\n params: AppPageParams;\n pathname: string;\n searchParams: URLSearchParams;\n};\n\ntype CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {\n basePath: string;\n clearRequestContext: () => void;\n configHeaders: NextHeader[];\n configRedirects: NextRedirect[];\n configRewrites: {\n afterFiles: NextRewrite[];\n beforeFiles: NextRewrite[];\n fallback: NextRewrite[];\n };\n dispatchMatchedPage: (options: DispatchMatchedPageOptions<TRoute>) => Promise<Response>;\n dispatchMatchedRouteHandler: (\n options: DispatchMatchedRouteHandlerOptions<TRoute>,\n ) => Promise<Response>;\n ensureInstrumentation?: () => Promise<void>;\n handleProgressiveActionRequest: (\n options: HandleProgressiveActionRequestOptions,\n ) => Promise<Response | null>;\n handleServerActionRequest: (\n options: HandleServerActionRequestOptions,\n ) => Promise<Response | null>;\n i18nConfig: NextI18nConfig | null;\n isMiddlewareProxy: boolean;\n loadPrerenderPagesRoutes?: () => Promise<unknown>;\n makeThenableParams: MakeThenableParams;\n matchRoute: (pathname: string) => AppRscRouteMatch<TRoute> | null;\n metadataRoutes: MetadataRoutes;\n middlewareModule: MiddlewareModule | null;\n publicFiles: ReadonlySet<string>;\n renderNotFound: (options: RenderNotFoundOptions<TRoute>) => Promise<Response | null>;\n renderPagesFallback?: (options: RenderPagesFallbackOptions) => Promise<Response | null>;\n rootParamNamesByPattern?: RootParamNamesMap;\n setNavigationContext: (context: NavigationContextValue) => void;\n staticParamsMap: StaticParamsMap;\n trailingSlash: boolean;\n validateDevRequestOrigin?: (request: Request) => Response | null;\n};\n\nfunction hasProperty<TKey extends PropertyKey>(\n value: object,\n key: TKey,\n): value is object & Record<TKey, unknown> {\n return key in value;\n}\n\nfunction isExecutionContextLike(value: unknown): value is ExecutionContextLike {\n if (!value || typeof value !== \"object\") return false;\n return hasProperty(value, \"waitUntil\") && typeof value.waitUntil === \"function\";\n}\n\nfunction redirectDestinationWithBasePath(destination: string, basePath: string): string {\n if (!basePath || isExternalUrl(destination) || hasBasePath(destination, basePath)) {\n return destination;\n }\n return basePath + destination;\n}\n\nasync function applyRewrite(\n options: {\n clearRequestContext: () => void;\n request: Request;\n requestContext: RequestContext;\n rewrites: NextRewrite[];\n },\n cleanPathname: string,\n): Promise<Response | string | null> {\n if (!options.rewrites.length) return null;\n\n const rewritten = matchRewrite(cleanPathname, options.rewrites, options.requestContext);\n if (!rewritten) return null;\n\n if (isExternalUrl(rewritten)) {\n options.clearRequestContext();\n return proxyExternalRequest(options.request, rewritten);\n }\n\n return rewritten;\n}\n\nasync function handleAppRscRequest<TRoute extends AppRscHandlerRoute>(\n options: CreateAppRscHandlerOptions<TRoute>,\n request: Request,\n preMiddlewareRequestContext: RequestContext,\n): Promise<Response> {\n const handlerStart = process.env.NODE_ENV !== \"production\" ? performance.now() : 0;\n\n if (process.env.NODE_ENV !== \"production\") {\n const originBlock = options.validateDevRequestOrigin?.(request);\n if (originBlock) return originBlock;\n }\n\n const normalized = normalizeRscRequest(request, options.basePath);\n if (normalized instanceof Response) return normalized;\n\n const { url, isRscRequest, interceptionContextHeader, mountedSlotsHeader } = normalized;\n let { pathname, cleanPathname } = normalized;\n\n const prerenderEndpointResponse = await handleAppPrerenderEndpoint(request, {\n isPrerenderEnabled() {\n return process.env.VINEXT_PRERENDER === \"1\";\n },\n loadPagesRoutes: options.loadPrerenderPagesRoutes,\n pathname,\n rootParamNamesByPattern: options.rootParamNamesByPattern,\n staticParamsMap: options.staticParamsMap,\n });\n if (prerenderEndpointResponse) return prerenderEndpointResponse;\n\n const trailingSlashRedirect = normalizeTrailingSlash(\n pathname,\n options.basePath,\n options.trailingSlash,\n url.search,\n );\n if (trailingSlashRedirect) return trailingSlashRedirect;\n\n const redirectPathname = pathname.endsWith(\".rsc\") ? pathname.slice(0, -4) : pathname;\n const redirect = matchRedirect(\n redirectPathname,\n options.configRedirects,\n preMiddlewareRequestContext,\n );\n if (redirect) {\n const destination = sanitizeDestination(\n redirectDestinationWithBasePath(redirect.destination, options.basePath),\n );\n return new Response(null, {\n status: redirect.permanent ? 308 : 307,\n headers: { Location: destination },\n });\n }\n\n const middlewareContext: AppRscMiddlewareContext = {\n headers: null,\n requestHeaders: null,\n status: null,\n };\n\n if (options.middlewareModule) {\n const middlewareResult = await applyAppMiddleware({\n basePath: options.basePath,\n cleanPathname,\n context: middlewareContext,\n i18nConfig: options.i18nConfig,\n isProxy: options.isMiddlewareProxy,\n module: options.middlewareModule,\n request,\n });\n if (middlewareResult.kind === \"response\") return middlewareResult.response;\n\n cleanPathname = middlewareResult.cleanPathname;\n if (middlewareResult.search !== null) {\n url.search = middlewareResult.search;\n }\n }\n\n const scriptNonce = getScriptNonceFromHeaderSources(request.headers, middlewareContext.headers);\n const postMiddlewareRequestContext = buildPostMwRequestContext(request);\n\n const beforeFilesRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.beforeFiles,\n },\n cleanPathname,\n );\n if (beforeFilesRewrite instanceof Response) return beforeFilesRewrite;\n if (beforeFilesRewrite) cleanPathname = beforeFilesRewrite;\n\n if (cleanPathname === \"/_vinext/image\") {\n const imageUrlResult = validateImageUrl(url.searchParams.get(\"url\"), request.url);\n if (imageUrlResult instanceof Response) return imageUrlResult;\n return Response.redirect(new URL(imageUrlResult, url.origin).href, 302);\n }\n\n const metadataRouteResponse = await handleMetadataRouteRequest({\n metadataRoutes: options.metadataRoutes,\n cleanPathname,\n makeThenableParams: options.makeThenableParams,\n });\n if (metadataRouteResponse) return metadataRouteResponse;\n\n const publicFileResponse = resolvePublicFileRoute({\n cleanPathname,\n middlewareContext,\n pathname,\n publicFiles: options.publicFiles,\n request,\n });\n if (publicFileResponse) {\n options.clearRequestContext();\n return publicFileResponse;\n }\n\n options.setNavigationContext({\n pathname: cleanPathname,\n searchParams: url.searchParams,\n params: {},\n });\n\n const actionId = request.headers.get(\"x-rsc-action\") ?? request.headers.get(\"next-action\");\n const contentType = request.headers.get(\"content-type\") || \"\";\n\n const progressiveActionResponse = await options.handleProgressiveActionRequest({\n actionId,\n cleanPathname,\n contentType,\n middlewareContext,\n request,\n });\n if (progressiveActionResponse) return progressiveActionResponse;\n\n const serverActionResponse = await options.handleServerActionRequest({\n actionId,\n cleanPathname,\n contentType,\n interceptionContext: interceptionContextHeader,\n isRscRequest,\n middlewareContext,\n mountedSlotsHeader,\n request,\n searchParams: url.searchParams,\n });\n if (serverActionResponse) return serverActionResponse;\n\n const afterFilesRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.afterFiles,\n },\n cleanPathname,\n );\n if (afterFilesRewrite instanceof Response) return afterFilesRewrite;\n if (afterFilesRewrite) cleanPathname = afterFilesRewrite;\n\n let match = options.matchRoute(cleanPathname);\n if (!match) {\n const fallbackRewrite = await applyRewrite(\n {\n clearRequestContext: options.clearRequestContext,\n request,\n requestContext: postMiddlewareRequestContext,\n rewrites: options.configRewrites.fallback,\n },\n cleanPathname,\n );\n if (fallbackRewrite instanceof Response) return fallbackRewrite;\n if (fallbackRewrite) {\n cleanPathname = fallbackRewrite;\n match = options.matchRoute(cleanPathname);\n }\n }\n\n if (!match) {\n const pagesFallbackResponse = await options.renderPagesFallback?.({\n isRscRequest,\n middlewareContext,\n request,\n url,\n });\n if (pagesFallbackResponse) {\n options.clearRequestContext();\n return pagesFallbackResponse;\n }\n\n const notFoundResponse = await options.renderNotFound({\n isRscRequest,\n middlewareContext,\n request,\n route: null,\n scriptNonce,\n });\n if (notFoundResponse) return notFoundResponse;\n\n options.clearRequestContext();\n const headers = new Headers();\n mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);\n return new Response(\"Not Found\", { status: 404, headers });\n }\n\n const { route, params } = match;\n options.setNavigationContext({\n pathname: cleanPathname,\n searchParams: url.searchParams,\n params,\n });\n setRootParams(pickRootParams(params, route.rootParamNames));\n\n if (route.routeHandler) {\n setCurrentFetchSoftTags(\n buildPageCacheTags(cleanPathname, [], [...route.routeSegments], \"route\"),\n );\n return options.dispatchMatchedRouteHandler({\n cleanPathname,\n middlewareContext,\n params,\n request,\n route,\n searchParams: url.searchParams,\n });\n }\n\n return options.dispatchMatchedPage({\n cleanPathname,\n handlerStart,\n interceptionContext: interceptionContextHeader,\n isRscRequest,\n middlewareContext,\n mountedSlotsHeader,\n params,\n request,\n route,\n scriptNonce,\n searchParams: url.searchParams,\n });\n}\n\nexport function createAppRscHandler<TRoute extends AppRscHandlerRoute>(\n options: CreateAppRscHandlerOptions<TRoute>,\n): (request: Request, ctx: unknown) => Promise<Response> {\n return async function appRscHandler(request, ctx) {\n await options.ensureInstrumentation?.();\n\n const executionContext = isExecutionContextLike(ctx)\n ? ctx\n : (getRequestExecutionContext() ?? null);\n const headersContext = headersContextFromRequest(request);\n const requestContext = createRequestContext({\n headersContext,\n executionContext,\n unstableCacheRevalidation: \"background\",\n });\n\n return runWithRequestContext(requestContext, () =>\n runWithPrerenderWorkUnit(\n async () => {\n ensureFetchPatch();\n const preMiddlewareRequestContext = requestContextFromRequest(request);\n let response: Response;\n\n try {\n response = await handleAppRscRequest(options, request, preMiddlewareRequestContext);\n } catch (error) {\n if (process.env.NODE_ENV !== \"production\") {\n flattenErrorCauses(error);\n }\n throw error;\n }\n\n return finalizeAppRscResponse(response, request, {\n basePath: options.basePath,\n configHeaders: options.configHeaders,\n requestContext: preMiddlewareRequestContext,\n });\n },\n { route: () => new URL(request.url).pathname },\n ),\n );\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
2
+
3
+ //#region src/server/app-rsc-request-normalization.d.ts
4
+ type NormalizedRscRequest = {
5
+ /** Parsed URL. Callers may mutate `url.search` after middleware runs. */url: URL; /** Normalized pathname with basePath stripped. Used for all internal routing. */
6
+ pathname: string; /** Pathname with `.rsc` suffix removed. Used for route matching and navigation context. */
7
+ cleanPathname: string; /** True when the client requests the RSC payload (.rsc suffix or Accept: text/x-component). */
8
+ isRscRequest: boolean; /** Sanitized X-Vinext-Interception-Context header (null bytes stripped). null when absent. */
9
+ interceptionContextHeader: string | null; /** Normalized x-vinext-mounted-slots header (deduplicated, sorted). null when absent or blank. */
10
+ mountedSlotsHeader: string | null;
11
+ };
12
+ /**
13
+ * Normalize an App Router RSC request.
14
+ *
15
+ * Performs all security-sensitive and compatibility-sensitive preprocessing before
16
+ * route matching. The ordering of steps is security-critical — changing it introduces
17
+ * vulnerabilities:
18
+ *
19
+ * 1. Parse URL
20
+ * 2. Protocol-relative URL guard — on the raw pathname, BEFORE normalizePath collapses
21
+ * `//` to `/`. If the guard ran after normalization, `//evil.com` → `/evil.com`
22
+ * would bypass the check and reach the trailing-slash redirector, which echoes the
23
+ * path into a `Location` header that browsers interpret as protocol-relative.
24
+ * 3. Strict percent-decode each segment — throws on malformed sequences (→ 400). Must
25
+ * run before basePath check so %2F-encoded slashes cannot create fake basePath prefixes.
26
+ * 4. Collapse double-slashes, resolve `.` and `..` segments (normalizePath)
27
+ * 5. basePath check + strip — 404 when pathname lacks the basePath prefix.
28
+ * `/__vinext/` bypasses this for internal prerender endpoints.
29
+ * 6. RSC detection: `.rsc` suffix or `Accept: text/x-component`
30
+ * 7. cleanPathname — pathname with `.rsc` suffix stripped
31
+ * 8. Sanitize X-Vinext-Interception-Context — strip null bytes (header injection)
32
+ * 9. Normalize x-vinext-mounted-slots — dedup and sort for canonical cache keys
33
+ *
34
+ * @returns A 400 or 404 Response for invalid or out-of-scope inputs,
35
+ * or a NormalizedRscRequest for valid requests.
36
+ */
37
+ declare function normalizeRscRequest(request: Request, basePath: string): Response | NormalizedRscRequest;
38
+ //#endregion
39
+ export { NormalizedRscRequest, normalizeMountedSlotsHeader, normalizeRscRequest };
40
+ //# sourceMappingURL=app-rsc-request-normalization.d.ts.map
@@ -0,0 +1,63 @@
1
+ import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
2
+ import { normalizePath } from "./normalize-path.js";
3
+ import { hasBasePath, stripBasePath } from "../utils/base-path.js";
4
+ import { guardProtocolRelativeUrl } from "./request-pipeline.js";
5
+ import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
6
+ //#region src/server/app-rsc-request-normalization.ts
7
+ /**
8
+ * Normalize an App Router RSC request.
9
+ *
10
+ * Performs all security-sensitive and compatibility-sensitive preprocessing before
11
+ * route matching. The ordering of steps is security-critical — changing it introduces
12
+ * vulnerabilities:
13
+ *
14
+ * 1. Parse URL
15
+ * 2. Protocol-relative URL guard — on the raw pathname, BEFORE normalizePath collapses
16
+ * `//` to `/`. If the guard ran after normalization, `//evil.com` → `/evil.com`
17
+ * would bypass the check and reach the trailing-slash redirector, which echoes the
18
+ * path into a `Location` header that browsers interpret as protocol-relative.
19
+ * 3. Strict percent-decode each segment — throws on malformed sequences (→ 400). Must
20
+ * run before basePath check so %2F-encoded slashes cannot create fake basePath prefixes.
21
+ * 4. Collapse double-slashes, resolve `.` and `..` segments (normalizePath)
22
+ * 5. basePath check + strip — 404 when pathname lacks the basePath prefix.
23
+ * `/__vinext/` bypasses this for internal prerender endpoints.
24
+ * 6. RSC detection: `.rsc` suffix or `Accept: text/x-component`
25
+ * 7. cleanPathname — pathname with `.rsc` suffix stripped
26
+ * 8. Sanitize X-Vinext-Interception-Context — strip null bytes (header injection)
27
+ * 9. Normalize x-vinext-mounted-slots — dedup and sort for canonical cache keys
28
+ *
29
+ * @returns A 400 or 404 Response for invalid or out-of-scope inputs,
30
+ * or a NormalizedRscRequest for valid requests.
31
+ */
32
+ function normalizeRscRequest(request, basePath) {
33
+ const url = new URL(request.url);
34
+ const protoGuard = guardProtocolRelativeUrl(url.pathname);
35
+ if (protoGuard) return protoGuard;
36
+ let decoded;
37
+ try {
38
+ decoded = normalizePathnameForRouteMatchStrict(url.pathname);
39
+ } catch {
40
+ return new Response("Bad Request", { status: 400 });
41
+ }
42
+ let pathname = normalizePath(decoded);
43
+ if (basePath) {
44
+ if (!hasBasePath(pathname, basePath) && !pathname.startsWith("/__vinext/")) return new Response("Not Found", { status: 404 });
45
+ pathname = stripBasePath(pathname, basePath);
46
+ }
47
+ const isRscRequest = pathname.endsWith(".rsc") || (request.headers.get("accept")?.includes("text/x-component") ?? false);
48
+ const cleanPathname = pathname.replace(/\.rsc$/, "");
49
+ const interceptionContextHeader = request.headers.get("X-Vinext-Interception-Context")?.replaceAll("\0", "") || null;
50
+ const mountedSlotsHeader = normalizeMountedSlotsHeader(request.headers.get("x-vinext-mounted-slots"));
51
+ return {
52
+ url,
53
+ pathname,
54
+ cleanPathname,
55
+ isRscRequest,
56
+ interceptionContextHeader,
57
+ mountedSlotsHeader
58
+ };
59
+ }
60
+ //#endregion
61
+ export { normalizeMountedSlotsHeader, normalizeRscRequest };
62
+
63
+ //# sourceMappingURL=app-rsc-request-normalization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-rsc-request-normalization.js","names":[],"sources":["../../src/server/app-rsc-request-normalization.ts"],"sourcesContent":["import { normalizePath } from \"./normalize-path.js\";\nimport { normalizePathnameForRouteMatchStrict } from \"../routing/utils.js\";\nimport { guardProtocolRelativeUrl } from \"./request-pipeline.js\";\nimport { hasBasePath, stripBasePath } from \"../utils/base-path.js\";\nimport { normalizeMountedSlotsHeader } from \"./app-mounted-slots-header.js\";\n\nexport { normalizeMountedSlotsHeader } from \"./app-mounted-slots-header.js\";\n\nexport type NormalizedRscRequest = {\n /** Parsed URL. Callers may mutate `url.search` after middleware runs. */\n url: URL;\n /** Normalized pathname with basePath stripped. Used for all internal routing. */\n pathname: string;\n /** Pathname with `.rsc` suffix removed. Used for route matching and navigation context. */\n cleanPathname: string;\n /** True when the client requests the RSC payload (.rsc suffix or Accept: text/x-component). */\n isRscRequest: boolean;\n /** Sanitized X-Vinext-Interception-Context header (null bytes stripped). null when absent. */\n interceptionContextHeader: string | null;\n /** Normalized x-vinext-mounted-slots header (deduplicated, sorted). null when absent or blank. */\n mountedSlotsHeader: string | null;\n};\n\n/**\n * Normalize an App Router RSC request.\n *\n * Performs all security-sensitive and compatibility-sensitive preprocessing before\n * route matching. The ordering of steps is security-critical — changing it introduces\n * vulnerabilities:\n *\n * 1. Parse URL\n * 2. Protocol-relative URL guard — on the raw pathname, BEFORE normalizePath collapses\n * `//` to `/`. If the guard ran after normalization, `//evil.com` → `/evil.com`\n * would bypass the check and reach the trailing-slash redirector, which echoes the\n * path into a `Location` header that browsers interpret as protocol-relative.\n * 3. Strict percent-decode each segment — throws on malformed sequences (→ 400). Must\n * run before basePath check so %2F-encoded slashes cannot create fake basePath prefixes.\n * 4. Collapse double-slashes, resolve `.` and `..` segments (normalizePath)\n * 5. basePath check + strip — 404 when pathname lacks the basePath prefix.\n * `/__vinext/` bypasses this for internal prerender endpoints.\n * 6. RSC detection: `.rsc` suffix or `Accept: text/x-component`\n * 7. cleanPathname — pathname with `.rsc` suffix stripped\n * 8. Sanitize X-Vinext-Interception-Context — strip null bytes (header injection)\n * 9. Normalize x-vinext-mounted-slots — dedup and sort for canonical cache keys\n *\n * @returns A 400 or 404 Response for invalid or out-of-scope inputs,\n * or a NormalizedRscRequest for valid requests.\n */\nexport function normalizeRscRequest(\n request: Request,\n basePath: string,\n): Response | NormalizedRscRequest {\n const url = new URL(request.url);\n\n // Step 2: Guard against protocol-relative open redirects on the raw pathname.\n // normalizePath (step 4) would collapse //evil.com to /evil.com, causing the\n // guard to miss it. Raw pathname must be checked first.\n const protoGuard = guardProtocolRelativeUrl(url.pathname);\n if (protoGuard) return protoGuard;\n\n // Step 3: Strict segment-wise percent-decode. Preserves encoded path delimiters\n // (%2F stays %2F) to prevent encoded slashes from acting as path separators.\n // Throws on malformed sequences like %GG — caller must return 400.\n let decoded: string;\n try {\n decoded = normalizePathnameForRouteMatchStrict(url.pathname);\n } catch {\n return new Response(\"Bad Request\", { status: 400 });\n }\n\n // Step 4: Collapse double-slashes and resolve . / .. segments.\n let pathname = normalizePath(decoded);\n\n // Step 5: basePath check and strip.\n // Skipped when basePath is empty (no basePath configured).\n // /__vinext/ prefix bypasses the check for internal prerender endpoints\n // that must be reachable regardless of basePath configuration.\n if (basePath) {\n if (!hasBasePath(pathname, basePath) && !pathname.startsWith(\"/__vinext/\")) {\n return new Response(\"Not Found\", { status: 404 });\n }\n pathname = stripBasePath(pathname, basePath);\n }\n\n // Steps 6-7: RSC detection and cleanPathname.\n const isRscRequest =\n pathname.endsWith(\".rsc\") ||\n (request.headers.get(\"accept\")?.includes(\"text/x-component\") ?? false);\n const cleanPathname = pathname.replace(/\\.rsc$/, \"\");\n\n // Step 8: Sanitize X-Vinext-Interception-Context.\n // Null bytes in header values can be used for injection in some HTTP stacks.\n const interceptionContextHeader =\n request.headers.get(\"X-Vinext-Interception-Context\")?.replaceAll(\"\\0\", \"\") || null;\n\n // Step 9: Normalize mounted-slots header for canonical cache keying.\n const mountedSlotsHeader = normalizeMountedSlotsHeader(\n request.headers.get(\"x-vinext-mounted-slots\"),\n );\n\n return {\n url,\n pathname,\n cleanPathname,\n isRscRequest,\n interceptionContextHeader,\n mountedSlotsHeader,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgDA,SAAgB,oBACd,SACA,UACiC;CACjC,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;CAKhC,MAAM,aAAa,yBAAyB,IAAI,SAAS;AACzD,KAAI,WAAY,QAAO;CAKvB,IAAI;AACJ,KAAI;AACF,YAAU,qCAAqC,IAAI,SAAS;SACtD;AACN,SAAO,IAAI,SAAS,eAAe,EAAE,QAAQ,KAAK,CAAC;;CAIrD,IAAI,WAAW,cAAc,QAAQ;AAMrC,KAAI,UAAU;AACZ,MAAI,CAAC,YAAY,UAAU,SAAS,IAAI,CAAC,SAAS,WAAW,aAAa,CACxE,QAAO,IAAI,SAAS,aAAa,EAAE,QAAQ,KAAK,CAAC;AAEnD,aAAW,cAAc,UAAU,SAAS;;CAI9C,MAAM,eACJ,SAAS,SAAS,OAAO,KACxB,QAAQ,QAAQ,IAAI,SAAS,EAAE,SAAS,mBAAmB,IAAI;CAClE,MAAM,gBAAgB,SAAS,QAAQ,UAAU,GAAG;CAIpD,MAAM,4BACJ,QAAQ,QAAQ,IAAI,gCAAgC,EAAE,WAAW,MAAM,GAAG,IAAI;CAGhF,MAAM,qBAAqB,4BACzB,QAAQ,QAAQ,IAAI,yBAAyB,CAC9C;AAED,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACD"}