vinext 1.0.1 → 1.2.0

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 (334) hide show
  1. package/README.md +93 -10
  2. package/dist/build/app-page-static-eligibility.d.ts +15 -0
  3. package/dist/build/app-page-static-eligibility.js +82 -0
  4. package/dist/build/client-build-config.d.ts +10 -0
  5. package/dist/build/client-build-config.js +18 -2
  6. package/dist/build/pages-client-assets-module.d.ts +8 -0
  7. package/dist/build/pages-client-assets-module.js +21 -1
  8. package/dist/build/prerender-paths.js +8 -81
  9. package/dist/build/prerender.js +33 -8
  10. package/dist/build/run-prerender.js +1 -1
  11. package/dist/build/server-manifest.d.ts +7 -0
  12. package/dist/build/server-manifest.js +11 -1
  13. package/dist/build/ssr-manifest.d.ts +2 -0
  14. package/dist/build/ssr-manifest.js +6 -2
  15. package/dist/cache/cache-adapters-virtual.d.ts +7 -1
  16. package/dist/cache/cache-adapters-virtual.js +3 -3
  17. package/dist/check.js +7 -6
  18. package/dist/cli.js +2 -1
  19. package/dist/client/client-redirect-matcher.d.ts +14 -0
  20. package/dist/client/client-redirect-matcher.js +37 -0
  21. package/dist/client/client-redirects.d.ts +27 -0
  22. package/dist/client/client-redirects.js +28 -0
  23. package/dist/client/client-rewrites.d.ts +2 -1
  24. package/dist/client/client-rewrites.js +1 -1
  25. package/dist/client/navigation-runtime.d.ts +11 -0
  26. package/dist/client/navigation-runtime.js +1 -1
  27. package/dist/config/config-matchers.d.ts +26 -11
  28. package/dist/config/config-matchers.js +81 -82
  29. package/dist/config/destination-params.d.ts +47 -0
  30. package/dist/config/destination-params.js +116 -0
  31. package/dist/config/next-config.d.ts +14 -0
  32. package/dist/config/next-config.js +21 -3
  33. package/dist/entries/app-rsc-entry.d.ts +6 -0
  34. package/dist/entries/app-rsc-entry.js +84 -49
  35. package/dist/entries/pages-client-entry.js +3 -1
  36. package/dist/entries/pages-server-entry.js +13 -37
  37. package/dist/index.d.ts +7 -2
  38. package/dist/index.js +193 -73
  39. package/dist/init-cloudflare.d.ts +9 -0
  40. package/dist/init-cloudflare.js +107 -31
  41. package/dist/init-platform.d.ts +4 -0
  42. package/dist/init-platform.js +27 -2
  43. package/dist/init.d.ts +1 -0
  44. package/dist/init.js +67 -3
  45. package/dist/plugins/ast-scope.d.ts +7 -0
  46. package/dist/plugins/ast-scope.js +59 -3
  47. package/dist/plugins/cache-flight-codec.d.ts +19 -0
  48. package/dist/plugins/cache-flight-codec.js +68 -0
  49. package/dist/plugins/commonjs-esm-facade.d.ts +35 -0
  50. package/dist/plugins/commonjs-esm-facade.js +80 -0
  51. package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
  52. package/dist/plugins/dynamic-preload-metadata.js +9 -8
  53. package/dist/plugins/fonts.d.ts +8 -11
  54. package/dist/plugins/fonts.js +71 -34
  55. package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
  56. package/dist/plugins/ignore-dynamic-requests.js +3 -4
  57. package/dist/plugins/middleware-server-only.d.ts +5 -4
  58. package/dist/plugins/middleware-server-only.js +8 -5
  59. package/dist/plugins/pages-node-externals.js +1 -1
  60. package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
  61. package/dist/plugins/rsc-scan-glob-imports.js +50 -0
  62. package/dist/plugins/strip-server-exports.js +262 -98
  63. package/dist/plugins/transform-result.d.ts +9 -5
  64. package/dist/plugins/transitive-externals.js +1 -1
  65. package/dist/plugins/typeof-window.d.ts +2 -2
  66. package/dist/plugins/use-cache-callable.js +8 -2
  67. package/dist/plugins/worker-server-only-imports.d.ts +20 -0
  68. package/dist/plugins/worker-server-only-imports.js +31 -0
  69. package/dist/plugins/worker-use-server.d.ts +25 -0
  70. package/dist/plugins/worker-use-server.js +129 -0
  71. package/dist/routing/file-matcher.d.ts +1 -0
  72. package/dist/routing/file-matcher.js +1 -1
  73. package/dist/server/api-handler.d.ts +1 -0
  74. package/dist/server/api-handler.js +19 -8
  75. package/dist/server/app-browser-action-result.d.ts +1 -1
  76. package/dist/server/app-browser-action-result.js +9 -2
  77. package/dist/server/app-browser-entry.js +11 -7
  78. package/dist/server/app-browser-history-controller.d.ts +2 -0
  79. package/dist/server/app-browser-history-controller.js +8 -0
  80. package/dist/server/app-browser-interception-context.js +26 -2
  81. package/dist/server/app-browser-navigation-controller.d.ts +7 -1
  82. package/dist/server/app-browser-navigation-controller.js +94 -11
  83. package/dist/server/app-browser-server-action-client.js +1 -1
  84. package/dist/server/app-fallback-renderer.d.ts +2 -0
  85. package/dist/server/app-fallback-renderer.js +1 -0
  86. package/dist/server/app-history-state.d.ts +3 -0
  87. package/dist/server/app-history-state.js +7 -0
  88. package/dist/server/app-middleware.d.ts +11 -0
  89. package/dist/server/app-middleware.js +19 -3
  90. package/dist/server/app-optimistic-routing.js +1 -1
  91. package/dist/server/app-page-boundary-render.d.ts +5 -0
  92. package/dist/server/app-page-boundary-render.js +6 -4
  93. package/dist/server/app-page-cache-finalizer.d.ts +11 -0
  94. package/dist/server/app-page-cache-finalizer.js +41 -7
  95. package/dist/server/app-page-cache-render.d.ts +18 -0
  96. package/dist/server/app-page-cache-render.js +63 -43
  97. package/dist/server/app-page-cache.d.ts +6 -1
  98. package/dist/server/app-page-cache.js +28 -8
  99. package/dist/server/app-page-dispatch.d.ts +12 -2
  100. package/dist/server/app-page-dispatch.js +51 -33
  101. package/dist/server/app-page-element-builder.d.ts +7 -0
  102. package/dist/server/app-page-element-builder.js +27 -42
  103. package/dist/server/app-page-execution.d.ts +15 -12
  104. package/dist/server/app-page-execution.js +30 -40
  105. package/dist/server/app-page-head.d.ts +5 -0
  106. package/dist/server/app-page-head.js +9 -3
  107. package/dist/server/app-page-ppr-runtime.js +1 -1
  108. package/dist/server/app-page-probe.d.ts +0 -109
  109. package/dist/server/app-page-probe.js +3 -136
  110. package/dist/server/app-page-render-identity.d.ts +0 -1
  111. package/dist/server/app-page-render-identity.js +1 -1
  112. package/dist/server/app-page-render-observation.js +3 -3
  113. package/dist/server/app-page-render.d.ts +13 -5
  114. package/dist/server/app-page-render.js +219 -119
  115. package/dist/server/app-page-request.d.ts +0 -1
  116. package/dist/server/app-page-request.js +54 -17
  117. package/dist/server/app-page-response.d.ts +4 -3
  118. package/dist/server/app-page-response.js +4 -3
  119. package/dist/server/app-page-route-wiring.d.ts +17 -5
  120. package/dist/server/app-page-route-wiring.js +57 -35
  121. package/dist/server/app-page-rsc-render-status.d.ts +48 -0
  122. package/dist/server/app-page-rsc-render-status.js +54 -0
  123. package/dist/server/app-page-stream.d.ts +15 -8
  124. package/dist/server/app-page-stream.js +6 -0
  125. package/dist/server/app-pages-bridge.d.ts +1 -1
  126. package/dist/server/app-pages-bridge.js +2 -3
  127. package/dist/server/app-prerender-endpoints.js +9 -6
  128. package/dist/server/app-request-stage-dispatch.js +7 -3
  129. package/dist/server/app-request-stage-independent-entry.js +29 -9
  130. package/dist/server/app-response-header-provenance.d.ts +2 -0
  131. package/dist/server/app-response-header-provenance.js +10 -4
  132. package/dist/server/app-response-stage-entry.js +10 -2
  133. package/dist/server/app-route-handler-cache.d.ts +1 -0
  134. package/dist/server/app-route-handler-cache.js +1 -0
  135. package/dist/server/app-route-handler-dispatch.d.ts +1 -0
  136. package/dist/server/app-route-handler-dispatch.js +6 -3
  137. package/dist/server/app-route-handler-execution.d.ts +1 -0
  138. package/dist/server/app-route-handler-execution.js +1 -0
  139. package/dist/server/app-route-handler-runtime.d.ts +4 -1
  140. package/dist/server/app-route-handler-runtime.js +45 -24
  141. package/dist/server/app-router-entry.js +27 -8
  142. package/dist/server/app-rsc-cache-busting.js +1 -1
  143. package/dist/server/app-rsc-errors.js +20 -16
  144. package/dist/server/app-rsc-handler.d.ts +11 -0
  145. package/dist/server/app-rsc-handler.js +291 -125
  146. package/dist/server/app-rsc-request-normalization.d.ts +3 -1
  147. package/dist/server/app-rsc-request-normalization.js +4 -2
  148. package/dist/server/app-rsc-response-stage.d.ts +1 -1
  149. package/dist/server/app-rsc-response-stage.js +10 -6
  150. package/dist/server/app-rsc-route-matching.d.ts +9 -1
  151. package/dist/server/app-rsc-route-matching.js +36 -19
  152. package/dist/server/app-segment-config.d.ts +2 -1
  153. package/dist/server/app-server-action-execution.d.ts +2 -1
  154. package/dist/server/app-server-action-execution.js +62 -23
  155. package/dist/server/app-ssr-entry.d.ts +3 -2
  156. package/dist/server/app-ssr-entry.js +8 -5
  157. package/dist/server/app-ssr-stream.d.ts +6 -1
  158. package/dist/server/app-ssr-stream.js +34 -15
  159. package/dist/server/app-worker-stages.d.ts +7 -2
  160. package/dist/server/app-worker-stages.js +4 -4
  161. package/dist/server/cacheability-request.js +11 -7
  162. package/dist/server/client-build-files.d.ts +16 -0
  163. package/dist/server/client-build-files.js +36 -0
  164. package/dist/server/client-reuse-manifest.js +1 -1
  165. package/dist/server/config-headers.js +2 -0
  166. package/dist/server/dev-server.js +50 -29
  167. package/dist/server/dev-stack-sourcemap.js +18 -23
  168. package/dist/server/document-initial-head.d.ts +0 -11
  169. package/dist/server/document-initial-head.js +1 -1
  170. package/dist/server/forwarded-middleware-context.d.ts +5 -0
  171. package/dist/server/forwarded-middleware-context.js +22 -0
  172. package/dist/server/headers.d.ts +18 -1
  173. package/dist/server/headers.js +19 -2
  174. package/dist/server/http-conditional.d.ts +11 -0
  175. package/dist/server/http-conditional.js +10 -1
  176. package/dist/server/http-error-responses.d.ts +1 -1
  177. package/dist/server/image-optimization.d.ts +54 -0
  178. package/dist/server/image-optimization.js +118 -9
  179. package/dist/server/isr-cache.d.ts +10 -0
  180. package/dist/server/isr-cache.js +43 -8
  181. package/dist/server/metadata-route-response.js +9 -8
  182. package/dist/server/middleware-matcher-pattern.js +8 -4
  183. package/dist/server/middleware-matcher.d.ts +2 -0
  184. package/dist/server/middleware-matcher.js +23 -2
  185. package/dist/server/middleware-response-headers.js +2 -0
  186. package/dist/server/middleware-runtime.d.ts +13 -0
  187. package/dist/server/middleware-runtime.js +33 -20
  188. package/dist/server/middleware.d.ts +1 -1
  189. package/dist/server/middleware.js +3 -1
  190. package/dist/server/multi-stage.d.ts +19 -0
  191. package/dist/server/navigation-planner.js +1 -1
  192. package/dist/server/node-response-signal.d.ts +16 -0
  193. package/dist/server/node-response-signal.js +26 -0
  194. package/dist/server/normalize-path.d.ts +0 -13
  195. package/dist/server/normalize-path.js +1 -34
  196. package/dist/server/open-redirect.d.ts +47 -0
  197. package/dist/server/open-redirect.js +74 -1
  198. package/dist/server/pages-api-route.d.ts +3 -2
  199. package/dist/server/pages-api-route.js +4 -3
  200. package/dist/server/pages-cache-tag.d.ts +12 -0
  201. package/dist/server/pages-cache-tag.js +19 -0
  202. package/dist/server/pages-client-assets.d.ts +2 -0
  203. package/dist/server/pages-data-route.d.ts +10 -0
  204. package/dist/server/pages-data-route.js +19 -2
  205. package/dist/server/pages-document-asset-props.d.ts +5 -1
  206. package/dist/server/pages-document-asset-props.js +13 -5
  207. package/dist/server/pages-document-splice.d.ts +19 -0
  208. package/dist/server/pages-document-splice.js +55 -0
  209. package/dist/server/pages-i18n.d.ts +12 -1
  210. package/dist/server/pages-i18n.js +18 -4
  211. package/dist/server/pages-node-compat.d.ts +16 -5
  212. package/dist/server/pages-node-compat.js +20 -12
  213. package/dist/server/pages-page-data.d.ts +32 -24
  214. package/dist/server/pages-page-data.js +50 -120
  215. package/dist/server/pages-page-handler.d.ts +0 -6
  216. package/dist/server/pages-page-handler.js +209 -130
  217. package/dist/server/pages-page-response.d.ts +12 -6
  218. package/dist/server/pages-page-response.js +41 -34
  219. package/dist/server/pages-request-pipeline.d.ts +10 -2
  220. package/dist/server/pages-request-pipeline.js +37 -18
  221. package/dist/server/pages-request-stage-entry.d.ts +6 -0
  222. package/dist/server/pages-request-stage-entry.js +79 -16
  223. package/dist/server/pages-response-stage-entry.js +4 -0
  224. package/dist/server/pages-revalidate.js +1 -1
  225. package/dist/server/pages-router-entry.js +4 -3
  226. package/dist/server/prerender-manifest.d.ts +3 -3
  227. package/dist/server/prerender-manifest.js +4 -3
  228. package/dist/server/prerender-work-unit-setup.js +4 -0
  229. package/dist/server/prod-server.d.ts +20 -7
  230. package/dist/server/prod-server.js +343 -129
  231. package/dist/server/proper-error.d.ts +4 -0
  232. package/dist/server/proper-error.js +31 -0
  233. package/dist/server/request-pipeline.d.ts +24 -9
  234. package/dist/server/request-pipeline.js +24 -9
  235. package/dist/server/response-compression.d.ts +43 -0
  236. package/dist/server/response-compression.js +111 -0
  237. package/dist/server/revalidation-request.d.ts +1 -0
  238. package/dist/server/revalidation-request.js +1 -1
  239. package/dist/server/rsc-stream-hints.js +31 -2
  240. package/dist/server/seed-cache.d.ts +1 -0
  241. package/dist/server/seed-cache.js +15 -11
  242. package/dist/server/server-reference-loader.d.ts +4 -0
  243. package/dist/server/server-reference-loader.js +29 -0
  244. package/dist/server/socket-error-backstop.d.ts +23 -1
  245. package/dist/server/socket-error-backstop.js +69 -17
  246. package/dist/server/static-file-signal.d.ts +15 -4
  247. package/dist/server/static-file-signal.js +46 -12
  248. package/dist/server/worker-image-optimization.d.ts +34 -0
  249. package/dist/server/worker-image-optimization.js +86 -0
  250. package/dist/server/worker-stages.d.ts +1 -1
  251. package/dist/server/worker-stages.js +2 -2
  252. package/dist/server/worker-utils.d.ts +8 -3
  253. package/dist/server/worker-utils.js +12 -7
  254. package/dist/shims/app-router-scroll.js +4 -1
  255. package/dist/shims/app-router-tree-context.d.ts +5 -0
  256. package/dist/shims/app-router-tree-context.js +27 -0
  257. package/dist/shims/cache-adapter-instantiate.d.ts +50 -0
  258. package/dist/shims/cache-adapter-instantiate.js +118 -0
  259. package/dist/shims/cache-callable-runtime.d.ts +6 -42
  260. package/dist/shims/cache-callable-runtime.js +65 -174
  261. package/dist/shims/cache-flight-arguments.d.ts +22 -0
  262. package/dist/shims/cache-flight-arguments.js +56 -0
  263. package/dist/shims/cache-handler.js +1 -9
  264. package/dist/shims/cache-request-state.d.ts +15 -0
  265. package/dist/shims/cache-request-state.js +31 -8
  266. package/dist/shims/cache-runtime.d.ts +12 -20
  267. package/dist/shims/cache-runtime.js +166 -225
  268. package/dist/shims/cache.d.ts +4 -4
  269. package/dist/shims/cache.js +44 -16
  270. package/dist/shims/cacheability-classification.d.ts +7 -0
  271. package/dist/shims/cdn-cache.d.ts +8 -0
  272. package/dist/shims/cdn-cache.js +17 -1
  273. package/dist/shims/disable-smooth-scroll.d.ts +3 -0
  274. package/dist/shims/disable-smooth-scroll.js +36 -0
  275. package/dist/shims/document-placeholders.d.ts +19 -0
  276. package/dist/shims/document-placeholders.js +45 -0
  277. package/dist/shims/document.js +21 -5
  278. package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
  279. package/dist/shims/dynamic-preload-chunks.js +13 -9
  280. package/dist/shims/dynamic.d.ts +1 -1
  281. package/dist/shims/dynamic.js +60 -8
  282. package/dist/shims/error-boundary-navigation.d.ts +7 -0
  283. package/dist/shims/error-boundary-navigation.js +19 -1
  284. package/dist/shims/error-boundary.d.ts +10 -10
  285. package/dist/shims/error-boundary.js +26 -7
  286. package/dist/shims/fetch-cache-state.d.ts +66 -0
  287. package/dist/shims/fetch-cache-state.js +92 -0
  288. package/dist/shims/fetch-cache.d.ts +3 -61
  289. package/dist/shims/fetch-cache.js +161 -108
  290. package/dist/shims/form.js +1 -1
  291. package/dist/shims/head.d.ts +10 -6
  292. package/dist/shims/head.js +15 -13
  293. package/dist/shims/headers.d.ts +13 -0
  294. package/dist/shims/headers.js +47 -4
  295. package/dist/shims/image.js +2 -1
  296. package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -2
  297. package/dist/shims/internal/app-page-props-cache-key.js +24 -15
  298. package/dist/shims/internal/headers-state.d.ts +0 -1
  299. package/dist/shims/internal/work-store-scope.d.ts +5 -0
  300. package/dist/shims/internal/work-store-scope.js +24 -0
  301. package/dist/shims/metadata.js +3 -3
  302. package/dist/shims/navigation-errors.d.ts +6 -0
  303. package/dist/shims/navigation-errors.js +11 -1
  304. package/dist/shims/navigation.d.ts +7 -0
  305. package/dist/shims/navigation.js +45 -9
  306. package/dist/shims/request-context.d.ts +11 -0
  307. package/dist/shims/request-state-types.d.ts +2 -1
  308. package/dist/shims/router.js +12 -20
  309. package/dist/shims/server.d.ts +16 -0
  310. package/dist/shims/server.js +24 -4
  311. package/dist/shims/thenable-params.d.ts +4 -0
  312. package/dist/shims/thenable-params.js +25 -3
  313. package/dist/shims/unified-request-context.d.ts +1 -1
  314. package/dist/shims/unified-request-context.js +1 -0
  315. package/dist/shims/url-utils.d.ts +2 -0
  316. package/dist/shims/url-utils.js +3 -1
  317. package/dist/utils/client-runtime-metadata.js +1 -1
  318. package/dist/utils/hash.d.ts +7 -0
  319. package/dist/utils/hash.js +11 -1
  320. package/dist/utils/mdx-scan.d.ts +5 -0
  321. package/dist/utils/mdx-scan.js +8 -1
  322. package/dist/utils/package-name.d.ts +6 -0
  323. package/dist/utils/package-name.js +12 -1
  324. package/dist/utils/plugin-rsc-version.d.ts +4 -0
  325. package/dist/utils/plugin-rsc-version.js +15 -0
  326. package/dist/utils/prerender-output-paths.js +15 -4
  327. package/dist/utils/public-file-path.d.ts +10 -2
  328. package/dist/utils/public-file-path.js +13 -9
  329. package/dist/utils/public-routes.js +2 -2
  330. package/dist/utils/react-version.d.ts +3 -0
  331. package/dist/utils/react-version.js +1 -1
  332. package/dist/utils/regex-safety.d.ts +10 -0
  333. package/dist/utils/regex-safety.js +70 -18
  334. package/package.json +9 -5
@@ -1,20 +1,22 @@
1
1
  import { preserveFullyBufferedBodyMetadata } from "./fully-buffered-response.js";
2
2
  import { closeAfterResponse, closeAfterResponseWithBody, createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
3
3
  import { PRERENDER_REVALIDATE_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
4
- import { hasMiddlewareRequestHeaderOverrides } from "../utils/middleware-request-headers.js";
4
+ import { buildRequestHeadersFromMiddlewareResponse, hasMiddlewareRequestHeaderOverrides } from "../utils/middleware-request-headers.js";
5
5
  import { requestContextFromRequest } from "../config/request-context.js";
6
6
  import { isExternalUrl } from "../utils/external-url.js";
7
7
  import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
8
- import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
8
+ import { normalizePathnameForRouteMatch, normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
9
9
  import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
10
10
  import { patternToNextFormat } from "../routing/route-validation.js";
11
11
  import { getRequestExecutionContext } from "../shims/request-context.js";
12
12
  import "./app-rsc-vary.js";
13
- import { ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_REWRITTEN_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER } from "./headers.js";
13
+ import { ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_REWRITTEN_HEADER, VINEXT_RENDERED_PATH_AND_SEARCH_HEADER, VINEXT_SPECIAL_ERROR_STATUS_HEADER } from "./headers.js";
14
+ import { runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
14
15
  import { isInterceptionMatchedUrlPath, normalizePath } from "./normalize-path.js";
15
16
  import { badRequestResponse, notFoundResponse, notFoundStaticAssetResponse } from "./http-error-responses.js";
16
- import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, normalizeTrailingSlash, resolvePublicFileRoute } from "./request-pipeline.js";
17
+ import { cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, normalizeTrailingSlash, normalizeTrailingSlashPathname, resolvePublicFileRoute } from "./request-pipeline.js";
17
18
  import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
19
+ import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
18
20
  import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
19
21
  import { markRouteCacheabilityDynamic, preserveRouteCacheabilityResponsePolicy } from "../shims/cacheability-classification.js";
20
22
  import { NEVER_CACHE_CONTROL, applyCdnResponseHeaders, captureCdnResponsePolicyOverrides, isCdnResponsePolicyHeader, reconcileCdnResponseHeadersAfterOuterPolicy } from "./cache-control.js";
@@ -22,9 +24,8 @@ import { isOnDemandRevalidateRequest } from "./revalidation-request.js";
22
24
  import { getDraftModeCookieHeader, getEffectiveRequestCookieHeader, getHeadersContext, hasEffectiveRequestCookieChanges, headersContextFromRequest, isDraftModeEnabled, isDraftModeRequest, runWithHeadersContext } from "../shims/headers.js";
23
25
  import { mergeRewriteQuery } from "../utils/query.js";
24
26
  import { getScriptNonceFromHeaderSources } from "./csp.js";
25
- import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
26
27
  import { traceFindPageComponents } from "./pages-execution-tracing.js";
27
- import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, resolveDevImageRedirect } from "./image-optimization.js";
28
+ import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, markImageOptimizationSignal, resolveDevImageRedirect } from "./image-optimization.js";
28
29
  import { parseCacheabilityManifest } from "./cacheability-manifest.js";
29
30
  import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
30
31
  import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestUrl, hasRscCacheBustingSearchParam, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
@@ -33,10 +34,13 @@ import { consumeResponseStageLinkProvenance, copyLinkHeaderProvenance } from "./
33
34
  import "./app-page-response.js";
34
35
  import { parseNextHttpErrorDigest } from "./next-error-digest.js";
35
36
  import { traceAppPageRender } from "./app-page-tracing.js";
37
+ import { openForwardedMiddlewareContext } from "./forwarded-middleware-context.js";
36
38
  import { setFrameworkRequestRoute, traceFrameworkRequest } from "./request-tracing.js";
37
39
  import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, serializePrerenderRouteParamsHeader } from "./prerender-route-params.js";
38
40
  import { buildPageCacheTags } from "./implicit-tags.js";
39
41
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
42
+ import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
43
+ import { normalizeInterceptionContextHeader } from "./app-interception-context-header.js";
40
44
  import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
41
45
  import { pickRootParams, setRootParams } from "../shims/root-params.js";
42
46
  import { createRouteTreePrefetchResponse, isRouteTreePrefetchRequest } from "./app-route-tree-prefetch.js";
@@ -51,6 +55,33 @@ import { consumePagesResponseStagePolicyOwner, withoutResponseStageVary } from "
51
55
  const HAS_CONFIG_HEADERS = process.env.__VINEXT_HAS_CONFIG_HEADERS !== "false";
52
56
  const HAS_CONFIG_REDIRECTS = process.env.__VINEXT_HAS_CONFIG_REDIRECTS !== "false";
53
57
  const HAS_CONFIG_REWRITES = process.env.__VINEXT_HAS_CONFIG_REWRITES !== "false";
58
+ /**
59
+ * Decode an interception context to the canonical source pathname it names.
60
+ * Throws for any value the client could not send back as its context header.
61
+ */
62
+ function decodeInterceptionSourcePathname(context) {
63
+ if (!isInterceptionMatchedUrlPath(context)) throw new Error("Invalid interception source pathname");
64
+ if (new URL(context, "http://n").pathname !== context) throw new Error("Interception source is not a parsed URL pathname");
65
+ const decodedSourcePathname = normalizePathnameForRouteMatchStrict(context);
66
+ if (/[\t\n\r]/.test(decodedSourcePathname)) throw new Error("Interception source contains a stripped URL character");
67
+ if (hasUrlParserDotSegment(decodedSourcePathname)) throw new Error("Interception source contains a URL dot segment");
68
+ const sourcePathname = normalizePath(decodedSourcePathname);
69
+ if (sourcePathname !== decodedSourcePathname) throw new Error("Non-canonical interception source pathname");
70
+ return sourcePathname;
71
+ }
72
+ /**
73
+ * Whether a server-derived context satisfies the whole inbound header
74
+ * contract, so the client can send it back unchanged on its next request.
75
+ */
76
+ function isValidInterceptionSourceContext(context) {
77
+ if (normalizeInterceptionContextHeader(context) !== context) return false;
78
+ try {
79
+ decodeInterceptionSourcePathname(context);
80
+ return true;
81
+ } catch {
82
+ return false;
83
+ }
84
+ }
54
85
  function ruleUsesUnkeyedRequestCondition(rule) {
55
86
  return [...rule.has ?? [], ...rule.missing ?? []].some((condition) => condition.type === "header" || condition.type === "cookie" || condition.type === "host");
56
87
  }
@@ -118,11 +149,32 @@ function applyMiddlewareContextToResponse(response, middlewareContext, appendToP
118
149
  const middlewareLink = middlewareContext.headers?.get("link");
119
150
  if (responseLink && middlewareLink) headers.set("link", `${middlewareLink}, ${responseLink}`);
120
151
  return preserveFullyBufferedBodyMetadata(response, new Response(response.body, {
121
- status: middlewareContext.status ?? response.status,
152
+ status: response.status === 304 ? 304 : middlewareContext.status ?? response.status,
122
153
  statusText: response.statusText,
123
154
  headers
124
155
  }));
125
156
  }
157
+ /**
158
+ * Next.js answers a Link's segment prefetch of a page whose notFound(),
159
+ * forbidden() or unauthorized() it stored with a 200, so its router renders
160
+ * the page's fallback without loading the document. A shared response stage
161
+ * gives that prefetch the navigation's response, so the request's own headers
162
+ * decide the status here.
163
+ */
164
+ function withStoredSpecialErrorStatus(response, isSegmentPrefetch) {
165
+ const marker = response.headers.get(VINEXT_SPECIAL_ERROR_STATUS_HEADER);
166
+ if (marker === null) return response;
167
+ const headers = new Headers(response.headers);
168
+ headers.delete(VINEXT_SPECIAL_ERROR_STATUS_HEADER);
169
+ const storedStatus = Number(marker);
170
+ const isStoredSpecialError = storedStatus === 401 || storedStatus === 403 || storedStatus === 404;
171
+ const status = response.status === 304 || !isStoredSpecialError ? response.status : isSegmentPrefetch ? 200 : storedStatus;
172
+ return preserveFullyBufferedBodyMetadata(response, new Response(response.body, {
173
+ headers,
174
+ status,
175
+ statusText: status === response.status ? response.statusText : ""
176
+ }));
177
+ }
126
178
  function hasProperty(value, key) {
127
179
  return key in value;
128
180
  }
@@ -155,8 +207,10 @@ async function applyRewrite(options, cleanPathname, recordCacheability = true) {
155
207
  if (isExternalUrl(rewritten)) {
156
208
  const validationResponse = await options.validateExternalRewriteRequest();
157
209
  if (validationResponse) return validationResponse;
210
+ const { requestWithMiddlewareContextHeaders } = await import("./app-middleware.js");
211
+ const proxyRequest = requestWithMiddlewareContextHeaders(options.request, options.middlewareContext);
158
212
  options.clearRequestContext();
159
- return configMatchers.proxyExternalRequest(options.request, rewritten);
213
+ return configMatchers.proxyExternalRequest(proxyRequest, rewritten);
160
214
  }
161
215
  return rewritten;
162
216
  }
@@ -171,6 +225,16 @@ function requestContextForResolvedUrl(requestContext, resolvedUrl, baseUrl) {
171
225
  function pathnameForResolvedUrl(resolvedUrl) {
172
226
  return resolvedUrl.split("#", 1)[0].split("?", 1)[0];
173
227
  }
228
+ /**
229
+ * Percent-encode the code points the URL parser encodes in a path (so `é`
230
+ * becomes `%C3%A9`) without resolving dot segments or `\`: Next.js only parses
231
+ * a rewrite destination's template, so a captured `../admin` stays verbatim.
232
+ */
233
+ function serializeResolvedUrl(resolvedUrl, base) {
234
+ const resolved = new URL(resolvedUrl, base);
235
+ stripRscCacheBustingSearchParam(resolved);
236
+ return pathnameForResolvedUrl(resolvedUrl).replace(/[\0-\x20"<>`{}^\x7F]|[^\0-\x7F]/gu, (char) => char.length === 1 && char >= "\ud800" && char <= "\udfff" ? "%EF%BF%BD" : encodeURIComponent(char)) + resolved.search + resolved.hash;
237
+ }
174
238
  async function applyConfigHeadersToMiddlewareRedirect(response, options) {
175
239
  if (response.status < 300 || response.status >= 400) return response;
176
240
  if (!HAS_CONFIG_HEADERS || !options.configHeaders.length) return response;
@@ -206,7 +270,8 @@ function requestWithoutRscSuffix(request) {
206
270
  url.pathname = pathname;
207
271
  return cloneRequestWithUrl(request, url.toString());
208
272
  }
209
- function markUnverifiedInterceptionResponseUncacheable(response) {
273
+ /** Send a response with the never-cache policy, rebuilding immutable headers. */
274
+ function withNeverCacheControl(response) {
210
275
  const applyNoStore = (headers) => {
211
276
  applyCdnResponseHeaders(headers, { cacheControl: NEVER_CACHE_CONTROL });
212
277
  };
@@ -224,6 +289,13 @@ function markUnverifiedInterceptionResponseUncacheable(response) {
224
289
  }
225
290
  return markedResponse;
226
291
  }
292
+ const unmatchedRouteResponses = /* @__PURE__ */ new WeakSet();
293
+ /** Send an unmatched route's 404 with the never-cache policy, as Next.js does. */
294
+ function withUnmatchedRouteCacheControl(response) {
295
+ const markedResponse = withNeverCacheControl(response);
296
+ unmatchedRouteResponses.add(markedResponse);
297
+ return markedResponse;
298
+ }
227
299
  async function handleAppRscRequest(options, request, preMiddlewareRequestContext, middlewareContext, isDataRequest, isMiddlewareDataRequest, pagesDataRequest, dispatchInternalRequest, allowInternalRscDocumentFallback, dispatchResponseStage, responseStageProbeMode = null, setInterceptionResponseUncacheable = () => {}) {
228
300
  const handlerStart = process.env.NODE_ENV !== "production" ? performance.now() : 0;
229
301
  if (process.env.NODE_ENV !== "production") {
@@ -248,12 +320,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
248
320
  if (hasRawInterceptionContext) setInterceptionResponseUncacheable(true);
249
321
  let interceptionSourcePathname = null;
250
322
  if (isRscRequest && interceptionContextHeader !== null) try {
251
- if (!isInterceptionMatchedUrlPath(interceptionContextHeader)) throw new Error("Invalid interception source pathname");
252
- const decodedInterceptionSourcePathname = normalizePathnameForRouteMatchStrict(interceptionContextHeader);
253
- if (/[\t\n\r]/.test(decodedInterceptionSourcePathname)) throw new Error("Interception source contains a stripped URL character");
254
- if (hasUrlParserDotSegment(decodedInterceptionSourcePathname)) throw new Error("Interception source contains a URL dot segment");
255
- interceptionSourcePathname = normalizePath(decodedInterceptionSourcePathname);
256
- if (interceptionSourcePathname !== decodedInterceptionSourcePathname) throw new Error("Non-canonical interception source pathname");
323
+ interceptionSourcePathname = decodeInterceptionSourcePathname(interceptionContextHeader);
257
324
  } catch {
258
325
  options.clearRequestContext();
259
326
  setInterceptionResponseUncacheable(true);
@@ -262,7 +329,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
262
329
  const { requestCleanPathname } = normalized;
263
330
  let { pathname, cleanPathname } = normalized;
264
331
  let resolvedUrl = cleanPathname + url.search;
265
- const originalResolvedUrl = resolvedUrl;
332
+ const originalResolvedUrl = serializeResolvedUrl(resolvedUrl, url);
266
333
  const getResolvedSearchParams = () => new URL(resolvedUrl, url).searchParams;
267
334
  const canonicalPathname = cleanPathname;
268
335
  const basePathState = {
@@ -282,10 +349,10 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
282
349
  });
283
350
  if (selectorCacheBustingRedirect) return selectorCacheBustingRedirect;
284
351
  }
285
- const provesConcreteInterceptionSource = (sourceMatch) => {
352
+ const provesConcreteInterceptionSource = (sourceMatch, sourceContext = interceptionContextHeader) => {
286
353
  if (sourceMatch === null) return false;
287
354
  if (sourceMatch.interceptionSourceIsConcrete !== void 0) return sourceMatch.interceptionSourceIsConcrete;
288
- return interceptionSourcePathname !== null && options.matchRoute(interceptionSourcePathname)?.route === sourceMatch.route;
355
+ return sourceContext !== null && (options.matchRequestRoute ?? options.matchRoute)(sourceContext)?.route === sourceMatch.route;
289
356
  };
290
357
  if (provesConcreteInterceptionSource(hadBasePath && hasRawInterceptionContext && interceptionContextHeader !== null ? options.matchInterceptRoute?.(requestCleanPathname, interceptionContextHeader, interceptionIdHeader) ?? null : null)) setInterceptionResponseUncacheable(false);
291
358
  if (pathname === "/__vinext/prerender/static-params" || pathname === "/__vinext/prerender/pages-static-paths" || pathname === "/__vinext/prerender/metadata-routes") {
@@ -302,15 +369,17 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
302
369
  });
303
370
  if (prerenderEndpointResponse) return prerenderEndpointResponse;
304
371
  }
305
- const trailingSlashRedirect = options.trailingSlash && options.isMetadataRoutePath && await options.isMetadataRoutePath(cleanPathname) ? null : normalizeTrailingSlash(requestCleanPathname, hadBasePath ? options.basePath : "", options.trailingSlash, url.search);
306
- if (trailingSlashRedirect) return trailingSlashRedirect;
372
+ if (!options.skipTrailingSlashRedirect) {
373
+ const trailingSlashRedirect = options.trailingSlash && options.isMetadataRoutePath && await options.isMetadataRoutePath(cleanPathname) ? null : normalizeTrailingSlash(requestCleanPathname, hadBasePath ? options.basePath : "", options.trailingSlash, url.search);
374
+ if (trailingSlashRedirect) return trailingSlashRedirect;
375
+ }
307
376
  const matchPathname = (p) => normalizeDefaultLocalePathname(p, options.i18nConfig, { hostname: url.hostname });
308
377
  const redirectPathname = matchPathname(requestCleanPathname);
309
378
  const configMatchers = HAS_CONFIG_REDIRECTS && options.configRedirects.length ? await import("../config/config-matchers.js") : null;
310
379
  const redirect = configMatchers ? configMatchers.matchRedirect(redirectPathname, options.configRedirects, preMiddlewareRequestContext, basePathState, dispatchResponseStage ? void 0 : markConditionalRedirectCacheability) : null;
311
380
  if (configMatchers && redirect) {
312
381
  const destination = configMatchers.sanitizeDestination(redirectDestinationWithBasePath(redirect.destination, options.basePath, hadBasePath));
313
- const location = isRscRequest && request.headers.get("RSC") === "1" ? await createRscRedirectLocation(destination, request) : configMatchers.preserveRedirectDestinationQuery(destination, url.search);
382
+ const location = isRscRequest && request.headers.get("RSC") === "1" ? await createRscRedirectLocation(destination, request) : configMatchers.preserveRedirectDestinationQuery(destination, url.search, redirect.destinationQuery);
314
383
  return new Response(null, {
315
384
  status: redirect.permanent ? 308 : 307,
316
385
  headers: { Location: location }
@@ -336,6 +405,11 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
336
405
  const isolatedMiddlewareRequest = isolatedMiddlewareSource ? requestWithoutRscCacheBustingSearchParam(requestWithoutRscSuffix(isolatedMiddlewareSource)) : void 0;
337
406
  let didMiddlewareRewrite = false;
338
407
  let didMiddlewareRewritePathname = false;
408
+ let resolvedPathnameHasBasePath = hadBasePath;
409
+ const currentBasePathState = () => ({
410
+ basePath: options.basePath,
411
+ hadBasePath: resolvedPathnameHasBasePath
412
+ });
339
413
  if (runMiddleware) {
340
414
  const middlewareResult = await runMiddleware({
341
415
  cleanPathname,
@@ -360,6 +434,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
360
434
  }
361
435
  cleanPathname = middlewareResult.cleanPathname;
362
436
  didMiddlewareRewrite = middlewareResult.rewritten;
437
+ if (didMiddlewareRewrite) resolvedPathnameHasBasePath = middlewareResult.rewriteHadBasePath ?? true;
363
438
  if (didMiddlewareRewrite || cleanPathname !== normalized.cleanPathname) cleanPathnameIsRequestPathname = false;
364
439
  didMiddlewareRewritePathname = cleanPathname !== normalized.cleanPathname;
365
440
  if (middlewareResult.search !== null) url.search = middlewareResult.search;
@@ -461,7 +536,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
461
536
  isRscRequest,
462
537
  middlewareCookieOverlay,
463
538
  mountedSlotsHeader,
464
- protocolVersion: 10,
539
+ protocolVersion: 11,
465
540
  requestOrigin: url.origin,
466
541
  renderMode,
467
542
  resolvedUrl,
@@ -522,8 +597,9 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
522
597
  filesystemRouteEligible ||= didMiddlewareRewrite;
523
598
  for (const rewrite of options.configRewrites.beforeFiles) {
524
599
  const beforeFilesRewrite = await applyRewrite({
525
- basePathState,
600
+ basePathState: currentBasePathState(),
526
601
  clearRequestContext: options.clearRequestContext,
602
+ middlewareContext,
527
603
  request: normalizedUserlandRequest,
528
604
  requestContext: requestContextForResolvedUrl(postMiddlewareRequestContext, resolvedUrl, url),
529
605
  paramsPathname: matchPathname(cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname),
@@ -536,6 +612,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
536
612
  cleanPathname = pathnameForResolvedUrl(resolvedUrl);
537
613
  cleanPathnameIsRequestPathname = false;
538
614
  filesystemRouteEligible = true;
615
+ resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
539
616
  }
540
617
  }
541
618
  const claimedRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
@@ -549,8 +626,9 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
549
626
  let actionMatch = null;
550
627
  for (const rewrite of options.configRewrites.afterFiles) {
551
628
  const rewritten = await applyRewrite({
552
- basePathState,
629
+ basePathState: currentBasePathState(),
553
630
  clearRequestContext: options.clearRequestContext,
631
+ middlewareContext,
554
632
  request: normalizedUserlandRequest,
555
633
  requestContext: requestContextForResolvedUrl(postMiddlewareRequestContext, resolvedUrl, url),
556
634
  paramsPathname: matchPathname(cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname),
@@ -563,13 +641,15 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
563
641
  cleanPathname = pathnameForResolvedUrl(resolvedUrl);
564
642
  cleanPathnameIsRequestPathname = false;
565
643
  filesystemRouteEligible = true;
644
+ resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
566
645
  actionMatch = matchCleanPathname();
567
646
  if (actionMatch) break;
568
647
  }
569
648
  if (!actionMatch) for (const rewrite of options.configRewrites.fallback) {
570
649
  const rewritten = await applyRewrite({
571
- basePathState,
650
+ basePathState: currentBasePathState(),
572
651
  clearRequestContext: options.clearRequestContext,
652
+ middlewareContext,
573
653
  request: normalizedUserlandRequest,
574
654
  requestContext: requestContextForResolvedUrl(postMiddlewareRequestContext, resolvedUrl, url),
575
655
  paramsPathname: matchPathname(cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname),
@@ -582,6 +662,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
582
662
  cleanPathname = pathnameForResolvedUrl(resolvedUrl);
583
663
  cleanPathnameIsRequestPathname = false;
584
664
  filesystemRouteEligible = true;
665
+ resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
585
666
  actionMatch = matchCleanPathname();
586
667
  if (actionMatch) break;
587
668
  }
@@ -589,15 +670,29 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
589
670
  }
590
671
  const lateActionRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
591
672
  if (lateActionRscCacheBustingRedirect) return lateActionRscCacheBustingRedirect;
592
- if (filesystemRouteEligible && isImageOptimizationPath(cleanPathname)) {
593
- const imageRedirect = resolveDevImageRedirect(url, [...options.imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...options.imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES], options.imageConfig?.qualities, { isDev: options.isDev });
594
- if (!imageRedirect) return new Response("Invalid image optimization parameters", { status: 400 });
595
- return Response.redirect(new URL(imageRedirect, url.origin).href, 302);
596
- }
673
+ const serveImageEndpointIfMatched = () => {
674
+ if (!filesystemRouteEligible || !resolvedPathnameHasBasePath || !isImageOptimizationPath(cleanPathname)) return null;
675
+ const imageUrl = new URL(resolvedUrl, url);
676
+ const imageRedirect = resolveDevImageRedirect(imageUrl, [...options.imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...options.imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES], options.imageConfig?.qualities, { isDev: options.isDev });
677
+ const middlewareHeaders = new Headers();
678
+ mergeMiddlewareResponseHeaders(middlewareHeaders, middlewareContext.headers);
679
+ if (!imageRedirect) return new Response("Invalid image optimization parameters", {
680
+ status: 400,
681
+ headers: middlewareHeaders
682
+ });
683
+ const overrideHeaders = middlewareContext.requestHeaders ?? middlewareContext.headers;
684
+ return markImageOptimizationSignal(Response.redirect(new URL(imageRedirect, url.origin).href, 302), {
685
+ middlewareHeaders,
686
+ requestHeaders: overrideHeaders ? buildRequestHeadersFromMiddlewareResponse(request.headers, overrideHeaders) : null,
687
+ search: imageUrl.search
688
+ });
689
+ };
690
+ const imageEndpointResponse = serveImageEndpointIfMatched();
691
+ if (imageEndpointResponse) return imageEndpointResponse;
597
692
  const metadataRouteResponse = await renderMetadataRouteIfMatched();
598
693
  if (metadataRouteResponse) return composeResponseStageResponse(metadataRouteResponse);
599
694
  const publicFileResponse = filesystemRouteEligible ? resolvePublicFileRoute({
600
- cleanPathname,
695
+ cleanPathname: cleanPathnameIsRequestPathname ? cleanPathname : normalizePathnameForRouteMatch(cleanPathname),
601
696
  middlewareContext,
602
697
  pathname,
603
698
  publicFiles: options.publicFiles,
@@ -608,9 +703,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
608
703
  return publicFileResponse;
609
704
  }
610
705
  stripRscCacheBustingSearchParam(url);
611
- const resolved = new URL(resolvedUrl, url);
612
- stripRscCacheBustingSearchParam(resolved);
613
- resolvedUrl = resolved.pathname + resolved.search + resolved.hash;
706
+ resolvedUrl = serializeResolvedUrl(resolvedUrl, url);
614
707
  options.setNavigationContext({
615
708
  pathname: canonicalPathname,
616
709
  searchParams: getResolvedSearchParams(),
@@ -618,8 +711,9 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
618
711
  });
619
712
  const directPreActionMatch = filesystemRouteEligible ? matchCleanPathname() : null;
620
713
  const preActionRoutePathname = cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname;
621
- const interceptionSourceMatch = filesystemRouteEligible && interceptionSourcePathname !== null && interceptionContextHeader !== null ? options.matchInterceptRoute?.(preActionRoutePathname, interceptionContextHeader, interceptionIdHeader) ?? null : null;
622
- const hasVerifiedInterceptionSource = provesConcreteInterceptionSource(interceptionSourceMatch);
714
+ let interceptionSourceContext = interceptionSourcePathname !== null ? interceptionContextHeader : null;
715
+ let interceptionSourceMatch = filesystemRouteEligible && interceptionSourcePathname !== null && interceptionContextHeader !== null ? options.matchInterceptRoute?.(preActionRoutePathname, interceptionContextHeader, interceptionIdHeader) ?? null : null;
716
+ let hasVerifiedInterceptionSource = provesConcreteInterceptionSource(interceptionSourceMatch);
623
717
  if (interceptionIdHeader !== null && !hasVerifiedInterceptionSource) {
624
718
  options.clearRequestContext();
625
719
  setInterceptionResponseUncacheable(true);
@@ -634,81 +728,142 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
634
728
  bypassInterceptionContextCache = true;
635
729
  setInterceptionResponseUncacheable(true);
636
730
  };
637
- if (interceptionSourceMatch !== null && interceptionSourcePathname !== null && runMiddleware && interceptionSourceMatch.route !== directPreActionMatch?.route) {
638
- const sourceUrl = new URL(userlandRequest.url);
639
- sourceUrl.search = new URL(resolvedUrl, url).search;
640
- sourceUrl.pathname = hadBasePath ? addBasePathToPathname(interceptionSourcePathname, options.basePath) : interceptionSourcePathname;
641
- const sourceRequest = userlandRequest.body ? userlandRequest.clone() : userlandRequest;
642
- const sourceMiddlewareRequest = cloneRequestWithUrl(sourceRequest, sourceUrl.href);
643
- sourceMiddlewareRequest.headers.delete(VINEXT_MW_CTX_HEADER);
644
- for (const header of FLIGHT_HEADERS) sourceMiddlewareRequest.headers.delete(header);
645
- const targetHeadersContext = getHeadersContext();
646
- const targetRequestHeaders = targetHeadersContext ? new Headers(targetHeadersContext.headers) : null;
647
- targetRequestHeaders?.delete(VINEXT_MW_CTX_HEADER);
648
- for (const header of FLIGHT_HEADERS) targetRequestHeaders?.delete(header);
649
- if (targetRequestHeaders) {
650
- const sourceHeaderNames = Array.from(sourceMiddlewareRequest.headers.keys());
651
- for (const header of sourceHeaderNames) sourceMiddlewareRequest.headers.delete(header);
652
- for (const [name, value] of targetRequestHeaders) sourceMiddlewareRequest.headers.append(name, value);
653
- }
654
- const sourceMiddlewareContext = {
655
- headers: null,
656
- requestHeaders: null,
657
- status: null
658
- };
659
- const sourceHeadersContext = headersContextFromRequest(sourceMiddlewareRequest, { draftModeSecret: options.draftModeSecret });
660
- let sourceMiddlewareResult;
661
- try {
662
- sourceMiddlewareResult = await runWithHeadersContext(sourceHeadersContext, () => runMiddleware({
663
- cleanPathname: interceptionSourcePathname,
664
- context: sourceMiddlewareContext,
665
- externalRewriteRequest: normalizedUserlandRequest,
666
- hadBasePath,
667
- isDataRequest: isMiddlewareDataRequest,
668
- request: sourceMiddlewareRequest,
669
- validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
670
- }));
671
- } finally {
672
- if (sourceMiddlewareRequest.body && !sourceMiddlewareRequest.bodyUsed && !sourceMiddlewareRequest.body.locked) sourceMiddlewareRequest.body.cancel().catch(() => {});
673
- if (sourceRequest !== userlandRequest && sourceRequest.body && !sourceRequest.bodyUsed && !sourceRequest.body.locked) sourceRequest.body.cancel().catch(() => {});
674
- }
675
- if (!dispatchResponseStage && sourceMiddlewareResult.pathnameEligible) markRouteCacheabilityDynamic(sourceMiddlewareResult.matched ? "middleware matched this request" : "middleware is eligible for this pathname");
676
- if (sourceMiddlewareResult.kind === "response") {
677
- options.clearRequestContext();
678
- return sourceMiddlewareResult.response;
679
- }
680
- let sourceHeadersCompatible = true;
681
- if (targetRequestHeaders) {
682
- for (const [name, value] of targetRequestHeaders) if (sourceHeadersContext.headers.get(name) !== value) {
683
- sourceHeadersCompatible = false;
684
- break;
731
+ if (interceptionSourceMatch !== null && interceptionContextHeader !== null && interceptionSourcePathname !== null && !(interceptionSourceMatch.route === directPreActionMatch?.route && haveSamePageParams(interceptionSourceMatch.params, directPreActionMatch.params))) {
732
+ const sourceRequestPathname = options.skipTrailingSlashRedirect ? interceptionContextHeader : normalizeTrailingSlashPathname(interceptionContextHeader, options.trailingSlash) ?? interceptionContextHeader;
733
+ const decodedSourceRequestPathname = options.skipTrailingSlashRedirect ? interceptionSourcePathname : normalizeTrailingSlashPathname(interceptionSourcePathname, options.trailingSlash) ?? interceptionSourcePathname;
734
+ const adoptRewrittenInterceptionSource = (rewrittenPathname) => {
735
+ const rewrittenInterceptionSourceMatch = isValidInterceptionSourceContext(rewrittenPathname) ? options.matchInterceptRoute?.(preActionRoutePathname, rewrittenPathname, interceptionIdHeader) ?? null : null;
736
+ if (rewrittenInterceptionSourceMatch !== null) {
737
+ interceptionSourceMatch = rewrittenInterceptionSourceMatch;
738
+ interceptionSourceContext = rewrittenPathname;
685
739
  }
686
- }
687
- if (!targetHeadersContext || !targetRequestHeaders || !sourceHeadersCompatible || !haveSameRequestCookies(targetHeadersContext.cookies, sourceHeadersContext.cookies)) {
740
+ const rewrittenSourceMatch = options.matchRoute(rewrittenPathname);
741
+ return interceptionSourceMatch !== null && rewrittenSourceMatch?.route === interceptionSourceMatch.route && haveSamePageParams(rewrittenSourceMatch.params, interceptionSourceMatch.params);
742
+ };
743
+ if (configMatchers?.matchRedirect(matchPathname(sourceRequestPathname), options.configRedirects, preMiddlewareRequestContext, basePathState, dispatchResponseStage ? void 0 : markConditionalRedirectCacheability)) {
688
744
  options.clearRequestContext();
689
745
  return notFoundResponse();
690
746
  }
691
- let addedSourceHeader = false;
692
- for (const [name, value] of sourceHeadersContext.headers) if (!targetRequestHeaders.has(name)) {
693
- targetHeadersContext.headers.set(name, value);
694
- addedSourceHeader = true;
695
- }
696
- if (addedSourceHeader) {
697
- targetHeadersContext.readonlyHeaders = void 0;
698
- canUseSharedWorkerResponseStage = false;
747
+ let sourceRulesPathname = sourceRequestPathname;
748
+ if (runMiddleware) {
749
+ const sourceUrl = new URL(userlandRequest.url);
750
+ sourceUrl.search = new URL(resolvedUrl, url).search;
751
+ const sourceUrlPathname = hadBasePath && options.basePath ? sourceRequestPathname === "/" ? options.basePath : options.basePath + sourceRequestPathname : sourceRequestPathname;
752
+ sourceUrl.pathname = sourceUrlPathname;
753
+ if (sourceUrl.pathname !== sourceUrlPathname) {
754
+ options.clearRequestContext();
755
+ setInterceptionResponseUncacheable(true);
756
+ return badRequestResponse();
757
+ }
758
+ const sourceRequest = userlandRequest.body ? userlandRequest.clone() : userlandRequest;
759
+ const sourceMiddlewareRequest = cloneRequestWithUrl(sourceRequest, sourceUrl.href);
760
+ sourceMiddlewareRequest.headers.delete(VINEXT_MW_CTX_HEADER);
761
+ for (const header of FLIGHT_HEADERS) sourceMiddlewareRequest.headers.delete(header);
762
+ const targetHeadersContext = getHeadersContext();
763
+ const targetRequestHeaders = targetHeadersContext ? new Headers(targetHeadersContext.headers) : null;
764
+ targetRequestHeaders?.delete(VINEXT_MW_CTX_HEADER);
765
+ for (const header of FLIGHT_HEADERS) targetRequestHeaders?.delete(header);
766
+ if (targetRequestHeaders) {
767
+ const sourceHeaderNames = Array.from(sourceMiddlewareRequest.headers.keys());
768
+ for (const header of sourceHeaderNames) sourceMiddlewareRequest.headers.delete(header);
769
+ for (const [name, value] of targetRequestHeaders) sourceMiddlewareRequest.headers.append(name, value);
770
+ }
771
+ const sourceMiddlewareContext = {
772
+ headers: null,
773
+ requestHeaders: null,
774
+ status: null
775
+ };
776
+ const sourceHeadersContext = headersContextFromRequest(sourceMiddlewareRequest, { draftModeSecret: options.draftModeSecret });
777
+ let sourceMiddlewareResult;
778
+ try {
779
+ sourceMiddlewareResult = await runWithHeadersContext(sourceHeadersContext, () => runMiddleware({
780
+ cleanPathname: decodedSourceRequestPathname,
781
+ context: sourceMiddlewareContext,
782
+ externalRewriteRequest: normalizedUserlandRequest,
783
+ hadBasePath,
784
+ isDataRequest: isMiddlewareDataRequest,
785
+ request: sourceMiddlewareRequest,
786
+ validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
787
+ }));
788
+ } finally {
789
+ if (sourceMiddlewareRequest.body && !sourceMiddlewareRequest.bodyUsed && !sourceMiddlewareRequest.body.locked) sourceMiddlewareRequest.body.cancel().catch(() => {});
790
+ if (sourceRequest !== userlandRequest && sourceRequest.body && !sourceRequest.bodyUsed && !sourceRequest.body.locked) sourceRequest.body.cancel().catch(() => {});
791
+ }
792
+ if (!dispatchResponseStage && sourceMiddlewareResult.pathnameEligible) markRouteCacheabilityDynamic(sourceMiddlewareResult.matched ? "middleware matched this request" : "middleware is eligible for this pathname");
793
+ if (sourceMiddlewareResult.kind === "response") {
794
+ options.clearRequestContext();
795
+ return sourceMiddlewareResult.response;
796
+ }
797
+ let sourceHeadersCompatible = true;
798
+ if (targetRequestHeaders) {
799
+ for (const [name, value] of targetRequestHeaders) if (sourceHeadersContext.headers.get(name) !== value) {
800
+ sourceHeadersCompatible = false;
801
+ break;
802
+ }
803
+ }
804
+ if (!targetHeadersContext || !targetRequestHeaders || !sourceHeadersCompatible || !haveSameRequestCookies(targetHeadersContext.cookies, sourceHeadersContext.cookies)) {
805
+ options.clearRequestContext();
806
+ return notFoundResponse();
807
+ }
808
+ let addedSourceHeader = false;
809
+ for (const [name, value] of sourceHeadersContext.headers) if (!targetRequestHeaders.has(name)) {
810
+ targetHeadersContext.headers.set(name, value);
811
+ addedSourceHeader = true;
812
+ }
813
+ if (addedSourceHeader) {
814
+ targetHeadersContext.readonlyHeaders = void 0;
815
+ canUseSharedWorkerResponseStage = false;
816
+ }
817
+ if (sourceMiddlewareResult.rewritten) {
818
+ if (sourceMiddlewareResult.search !== sourceUrl.search || !adoptRewrittenInterceptionSource(sourceMiddlewareResult.cleanPathname)) {
819
+ options.clearRequestContext();
820
+ return notFoundResponse();
821
+ }
822
+ sourceRulesPathname = sourceMiddlewareResult.cleanPathname;
823
+ }
699
824
  }
700
- if (sourceMiddlewareResult.rewritten) {
701
- const rewrittenSourceMatch = options.matchRoute(sourceMiddlewareResult.cleanPathname);
702
- if (sourceMiddlewareResult.search !== sourceUrl.search || rewrittenSourceMatch?.route !== interceptionSourceMatch.route || !haveSamePageParams(rewrittenSourceMatch.params, interceptionSourceMatch.params)) {
825
+ if (HAS_CONFIG_REWRITES && options.configRewrites.beforeFiles.length) {
826
+ const { matchRewrite } = await import("../config/config-matchers.js");
827
+ const sourceRewriteContext = requestContextForResolvedUrl(buildPostMwRequestContext(userlandRequest), resolvedUrl, url);
828
+ let didRewriteSource = false;
829
+ for (const rewrite of options.configRewrites.beforeFiles) {
830
+ const destination = matchRewrite(matchPathname(sourceRulesPathname), [rewrite], sourceRewriteContext, basePathState, matchPathname(sourceRulesPathname), dispatchResponseStage === void 0 ? markConditionalRewriteCacheability : void 0);
831
+ if (!destination) continue;
832
+ if (isExternalUrl(destination) || destination.includes("?")) {
833
+ options.clearRequestContext();
834
+ return notFoundResponse();
835
+ }
836
+ sourceRulesPathname = pathnameForResolvedUrl(destination);
837
+ didRewriteSource = true;
838
+ }
839
+ if (didRewriteSource && !adoptRewrittenInterceptionSource(sourceRulesPathname)) {
703
840
  options.clearRequestContext();
704
841
  return notFoundResponse();
705
842
  }
706
843
  }
707
844
  }
845
+ if (interceptionSourceMatch !== null) {
846
+ hasVerifiedInterceptionSource = provesConcreteInterceptionSource(interceptionSourceMatch, interceptionSourceContext);
847
+ if (!hasVerifiedInterceptionSource) {
848
+ if (interceptionIdHeader !== null) {
849
+ options.clearRequestContext();
850
+ setInterceptionResponseUncacheable(true);
851
+ return badRequestResponse();
852
+ }
853
+ interceptionSourceMatch = null;
854
+ interceptionSourceContext = null;
855
+ }
856
+ bypassInterceptionContextCache = hasRawInterceptionContext && !hasVerifiedInterceptionSource;
857
+ setInterceptionResponseUncacheable(bypassInterceptionContextCache);
858
+ }
708
859
  const interceptionPreActionMatch = filesystemRouteEligible && directPreActionMatch === null && isRscRequest && interceptionSourcePathname !== null ? interceptionSourceMatch : null;
709
860
  const preActionMatch = directPreActionMatch ?? interceptionPreActionMatch;
710
861
  const isInterceptionMatch = interceptionPreActionMatch !== null;
711
- if (preActionMatch) setRootParams(pickRootParams(preActionMatch.params, preActionMatch.route.rootParamNames));
862
+ const rendersRawRequestMatch = options.matchRawRequestRoute !== void 0 && (isPossibleAppRouteActionRequest(request) || isDraftModeRequest(request, options.draftModeSecret) || isDraftModeEnabled());
863
+ const usesRawRequestMatch = () => rendersRawRequestMatch && cleanPathnameIsRequestPathname && !isInterceptionMatch;
864
+ const renderedRouteMatch = (routeMatch) => routeMatch !== null && usesRawRequestMatch() ? options.matchRawRequestRoute(requestCleanPathname) ?? routeMatch : routeMatch;
865
+ const renderedPreActionMatch = renderedRouteMatch(preActionMatch);
866
+ if (renderedPreActionMatch) setRootParams(pickRootParams(renderedPreActionMatch.params, renderedPreActionMatch.route.rootParamNames));
712
867
  if (pagesDataRequest && didMiddlewareRewritePathname && preActionMatch && !preActionMatch.route.isDynamic) {
713
868
  const headers = new Headers();
714
869
  mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);
@@ -729,7 +884,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
729
884
  contentType,
730
885
  middlewareContext,
731
886
  request,
732
- routeMatch: preActionMatch
887
+ routeMatch: renderedPreActionMatch
733
888
  });
734
889
  else if (preActionMatch?.route.__loadPage && !preActionMatch.route.__loadRouteHandler) return createMissingServerActionResponse(options, null);
735
890
  }
@@ -761,13 +916,13 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
761
916
  actionId,
762
917
  cleanPathname,
763
918
  contentType,
764
- interceptionContext: interceptionContextHeader,
919
+ interceptionContext: interceptionSourceContext,
765
920
  isRscRequest,
766
921
  middlewareContext,
767
922
  mountedSlotsHeader,
768
923
  request,
769
924
  scriptNonce,
770
- routeMatch: preActionMatch,
925
+ routeMatch: renderedPreActionMatch,
771
926
  routePathname: preActionRoutePathname,
772
927
  dispatchRedirectTargetRequest: dispatchInternalRequest,
773
928
  sourceConfigHeaders,
@@ -778,6 +933,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
778
933
  let match = preActionMatch;
779
934
  const renderPagesForMatchKind = async (matchKind) => {
780
935
  if (!filesystemRouteEligible) return null;
936
+ const pagesRouteUrl = cleanPathnameIsRequestPathname ? requestCleanPathname + resolvedUrl.slice(pathnameForResolvedUrl(resolvedUrl).length) : resolvedUrl;
781
937
  let sharedOuterPolicyNeedsReconciliation = false;
782
938
  const dispatchPagesResponseStage = dispatchResponseStage ? async (stageRequest, resourceKind, dataKind, hasRequestAwareDocument) => {
783
939
  const pagesOnDemandRevalidate = resourceKind === "page" && isOnDemandRevalidateRequest(stageRequest.headers.get("x-prerender-revalidate"));
@@ -803,11 +959,11 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
803
959
  matchKind,
804
960
  middlewareCookieOverlay,
805
961
  preHandlerHeaders: cache === "shared" && resourceKind === "page" && dataKind === "static" ? null : [...await loadPreHandlerResponseHeaders()],
806
- protocolVersion: 10,
962
+ protocolVersion: 11,
807
963
  requestOrigin: url.origin,
808
964
  resourceKind,
809
965
  requestUrl: request.url,
810
- resolvedUrl,
966
+ resolvedUrl: pagesRouteUrl,
811
967
  scriptNonce: scriptNonce ?? null
812
968
  }, { cache });
813
969
  const policyOwner = resourceKind === "page" ? consumePagesResponseStagePolicyOwner(response) : {
@@ -822,7 +978,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
822
978
  if (!responseStageHasContentLength) response.headers.delete("Content-Length");
823
979
  return response;
824
980
  } : void 0;
825
- const response = !isInterceptionMatch && (match === null || match.route.isDynamic) ? await options.renderPagesFallback?.({
981
+ const response = !isInterceptionMatch && (match === null || match.route.isDynamic) ? await runOutsideWorkStoreScope(() => options.renderPagesFallback?.({
826
982
  appRouteMatch: match ?? null,
827
983
  allowRscDocumentFallback: didMiddlewareRewritePathname || allowInternalRscDocumentFallback,
828
984
  dispatchPagesResponseStage,
@@ -830,11 +986,11 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
830
986
  isRscRequest,
831
987
  matchKind,
832
988
  middlewareContext,
833
- pathname: resolvedUrl,
989
+ pathname: pagesRouteUrl,
834
990
  pagesDataRequest,
835
991
  request,
836
992
  url
837
- }) ?? null : null;
993
+ })) ?? null : null;
838
994
  if (response) preserveRouteCacheabilityResponsePolicy();
839
995
  if (!response) return null;
840
996
  if (sharedOuterPolicyNeedsReconciliation) reconcileCdnResponseHeadersAfterOuterPolicy(response.headers, await loadOuterResponsePolicy());
@@ -858,8 +1014,9 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
858
1014
  }
859
1015
  if (!isInterceptionMatch && !resolvedLateRewritesForAction && (!match || match.route.isDynamic)) for (const rewrite of options.configRewrites.afterFiles) {
860
1016
  const afterFilesRewrite = await applyRewrite({
861
- basePathState,
1017
+ basePathState: currentBasePathState(),
862
1018
  clearRequestContext: options.clearRequestContext,
1019
+ middlewareContext,
863
1020
  request: normalizedUserlandRequest,
864
1021
  requestContext: requestContextForResolvedUrl(postMiddlewareRequestContext, resolvedUrl, url),
865
1022
  paramsPathname: matchPathname(cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname),
@@ -876,8 +1033,11 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
876
1033
  cleanPathnameIsRequestPathname = false;
877
1034
  invalidateInterceptionCacheProof();
878
1035
  filesystemRouteEligible = true;
1036
+ resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
879
1037
  const claimedRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
880
1038
  if (claimedRscCacheBustingRedirect) return claimedRscCacheBustingRedirect;
1039
+ const rewrittenImageEndpointResponse = serveImageEndpointIfMatched();
1040
+ if (rewrittenImageEndpointResponse) return rewrittenImageEndpointResponse;
881
1041
  const rewrittenMetadataResponse = await renderMetadataRouteIfMatched();
882
1042
  if (rewrittenMetadataResponse) return composeResponseStageResponse(rewrittenMetadataResponse);
883
1043
  match = matchCleanPathname();
@@ -900,8 +1060,9 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
900
1060
  }
901
1061
  if (!resolvedLateRewritesForAction && !match) for (const rewrite of options.configRewrites.fallback) {
902
1062
  const fallbackRewrite = await applyRewrite({
903
- basePathState,
1063
+ basePathState: currentBasePathState(),
904
1064
  clearRequestContext: options.clearRequestContext,
1065
+ middlewareContext,
905
1066
  request: normalizedUserlandRequest,
906
1067
  requestContext: requestContextForResolvedUrl(postMiddlewareRequestContext, resolvedUrl, url),
907
1068
  paramsPathname: matchPathname(cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname),
@@ -918,8 +1079,11 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
918
1079
  cleanPathnameIsRequestPathname = false;
919
1080
  invalidateInterceptionCacheProof();
920
1081
  filesystemRouteEligible = true;
1082
+ resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
921
1083
  const claimedRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
922
1084
  if (claimedRscCacheBustingRedirect) return claimedRscCacheBustingRedirect;
1085
+ const rewrittenImageEndpointResponse = serveImageEndpointIfMatched();
1086
+ if (rewrittenImageEndpointResponse) return rewrittenImageEndpointResponse;
923
1087
  const rewrittenMetadataResponse = await renderMetadataRouteIfMatched();
924
1088
  if (rewrittenMetadataResponse) return composeResponseStageResponse(rewrittenMetadataResponse);
925
1089
  match = matchCleanPathname();
@@ -935,15 +1099,16 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
935
1099
  }
936
1100
  if (match) break;
937
1101
  }
938
- if (interceptionCacheProofInvalidated && interceptionContextHeader !== null) {
1102
+ if (interceptionCacheProofInvalidated && interceptionSourceContext !== null) {
939
1103
  const finalInterceptionTargetPathname = cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname;
940
- const finalInterceptionSourceMatch = filesystemRouteEligible && match !== null ? options.matchInterceptRoute?.(finalInterceptionTargetPathname, interceptionContextHeader, interceptionIdHeader) ?? null : null;
1104
+ const finalInterceptionSourceMatch = filesystemRouteEligible && match !== null ? options.matchInterceptRoute?.(finalInterceptionTargetPathname, interceptionSourceContext, interceptionIdHeader) ?? null : null;
941
1105
  const hasVerifiedFinalInterceptionSource = hasVerifiedInterceptionSource && interceptionSourceMatch !== null && provesConcreteInterceptionSource(finalInterceptionSourceMatch) && finalInterceptionSourceMatch?.route === interceptionSourceMatch.route && haveSamePageParams(finalInterceptionSourceMatch.params, interceptionSourceMatch.params);
942
1106
  if (interceptionIdHeader !== null && !hasVerifiedFinalInterceptionSource) {
943
1107
  options.clearRequestContext();
944
1108
  setInterceptionResponseUncacheable(true);
945
1109
  return badRequestResponse();
946
1110
  }
1111
+ if (!hasVerifiedFinalInterceptionSource) interceptionSourceContext = null;
947
1112
  bypassInterceptionContextCache = !hasVerifiedFinalInterceptionSource;
948
1113
  setInterceptionResponseUncacheable(bypassInterceptionContextCache);
949
1114
  }
@@ -958,7 +1123,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
958
1123
  options.clearRequestContext();
959
1124
  const headers = new Headers();
960
1125
  mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);
961
- return notFoundResponse({ headers });
1126
+ return withUnmatchedRouteCacheControl(notFoundResponse({ headers }));
962
1127
  }
963
1128
  if (pagesDataRequest) {
964
1129
  options.clearRequestContext();
@@ -982,7 +1147,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
982
1147
  }
983
1148
  setFrameworkRequestRoute("/404", isRscRequest);
984
1149
  const notFoundResponseStage = transportedResponseStage ?? options.renderResponseStageLocally;
985
- if (notFoundResponseStage) return composeResponseStageResponse(await notFoundResponseStage(responseStageRequest(), {
1150
+ if (notFoundResponseStage) return withUnmatchedRouteCacheControl(await composeResponseStageResponse(await notFoundResponseStage(responseStageRequest(), {
986
1151
  kind: "app-not-found",
987
1152
  buildId: options.buildId,
988
1153
  cacheability: responseStageCacheability(resolvedUrl),
@@ -992,12 +1157,12 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
992
1157
  isRscRequest,
993
1158
  middlewareCookieOverlay,
994
1159
  mountedSlotsHeader,
995
- protocolVersion: 10,
1160
+ protocolVersion: 11,
996
1161
  requestOrigin: url.origin,
997
1162
  renderMode,
998
1163
  resolvedUrl,
999
1164
  scriptNonce: scriptNonce ?? null
1000
- }));
1165
+ })));
1001
1166
  const renderedNotFoundResponse = await traceAppPageRender("/404", "render", () => options.renderNotFound({
1002
1167
  isRscRequest,
1003
1168
  middlewareContext,
@@ -1005,12 +1170,13 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1005
1170
  route: null,
1006
1171
  scriptNonce
1007
1172
  }));
1008
- if (renderedNotFoundResponse) return renderedNotFoundResponse;
1173
+ if (renderedNotFoundResponse) return withUnmatchedRouteCacheControl(renderedNotFoundResponse);
1009
1174
  options.clearRequestContext();
1010
1175
  const headers = new Headers();
1011
1176
  mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);
1012
- return notFoundResponse({ headers });
1177
+ return withUnmatchedRouteCacheControl(notFoundResponse({ headers }));
1013
1178
  }
1179
+ match = renderedRouteMatch(match);
1014
1180
  const { route, params } = match;
1015
1181
  const requestPathnameDiffersFromCachePath = requestCleanPathname !== cleanPathname;
1016
1182
  const rawRequestPathnameIsObservable = isInterceptionMatch || route.routeHandler != null || typeof route.__loadRouteHandler === "function";
@@ -1038,7 +1204,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1038
1204
  const prerenderRouteParams = prerenderRouteParamsMatch?.params ?? null;
1039
1205
  const isPrerenderFallbackShell = prerenderRouteParamsMatch?.kind === "fallback-shell";
1040
1206
  const renderParams = prerenderRouteParams ?? params;
1041
- const responseStageMatchKind = isInterceptionMatch ? "interception" : cleanPathnameIsRequestPathname && options.matchRequestRoute ? "request" : "resolved";
1207
+ const responseStageMatchKind = isInterceptionMatch ? "interception" : cleanPathnameIsRequestPathname && options.matchRequestRoute ? usesRawRequestMatch() ? "raw-request" : "request" : "resolved";
1042
1208
  const responseStageRoutePathname = isInterceptionMatch ? preActionRoutePathname : cleanPathnameIsRequestPathname ? requestCleanPathname || "/" : cleanPathname || "/";
1043
1209
  const matchedResponseStage = transportedResponseStage ?? options.renderResponseStageLocally;
1044
1210
  let runtimeFallbackShells = [];
@@ -1078,7 +1244,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1078
1244
  middlewareCookieOverlay,
1079
1245
  mountedSlotsHeader,
1080
1246
  params,
1081
- protocolVersion: 10,
1247
+ protocolVersion: 11,
1082
1248
  requestOrigin: url.origin,
1083
1249
  renderMode,
1084
1250
  resolvedUrl,
@@ -1099,7 +1265,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1099
1265
  searchParams: resolvedSearchParams
1100
1266
  });
1101
1267
  }
1102
- const pageResponse = matchedResponseStage ? await matchedResponseStage(responseStageRequest(), {
1268
+ const pageResponse = withStoredSpecialErrorStatus(matchedResponseStage ? await matchedResponseStage(responseStageRequest(), {
1103
1269
  kind: "app-page",
1104
1270
  buildId: options.buildId,
1105
1271
  cacheability: responseStageCacheability(resolvedUrl),
@@ -1110,14 +1276,14 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1110
1276
  cleanPathname,
1111
1277
  draftModeCookie,
1112
1278
  forceDynamic: route.forceDynamic === true,
1113
- interceptionContext: isRscRequest ? interceptionContextHeader : null,
1279
+ interceptionContext: interceptionSourceContext,
1114
1280
  interceptionId: interceptionIdHeader,
1115
1281
  isRscRequest,
1116
1282
  matchKind: responseStageMatchKind,
1117
1283
  middlewareCookieOverlay,
1118
1284
  mountedSlotsHeader,
1119
1285
  params,
1120
- protocolVersion: 10,
1286
+ protocolVersion: 11,
1121
1287
  requestOrigin: url.origin,
1122
1288
  renderMode,
1123
1289
  resolvedUrl,
@@ -1134,7 +1300,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1134
1300
  actionError: normalizedProgressiveActionError,
1135
1301
  actionFailed,
1136
1302
  handlerStart,
1137
- interceptionContext: isRscRequest ? interceptionContextHeader : null,
1303
+ interceptionContext: interceptionSourceContext,
1138
1304
  interceptionId: interceptionIdHeader,
1139
1305
  interceptionPathname: cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname,
1140
1306
  isProgressiveActionRender,
@@ -1157,7 +1323,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1157
1323
  scriptNonce,
1158
1324
  searchParams: resolvedSearchParams,
1159
1325
  renderMode
1160
- });
1326
+ }), isRscRequest && request.headers.get("Next-Router-Prefetch") === "1" && request.headers.has("Next-Router-Segment-Prefetch"));
1161
1327
  if (isProgressiveActionRender) return applyProgressiveActionSideEffects(pageResponse, progressiveActionFormState);
1162
1328
  return pageResponse;
1163
1329
  }
@@ -1196,7 +1362,7 @@ function applyProgressiveActionSideEffects(response, sideEffects) {
1196
1362
  /** Build the request-only handler without retaining the response renderer graph. */
1197
1363
  function createAppRscRequestHandler(options) {
1198
1364
  const handleAppRscRequestLifecycle = async (rawRequest, ctx, allowInternalRscDocumentFallback = false, dispatchResponseStage, responseStageProbeMode = null, transportedPrerenderState) => {
1199
- const mwCtx = rawRequest.headers.get(VINEXT_MW_CTX_HEADER);
1365
+ const mwCtx = openForwardedMiddlewareContext(rawRequest.headers.get(VINEXT_MW_CTX_HEADER), options.devForwardedMiddlewareContextKey);
1200
1366
  const pagesDataUrl = new URL(rawRequest.url);
1201
1367
  const pagesDataInScope = !options.basePath || hasBasePath(pagesDataUrl.pathname, options.basePath);
1202
1368
  if (pagesDataInScope) pagesDataUrl.pathname = stripBasePath(pagesDataUrl.pathname, options.basePath);
@@ -1261,7 +1427,7 @@ function createAppRscRequestHandler(options) {
1261
1427
  recordCacheability: dispatchResponseStage === void 0,
1262
1428
  requestContext: preMiddlewareRequestContext
1263
1429
  });
1264
- return interceptionResponseUncacheable ? markUnverifiedInterceptionResponseUncacheable(response) : response;
1430
+ return interceptionResponseUncacheable || unmatchedRouteResponses.has(response) ? withNeverCacheControl(response) : response;
1265
1431
  }, {
1266
1432
  cacheComponents: options.createPprFallbackShells !== void 0,
1267
1433
  route: () => new URL(request.url).pathname