vinext 1.0.0-beta.0 → 1.0.0-beta.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 -2
- package/dist/build/assets-ignore.js +1 -1
- package/dist/build/clean-output.js +1 -1
- package/dist/build/client-build-config.js +7 -4
- package/dist/build/css-url-assets.js +3 -3
- package/dist/build/google-fonts/fallback-metrics.js +1 -1
- package/dist/build/google-fonts/font-metadata.js +1 -1
- package/dist/build/inject-pregenerated-paths.js +1 -1
- package/dist/build/inline-css.js +2 -5
- package/dist/build/module-dependency-cache.d.ts +4 -0
- package/dist/build/module-dependency-cache.js +13 -0
- package/dist/build/next-client-runtime-manifests.js +1 -1
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/precompress.js +7 -7
- package/dist/build/prerender-paths.d.ts +2 -2
- package/dist/build/prerender-paths.js +10 -15
- package/dist/build/prerender-server-pool.js +2 -2
- package/dist/build/prerender.js +1 -1
- package/dist/build/preview-credentials.d.ts +11 -0
- package/dist/build/preview-credentials.js +19 -0
- package/dist/build/report.d.ts +8 -4
- package/dist/build/report.js +14 -6
- package/dist/build/run-prerender.d.ts +2 -11
- package/dist/build/run-prerender.js +2 -10
- package/dist/build/server-manifest.js +1 -1
- package/dist/build/ssr-manifest.d.ts +4 -0
- package/dist/build/ssr-manifest.js +10 -6
- package/dist/build/standalone.js +37 -37
- package/dist/cache/cache-adapters-virtual.d.ts +1 -17
- package/dist/cache/cache-adapters-virtual.js +20 -11
- package/dist/check.d.ts +0 -16
- package/dist/check.js +27 -36
- package/dist/cli.js +61 -55
- package/dist/client/instrumentation-client-inject.js +1 -1
- package/dist/client/pages-router-link-navigation.js +1 -1
- package/dist/config/config-matchers.d.ts +13 -37
- package/dist/config/config-matchers.js +33 -123
- package/dist/config/dotenv.js +1 -1
- package/dist/config/next-config.d.ts +7 -3
- package/dist/config/next-config.js +84 -15
- package/dist/config/prerender.d.ts +2 -2
- package/dist/config/prerender.js +7 -15
- package/dist/config/request-context.d.ts +14 -0
- package/dist/config/request-context.js +26 -0
- package/dist/config/server-external-packages.js +1 -1
- package/dist/config/tsconfig-paths.js +2 -2
- package/dist/{node_modules/.pnpm/am-i-vibing@0.5.0/node_modules → deps/.pnpm/am-i-vibing@0.5.0/deps}/am-i-vibing/dist/detector-1yx2Hoe0.js +2 -2
- package/dist/deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js +50 -0
- package/dist/entries/app-rsc-entry.js +39 -14
- package/dist/entries/app-rsc-manifest.js +21 -4
- package/dist/entries/pages-client-entry.js +6 -5
- package/dist/entries/pages-server-entry.js +18 -28
- package/dist/entries/runtime-entry-module.js +2 -2
- package/dist/index.js +314 -230
- package/dist/init-cloudflare.js +1 -1
- package/dist/init-platform.js +1 -1
- package/dist/init.d.ts +6 -4
- package/dist/init.js +25 -27
- package/dist/plugins/ast-utils.js +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +7 -7
- package/dist/plugins/extensionless-dynamic-import.js +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +13 -8
- package/dist/plugins/import-meta-url.js +16 -17
- package/dist/plugins/middleware-export-validation.js +1 -1
- package/dist/plugins/middleware-server-only.js +2 -2
- package/dist/plugins/og-asset-ownership.js +7 -6
- package/dist/plugins/og-assets.js +5 -6
- package/dist/plugins/optimize-imports.js +12 -13
- package/dist/plugins/postcss.js +1 -1
- package/dist/plugins/remove-console.js +1 -1
- package/dist/plugins/require-context.js +1 -1
- package/dist/plugins/sass.js +2 -2
- package/dist/plugins/server-externals-manifest.js +1 -1
- package/dist/plugins/strip-server-exports.js +1 -1
- package/dist/plugins/styled-jsx.js +3 -2
- package/dist/plugins/typeof-window.js +1 -1
- package/dist/routing/app-route-graph.d.ts +16 -15
- package/dist/routing/app-route-graph.js +86 -88
- package/dist/routing/app-router.d.ts +0 -5
- package/dist/routing/app-router.js +12 -11
- package/dist/routing/file-matcher.d.ts +13 -28
- package/dist/routing/file-matcher.js +31 -44
- package/dist/routing/pages-router.js +26 -32
- package/dist/routing/route-matching.d.ts +14 -1
- package/dist/routing/route-matching.js +13 -1
- package/dist/routing/route-pattern.d.ts +2 -1
- package/dist/routing/route-pattern.js +7 -4
- package/dist/routing/route-trie.d.ts +5 -1
- package/dist/routing/route-trie.js +5 -2
- package/dist/server/api-handler.js +41 -33
- package/dist/server/app-browser-entry.js +18 -11
- package/dist/server/app-browser-history-controller.d.ts +1 -1
- package/dist/server/app-browser-history-controller.js +3 -3
- package/dist/server/app-browser-navigation-controller.js +4 -2
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-elements-wire.d.ts +2 -1
- package/dist/server/app-fallback-renderer.d.ts +11 -0
- package/dist/server/app-fallback-renderer.js +16 -2
- package/dist/server/app-middleware.js +2 -1
- package/dist/server/app-page-boundary-render.d.ts +26 -2
- package/dist/server/app-page-boundary-render.js +190 -55
- package/dist/server/app-page-cache-finalizer.d.ts +1 -1
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-dispatch.d.ts +12 -2
- package/dist/server/app-page-dispatch.js +37 -51
- package/dist/server/app-page-element-builder.d.ts +8 -2
- package/dist/server/app-page-element-builder.js +112 -27
- package/dist/server/app-page-execution.d.ts +3 -1
- package/dist/server/app-page-execution.js +31 -39
- package/dist/server/app-page-head.d.ts +54 -2
- package/dist/server/app-page-head.js +164 -78
- package/dist/server/app-page-http-access-fallback-metadata.d.ts +29 -0
- package/dist/server/app-page-http-access-fallback-metadata.js +106 -0
- package/dist/server/app-page-render.d.ts +2 -2
- package/dist/server/app-page-render.js +1 -1
- package/dist/server/app-page-request.d.ts +12 -0
- package/dist/server/app-page-request.js +134 -14
- package/dist/server/app-page-route-wiring.d.ts +9 -0
- package/dist/server/app-page-route-wiring.js +44 -4
- package/dist/server/app-post-middleware-context.d.ts +1 -1
- package/dist/server/app-post-middleware-context.js +1 -1
- package/dist/server/app-route-handler-dispatch.js +31 -17
- package/dist/server/app-route-handler-execution.d.ts +6 -1
- package/dist/server/app-route-handler-execution.js +41 -15
- package/dist/server/app-route-handler-policy.d.ts +2 -0
- package/dist/server/app-route-handler-policy.js +3 -3
- package/dist/server/app-route-module-loader.d.ts +3 -1
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-route-tree-prefetch.js +1 -1
- package/dist/server/app-rsc-cache-busting.d.ts +1 -1
- package/dist/server/app-rsc-cache-busting.js +1 -1
- package/dist/server/app-rsc-errors.d.ts +1 -1
- package/dist/server/app-rsc-errors.js +12 -2
- package/dist/server/app-rsc-handler.d.ts +10 -5
- package/dist/server/app-rsc-handler.js +51 -23
- package/dist/server/app-rsc-redirect-flight.d.ts +66 -0
- package/dist/server/app-rsc-redirect-flight.js +71 -0
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +8 -2
- package/dist/server/app-rsc-response-finalizer.d.ts +2 -2
- package/dist/server/app-rsc-response-finalizer.js +5 -11
- package/dist/server/app-rsc-route-matching.d.ts +20 -0
- package/dist/server/app-rsc-route-matching.js +87 -11
- package/dist/server/app-segment-config.js +15 -5
- package/dist/server/app-server-action-execution.d.ts +3 -1
- package/dist/server/app-server-action-execution.js +8 -6
- package/dist/server/app-ssr-entry.js +4 -1
- package/dist/server/app-ssr-stream.d.ts +2 -7
- package/dist/server/app-ssr-stream.js +5 -10
- package/dist/server/cache-proof.js +1 -1
- package/dist/server/config-headers.d.ts +24 -0
- package/dist/server/config-headers.js +52 -0
- package/dist/server/default-global-error-module.d.ts +3 -1
- package/dist/server/default-not-found-module.d.ts +3 -1
- package/dist/server/dev-initial-server-error.d.ts +1 -1
- package/dist/server/dev-lockfile.js +2 -3
- package/dist/server/dev-route-files.js +1 -1
- package/dist/server/dev-server.js +281 -173
- package/dist/server/dev-stack-sourcemap.js +4 -3
- package/dist/server/headers.d.ts +3 -1
- package/dist/server/headers.js +3 -1
- package/dist/server/image-optimization.js +2 -2
- package/dist/server/implicit-tags.js +2 -1
- package/dist/server/instrumentation.js +2 -2
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +1 -1
- package/dist/server/metadata-routes.js +4 -4
- package/dist/server/middleware-matcher-pattern.d.ts +22 -0
- package/dist/server/middleware-matcher-pattern.js +219 -0
- package/dist/server/middleware-matcher.d.ts +2 -7
- package/dist/server/middleware-matcher.js +13 -60
- package/dist/server/middleware-path-to-regexp.d.ts +14 -0
- package/dist/server/middleware-path-to-regexp.js +228 -0
- package/dist/server/middleware-response-headers.js +1 -1
- package/dist/server/middleware-runtime.js +5 -4
- package/dist/server/middleware.d.ts +2 -1
- package/dist/server/middleware.js +3 -2
- package/dist/server/navigation-planner.d.ts +2 -0
- package/dist/server/navigation-planner.js +8 -2
- package/dist/server/next-error-digest.d.ts +9 -24
- package/dist/server/next-error-digest.js +23 -15
- package/dist/server/operation-token.js +1 -1
- package/dist/server/pages-body-parser-config.js +2 -1
- package/dist/server/pages-data-route.d.ts +11 -1
- package/dist/server/pages-data-route.js +16 -1
- package/dist/server/pages-dev-hydration.d.ts +14 -0
- package/dist/server/pages-dev-hydration.js +83 -0
- package/dist/server/pages-dev-module-url.js +2 -2
- package/dist/server/pages-get-initial-props.d.ts +15 -2
- package/dist/server/pages-get-initial-props.js +16 -6
- package/dist/server/pages-node-compat.d.ts +13 -6
- package/dist/server/pages-node-compat.js +44 -45
- package/dist/server/pages-page-data.d.ts +4 -2
- package/dist/server/pages-page-data.js +20 -10
- package/dist/server/pages-page-handler.d.ts +4 -2
- package/dist/server/pages-page-handler.js +74 -43
- package/dist/server/pages-page-response.d.ts +2 -2
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-preview.d.ts +26 -0
- package/dist/server/pages-preview.js +165 -0
- package/dist/server/pages-readiness.d.ts +5 -4
- package/dist/server/pages-readiness.js +4 -2
- package/dist/server/pages-request-pipeline.d.ts +1 -0
- package/dist/server/pages-request-pipeline.js +25 -11
- package/dist/server/pages-router-entry.js +6 -0
- package/dist/server/prerender-route-params.js +2 -2
- package/dist/server/prod-server.d.ts +1 -4
- package/dist/server/prod-server.js +44 -30
- package/dist/server/request-pipeline.d.ts +15 -29
- package/dist/server/request-pipeline.js +25 -60
- package/dist/server/rsc-stream-hints.js +122 -18
- package/dist/server/seed-cache.js +1 -1
- package/dist/server/socket-error-backstop.js +1 -1
- package/dist/server/static-file-cache.js +7 -8
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/app.d.ts +1 -1
- package/dist/shims/cache-request-state.d.ts +27 -1
- package/dist/shims/cache-request-state.js +60 -1
- package/dist/shims/cache-runtime.d.ts +12 -1
- package/dist/shims/cache-runtime.js +22 -7
- package/dist/shims/cache.d.ts +5 -5
- package/dist/shims/cache.js +28 -11
- package/dist/shims/constants.js +1 -1
- package/dist/shims/document.d.ts +42 -83
- package/dist/shims/document.js +62 -53
- package/dist/shims/dynamic.d.ts +5 -25
- package/dist/shims/dynamic.js +29 -8
- package/dist/shims/error-boundary.d.ts +4 -4
- package/dist/shims/error.d.ts +22 -6
- package/dist/shims/error.js +53 -15
- package/dist/shims/fetch-cache.js +13 -4
- package/dist/shims/font-google-base.d.ts +11 -4
- package/dist/shims/font-local.d.ts +10 -3
- package/dist/shims/font-utils.js +1 -1
- package/dist/shims/form.d.ts +1 -1
- package/dist/shims/head.d.ts +13 -2
- package/dist/shims/head.js +6 -6
- package/dist/shims/headers.d.ts +28 -31
- package/dist/shims/headers.js +115 -53
- package/dist/shims/image.d.ts +27 -37
- package/dist/shims/image.js +21 -14
- package/dist/shims/internal/cookie-serialize.d.ts +3 -1
- package/dist/shims/internal/cookie-serialize.js +3 -1
- package/dist/shims/internal/hybrid-client-route-owner.js +3 -1
- package/dist/shims/internal/pages-data-fetch-dedup.js +5 -3
- package/dist/shims/internal/utils.d.ts +3 -3
- package/dist/shims/layout-segment-context.d.ts +1 -1
- package/dist/shims/legacy-image.d.ts +3 -37
- package/dist/shims/legacy-image.js +6 -16
- package/dist/shims/link.d.ts +16 -21
- package/dist/shims/link.js +25 -13
- package/dist/shims/navigation-context-state.d.ts +1 -1
- package/dist/shims/navigation-errors.d.ts +2 -1
- package/dist/shims/navigation-errors.js +9 -13
- package/dist/shims/navigation.d.ts +8 -4
- package/dist/shims/navigation.js +29 -18
- package/dist/shims/next-shims-augmentations.d.ts +1 -0
- package/dist/shims/next-shims-public.d.ts +1 -0
- package/dist/shims/public-shim-map.json.js +103 -0
- package/dist/shims/readonly-url-search-params.d.ts +3 -3
- package/dist/shims/readonly-url-search-params.js +3 -3
- package/dist/shims/request-state-types.d.ts +1 -1
- package/dist/shims/router-state.d.ts +1 -0
- package/dist/shims/router.d.ts +57 -22
- package/dist/shims/router.js +178 -46
- package/dist/shims/script.d.ts +6 -10
- package/dist/shims/script.js +7 -4
- package/dist/shims/server.d.ts +45 -22
- package/dist/shims/server.js +46 -7
- package/dist/shims/slot.d.ts +1 -1
- package/dist/shims/thenable-params.js +1 -1
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/url-safety.d.ts +1 -1
- package/dist/shims/url-safety.js +2 -2
- package/dist/typegen.d.ts +8 -2
- package/dist/typegen.js +84 -25
- package/dist/utils/client-build-manifest.js +2 -2
- package/dist/utils/client-entry-manifest.js +1 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/commonjs-loader.js +3 -3
- package/dist/utils/domain-locale.d.ts +2 -2
- package/dist/utils/external-url.d.ts +5 -0
- package/dist/utils/external-url.js +7 -0
- package/dist/utils/mdx-scan.js +1 -1
- package/dist/utils/path.d.ts +1 -13
- package/dist/utils/path.js +1 -15
- package/dist/utils/plugin-options.d.ts +4 -0
- package/dist/utils/plugin-options.js +8 -0
- package/dist/utils/project.d.ts +0 -6
- package/dist/utils/project.js +2 -8
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.js +1 -1
- package/dist/utils/redirect-digest.d.ts +9 -0
- package/dist/utils/redirect-digest.js +25 -0
- package/dist/utils/regex-safety.d.ts +8 -0
- package/dist/utils/regex-safety.js +737 -0
- package/dist/utils/vinext-root.js +1 -1
- package/dist/utils/vite-version.d.ts +5 -2
- package/dist/utils/vite-version.js +43 -17
- package/package.json +16 -4
- /package/dist/build/google-fonts/{fallback-metrics-data.js → fallback-metrics-data.json.js} +0 -0
- /package/dist/build/google-fonts/{font-data.js → font-data.json.js} +0 -0
- /package/dist/{node_modules/.pnpm/process-ancestry@0.1.0/node_modules → deps/.pnpm/process-ancestry@0.1.0/deps}/process-ancestry/dist/index.js +0 -0
|
@@ -46,8 +46,14 @@ function collectParentParamNames(routeSegments, boundaryPosition) {
|
|
|
46
46
|
}
|
|
47
47
|
return names;
|
|
48
48
|
}
|
|
49
|
-
function getLayoutGenerateStaticParamsBoundary(layoutTreePosition) {
|
|
50
|
-
|
|
49
|
+
function getLayoutGenerateStaticParamsBoundary(routeSegments, layoutTreePosition) {
|
|
50
|
+
let boundary = Math.min((layoutTreePosition ?? 0) - 1, routeSegments.length - 1);
|
|
51
|
+
while (boundary >= 0) {
|
|
52
|
+
const segment = routeSegments[boundary];
|
|
53
|
+
if (!segment.startsWith("@") && !(segment.startsWith("(") && segment.endsWith(")"))) break;
|
|
54
|
+
boundary -= 1;
|
|
55
|
+
}
|
|
56
|
+
return boundary;
|
|
51
57
|
}
|
|
52
58
|
function getParallelParentParamNames(routeParamNames, branch, boundaryPosition) {
|
|
53
59
|
const slotParamNames = branch.paramNames ?? routeParamNames;
|
|
@@ -57,18 +63,20 @@ function getParallelParentParamNames(routeParamNames, branch, boundaryPosition)
|
|
|
57
63
|
return name ? [name] : [];
|
|
58
64
|
}));
|
|
59
65
|
const ownerParamNames = slotParamNames.filter((name) => !branchParamNameSet.has(name));
|
|
60
|
-
return [
|
|
66
|
+
return [.../* @__PURE__ */ new Set([...ownerParamNames, ...branchParamNames])];
|
|
61
67
|
}
|
|
62
68
|
function resolveAppPageGenerateStaticParamsSources(options) {
|
|
63
69
|
const sources = [];
|
|
64
70
|
options.layouts?.forEach((layout, index) => {
|
|
65
71
|
if (typeof layout?.generateStaticParams !== "function") return;
|
|
66
72
|
sources.push({
|
|
73
|
+
chained: true,
|
|
67
74
|
generateStaticParams: layout.generateStaticParams,
|
|
68
|
-
parentParamNames: collectParentParamNames(options.routeSegments, getLayoutGenerateStaticParamsBoundary(options.layoutTreePositions?.[index]))
|
|
75
|
+
parentParamNames: collectParentParamNames(options.routeSegments, getLayoutGenerateStaticParamsBoundary(options.routeSegments, options.layoutTreePositions?.[index]))
|
|
69
76
|
});
|
|
70
77
|
});
|
|
71
78
|
if (typeof options.page?.generateStaticParams === "function") sources.push({
|
|
79
|
+
chained: true,
|
|
72
80
|
generateStaticParams: options.page.generateStaticParams,
|
|
73
81
|
parentParamNames: collectParentParamNames(options.routeSegments, Math.max(0, options.routeSegments.length - 1))
|
|
74
82
|
});
|
|
@@ -76,7 +84,7 @@ function resolveAppPageGenerateStaticParamsSources(options) {
|
|
|
76
84
|
const name = getAppPageSegmentParamName(segment);
|
|
77
85
|
return name ? [name] : [];
|
|
78
86
|
});
|
|
79
|
-
for (const parallelBranch of options.parallelBranches ?? []) {
|
|
87
|
+
for (const [independentChain, parallelBranch] of (options.parallelBranches ?? []).entries()) {
|
|
80
88
|
if (!parallelBranch) continue;
|
|
81
89
|
const slotParamNames = parallelBranch.paramNames ?? routeParamNames;
|
|
82
90
|
const paramAliases = Object.fromEntries(routeParamNames.flatMap((routeParamName, index) => {
|
|
@@ -87,6 +95,7 @@ function resolveAppPageGenerateStaticParamsSources(options) {
|
|
|
87
95
|
if (typeof module?.generateStaticParams !== "function") return;
|
|
88
96
|
sources.push({
|
|
89
97
|
generateStaticParams: module.generateStaticParams,
|
|
98
|
+
independentChain,
|
|
90
99
|
...Object.keys(paramAliases).length > 0 ? { paramAliases } : {},
|
|
91
100
|
...parallelBranch.patternParts ? { paramPatternParts: parallelBranch.patternParts } : {},
|
|
92
101
|
...options.routePatternParts ? { routePatternParts: options.routePatternParts } : {},
|
|
@@ -95,24 +104,101 @@ function resolveAppPageGenerateStaticParamsSources(options) {
|
|
|
95
104
|
};
|
|
96
105
|
addParallelSource(parallelBranch.layout, -1);
|
|
97
106
|
parallelBranch.configLayouts?.forEach((layout, index) => {
|
|
98
|
-
addParallelSource(layout, getLayoutGenerateStaticParamsBoundary(parallelBranch.configLayoutTreePositions?.[index]));
|
|
107
|
+
addParallelSource(layout, getLayoutGenerateStaticParamsBoundary(parallelBranch.routeSegments ?? [], parallelBranch.configLayoutTreePositions?.[index]));
|
|
99
108
|
});
|
|
100
109
|
addParallelSource(parallelBranch.page, Math.max(0, (parallelBranch.routeSegments?.length ?? 0) - 1));
|
|
101
110
|
}
|
|
102
111
|
return sources;
|
|
103
112
|
}
|
|
104
|
-
function areStaticParamsAllowed(params, staticParams) {
|
|
113
|
+
function areStaticParamsAllowed(params, staticParams, allowMissingValues = false) {
|
|
105
114
|
const paramKeys = Object.keys(params);
|
|
115
|
+
const stringParamMatches = (value, staticValue) => value === encodeURIComponent(staticValue);
|
|
106
116
|
return staticParams.some((staticParamSet) => paramKeys.every((key) => {
|
|
107
117
|
const value = params[key];
|
|
108
118
|
const staticValue = staticParamSet[key];
|
|
109
|
-
if (
|
|
110
|
-
if (Array.isArray(value)) return Array.isArray(staticValue) && value.length === staticValue.length && value.every((part, index) => typeof staticValue[index] === "string" ? part
|
|
111
|
-
if (typeof staticValue === "string") return value
|
|
119
|
+
if (!Object.hasOwn(staticParamSet, key)) return allowMissingValues;
|
|
120
|
+
if (Array.isArray(value)) return Array.isArray(staticValue) && value.length === staticValue.length && value.every((part, index) => typeof staticValue[index] === "string" ? stringParamMatches(part, staticValue[index]) : part === staticValue[index]);
|
|
121
|
+
if (typeof staticValue === "string") return stringParamMatches(value, staticValue);
|
|
112
122
|
if (typeof staticValue === "number" || typeof staticValue === "boolean") return String(value) === String(staticValue);
|
|
113
123
|
return JSON.stringify(value) === JSON.stringify(staticValue);
|
|
114
124
|
}));
|
|
115
125
|
}
|
|
126
|
+
function remapStaticParamsToRouteParams(staticParams, source) {
|
|
127
|
+
if (!source.paramAliases) return [...staticParams];
|
|
128
|
+
const routeParamNamesBySourceName = new Map(Object.entries(source.paramAliases).map(([routeParamName, sourceParamName]) => [sourceParamName, routeParamName]));
|
|
129
|
+
return staticParams.map((params) => Object.fromEntries(Object.entries(params).map(([name, value]) => [routeParamNamesBySourceName.get(name) ?? name, value])));
|
|
130
|
+
}
|
|
131
|
+
async function generateIndependentStaticParams(sources, primaryParams, requestParams) {
|
|
132
|
+
let rows = (primaryParams ?? []).map((params) => ({
|
|
133
|
+
params,
|
|
134
|
+
branchParams: {}
|
|
135
|
+
}));
|
|
136
|
+
let hasParentParams = rows.length > 0;
|
|
137
|
+
let validated = false;
|
|
138
|
+
for (const source of sources) {
|
|
139
|
+
const parents = hasParentParams ? rows : [{
|
|
140
|
+
params: {},
|
|
141
|
+
branchParams: {}
|
|
142
|
+
}];
|
|
143
|
+
const nextRows = [];
|
|
144
|
+
for (const parent of parents) {
|
|
145
|
+
const sourceParams = remapRouteParams({
|
|
146
|
+
...requestParams,
|
|
147
|
+
...parent.params
|
|
148
|
+
}, source);
|
|
149
|
+
const branchParams = remapRouteParams(parent.branchParams, source);
|
|
150
|
+
const result = await runWithFetchDedupe(() => source.generateStaticParams({ params: {
|
|
151
|
+
...pickRouteParams(sourceParams, source.parentParamNames),
|
|
152
|
+
...branchParams
|
|
153
|
+
} }));
|
|
154
|
+
if (!Array.isArray(result)) {
|
|
155
|
+
if (hasParentParams) nextRows.push(parent);
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
validated = true;
|
|
159
|
+
const routeResults = remapStaticParamsToRouteParams(result, source);
|
|
160
|
+
if (routeResults.length === 0) {
|
|
161
|
+
if (hasParentParams) nextRows.push(parent);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
for (const routeResult of routeResults) nextRows.push({
|
|
165
|
+
params: {
|
|
166
|
+
...parent.params,
|
|
167
|
+
...routeResult
|
|
168
|
+
},
|
|
169
|
+
branchParams: {
|
|
170
|
+
...parent.branchParams,
|
|
171
|
+
...routeResult
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
rows = nextRows;
|
|
176
|
+
hasParentParams = rows.length > 0;
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
staticParams: rows.map((row) => row.params),
|
|
180
|
+
validated
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
async function generateChainedStaticParams(sources) {
|
|
184
|
+
let generatedParams = [];
|
|
185
|
+
for (const source of sources) {
|
|
186
|
+
const hasParentParams = generatedParams.length > 0;
|
|
187
|
+
const parents = hasParentParams ? generatedParams : [{}];
|
|
188
|
+
const nextParams = [];
|
|
189
|
+
for (const parentParams of parents) {
|
|
190
|
+
const result = await runWithFetchDedupe(() => source.generateStaticParams({ params: parentParams }));
|
|
191
|
+
if (Array.isArray(result) && result.length > 0) {
|
|
192
|
+
for (const item of result) if (item !== null && typeof item === "object" && !Array.isArray(item)) nextParams.push({
|
|
193
|
+
...parentParams,
|
|
194
|
+
...item
|
|
195
|
+
});
|
|
196
|
+
} else if (hasParentParams) nextParams.push(parentParams);
|
|
197
|
+
}
|
|
198
|
+
generatedParams = nextParams;
|
|
199
|
+
}
|
|
200
|
+
return generatedParams;
|
|
201
|
+
}
|
|
116
202
|
function normalizeGenerateStaticParams(generateStaticParams) {
|
|
117
203
|
return (Array.isArray(generateStaticParams) ? generateStaticParams : [generateStaticParams]).flatMap((source) => {
|
|
118
204
|
if (typeof source === "function") return [{
|
|
@@ -130,10 +216,28 @@ async function validateAppPageDynamicParams(options) {
|
|
|
130
216
|
options.clearRequestContext();
|
|
131
217
|
return notFoundResponse();
|
|
132
218
|
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
219
|
+
const chainedSources = generateStaticParamsSources.filter((source) => source.chained);
|
|
220
|
+
let chainedStaticParams = null;
|
|
221
|
+
if (chainedSources.length > 0) chainedStaticParams = await generateChainedStaticParams(chainedSources);
|
|
222
|
+
const independentChains = /* @__PURE__ */ new Map();
|
|
223
|
+
for (const source of generateStaticParamsSources.filter((source) => !source.chained)) {
|
|
224
|
+
const chain = independentChains.get(source.independentChain ?? source) ?? [];
|
|
225
|
+
chain.push(source);
|
|
226
|
+
independentChains.set(source.independentChain ?? source, chain);
|
|
227
|
+
}
|
|
228
|
+
let validatedIndependentResults = false;
|
|
229
|
+
for (const sources of independentChains.values()) {
|
|
230
|
+
const result = await generateIndependentStaticParams(sources, chainedStaticParams, options.params);
|
|
231
|
+
if (result.validated) {
|
|
232
|
+
validatedIndependentResults = true;
|
|
233
|
+
if (!areStaticParamsAllowed(options.params, result.staticParams, true)) {
|
|
234
|
+
options.clearRequestContext();
|
|
235
|
+
return notFoundResponse();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (chainedStaticParams && !validatedIndependentResults) {
|
|
240
|
+
if (!areStaticParamsAllowed(options.params, chainedStaticParams)) {
|
|
137
241
|
options.clearRequestContext();
|
|
138
242
|
return notFoundResponse();
|
|
139
243
|
}
|
|
@@ -187,6 +291,22 @@ async function resolveAppPageInterceptState(options) {
|
|
|
187
291
|
if (loadState) loadState.pageLoading = loading;
|
|
188
292
|
await loading;
|
|
189
293
|
}
|
|
294
|
+
if (loadState?.notFound != null) intercept.notFound = loadState.notFound;
|
|
295
|
+
if (intercept.__loadNotFound && intercept.notFound == null) {
|
|
296
|
+
const loading = loadState?.notFoundLoading ?? intercept.__loadNotFound().then((notFound) => {
|
|
297
|
+
intercept.notFound = notFound;
|
|
298
|
+
if (loadState) {
|
|
299
|
+
loadState.notFound = notFound;
|
|
300
|
+
loadState.notFoundLoading = null;
|
|
301
|
+
}
|
|
302
|
+
return notFound;
|
|
303
|
+
}).catch((error) => {
|
|
304
|
+
if (loadState) loadState.notFoundLoading = null;
|
|
305
|
+
throw error;
|
|
306
|
+
});
|
|
307
|
+
if (loadState) loadState.notFoundLoading = loading;
|
|
308
|
+
await loading;
|
|
309
|
+
}
|
|
190
310
|
if (intercept.__loadInterceptLayouts) await loadAppInterceptLayouts(intercept);
|
|
191
311
|
const sourceRoute = await options.getSourceRoute(intercept.sourceRouteIndex);
|
|
192
312
|
if (!sourceRoute) return { kind: "none" };
|
|
@@ -37,6 +37,8 @@ type AppPageRouteWiringSlot<TModule extends AppPageModule = AppPageModule, TErro
|
|
|
37
37
|
layout?: TModule | null;
|
|
38
38
|
layoutIndex: number;
|
|
39
39
|
loading?: TModule | null;
|
|
40
|
+
notFound?: TModule | null;
|
|
41
|
+
notFoundTreePosition?: number | null;
|
|
40
42
|
page?: TModule | null;
|
|
41
43
|
routeSegments?: readonly string[] | null;
|
|
42
44
|
/**
|
|
@@ -59,9 +61,12 @@ type AppPageRouteWiringRoute<TModule extends AppPageModule = AppPageModule, TErr
|
|
|
59
61
|
loading?: TModule | null;
|
|
60
62
|
notFound?: TModule | null;
|
|
61
63
|
notFounds?: readonly (TModule | null | undefined)[] | null;
|
|
64
|
+
notFoundTreePosition?: number | null;
|
|
62
65
|
forbidden?: TModule | null;
|
|
66
|
+
forbiddenTreePosition?: number | null;
|
|
63
67
|
forbiddens?: readonly (TModule | null | undefined)[] | null;
|
|
64
68
|
unauthorized?: TModule | null;
|
|
69
|
+
unauthorizedTreePosition?: number | null;
|
|
65
70
|
unauthorizeds?: readonly (TModule | null | undefined)[] | null;
|
|
66
71
|
routeSegments?: readonly string[];
|
|
67
72
|
childrenRouteSegments?: readonly string[] | null;
|
|
@@ -124,6 +129,10 @@ type BuildAppPageRouteElementOptions<TModule extends AppPageModule = AppPageModu
|
|
|
124
129
|
resolvedMetadata: Metadata | null;
|
|
125
130
|
resolvedMetadataPathname?: string;
|
|
126
131
|
resolvedViewport: Viewport;
|
|
132
|
+
streamingMetadata?: Promise<Metadata | null> | null;
|
|
133
|
+
streamingMetadataOutlet?: Promise<unknown> | null;
|
|
134
|
+
streamingMetadataOutletSuspended?: boolean;
|
|
135
|
+
streamingMetadataTags?: Promise<Metadata | null> | null;
|
|
127
136
|
trailingSlash?: boolean;
|
|
128
137
|
rootForbiddenModule?: TModule | null;
|
|
129
138
|
rootNotFoundModule?: TModule | null;
|
|
@@ -179,6 +179,37 @@ function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement, t
|
|
|
179
179
|
dangerouslySetInnerHTML: { __html: renderMetadataToHtml(metadata, pathname, { trailingSlash }) }
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
|
+
async function AppPageStreamingMetadata(props) {
|
|
183
|
+
try {
|
|
184
|
+
return createAppPageRouteBodyMetadata(await props.metadata, props.pathname, "body", props.trailingSlash);
|
|
185
|
+
} catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
AppPageStreamingMetadata.displayName = "Vinext.StreamingMetadata";
|
|
190
|
+
async function AppPageMetadataOutlet(props) {
|
|
191
|
+
await props.metadata;
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
AppPageMetadataOutlet.displayName = "Vinext.MetadataOutlet";
|
|
195
|
+
function createAppPageStreamingMetadataOutlet(elementId, suspended = true) {
|
|
196
|
+
if (!elementId) return null;
|
|
197
|
+
const outlet = /* @__PURE__ */ jsx(Slot, { id: elementId });
|
|
198
|
+
return suspended ? /* @__PURE__ */ jsx(Suspense, {
|
|
199
|
+
fallback: null,
|
|
200
|
+
children: outlet
|
|
201
|
+
}) : outlet;
|
|
202
|
+
}
|
|
203
|
+
function createAppPageStreamingMetadataBody(elementId) {
|
|
204
|
+
if (!elementId) return null;
|
|
205
|
+
return /* @__PURE__ */ jsx("div", {
|
|
206
|
+
hidden: true,
|
|
207
|
+
children: /* @__PURE__ */ jsx(Suspense, {
|
|
208
|
+
fallback: null,
|
|
209
|
+
children: /* @__PURE__ */ jsx(Slot, { id: elementId })
|
|
210
|
+
})
|
|
211
|
+
});
|
|
212
|
+
}
|
|
182
213
|
function buildAppPageElements(options) {
|
|
183
214
|
const renderIdentity = options.renderIdentity;
|
|
184
215
|
const interceptionContext = renderIdentity?.interceptionContext ?? options.interceptionContext ?? null;
|
|
@@ -188,6 +219,8 @@ function buildAppPageElements(options) {
|
|
|
188
219
|
const routeId = renderIdentity?.routeId ?? AppElementsWire.encodeRouteId(options.routePath, interceptionContext);
|
|
189
220
|
const pageId = renderIdentity?.pageId ?? AppElementsWire.encodePageId(options.routePath, interceptionContext);
|
|
190
221
|
const pageElementId = options.route.childrenSlot?.id ?? pageId;
|
|
222
|
+
const streamingMetadataBodyId = options.streamingMetadata ? `__vinext_streaming_metadata_body:${routeId}` : null;
|
|
223
|
+
const streamingMetadataOutletId = options.streamingMetadataOutlet ? `__vinext_streaming_metadata_outlet:${routeId}` : null;
|
|
191
224
|
const layoutEntries = createAppPageLayoutEntries(options.route);
|
|
192
225
|
const templateEntries = createAppPageTemplateEntries(options.route);
|
|
193
226
|
const errorEntries = createAppPageErrorEntries(options.route);
|
|
@@ -213,7 +246,7 @@ function buildAppPageElements(options) {
|
|
|
213
246
|
const slotName = slot.name;
|
|
214
247
|
slotNameCounts.set(slotName, (slotNameCounts.get(slotName) ?? 0) + 1);
|
|
215
248
|
}
|
|
216
|
-
const orderedTreePositions = Array.from(new Set([
|
|
249
|
+
const orderedTreePositions = Array.from(/* @__PURE__ */ new Set([
|
|
217
250
|
...layoutEntries.map((entry) => entry.treePosition),
|
|
218
251
|
...templateEntries.map((entry) => entry.treePosition),
|
|
219
252
|
...errorEntries.map((entry) => entry.treePosition)
|
|
@@ -237,6 +270,12 @@ function buildAppPageElements(options) {
|
|
|
237
270
|
})
|
|
238
271
|
}) };
|
|
239
272
|
if (options.route.staticSiblings && options.route.staticSiblings.length > 0) elements[APP_STATIC_SIBLINGS_KEY] = options.route.staticSiblings;
|
|
273
|
+
if (options.streamingMetadata && streamingMetadataBodyId) elements[streamingMetadataBodyId] = /* @__PURE__ */ jsx(AppPageStreamingMetadata, {
|
|
274
|
+
metadata: options.streamingMetadataTags ?? options.streamingMetadata,
|
|
275
|
+
pathname: options.resolvedMetadataPathname ?? options.routePath,
|
|
276
|
+
trailingSlash: options.trailingSlash
|
|
277
|
+
});
|
|
278
|
+
if (options.streamingMetadataOutlet && streamingMetadataOutletId) elements[streamingMetadataOutletId] = /* @__PURE__ */ jsx(AppPageMetadataOutlet, { metadata: options.streamingMetadataOutlet });
|
|
240
279
|
const getEffectiveSlotParams = (slotKey, slotName) => resolveSlotOverride(slotKey, slotName)?.params ?? options.matchedParams;
|
|
241
280
|
for (const treePosition of orderedTreePositions) {
|
|
242
281
|
const layoutIndex = layoutIndicesByTreePosition.get(treePosition);
|
|
@@ -365,11 +404,11 @@ function buildAppPageElements(options) {
|
|
|
365
404
|
});
|
|
366
405
|
elements[slotId] = renderAfterAppDependencies(slotElement, targetIndex >= 0 ? slotDependenciesByLayoutIndex[targetIndex] ?? [] : []);
|
|
367
406
|
}
|
|
368
|
-
let routeChildren = /* @__PURE__ */ jsx(LayoutSegmentProvider, {
|
|
407
|
+
let routeChildren = /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(LayoutSegmentProvider, {
|
|
369
408
|
providerId: pageElementId,
|
|
370
409
|
segmentMap: { children: [APP_PAGE_SEGMENT_KEY] },
|
|
371
410
|
children: /* @__PURE__ */ jsx(Slot, { id: pageElementId })
|
|
372
|
-
});
|
|
411
|
+
}), createAppPageStreamingMetadataOutlet(streamingMetadataOutletId, options.streamingMetadataOutletSuspended)] });
|
|
373
412
|
if (isPrefetchLoadingShell) if (routeLoadingComponent === null) routeChildren = null;
|
|
374
413
|
else routeChildren = /* @__PURE__ */ jsx(routeLoadingComponent, {});
|
|
375
414
|
else {
|
|
@@ -479,7 +518,8 @@ function buildAppPageElements(options) {
|
|
|
479
518
|
elements[routeId] = /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
480
519
|
createAppPageRouteHead(options.resolvedMetadata, options.resolvedViewport, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash),
|
|
481
520
|
routeChildren,
|
|
482
|
-
createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash)
|
|
521
|
+
createAppPageRouteBodyMetadata(options.resolvedMetadata, options.resolvedMetadataPathname ?? options.routePath, metadataPlacement, options.trailingSlash),
|
|
522
|
+
createAppPageStreamingMetadataBody(streamingMetadataBodyId)
|
|
483
523
|
] });
|
|
484
524
|
registerAppElementRenderDependencies(elements, renderDependenciesByElementId);
|
|
485
525
|
return elements;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { normalizeHost, requestContextFromRequest } from "../config/
|
|
1
|
+
import { normalizeHost, requestContextFromRequest } from "../config/request-context.js";
|
|
2
2
|
import { getHeadersContext } from "../shims/headers.js";
|
|
3
3
|
//#region src/server/app-post-middleware-context.ts
|
|
4
4
|
/**
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
2
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
3
3
|
import { reportRequestError } from "./instrumentation.js";
|
|
4
|
-
import { consumeDynamicUsage, getAndClearPendingCookies, getDraftModeCookieHeader, markDynamicUsage, setHeadersAccessPhase } from "../shims/headers.js";
|
|
4
|
+
import { consumeDynamicUsage, getActiveDraftModeState, getAndClearPendingCookies, getDraftModeCookieHeader, isDraftModeRequest, markDynamicUsage, setHeadersAccessPhase } from "../shims/headers.js";
|
|
5
|
+
import { _drainPendingRevalidations } from "../shims/cache-request-state.js";
|
|
5
6
|
import { ensureFetchPatch, getCollectedFetchTags, setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
6
7
|
import { setNavigationContext } from "../shims/navigation-context-state.js";
|
|
7
8
|
import { makeThenableParams } from "../shims/thenable-params.js";
|
|
8
9
|
import "../shims/navigation.js";
|
|
9
10
|
import { buildPageCacheTags } from "./implicit-tags.js";
|
|
10
|
-
import { applyRouteHandlerMiddlewareContext } from "./app-route-handler-response.js";
|
|
11
|
+
import { applyRouteHandlerMiddlewareContext, finalizeRouteHandlerResponse } from "./app-route-handler-response.js";
|
|
11
12
|
import { isKnownDynamicAppRoute, isValidHTTPMethod } from "./app-route-handler-runtime.js";
|
|
12
13
|
import { createStaticGenerationHeadersContext } from "./app-static-generation.js";
|
|
13
14
|
import { getAppRouteHandlerRevalidateSeconds, hasAppRouteHandlerDefaultExport, resolveAppRouteHandlerMethod, shouldReadAppRouteHandlerCache } from "./app-route-handler-policy.js";
|
|
14
|
-
import { executeAppRouteHandler } from "./app-route-handler-execution.js";
|
|
15
|
+
import { applyDraftModeCachePolicy, executeAppRouteHandler } from "./app-route-handler-execution.js";
|
|
15
16
|
import { readAppRouteHandlerCacheResponse } from "./app-route-handler-cache.js";
|
|
16
17
|
import { resolveAppRouteHandlerFetchCacheMode } from "./app-segment-config.js";
|
|
17
18
|
//#region src/server/app-route-handler-dispatch.ts
|
|
@@ -37,7 +38,11 @@ async function runInRouteHandlerRevalidationContext(options, renderFn) {
|
|
|
37
38
|
setCurrentFetchSoftTags(buildRouteHandlerPageCacheTags(options.cleanPathname, [], options.routeSegments));
|
|
38
39
|
setCurrentFetchCacheMode(options.fetchCacheMode);
|
|
39
40
|
setCurrentForceDynamicFetchDefault(options.dynamicConfig === "force-dynamic");
|
|
40
|
-
|
|
41
|
+
try {
|
|
42
|
+
await renderFn();
|
|
43
|
+
} finally {
|
|
44
|
+
await _drainPendingRevalidations();
|
|
45
|
+
}
|
|
41
46
|
});
|
|
42
47
|
}
|
|
43
48
|
async function dispatchAppRouteHandler(options) {
|
|
@@ -47,19 +52,25 @@ async function dispatchAppRouteHandler(options) {
|
|
|
47
52
|
const revalidateSeconds = getAppRouteHandlerRevalidateSeconds(handler);
|
|
48
53
|
const isDevelopment = options.isDevelopment ?? process.env.NODE_ENV === "development";
|
|
49
54
|
const isProduction = options.isProduction ?? process.env.NODE_ENV === "production";
|
|
50
|
-
|
|
51
|
-
|
|
55
|
+
const isDraftMode = getActiveDraftModeState() ?? isDraftModeRequest(options.request, options.draftModeSecret);
|
|
56
|
+
const initialDraftModeCookie = getDraftModeCookieHeader();
|
|
57
|
+
const hasDraftModeTransition = initialDraftModeCookie != null;
|
|
58
|
+
const finalizeFrameworkResponse = (response, isHead = false) => {
|
|
59
|
+
const finalized = finalizeRouteHandlerResponse(response, {
|
|
60
|
+
pendingCookies: getAndClearPendingCookies(),
|
|
61
|
+
draftCookie: initialDraftModeCookie,
|
|
62
|
+
isHead
|
|
63
|
+
});
|
|
52
64
|
options.clearRequestContext();
|
|
53
|
-
return applyRouteHandlerMiddlewareContext(
|
|
54
|
-
}
|
|
65
|
+
return applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(finalized, options.middlewareContext), isDraftMode || hasDraftModeTransition);
|
|
66
|
+
};
|
|
67
|
+
if (hasAppRouteHandlerDefaultExport(handler) && isDevelopment) console.error("[vinext] Detected default export in route handler " + route.pattern + ". Export a named export for each HTTP method instead.");
|
|
68
|
+
if (!isValidHTTPMethod(method)) return finalizeFrameworkResponse(new Response(null, { status: 400 }));
|
|
55
69
|
const { allowHeaderForOptions, handlerFn, isAutoHead, shouldAutoRespondToOptions } = resolveAppRouteHandlerMethod(handler, method);
|
|
56
|
-
if (shouldAutoRespondToOptions) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
headers: { Allow: allowHeaderForOptions }
|
|
61
|
-
}), options.middlewareContext);
|
|
62
|
-
}
|
|
70
|
+
if (shouldAutoRespondToOptions) return finalizeFrameworkResponse(new Response(null, {
|
|
71
|
+
status: 204,
|
|
72
|
+
headers: { Allow: allowHeaderForOptions }
|
|
73
|
+
}));
|
|
63
74
|
const resolvedHandlerFn = isAppRouteHandlerFunction(handlerFn) ? handlerFn : void 0;
|
|
64
75
|
const fetchCacheMode = resolveAppRouteHandlerFetchCacheMode(handler);
|
|
65
76
|
setCurrentFetchCacheMode(fetchCacheMode);
|
|
@@ -69,6 +80,7 @@ async function dispatchAppRouteHandler(options) {
|
|
|
69
80
|
handlerFn: resolvedHandlerFn,
|
|
70
81
|
isAutoHead,
|
|
71
82
|
isKnownDynamic: isKnownDynamicAppRoute(route.pattern),
|
|
83
|
+
isDraftMode: isDraftMode || hasDraftModeTransition,
|
|
72
84
|
isProduction,
|
|
73
85
|
method,
|
|
74
86
|
revalidateSeconds
|
|
@@ -133,12 +145,15 @@ async function dispatchAppRouteHandler(options) {
|
|
|
133
145
|
executionContext: getRequestExecutionContext(),
|
|
134
146
|
getAndClearPendingCookies,
|
|
135
147
|
getCollectedFetchTags,
|
|
148
|
+
getActiveDraftModeState,
|
|
136
149
|
getDraftModeCookieHeader,
|
|
137
150
|
handler,
|
|
138
151
|
handlerFn: resolvedHandlerFn,
|
|
139
152
|
i18n: options.i18n,
|
|
140
153
|
trailingSlash: options.trailingSlash,
|
|
141
154
|
isAutoHead,
|
|
155
|
+
initialDraftModeCookie,
|
|
156
|
+
isDraftMode,
|
|
142
157
|
isProduction,
|
|
143
158
|
isrDebug: options.isrDebug,
|
|
144
159
|
isrRouteKey: options.isrRouteKey,
|
|
@@ -157,8 +172,7 @@ async function dispatchAppRouteHandler(options) {
|
|
|
157
172
|
routePattern: route.pattern,
|
|
158
173
|
setHeadersAccessPhase
|
|
159
174
|
});
|
|
160
|
-
|
|
161
|
-
return applyRouteHandlerMiddlewareContext(new Response(null, { status: 405 }), options.middlewareContext);
|
|
175
|
+
return finalizeFrameworkResponse(new Response(null, { status: 405 }));
|
|
162
176
|
}
|
|
163
177
|
//#endregion
|
|
164
178
|
export { dispatchAppRouteHandler };
|
|
@@ -42,6 +42,7 @@ type RunAppRouteHandlerOptions = {
|
|
|
42
42
|
dynamicConfig?: string;
|
|
43
43
|
handlerFn: AppRouteHandlerFunction;
|
|
44
44
|
i18n?: NextI18nConfig | null;
|
|
45
|
+
isDraftMode?: boolean;
|
|
45
46
|
trailingSlash?: boolean;
|
|
46
47
|
markDynamicUsage: MarkAppRouteDynamicUsageFn;
|
|
47
48
|
middlewareRequestHeaders?: Headers | null;
|
|
@@ -58,6 +59,7 @@ type RunAppRouteHandlerResult = {
|
|
|
58
59
|
dynamicUsedInHandler: boolean;
|
|
59
60
|
response: Response;
|
|
60
61
|
};
|
|
62
|
+
declare function applyDraftModeCachePolicy(response: Response, isDraftMode: boolean): Response;
|
|
61
63
|
type ExecuteAppRouteHandlerOptions = {
|
|
62
64
|
buildPageCacheTags: (pathname: string, extraTags: string[]) => string[];
|
|
63
65
|
clearRequestContext: () => void;
|
|
@@ -65,9 +67,12 @@ type ExecuteAppRouteHandlerOptions = {
|
|
|
65
67
|
executionContext: ExecutionContextLike | null;
|
|
66
68
|
getAndClearPendingCookies: () => string[];
|
|
67
69
|
getCollectedFetchTags: () => string[];
|
|
70
|
+
getActiveDraftModeState?: () => boolean | null;
|
|
68
71
|
getDraftModeCookieHeader: () => string | null | undefined;
|
|
69
72
|
handler: AppRouteHandlerModule;
|
|
70
73
|
isAutoHead: boolean;
|
|
74
|
+
initialDraftModeCookie?: string | null;
|
|
75
|
+
isDraftMode?: boolean;
|
|
71
76
|
isProduction: boolean;
|
|
72
77
|
isrDebug?: AppRouteDebugLogger;
|
|
73
78
|
isrRouteKey: (pathname: string) => string;
|
|
@@ -83,4 +88,4 @@ type ExecuteAppRouteHandlerOptions = {
|
|
|
83
88
|
declare function runAppRouteHandler(options: RunAppRouteHandlerOptions): Promise<RunAppRouteHandlerResult>;
|
|
84
89
|
declare function executeAppRouteHandler(options: ExecuteAppRouteHandlerOptions): Promise<Response>;
|
|
85
90
|
//#endregion
|
|
86
|
-
export { AppRouteDebugLogger, AppRouteDynamicUsageFn, AppRouteHandlerFunction, AppRouteParams, MarkAppRouteDynamicUsageFn, RouteHandlerCacheSetter, executeAppRouteHandler, runAppRouteHandler };
|
|
91
|
+
export { AppRouteDebugLogger, AppRouteDynamicUsageFn, AppRouteHandlerFunction, AppRouteParams, MarkAppRouteDynamicUsageFn, RouteHandlerCacheSetter, applyDraftModeCachePolicy, executeAppRouteHandler, runAppRouteHandler };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { NEVER_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
|
|
1
2
|
import { isDraftModeRequest, setHeadersContext } from "../shims/headers.js";
|
|
3
|
+
import { _drainPendingRevalidations } from "../shims/cache-request-state.js";
|
|
2
4
|
import { isPossibleAppRouteActionRequest } from "./app-action-request.js";
|
|
3
5
|
import { runWithRootParamsUsage } from "../shims/root-params.js";
|
|
4
6
|
import { applyRouteHandlerMiddlewareContext, applyRouteHandlerRevalidateHeader, assertSupportedAppRouteHandlerResponse, buildAppRouteCacheValue, finalizeRouteHandlerResponse, markRouteHandlerCacheMiss } from "./app-route-handler-response.js";
|
|
@@ -6,10 +8,20 @@ import { createTrackedAppRouteRequest, markKnownDynamicAppRoute } from "./app-ro
|
|
|
6
8
|
import { createStaticGenerationHeadersContext, getAppRouteStaticGenerationErrorMessage } from "./app-static-generation.js";
|
|
7
9
|
import { resolveAppRouteHandlerSpecialError, shouldApplyAppRouteHandlerRevalidateHeader, shouldWriteAppRouteHandlerCache } from "./app-route-handler-policy.js";
|
|
8
10
|
//#region src/server/app-route-handler-execution.ts
|
|
11
|
+
function applyDraftModeCachePolicy(response, isDraftMode) {
|
|
12
|
+
if (!isDraftMode) return response;
|
|
13
|
+
const headers = new Headers(response.headers);
|
|
14
|
+
applyCdnResponseHeaders(headers, { cacheControl: NEVER_CACHE_CONTROL });
|
|
15
|
+
return new Response(response.body, {
|
|
16
|
+
status: response.status,
|
|
17
|
+
statusText: response.statusText,
|
|
18
|
+
headers
|
|
19
|
+
});
|
|
20
|
+
}
|
|
9
21
|
function configureAppRouteStaticGenerationContext(options) {
|
|
10
22
|
if (options.dynamicConfig === "force-static" || options.dynamicConfig === "error") {
|
|
11
23
|
setHeadersContext(createStaticGenerationHeadersContext({
|
|
12
|
-
draftModeEnabled: options.draftModeSecret !== void 0 && isDraftModeRequest(options.request, options.draftModeSecret),
|
|
24
|
+
draftModeEnabled: options.isDraftMode ?? (options.draftModeSecret !== void 0 && isDraftModeRequest(options.request, options.draftModeSecret)),
|
|
13
25
|
draftModeSecret: options.draftModeSecret,
|
|
14
26
|
dynamicConfig: options.dynamicConfig,
|
|
15
27
|
routeKind: "route",
|
|
@@ -46,18 +58,30 @@ async function runAppRouteHandler(options) {
|
|
|
46
58
|
async function executeAppRouteHandler(options) {
|
|
47
59
|
const previousHeadersPhase = options.setHeadersAccessPhase("route-handler");
|
|
48
60
|
try {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
61
|
+
let handlerResult;
|
|
62
|
+
try {
|
|
63
|
+
handlerResult = await runAppRouteHandler({
|
|
64
|
+
...options,
|
|
65
|
+
dynamicConfig: options.handler.dynamic
|
|
66
|
+
});
|
|
67
|
+
} finally {
|
|
68
|
+
await _drainPendingRevalidations();
|
|
69
|
+
}
|
|
70
|
+
const { dynamicUsedInHandler, response } = handlerResult;
|
|
53
71
|
assertSupportedAppRouteHandlerResponse(response);
|
|
54
72
|
const handlerSetCacheControl = response.headers.has("cache-control");
|
|
55
73
|
if (dynamicUsedInHandler) markKnownDynamicAppRoute(options.routePattern);
|
|
74
|
+
const pendingCookies = options.getAndClearPendingCookies();
|
|
75
|
+
const handlerDraftCookie = options.getDraftModeCookieHeader();
|
|
76
|
+
const draftCookie = handlerDraftCookie ?? options.initialDraftModeCookie;
|
|
77
|
+
const shouldApplyDraftPolicy = (options.getActiveDraftModeState?.() ?? options.isDraftMode === true) || draftCookie != null;
|
|
78
|
+
if (handlerDraftCookie != null) markKnownDynamicAppRoute(options.routePattern);
|
|
56
79
|
const routeTags = options.buildPageCacheTags(options.cleanPathname, options.getCollectedFetchTags());
|
|
57
80
|
if (shouldApplyAppRouteHandlerRevalidateHeader({
|
|
58
81
|
dynamicUsedInHandler,
|
|
59
82
|
handlerSetCacheControl,
|
|
60
83
|
isAutoHead: options.isAutoHead,
|
|
84
|
+
isDraftMode: shouldApplyDraftPolicy,
|
|
61
85
|
method: options.method,
|
|
62
86
|
revalidateSeconds: options.revalidateSeconds
|
|
63
87
|
})) {
|
|
@@ -70,6 +94,7 @@ async function executeAppRouteHandler(options) {
|
|
|
70
94
|
dynamicUsedInHandler,
|
|
71
95
|
handlerSetCacheControl,
|
|
72
96
|
isAutoHead: options.isAutoHead,
|
|
97
|
+
isDraftMode: shouldApplyDraftPolicy,
|
|
73
98
|
isProduction: options.isProduction,
|
|
74
99
|
method: options.method,
|
|
75
100
|
revalidateSeconds: options.revalidateSeconds
|
|
@@ -90,29 +115,30 @@ async function executeAppRouteHandler(options) {
|
|
|
90
115
|
})();
|
|
91
116
|
options.executionContext?.waitUntil(routeWritePromise);
|
|
92
117
|
}
|
|
93
|
-
const pendingCookies = options.getAndClearPendingCookies();
|
|
94
|
-
const draftCookie = options.getDraftModeCookieHeader();
|
|
95
118
|
options.clearRequestContext();
|
|
96
|
-
return applyRouteHandlerMiddlewareContext(finalizeRouteHandlerResponse(response, {
|
|
119
|
+
return applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(finalizeRouteHandlerResponse(response, {
|
|
97
120
|
pendingCookies,
|
|
98
121
|
draftCookie,
|
|
99
122
|
isHead: options.isAutoHead
|
|
100
|
-
}), options.middlewareContext);
|
|
123
|
+
}), options.middlewareContext), shouldApplyDraftPolicy);
|
|
101
124
|
} catch (error) {
|
|
102
125
|
const pendingCookies = options.getAndClearPendingCookies();
|
|
103
|
-
const
|
|
126
|
+
const handlerDraftCookie = options.getDraftModeCookieHeader();
|
|
127
|
+
const draftCookie = handlerDraftCookie ?? options.initialDraftModeCookie;
|
|
128
|
+
const shouldApplyDraftPolicy = (options.getActiveDraftModeState?.() ?? options.isDraftMode === true) || draftCookie != null;
|
|
129
|
+
if (handlerDraftCookie != null) markKnownDynamicAppRoute(options.routePattern);
|
|
104
130
|
const specialError = resolveAppRouteHandlerSpecialError(error, options.request.url, { isAction: isPossibleAppRouteActionRequest(options.request) });
|
|
105
131
|
options.clearRequestContext();
|
|
106
132
|
if (specialError) {
|
|
107
|
-
if (specialError.kind === "redirect") return applyRouteHandlerMiddlewareContext(finalizeRouteHandlerResponse(new Response(null, {
|
|
133
|
+
if (specialError.kind === "redirect") return applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(finalizeRouteHandlerResponse(new Response(null, {
|
|
108
134
|
status: specialError.statusCode,
|
|
109
135
|
headers: { Location: specialError.location }
|
|
110
136
|
}), {
|
|
111
137
|
pendingCookies,
|
|
112
138
|
draftCookie,
|
|
113
139
|
isHead: options.isAutoHead
|
|
114
|
-
}), options.middlewareContext);
|
|
115
|
-
return applyRouteHandlerMiddlewareContext(new Response(null, { status: specialError.statusCode }), options.middlewareContext);
|
|
140
|
+
}), options.middlewareContext), shouldApplyDraftPolicy);
|
|
141
|
+
return applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(new Response(null, { status: specialError.statusCode }), options.middlewareContext), shouldApplyDraftPolicy);
|
|
116
142
|
}
|
|
117
143
|
console.error("[vinext] Route handler error:", error);
|
|
118
144
|
options.reportRequestError(error instanceof Error ? error : new Error(String(error)), {
|
|
@@ -124,10 +150,10 @@ async function executeAppRouteHandler(options) {
|
|
|
124
150
|
routePath: options.routePattern,
|
|
125
151
|
routeType: "route"
|
|
126
152
|
});
|
|
127
|
-
return applyRouteHandlerMiddlewareContext(new Response(null, { status: 500 }), options.middlewareContext);
|
|
153
|
+
return applyDraftModeCachePolicy(applyRouteHandlerMiddlewareContext(new Response(null, { status: 500 }), options.middlewareContext), shouldApplyDraftPolicy);
|
|
128
154
|
} finally {
|
|
129
155
|
options.setHeadersAccessPhase(previousHeadersPhase);
|
|
130
156
|
}
|
|
131
157
|
}
|
|
132
158
|
//#endregion
|
|
133
|
-
export { executeAppRouteHandler, runAppRouteHandler };
|
|
159
|
+
export { applyDraftModeCachePolicy, executeAppRouteHandler, runAppRouteHandler };
|
|
@@ -20,6 +20,7 @@ type AppRouteHandlerCacheReadOptions = {
|
|
|
20
20
|
handlerFn: unknown;
|
|
21
21
|
isAutoHead: boolean;
|
|
22
22
|
isKnownDynamic: boolean;
|
|
23
|
+
isDraftMode?: boolean;
|
|
23
24
|
isProduction: boolean;
|
|
24
25
|
method: string;
|
|
25
26
|
revalidateSeconds: number | null;
|
|
@@ -29,6 +30,7 @@ type AppRouteHandlerResponseCacheOptions = {
|
|
|
29
30
|
dynamicUsedInHandler: boolean;
|
|
30
31
|
handlerSetCacheControl: boolean;
|
|
31
32
|
isAutoHead: boolean;
|
|
33
|
+
isDraftMode?: boolean;
|
|
32
34
|
isProduction: boolean;
|
|
33
35
|
method: string;
|
|
34
36
|
revalidateSeconds: number | null;
|
|
@@ -30,13 +30,13 @@ function resolveAppRouteHandlerMethod(handler, method) {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
function shouldReadAppRouteHandlerCache(options) {
|
|
33
|
-
return options.isProduction && options.revalidateSeconds !== null && options.revalidateSeconds > 0 && options.revalidateSeconds !== Infinity && options.dynamicConfig !== "force-dynamic" && !options.isKnownDynamic && (options.method === "GET" || options.isAutoHead) && typeof options.handlerFn === "function";
|
|
33
|
+
return options.isProduction && options.revalidateSeconds !== null && options.revalidateSeconds > 0 && options.revalidateSeconds !== Infinity && options.dynamicConfig !== "force-dynamic" && !options.isDraftMode && !options.isKnownDynamic && (options.method === "GET" || options.isAutoHead) && typeof options.handlerFn === "function";
|
|
34
34
|
}
|
|
35
35
|
function shouldApplyAppRouteHandlerRevalidateHeader(options) {
|
|
36
|
-
return options.revalidateSeconds !== null && !options.dynamicUsedInHandler && (options.method === "GET" || options.isAutoHead) && !options.handlerSetCacheControl;
|
|
36
|
+
return options.revalidateSeconds !== null && !options.isDraftMode && !options.dynamicUsedInHandler && (options.method === "GET" || options.isAutoHead) && !options.handlerSetCacheControl;
|
|
37
37
|
}
|
|
38
38
|
function shouldWriteAppRouteHandlerCache(options) {
|
|
39
|
-
return options.isProduction && options.revalidateSeconds !== null && options.revalidateSeconds > 0 && options.revalidateSeconds !== Infinity && options.dynamicConfig !== "force-dynamic" && shouldApplyAppRouteHandlerRevalidateHeader(options);
|
|
39
|
+
return options.isProduction && options.revalidateSeconds !== null && options.revalidateSeconds > 0 && options.revalidateSeconds !== Infinity && options.dynamicConfig !== "force-dynamic" && !options.isDraftMode && shouldApplyAppRouteHandlerRevalidateHeader(options);
|
|
40
40
|
}
|
|
41
41
|
function resolveAppRouteHandlerSpecialError(error, requestUrl, options) {
|
|
42
42
|
if (!(error && typeof error === "object" && "digest" in error)) return null;
|