vinext 1.0.0-beta.2 → 1.0.0-beta.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.
- package/README.md +6 -9
- package/dist/build/client-build-config.js +7 -1
- package/dist/check.js +4 -0
- package/dist/config/config-matchers.js +4 -1
- package/dist/config/next-config.d.ts +12 -3
- package/dist/config/next-config.js +4 -0
- package/dist/entries/app-browser-entry.d.ts +4 -10
- package/dist/entries/app-browser-entry.js +20 -4
- package/dist/entries/app-rsc-entry.js +3 -0
- package/dist/entries/app-rsc-manifest.js +19 -0
- package/dist/entries/pages-client-entry.js +0 -1
- package/dist/entries/pages-server-entry.js +10 -3
- package/dist/index.js +112 -43
- package/dist/init-cloudflare.d.ts +3 -1
- package/dist/init-cloudflare.js +59 -5
- package/dist/plugins/extensionless-dynamic-import.js +23 -18
- package/dist/plugins/ignore-dynamic-requests.js +3 -1
- package/dist/plugins/import-meta-url.js +17 -6
- package/dist/plugins/require-context.js +20 -15
- package/dist/plugins/transform-cache.d.ts +19 -0
- package/dist/plugins/transform-cache.js +36 -0
- package/dist/routing/app-route-graph.d.ts +14 -6
- package/dist/routing/app-route-graph.js +106 -16
- package/dist/server/api-handler.d.ts +2 -0
- package/dist/server/api-handler.js +3 -3
- package/dist/server/app-browser-entry.js +103 -31
- package/dist/server/app-browser-navigation-controller.d.ts +23 -21
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-page-cache-finalizer.js +1 -1
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-cache.js +16 -2
- package/dist/server/app-page-dispatch.d.ts +8 -0
- package/dist/server/app-page-dispatch.js +31 -6
- package/dist/server/app-page-element-builder.d.ts +2 -0
- package/dist/server/app-page-element-builder.js +33 -7
- package/dist/server/app-page-head.d.ts +3 -3
- package/dist/server/app-page-head.js +58 -13
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +2 -2
- package/dist/server/app-page-http-access-fallback-metadata.js +9 -1
- package/dist/server/app-page-probe.d.ts +4 -0
- package/dist/server/app-page-probe.js +6 -2
- package/dist/server/app-page-request.d.ts +3 -0
- package/dist/server/app-page-request.js +1 -1
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +7 -0
- package/dist/server/app-page-route-wiring.js +211 -49
- package/dist/server/app-pages-bridge.d.ts +1 -1
- package/dist/server/app-pages-bridge.js +2 -1
- package/dist/server/app-route-handler-cache.js +4 -0
- package/dist/server/app-route-handler-dispatch.js +9 -3
- package/dist/server/app-route-handler-response.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +6 -0
- package/dist/server/app-route-module-loader.js +3 -0
- package/dist/server/app-router-entry.js +6 -3
- package/dist/server/app-rsc-errors.js +10 -0
- package/dist/server/app-rsc-handler.js +21 -9
- package/dist/server/app-rsc-route-matching.d.ts +9 -0
- package/dist/server/app-rsc-route-matching.js +6 -0
- package/dist/server/app-ssr-entry.js +4 -4
- package/dist/server/cache-control.d.ts +2 -2
- package/dist/server/cache-control.js +2 -1
- package/dist/server/dev-server.d.ts +3 -1
- package/dist/server/dev-server.js +145 -312
- package/dist/server/headers.d.ts +2 -2
- package/dist/server/headers.js +4 -3
- package/dist/server/isr-cache.d.ts +10 -33
- package/dist/server/isr-cache.js +33 -43
- package/dist/server/isr-decision.d.ts +2 -2
- package/dist/server/pages-api-route.d.ts +2 -0
- package/dist/server/pages-api-route.js +4 -1
- package/dist/server/pages-dev-hydration.js +0 -1
- package/dist/server/pages-get-initial-props.d.ts +1 -1
- package/dist/server/pages-get-initial-props.js +1 -4
- package/dist/server/pages-i18n.js +64 -16
- package/dist/server/pages-node-compat.d.ts +2 -0
- package/dist/server/pages-node-compat.js +7 -3
- package/dist/server/pages-page-data.d.ts +61 -9
- package/dist/server/pages-page-data.js +334 -74
- package/dist/server/pages-page-handler.d.ts +5 -1
- package/dist/server/pages-page-handler.js +115 -19
- package/dist/server/pages-page-response.d.ts +5 -3
- package/dist/server/pages-page-response.js +23 -26
- package/dist/server/pages-request-pipeline.d.ts +7 -0
- package/dist/server/pages-request-pipeline.js +5 -1
- package/dist/server/pages-revalidate.d.ts +1 -1
- package/dist/server/pages-revalidate.js +54 -8
- package/dist/server/pages-router-entry.d.ts +1 -0
- package/dist/server/pages-router-entry.js +10 -4
- package/dist/server/prod-server.d.ts +2 -1
- package/dist/server/prod-server.js +37 -13
- package/dist/server/revalidation-host.d.ts +11 -0
- package/dist/server/revalidation-host.js +19 -0
- package/dist/server/worker-revalidation-context.d.ts +13 -0
- package/dist/server/worker-revalidation-context.js +29 -0
- package/dist/shims/cache-handler.d.ts +1 -1
- package/dist/shims/cache-handler.js +10 -7
- package/dist/shims/cache-runtime.d.ts +6 -0
- package/dist/shims/cache-runtime.js +4 -1
- package/dist/shims/cache.js +1 -1
- package/dist/shims/error.js +1 -1
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/font-google-base.js +17 -8
- package/dist/shims/font-local.js +41 -10
- package/dist/shims/headers.d.ts +10 -13
- package/dist/shims/headers.js +85 -36
- package/dist/shims/internal/cookie-serialize.d.ts +10 -9
- package/dist/shims/internal/cookie-serialize.js +9 -8
- package/dist/shims/internal/interpolate-as.d.ts +15 -1
- package/dist/shims/internal/interpolate-as.js +27 -2
- package/dist/shims/link.js +18 -6
- package/dist/shims/metadata.d.ts +7 -17
- package/dist/shims/metadata.js +74 -24
- package/dist/shims/navigation.js +1 -1
- package/dist/shims/request-context.d.ts +4 -1
- package/dist/shims/router.js +18 -7
- package/dist/shims/script.js +1 -1
- package/dist/shims/server.d.ts +7 -6
- package/dist/shims/server.js +156 -57
- package/dist/shims/unified-request-context.d.ts +21 -2
- package/dist/shims/unified-request-context.js +82 -1
- package/dist/utils/cache-control-metadata.d.ts +2 -1
- package/dist/utils/cache-control-metadata.js +5 -1
- package/dist/utils/html-limited-bots.js +1 -1
- package/dist/utils/protocol-headers.d.ts +7 -1
- package/dist/utils/protocol-headers.js +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -345,24 +345,16 @@ Requires a custom domain (zone analytics are unavailable on `*.workers.dev`) and
|
|
|
345
345
|
|
|
346
346
|
#### Custom Vite configuration
|
|
347
347
|
|
|
348
|
-
If you need to customize the Vite config, create a `vite.config.ts`. vinext will merge its config with yours.
|
|
348
|
+
If you need to customize the Vite config, create a `vite.config.ts`. vinext will merge its config with yours. For Cloudflare Workers deployment with the App Router, configure `@cloudflare/vite-plugin` so the RSC environment runs in workerd:
|
|
349
349
|
|
|
350
350
|
```ts
|
|
351
351
|
import { defineConfig } from "vite";
|
|
352
352
|
import vinext from "vinext";
|
|
353
|
-
import rsc from "@vitejs/plugin-rsc";
|
|
354
353
|
import { cloudflare } from "@cloudflare/vite-plugin";
|
|
355
354
|
|
|
356
355
|
export default defineConfig({
|
|
357
356
|
plugins: [
|
|
358
357
|
vinext(),
|
|
359
|
-
rsc({
|
|
360
|
-
entries: {
|
|
361
|
-
rsc: "virtual:vinext-rsc-entry",
|
|
362
|
-
ssr: "virtual:vinext-app-ssr-entry",
|
|
363
|
-
client: "virtual:vinext-app-browser-entry",
|
|
364
|
-
},
|
|
365
|
-
}),
|
|
366
358
|
cloudflare({
|
|
367
359
|
viteEnvironment: { name: "rsc", childEnvironments: ["ssr"] },
|
|
368
360
|
}),
|
|
@@ -370,6 +362,11 @@ export default defineConfig({
|
|
|
370
362
|
});
|
|
371
363
|
```
|
|
372
364
|
|
|
365
|
+
> **Do not register `@vitejs/plugin-rsc` yourself.** It is an optional peer dependency, so it must be
|
|
366
|
+
> _installed_ in your project, but vinext auto-registers it whenever an `app/` directory is detected.
|
|
367
|
+
> Adding an explicit `rsc()` call fails the build with `[vinext] Duplicate @vitejs/plugin-rsc detected`.
|
|
368
|
+
> Pass `rsc: false` to `vinext()` only if you want to own that registration.
|
|
369
|
+
|
|
373
370
|
See the [examples](#live-examples) for complete working configurations.
|
|
374
371
|
|
|
375
372
|
### Other platforms (via Nitro)
|
|
@@ -89,7 +89,13 @@ function createClientManualChunks(shimsDir, preserveRouteBoundaries = false) {
|
|
|
89
89
|
if (id.includes("node_modules")) {
|
|
90
90
|
const pkg = getPackageName(id);
|
|
91
91
|
if (!pkg) return void 0;
|
|
92
|
-
if (pkg === "react
|
|
92
|
+
if (pkg === "react-dom") {
|
|
93
|
+
const slashedId = toSlash(id);
|
|
94
|
+
const sub = slashedId.slice(slashedId.lastIndexOf("react-dom/") + 10);
|
|
95
|
+
if (sub.startsWith("server.") || sub.startsWith("static.") || sub.startsWith("cjs/react-dom-server")) return "react-dom-server";
|
|
96
|
+
return "framework";
|
|
97
|
+
}
|
|
98
|
+
if (pkg === "react" || pkg === "scheduler") return "framework";
|
|
93
99
|
return;
|
|
94
100
|
}
|
|
95
101
|
const slashedId = toSlash(id);
|
package/dist/check.js
CHANGED
|
@@ -230,6 +230,10 @@ const CONFIG_SUPPORT = {
|
|
|
230
230
|
status: "supported",
|
|
231
231
|
detail: "server actions via 'use server' directive"
|
|
232
232
|
},
|
|
233
|
+
"experimental.allowedRevalidateHeaderKeys": {
|
|
234
|
+
status: "supported",
|
|
235
|
+
detail: "forwards explicitly allowed request headers during Pages Router revalidation"
|
|
236
|
+
},
|
|
233
237
|
"experimental.prefetchInlining": {
|
|
234
238
|
status: "partial",
|
|
235
239
|
detail: "config recognized; Link prefetch preserves pending/dedup semantics, but vinext does not implement per-segment cache storage"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "../utils/protocol-headers.js";
|
|
1
|
+
import { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
|
|
2
2
|
import { buildRequestHeadersFromMiddlewareResponse } from "../utils/middleware-request-headers.js";
|
|
3
3
|
import { analyzeRegexSafety } from "../utils/regex-safety.js";
|
|
4
4
|
import { normalizeHost, parseCookies, requestContextFromRequest } from "./request-context.js";
|
|
@@ -835,6 +835,9 @@ async function proxyExternalRequest(request, externalUrl) {
|
|
|
835
835
|
for (const key of keysToDelete) headers.delete(key);
|
|
836
836
|
headers.delete(VINEXT_PRERENDER_SECRET_HEADER);
|
|
837
837
|
headers.delete(VINEXT_PRERENDER_ROUTE_PARAMS_HEADER);
|
|
838
|
+
headers.delete(PRERENDER_REVALIDATE_HEADER);
|
|
839
|
+
headers.delete(PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER);
|
|
840
|
+
headers.delete(VINEXT_REVALIDATE_HOST_HEADER);
|
|
838
841
|
headers.delete(VINEXT_MW_CTX_HEADER);
|
|
839
842
|
const method = request.method;
|
|
840
843
|
const hasBody = method !== "GET" && method !== "HEAD";
|
|
@@ -100,7 +100,11 @@ type NextConfig = {
|
|
|
100
100
|
* @see https://nextjs.org/docs/app/api-reference/config/next-config-js/assetPrefix
|
|
101
101
|
*/
|
|
102
102
|
assetPrefix?: string; /** Whether to add trailing slashes */
|
|
103
|
-
trailingSlash?: boolean; /**
|
|
103
|
+
trailingSlash?: boolean; /** TypeScript build settings. */
|
|
104
|
+
typescript?: {
|
|
105
|
+
/** Project-relative path to the TypeScript configuration file. */tsconfigPath?: string;
|
|
106
|
+
[key: string]: unknown;
|
|
107
|
+
}; /** Internationalization routing config */
|
|
104
108
|
i18n?: NextI18nConfig; /** URL redirect rules */
|
|
105
109
|
redirects?: () => Promise<NextRedirect[]> | NextRedirect[]; /** URL rewrite rules */
|
|
106
110
|
rewrites?: () => Promise<NextRewrite[] | {
|
|
@@ -217,7 +221,8 @@ type NextConfig = {
|
|
|
217
221
|
prefetchInlining?: boolean | {
|
|
218
222
|
maxBundleSize?: number;
|
|
219
223
|
maxSize?: number;
|
|
220
|
-
};
|
|
224
|
+
}; /** Header names forwarded by Pages Router `res.revalidate()` internal requests. */
|
|
225
|
+
allowedRevalidateHeaderKeys?: string[];
|
|
221
226
|
[key: string]: unknown;
|
|
222
227
|
};
|
|
223
228
|
/**
|
|
@@ -266,6 +271,9 @@ type ResolvedNextConfig = {
|
|
|
266
271
|
*/
|
|
267
272
|
assetPrefix: string;
|
|
268
273
|
trailingSlash: boolean;
|
|
274
|
+
typescript: {
|
|
275
|
+
tsconfigPath?: string;
|
|
276
|
+
};
|
|
269
277
|
output: "" | "export" | "standalone";
|
|
270
278
|
pageExtensions: string[];
|
|
271
279
|
resolveExtensions: string[] | null;
|
|
@@ -295,7 +303,8 @@ type ResolvedNextConfig = {
|
|
|
295
303
|
mdx: MdxOptions | null; /** Explicit module aliases preserved from wrapped next.config plugins. */
|
|
296
304
|
aliases: Record<string, string>; /** Extra allowed origins for dev server access (from allowedDevOrigins). */
|
|
297
305
|
allowedDevOrigins: string[]; /** Extra allowed origins for server action CSRF validation (from experimental.serverActions.allowedOrigins). */
|
|
298
|
-
serverActionsAllowedOrigins: string[]; /**
|
|
306
|
+
serverActionsAllowedOrigins: string[]; /** Header names forwarded by Pages Router `res.revalidate()` internal requests. */
|
|
307
|
+
allowedRevalidateHeaderKeys: string[]; /** Packages whose barrel imports should be optimized (from experimental.optimizePackageImports). */
|
|
299
308
|
optimizePackageImports: string[]; /** Packages explicitly requested for server/client transpilation. */
|
|
300
309
|
transpilePackages: string[]; /** Packages treated as application code by Turbopack's foreign-code condition. */
|
|
301
310
|
turbopackTranspilePackages: string[]; /** Inline app CSS into production HTML (from experimental.inlineCss). */
|
|
@@ -658,6 +658,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
658
658
|
basePath: "",
|
|
659
659
|
assetPrefix: "",
|
|
660
660
|
trailingSlash: false,
|
|
661
|
+
typescript: {},
|
|
661
662
|
output: "",
|
|
662
663
|
pageExtensions: normalizePageExtensions(),
|
|
663
664
|
resolveExtensions: null,
|
|
@@ -679,6 +680,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
679
680
|
aliases: {},
|
|
680
681
|
allowedDevOrigins: [],
|
|
681
682
|
serverActionsAllowedOrigins: [],
|
|
683
|
+
allowedRevalidateHeaderKeys: [],
|
|
682
684
|
optimizePackageImports: [],
|
|
683
685
|
transpilePackages: [],
|
|
684
686
|
turbopackTranspilePackages: [...DEFAULT_TRANSPILED_PACKAGES],
|
|
@@ -833,6 +835,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
833
835
|
basePath: config.basePath ?? "",
|
|
834
836
|
assetPrefix: normalizeAssetPrefix(config.assetPrefix),
|
|
835
837
|
trailingSlash: config.trailingSlash ?? false,
|
|
838
|
+
typescript: typeof config.typescript?.tsconfigPath === "string" ? { tsconfigPath: config.typescript.tsconfigPath } : {},
|
|
836
839
|
output: output === "export" || output === "standalone" ? output : "",
|
|
837
840
|
pageExtensions,
|
|
838
841
|
resolveExtensions: resolveExtensions ?? webpackProbe.resolveExtensions,
|
|
@@ -851,6 +854,7 @@ async function resolveNextConfig(config, root = toSlash(process.cwd()), options
|
|
|
851
854
|
aliases,
|
|
852
855
|
allowedDevOrigins,
|
|
853
856
|
serverActionsAllowedOrigins,
|
|
857
|
+
allowedRevalidateHeaderKeys: Array.isArray(experimental?.allowedRevalidateHeaderKeys) ? experimental.allowedRevalidateHeaderKeys.filter((value) => typeof value === "string").map((value) => value.toLowerCase()) : [],
|
|
854
858
|
optimizePackageImports,
|
|
855
859
|
transpilePackages,
|
|
856
860
|
turbopackTranspilePackages,
|
|
@@ -15,15 +15,9 @@ declare function generateBrowserEntry(routes?: readonly AppRoute[], routeManifes
|
|
|
15
15
|
beforeFiles: NextRewrite[];
|
|
16
16
|
fallback: NextRewrite[];
|
|
17
17
|
}): string;
|
|
18
|
-
/**
|
|
19
|
-
* Filter for routes that should appear in the `__VINEXT_LINK_PREFETCH_ROUTES__`
|
|
20
|
-
* manifest. Exported so the Pages Router client entry can reuse it when
|
|
21
|
-
* emitting the same manifest for hybrid builds — see issue #1526 and
|
|
22
|
-
* `pages-client-entry.ts`.
|
|
23
|
-
*/
|
|
24
|
-
declare function isLinkPrefetchRoute(route: AppRoute): boolean;
|
|
25
|
-
declare function toDocumentOnlyAppRoute(route: AppRoute): VinextLinkPrefetchRoute;
|
|
26
18
|
/** Project an `AppRoute` down to the public `VinextLinkPrefetchRoute` shape. */
|
|
27
|
-
declare function toLinkPrefetchRoute(route: AppRoute): VinextLinkPrefetchRoute;
|
|
19
|
+
declare function toLinkPrefetchRoute(route: AppRoute, hasSiblingInterceptLoading?: boolean): VinextLinkPrefetchRoute;
|
|
20
|
+
/** Project App routes together so sibling-intercept loading is applied to its target route. */
|
|
21
|
+
declare function toLinkPrefetchRoutes(routes: readonly AppRoute[]): VinextLinkPrefetchRoute[];
|
|
28
22
|
//#endregion
|
|
29
|
-
export { generateBrowserEntry,
|
|
23
|
+
export { generateBrowserEntry, toLinkPrefetchRoute, toLinkPrefetchRoutes };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { resolveClientRuntimeModule, resolveRuntimeEntryModule } from "./runtime-entry-module.js";
|
|
2
|
+
import { patternsStructurallyEquivalent } from "../routing/app-route-graph.js";
|
|
2
3
|
//#region src/entries/app-browser-entry.ts
|
|
3
4
|
/**
|
|
4
5
|
* Generate the virtual browser entry module.
|
|
@@ -14,7 +15,7 @@ function generateBrowserEntry(routes = [], routeManifest = null, pagesPrefetchRo
|
|
|
14
15
|
}) {
|
|
15
16
|
const entryPath = resolveRuntimeEntryModule("app-browser-entry");
|
|
16
17
|
const navigationRuntimePath = resolveClientRuntimeModule("navigation-runtime");
|
|
17
|
-
const prefetchRoutes = routes
|
|
18
|
+
const prefetchRoutes = toLinkPrefetchRoutes(routes);
|
|
18
19
|
return `import { registerNavigationRuntimeBootstrap } from ${JSON.stringify(navigationRuntimePath)};
|
|
19
20
|
|
|
20
21
|
window.__VINEXT_LINK_PREFETCH_ROUTES__ = ${JSON.stringify(prefetchRoutes)};
|
|
@@ -50,15 +51,30 @@ function toDocumentOnlyAppRoute(route) {
|
|
|
50
51
|
function requiresDynamicNavigationRequest(route) {
|
|
51
52
|
return route.isDynamic && route.parallelSlots.length > 0;
|
|
52
53
|
}
|
|
54
|
+
function splitPatternParts(pattern) {
|
|
55
|
+
return pattern.split("/").filter(Boolean);
|
|
56
|
+
}
|
|
57
|
+
function interceptTargetsRoute(interceptTargetPattern, route) {
|
|
58
|
+
return patternsStructurallyEquivalent(splitPatternParts(interceptTargetPattern), route.patternParts);
|
|
59
|
+
}
|
|
60
|
+
function hasLoadingBoundary(route, hasSiblingInterceptLoading) {
|
|
61
|
+
return route.loadingPath !== null || (route.loadingPaths?.length ?? 0) > 0 || route.parallelSlots.some((slot) => slot.loadingPath !== null || (slot.loadingPaths?.length ?? 0) > 0 || slot.interceptingRoutes.some((intercept) => interceptTargetsRoute(intercept.targetPattern, route) && (intercept.loadingPaths?.length ?? 0) > 0)) || hasSiblingInterceptLoading;
|
|
62
|
+
}
|
|
53
63
|
/** Project an `AppRoute` down to the public `VinextLinkPrefetchRoute` shape. */
|
|
54
|
-
function toLinkPrefetchRoute(route) {
|
|
64
|
+
function toLinkPrefetchRoute(route, hasSiblingInterceptLoading = route.siblingIntercepts.some((intercept) => interceptTargetsRoute(intercept.targetPattern, route) && (intercept.loadingPaths?.length ?? 0) > 0)) {
|
|
55
65
|
return {
|
|
56
|
-
canPrefetchLoadingShell: route
|
|
66
|
+
canPrefetchLoadingShell: hasLoadingBoundary(route, hasSiblingInterceptLoading),
|
|
57
67
|
patternParts: [...route.patternParts],
|
|
58
68
|
isDynamic: route.isDynamic,
|
|
59
69
|
...requiresDynamicNavigationRequest(route) ? { requiresDynamicNavigationRequest: true } : {}
|
|
60
70
|
};
|
|
61
71
|
}
|
|
72
|
+
/** Project App routes together so sibling-intercept loading is applied to its target route. */
|
|
73
|
+
function toLinkPrefetchRoutes(routes) {
|
|
74
|
+
const siblingInterceptLoadingTargets = [];
|
|
75
|
+
for (const route of routes) for (const intercept of route.siblingIntercepts) if ((intercept.loadingPaths?.length ?? 0) > 0) siblingInterceptLoadingTargets.push(splitPatternParts(intercept.targetPattern));
|
|
76
|
+
return routes.map((route) => isLinkPrefetchRoute(route) ? toLinkPrefetchRoute(route, siblingInterceptLoadingTargets.some((targetParts) => patternsStructurallyEquivalent(targetParts, route.patternParts))) : toDocumentOnlyAppRoute(route));
|
|
77
|
+
}
|
|
62
78
|
function buildRouteManifestExpression(routeManifest) {
|
|
63
79
|
if (routeManifest === null) return "null";
|
|
64
80
|
const graph = routeManifest.segmentGraph;
|
|
@@ -84,4 +100,4 @@ function buildMapExpression(map) {
|
|
|
84
100
|
return `new Map(${JSON.stringify(Array.from(map.entries()))})`;
|
|
85
101
|
}
|
|
86
102
|
//#endregion
|
|
87
|
-
export { generateBrowserEntry,
|
|
103
|
+
export { generateBrowserEntry, toLinkPrefetchRoute, toLinkPrefetchRoutes };
|
|
@@ -195,6 +195,7 @@ import {
|
|
|
195
195
|
isrGet as __isrGet,
|
|
196
196
|
isrSet as __isrSet,
|
|
197
197
|
isrSetPrerenderedAppPage as __isrSetPrerenderedAppPage,
|
|
198
|
+
isOnDemandRevalidateRequest as __isOnDemandRevalidateRequest,
|
|
198
199
|
triggerBackgroundRegeneration as __triggerBackgroundRegeneration,
|
|
199
200
|
} from ${JSON.stringify(isrCachePath)};
|
|
200
201
|
// Import server-only state module to register ALS-backed accessors.
|
|
@@ -436,6 +437,8 @@ async function buildPageElements(route, params, routePath, pageRequest, layoutPa
|
|
|
436
437
|
}
|
|
437
438
|
|
|
438
439
|
const __i18nConfig = ${JSON.stringify(i18nConfig)};
|
|
440
|
+
export { __i18nConfig };
|
|
441
|
+
export const authorizeOnDemandRevalidate = __isOnDemandRevalidateRequest;
|
|
439
442
|
const __configRedirects = ${JSON.stringify(redirects)};
|
|
440
443
|
const __configRewrites = ${JSON.stringify(rewrites)};
|
|
441
444
|
const __configHeaders = ${JSON.stringify(headers)};
|
|
@@ -53,6 +53,7 @@ function registerRouteModules(routes, imports) {
|
|
|
53
53
|
for (const layout of route.layouts) imports.getLazyLoaderVar(layout);
|
|
54
54
|
for (const tmpl of route.templates) imports.getLazyLoaderVar(tmpl);
|
|
55
55
|
if (route.loadingPath) imports.getLazyLoaderVar(route.loadingPath);
|
|
56
|
+
for (const loadingPath of route.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
|
|
56
57
|
if (route.errorPath) imports.getLazyLoaderVar(route.errorPath);
|
|
57
58
|
if (route.layoutErrorPaths) {
|
|
58
59
|
for (const ep of route.layoutErrorPaths) if (ep) imports.getLazyLoaderVar(ep);
|
|
@@ -76,18 +77,21 @@ function registerRouteModules(routes, imports) {
|
|
|
76
77
|
if (slot.layoutPath) imports.getLazyLoaderVar(slot.layoutPath);
|
|
77
78
|
for (const layoutPath of slot.configLayoutPaths ?? []) imports.getLazyLoaderVar(layoutPath);
|
|
78
79
|
if (slot.loadingPath) imports.getLazyLoaderVar(slot.loadingPath);
|
|
80
|
+
for (const loadingPath of slot.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
|
|
79
81
|
if (slot.errorPath) imports.getLazyLoaderVar(slot.errorPath);
|
|
80
82
|
if (slot.notFoundPath) imports.getLazyLoaderVar(slot.notFoundPath);
|
|
81
83
|
for (const ir of slot.interceptingRoutes) {
|
|
82
84
|
imports.getLazyLoaderVar(ir.pagePath);
|
|
83
85
|
if (ir.notFoundPath) imports.getLazyLoaderVar(ir.notFoundPath);
|
|
84
86
|
for (const layoutPath of ir.layoutPaths) imports.getLazyLoaderVar(layoutPath);
|
|
87
|
+
for (const loadingPath of ir.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
|
|
85
88
|
}
|
|
86
89
|
}
|
|
87
90
|
for (const ir of route.siblingIntercepts ?? []) {
|
|
88
91
|
imports.getLazyLoaderVar(ir.pagePath);
|
|
89
92
|
if (ir.notFoundPath) imports.getLazyLoaderVar(ir.notFoundPath);
|
|
90
93
|
for (const layoutPath of ir.layoutPaths) imports.getLazyLoaderVar(layoutPath);
|
|
94
|
+
for (const loadingPath of ir.loadingPaths ?? []) imports.getLazyLoaderVar(loadingPath);
|
|
91
95
|
}
|
|
92
96
|
}
|
|
93
97
|
}
|
|
@@ -102,10 +106,12 @@ function buildRouteEntries(routes, imports) {
|
|
|
102
106
|
const staticSiblings = route.isDynamic ? computeAppRouteStaticSiblings(routes, route) : [];
|
|
103
107
|
const layoutLoaders = lazyLoaderArray(route.layouts, imports);
|
|
104
108
|
const templateLoaders = lazyLoaderArray(route.templates, imports);
|
|
109
|
+
const loadingPaths = route.loadingPaths ?? [];
|
|
105
110
|
const notFoundPaths = route.notFoundPaths ?? [];
|
|
106
111
|
const forbiddenPaths = route.forbiddenPaths ?? [];
|
|
107
112
|
const unauthorizedPaths = route.unauthorizedPaths ?? [];
|
|
108
113
|
const notFoundLoaders = lazyLoaderArray(notFoundPaths, imports);
|
|
114
|
+
const loadingLoaders = lazyLoaderArray(loadingPaths, imports);
|
|
109
115
|
const forbiddenLoaders = lazyLoaderArray(forbiddenPaths, imports);
|
|
110
116
|
const unauthorizedLoaders = lazyLoaderArray(unauthorizedPaths, imports);
|
|
111
117
|
const siblingInterceptEntries = (route.siblingIntercepts ?? []).map((ir) => ` {
|
|
@@ -118,6 +124,9 @@ function buildRouteEntries(routes, imports) {
|
|
|
118
124
|
__loadInterceptLayouts: ${lazyLoaderArray(ir.layoutPaths, imports)},
|
|
119
125
|
interceptLayoutSegments: ${JSON.stringify(ir.layoutSegments ?? [])},
|
|
120
126
|
interceptBranchSegments: ${JSON.stringify(ir.branchSegments ?? [])},
|
|
127
|
+
interceptLoadings: ${moduleArray(ir.loadingPaths?.length ?? 0)},
|
|
128
|
+
__loadInterceptLoadings: ${lazyLoaderArray(ir.loadingPaths ?? [], imports)},
|
|
129
|
+
interceptLoadingTreePositions: ${JSON.stringify(ir.loadingTreePositions ?? [])},
|
|
121
130
|
interceptNotFoundBranchSegments: ${JSON.stringify(ir.notFoundBranchSegments ?? ir.branchSegments ?? [])},
|
|
122
131
|
page: null,
|
|
123
132
|
__pageLoader: ${imports.getLazyLoaderVar(ir.pagePath)},
|
|
@@ -136,6 +145,9 @@ function buildRouteEntries(routes, imports) {
|
|
|
136
145
|
__loadInterceptLayouts: ${lazyLoaderArray(ir.layoutPaths, imports)},
|
|
137
146
|
interceptLayoutSegments: ${JSON.stringify(ir.layoutSegments ?? [])},
|
|
138
147
|
interceptBranchSegments: ${JSON.stringify(ir.branchSegments ?? [])},
|
|
148
|
+
interceptLoadings: ${moduleArray(ir.loadingPaths?.length ?? 0)},
|
|
149
|
+
__loadInterceptLoadings: ${lazyLoaderArray(ir.loadingPaths ?? [], imports)},
|
|
150
|
+
interceptLoadingTreePositions: ${JSON.stringify(ir.loadingTreePositions ?? [])},
|
|
139
151
|
interceptNotFoundBranchSegments: ${JSON.stringify(ir.notFoundBranchSegments ?? ir.branchSegments ?? [])},
|
|
140
152
|
page: null,
|
|
141
153
|
__pageLoader: ${imports.getLazyLoaderVar(ir.pagePath)},
|
|
@@ -147,6 +159,7 @@ function buildRouteEntries(routes, imports) {
|
|
|
147
159
|
return ` ${JSON.stringify(slot.key)}: {
|
|
148
160
|
id: ${JSON.stringify(slot.id ?? null)},
|
|
149
161
|
name: ${JSON.stringify(slot.name)},
|
|
162
|
+
ownerTreePosition: ${slot.ownerTreePosition ?? "null"},
|
|
150
163
|
page: null,
|
|
151
164
|
__loadPage: ${slot.pagePath ? imports.getLazyLoaderVar(slot.pagePath) : "null"},
|
|
152
165
|
default: null,
|
|
@@ -158,6 +171,9 @@ function buildRouteEntries(routes, imports) {
|
|
|
158
171
|
configLayoutTreePositions: ${JSON.stringify(slot.configLayoutTreePositions ?? [])},
|
|
159
172
|
loading: null,
|
|
160
173
|
__loadLoading: ${slot.loadingPath ? imports.getLazyLoaderVar(slot.loadingPath) : "null"},
|
|
174
|
+
loadings: ${moduleArray(slot.loadingPaths?.length ?? 0)},
|
|
175
|
+
__loadLoadings: ${lazyLoaderArray(slot.loadingPaths ?? [], imports)},
|
|
176
|
+
loadingTreePositions: ${JSON.stringify(slot.loadingTreePositions ?? [])},
|
|
161
177
|
error: null,
|
|
162
178
|
__loadError: ${slot.errorPath ? imports.getLazyLoaderVar(slot.errorPath) : "null"},
|
|
163
179
|
notFound: null,
|
|
@@ -200,6 +216,9 @@ ${interceptEntries.join(",\n")}
|
|
|
200
216
|
layoutTreePositions: ${JSON.stringify(route.layoutTreePositions)},
|
|
201
217
|
templates: ${moduleArray(route.templates.length)},
|
|
202
218
|
__loadTemplates: ${templateLoaders},
|
|
219
|
+
loadings: ${moduleArray(loadingPaths.length)},
|
|
220
|
+
__loadLoadings: ${loadingLoaders},
|
|
221
|
+
loadingTreePositions: ${JSON.stringify(route.loadingTreePositions ?? null)},
|
|
203
222
|
errors: ${moduleArray(layoutErrorPaths.length)},
|
|
204
223
|
__loadErrors: ${layoutErrorLoaders},
|
|
205
224
|
errorPaths: ${moduleArray(errorPaths.length)},
|
|
@@ -24,6 +24,7 @@ const _pagesApiRoutePath = resolveEntryPath("../server/pages-api-route.js", impo
|
|
|
24
24
|
const _serverGlobalsPath = resolveEntryPath("../server/server-globals.js", import.meta.url);
|
|
25
25
|
const _queryUtilsPath = resolveEntryPath("../utils/query.js", import.meta.url);
|
|
26
26
|
const _pagesPageHandlerPath = resolveEntryPath("../server/pages-page-handler.js", import.meta.url);
|
|
27
|
+
const _isrCachePath = resolveEntryPath("../server/isr-cache.js", import.meta.url);
|
|
27
28
|
async function getPagesDataKind(filePath) {
|
|
28
29
|
const source = await readFile(filePath, "utf8");
|
|
29
30
|
if (hasExportedName(source, "getStaticProps")) return "static";
|
|
@@ -71,6 +72,7 @@ async function generateServerEntry(pagesDir, nextConfig, fileMatcher, middleware
|
|
|
71
72
|
},
|
|
72
73
|
headers: nextConfig?.headers ?? [],
|
|
73
74
|
expireTime: nextConfig?.expireTime,
|
|
75
|
+
allowedRevalidateHeaderKeys: nextConfig?.allowedRevalidateHeaderKeys ?? [],
|
|
74
76
|
cacheMaxMemorySize: nextConfig?.cacheMaxMemorySize,
|
|
75
77
|
htmlLimitedBots: nextConfig?.htmlLimitedBots,
|
|
76
78
|
i18n: nextConfig?.i18n ?? null,
|
|
@@ -151,11 +153,17 @@ import { handlePagesApiRoute as __handlePagesApiRoute } from ${JSON.stringify(_p
|
|
|
151
153
|
import { normalizePagesDataRequest as __normalizePagesDataRequest, buildNextDataNotFoundResponse as __buildNextDataNotFoundResponse } from ${JSON.stringify(_pagesDataRoutePath)};
|
|
152
154
|
import { buildDefaultPagesNotFoundResponse as __buildDefaultPagesNotFoundResponse } from ${JSON.stringify(_pagesDefault404Path)};
|
|
153
155
|
import { createPagesPageHandler as __createPagesPageHandler } from ${JSON.stringify(_pagesPageHandlerPath)};
|
|
156
|
+
import { isOnDemandRevalidateRequest as __isOnDemandRevalidateRequest } from ${JSON.stringify(_isrCachePath)};
|
|
154
157
|
${instrumentationImportCode}
|
|
155
158
|
${middlewareImportCode}
|
|
156
159
|
|
|
157
160
|
${instrumentationInitCode}
|
|
158
161
|
|
|
162
|
+
// The outer Node production pipeline runs outside this generated bundle, so
|
|
163
|
+
// it cannot safely validate against its own development fallback secret. Give
|
|
164
|
+
// it a verifier closed over this entry's build-time-baked secret instead.
|
|
165
|
+
export const authorizeOnDemandRevalidate = __isOnDemandRevalidateRequest;
|
|
166
|
+
|
|
159
167
|
// i18n config (embedded at build time)
|
|
160
168
|
const i18nConfig = ${i18nConfigJson};
|
|
161
169
|
|
|
@@ -344,7 +352,6 @@ const _renderPage = __createPagesPageHandler({
|
|
|
344
352
|
? React.createElement(AppComponent, {
|
|
345
353
|
...props,
|
|
346
354
|
Component: PageComponent,
|
|
347
|
-
pageProps: rawPageProps,
|
|
348
355
|
router: Router,
|
|
349
356
|
})
|
|
350
357
|
: React.createElement(PageComponent, pageProps);
|
|
@@ -362,7 +369,6 @@ const _renderPage = __createPagesPageHandler({
|
|
|
362
369
|
? React.createElement(FinalApp, {
|
|
363
370
|
...props,
|
|
364
371
|
Component: FinalComp,
|
|
365
|
-
pageProps: rawPageProps,
|
|
366
372
|
router: Router,
|
|
367
373
|
})
|
|
368
374
|
: React.createElement(FinalComp, pageProps);
|
|
@@ -379,7 +385,7 @@ export async function renderPage(request, url, manifest, ctx, middlewareHeaders,
|
|
|
379
385
|
|
|
380
386
|
|
|
381
387
|
|
|
382
|
-
export async function handleApiRoute(request, url, ctx) {
|
|
388
|
+
export async function handleApiRoute(request, url, ctx, trustedRevalidateOrigin) {
|
|
383
389
|
__registerConfiguredCacheAdapters();
|
|
384
390
|
const match = matchRoute(url, apiRoutes);
|
|
385
391
|
return __handlePagesApiRoute({
|
|
@@ -387,6 +393,7 @@ export async function handleApiRoute(request, url, ctx) {
|
|
|
387
393
|
match,
|
|
388
394
|
nextConfig: vinextConfig,
|
|
389
395
|
request,
|
|
396
|
+
trustedRevalidateOrigin,
|
|
390
397
|
url,
|
|
391
398
|
reportRequestError(error, routePattern) {
|
|
392
399
|
console.error("[vinext] API error:", error);
|