vinext 1.4.0 → 1.4.2
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.
- package/README.md +21 -21
- package/dist/build/action-owner-manifest.js +1 -0
- package/dist/build/prerender.js +3 -2
- package/dist/check.js +4 -7
- package/dist/client/dev-error-overlay-store.d.ts +1 -0
- package/dist/client/dev-error-overlay.d.ts +2 -0
- package/dist/client/dev-error-overlay.js +19 -3
- package/dist/config/config-matchers.js +4 -2
- package/dist/config/destination-params.d.ts +2 -1
- package/dist/config/destination-params.js +55 -2
- package/dist/config/next-config.d.ts +22 -1
- package/dist/config/next-config.js +49 -4
- package/dist/entries/app-rsc-entry.js +41 -19
- package/dist/entries/app-rsc-manifest.js +4 -0
- package/dist/entries/pages-server-entry.js +5 -1
- package/dist/index.js +44 -32
- package/dist/init-cloudflare.js +18 -2
- package/dist/plugins/css-target.d.ts +18 -0
- package/dist/plugins/css-target.js +93 -0
- package/dist/plugins/strip-server-exports.js +2 -1
- package/dist/routing/app-route-graph.d.ts +10 -0
- package/dist/routing/app-route-graph.js +15 -1
- package/dist/server/api-handler.d.ts +2 -0
- package/dist/server/api-handler.js +5 -6
- package/dist/server/app-action-forwarding.js +3 -1
- package/dist/server/app-browser-entry.js +28 -7
- package/dist/server/app-browser-rsc-redirect.js +3 -3
- package/dist/server/app-browser-server-action-client.js +2 -2
- package/dist/server/app-browser-visible-commit.js +2 -2
- package/dist/server/app-elements.d.ts +3 -0
- package/dist/server/app-elements.js +14 -1
- package/dist/server/app-fallback-renderer.js +2 -2
- package/dist/server/app-optimistic-routing.d.ts +12 -1
- package/dist/server/app-optimistic-routing.js +40 -19
- package/dist/server/app-page-boundary-render.js +7 -12
- package/dist/server/app-page-cache-render.js +1 -1
- package/dist/server/app-page-dispatch.d.ts +10 -2
- package/dist/server/app-page-dispatch.js +73 -31
- package/dist/server/app-page-element-builder.d.ts +9 -20
- package/dist/server/app-page-element-builder.js +40 -52
- package/dist/server/app-page-execution.js +9 -6
- package/dist/server/app-page-intercept-segment-config.d.ts +56 -0
- package/dist/server/app-page-intercept-segment-config.js +90 -0
- package/dist/server/app-page-navigation-params.d.ts +23 -0
- package/dist/server/app-page-navigation-params.js +49 -0
- package/dist/server/app-page-render.d.ts +5 -3
- package/dist/server/app-page-render.js +31 -17
- package/dist/server/app-page-request.d.ts +24 -2
- package/dist/server/app-page-request.js +10 -10
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +10 -0
- package/dist/server/app-page-route-wiring.js +34 -13
- package/dist/server/app-page-segment-plan.js +9 -1
- package/dist/server/app-page-segment-state.d.ts +9 -0
- package/dist/server/app-page-segment-state.js +54 -1
- package/dist/server/app-page-stream.d.ts +10 -8
- package/dist/server/app-page-stream.js +2 -1
- package/dist/server/app-request-stage-independent-entry.js +1 -1
- package/dist/server/app-response-stage-entry.js +1 -0
- package/dist/server/app-route-handler-execution.js +3 -2
- package/dist/server/app-route-handler-runtime.d.ts +1 -1
- package/dist/server/app-route-handler-runtime.js +11 -7
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.js +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +10 -10
- package/dist/server/app-rsc-cache-busting.js +27 -68
- package/dist/server/app-rsc-error-handler.js +1 -1
- package/dist/server/app-rsc-errors.js +4 -1
- package/dist/server/app-rsc-handler.d.ts +10 -1
- package/dist/server/app-rsc-handler.js +126 -103
- package/dist/server/app-rsc-request-normalization.d.ts +10 -12
- package/dist/server/app-rsc-request-normalization.js +11 -14
- package/dist/server/app-rsc-response-finalizer.d.ts +3 -0
- package/dist/server/app-rsc-response-finalizer.js +11 -1
- package/dist/server/app-rsc-response-stage.js +4 -12
- package/dist/server/app-rsc-route-matching.d.ts +14 -0
- package/dist/server/app-rsc-route-matching.js +42 -18
- package/dist/server/app-server-action-execution.js +24 -14
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +13 -8
- package/dist/server/app-worker-stages.d.ts +12 -3
- package/dist/server/app-worker-stages.js +37 -4
- package/dist/server/bfcache-identity.d.ts +7 -0
- package/dist/server/bfcache-identity.js +10 -1
- package/dist/server/cache-control.d.ts +2 -0
- package/dist/server/cache-control.js +3 -1
- package/dist/server/cacheability-manifest.js +1 -2
- package/dist/server/dev-origin-check.d.ts +2 -1
- package/dist/server/dev-origin-check.js +2 -1
- package/dist/server/dev-server.js +2 -1
- package/dist/server/image-local-patterns.d.ts +21 -0
- package/dist/server/image-local-patterns.js +59 -0
- package/dist/server/image-optimization.d.ts +28 -22
- package/dist/server/image-optimization.js +17 -2
- package/dist/server/isr-cache.js +4 -1
- package/dist/server/metadata-route-response.js +25 -7
- package/dist/server/middleware-matcher.js +19 -6
- package/dist/server/middleware-runtime.js +6 -2
- package/dist/server/multi-stage.d.ts +7 -3
- package/dist/server/nitro-public-files-plugin.js +20 -8
- package/dist/server/pages-data-route.d.ts +5 -1
- package/dist/server/pages-data-route.js +14 -6
- package/dist/server/pages-node-compat.d.ts +1 -1
- package/dist/server/pages-node-compat.js +2 -0
- package/dist/server/pages-page-data.js +2 -1
- package/dist/server/pages-page-handler.js +17 -6
- package/dist/server/pages-page-response.d.ts +9 -0
- package/dist/server/pages-page-response.js +18 -4
- package/dist/server/pages-request-pipeline.js +6 -5
- package/dist/server/pages-request-stage-entry.js +25 -4
- package/dist/server/pages-router-entry.js +3 -2
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +59 -17
- package/dist/server/request-error-log.d.ts +9 -0
- package/dist/server/request-error-log.js +13 -0
- package/dist/server/request-pipeline.d.ts +14 -4
- package/dist/server/request-pipeline.js +33 -15
- package/dist/server/response-stage-cacheability.d.ts +7 -0
- package/dist/server/response-stage-cacheability.js +6 -5
- package/dist/server/rsc-completion-metadata.js +3 -0
- package/dist/server/static-file-cache.d.ts +9 -0
- package/dist/server/static-file-cache.js +13 -2
- package/dist/server/worker-image-optimization.d.ts +2 -2
- package/dist/server/worker-image-optimization.js +18 -3
- package/dist/server/worker-utils.d.ts +8 -0
- package/dist/server/worker-utils.js +19 -2
- package/dist/shims/cache-request-state.d.ts +6 -6
- package/dist/shims/cache-request-state.js +6 -36
- package/dist/shims/cache-runtime.d.ts +3 -1
- package/dist/shims/cache-runtime.js +77 -47
- package/dist/shims/cache.d.ts +10 -5
- package/dist/shims/cache.js +35 -22
- package/dist/shims/client-hook-error.d.ts +2 -0
- package/dist/shims/client-hook-error.js +16 -1
- package/dist/shims/fetch-cache.js +6 -2
- package/dist/shims/headers.d.ts +2 -1
- package/dist/shims/headers.js +5 -3
- package/dist/shims/image-props.d.ts +6 -0
- package/dist/shims/image-props.js +39 -3
- package/dist/shims/image.js +3 -3
- package/dist/shims/internal/cache-context-accessor.d.ts +1 -1
- package/dist/shims/link.js +5 -10
- package/dist/shims/navigation.js +2 -3
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/slot.d.ts +9 -2
- package/dist/shims/slot.js +76 -11
- package/dist/shims/unified-request-context.d.ts +6 -0
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/utils/base-path.d.ts +7 -0
- package/dist/utils/base-path.js +11 -1
- package/dist/utils/cache-life-profiles.d.ts +33 -0
- package/dist/utils/cache-life-profiles.js +111 -0
- package/dist/utils/middleware-request-headers.d.ts +14 -3
- package/dist/utils/middleware-request-headers.js +54 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -659,26 +659,26 @@ Every `next/*` import is shimmed to a Vite-compatible implementation.
|
|
|
659
659
|
|
|
660
660
|
### Server features
|
|
661
661
|
|
|
662
|
-
| Feature | | Notes
|
|
663
|
-
| ------------------------------------------ | --- |
|
|
664
|
-
| SSR (Pages Router) | ✅ | Streaming, `_app`/`_document`, `__NEXT_DATA__`, hydration
|
|
665
|
-
| SSR (App Router) | ✅ | RSC pipeline, nested layouts, streaming, nav context for client components
|
|
666
|
-
| `getStaticProps` | ✅ | Props, redirect, notFound, revalidate
|
|
667
|
-
| `getStaticPaths` | ✅ | `fallback: false`, `true`, `"blocking"`
|
|
668
|
-
| `getServerSideProps` | ✅ | Full context including locale
|
|
669
|
-
| ISR | ✅ | Stale-while-revalidate, pluggable `CacheHandler`, background regeneration
|
|
670
|
-
| Server Actions (`"use server"`) | ✅ | Action execution, FormData, re-render after mutation, `redirect()` in actions
|
|
671
|
-
| React Server Components | ✅ | Via `@vitejs/plugin-rsc`. `"use client"` boundaries work correctly
|
|
672
|
-
| Streaming SSR | ✅ | Both routers
|
|
673
|
-
| Metadata API | ✅ | `metadata`, `generateMetadata`, `viewport`, `generateViewport`, title templates
|
|
674
|
-
| `generateStaticParams` | ✅ | With `dynamicParams` enforcement
|
|
675
|
-
| Metadata file routes | ✅ | sitemap.xml, robots.txt, manifest, favicon, OG images (static + dynamic)
|
|
676
|
-
| Static export (`output: 'export'`) | ✅ | Generates static HTML/JSON for all routes
|
|
677
|
-
| Standalone output (`output: 'standalone'`) | ✅ | Generates `dist/standalone` with `server.js`, build artifacts, and runtime deps
|
|
678
|
-
| `connection()` | ✅ | Forces dynamic rendering
|
|
679
|
-
| `"use cache"` directive | ✅ | File-level and function-level. `cacheLife()` profiles, `cacheTag()`, stale-while-revalidate |
|
|
680
|
-
| `instrumentation.ts` | ✅ | `register()`, `onRequestError()`, and [framework tracing](docs/tracing.mdx)
|
|
681
|
-
| Route segment config | 🟡 | `revalidate`, `dynamic`, `dynamicParams`, `runtime` (not placement). No `preferredRegion`
|
|
662
|
+
| Feature | | Notes |
|
|
663
|
+
| ------------------------------------------ | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
664
|
+
| SSR (Pages Router) | ✅ | Streaming, `_app`/`_document`, `__NEXT_DATA__`, hydration |
|
|
665
|
+
| SSR (App Router) | ✅ | RSC pipeline, nested layouts, streaming, nav context for client components |
|
|
666
|
+
| `getStaticProps` | ✅ | Props, redirect, notFound, revalidate |
|
|
667
|
+
| `getStaticPaths` | ✅ | `fallback: false`, `true`, `"blocking"` |
|
|
668
|
+
| `getServerSideProps` | ✅ | Full context including locale |
|
|
669
|
+
| ISR | ✅ | Stale-while-revalidate, pluggable `CacheHandler`, background regeneration |
|
|
670
|
+
| Server Actions (`"use server"`) | ✅ | Action execution, FormData, re-render after mutation, `redirect()` in actions |
|
|
671
|
+
| React Server Components | ✅ | Via `@vitejs/plugin-rsc`. `"use client"` boundaries work correctly |
|
|
672
|
+
| Streaming SSR | ✅ | Both routers |
|
|
673
|
+
| Metadata API | ✅ | `metadata`, `generateMetadata`, `viewport`, `generateViewport`, title templates |
|
|
674
|
+
| `generateStaticParams` | ✅ | With `dynamicParams` enforcement |
|
|
675
|
+
| Metadata file routes | ✅ | sitemap.xml, robots.txt, manifest, favicon, OG images (static + dynamic) |
|
|
676
|
+
| Static export (`output: 'export'`) | ✅ | Generates static HTML/JSON for all routes |
|
|
677
|
+
| Standalone output (`output: 'standalone'`) | ✅ | Generates `dist/standalone` with `server.js`, build artifacts, and runtime deps |
|
|
678
|
+
| `connection()` | ✅ | Forces dynamic rendering |
|
|
679
|
+
| `"use cache"` directive | ✅ | File-level and function-level. `cacheLife()` with built-in and next.config `cacheLife` (or legacy `experimental.cacheLife`) profiles, `cacheTag()`, stale-while-revalidate |
|
|
680
|
+
| `instrumentation.ts` | ✅ | `register()`, `onRequestError()`, and [framework tracing](docs/tracing.mdx) |
|
|
681
|
+
| Route segment config | 🟡 | `revalidate`, `dynamic`, `dynamicParams`, `runtime` (not placement). No `preferredRegion` |
|
|
682
682
|
|
|
683
683
|
### Configuration
|
|
684
684
|
|
|
@@ -687,7 +687,7 @@ Every `next/*` import is shimmed to a Vite-compatible implementation.
|
|
|
687
687
|
| `next.config.js` / `.ts` / `.mjs` | ✅ | Function configs, phase argument |
|
|
688
688
|
| `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
689
|
| 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
|
|
690
|
+
| `images` config | 🟡 | Parsed but not used for optimization; the production image endpoint enforces `localPatterns` (dev serves any local source) |
|
|
691
691
|
| `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
692
|
| `vinext({ nextConfig })` | ✅ | Inline Next-style config from `vite.config.*`. Supports object-form and function-form config. When provided, this overrides root `next.config.*`. |
|
|
693
693
|
| `vinext({ react: { compiler: true } })` | ✅ | React Compiler auto memoization. Needs `@vitejs/plugin-react` 6.1+ and the optional `oxc-transform-react` package. |
|
package/dist/build/prerender.js
CHANGED
|
@@ -608,12 +608,13 @@ async function prerenderPages({ routes, apiRoutes, pagesDir, outDir, config, mod
|
|
|
608
608
|
fs.writeFileSync(htmlFullPath, html, "utf-8");
|
|
609
609
|
outputFiles.push(htmlOutputPath);
|
|
610
610
|
}
|
|
611
|
+
const renderedRevalidate = isStaticPropsResponse ? readPrerenderCacheLifeHeader(response.headers)?.revalidate ?? false : revalidate;
|
|
611
612
|
result = {
|
|
612
613
|
route: route.pattern,
|
|
613
614
|
status: "rendered",
|
|
614
615
|
outputFiles,
|
|
615
|
-
revalidate,
|
|
616
|
-
...typeof
|
|
616
|
+
revalidate: renderedRevalidate,
|
|
617
|
+
...typeof renderedRevalidate === "number" ? { expire: config.expireTime } : {},
|
|
617
618
|
router: "pages",
|
|
618
619
|
...urlPath !== route.pattern ? { path: urlPath } : {},
|
|
619
620
|
...locale ? { locale } : {},
|
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",
|
|
@@ -243,13 +243,10 @@ const CONFIG_SUPPORT = {
|
|
|
243
243
|
status: "unsupported",
|
|
244
244
|
detail: "ignored; configure cache adapters with vinext({ cache }) in vite.config"
|
|
245
245
|
},
|
|
246
|
-
cacheLife: {
|
|
247
|
-
status: "unsupported",
|
|
248
|
-
detail: "custom cacheLife profiles are ignored; only the built-in profiles are available"
|
|
249
|
-
},
|
|
246
|
+
cacheLife: { status: "supported" },
|
|
250
247
|
"experimental.cacheLife": {
|
|
251
|
-
status: "
|
|
252
|
-
detail: "
|
|
248
|
+
status: "supported",
|
|
249
|
+
detail: "legacy alias of cacheLife"
|
|
253
250
|
},
|
|
254
251
|
skipTrailingSlashRedirect: { status: "supported" },
|
|
255
252
|
"experimental.skipTrailingSlashRedirect": {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { ReportedError, dismissOverlay } from "./dev-error-overlay-store.js";
|
|
2
|
+
import { InitialDevServerErrorPayload } from "../server/dev-initial-server-error.js";
|
|
2
3
|
//#region src/client/dev-error-overlay.d.ts
|
|
3
4
|
export declare const DEV_ERROR_OVERLAY_HOST_ID = "__vinext_dev_error_overlay_root";
|
|
4
5
|
export declare const DEV_ERROR_OVERLAY_MOUNT_ID = "__vinext_dev_error_overlay_mount";
|
|
5
6
|
export declare function installDevErrorOverlay(): void;
|
|
6
7
|
export declare function installReactRefreshErrorRecovery(): void;
|
|
8
|
+
export declare function selectUnreportedInitialDevServerErrors(payloads: readonly InitialDevServerErrorPayload[], reported: readonly ReportedError[]): InitialDevServerErrorPayload[];
|
|
7
9
|
export declare function reportInitialDevServerErrors(): void;
|
|
8
10
|
type ViteHmrErrorPayload = {
|
|
9
11
|
err?: ViteHmrError;
|
|
@@ -11,6 +11,7 @@ const DEV_ERROR_OVERLAY_MOUNT_ID = "__vinext_dev_error_overlay_mount";
|
|
|
11
11
|
const VITE_ERROR_HANDLER_DATA_KEY = "__vinext_vite_error_handler__";
|
|
12
12
|
const REACT_REFRESH_RECOVERY_RETRY_DELAY_MS = 16;
|
|
13
13
|
let reactRoot = null;
|
|
14
|
+
let overlayHost = null;
|
|
14
15
|
let installed = false;
|
|
15
16
|
const reportedErrors = /* @__PURE__ */ new WeakSet();
|
|
16
17
|
function rememberReported(error) {
|
|
@@ -81,12 +82,21 @@ function tryInstallReactRefreshErrorRecovery() {
|
|
|
81
82
|
});
|
|
82
83
|
return true;
|
|
83
84
|
}
|
|
85
|
+
function selectUnreportedInitialDevServerErrors(payloads, reported) {
|
|
86
|
+
const rethrownErrors = reported.filter((error) => error.source === "caught" || error.source === "uncaught" || error.source === "window-error");
|
|
87
|
+
return payloads.filter((payload) => {
|
|
88
|
+
const rethrownIndex = rethrownErrors.findIndex((error) => error.message === payload.message && (error.name || "Error") === (payload.name || "Error"));
|
|
89
|
+
if (rethrownIndex === -1) return true;
|
|
90
|
+
rethrownErrors.splice(rethrownIndex, 1);
|
|
91
|
+
return false;
|
|
92
|
+
});
|
|
93
|
+
}
|
|
84
94
|
function reportInitialDevServerErrors() {
|
|
85
95
|
if (typeof window === "undefined") return;
|
|
86
96
|
const errors = window.__VINEXT_INITIAL_DEV_ERRORS__;
|
|
87
97
|
if (!errors || errors.length === 0) return;
|
|
88
98
|
window.__VINEXT_INITIAL_DEV_ERRORS__ = [];
|
|
89
|
-
for (const payload of errors) {
|
|
99
|
+
for (const payload of selectUnreportedInitialDevServerErrors(errors, getOverlaySnapshot().errors)) {
|
|
90
100
|
const error = new Error(payload.message);
|
|
91
101
|
if (payload.name) error.name = payload.name;
|
|
92
102
|
if (payload.stack) error.stack = payload.stack;
|
|
@@ -130,6 +140,7 @@ function reportDevError(error, options) {
|
|
|
130
140
|
ensureMounted();
|
|
131
141
|
const id = reportToOverlay({
|
|
132
142
|
source: options.source,
|
|
143
|
+
name: error instanceof Error ? error.name : void 0,
|
|
133
144
|
message,
|
|
134
145
|
stack,
|
|
135
146
|
ignoredStackFrames: void 0,
|
|
@@ -176,8 +187,13 @@ function stringValue(value) {
|
|
|
176
187
|
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
177
188
|
}
|
|
178
189
|
function ensureMounted() {
|
|
179
|
-
if (reactRoot)
|
|
190
|
+
if (reactRoot) {
|
|
191
|
+
const host = overlayHost;
|
|
192
|
+
if (host && !host.isConnected) (document.body ?? document.documentElement).appendChild(host);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
180
195
|
const node = createDevErrorOverlayMountNode(document);
|
|
196
|
+
overlayHost = document.getElementById(DEV_ERROR_OVERLAY_HOST_ID);
|
|
181
197
|
reactRoot = createRoot(node);
|
|
182
198
|
reactRoot.render(/* @__PURE__ */ jsx(DevErrorOverlayApp, {}));
|
|
183
199
|
}
|
|
@@ -1342,4 +1358,4 @@ const componentStackStyle = {
|
|
|
1342
1358
|
color: "var(--vinext-overlay-muted)"
|
|
1343
1359
|
};
|
|
1344
1360
|
//#endregion
|
|
1345
|
-
export { DEV_ERROR_OVERLAY_HOST_ID, DEV_ERROR_OVERLAY_MOUNT_ID, createDevErrorOverlayMountNode, createViteOpenInEditorUrl, devOnCaughtError, devOnUncaughtError, dismissOverlay, formatErrorInfoForClipboard, formatOverlayDisplayFile, formatViteOpenInEditorFile, installDevErrorOverlay, installReactRefreshErrorRecovery, installViteHmrErrorHandler, normalizeViteHmrError, reportInitialDevServerErrors };
|
|
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 };
|
|
@@ -719,7 +719,7 @@ function preserveRedirectDestinationQuery(destination, requestSearch, destinatio
|
|
|
719
719
|
}
|
|
720
720
|
const LOCATION_STRIPPED_RE = /^[\u0000- ]+|[\u0000- ]+$|[\t\n\r]/g;
|
|
721
721
|
const LOCATION_UNSAFE_RE = /[\u0000-\u0008\u000A-\u001F\u007F]|[^\u0000-\u007F]/gu;
|
|
722
|
-
const
|
|
722
|
+
const SURROGATE_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDFFF]/g;
|
|
723
723
|
/**
|
|
724
724
|
* Percent-encode what a config-redirect `Location` header cannot carry.
|
|
725
725
|
*
|
|
@@ -731,7 +731,7 @@ const LONE_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF
|
|
|
731
731
|
* constructor throws the same way); vinext percent-encodes them instead.
|
|
732
732
|
*/
|
|
733
733
|
function encodeRedirectLocation(location) {
|
|
734
|
-
return location.replace(
|
|
734
|
+
return location.replace(SURROGATE_RE, (surrogate) => surrogate.length === 2 ? surrogate : "�").replace(LOCATION_UNSAFE_RE, encodeURIComponent);
|
|
735
735
|
}
|
|
736
736
|
function parseExternalRewriteUrl(externalUrl) {
|
|
737
737
|
try {
|
|
@@ -759,8 +759,10 @@ async function proxyExternalRequest(request, externalUrl) {
|
|
|
759
759
|
const destinationKeys = new Set(targetUrl.searchParams.keys());
|
|
760
760
|
for (const [key, value] of originalUrl.searchParams) if (!destinationKeys.has(key)) targetUrl.searchParams.append(key, value);
|
|
761
761
|
const headers = new Headers(request.headers);
|
|
762
|
+
const requestHost = headers.get("host") ?? "";
|
|
762
763
|
headers.set("host", targetUrl.host);
|
|
763
764
|
stripHopByHopRequestHeaders(headers);
|
|
765
|
+
headers.set("x-forwarded-host", requestHost);
|
|
764
766
|
const keysToDelete = [];
|
|
765
767
|
for (const key of headers.keys()) if (key.startsWith("x-middleware-") && !key.startsWith("x-middleware-request-")) keysToDelete.push(key);
|
|
766
768
|
for (const key of keysToDelete) headers.delete(key);
|
|
@@ -25,7 +25,8 @@
|
|
|
25
25
|
* `%XX` escapes a raw path capture already carries. A decoded `has` capture
|
|
26
26
|
* carrying `#`, `/`, `?`, `@` or `:` then makes the host invalid instead of
|
|
27
27
|
* moving the proxy to another host. Next.js substitutes the hostname verbatim
|
|
28
|
-
* and can be retargeted this way; vinext is stricter.
|
|
28
|
+
* and can be retargeted this way; vinext is stricter. Params in a rewrite's
|
|
29
|
+
* path follow substituteRewritePath.
|
|
29
30
|
*
|
|
30
31
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/prepare-destination.ts
|
|
31
32
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/server/server-route-utils.ts
|
|
@@ -33,7 +33,8 @@ const _compiledDestinationParamCache = /* @__PURE__ */ new Map();
|
|
|
33
33
|
* `%XX` escapes a raw path capture already carries. A decoded `has` capture
|
|
34
34
|
* carrying `#`, `/`, `?`, `@` or `:` then makes the host invalid instead of
|
|
35
35
|
* moving the proxy to another host. Next.js substitutes the hostname verbatim
|
|
36
|
-
* and can be retargeted this way; vinext is stricter.
|
|
36
|
+
* and can be retargeted this way; vinext is stricter. Params in a rewrite's
|
|
37
|
+
* path follow substituteRewritePath.
|
|
37
38
|
*
|
|
38
39
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/prepare-destination.ts
|
|
39
40
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/server/server-route-utils.ts
|
|
@@ -49,7 +50,59 @@ function substituteDestinationParams(destination, params, kind) {
|
|
|
49
50
|
const queryIndex = beforeHash.indexOf("?");
|
|
50
51
|
const beforeQuery = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);
|
|
51
52
|
const authorityEnd = getAbsoluteUrlAuthorityEnd(beforeQuery.replace(paramRe, (token) => "x".repeat(token.length)));
|
|
52
|
-
|
|
53
|
+
const [path, pathHash] = substituteRewritePath(beforeQuery.slice(authorityEnd), paramRe, params, authorityEnd > 0);
|
|
54
|
+
const query = queryIndex === -1 ? "" : `?${replaceParams(beforeHash.slice(queryIndex + 1), encodeRewriteQueryParamValue)}`;
|
|
55
|
+
return `${replaceParams(beforeQuery.slice(0, authorityEnd), encodeAuthorityParam)}${path}${query}${pathHash ?? replaceParams(hash, (value) => value)}`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Substitute params into a rewrite destination's path, returning the path and,
|
|
59
|
+
* when a param carried a `#`, the hash it starts.
|
|
60
|
+
*
|
|
61
|
+
* Next.js inserts path params verbatim, splits the result at the first `#`
|
|
62
|
+
* and escapes a `?` when it formats the URL. A decoded `has` capture can end
|
|
63
|
+
* the path with `#`, but neither `?` nor `#` can displace the destination's
|
|
64
|
+
* own query.
|
|
65
|
+
*
|
|
66
|
+
* An absolute destination is proxied with the URL parser, which removes tab
|
|
67
|
+
* and newlines, trims trailing control characters and spaces, and resolves
|
|
68
|
+
* `.`/`..` segments against the destination's literal path. Next.js sends a
|
|
69
|
+
* param's control characters and spaces percent-encoded, as vinext does, and
|
|
70
|
+
* its dot segments as written. A parsed URL cannot carry a `..` segment, so a
|
|
71
|
+
* dot segment that a param is in or next to is escaped once more (`.` as
|
|
72
|
+
* `%252E`, `%2e` as `%252e`) and stays inside the destination's path. The
|
|
73
|
+
* destination's own dot segments still resolve.
|
|
74
|
+
*
|
|
75
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/prepare-destination.ts
|
|
76
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/router/utils/format-url.ts
|
|
77
|
+
*/
|
|
78
|
+
function substituteRewritePath(template, paramRe, params, absolute) {
|
|
79
|
+
const encodeParam = absolute ? encodeAbsoluteUrlPathParam : encodePathQueryDelimiter;
|
|
80
|
+
const paramRanges = [];
|
|
81
|
+
let substituted = "";
|
|
82
|
+
let templateIndex = 0;
|
|
83
|
+
for (const match of template.matchAll(paramRe)) {
|
|
84
|
+
substituted += template.slice(templateIndex, match.index);
|
|
85
|
+
const value = encodeParam(params[match[1]]);
|
|
86
|
+
paramRanges.push([substituted.length, substituted.length + value.length]);
|
|
87
|
+
substituted += value;
|
|
88
|
+
templateIndex = match.index + match[0].length;
|
|
89
|
+
}
|
|
90
|
+
substituted += template.slice(templateIndex);
|
|
91
|
+
const [path, hash] = substituted.split("#", 2);
|
|
92
|
+
const pathHash = hash === void 0 ? void 0 : hash ? `#${hash}` : "";
|
|
93
|
+
if (!absolute) return [path, 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];
|
|
98
|
+
}
|
|
99
|
+
const DOT_SEGMENT_RE = /(^|[/\\])((?:\.|%2e){1,2})(?=[/\\]|$)/gi;
|
|
100
|
+
function encodePathQueryDelimiter(value) {
|
|
101
|
+
return value.replaceAll("?", "%3F");
|
|
102
|
+
}
|
|
103
|
+
const ABSOLUTE_URL_PATH_PARAM_UNSAFE_RE = /[?\u0000- ]/g;
|
|
104
|
+
function encodeAbsoluteUrlPathParam(value) {
|
|
105
|
+
return value.replace(ABSOLUTE_URL_PATH_PARAM_UNSAFE_RE, encodeURIComponent);
|
|
53
106
|
}
|
|
54
107
|
function getAbsoluteUrlAuthorityEnd(value) {
|
|
55
108
|
const scheme = /^[a-z][a-z0-9+.-]*:[/\\\t\n\r]*/i.exec(value);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CacheLifeConfig } from "../utils/cache-life-profiles.js";
|
|
1
2
|
import { PHASE_PRODUCTION_BUILD } from "../shims/constants.js";
|
|
2
3
|
import { PluginOption } from "vite";
|
|
3
4
|
//#region src/config/next-config.d.ts
|
|
@@ -182,12 +183,27 @@ export type NextConfig = {
|
|
|
182
183
|
search?: string;
|
|
183
184
|
}>;
|
|
184
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
|
+
}>;
|
|
185
196
|
unoptimized?: boolean;
|
|
186
197
|
/** Allowed device widths for image optimization. Defaults to Next.js defaults: [640, 750, 828, 1080, 1200, 1920, 2048, 3840] */
|
|
187
198
|
deviceSizes?: number[];
|
|
188
199
|
/** Allowed image sizes for fixed-width images. Defaults to Next.js defaults: [32, 48, 64, 96, 128, 256, 384] */
|
|
189
200
|
imageSizes?: number[];
|
|
190
|
-
/**
|
|
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
|
+
*/
|
|
191
207
|
qualities?: number[];
|
|
192
208
|
/** Allow SVG images through the image optimization endpoint. SVG can contain scripts, so only enable if you trust all image sources. */
|
|
193
209
|
dangerouslyAllowSVG?: boolean;
|
|
@@ -551,6 +567,11 @@ export type ResolvedNextConfig = {
|
|
|
551
567
|
dynamic: number;
|
|
552
568
|
static: number;
|
|
553
569
|
};
|
|
570
|
+
/**
|
|
571
|
+
* `cacheLife` profiles (or legacy `experimental.cacheLife`) merged over the
|
|
572
|
+
* built-ins with Next.js's rules; read by the `cacheLife()` shim.
|
|
573
|
+
*/
|
|
574
|
+
cacheLife: Record<string, CacheLifeConfig>;
|
|
554
575
|
/**
|
|
555
576
|
* Mirrors Next.js `experimental.useLightningcss`. When `true`, switch
|
|
556
577
|
* Vite's CSS pipeline from PostCSS to lightningcss for both transforms
|
|
@@ -6,6 +6,7 @@ import { isUnknownRecord } from "../utils/record.js";
|
|
|
6
6
|
import { PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_BUILD } from "../shims/constants.js";
|
|
7
7
|
import { getHtmlLimitedBotRegex } from "../utils/html-limited-bots.js";
|
|
8
8
|
import { flattenPluginOptions } from "../utils/plugin-options.js";
|
|
9
|
+
import { resolveCacheLifeProfiles } from "../utils/cache-life-profiles.js";
|
|
9
10
|
import { configSourceError } from "./config-source.js";
|
|
10
11
|
import { isExternalUrl } from "../utils/external-url.js";
|
|
11
12
|
import { applyLocaleToRoutes } from "./config-matchers.js";
|
|
@@ -376,7 +377,11 @@ function warnDeprecatedConfigOptions(config, root) {
|
|
|
376
377
|
];
|
|
377
378
|
for (const [propertyPath, warning] of warnings) if (hasConfigProperty(config, propertyPath)) warnConfigOnce(warning);
|
|
378
379
|
const experimental = readOptionalRecord(config.experimental);
|
|
379
|
-
for (const key of [
|
|
380
|
+
for (const key of [
|
|
381
|
+
"skipTrailingSlashRedirect",
|
|
382
|
+
"cacheComponents",
|
|
383
|
+
"cacheLife"
|
|
384
|
+
]) if (experimental?.[key] != null) warnConfigOnce(`\`experimental.${key}\` has been moved to \`${key}\`. Please update your ${configFileName} file accordingly.`);
|
|
380
385
|
}
|
|
381
386
|
async function resolveNextConfigInput(config, phase = PHASE_DEVELOPMENT_SERVER) {
|
|
382
387
|
return await resolveConfigValue(config, phase);
|
|
@@ -502,6 +507,35 @@ async function resolveBuildId(generate) {
|
|
|
502
507
|
return trimmed;
|
|
503
508
|
}
|
|
504
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
|
+
/**
|
|
505
539
|
* Normalize the `assetPrefix` option from next.config.
|
|
506
540
|
*
|
|
507
541
|
* Accepts both absolute URLs (`https://cdn.example.com[/subpath]`) and
|
|
@@ -935,6 +969,10 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
935
969
|
instrumentationServerValueInjections: {},
|
|
936
970
|
clientTraceMetadata: void 0,
|
|
937
971
|
staleTimes: { ...DEFAULT_STALE_TIMES },
|
|
972
|
+
cacheLife: resolveCacheLifeProfiles(void 0, {
|
|
973
|
+
expireTime: DEFAULT_EXPIRE_TIME,
|
|
974
|
+
staticStaleTime: DEFAULT_STALE_TIMES.static
|
|
975
|
+
}, warnConfigOnce),
|
|
938
976
|
useLightningcss: false,
|
|
939
977
|
lightningCssFeatures: {
|
|
940
978
|
include: 0,
|
|
@@ -1014,6 +1052,8 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
1014
1052
|
const allowedDevOrigins = Array.isArray(config.allowedDevOrigins) ? config.allowedDevOrigins : [];
|
|
1015
1053
|
const experimental = readOptionalRecord(config.experimental);
|
|
1016
1054
|
const cacheComponents = (experimental?.cacheComponents ?? config.cacheComponents) === true;
|
|
1055
|
+
const expireTime = typeof config.expireTime === "number" ? config.expireTime : DEFAULT_EXPIRE_TIME;
|
|
1056
|
+
const staleTimes = resolveStaleTimes(experimental);
|
|
1017
1057
|
const serverActionsConfig = readOptionalRecord(experimental?.serverActions);
|
|
1018
1058
|
const serverActionsAllowedOrigins = readStringArray(serverActionsConfig?.allowedOrigins);
|
|
1019
1059
|
const serverActionsBodySizeLimitConfig = readOptionalBodySizeLimit(serverActionsConfig?.bodySizeLimit);
|
|
@@ -1083,7 +1123,8 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
1083
1123
|
port: pattern.port,
|
|
1084
1124
|
pathname: pattern.pathname,
|
|
1085
1125
|
search: pattern.search
|
|
1086
|
-
} : { ...pattern })
|
|
1126
|
+
} : { ...pattern }),
|
|
1127
|
+
localPatterns: resolveImageLocalPatterns(config.images.localPatterns)
|
|
1087
1128
|
} : void 0;
|
|
1088
1129
|
const resolved = {
|
|
1089
1130
|
env: config.env ?? {},
|
|
@@ -1124,7 +1165,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
1124
1165
|
globalNotFound,
|
|
1125
1166
|
serverActionsBodySizeLimit,
|
|
1126
1167
|
serverActionsBodySizeLimitLabel,
|
|
1127
|
-
expireTime
|
|
1168
|
+
expireTime,
|
|
1128
1169
|
reactMaxHeadersLength: typeof config.reactMaxHeadersLength === "number" ? config.reactMaxHeadersLength : DEFAULT_REACT_MAX_HEADERS_LENGTH,
|
|
1129
1170
|
htmlLimitedBots,
|
|
1130
1171
|
serverExternalPackages,
|
|
@@ -1144,7 +1185,11 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
1144
1185
|
compilerDefine: serializeCompilerDefine(config.compiler?.define),
|
|
1145
1186
|
compilerDefineServer: serializeCompilerDefine(config.compiler?.defineServer),
|
|
1146
1187
|
clientTraceMetadata: Array.isArray(experimental?.clientTraceMetadata) ? experimental.clientTraceMetadata.filter((value) => typeof value === "string") : void 0,
|
|
1147
|
-
staleTimes
|
|
1188
|
+
staleTimes,
|
|
1189
|
+
cacheLife: resolveCacheLifeProfiles(experimental?.cacheLife ?? config.cacheLife, {
|
|
1190
|
+
expireTime,
|
|
1191
|
+
staticStaleTime: staleTimes.static
|
|
1192
|
+
}, warnConfigOnce),
|
|
1148
1193
|
useLightningcss,
|
|
1149
1194
|
lightningCssFeatures
|
|
1150
1195
|
};
|
|
@@ -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
|
|
98
|
-
* reaches a dynamic sibling but whose segment-decoded pathname names
|
|
99
|
-
* `/%61` and `/caf%C3%A9` render `/a` and `/café` rather than
|
|
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) => {
|
|
@@ -148,6 +152,10 @@ function buildAppRequestRouteMetadata(routes) {
|
|
|
148
152
|
slots: Object.fromEntries(route.parallelSlots.map((slot) => [slot.key, {
|
|
149
153
|
id: slot.id ?? null,
|
|
150
154
|
name: slot.name,
|
|
155
|
+
__loadPage: slot.pagePath ? true : null,
|
|
156
|
+
__loadDefault: slot.defaultPath ? true : null,
|
|
157
|
+
slotPatternParts: slot.slotPatternParts ?? null,
|
|
158
|
+
slotParamNames: slot.slotParamNames ?? null,
|
|
151
159
|
intercepts: slot.interceptingRoutes.map((intercept) => ({
|
|
152
160
|
id: intercept.id ?? null,
|
|
153
161
|
targetPattern: intercept.targetPattern,
|
|
@@ -244,6 +252,8 @@ import { dispatchAppRequestStage as __dispatchAppRequestStage } from ${JSON.stri
|
|
|
244
252
|
import { registerConfiguredCacheAdapters as __registerConfiguredCacheAdapters } from "virtual:vinext-cdn-cache-adapter";
|
|
245
253
|
import { clearAppRequestStageContext as __clearRequestContext, setAppRequestStageNavigationContext as setNavigationContext } from ${JSON.stringify(appRequestStageContextPath)};
|
|
246
254
|
import { matchRoutePattern as __matchRoutePattern } from ${JSON.stringify(routePatternPath)};
|
|
255
|
+
import { initPregeneratedPathsFromGlobals as __initPregeneratedPathsFromGlobals } from ${JSON.stringify(pregeneratedConcretePathsPath)};
|
|
256
|
+
import "virtual:vinext-pregenerated-concrete-paths";
|
|
247
257
|
import __pagesClientAssets from "virtual:vinext-pages-client-assets";
|
|
248
258
|
${middlewarePath ? `import { applyAppMiddleware as __applyAppMiddleware } from ${JSON.stringify(appMiddlewarePath)};` : ""}
|
|
249
259
|
${instrumentationPath ? `import * as _instrumentation from ${JSON.stringify(toSlash(instrumentationPath))};
|
|
@@ -278,12 +288,16 @@ export { __basePath };
|
|
|
278
288
|
export const __imageAllowedWidths = ${JSON.stringify([...config?.imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...config?.imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES])};
|
|
279
289
|
export const __imageConfig = ${JSON.stringify({
|
|
280
290
|
qualities: config?.imageConfig?.qualities,
|
|
291
|
+
localPatterns: config?.imageConfig?.localPatterns,
|
|
281
292
|
dangerouslyAllowSVG: config?.imageConfig?.dangerouslyAllowSVG,
|
|
282
293
|
dangerouslyAllowLocalIP: config?.imageConfig?.dangerouslyAllowLocalIP,
|
|
283
294
|
contentDispositionType: config?.imageConfig?.contentDispositionType,
|
|
284
295
|
contentSecurityPolicy: config?.imageConfig?.contentSecurityPolicy
|
|
285
296
|
})};
|
|
286
297
|
export const __clientBuildFiles = __pagesClientAssets.clientBuildFiles ?? [];
|
|
298
|
+
// The matcher reads recorded prerenders, and this stage can run without the
|
|
299
|
+
// response entry that also loads them.
|
|
300
|
+
__initPregeneratedPathsFromGlobals();
|
|
287
301
|
const __routes = ${JSON.stringify(requestRoutes)};
|
|
288
302
|
const __routeMatcher = __createAppRscRouteMatcher(__routes, ${JSON.stringify(buildAppDecodedPathnamePatterns(routes, config))});
|
|
289
303
|
const __metadataRouteMatchers = ${JSON.stringify(metadataRouteMatchers)};
|
|
@@ -354,17 +368,21 @@ const __requestHandler = createAppRscRequestHandler({
|
|
|
354
368
|
const intercept = __routeMatcher.findIntercept(pathname, sourcePathname, interceptionId);
|
|
355
369
|
if (!intercept) return null;
|
|
356
370
|
const route = __routes[intercept.sourceRouteIndex];
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
371
|
+
const authorizationRoute = __routes[intercept.authorizationSourceRouteIndex];
|
|
372
|
+
if (!route || !authorizationRoute) return null;
|
|
373
|
+
const pickParams = (targetRoute, source) => {
|
|
374
|
+
const params = Object.create(null);
|
|
375
|
+
for (const name of targetRoute.params) {
|
|
376
|
+
if (Object.prototype.hasOwnProperty.call(source, name)) params[name] = source[name];
|
|
362
377
|
}
|
|
363
|
-
|
|
378
|
+
return params;
|
|
379
|
+
};
|
|
364
380
|
return {
|
|
381
|
+
authorizationParams: pickParams(authorizationRoute, intercept.authorizationSourceParams),
|
|
382
|
+
authorizationRoute,
|
|
365
383
|
interceptionSourceIsConcrete: intercept.sourceRouteIsConcrete,
|
|
366
384
|
route,
|
|
367
|
-
params,
|
|
385
|
+
params: pickParams(route, intercept.sourceMatchedParams),
|
|
368
386
|
};
|
|
369
387
|
},
|
|
370
388
|
${middlewarePath ? `runMiddleware({ cleanPathname, context, externalRewriteRequest, hadBasePath, isDataRequest, middlewareRequest, request, validateExternalRewriteRequest }) {
|
|
@@ -482,6 +500,7 @@ function generateRscEntry(appDir, routes, middlewarePath, metadataRoutes, global
|
|
|
482
500
|
const imageAllowedWidths = [...config?.imageConfig?.deviceSizes ?? DEFAULT_DEVICE_SIZES, ...config?.imageConfig?.imageSizes ?? DEFAULT_IMAGE_SIZES];
|
|
483
501
|
const imageConfig = {
|
|
484
502
|
qualities: config?.imageConfig?.qualities,
|
|
503
|
+
localPatterns: config?.imageConfig?.localPatterns,
|
|
485
504
|
dangerouslyAllowSVG: config?.imageConfig?.dangerouslyAllowSVG,
|
|
486
505
|
dangerouslyAllowLocalIP: config?.imageConfig?.dangerouslyAllowLocalIP,
|
|
487
506
|
contentDispositionType: config?.imageConfig?.contentDispositionType,
|
|
@@ -1161,7 +1180,6 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
|
|
|
1161
1180
|
getSourceRoute(sourceRouteIndex) {
|
|
1162
1181
|
return routes[sourceRouteIndex];
|
|
1163
1182
|
},
|
|
1164
|
-
hasCustomGlobalError: ${globalErrorVar ? `Boolean(${globalErrorVar}?.default)` : "false"},
|
|
1165
1183
|
hasAnyGenerateStaticParams: __generateStaticParams.length > 0,
|
|
1166
1184
|
hasGenerateStaticParams: __staticGeneration.hasGenerateStaticParams,
|
|
1167
1185
|
hasPageDefaultExport: !!PageComponent,
|
|
@@ -1636,17 +1654,21 @@ ${responseStageOnly ? "const __responseStageOptions = {" : "const __appRscHandle
|
|
|
1636
1654
|
const intercept = findIntercept(pathname, sourcePathname, interceptionId);
|
|
1637
1655
|
if (!intercept) return null;
|
|
1638
1656
|
const route = routes[intercept.sourceRouteIndex];
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1657
|
+
const authorizationRoute = routes[intercept.authorizationSourceRouteIndex];
|
|
1658
|
+
if (!route || !authorizationRoute) return null;
|
|
1659
|
+
const pickParams = (targetRoute, source) => {
|
|
1660
|
+
const params = Object.create(null);
|
|
1661
|
+
for (const name of targetRoute.params) {
|
|
1662
|
+
if (Object.prototype.hasOwnProperty.call(source, name)) params[name] = source[name];
|
|
1644
1663
|
}
|
|
1645
|
-
|
|
1664
|
+
return params;
|
|
1665
|
+
};
|
|
1646
1666
|
return {
|
|
1667
|
+
authorizationParams: pickParams(authorizationRoute, intercept.authorizationSourceParams),
|
|
1668
|
+
authorizationRoute,
|
|
1647
1669
|
interceptionSourceIsConcrete: intercept.sourceRouteIsConcrete,
|
|
1648
1670
|
route,
|
|
1649
|
-
params,
|
|
1671
|
+
params: pickParams(route, intercept.sourceMatchedParams),
|
|
1650
1672
|
};
|
|
1651
1673
|
},
|
|
1652
1674
|
${middlewarePath ? `runMiddleware({ cleanPathname, context, externalRewriteRequest, hadBasePath, isDataRequest, middlewareRequest, request, validateExternalRewriteRequest }) {
|
|
@@ -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"},
|