vinext 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +5 -2
  2. package/dist/build/action-owner-manifest.js +1 -0
  3. package/dist/build/prerender-paths.d.ts +11 -1
  4. package/dist/build/prerender-paths.js +36 -10
  5. package/dist/check.js +1 -1
  6. package/dist/cli.js +1 -1
  7. package/dist/client/dev-error-overlay.d.ts +2 -1
  8. package/dist/client/dev-error-overlay.js +8 -3
  9. package/dist/config/config-matchers.js +8 -4
  10. package/dist/config/destination-params.js +5 -2
  11. package/dist/config/next-config.d.ts +25 -1
  12. package/dist/config/next-config.js +31 -1
  13. package/dist/entries/app-rsc-entry.js +65 -30
  14. package/dist/entries/app-rsc-manifest.js +4 -0
  15. package/dist/entries/pages-server-entry.js +19 -4
  16. package/dist/index.js +37 -37
  17. package/dist/init-cloudflare.js +18 -2
  18. package/dist/init-platform.js +2 -2
  19. package/dist/init.js +42 -5
  20. package/dist/plugins/css-target.d.ts +18 -0
  21. package/dist/plugins/css-target.js +93 -0
  22. package/dist/routing/app-route-graph.d.ts +10 -0
  23. package/dist/routing/app-route-graph.js +15 -1
  24. package/dist/server/api-handler.d.ts +2 -0
  25. package/dist/server/api-handler.js +10 -8
  26. package/dist/server/app-action-forwarding.js +3 -1
  27. package/dist/server/app-browser-entry.js +37 -41
  28. package/dist/server/app-browser-error.d.ts +1 -1
  29. package/dist/server/app-browser-error.js +13 -4
  30. package/dist/server/app-browser-supplemental-refresh.d.ts +13 -0
  31. package/dist/server/app-browser-supplemental-refresh.js +36 -4
  32. package/dist/server/app-elements.d.ts +3 -0
  33. package/dist/server/app-elements.js +14 -1
  34. package/dist/server/app-fallback-renderer.js +2 -2
  35. package/dist/server/app-middleware.d.ts +2 -0
  36. package/dist/server/app-middleware.js +1 -0
  37. package/dist/server/app-optimistic-routing.d.ts +12 -1
  38. package/dist/server/app-optimistic-routing.js +38 -16
  39. package/dist/server/app-page-boundary-render.js +4 -2
  40. package/dist/server/app-page-cache-render.js +1 -1
  41. package/dist/server/app-page-dispatch.d.ts +11 -1
  42. package/dist/server/app-page-dispatch.js +78 -31
  43. package/dist/server/app-page-element-builder.d.ts +11 -20
  44. package/dist/server/app-page-element-builder.js +39 -50
  45. package/dist/server/app-page-intercept-segment-config.d.ts +56 -0
  46. package/dist/server/app-page-intercept-segment-config.js +90 -0
  47. package/dist/server/app-page-navigation-params.d.ts +23 -0
  48. package/dist/server/app-page-navigation-params.js +49 -0
  49. package/dist/server/app-page-render.d.ts +5 -2
  50. package/dist/server/app-page-render.js +17 -3
  51. package/dist/server/app-page-request.d.ts +24 -2
  52. package/dist/server/app-page-request.js +10 -10
  53. package/dist/server/app-page-route-wiring.d.ts +17 -5
  54. package/dist/server/app-page-route-wiring.js +19 -13
  55. package/dist/server/app-page-segment-plan.js +9 -1
  56. package/dist/server/app-page-segment-state.d.ts +9 -0
  57. package/dist/server/app-page-segment-state.js +54 -1
  58. package/dist/server/app-pages-bridge.d.ts +6 -0
  59. package/dist/server/app-pages-bridge.js +8 -3
  60. package/dist/server/app-request-stage-independent-entry.js +2 -3
  61. package/dist/server/app-response-stage-entry.js +1 -0
  62. package/dist/server/app-route-module-loader.d.ts +2 -0
  63. package/dist/server/app-route-module-loader.js +1 -0
  64. package/dist/server/app-router-entry.js +2 -3
  65. package/dist/server/app-rsc-cache-busting.d.ts +8 -0
  66. package/dist/server/app-rsc-cache-busting.js +13 -1
  67. package/dist/server/app-rsc-combined-handler.js +2 -1
  68. package/dist/server/app-rsc-handler.d.ts +14 -1
  69. package/dist/server/app-rsc-handler.js +111 -62
  70. package/dist/server/app-rsc-response-finalizer.d.ts +18 -3
  71. package/dist/server/app-rsc-response-finalizer.js +61 -7
  72. package/dist/server/app-rsc-route-matching.d.ts +14 -0
  73. package/dist/server/app-rsc-route-matching.js +42 -18
  74. package/dist/server/app-server-action-execution.js +16 -10
  75. package/dist/server/app-ssr-entry.js +8 -0
  76. package/dist/server/cache-control.d.ts +2 -0
  77. package/dist/server/cache-control.js +3 -1
  78. package/dist/server/config-headers.d.ts +7 -0
  79. package/dist/server/config-headers.js +20 -1
  80. package/dist/server/image-animation.d.ts +9 -0
  81. package/dist/server/image-animation.js +118 -0
  82. package/dist/server/image-local-patterns.d.ts +21 -0
  83. package/dist/server/image-local-patterns.js +59 -0
  84. package/dist/server/image-optimization.d.ts +48 -27
  85. package/dist/server/image-optimization.js +316 -22
  86. package/dist/server/image-source-reader.d.ts +34 -0
  87. package/dist/server/image-source-reader.js +126 -0
  88. package/dist/server/metadata-route-response.d.ts +6 -1
  89. package/dist/server/metadata-route-response.js +46 -10
  90. package/dist/server/middleware-matcher.d.ts +1 -0
  91. package/dist/server/middleware-matcher.js +1 -1
  92. package/dist/server/middleware-runtime.d.ts +5 -0
  93. package/dist/server/middleware-runtime.js +48 -15
  94. package/dist/server/middleware.d.ts +1 -1
  95. package/dist/server/middleware.js +2 -1
  96. package/dist/server/nitro-public-files-plugin.js +20 -8
  97. package/dist/server/nitro-request-target-plugin.d.ts +17 -0
  98. package/dist/server/nitro-request-target-plugin.js +22 -0
  99. package/dist/server/open-redirect.d.ts +2 -1
  100. package/dist/server/open-redirect.js +2 -1
  101. package/dist/server/pages-client-assets.d.ts +1 -0
  102. package/dist/server/pages-data-route.d.ts +5 -1
  103. package/dist/server/pages-data-route.js +14 -6
  104. package/dist/server/pages-i18n.d.ts +7 -0
  105. package/dist/server/pages-i18n.js +14 -1
  106. package/dist/server/pages-node-compat.js +7 -3
  107. package/dist/server/pages-page-handler.js +4 -4
  108. package/dist/server/pages-request-pipeline.d.ts +9 -0
  109. package/dist/server/pages-request-pipeline.js +35 -15
  110. package/dist/server/pages-request-stage-entry.js +8 -2
  111. package/dist/server/pages-router-entry.js +3 -0
  112. package/dist/server/prod-server.d.ts +1 -1
  113. package/dist/server/prod-server.js +64 -62
  114. package/dist/server/request-pipeline.d.ts +5 -0
  115. package/dist/server/request-pipeline.js +11 -1
  116. package/dist/server/response-stage-cacheability.d.ts +7 -0
  117. package/dist/server/response-stage-cacheability.js +6 -5
  118. package/dist/server/srvx-middleware-origin.d.ts +13 -0
  119. package/dist/server/srvx-middleware-origin.js +19 -0
  120. package/dist/server/srvx-request-target.d.ts +12 -0
  121. package/dist/server/srvx-request-target.js +20 -0
  122. package/dist/server/static-file-cache.js +10 -22
  123. package/dist/server/worker-image-optimization.d.ts +10 -3
  124. package/dist/server/worker-image-optimization.js +43 -9
  125. package/dist/server/worker-revalidation-context.js +1 -0
  126. package/dist/server/worker-utils.d.ts +8 -0
  127. package/dist/server/worker-utils.js +19 -2
  128. package/dist/shims/error-boundary.d.ts +6 -2
  129. package/dist/shims/error-boundary.js +4 -2
  130. package/dist/shims/image-props.d.ts +6 -0
  131. package/dist/shims/image-props.js +39 -3
  132. package/dist/shims/image.js +3 -3
  133. package/dist/shims/request-context.d.ts +3 -1
  134. package/dist/shims/slot.d.ts +3 -0
  135. package/dist/shims/slot.js +67 -9
  136. package/dist/shims/url-utils.js +6 -1
  137. package/dist/utils/base-path.d.ts +7 -0
  138. package/dist/utils/base-path.js +11 -1
  139. package/dist/utils/client-entry-manifest.d.ts +5 -0
  140. package/dist/utils/client-entry-manifest.js +1 -0
  141. package/dist/utils/client-runtime-metadata.d.ts +5 -0
  142. package/dist/utils/client-runtime-metadata.js +33 -7
  143. package/package.json +1 -1
package/README.md CHANGED
@@ -137,10 +137,13 @@ files to `.cjs`) when an unambiguous default Vite config requires the ESM migrat
137
137
  `"type": "commonjs"` is never changed. Direct `vite dev` and `vite build` do not perform these
138
138
  wrapper compatibility steps.
139
139
 
140
- `@vinext/cloudflare deploy` options: `--preview`, `--env <name>`, `--name <name>`, `--vite-config <path>`, `--skip-build`, `--dry-run`, `--warm-cache`, `--traffic-aware-warm-cache`.
140
+ `@vinext/cloudflare deploy` options: `--preview`, `--env <name>`, `--name <name>` (Wrangler config projects only), `--vite-config <path>`, `--skip-build`, `--dry-run`, `--warm-cache`, `--traffic-aware-warm-cache`.
141
141
 
142
142
  `vinext init` prompts for a deployment target, defaulting to Cloudflare. Agents must ask the
143
143
  user which target they want, then pass `--platform=cloudflare` or `--platform=node`.
144
+ For Cloudflare, agents and CI must also pass `--cdn-cache`, `--data-cache`, and
145
+ `--image-optimization`; see
146
+ [Run init without prompts](https://vinext.dev/docs/deploying/cloudflare#run-init-without-prompts).
144
147
 
145
148
  Other options: `--port <port>` (default: 3001), `--skip-check`, `--force`.
146
149
 
@@ -687,7 +690,7 @@ Every `next/*` import is shimmed to a Vite-compatible implementation.
687
690
  | `next.config.js` / `.ts` / `.mjs` | ✅ | Function configs, phase argument |
688
691
  | `rewrites` / `redirects` / `headers` | ✅ | All phases, param interpolation. A source Next.js rejects fails config loading, as it fails the Next.js build: missing, not starting with `/`, over the 4,096-character built-regex limit, or rejected by path-to-regexp, such as a header glob `/api/*` |
689
692
  | Environment variables (`.env*`, `NEXT_PUBLIC_*`) | ✅ | Auto-loads Next.js-style dotenv files; only public vars are inlined |
690
- | `images` config | 🟡 | Parsed but not used for optimization |
693
+ | `images` config | 🟡 | Parsed but not used for optimization; the production image endpoint enforces `localPatterns` (dev serves any local source) |
691
694
  | `experimental.optimizePackageImports` | ✅ | Rewrites barrel imports to direct sub-module imports in RSC/SSR environments. A default set (lucide-react, date-fns, radix-ui, antd, MUI, and others) are always optimized. Add package names here to extend the list. |
692
695
  | `vinext({ nextConfig })` | ✅ | Inline Next-style config from `vite.config.*`. Supports object-form and function-form config. When provided, this overrides root `next.config.*`. |
693
696
  | `vinext({ react: { compiler: true } })` | ✅ | React Compiler auto memoization. Needs `@vitejs/plugin-react` 6.1+ and the optional `oxc-transform-react` package. |
@@ -26,6 +26,7 @@ function actionOwnerRouteEntryIds(route) {
26
26
  slot.loadingPath,
27
27
  ...slot.loadingPaths ?? [],
28
28
  slot.errorPath,
29
+ ...slot.errorPaths ?? [],
29
30
  slot.notFoundPath,
30
31
  ...slot.notFoundPaths ?? [],
31
32
  ...slot.interceptingRoutes.flatMap((intercept) => [
@@ -91,7 +91,17 @@ type PrerenderPathDiscoveryOptions = {
91
91
  };
92
92
  };
93
93
  /** @internal Match the pathname forms and locale provenance used by middleware runtime. */
94
- export declare function matchesMiddlewareWarmPath(pathname: string, matcher: MatcherConfig | undefined, i18n: ResolvedNextConfig["i18n"]): boolean;
94
+ export declare function matchesMiddlewareWarmPath(pathname: string, matcher: MatcherConfig | undefined, i18n: ResolvedNextConfig["i18n"], options?: {
95
+ basePath?: string;
96
+ /**
97
+ * Whether the path's Pages data request reaches middleware slashed
98
+ * (`shouldAddTrailingSlashToPagesDataPath`). Omit for a path without a
99
+ * Pages data target.
100
+ */
101
+ pagesDataTrailingSlash?: boolean;
102
+ skipProxyUrlNormalize?: boolean;
103
+ trailingSlash?: boolean;
104
+ }): boolean;
95
105
  export declare function discoverPrerenderPathManifest(options: PrerenderPathDiscoveryOptions): Promise<PrerenderPathManifest | null>;
96
106
  export declare function emitPrerenderPathManifest(options: PrerenderPathDiscoveryOptions): Promise<PrerenderPathManifest | null>;
97
107
  //#endregion
@@ -10,6 +10,7 @@ import { appRouteHasMainTreeLoadingBoundary, appRouter, matchAppRoute } from "..
10
10
  import { apiRouter, matchRoute, pagesRouter } from "../routing/pages-router.js";
11
11
  import { matchesMiddlewarePathname } from "../server/middleware-matcher.js";
12
12
  import { extractLocaleFromUrl, normalizeDefaultLocalePathname, shouldRestoreLocaleRootTrailingSlash } from "../server/pages-i18n.js";
13
+ import { normalizeNextDataPagePathname, shouldAddTrailingSlashToPagesDataPath } from "../server/pages-data-route.js";
13
14
  import { classifyAppRoute, classifyAppRouteHandler, classifyPagesRoute, extractExportConstString, extractMiddlewareMatcherConfig, getAppRouteRenderEntryPath } from "./report.js";
14
15
  import { normalizeStaticPathname, normalizeStaticPathsEntry } from "../routing/route-pattern.js";
15
16
  import { buildPagesDataHref } from "../shims/internal/pages-data-url.js";
@@ -684,19 +685,37 @@ function findMiddlewareConventionFile(root, appDir, pagesDir, pageExtensions) {
684
685
  return null;
685
686
  }
686
687
  /** @internal Match the pathname forms and locale provenance used by middleware runtime. */
687
- function matchesMiddlewareWarmPath(pathname, matcher, i18n) {
688
+ function matchesMiddlewareWarmPath(pathname, matcher, i18n, options = {}) {
688
689
  const encodedPathname = new URL(pathname, "https://vinext.invalid").pathname;
690
+ const trailingSlash = options.trailingSlash ?? false;
691
+ const htmlRequestPathname = normalizePathTrailingSlash(options.basePath ? `${options.basePath}${encodedPathname === "/" ? "" : encodedPathname}` : encodedPathname, trailingSlash);
689
692
  const firstSegment = encodedPathname.split("/", 3)[1]?.toLowerCase();
690
693
  const localeContexts = i18n ? i18n.locales.some((locale) => locale.toLowerCase() === firstSegment) ? [{ kind: "literal" }] : Array.from(/* @__PURE__ */ new Set([i18n.defaultLocale, ...i18n.domains?.map((domain) => domain.defaultLocale) ?? []]), (defaultLocale) => ({
691
694
  defaultLocale,
692
695
  kind: "defaulted"
693
696
  })) : [void 0];
694
- const matchPathnames = [encodedPathname];
695
- try {
696
- const decodedPathname = decodeURIComponent(encodedPathname);
697
- if (decodedPathname !== encodedPathname) matchPathnames.push(decodedPathname);
698
- } catch {}
699
- return matchPathnames.some((matchPathname) => localeContexts.some((localeContext) => matchesMiddlewarePathname(matchPathname, matcher, i18n, localeContext)));
697
+ const requestSpellings = [{
698
+ localeContexts: shouldRestoreLocaleRootTrailingSlash(htmlRequestPathname, options) ? localeContexts.map((localeContext) => localeContext?.kind === "defaulted" ? {
699
+ ...localeContext,
700
+ restoreRootTrailingSlash: true
701
+ } : localeContext) : localeContexts,
702
+ pathname: normalizePathTrailingSlash(encodedPathname, trailingSlash)
703
+ }];
704
+ if (options.pagesDataTrailingSlash !== void 0) {
705
+ const dataLocaleContexts = [i18n ? { kind: "literal" } : void 0];
706
+ requestSpellings.push({
707
+ localeContexts: dataLocaleContexts,
708
+ pathname: normalizeNextDataPagePathname(localizePagesDataPath(encodedPathname, i18n), options.pagesDataTrailingSlash)
709
+ });
710
+ }
711
+ return requestSpellings.some((spelling) => {
712
+ const matchPathnames = [spelling.pathname];
713
+ try {
714
+ const decodedPathname = decodeURIComponent(spelling.pathname);
715
+ if (decodedPathname !== spelling.pathname) matchPathnames.push(decodedPathname);
716
+ } catch {}
717
+ return matchPathnames.some((matchPathname) => spelling.localeContexts.some((localeContext) => matchesMiddlewarePathname(matchPathname, matcher, i18n, localeContext)));
718
+ });
700
719
  }
701
720
  async function startPathDiscoveryServer(options) {
702
721
  return startProdServer({
@@ -822,10 +841,7 @@ async function discoverPrerenderPathManifest(options) {
822
841
  const hasStagedRequestRouting = options.requestRouting === "uncached-stage";
823
842
  const middlewarePath = hasStagedRequestRouting ? findMiddlewareConventionFile(root, appDir, pagesDir, config.pageExtensions) : null;
824
843
  const configuredMatcher = middlewarePath ? extractMiddlewareMatcherConfig(middlewarePath) : void 0;
825
- const middlewareMayRouteWarmPath = (pathname) => middlewarePath !== null && matchesMiddlewareWarmPath(pathname, configuredMatcher, config.i18n);
826
844
  const routedWarmPaths = [...paths, ...discoveredRouteHandlerPaths];
827
- const routeMayResolveWarmPathSet = new Set(hasStagedRequestRouting ? routedWarmPaths.filter((pathname) => middlewareMayRouteWarmPath(pathname) || configuredRewritesCanReplaceWarmPath(pathname, config.rewrites, discoveredNonDynamicPathSet.has(pathname), config, (rewrite) => !isExternalUrl(rewrite.destination))) : []);
828
- const requestStageMayTerminateWarmPathSet = new Set(hasStagedRequestRouting ? routedWarmPaths.filter((pathname) => middlewareMayRouteWarmPath(pathname) || configuredRulesAffectWarmPath(pathname, config.redirects, config) || configuredRewritesCanReplaceWarmPath(pathname, config.rewrites, discoveredNonDynamicPathSet.has(pathname), config, (rewrite) => isExternalUrl(rewrite.destination))) : []);
829
845
  const excludedWarmPathSet = new Set(options.responseVary && !hasStagedRequestRouting ? routedWarmPaths.filter((pathname) => configuredRulesAffectWarmPath(pathname, config.redirects, config) || configuredRewritesCanReplaceWarmPath(pathname, config.rewrites, discoveredNonDynamicPathSet.has(pathname), config, () => true)) : []);
830
846
  const configuredPagesWarmPaths = discoveredPagesPaths.filter((pathname) => !excludedWarmPathSet.has(pathname));
831
847
  const resolvedPagesWarmPaths = !appDir && pagesDir ? await excludePagesApiWarmPaths({
@@ -864,6 +880,16 @@ async function discoverPrerenderPathManifest(options) {
864
880
  routePatterns: pagesWarmMetadata.routePatterns,
865
881
  rscPaths: []
866
882
  };
883
+ const pagesDataRequestsGetTrailingSlash = shouldAddTrailingSlashToPagesDataPath(true, config.trailingSlash, config.skipProxyUrlNormalize);
884
+ const pagesOwnedPathSet = appDir ? new Set(appOwnedWarmPaths.pagesPaths) : null;
885
+ const middlewareMatchesWarmPath = (pathname) => middlewarePath !== null && matchesMiddlewareWarmPath(pathname, configuredMatcher, config.i18n, {
886
+ basePath: config.basePath,
887
+ pagesDataTrailingSlash: discoveredPagesDataPathSet.has(pathname) && (pagesOwnedPathSet?.has(pathname) ?? true) ? pagesDataRequestsGetTrailingSlash : void 0,
888
+ skipProxyUrlNormalize: config.skipProxyUrlNormalize,
889
+ trailingSlash: config.trailingSlash
890
+ });
891
+ const routeMayResolveWarmPathSet = new Set(hasStagedRequestRouting ? routedWarmPaths.filter((pathname) => middlewareMatchesWarmPath(pathname) || configuredRewritesCanReplaceWarmPath(pathname, config.rewrites, discoveredNonDynamicPathSet.has(pathname), config, (rewrite) => !isExternalUrl(rewrite.destination))) : []);
892
+ const requestStageMayTerminateWarmPathSet = new Set(hasStagedRequestRouting ? routedWarmPaths.filter((pathname) => middlewareMatchesWarmPath(pathname) || configuredRulesAffectWarmPath(pathname, config.redirects, config) || configuredRewritesCanReplaceWarmPath(pathname, config.rewrites, discoveredNonDynamicPathSet.has(pathname), config, (rewrite) => isExternalUrl(rewrite.destination))) : []);
867
893
  for (const pathname of configuredCandidatePaths) {
868
894
  if (appOwnedWarmPaths.routePatterns[pathname] || !routeMayResolveWarmPathSet.has(pathname) && !requestStageMayTerminateWarmPathSet.has(pathname)) continue;
869
895
  appOwnedWarmPaths.htmlPaths.push(pathname);
package/dist/check.js CHANGED
@@ -197,7 +197,7 @@ const CONFIG_SUPPORT = {
197
197
  env: { status: "supported" },
198
198
  images: {
199
199
  status: "partial",
200
- detail: "remotePatterns, deviceSizes/imageSizes, qualities and SVG/CSP options honoured; resizing needs an optimizer via vinext({ images: { optimizer } }), images are served as-is otherwise; loader/loaderFile are ignored"
200
+ detail: "remotePatterns, deviceSizes/imageSizes, qualities, localPatterns (production only) and SVG/CSP options honoured; resizing needs an optimizer via vinext({ images: { optimizer } }), images are served as-is otherwise; loader/loaderFile are ignored"
201
201
  },
202
202
  allowedDevOrigins: {
203
203
  status: "supported",
package/dist/cli.js CHANGED
@@ -281,7 +281,7 @@ function printHelp(cmd) {
281
281
  --prerender Configure Vite builds to pre-render static routes
282
282
  (Cloudflare deploy won't serve them unless using Static Assets)
283
283
  --warm-cache Add cache warming to the Cloudflare deploy script
284
- (Response Store or Workers Cache, default: prompt with No)
284
+ (requires a --cdn-cache other than none, default: prompt with No)
285
285
  --legacy-wrangler-cloudflare-init
286
286
  Use the legacy Wrangler setup instead of cf
287
287
  --ignore-wrangler-config
@@ -5,7 +5,8 @@ export declare const DEV_ERROR_OVERLAY_HOST_ID = "__vinext_dev_error_overlay_roo
5
5
  export declare const DEV_ERROR_OVERLAY_MOUNT_ID = "__vinext_dev_error_overlay_mount";
6
6
  export declare function installDevErrorOverlay(): void;
7
7
  export declare function installReactRefreshErrorRecovery(): void;
8
- export declare function selectUnreportedInitialDevServerErrors(payloads: readonly InitialDevServerErrorPayload[], reported: readonly ReportedError[]): InitialDevServerErrorPayload[];
8
+ export declare function reportRootErrorBoundaryCatch(): void;
9
+ export declare function selectUnreportedInitialDevServerErrors(payloads: readonly InitialDevServerErrorPayload[], reported: readonly ReportedError[], rootBoundaryCaught?: boolean): InitialDevServerErrorPayload[];
9
10
  export declare function reportInitialDevServerErrors(): void;
10
11
  type ViteHmrErrorPayload = {
11
12
  err?: ViteHmrError;
@@ -82,7 +82,12 @@ function tryInstallReactRefreshErrorRecovery() {
82
82
  });
83
83
  return true;
84
84
  }
85
- function selectUnreportedInitialDevServerErrors(payloads, reported) {
85
+ let rootErrorBoundaryCaught = false;
86
+ function reportRootErrorBoundaryCatch() {
87
+ rootErrorBoundaryCaught = true;
88
+ }
89
+ function selectUnreportedInitialDevServerErrors(payloads, reported, rootBoundaryCaught = false) {
90
+ if (rootBoundaryCaught) return [];
86
91
  const rethrownErrors = reported.filter((error) => error.source === "caught" || error.source === "uncaught" || error.source === "window-error");
87
92
  return payloads.filter((payload) => {
88
93
  const rethrownIndex = rethrownErrors.findIndex((error) => error.message === payload.message && (error.name || "Error") === (payload.name || "Error"));
@@ -96,7 +101,7 @@ function reportInitialDevServerErrors() {
96
101
  const errors = window.__VINEXT_INITIAL_DEV_ERRORS__;
97
102
  if (!errors || errors.length === 0) return;
98
103
  window.__VINEXT_INITIAL_DEV_ERRORS__ = [];
99
- for (const payload of selectUnreportedInitialDevServerErrors(errors, getOverlaySnapshot().errors)) {
104
+ for (const payload of selectUnreportedInitialDevServerErrors(errors, getOverlaySnapshot().errors, rootErrorBoundaryCaught)) {
100
105
  const error = new Error(payload.message);
101
106
  if (payload.name) error.name = payload.name;
102
107
  if (payload.stack) error.stack = payload.stack;
@@ -1358,4 +1363,4 @@ const componentStackStyle = {
1358
1363
  color: "var(--vinext-overlay-muted)"
1359
1364
  };
1360
1365
  //#endregion
1361
- export { DEV_ERROR_OVERLAY_HOST_ID, DEV_ERROR_OVERLAY_MOUNT_ID, createDevErrorOverlayMountNode, createViteOpenInEditorUrl, devOnCaughtError, devOnUncaughtError, dismissOverlay, formatErrorInfoForClipboard, formatOverlayDisplayFile, formatViteOpenInEditorFile, installDevErrorOverlay, installReactRefreshErrorRecovery, installViteHmrErrorHandler, normalizeViteHmrError, reportInitialDevServerErrors, selectUnreportedInitialDevServerErrors };
1366
+ export { DEV_ERROR_OVERLAY_HOST_ID, DEV_ERROR_OVERLAY_MOUNT_ID, createDevErrorOverlayMountNode, createViteOpenInEditorUrl, devOnCaughtError, devOnUncaughtError, dismissOverlay, formatErrorInfoForClipboard, formatOverlayDisplayFile, formatViteOpenInEditorFile, installDevErrorOverlay, installReactRefreshErrorRecovery, installViteHmrErrorHandler, normalizeViteHmrError, reportInitialDevServerErrors, reportRootErrorBoundaryCatch, selectUnreportedInitialDevServerErrors };
@@ -179,10 +179,14 @@ const REQUEST_HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
179
179
  "transfer-encoding",
180
180
  "upgrade"
181
181
  ]);
182
+ /**
183
+ * Strip the fixed request hop-by-hop list. Fields the client nominates in
184
+ * `Connection` are forwarded, like Next.js: the headers here already include
185
+ * middleware's request overrides, so honouring the client's list would let it
186
+ * drop headers middleware set.
187
+ */
182
188
  function stripHopByHopRequestHeaders(headers) {
183
- const connectionTokens = (headers.get("connection") || "").split(",").map((value) => value.trim().toLowerCase()).filter(Boolean);
184
189
  for (const header of REQUEST_HOP_BY_HOP_HEADERS) headers.delete(header);
185
- for (const token of connectionTokens) headers.delete(token);
186
190
  }
187
191
  /**
188
192
  * Compile a regex from next.config, or return null when it is invalid.
@@ -719,7 +723,7 @@ function preserveRedirectDestinationQuery(destination, requestSearch, destinatio
719
723
  }
720
724
  const LOCATION_STRIPPED_RE = /^[\u0000- ]+|[\u0000- ]+$|[\t\n\r]/g;
721
725
  const LOCATION_UNSAFE_RE = /[\u0000-\u0008\u000A-\u001F\u007F]|[^\u0000-\u007F]/gu;
722
- const LONE_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
726
+ const SURROGATE_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g;
723
727
  /**
724
728
  * Percent-encode what a config-redirect `Location` header cannot carry.
725
729
  *
@@ -731,7 +735,7 @@ const LONE_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF
731
735
  * constructor throws the same way); vinext percent-encodes them instead.
732
736
  */
733
737
  function encodeRedirectLocation(location) {
734
- return location.replace(LONE_SURROGATE_RE, "�").replace(LOCATION_UNSAFE_RE, encodeURIComponent);
738
+ return location.replace(SURROGATE_RE, (surrogate) => surrogate.length === 2 ? surrogate : "�").replace(LOCATION_UNSAFE_RE, encodeURIComponent);
735
739
  }
736
740
  function parseExternalRewriteUrl(externalUrl) {
737
741
  try {
@@ -91,9 +91,12 @@ function substituteRewritePath(template, paramRe, params, absolute) {
91
91
  const [path, hash] = substituted.split("#", 2);
92
92
  const pathHash = hash === void 0 ? void 0 : hash ? `#${hash}` : "";
93
93
  if (!absolute) return [path, pathHash];
94
- return [path.replace(DOT_SEGMENT_RE, (segment, offset) => paramRanges.some(([start, end]) => start <= offset + segment.length && end >= offset) ? segment.replace(/\.|%(?=2e)/gi, (char) => char === "." ? "%252E" : "%25") : segment), pathHash];
94
+ return [path.replace(DOT_SEGMENT_RE, (_match, separator, segment, offset) => {
95
+ const start = offset + separator.length;
96
+ return paramRanges.some(([paramStart, end]) => paramStart <= start + segment.length && end >= start) ? separator + segment.replace(/\.|%(?=2e)/gi, (char) => char === "." ? "%252E" : "%25") : separator + segment;
97
+ }), pathHash];
95
98
  }
96
- const DOT_SEGMENT_RE = /(?<=^|[/\\])(?:\.|%2e){1,2}(?=[/\\]|$)/gi;
99
+ const DOT_SEGMENT_RE = /(^|[/\\])((?:\.|%2e){1,2})(?=[/\\]|$)/gi;
97
100
  function encodePathQueryDelimiter(value) {
98
101
  return value.replaceAll("?", "%3F");
99
102
  }
@@ -183,12 +183,27 @@ export type NextConfig = {
183
183
  search?: string;
184
184
  }>;
185
185
  domains?: string[];
186
+ /**
187
+ * Local sources the image optimization endpoint may serve. Statically
188
+ * imported images are allowed too, except under a basePath (the added
189
+ * pattern is unprefixed, as in Next.js). When unset, any local path
190
+ * without a query string is allowed (matches Next.js).
191
+ */
192
+ localPatterns?: Array<{
193
+ pathname?: string;
194
+ search?: string;
195
+ }>;
186
196
  unoptimized?: boolean;
187
197
  /** Allowed device widths for image optimization. Defaults to Next.js defaults: [640, 750, 828, 1080, 1200, 1920, 2048, 3840] */
188
198
  deviceSizes?: number[];
189
199
  /** Allowed image sizes for fixed-width images. Defaults to Next.js defaults: [32, 48, 64, 96, 128, 256, 384] */
190
200
  imageSizes?: number[];
191
- /** Allowed image qualities. When unset, any quality from 1-100 is permitted (matches Next.js). */
201
+ /**
202
+ * Allowed image qualities. When set, the endpoint accepts only these and the
203
+ * default loader rounds `quality` to the closest entry, as in Next.js. When
204
+ * unset, any quality from 1-100 is permitted: a deliberate divergence from
205
+ * Next.js 16's `[75]` default that keeps Next.js 14/15 apps working.
206
+ */
192
207
  qualities?: number[];
193
208
  /** Allow SVG images through the image optimization endpoint. SVG can contain scripts, so only enable if you trust all image sources. */
194
209
  dangerouslyAllowSVG?: boolean;
@@ -198,6 +213,15 @@ export type NextConfig = {
198
213
  contentDispositionType?: "inline" | "attachment";
199
214
  /** Content-Security-Policy header for image responses. Defaults to "script-src 'none'; frame-src 'none'; sandbox;" */
200
215
  contentSecurityPolicy?: string;
216
+ /** Least max-age, in seconds, of an image the endpoint serves as-is. Defaults to 14400. */
217
+ minimumCacheTTL?: number;
218
+ /**
219
+ * Most bytes the endpoint reads of a GIF, PNG or WebP source bound for an
220
+ * image optimizer (while detecting animation and while streaming to the
221
+ * optimizer) before answering 413. Other sources stream unbounded.
222
+ * Defaults to 50000000.
223
+ */
224
+ maximumResponseBody?: number;
201
225
  };
202
226
  /**
203
227
  * Enable React Strict Mode. When `true`, the client root is wrapped in
@@ -507,6 +507,35 @@ async function resolveBuildId(generate) {
507
507
  return trimmed;
508
508
  }
509
509
  /**
510
+ * Mirror Next.js's config resolution of `images.localPatterns`: statically
511
+ * imported images (`/_next/static/media/**`) stay allowed whatever the app
512
+ * lists, though like Next.js the pattern is unprefixed, so it never matches
513
+ * under a basePath. An unset list stays unset; the image endpoint then applies the
514
+ * Next.js default.
515
+ */
516
+ function resolveImageLocalPatterns(localPatterns) {
517
+ if (localPatterns === void 0) return void 0;
518
+ if (!Array.isArray(localPatterns)) throw new Error(`Specified images.localPatterns should be an Array received ${localPatterns === null ? "null" : typeof localPatterns}.\nSee more info here: https://nextjs.org/docs/messages/invalid-images-config`);
519
+ if (localPatterns.length > 25) throw new Error("Specified images.localPatterns can have at most 25 entries.");
520
+ const patterns = Array.from(localPatterns, (pattern, index) => {
521
+ const entry = pattern;
522
+ let valid = typeof pattern === "object" && pattern !== null && !Array.isArray(pattern) && !(pattern instanceof Date) && !(pattern instanceof Map) && !(pattern instanceof Set) && !(typeof entry.then === "function" && typeof pattern.catch === "function") && (entry.pathname === void 0 || typeof entry.pathname === "string") && (entry.search === void 0 || typeof entry.search === "string");
523
+ if (valid) {
524
+ for (const key in pattern) if (key !== "pathname" && key !== "search") valid = false;
525
+ }
526
+ if (!valid) throw new Error(`Specified images.localPatterns[${index}] should be an object with optional string \`pathname\` and \`search\` fields.`);
527
+ const resolved = {};
528
+ if (entry.pathname !== void 0) resolved.pathname = entry.pathname;
529
+ if (entry.search !== void 0) resolved.search = entry.search;
530
+ return resolved;
531
+ });
532
+ if (!patterns.some((pattern) => pattern.pathname === "/_next/static/media/**" && pattern.search === "")) patterns.push({
533
+ pathname: "/_next/static/media/**",
534
+ search: ""
535
+ });
536
+ return patterns;
537
+ }
538
+ /**
510
539
  * Normalize the `assetPrefix` option from next.config.
511
540
  *
512
541
  * Accepts both absolute URLs (`https://cdn.example.com[/subpath]`) and
@@ -1094,7 +1123,8 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
1094
1123
  port: pattern.port,
1095
1124
  pathname: pattern.pathname,
1096
1125
  search: pattern.search
1097
- } : { ...pattern })
1126
+ } : { ...pattern }),
1127
+ localPatterns: resolveImageLocalPatterns(config.images.localPatterns)
1098
1128
  } : void 0;
1099
1129
  const resolved = {
1100
1130
  env: config.env ?? {},
@@ -94,9 +94,10 @@ function appPageSegmentConfigPaths(route) {
94
94
  ];
95
95
  }
96
96
  /**
97
- * Patterns of the static App pages that answer a request whose raw pathname
98
- * reaches a dynamic sibling but whose segment-decoded pathname names them, so
99
- * `/%61` and `/caf%C3%A9` render `/a` and `/café` rather than `/[slug]`.
97
+ * Patterns of the static App pages that may answer a request whose raw
98
+ * pathname reaches a dynamic sibling but whose segment-decoded pathname names
99
+ * them, so `/%61` and `/caf%C3%A9` can render `/a` and `/café` rather than
100
+ * `/[slug]`.
100
101
  *
101
102
  * Next.js serves those requests from the response cached under the decoded
102
103
  * pathname, which exists only for a page it prerendered. The prerender listing
@@ -105,7 +106,10 @@ function appPageSegmentConfigPaths(route) {
105
106
  * runtime on any segment) and a Route Handler have no such entry, so the
106
107
  * dynamic sibling renders. So does a page whose sources can't be read here;
107
108
  * its sibling's render stays out of the shared caches. A cacheComponents
108
- * build lists every page route, as the prerender listing does.
109
+ * build lists every page route, as the prerender listing does. Segment config
110
+ * can't tell a page that reads request data, so the matcher renders the page
111
+ * for another spelling (`/%61dmin`) only once the build recorded the decoded
112
+ * pathname's prerender; the browser's own spelling needs none.
109
113
  */
110
114
  function buildAppDecodedPathnamePatterns(routes, config) {
111
115
  const isPrerenderedPage = (route) => {
@@ -118,8 +122,7 @@ function buildAppDecodedPathnamePatterns(routes, config) {
118
122
  };
119
123
  return routes.filter((route) => !route.isDynamic && !route.routePath && getAppRouteRenderEntryPath(route) !== null && isPrerenderedPage(route)).map((route) => route.pattern);
120
124
  }
121
- function createForcesDynamicReader() {
122
- const readSource = createSegmentSourceReader();
125
+ function createForcesDynamicReader(readSource = createSegmentSourceReader()) {
123
126
  return (filePath) => {
124
127
  const source = readSource(filePath);
125
128
  return source !== null && extractExportConstString(source, "dynamic") === "force-dynamic";
@@ -130,7 +133,13 @@ function directRequestForcesDynamic(route, forcesDynamic) {
130
133
  return route.routePath ? forcesDynamic(route.routePath) : appPageSegmentConfigPaths(route).some(forcesDynamic);
131
134
  }
132
135
  function buildAppRequestRouteMetadata(routes) {
133
- const forcesDynamic = createForcesDynamicReader();
136
+ const readSource = createSegmentSourceReader();
137
+ const forcesDynamic = createForcesDynamicReader(readSource);
138
+ const routeHandlerMetadata = (filePath) => {
139
+ const source = readSource(filePath);
140
+ const runtime = source === null ? null : extractExportConstString(source, "runtime");
141
+ return runtime ? { runtime } : true;
142
+ };
134
143
  return routes.map((route) => ({
135
144
  canUseCanonicalLoadingShell: appRouteHasMainTreeLoadingBoundary(route),
136
145
  forceDynamic: directRequestForcesDynamic(route, forcesDynamic) || [...route.parallelSlots.flatMap((slot) => slot.interceptingRoutes.flatMap((intercept) => [...intercept.layoutPaths, intercept.pagePath])), ...route.siblingIntercepts.flatMap((intercept) => [...intercept.layoutPaths, intercept.pagePath])].some(forcesDynamic),
@@ -141,13 +150,17 @@ function buildAppRequestRouteMetadata(routes) {
141
150
  params: route.params,
142
151
  rootParamNames: route.rootParamNames ?? [],
143
152
  page: route.pagePath ? true : null,
144
- routeHandler: route.routePath ? true : null,
153
+ routeHandler: route.routePath ? routeHandlerMetadata(route.routePath) : null,
145
154
  routeSegments: route.routeSegments,
146
155
  layouts: [],
147
156
  layoutTreePositions: [],
148
157
  slots: Object.fromEntries(route.parallelSlots.map((slot) => [slot.key, {
149
158
  id: slot.id ?? null,
150
159
  name: slot.name,
160
+ __loadPage: slot.pagePath ? true : null,
161
+ __loadDefault: slot.defaultPath ? true : null,
162
+ slotPatternParts: slot.slotPatternParts ?? null,
163
+ slotParamNames: slot.slotParamNames ?? null,
151
164
  intercepts: slot.interceptingRoutes.map((intercept) => ({
152
165
  id: intercept.id ?? null,
153
166
  targetPattern: intercept.targetPattern,
@@ -244,6 +257,8 @@ import { dispatchAppRequestStage as __dispatchAppRequestStage } from ${JSON.stri
244
257
  import { registerConfiguredCacheAdapters as __registerConfiguredCacheAdapters } from "virtual:vinext-cdn-cache-adapter";
245
258
  import { clearAppRequestStageContext as __clearRequestContext, setAppRequestStageNavigationContext as setNavigationContext } from ${JSON.stringify(appRequestStageContextPath)};
246
259
  import { matchRoutePattern as __matchRoutePattern } from ${JSON.stringify(routePatternPath)};
260
+ import { initPregeneratedPathsFromGlobals as __initPregeneratedPathsFromGlobals } from ${JSON.stringify(pregeneratedConcretePathsPath)};
261
+ import "virtual:vinext-pregenerated-concrete-paths";
247
262
  import __pagesClientAssets from "virtual:vinext-pages-client-assets";
248
263
  ${middlewarePath ? `import { applyAppMiddleware as __applyAppMiddleware } from ${JSON.stringify(appMiddlewarePath)};` : ""}
249
264
  ${instrumentationPath ? `import * as _instrumentation from ${JSON.stringify(toSlash(instrumentationPath))};
@@ -278,12 +293,18 @@ export { __basePath };
278
293
  export const __imageAllowedWidths = ${JSON.stringify([...config?.imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...config?.imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES])};
279
294
  export const __imageConfig = ${JSON.stringify({
280
295
  qualities: config?.imageConfig?.qualities,
296
+ localPatterns: config?.imageConfig?.localPatterns,
281
297
  dangerouslyAllowSVG: config?.imageConfig?.dangerouslyAllowSVG,
282
298
  dangerouslyAllowLocalIP: config?.imageConfig?.dangerouslyAllowLocalIP,
283
299
  contentDispositionType: config?.imageConfig?.contentDispositionType,
284
- contentSecurityPolicy: config?.imageConfig?.contentSecurityPolicy
300
+ contentSecurityPolicy: config?.imageConfig?.contentSecurityPolicy,
301
+ minimumCacheTTL: config?.imageConfig?.minimumCacheTTL,
302
+ maximumResponseBody: config?.imageConfig?.maximumResponseBody
285
303
  })};
286
304
  export const __clientBuildFiles = __pagesClientAssets.clientBuildFiles ?? [];
305
+ // The matcher reads recorded prerenders, and this stage can run without the
306
+ // response entry that also loads them.
307
+ __initPregeneratedPathsFromGlobals();
287
308
  const __routes = ${JSON.stringify(requestRoutes)};
288
309
  const __routeMatcher = __createAppRscRouteMatcher(__routes, ${JSON.stringify(buildAppDecodedPathnamePatterns(routes, config))});
289
310
  const __metadataRouteMatchers = ${JSON.stringify(metadataRouteMatchers)};
@@ -354,20 +375,24 @@ const __requestHandler = createAppRscRequestHandler({
354
375
  const intercept = __routeMatcher.findIntercept(pathname, sourcePathname, interceptionId);
355
376
  if (!intercept) return null;
356
377
  const route = __routes[intercept.sourceRouteIndex];
357
- if (!route) return null;
358
- const params = Object.create(null);
359
- for (const name of route.params) {
360
- if (Object.prototype.hasOwnProperty.call(intercept.sourceMatchedParams, name)) {
361
- params[name] = intercept.sourceMatchedParams[name];
378
+ const authorizationRoute = __routes[intercept.authorizationSourceRouteIndex];
379
+ if (!route || !authorizationRoute) return null;
380
+ const pickParams = (targetRoute, source) => {
381
+ const params = Object.create(null);
382
+ for (const name of targetRoute.params) {
383
+ if (Object.prototype.hasOwnProperty.call(source, name)) params[name] = source[name];
362
384
  }
363
- }
385
+ return params;
386
+ };
364
387
  return {
388
+ authorizationParams: pickParams(authorizationRoute, intercept.authorizationSourceParams),
389
+ authorizationRoute,
365
390
  interceptionSourceIsConcrete: intercept.sourceRouteIsConcrete,
366
391
  route,
367
- params,
392
+ params: pickParams(route, intercept.sourceMatchedParams),
368
393
  };
369
394
  },
370
- ${middlewarePath ? `runMiddleware({ cleanPathname, context, externalRewriteRequest, hadBasePath, isDataRequest, middlewareRequest, request, validateExternalRewriteRequest }) {
395
+ ${middlewarePath ? `runMiddleware({ cleanPathname, context, externalRewriteRequest, hadBasePath, isDataRequest, middlewareRequest, request, restoreLocaleRootTrailingSlash, validateExternalRewriteRequest }) {
371
396
  return __applyAppMiddleware({
372
397
  basePath: __basePath,
373
398
  cleanPathname,
@@ -381,6 +406,7 @@ const __requestHandler = createAppRscRequestHandler({
381
406
  middlewareRequest,
382
407
  module: middlewareModule,
383
408
  request,
409
+ restoreLocaleRootTrailingSlash,
384
410
  skipTrailingSlashRedirect: ${JSON.stringify(config?.skipTrailingSlashRedirect ?? false)},
385
411
  trailingSlash: __trailingSlash,
386
412
  validateExternalRewriteRequest,
@@ -389,9 +415,9 @@ const __requestHandler = createAppRscRequestHandler({
389
415
  publicFiles: new Set(${JSON.stringify(config?.publicFiles ?? [])}),
390
416
  registerCacheAdapters: __registerConfiguredCacheAdapters,
391
417
  renderNotFound: async () => null,
392
- ${hasPagesDir ? `async renderPagesFallback({ allowRscDocumentFallback, appRouteMatch, dispatchPagesResponseStage, initialResponseHeaders, isDataRequest, isRscRequest, matchKind, middlewareContext, pathname, pagesDataRequest, request, sharedAcrossHosts, url }) {
418
+ ${hasPagesDir ? `async renderPagesFallback({ allowRscDocumentFallback, appRouteMatch, dispatchPagesResponseStage, initialResponseHeaders, isDataRequest, isRscRequest, matchKind, middlewareContext, pathname, pagesDataRequest, request, requestBasePath, sharedAcrossHosts, url }) {
393
419
  return __renderPagesFallback(
394
- { allowRscDocumentFallback, appRouteMatch, initialResponseHeaders, isDataRequest, isRscRequest, matchKind, middlewareContext, pathname, pagesDataRequest, request, sharedAcrossHosts, url },
420
+ { allowRscDocumentFallback, appRouteMatch, initialResponseHeaders, isDataRequest, isRscRequest, matchKind, middlewareContext, pathname, pagesDataRequest, request, requestBasePath, sharedAcrossHosts, url },
395
421
  {
396
422
  async loadPagesEntry() {
397
423
  if (!dispatchPagesResponseStage) {
@@ -482,10 +508,13 @@ function generateRscEntry(appDir, routes, middlewarePath, metadataRoutes, global
482
508
  const imageAllowedWidths = [...config?.imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...config?.imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES];
483
509
  const imageConfig = {
484
510
  qualities: config?.imageConfig?.qualities,
511
+ localPatterns: config?.imageConfig?.localPatterns,
485
512
  dangerouslyAllowSVG: config?.imageConfig?.dangerouslyAllowSVG,
486
513
  dangerouslyAllowLocalIP: config?.imageConfig?.dangerouslyAllowLocalIP,
487
514
  contentDispositionType: config?.imageConfig?.contentDispositionType,
488
- contentSecurityPolicy: config?.imageConfig?.contentSecurityPolicy
515
+ contentSecurityPolicy: config?.imageConfig?.contentSecurityPolicy,
516
+ minimumCacheTTL: config?.imageConfig?.minimumCacheTTL,
517
+ maximumResponseBody: config?.imageConfig?.maximumResponseBody
489
518
  };
490
519
  const { imports, importInitializers, routeEntries, metaRouteEntries, generateStaticParamsEntries, rootParamNameEntries, rootNotFoundVar, rootForbiddenVar, rootUnauthorizedVar, rootLayoutVars, globalErrorVar, globalNotFoundImportSpecifier } = buildAppRscManifestCode({
491
520
  deferEagerImports: Boolean(instrumentationPath),
@@ -1124,6 +1153,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1124
1153
  observePageSearchParamsAccess: buildOptions?.observePageSearchParamsAccess === true,
1125
1154
  isForceStatic: buildOptions?.isForceStatic === true,
1126
1155
  isUncacheableRender: buildOptions?.isUncacheableRender === true,
1156
+ routeTreeOnlyPrefetchShell: buildOptions?.routeTreeOnlyPrefetchShell === true,
1127
1157
  mountedLayouts: buildOptions?.mountedLayouts ?? null,
1128
1158
  serveStreamingMetadata: buildOptions?.serveStreamingMetadata,
1129
1159
  placeStreamedMetadataInHead: buildOptions?.placeStreamedMetadataInHead === true,
@@ -1635,20 +1665,24 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1635
1665
  const intercept = findIntercept(pathname, sourcePathname, interceptionId);
1636
1666
  if (!intercept) return null;
1637
1667
  const route = routes[intercept.sourceRouteIndex];
1638
- if (!route) return null;
1639
- const params = Object.create(null);
1640
- for (const name of route.params) {
1641
- if (Object.prototype.hasOwnProperty.call(intercept.sourceMatchedParams, name)) {
1642
- params[name] = intercept.sourceMatchedParams[name];
1668
+ const authorizationRoute = routes[intercept.authorizationSourceRouteIndex];
1669
+ if (!route || !authorizationRoute) return null;
1670
+ const pickParams = (targetRoute, source) => {
1671
+ const params = Object.create(null);
1672
+ for (const name of targetRoute.params) {
1673
+ if (Object.prototype.hasOwnProperty.call(source, name)) params[name] = source[name];
1643
1674
  }
1644
- }
1675
+ return params;
1676
+ };
1645
1677
  return {
1678
+ authorizationParams: pickParams(authorizationRoute, intercept.authorizationSourceParams),
1679
+ authorizationRoute,
1646
1680
  interceptionSourceIsConcrete: intercept.sourceRouteIsConcrete,
1647
1681
  route,
1648
- params,
1682
+ params: pickParams(route, intercept.sourceMatchedParams),
1649
1683
  };
1650
1684
  },
1651
- ${middlewarePath ? `runMiddleware({ cleanPathname, context, externalRewriteRequest, hadBasePath, isDataRequest, middlewareRequest, request, validateExternalRewriteRequest }) {
1685
+ ${middlewarePath ? `runMiddleware({ cleanPathname, context, externalRewriteRequest, hadBasePath, isDataRequest, middlewareRequest, request, restoreLocaleRootTrailingSlash, validateExternalRewriteRequest }) {
1652
1686
  return __applyAppMiddleware({
1653
1687
  basePath: __basePath,
1654
1688
  cleanPathname,
@@ -1662,6 +1696,7 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1662
1696
  middlewareRequest,
1663
1697
  module: middlewareModule,
1664
1698
  request,
1699
+ restoreLocaleRootTrailingSlash,
1665
1700
  skipTrailingSlashRedirect: ${JSON.stringify(config?.skipTrailingSlashRedirect ?? false)},
1666
1701
  trailingSlash: __trailingSlash,
1667
1702
  validateExternalRewriteRequest,
@@ -1672,9 +1707,9 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
1672
1707
  const __isEdge = route ? __isEdgeRuntime(__resolveRouteRuntime(route)) : false;
1673
1708
  return __fallbackRenderer.renderNotFound(route, isRscRequest, request, matchedParams, scriptNonce, middlewareContext, { isEdgeRuntime: __isEdge });
1674
1709
  },
1675
- ${hasPagesDir ? `async renderPagesFallback({ allowRscDocumentFallback, appRouteMatch, dispatchPagesResponseStage, initialResponseHeaders, isDataRequest, isRscRequest, matchKind, middlewareContext, pathname, pagesDataRequest, request, sharedAcrossHosts, url }) {
1710
+ ${hasPagesDir ? `async renderPagesFallback({ allowRscDocumentFallback, appRouteMatch, dispatchPagesResponseStage, initialResponseHeaders, isDataRequest, isRscRequest, matchKind, middlewareContext, pathname, pagesDataRequest, request, requestBasePath, sharedAcrossHosts, url }) {
1676
1711
  return __renderPagesFallback(
1677
- { allowRscDocumentFallback, appRouteMatch, initialResponseHeaders, isDataRequest, isRscRequest, matchKind, middlewareContext, pathname, pagesDataRequest, request, sharedAcrossHosts, url },
1712
+ { allowRscDocumentFallback, appRouteMatch, initialResponseHeaders, isDataRequest, isRscRequest, matchKind, middlewareContext, pathname, pagesDataRequest, request, requestBasePath, sharedAcrossHosts, url },
1678
1713
  {
1679
1714
  async loadPagesEntry() {
1680
1715
  const __pagesEntry = await __ensureHybridPagesApplication();
@@ -108,6 +108,7 @@ function registerRouteModules(routes, imports) {
108
108
  if (slot.loadingPath) imports.getLazyLoaderVar(slot.loadingPath);
109
109
  for (const loadingPath of slot.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
110
110
  if (slot.errorPath) imports.getLazyLoaderVar(slot.errorPath);
111
+ for (const errorPath of slot.errorPaths ?? []) imports.getLazyLoaderVar(errorPath);
111
112
  if (slot.notFoundPath) imports.getLazyLoaderVar(slot.notFoundPath);
112
113
  for (const notFoundPath of slot.notFoundPaths ?? []) imports.getLazyLoaderVar(notFoundPath);
113
114
  for (const ir of slot.interceptingRoutes) {
@@ -240,6 +241,9 @@ function buildRouteEntries(routes, imports) {
240
241
  loadingTreePositions: ${JSON.stringify(slot.loadingTreePositions ?? [])},
241
242
  error: null,
242
243
  __loadError: ${slot.errorPath ? imports.getLazyLoaderVar(slot.errorPath) : "null"},
244
+ errors: ${moduleArray(slot.errorPaths?.length ?? 0)},
245
+ __loadErrors: ${lazyLoaderArray(slot.errorPaths ?? [], imports)},
246
+ errorTreePositions: ${JSON.stringify(slot.errorTreePositions ?? [])},
243
247
  notFound: null,
244
248
  __loadNotFound: ${slot.notFoundPath ? imports.getLazyLoaderVar(slot.notFoundPath) : "null"},
245
249
  notFoundTreePosition: ${slot.notFoundTreePosition ?? "null"},