vinext 1.2.1 → 1.3.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 (212) hide show
  1. package/README.md +12 -9
  2. package/dist/build/client-build-config.d.ts +64 -3
  3. package/dist/build/client-build-config.js +131 -4
  4. package/dist/build/client-reference-groups.d.ts +163 -0
  5. package/dist/build/client-reference-groups.js +534 -0
  6. package/dist/build/module-dependency-cache.d.ts +31 -0
  7. package/dist/build/module-dependency-cache.js +51 -1
  8. package/dist/build/next-client-runtime-manifests.d.ts +10 -1
  9. package/dist/build/next-client-runtime-manifests.js +19 -4
  10. package/dist/build/nitro-public-files.d.ts +24 -0
  11. package/dist/build/nitro-public-files.js +60 -0
  12. package/dist/build/pages-client-assets-module.js +1 -1
  13. package/dist/build/prerender-paths.js +5 -2
  14. package/dist/build/server-actions-encryption-key.d.ts +23 -0
  15. package/dist/build/server-actions-encryption-key.js +101 -0
  16. package/dist/build/ssr-manifest.d.ts +3 -0
  17. package/dist/build/ssr-manifest.js +10 -1
  18. package/dist/client/client-rewrite-params.d.ts +9 -0
  19. package/dist/client/client-rewrite-params.js +20 -0
  20. package/dist/client/dev-error-overlay.js +2 -1
  21. package/dist/client/navigation-runtime.d.ts +25 -2
  22. package/dist/client/navigation-runtime.js +42 -11
  23. package/dist/client/vinext-next-data.d.ts +0 -1
  24. package/dist/config/config-matchers.d.ts +15 -40
  25. package/dist/config/config-matchers.js +183 -255
  26. package/dist/config/config-source.d.ts +34 -0
  27. package/dist/config/config-source.js +141 -0
  28. package/dist/config/header-params.d.ts +29 -0
  29. package/dist/config/header-params.js +106 -0
  30. package/dist/config/next-config.d.ts +7 -5
  31. package/dist/config/next-config.js +120 -7
  32. package/dist/entries/app-browser-entry.d.ts +14 -1
  33. package/dist/entries/app-browser-entry.js +26 -36
  34. package/dist/entries/app-rsc-entry.d.ts +2 -0
  35. package/dist/entries/app-rsc-entry.js +92 -57
  36. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  37. package/dist/entries/app-rsc-manifest.js +20 -1
  38. package/dist/entries/app-ssr-entry.d.ts +4 -1
  39. package/dist/entries/app-ssr-entry.js +9 -2
  40. package/dist/entries/pages-client-entry.d.ts +1 -0
  41. package/dist/entries/pages-client-entry.js +6 -6
  42. package/dist/entries/pages-server-entry.js +17 -14
  43. package/dist/index.d.ts +11 -0
  44. package/dist/index.js +239 -83
  45. package/dist/init.js +17 -0
  46. package/dist/plugins/optimize-imports.d.ts +25 -2
  47. package/dist/plugins/optimize-imports.js +106 -20
  48. package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
  49. package/dist/plugins/rsc-client-reference-loaders.js +336 -18
  50. package/dist/plugins/use-cache-callable.d.ts +5 -0
  51. package/dist/plugins/use-cache-callable.js +30 -8
  52. package/dist/plugins/worker-image-imports.d.ts +1 -0
  53. package/dist/plugins/worker-image-imports.js +1 -1
  54. package/dist/routing/app-route-graph.d.ts +1 -1
  55. package/dist/routing/browser-route-manifest.d.ts +43 -0
  56. package/dist/routing/browser-route-manifest.js +195 -0
  57. package/dist/routing/hashed-route-patterns.d.ts +4 -0
  58. package/dist/routing/hashed-route-patterns.js +22 -0
  59. package/dist/routing/optimistic-route-trie.d.ts +27 -0
  60. package/dist/routing/optimistic-route-trie.js +102 -0
  61. package/dist/routing/route-validation.d.ts +6 -1
  62. package/dist/routing/route-validation.js +26 -10
  63. package/dist/server/app-action-forwarding.d.ts +8 -0
  64. package/dist/server/app-action-forwarding.js +15 -1
  65. package/dist/server/app-browser-entry.js +147 -60
  66. package/dist/server/app-browser-error.d.ts +3 -1
  67. package/dist/server/app-browser-error.js +7 -2
  68. package/dist/server/app-browser-interception-context.d.ts +2 -2
  69. package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
  70. package/dist/server/app-browser-mpa-navigation.js +6 -5
  71. package/dist/server/app-browser-navigation-controller.d.ts +17 -6
  72. package/dist/server/app-browser-navigation-controller.js +88 -26
  73. package/dist/server/app-browser-state.d.ts +2 -2
  74. package/dist/server/app-browser-visible-commit.d.ts +4 -4
  75. package/dist/server/app-client-reference-preloader.d.ts +23 -0
  76. package/dist/server/app-client-reference-preloader.js +30 -7
  77. package/dist/server/app-fallback-renderer.js +2 -1
  78. package/dist/server/app-middleware.d.ts +6 -0
  79. package/dist/server/app-middleware.js +8 -10
  80. package/dist/server/app-optimistic-routing.d.ts +8 -10
  81. package/dist/server/app-optimistic-routing.js +4 -95
  82. package/dist/server/app-page-boundary-render.js +8 -1
  83. package/dist/server/app-page-cache-render.js +1 -0
  84. package/dist/server/app-page-dispatch.js +2 -0
  85. package/dist/server/app-page-render.js +3 -1
  86. package/dist/server/app-page-rsc-render-status.d.ts +1 -0
  87. package/dist/server/app-page-rsc-render-status.js +1 -0
  88. package/dist/server/app-page-search-params-observation.d.ts +1 -4
  89. package/dist/server/app-page-search-params-observation.js +8 -10
  90. package/dist/server/app-page-stream.d.ts +7 -0
  91. package/dist/server/app-page-stream.js +1 -0
  92. package/dist/server/app-pages-bridge.d.ts +2 -1
  93. package/dist/server/app-pages-bridge.js +11 -7
  94. package/dist/server/app-prerender-static-params.js +3 -2
  95. package/dist/server/app-render-dependency.js +42 -2
  96. package/dist/server/app-request-stage-independent-entry.js +2 -2
  97. package/dist/server/app-response-stage-entry.js +3 -3
  98. package/dist/server/app-route-handler-dispatch.js +3 -1
  99. package/dist/server/app-route-handler-execution.d.ts +2 -0
  100. package/dist/server/app-route-handler-execution.js +9 -2
  101. package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
  102. package/dist/server/app-route-handler-middleware-context.js +3 -3
  103. package/dist/server/app-route-handler-response.d.ts +2 -1
  104. package/dist/server/app-route-handler-response.js +2 -2
  105. package/dist/server/app-route-handler-runtime.d.ts +2 -0
  106. package/dist/server/app-route-handler-runtime.js +20 -3
  107. package/dist/server/app-route-module-loader.js +7 -6
  108. package/dist/server/app-route-tree.d.ts +20 -0
  109. package/dist/server/app-route-tree.js +18 -0
  110. package/dist/server/app-router-entry.js +2 -2
  111. package/dist/server/app-rsc-combined-handler.js +8 -1
  112. package/dist/server/app-rsc-errors.d.ts +7 -0
  113. package/dist/server/app-rsc-errors.js +9 -2
  114. package/dist/server/app-rsc-handler.d.ts +4 -1
  115. package/dist/server/app-rsc-handler.js +146 -130
  116. package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
  117. package/dist/server/app-rsc-response-finalizer.js +4 -1
  118. package/dist/server/app-rsc-response-stage.js +3 -1
  119. package/dist/server/app-rsc-route-matching.d.ts +1 -0
  120. package/dist/server/app-rsc-route-matching.js +1 -1
  121. package/dist/server/app-server-action-execution.d.ts +23 -6
  122. package/dist/server/app-server-action-execution.js +50 -56
  123. package/dist/server/app-ssr-entry.d.ts +6 -0
  124. package/dist/server/app-ssr-entry.js +16 -7
  125. package/dist/server/app-ssr-stream.d.ts +7 -0
  126. package/dist/server/app-ssr-stream.js +13 -1
  127. package/dist/server/config-headers.js +12 -3
  128. package/dist/server/isolate-shared-promise.d.ts +10 -0
  129. package/dist/server/isolate-shared-promise.js +33 -0
  130. package/dist/server/isr-cache.js +3 -2
  131. package/dist/server/middleware-matcher-pattern.d.ts +0 -1
  132. package/dist/server/middleware-matcher-pattern.js +11 -140
  133. package/dist/server/middleware-matcher.js +5 -6
  134. package/dist/server/middleware-response-headers.d.ts +31 -0
  135. package/dist/server/middleware-response-headers.js +57 -1
  136. package/dist/server/middleware-runtime.js +26 -13
  137. package/dist/server/navigation-planner.d.ts +2 -2
  138. package/dist/server/nitro-public-files-plugin.d.ts +38 -0
  139. package/dist/server/nitro-public-files-plugin.js +106 -0
  140. package/dist/server/nitro-public-files.d.ts +21 -0
  141. package/dist/server/nitro-public-files.js +39 -0
  142. package/dist/server/pages-asset-tags.d.ts +5 -0
  143. package/dist/server/pages-asset-tags.js +9 -2
  144. package/dist/server/pages-client-assets.d.ts +4 -1
  145. package/dist/server/pages-i18n.d.ts +18 -0
  146. package/dist/server/pages-i18n.js +18 -2
  147. package/dist/server/pages-node-compat.d.ts +5 -3
  148. package/dist/server/pages-node-compat.js +35 -16
  149. package/dist/server/pages-request-pipeline.d.ts +6 -1
  150. package/dist/server/pages-request-pipeline.js +31 -35
  151. package/dist/server/pages-request-stage-entry.js +16 -6
  152. package/dist/server/pages-response-stage-entry.js +1 -1
  153. package/dist/server/pages-revalidate.js +1 -0
  154. package/dist/server/pages-router-entry.js +1 -1
  155. package/dist/server/prod-server.d.ts +2 -2
  156. package/dist/server/prod-server.js +71 -33
  157. package/dist/server/proxy-trust.d.ts +6 -0
  158. package/dist/server/proxy-trust.js +12 -6
  159. package/dist/server/request-pipeline.d.ts +5 -0
  160. package/dist/server/request-pipeline.js +12 -1
  161. package/dist/server/server-reference-loader.js +10 -1
  162. package/dist/server/static-file-cache.js +15 -3
  163. package/dist/server/worker-utils.js +1 -1
  164. package/dist/shims/cache-handler.js +3 -2
  165. package/dist/shims/cache-request-state.d.ts +40 -3
  166. package/dist/shims/cache-request-state.js +70 -5
  167. package/dist/shims/cache-runtime.js +47 -19
  168. package/dist/shims/cache.d.ts +2 -2
  169. package/dist/shims/cache.js +17 -8
  170. package/dist/shims/cdn-purge-routes.d.ts +24 -0
  171. package/dist/shims/cdn-purge-routes.js +77 -0
  172. package/dist/shims/dynamic.js +17 -4
  173. package/dist/shims/form.js +8 -3
  174. package/dist/shims/image-props.d.ts +93 -0
  175. package/dist/shims/image-props.js +323 -0
  176. package/dist/shims/image.d.ts +4 -18
  177. package/dist/shims/image.js +4 -319
  178. package/dist/shims/internal/headers-state.d.ts +7 -0
  179. package/dist/shims/internal/headers-state.js +14 -2
  180. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
  181. package/dist/shims/internal/hybrid-client-route-owner-direct.js +31 -14
  182. package/dist/shims/internal/hybrid-client-route-owner.js +8 -8
  183. package/dist/shims/link.js +5 -3
  184. package/dist/shims/navigation.d.ts +1 -1
  185. package/dist/shims/navigation.js +17 -5
  186. package/dist/shims/og.js +35 -10
  187. package/dist/shims/request-context.d.ts +13 -0
  188. package/dist/shims/router.js +19 -40
  189. package/dist/shims/server.d.ts +31 -4
  190. package/dist/shims/server.js +58 -10
  191. package/dist/shims/thenable-params.d.ts +6 -1
  192. package/dist/shims/thenable-params.js +11 -2
  193. package/dist/shims/unified-request-context.d.ts +5 -0
  194. package/dist/shims/unified-request-context.js +2 -0
  195. package/dist/utils/asset-prefix.d.ts +7 -0
  196. package/dist/utils/asset-prefix.js +10 -1
  197. package/dist/utils/client-build-manifest.js +12 -5
  198. package/dist/utils/client-runtime-metadata.d.ts +1 -0
  199. package/dist/utils/client-runtime-metadata.js +15 -2
  200. package/dist/utils/lazy-chunks.d.ts +4 -0
  201. package/dist/utils/manifest-paths.d.ts +14 -0
  202. package/dist/utils/manifest-paths.js +22 -1
  203. package/dist/utils/path-to-regexp.d.ts +21 -0
  204. package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
  205. package/dist/utils/plugin-react-version.d.ts +15 -0
  206. package/dist/utils/plugin-react-version.js +64 -0
  207. package/dist/utils/public-routes.d.ts +2 -0
  208. package/dist/utils/public-routes.js +18 -7
  209. package/package.json +1 -1
  210. package/dist/server/middleware-path-to-regexp.d.ts +0 -13
  211. package/dist/utils/regex-safety.d.ts +0 -17
  212. package/dist/utils/regex-safety.js +0 -789
@@ -31,7 +31,7 @@ var app_router_entry_default = {
31
31
  __ensureInstrumentation,
32
32
  async fetch(request, env, ctx) {
33
33
  const handleFetch = async () => {
34
- await __ensureInstrumentation();
34
+ await __ensureInstrumentation(ctx);
35
35
  const url = new URL(request.url);
36
36
  return traceFrameworkRequest({
37
37
  callback: async () => applyCdnResponseIdentityHeaders(await handleRequest(request, env, ctx), request),
@@ -53,7 +53,7 @@ async function handleRequest(request, env, platformCtx) {
53
53
  let ctx = createWorkerPrerenderDiscoveryContext(requestCtx, request, __prerenderSecret);
54
54
  const readinessResponse = createWorkerPrerenderReadinessResponse(ctx, request);
55
55
  if (readinessResponse) {
56
- if (readinessResponse.status === 204) await __ensureHybridPagesApplication();
56
+ if (readinessResponse.status === 204) await __ensureHybridPagesApplication(ctx);
57
57
  return await validateCdnRequest(request) ?? readinessResponse;
58
58
  }
59
59
  let finalizeCacheabilityResponse;
@@ -1,8 +1,15 @@
1
+ import { getRequestExecutionContext, runWithExecutionContext } from "../shims/request-context.js";
2
+ import { createWorkerRevalidationContext } from "./worker-revalidation-context.js";
1
3
  import { createAppRscRequestHandler } from "./app-rsc-handler.js";
2
4
  //#region src/server/app-rsc-combined-handler.ts
3
5
  /** Combined request/response handler used by default single-stage App entries. */
4
6
  function createAppRscHandler(options) {
5
- const appRscHandler = createAppRscRequestHandler(options);
7
+ const appRscRequestHandler = createAppRscRequestHandler(options);
8
+ const appRscHandler = (request, ctx, ...rest) => {
9
+ if (ctx != null || getRequestExecutionContext()) return appRscRequestHandler(request, ctx, ...rest);
10
+ const executionContext = createWorkerRevalidationContext(void 0, (internalRequest, internalCtx) => runWithExecutionContext(internalCtx, () => appRscRequestHandler(internalRequest, internalCtx)), "node");
11
+ return runWithExecutionContext(executionContext, () => appRscRequestHandler(request, ctx, ...rest));
12
+ };
6
13
  return Object.assign(appRscHandler, { handleResponseStage(request, ctx, props, stageOptions) {
7
14
  return import("./app-rsc-response-stage.js").then(({ renderAppWorkerResponseStage }) => renderAppWorkerResponseStage(options, request, ctx, props, stageOptions));
8
15
  } });
@@ -37,6 +37,13 @@ export declare function getDigestForWellKnownError(error: unknown): string | und
37
37
  * djb2 hash matching Next.js's string-hash package for RSC error digests.
38
38
  */
39
39
  export declare function errorDigest(input: string): string;
40
+ /**
41
+ * The message React 19.3's production Flight client gives a Server Components
42
+ * error in the browser (minified error #441). Sanitized errors that vinext
43
+ * serializes itself, such as the error passed to app/global-error, use the
44
+ * same text so they read the same as errors React reconstructs.
45
+ */
46
+ export declare const PRODUCTION_SERVER_COMPONENTS_ERROR_MESSAGE = "Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";
40
47
  export declare function sanitizeErrorForClient(error: unknown, nodeEnv?: "development" | "production" | "test"): unknown;
41
48
  export declare function createRscOnErrorHandler(options: CreateRscOnErrorHandlerOptions): (error: unknown) => string | undefined;
42
49
  //#endregion
@@ -41,10 +41,17 @@ function errorDigest(input) {
41
41
  for (let i = input.length - 1; i >= 0; i--) hash = hash * 33 ^ input.charCodeAt(i);
42
42
  return (hash >>> 0).toString();
43
43
  }
44
+ /**
45
+ * The message React 19.3's production Flight client gives a Server Components
46
+ * error in the browser (minified error #441). Sanitized errors that vinext
47
+ * serializes itself, such as the error passed to app/global-error, use the
48
+ * same text so they read the same as errors React reconstructs.
49
+ */
50
+ const PRODUCTION_SERVER_COMPONENTS_ERROR_MESSAGE = "Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";
44
51
  function sanitizeErrorForClient(error, nodeEnv = process.env.NODE_ENV) {
45
52
  if (resolveAppPageSpecialError(error)) return error;
46
53
  if (nodeEnv !== "production") return error;
47
- 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.");
54
+ const sanitized = /* @__PURE__ */ new Error(PRODUCTION_SERVER_COMPONENTS_ERROR_MESSAGE);
48
55
  sanitized.digest = hasDigest(error) ? String(error.digest) : getThrownValueDigest(error);
49
56
  Object.defineProperty(sanitized, ORIGINAL_SERVER_ERROR, {
50
57
  configurable: false,
@@ -85,4 +92,4 @@ function createRscOnErrorHandler(options) {
85
92
  };
86
93
  }
87
94
  //#endregion
88
- export { createRscOnErrorHandler, errorDigest, getDigestForWellKnownError, hasDigest, sanitizeErrorForClient };
95
+ export { PRODUCTION_SERVER_COMPONENTS_ERROR_MESSAGE, createRscOnErrorHandler, errorDigest, getDigestForWellKnownError, hasDigest, sanitizeErrorForClient };
@@ -1,6 +1,7 @@
1
1
  import { VinextCacheabilityProbeMode } from "./multi-stage.js";
2
2
  import { NextHeader, NextI18nConfig, NextRedirect, NextRewrite } from "../config/next-config.js";
3
3
  import { ImageConfig } from "./image-optimization.js";
4
+ import { ExecutionContextLike } from "../shims/request-context.js";
4
5
  import { AppMiddlewareContext, ApplyAppMiddlewareResult } from "./app-middleware.js";
5
6
  import { ClientReuseManifestParseResult } from "./client-reuse-manifest.js";
6
7
  import { AppRscRenderMode } from "./app-rsc-render-mode.js";
@@ -217,7 +218,7 @@ export type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
217
218
  * dedup'd. Provided by the generated RSC entry; absent in older entries.
218
219
  */
219
220
  ensureRouteLoaded?: (route: TRoute) => unknown;
220
- ensureInstrumentation?: () => Promise<void>;
221
+ ensureInstrumentation?: (ctx: ExecutionContextLike | null) => Promise<void>;
221
222
  /**
222
223
  * Register cache adapters configured via the vinext() `cache` option. Wired
223
224
  * from the generated RSC entry (which can import `virtual:vinext-cache-adapters`)
@@ -251,6 +252,8 @@ export type CreateAppRscHandlerOptions<TRoute extends AppRscHandlerRoute> = {
251
252
  renderPagesFallback?: (options: RenderPagesFallbackOptions) => Promise<Response | null>;
252
253
  rootParamNamesByPattern?: RootParamNamesMap;
253
254
  setNavigationContext: (context: NavigationContextValue) => void;
255
+ /** next.config `skipProxyUrlNormalize`. */
256
+ skipProxyUrlNormalize?: boolean;
254
257
  /** next.config `skipTrailingSlashRedirect`: serve both slash forms without a 308. */
255
258
  skipTrailingSlashRedirect?: boolean;
256
259
  staticParamsMap: StaticParamsMap;
@@ -15,7 +15,7 @@ import { patternToNextFormat } from "../routing/route-validation.js";
15
15
  import { getRequestExecutionContext } from "../shims/request-context.js";
16
16
  import { runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
17
17
  import { isInterceptionMatchedUrlPath, normalizePath } from "./normalize-path.js";
18
- import { normalizeDefaultLocalePathname } from "./pages-i18n.js";
18
+ import { normalizeDefaultLocalePathname, shouldRestoreLocaleRootTrailingSlash } from "./pages-i18n.js";
19
19
  import { buildNextDataNotFoundResponse, normalizePagesDataRequest } from "./pages-data-route.js";
20
20
  import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
21
21
  import { markRouteCacheabilityDynamic, preserveRouteCacheabilityResponsePolicy } from "../shims/cacheability-classification.js";
@@ -29,7 +29,7 @@ import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, isImageOptimizationPath, mar
29
29
  import { parseCacheabilityManifest } from "./cacheability-manifest.js";
30
30
  import { getRenderedConcreteUrlPathsForRoute } from "./pregenerated-concrete-paths.js";
31
31
  import { VINEXT_RSC_CACHE_BUSTING_SEARCH_PARAM, canonicalizeLoadingShellRscRequestHeaders, canonicalizePrewarmableRscRequestHeaders, createCanonicalRscRequestUrl, createRscRedirectLocation, createRscRequestUrl, hasRscCacheBustingSearchParam, resolveInvalidRscCacheBustingRequest, stripRscCacheBustingSearchParam, stripRscSuffix } from "./app-rsc-cache-busting.js";
32
- import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
32
+ import { mergeMiddlewareResponseHeaders, mergeMiddlewareResponseHeadersOntoResponse, withExternalRewriteResponseHeaders } from "./middleware-response-headers.js";
33
33
  import { consumeResponseStageLinkProvenance, copyLinkHeaderProvenance } from "./app-response-header-provenance.js";
34
34
  import "./app-page-response.js";
35
35
  import { parseNextHttpErrorDigest } from "./next-error-digest.js";
@@ -40,6 +40,7 @@ import { matchPrerenderRouteParamsPayload, readTrustedPrerenderRouteParams, seri
40
40
  import { buildPageCacheTags } from "./implicit-tags.js";
41
41
  import { createServerActionNotFoundResponse, getServerActionNotFoundMessage } from "./server-action-not-found.js";
42
42
  import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
43
+ import { isAppRouteHandlerRoute } from "./app-rsc-route-matching.js";
43
44
  import { normalizeInterceptionContextHeader } from "./app-interception-context-header.js";
44
45
  import { buildPostMwRequestContext } from "./app-post-middleware-context.js";
45
46
  import { pickRootParams, setRootParams } from "../shims/root-params.js";
@@ -145,7 +146,7 @@ function applyMiddlewareContextToResponse(response, middlewareContext, appendToP
145
146
  if (!middlewareContext.headers && middlewareContext.status == null) return response;
146
147
  const headers = new Headers(response.headers);
147
148
  const responseLink = appendToPostConfigLink ? headers.get("link") : null;
148
- mergeMiddlewareResponseHeaders(headers, middlewareContext.headers);
149
+ mergeMiddlewareResponseHeadersOntoResponse(headers, middlewareContext.headers);
149
150
  const middlewareLink = middlewareContext.headers?.get("link");
150
151
  if (responseLink && middlewareLink) headers.set("link", `${middlewareLink}, ${responseLink}`);
151
152
  return preserveFullyBufferedBodyMetadata(response, new Response(response.body, {
@@ -210,7 +211,7 @@ async function applyRewrite(options, cleanPathname, recordCacheability = true) {
210
211
  const { requestWithMiddlewareContextHeaders } = await import("./app-middleware.js");
211
212
  const proxyRequest = requestWithMiddlewareContextHeaders(options.request, options.middlewareContext);
212
213
  options.clearRequestContext();
213
- return configMatchers.proxyExternalRequest(proxyRequest, rewritten);
214
+ return markAppRscResponseConfigHeadersApplied(withExternalRewriteResponseHeaders(await configMatchers.proxyExternalRequest(proxyRequest, rewritten), new Headers(), options.middlewareContext.headers?.getSetCookie() ?? []));
214
215
  }
215
216
  return rewritten;
216
217
  }
@@ -245,6 +246,7 @@ async function applyConfigHeadersToMiddlewareRedirect(response, options) {
245
246
  pathname: options.pathname,
246
247
  requestContext: options.requestContext,
247
248
  basePathState: options.basePathState,
249
+ middlewareHeaders: response.headers,
248
250
  recordCacheability: options.recordCacheability
249
251
  });
250
252
  if (!headers.entries().next().done) {
@@ -374,6 +376,11 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
374
376
  if (trailingSlashRedirect) return trailingSlashRedirect;
375
377
  }
376
378
  const matchPathname = (p) => normalizeDefaultLocalePathname(p, options.i18nConfig, { hostname: url.hostname });
379
+ const restoreLocaleRootTrailingSlash = !pagesDataRequest && shouldRestoreLocaleRootTrailingSlash(stripRscSuffix(url.pathname), options);
380
+ const headerMatchPathname = normalizeDefaultLocalePathname(requestCleanPathname, options.i18nConfig, {
381
+ hostname: url.hostname,
382
+ restoreRootTrailingSlash: restoreLocaleRootTrailingSlash
383
+ });
377
384
  const redirectPathname = matchPathname(requestCleanPathname);
378
385
  const configMatchers = HAS_CONFIG_REDIRECTS && options.configRedirects.length ? await import("../config/config-matchers.js") : null;
379
386
  const redirect = configMatchers ? configMatchers.matchRedirect(redirectPathname, options.configRedirects, preMiddlewareRequestContext, basePathState, dispatchResponseStage ? void 0 : markConditionalRedirectCacheability) : null;
@@ -424,10 +431,24 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
424
431
  if (!dispatchResponseStage && middlewareResult.pathnameEligible) markRouteCacheabilityDynamic(middlewareResult.matched ? "middleware matched this request" : "middleware is eligible for this pathname");
425
432
  if (middlewareResult.kind === "response") {
426
433
  if (request.body && !request.body.locked) request.body.cancel().catch(() => {});
434
+ if (middlewareResult.externalRewrite) {
435
+ const headers = new Headers();
436
+ await applyAppRscConfigHeaders(headers, request, {
437
+ basePath: options.basePath,
438
+ configHeaders: options.configHeaders,
439
+ i18nConfig: options.i18nConfig,
440
+ restoreLocaleRootTrailingSlash,
441
+ middlewareHeaders: middlewareContext.headers,
442
+ recordCacheability: dispatchResponseStage === void 0,
443
+ requestContext: preMiddlewareRequestContext
444
+ });
445
+ return markAppRscResponseConfigHeadersApplied(withExternalRewriteResponseHeaders(middlewareResult.response, headers, []));
446
+ }
447
+ middlewareContext.headers ??= new Headers(middlewareResult.response.headers);
427
448
  return applyConfigHeadersToMiddlewareRedirect(middlewareResult.response, {
428
449
  basePathState,
429
450
  configHeaders: options.configHeaders,
430
- pathname: matchPathname(requestCleanPathname),
451
+ pathname: headerMatchPathname,
431
452
  recordCacheability: dispatchResponseStage === void 0,
432
453
  requestContext: preMiddlewareRequestContext
433
454
  });
@@ -453,7 +474,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
453
474
  const loadResponseStagePolicy = () => responseStagePolicyPromise ??= options.configHeaders.length ? import("./config-headers.js").then(({ resolveResponseStageCachePolicy }) => withoutResponseStageVary(resolveResponseStageCachePolicy({
454
475
  basePathState,
455
476
  configHeaders: options.configHeaders,
456
- pathname: matchPathname(requestCleanPathname),
477
+ pathname: headerMatchPathname,
457
478
  requestContext: preMiddlewareRequestContext
458
479
  }))) : Promise.resolve(null);
459
480
  let canUseSharedWorkerResponseStage = draftModeCookie === null && !hasMiddlewareCookieOverlay && !hasMiddlewareRequestHeaderOverrides(middlewareContext.requestHeaders ?? middlewareContext.headers) && !requestOptsOutOfWorkerResponseStage(request, options, scriptNonce, allowInternalRscDocumentFallback);
@@ -558,6 +579,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
558
579
  basePath: options.basePath,
559
580
  configHeaders: options.configHeaders,
560
581
  i18nConfig: options.i18nConfig,
582
+ restoreLocaleRootTrailingSlash,
561
583
  middlewareHeaders: middlewareContext.headers,
562
584
  overwriteExisting: preserveExistingPolicy ? /* @__PURE__ */ new Set() : isCdnResponsePolicyHeader,
563
585
  recordCacheability: dispatchResponseStage === void 0,
@@ -576,6 +598,8 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
576
598
  basePath: options.basePath,
577
599
  configHeaders: options.configHeaders,
578
600
  i18nConfig: options.i18nConfig,
601
+ restoreLocaleRootTrailingSlash,
602
+ middlewareHeaders: middlewareContext.headers,
579
603
  overwriteExisting: isCdnResponsePolicyHeader,
580
604
  recordCacheability: false,
581
605
  requestContext: preMiddlewareRequestContext
@@ -594,7 +618,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
594
618
  return markAppRscResponseConfigHeadersApplied(response);
595
619
  };
596
620
  const postMiddlewareRequestContext = buildPostMwRequestContext(userlandRequest);
597
- filesystemRouteEligible ||= didMiddlewareRewrite;
621
+ if (didMiddlewareRewrite) filesystemRouteEligible = resolvedPathnameHasBasePath;
598
622
  for (const rewrite of options.configRewrites.beforeFiles) {
599
623
  const beforeFilesRewrite = await applyRewrite({
600
624
  basePathState: currentBasePathState(),
@@ -611,8 +635,8 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
611
635
  resolvedUrl = mergeRewriteQuery(resolvedUrl, beforeFilesRewrite);
612
636
  cleanPathname = pathnameForResolvedUrl(resolvedUrl);
613
637
  cleanPathnameIsRequestPathname = false;
614
- filesystemRouteEligible = true;
615
638
  resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
639
+ filesystemRouteEligible = resolvedPathnameHasBasePath;
616
640
  }
617
641
  }
618
642
  const claimedRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
@@ -621,55 +645,6 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
621
645
  const isPostRequest = request.method.toUpperCase() === "POST";
622
646
  const contentType = request.headers.get("content-type") || "";
623
647
  const isProgressiveActionRequest = isPostRequest && !actionId && contentType.startsWith("multipart/form-data");
624
- let resolvedLateRewritesForAction = false;
625
- if (!filesystemRouteEligible && (actionId || isProgressiveActionRequest)) {
626
- let actionMatch = null;
627
- for (const rewrite of options.configRewrites.afterFiles) {
628
- const rewritten = await applyRewrite({
629
- basePathState: currentBasePathState(),
630
- clearRequestContext: options.clearRequestContext,
631
- middlewareContext,
632
- request: normalizedUserlandRequest,
633
- requestContext: requestContextForResolvedUrl(postMiddlewareRequestContext, resolvedUrl, url),
634
- paramsPathname: matchPathname(cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname),
635
- rewrites: [rewrite],
636
- validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
637
- }, matchPathname(cleanPathname), dispatchResponseStage === void 0);
638
- if (rewritten instanceof Response) return rewritten;
639
- if (!rewritten) continue;
640
- resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
641
- cleanPathname = pathnameForResolvedUrl(resolvedUrl);
642
- cleanPathnameIsRequestPathname = false;
643
- filesystemRouteEligible = true;
644
- resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
645
- actionMatch = matchCleanPathname();
646
- if (actionMatch) break;
647
- }
648
- if (!actionMatch) for (const rewrite of options.configRewrites.fallback) {
649
- const rewritten = await applyRewrite({
650
- basePathState: currentBasePathState(),
651
- clearRequestContext: options.clearRequestContext,
652
- middlewareContext,
653
- request: normalizedUserlandRequest,
654
- requestContext: requestContextForResolvedUrl(postMiddlewareRequestContext, resolvedUrl, url),
655
- paramsPathname: matchPathname(cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname),
656
- rewrites: [rewrite],
657
- validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
658
- }, matchPathname(cleanPathname), dispatchResponseStage === void 0);
659
- if (rewritten instanceof Response) return rewritten;
660
- if (!rewritten) continue;
661
- resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
662
- cleanPathname = pathnameForResolvedUrl(resolvedUrl);
663
- cleanPathnameIsRequestPathname = false;
664
- filesystemRouteEligible = true;
665
- resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
666
- actionMatch = matchCleanPathname();
667
- if (actionMatch) break;
668
- }
669
- resolvedLateRewritesForAction = filesystemRouteEligible;
670
- }
671
- const lateActionRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
672
- if (lateActionRscCacheBustingRedirect) return lateActionRscCacheBustingRedirect;
673
648
  const serveImageEndpointIfMatched = () => {
674
649
  if (!filesystemRouteEligible || !resolvedPathnameHasBasePath || !isImageOptimizationPath(cleanPathname)) return null;
675
650
  const imageUrl = new URL(resolvedUrl, url);
@@ -691,17 +666,20 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
691
666
  if (imageEndpointResponse) return imageEndpointResponse;
692
667
  const metadataRouteResponse = await renderMetadataRouteIfMatched();
693
668
  if (metadataRouteResponse) return composeResponseStageResponse(metadataRouteResponse);
694
- const publicFileResponse = filesystemRouteEligible ? resolvePublicFileRoute({
695
- cleanPathname: cleanPathnameIsRequestPathname ? cleanPathname : normalizePathnameForRouteMatch(cleanPathname),
696
- middlewareContext,
697
- pathname,
698
- publicFiles: options.publicFiles,
699
- request
700
- }) : null;
701
- if (publicFileResponse) {
702
- options.clearRequestContext();
669
+ const servePublicFileIfMatched = () => {
670
+ if (!filesystemRouteEligible) return null;
671
+ const publicFileResponse = resolvePublicFileRoute({
672
+ cleanPathname: cleanPathnameIsRequestPathname ? cleanPathname : normalizePathnameForRouteMatch(cleanPathname),
673
+ middlewareContext,
674
+ pathname,
675
+ publicFiles: options.publicFiles,
676
+ request
677
+ });
678
+ if (publicFileResponse) options.clearRequestContext();
703
679
  return publicFileResponse;
704
- }
680
+ };
681
+ const publicFileResponse = servePublicFileIfMatched();
682
+ if (publicFileResponse) return publicFileResponse;
705
683
  stripRscCacheBustingSearchParam(url);
706
684
  resolvedUrl = serializeResolvedUrl(resolvedUrl, url);
707
685
  options.setNavigationContext({
@@ -740,7 +718,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
740
718
  const rewrittenSourceMatch = options.matchRoute(rewrittenPathname);
741
719
  return interceptionSourceMatch !== null && rewrittenSourceMatch?.route === interceptionSourceMatch.route && haveSamePageParams(rewrittenSourceMatch.params, interceptionSourceMatch.params);
742
720
  };
743
- if (configMatchers?.matchRedirect(matchPathname(sourceRequestPathname), options.configRedirects, preMiddlewareRequestContext, basePathState, dispatchResponseStage ? void 0 : markConditionalRedirectCacheability)) {
721
+ if (configMatchers?.matchRedirect(matchPathname(sourceRequestPathname), options.configRedirects, preMiddlewareRequestContext, currentBasePathState(), dispatchResponseStage ? void 0 : markConditionalRedirectCacheability)) {
744
722
  options.clearRequestContext();
745
723
  return notFoundResponse();
746
724
  }
@@ -748,7 +726,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
748
726
  if (runMiddleware) {
749
727
  const sourceUrl = new URL(userlandRequest.url);
750
728
  sourceUrl.search = new URL(resolvedUrl, url).search;
751
- const sourceUrlPathname = hadBasePath && options.basePath ? sourceRequestPathname === "/" ? options.basePath : options.basePath + sourceRequestPathname : sourceRequestPathname;
729
+ const sourceUrlPathname = resolvedPathnameHasBasePath && options.basePath ? sourceRequestPathname === "/" ? options.basePath : options.basePath + sourceRequestPathname : sourceRequestPathname;
752
730
  sourceUrl.pathname = sourceUrlPathname;
753
731
  if (sourceUrl.pathname !== sourceUrlPathname) {
754
732
  options.clearRequestContext();
@@ -780,7 +758,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
780
758
  cleanPathname: decodedSourceRequestPathname,
781
759
  context: sourceMiddlewareContext,
782
760
  externalRewriteRequest: normalizedUserlandRequest,
783
- hadBasePath,
761
+ hadBasePath: resolvedPathnameHasBasePath,
784
762
  isDataRequest: isMiddlewareDataRequest,
785
763
  request: sourceMiddlewareRequest,
786
764
  validateExternalRewriteRequest: () => validateClaimedOutsideBasePathRsc(true)
@@ -815,7 +793,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
815
793
  canUseSharedWorkerResponseStage = false;
816
794
  }
817
795
  if (sourceMiddlewareResult.rewritten) {
818
- if (sourceMiddlewareResult.search !== sourceUrl.search || !adoptRewrittenInterceptionSource(sourceMiddlewareResult.cleanPathname)) {
796
+ if (options.basePath && sourceMiddlewareResult.rewriteHadBasePath === false || sourceMiddlewareResult.search !== sourceUrl.search || !adoptRewrittenInterceptionSource(sourceMiddlewareResult.cleanPathname)) {
819
797
  options.clearRequestContext();
820
798
  return notFoundResponse();
821
799
  }
@@ -827,7 +805,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
827
805
  const sourceRewriteContext = requestContextForResolvedUrl(buildPostMwRequestContext(userlandRequest), resolvedUrl, url);
828
806
  let didRewriteSource = false;
829
807
  for (const rewrite of options.configRewrites.beforeFiles) {
830
- const destination = matchRewrite(matchPathname(sourceRulesPathname), [rewrite], sourceRewriteContext, basePathState, matchPathname(sourceRulesPathname), dispatchResponseStage === void 0 ? markConditionalRewriteCacheability : void 0);
808
+ const destination = matchRewrite(matchPathname(sourceRulesPathname), [rewrite], sourceRewriteContext, currentBasePathState(), matchPathname(sourceRulesPathname), dispatchResponseStage === void 0 ? markConditionalRewriteCacheability : void 0);
831
809
  if (!destination) continue;
832
810
  if (isExternalUrl(destination) || destination.includes("?")) {
833
811
  options.clearRequestContext();
@@ -872,64 +850,76 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
872
850
  options.clearRequestContext();
873
851
  return new Response("{}", { headers });
874
852
  }
875
- if (!filesystemRouteEligible && isPostRequest && actionId) {
876
- options.clearRequestContext();
877
- return notFoundResponse();
878
- }
879
- let progressiveActionResult = null;
880
- if (filesystemRouteEligible && isPostRequest && contentType.startsWith("multipart/form-data") && !actionId) {
881
- if (options.handleProgressiveActionRequest) progressiveActionResult = await options.handleProgressiveActionRequest({
882
- actionId,
883
- cleanPathname,
884
- contentType,
885
- middlewareContext,
886
- request,
887
- routeMatch: renderedPreActionMatch
888
- });
889
- else if (preActionMatch?.route.__loadPage && !preActionMatch.route.__loadRouteHandler) return createMissingServerActionResponse(options, null);
890
- }
891
- if (progressiveActionResult instanceof Response) return progressiveActionResult;
892
- const progressiveActionFormState = progressiveActionResult?.kind === "form-state" ? progressiveActionResult : null;
893
- const isProgressiveActionRender = progressiveActionFormState !== null;
894
- const formState = progressiveActionFormState?.formState ?? null;
895
- const failedProgressiveActionResult = progressiveActionFormState && "actionError" in progressiveActionFormState ? progressiveActionFormState : null;
896
- const actionFailed = failedProgressiveActionResult !== null;
897
- const actionError = failedProgressiveActionResult?.actionError;
898
- const actionErrorDigest = actionError && typeof actionError === "object" && "digest" in actionError ? String(actionError.digest) : null;
899
- const actionHttpFallbackStatus = actionErrorDigest ? parseNextHttpErrorDigest(actionErrorDigest)?.status ?? null : null;
900
- const normalizedProgressiveActionError = actionHttpFallbackStatus === null || actionHttpFallbackStatus === 404 ? actionError : { digest: "NEXT_NOT_FOUND" };
901
- if (actionFailed && middlewareContext.status === null && actionHttpFallbackStatus === null) middlewareContext.status = 500;
902
- let sourceConfigHeaders = null;
903
- if (filesystemRouteEligible && isPostRequest && actionId && options.handleServerActionRequest) {
904
- sourceConfigHeaders = new Headers();
853
+ const literalRoutePattern = preActionMatch !== null && !isAppRouteHandlerRoute(preActionMatch.route) ? patternToNextFormat(preActionMatch.route.pattern) : null;
854
+ const routeMatchPathname = cleanPathnameIsRequestPathname ? cleanPathname : normalizePathnameForRouteMatch(cleanPathname);
855
+ const isServerActionRequest = isPostRequest && Boolean(actionId);
856
+ const requestsLiteralRoutePattern = (isProgressiveActionRequest || isServerActionRequest) && literalRoutePattern !== null && literalRoutePattern === (routeMatchPathname.length > 1 && routeMatchPathname.endsWith("/") ? routeMatchPathname.slice(0, -1) : routeMatchPathname);
857
+ const isFinalRouteMatch = isInterceptionMatch || requestsLiteralRoutePattern;
858
+ const preActionMatchIsFinal = preActionMatch !== null && (isFinalRouteMatch || !preActionMatch.route.isDynamic);
859
+ let serverActionHandled = false;
860
+ const handleServerAction = async (routeMatch, routePathname) => {
861
+ if (!filesystemRouteEligible || !isPostRequest || !actionId) return null;
862
+ if (routeMatch && isAppRouteHandlerRoute(routeMatch.route)) return null;
863
+ if (!options.handleServerActionRequest) return createMissingServerActionResponse(options, actionId);
864
+ const sourceConfigHeaders = new Headers();
905
865
  const sourceConfigUrl = new URL(request.url);
906
866
  sourceConfigUrl.pathname = hadBasePath ? addBasePathToPathname(requestCleanPathname, options.basePath) : requestCleanPathname;
907
867
  await applyAppRscConfigHeaders(sourceConfigHeaders, cloneRequestWithUrl(request, sourceConfigUrl.toString()), {
908
868
  basePath: options.basePath,
909
869
  configHeaders: options.configHeaders,
910
870
  i18nConfig: options.i18nConfig,
871
+ restoreLocaleRootTrailingSlash,
872
+ middlewareHeaders: middlewareContext.headers,
911
873
  recordCacheability: dispatchResponseStage === void 0,
912
874
  requestContext: preMiddlewareRequestContext
913
875
  });
876
+ return options.handleServerActionRequest({
877
+ actionId,
878
+ cleanPathname,
879
+ contentType,
880
+ interceptionContext: interceptionSourceContext,
881
+ isRscRequest,
882
+ middlewareContext,
883
+ mountedSlotsHeader,
884
+ request,
885
+ scriptNonce,
886
+ routeMatch,
887
+ routePathname,
888
+ dispatchRedirectTargetRequest: dispatchInternalRequest,
889
+ sourceConfigHeaders,
890
+ searchParams: getResolvedSearchParams()
891
+ });
892
+ };
893
+ let progressiveActionHandled = false;
894
+ let progressiveActionFormState = null;
895
+ const handleProgressiveAction = async (routeMatch, unrenderedRouteMatch) => {
896
+ if (!filesystemRouteEligible || !isProgressiveActionRequest) return null;
897
+ if (routeMatch && isAppRouteHandlerRoute(routeMatch.route)) return null;
898
+ if (!options.handleProgressiveActionRequest) return unrenderedRouteMatch?.route.__loadPage && !unrenderedRouteMatch.route.__loadRouteHandler ? createMissingServerActionResponse(options, null) : null;
899
+ const progressiveActionResult = await options.handleProgressiveActionRequest({
900
+ actionId,
901
+ cleanPathname,
902
+ contentType,
903
+ middlewareContext,
904
+ request,
905
+ routeMatch
906
+ });
907
+ if (progressiveActionResult instanceof Response) return progressiveActionResult;
908
+ if (progressiveActionResult?.kind !== "form-state") return null;
909
+ if ("actionError" in progressiveActionResult && middlewareContext.status === null && progressiveActionHttpFallbackStatus(progressiveActionResult.actionError) === null) middlewareContext.status = 500;
910
+ return progressiveActionResult;
911
+ };
912
+ if (preActionMatchIsFinal) {
913
+ progressiveActionHandled = true;
914
+ const progressiveActionResult = await handleProgressiveAction(renderedPreActionMatch, preActionMatch);
915
+ if (progressiveActionResult instanceof Response) return progressiveActionResult;
916
+ progressiveActionFormState = progressiveActionResult;
917
+ }
918
+ if (isServerActionRequest && preActionMatchIsFinal) {
919
+ serverActionHandled = true;
920
+ const serverActionResponse = await handleServerAction(renderedPreActionMatch, preActionRoutePathname);
921
+ if (serverActionResponse) return serverActionResponse;
914
922
  }
915
- const serverActionResponse = filesystemRouteEligible && isPostRequest && actionId && options.handleServerActionRequest ? await options.handleServerActionRequest({
916
- actionId,
917
- cleanPathname,
918
- contentType,
919
- interceptionContext: interceptionSourceContext,
920
- isRscRequest,
921
- middlewareContext,
922
- mountedSlotsHeader,
923
- request,
924
- scriptNonce,
925
- routeMatch: renderedPreActionMatch,
926
- routePathname: preActionRoutePathname,
927
- dispatchRedirectTargetRequest: dispatchInternalRequest,
928
- sourceConfigHeaders,
929
- searchParams: getResolvedSearchParams()
930
- }) : null;
931
- if (serverActionResponse) return serverActionResponse;
932
- if (filesystemRouteEligible && isPostRequest && actionId && !options.handleServerActionRequest) return createMissingServerActionResponse(options, actionId);
933
923
  let match = preActionMatch;
934
924
  const renderPagesForMatchKind = async (matchKind) => {
935
925
  if (!filesystemRouteEligible) return null;
@@ -978,7 +968,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
978
968
  if (!responseStageHasContentLength) response.headers.delete("Content-Length");
979
969
  return response;
980
970
  } : void 0;
981
- const response = !isInterceptionMatch && (match === null || match.route.isDynamic) ? await runOutsideWorkStoreScope(() => options.renderPagesFallback?.({
971
+ const response = !isFinalRouteMatch && (match === null || match.route.isDynamic) ? await runOutsideWorkStoreScope(() => options.renderPagesFallback?.({
982
972
  appRouteMatch: match ?? null,
983
973
  allowRscDocumentFallback: didMiddlewareRewritePathname || allowInternalRscDocumentFallback,
984
974
  dispatchPagesResponseStage,
@@ -1012,7 +1002,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1012
1002
  options.clearRequestContext();
1013
1003
  return staticPagesFallbackResponse;
1014
1004
  }
1015
- if (!isInterceptionMatch && !resolvedLateRewritesForAction && (!match || match.route.isDynamic)) for (const rewrite of options.configRewrites.afterFiles) {
1005
+ if (!isFinalRouteMatch && (!match || match.route.isDynamic)) for (const rewrite of options.configRewrites.afterFiles) {
1016
1006
  const afterFilesRewrite = await applyRewrite({
1017
1007
  basePathState: currentBasePathState(),
1018
1008
  clearRequestContext: options.clearRequestContext,
@@ -1032,14 +1022,16 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1032
1022
  cleanPathname = pathnameForResolvedUrl(resolvedUrl);
1033
1023
  cleanPathnameIsRequestPathname = false;
1034
1024
  invalidateInterceptionCacheProof();
1035
- filesystemRouteEligible = true;
1036
1025
  resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
1026
+ filesystemRouteEligible = resolvedPathnameHasBasePath;
1037
1027
  const claimedRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
1038
1028
  if (claimedRscCacheBustingRedirect) return claimedRscCacheBustingRedirect;
1039
1029
  const rewrittenImageEndpointResponse = serveImageEndpointIfMatched();
1040
1030
  if (rewrittenImageEndpointResponse) return rewrittenImageEndpointResponse;
1041
1031
  const rewrittenMetadataResponse = await renderMetadataRouteIfMatched();
1042
1032
  if (rewrittenMetadataResponse) return composeResponseStageResponse(rewrittenMetadataResponse);
1033
+ const rewrittenPublicFileResponse = servePublicFileIfMatched();
1034
+ if (rewrittenPublicFileResponse) return rewrittenPublicFileResponse;
1043
1035
  match = matchCleanPathname();
1044
1036
  const rewrittenStaticPagesResponse = await renderPagesForMatchKind("static");
1045
1037
  if (rewrittenStaticPagesResponse) {
@@ -1058,7 +1050,7 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1058
1050
  options.clearRequestContext();
1059
1051
  return dynamicPagesFallbackResponse;
1060
1052
  }
1061
- if (!resolvedLateRewritesForAction && !match) for (const rewrite of options.configRewrites.fallback) {
1053
+ if (!match) for (const rewrite of options.configRewrites.fallback) {
1062
1054
  const fallbackRewrite = await applyRewrite({
1063
1055
  basePathState: currentBasePathState(),
1064
1056
  clearRequestContext: options.clearRequestContext,
@@ -1078,14 +1070,16 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1078
1070
  cleanPathname = pathnameForResolvedUrl(resolvedUrl);
1079
1071
  cleanPathnameIsRequestPathname = false;
1080
1072
  invalidateInterceptionCacheProof();
1081
- filesystemRouteEligible = true;
1082
1073
  resolvedPathnameHasBasePath = !options.basePath || rewrite.basePath !== false;
1074
+ filesystemRouteEligible = resolvedPathnameHasBasePath;
1083
1075
  const claimedRscCacheBustingRedirect = await validateClaimedOutsideBasePathRsc();
1084
1076
  if (claimedRscCacheBustingRedirect) return claimedRscCacheBustingRedirect;
1085
1077
  const rewrittenImageEndpointResponse = serveImageEndpointIfMatched();
1086
1078
  if (rewrittenImageEndpointResponse) return rewrittenImageEndpointResponse;
1087
1079
  const rewrittenMetadataResponse = await renderMetadataRouteIfMatched();
1088
1080
  if (rewrittenMetadataResponse) return composeResponseStageResponse(rewrittenMetadataResponse);
1081
+ const rewrittenPublicFileResponse = servePublicFileIfMatched();
1082
+ if (rewrittenPublicFileResponse) return rewrittenPublicFileResponse;
1089
1083
  match = matchCleanPathname();
1090
1084
  const rewrittenStaticPagesResponse = await renderPagesForMatchKind("static");
1091
1085
  if (rewrittenStaticPagesResponse) {
@@ -1140,6 +1134,18 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1140
1134
  }
1141
1135
  return buildNextDataNotFoundResponse();
1142
1136
  }
1137
+ if (isProgressiveActionRequest && !progressiveActionHandled || isServerActionRequest && !serverActionHandled) {
1138
+ const finalRouteMatch = renderedRouteMatch(match);
1139
+ setRootParams(finalRouteMatch ? pickRootParams(finalRouteMatch.params, finalRouteMatch.route.rootParamNames) : null);
1140
+ if (isServerActionRequest) {
1141
+ const serverActionResponse = await handleServerAction(finalRouteMatch, cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname);
1142
+ if (serverActionResponse) return serverActionResponse;
1143
+ } else {
1144
+ const progressiveActionResult = await handleProgressiveAction(finalRouteMatch, match);
1145
+ if (progressiveActionResult instanceof Response) return progressiveActionResult;
1146
+ progressiveActionFormState = progressiveActionResult;
1147
+ }
1148
+ }
1143
1149
  if (!match) {
1144
1150
  if (process.env.NODE_ENV !== "production" && canonicalPathname === "/favicon.ico") {
1145
1151
  options.clearRequestContext();
@@ -1265,6 +1271,9 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1265
1271
  searchParams: resolvedSearchParams
1266
1272
  });
1267
1273
  }
1274
+ const failedProgressiveActionResult = progressiveActionFormState && "actionError" in progressiveActionFormState ? progressiveActionFormState : null;
1275
+ const actionHttpFallbackStatus = failedProgressiveActionResult ? progressiveActionHttpFallbackStatus(failedProgressiveActionResult.actionError) : null;
1276
+ const normalizedProgressiveActionError = actionHttpFallbackStatus === null || actionHttpFallbackStatus === 404 ? failedProgressiveActionResult?.actionError : { digest: "NEXT_NOT_FOUND" };
1268
1277
  const pageResponse = withStoredSpecialErrorStatus(matchedResponseStage ? await matchedResponseStage(responseStageRequest(), {
1269
1278
  kind: "app-page",
1270
1279
  buildId: options.buildId,
@@ -1296,14 +1305,14 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1296
1305
  clientReuseManifest,
1297
1306
  cleanPathname,
1298
1307
  displayPathname: canonicalPathname,
1299
- formState,
1308
+ formState: progressiveActionFormState?.formState ?? null,
1300
1309
  actionError: normalizedProgressiveActionError,
1301
- actionFailed,
1310
+ actionFailed: failedProgressiveActionResult !== null,
1302
1311
  handlerStart,
1303
1312
  interceptionContext: interceptionSourceContext,
1304
1313
  interceptionId: interceptionIdHeader,
1305
1314
  interceptionPathname: cleanPathnameIsRequestPathname ? requestCleanPathname : cleanPathname,
1306
- isProgressiveActionRender,
1315
+ isProgressiveActionRender: progressiveActionFormState !== null,
1307
1316
  isRscRequest,
1308
1317
  middlewareContext,
1309
1318
  mountedSlotsHeader,
@@ -1324,9 +1333,13 @@ async function handleAppRscRequest(options, request, preMiddlewareRequestContext
1324
1333
  searchParams: resolvedSearchParams,
1325
1334
  renderMode
1326
1335
  }), isRscRequest && request.headers.get("Next-Router-Prefetch") === "1" && request.headers.has("Next-Router-Segment-Prefetch"));
1327
- if (isProgressiveActionRender) return applyProgressiveActionSideEffects(pageResponse, progressiveActionFormState);
1336
+ if (progressiveActionFormState) return applyProgressiveActionSideEffects(pageResponse, progressiveActionFormState);
1328
1337
  return pageResponse;
1329
1338
  }
1339
+ function progressiveActionHttpFallbackStatus(actionError) {
1340
+ const actionErrorDigest = actionError && typeof actionError === "object" && "digest" in actionError ? String(actionError.digest) : null;
1341
+ return actionErrorDigest ? parseNextHttpErrorDigest(actionErrorDigest)?.status ?? null : null;
1342
+ }
1330
1343
  /**
1331
1344
  * Append `Set-Cookie` headers and the `x-action-revalidated` marker captured
1332
1345
  * during progressive (no-JS) server action execution to the page render
@@ -1362,6 +1375,7 @@ function applyProgressiveActionSideEffects(response, sideEffects) {
1362
1375
  /** Build the request-only handler without retaining the response renderer graph. */
1363
1376
  function createAppRscRequestHandler(options) {
1364
1377
  const handleAppRscRequestLifecycle = async (rawRequest, ctx, allowInternalRscDocumentFallback = false, dispatchResponseStage, responseStageProbeMode = null, transportedPrerenderState) => {
1378
+ const rawRequestSignal = rawRequest.signal;
1365
1379
  const mwCtx = openForwardedMiddlewareContext(rawRequest.headers.get(VINEXT_MW_CTX_HEADER), options.devForwardedMiddlewareContextKey);
1366
1380
  const pagesDataUrl = new URL(rawRequest.url);
1367
1381
  const pagesDataInScope = !options.basePath || hasBasePath(pagesDataUrl.pathname, options.basePath);
@@ -1396,6 +1410,7 @@ function createAppRscRequestHandler(options) {
1396
1410
  const requestContext = createRequestContext({
1397
1411
  headersContext,
1398
1412
  executionContext,
1413
+ requestSignal: executionContext?.requestSignal ?? rawRequestSignal,
1399
1414
  unstableCacheRevalidation: "background"
1400
1415
  });
1401
1416
  let interceptionResponseUncacheable = false;
@@ -1423,6 +1438,7 @@ function createAppRscRequestHandler(options) {
1423
1438
  basePath: options.basePath,
1424
1439
  configHeaders: options.configHeaders,
1425
1440
  i18nConfig: options.i18nConfig,
1441
+ restoreLocaleRootTrailingSlash: shouldRestoreLocaleRootTrailingSlash(stripRscSuffix(new URL(rawRequest.url).pathname), options),
1426
1442
  middlewareHeaders: middlewareContext.headers,
1427
1443
  recordCacheability: dispatchResponseStage === void 0,
1428
1444
  requestContext: preMiddlewareRequestContext
@@ -1443,7 +1459,7 @@ function createAppRscRequestHandler(options) {
1443
1459
  };
1444
1460
  const appRscHandler = async function appRscHandler(rawRequest, ctx, allowInternalRscDocumentFallback = false, dispatchResponseStage, responseStageProbeMode = null, transportedPrerenderState, detachedTrace = false) {
1445
1461
  options.registerCacheAdapters();
1446
- await options.ensureInstrumentation?.();
1462
+ await options.ensureInstrumentation?.(isExecutionContextLike(ctx) ? ctx : null);
1447
1463
  const traceUrl = new URL(rawRequest.url);
1448
1464
  return traceFrameworkRequest({
1449
1465
  callback: () => handleAppRscRequestLifecycle(rawRequest, ctx, allowInternalRscDocumentFallback, dispatchResponseStage, responseStageProbeMode, transportedPrerenderState),