vinext 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -9
- package/dist/build/client-build-config.d.ts +10 -0
- package/dist/build/client-build-config.js +18 -2
- package/dist/build/pages-client-assets-module.d.ts +8 -0
- package/dist/build/pages-client-assets-module.js +21 -1
- package/dist/build/prerender-paths.js +5 -3
- package/dist/build/run-prerender.js +1 -1
- package/dist/build/ssr-manifest.d.ts +2 -0
- package/dist/build/ssr-manifest.js +6 -2
- package/dist/check.js +7 -6
- package/dist/cli.js +2 -1
- package/dist/client/client-redirect-matcher.d.ts +14 -0
- package/dist/client/client-redirect-matcher.js +37 -0
- package/dist/client/client-redirects.d.ts +27 -0
- package/dist/client/client-redirects.js +28 -0
- package/dist/client/client-rewrites.d.ts +2 -1
- package/dist/client/client-rewrites.js +1 -1
- package/dist/config/config-matchers.d.ts +26 -11
- package/dist/config/config-matchers.js +78 -81
- package/dist/config/destination-params.d.ts +47 -0
- package/dist/config/destination-params.js +116 -0
- package/dist/config/next-config.d.ts +7 -0
- package/dist/config/next-config.js +3 -0
- package/dist/entries/app-rsc-entry.d.ts +4 -0
- package/dist/entries/app-rsc-entry.js +20 -6
- package/dist/entries/pages-client-entry.js +3 -1
- package/dist/entries/pages-server-entry.js +13 -37
- package/dist/index.d.ts +3 -1
- package/dist/index.js +134 -43
- package/dist/init-cloudflare.d.ts +9 -0
- package/dist/init-cloudflare.js +107 -31
- package/dist/init-platform.d.ts +4 -0
- package/dist/init-platform.js +27 -2
- package/dist/init.d.ts +1 -0
- package/dist/init.js +67 -3
- package/dist/plugins/ast-scope.d.ts +7 -0
- package/dist/plugins/ast-scope.js +59 -3
- package/dist/plugins/cache-flight-codec.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +9 -8
- package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +3 -4
- package/dist/plugins/middleware-server-only.d.ts +5 -4
- package/dist/plugins/middleware-server-only.js +8 -5
- package/dist/plugins/pages-node-externals.js +1 -1
- package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
- package/dist/plugins/rsc-scan-glob-imports.js +50 -0
- package/dist/plugins/strip-server-exports.js +262 -98
- package/dist/plugins/transform-result.d.ts +9 -5
- package/dist/plugins/transitive-externals.js +1 -1
- package/dist/plugins/typeof-window.d.ts +2 -2
- package/dist/plugins/use-cache-callable.js +8 -2
- package/dist/plugins/worker-server-only-imports.d.ts +20 -0
- package/dist/plugins/worker-server-only-imports.js +31 -0
- package/dist/plugins/worker-use-server.d.ts +25 -0
- package/dist/plugins/worker-use-server.js +129 -0
- package/dist/server/api-handler.d.ts +1 -0
- package/dist/server/api-handler.js +2 -1
- package/dist/server/app-browser-action-result.d.ts +1 -1
- package/dist/server/app-browser-action-result.js +9 -2
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-middleware.d.ts +11 -0
- package/dist/server/app-middleware.js +17 -2
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-cache.js +1 -1
- package/dist/server/app-page-dispatch.d.ts +3 -1
- package/dist/server/app-page-dispatch.js +4 -3
- package/dist/server/app-page-ppr-runtime.js +1 -1
- package/dist/server/app-page-render-observation.js +1 -1
- package/dist/server/app-page-request.js +53 -15
- package/dist/server/app-page-route-wiring.js +2 -2
- package/dist/server/app-pages-bridge.d.ts +1 -1
- package/dist/server/app-pages-bridge.js +2 -3
- package/dist/server/app-prerender-endpoints.js +9 -6
- package/dist/server/app-request-stage-dispatch.js +6 -2
- package/dist/server/app-request-stage-independent-entry.js +25 -5
- package/dist/server/app-response-stage-entry.js +10 -2
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +5 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-runtime.d.ts +4 -1
- package/dist/server/app-route-handler-runtime.js +45 -24
- package/dist/server/app-router-entry.js +24 -5
- package/dist/server/app-rsc-cache-busting.js +1 -1
- package/dist/server/app-rsc-errors.js +20 -16
- package/dist/server/app-rsc-handler.d.ts +7 -0
- package/dist/server/app-rsc-handler.js +85 -35
- package/dist/server/app-rsc-response-stage.js +4 -2
- package/dist/server/app-segment-config.d.ts +2 -1
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +61 -22
- package/dist/server/app-ssr-entry.js +2 -1
- package/dist/server/app-worker-stages.d.ts +5 -0
- package/dist/server/app-worker-stages.js +1 -1
- package/dist/server/cacheability-request.js +2 -2
- package/dist/server/client-build-files.d.ts +16 -0
- package/dist/server/client-build-files.js +36 -0
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/dev-server.js +38 -27
- package/dist/server/dev-stack-sourcemap.js +18 -23
- package/dist/server/document-initial-head.d.ts +0 -11
- package/dist/server/document-initial-head.js +1 -1
- package/dist/server/forwarded-middleware-context.d.ts +5 -0
- package/dist/server/forwarded-middleware-context.js +22 -0
- package/dist/server/headers.d.ts +4 -1
- package/dist/server/headers.js +4 -1
- package/dist/server/http-conditional.d.ts +11 -0
- package/dist/server/http-conditional.js +10 -1
- package/dist/server/http-error-responses.d.ts +1 -1
- package/dist/server/image-optimization.d.ts +38 -0
- package/dist/server/image-optimization.js +93 -4
- package/dist/server/isr-cache.d.ts +10 -0
- package/dist/server/isr-cache.js +41 -6
- package/dist/server/metadata-route-response.js +9 -8
- package/dist/server/middleware-matcher.d.ts +2 -0
- package/dist/server/middleware-matcher.js +23 -2
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +33 -20
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +3 -1
- package/dist/server/multi-stage.d.ts +11 -0
- package/dist/server/normalize-path.d.ts +0 -13
- package/dist/server/normalize-path.js +1 -34
- package/dist/server/pages-api-route.d.ts +3 -2
- package/dist/server/pages-api-route.js +4 -3
- package/dist/server/pages-cache-tag.d.ts +12 -0
- package/dist/server/pages-cache-tag.js +19 -0
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-data-route.d.ts +10 -0
- package/dist/server/pages-data-route.js +19 -2
- package/dist/server/pages-document-asset-props.d.ts +5 -1
- package/dist/server/pages-document-asset-props.js +13 -5
- package/dist/server/pages-document-splice.d.ts +19 -0
- package/dist/server/pages-document-splice.js +55 -0
- package/dist/server/pages-i18n.d.ts +12 -1
- package/dist/server/pages-i18n.js +18 -4
- package/dist/server/pages-node-compat.d.ts +16 -5
- package/dist/server/pages-node-compat.js +20 -12
- package/dist/server/pages-page-data.d.ts +32 -24
- package/dist/server/pages-page-data.js +50 -120
- package/dist/server/pages-page-handler.d.ts +0 -6
- package/dist/server/pages-page-handler.js +188 -126
- package/dist/server/pages-page-response.d.ts +12 -6
- package/dist/server/pages-page-response.js +41 -34
- package/dist/server/pages-request-pipeline.d.ts +10 -2
- package/dist/server/pages-request-pipeline.js +37 -18
- package/dist/server/pages-request-stage-entry.d.ts +6 -0
- package/dist/server/pages-request-stage-entry.js +71 -12
- package/dist/server/pages-response-stage-entry.js +4 -0
- package/dist/server/pages-revalidate.js +1 -1
- package/dist/server/pages-router-entry.js +4 -3
- package/dist/server/prerender-manifest.d.ts +3 -3
- package/dist/server/prerender-manifest.js +4 -3
- package/dist/server/prerender-work-unit-setup.js +4 -0
- package/dist/server/prod-server.d.ts +12 -0
- package/dist/server/prod-server.js +199 -69
- package/dist/server/proper-error.d.ts +4 -0
- package/dist/server/proper-error.js +31 -0
- package/dist/server/request-pipeline.d.ts +4 -1
- package/dist/server/request-pipeline.js +3 -2
- package/dist/server/revalidation-request.d.ts +1 -0
- package/dist/server/revalidation-request.js +1 -1
- package/dist/server/rsc-stream-hints.js +31 -2
- package/dist/server/seed-cache.d.ts +1 -0
- package/dist/server/seed-cache.js +5 -4
- package/dist/server/server-reference-loader.d.ts +4 -0
- package/dist/server/server-reference-loader.js +29 -0
- package/dist/server/socket-error-backstop.d.ts +9 -1
- package/dist/server/socket-error-backstop.js +46 -17
- package/dist/server/static-file-signal.d.ts +15 -4
- package/dist/server/static-file-signal.js +46 -12
- package/dist/server/worker-image-optimization.d.ts +34 -0
- package/dist/server/worker-image-optimization.js +86 -0
- package/dist/server/worker-stages.d.ts +1 -1
- package/dist/server/worker-stages.js +2 -2
- package/dist/server/worker-utils.d.ts +8 -3
- package/dist/server/worker-utils.js +12 -7
- package/dist/shims/app-router-scroll.js +4 -1
- package/dist/shims/app-router-tree-context.d.ts +5 -0
- package/dist/shims/app-router-tree-context.js +27 -0
- package/dist/shims/cache-callable-runtime.d.ts +4 -2
- package/dist/shims/cache-callable-runtime.js +21 -12
- package/dist/shims/cache-handler.js +1 -9
- package/dist/shims/cache-runtime.d.ts +6 -1
- package/dist/shims/cache-runtime.js +2 -1
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +40 -13
- package/dist/shims/cdn-cache.d.ts +8 -0
- package/dist/shims/cdn-cache.js +17 -1
- package/dist/shims/disable-smooth-scroll.d.ts +3 -0
- package/dist/shims/disable-smooth-scroll.js +36 -0
- package/dist/shims/document-placeholders.d.ts +19 -0
- package/dist/shims/document-placeholders.js +45 -0
- package/dist/shims/document.js +21 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
- package/dist/shims/dynamic-preload-chunks.js +13 -9
- package/dist/shims/dynamic.d.ts +1 -1
- package/dist/shims/dynamic.js +60 -8
- package/dist/shims/fetch-cache-state.d.ts +66 -0
- package/dist/shims/fetch-cache-state.js +92 -0
- package/dist/shims/fetch-cache.d.ts +3 -67
- package/dist/shims/fetch-cache.js +160 -125
- package/dist/shims/head.d.ts +10 -6
- package/dist/shims/head.js +15 -13
- package/dist/shims/image.js +2 -1
- package/dist/shims/internal/work-store-scope.d.ts +5 -0
- package/dist/shims/internal/work-store-scope.js +24 -0
- package/dist/shims/navigation.js +31 -5
- package/dist/shims/request-context.d.ts +2 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/router.js +12 -20
- package/dist/shims/server.d.ts +16 -0
- package/dist/shims/server.js +24 -4
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/url-utils.d.ts +2 -0
- package/dist/shims/url-utils.js +3 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/hash.d.ts +7 -0
- package/dist/utils/hash.js +11 -1
- package/dist/utils/package-name.d.ts +6 -0
- package/dist/utils/package-name.js +12 -1
- package/dist/utils/plugin-rsc-version.d.ts +4 -0
- package/dist/utils/plugin-rsc-version.js +15 -0
- package/dist/utils/prerender-output-paths.js +15 -4
- package/dist/utils/public-file-path.d.ts +10 -2
- package/dist/utils/public-file-path.js +13 -9
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.d.ts +3 -0
- package/dist/utils/react-version.js +1 -1
- package/package.json +7 -3
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Plugin } from "vite";
|
|
2
|
+
//#region src/plugins/worker-use-server.d.ts
|
|
3
|
+
type RscPluginModule = typeof import("@vitejs/plugin-rsc");
|
|
4
|
+
/**
|
|
5
|
+
* Replace `"use server"` modules in browser Web Worker bundles with Server
|
|
6
|
+
* Function reference proxies.
|
|
7
|
+
*
|
|
8
|
+
* Vite bundles every worker in a fresh plugin container built from
|
|
9
|
+
* `worker.plugins`, so @vitejs/plugin-rsc's `rsc:use-server` transform never
|
|
10
|
+
* sees worker modules in production builds and the module bodies would be
|
|
11
|
+
* emitted verbatim. Next.js compiles workers as part of the browser graph,
|
|
12
|
+
* where `"use server"` exports become `createServerReference(...)` proxies.
|
|
13
|
+
* This mirrors the client-environment branch of `rsc:use-server` with the
|
|
14
|
+
* same reference keys, without claiming references.
|
|
15
|
+
*
|
|
16
|
+
* The worker realm has no router to dispatch Server Function calls. Next.js's
|
|
17
|
+
* `callServer` dispatches inside `startTransition`, so the dispatch error is
|
|
18
|
+
* reported globally and the call's promise never settles; the worker
|
|
19
|
+
* references reproduce that instead of reaching the server.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createWorkerUseServerPlugins(options: {
|
|
22
|
+
rscPluginModule: Promise<RscPluginModule>;
|
|
23
|
+
rscPluginPath: string;
|
|
24
|
+
}): Promise<Plugin[]>;
|
|
25
|
+
//#endregion
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import path, { toSlash } from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
|
+
import { escapeRegExp } from "../utils/regex.js";
|
|
3
|
+
import { magicStringTransformResult } from "./transform-result.js";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import { pathToFileURL } from "node:url";
|
|
7
|
+
import { parseAstAsync, transformWithOxc } from "vite";
|
|
8
|
+
//#region src/plugins/worker-use-server.ts
|
|
9
|
+
const WORKER_REFERENCE_RUNTIME_ID = "\0vinext:worker-server-reference";
|
|
10
|
+
const WORKER_REFERENCE_RUNTIME_ID_RE = /^\0vinext:worker-server-reference$/;
|
|
11
|
+
function workerReferenceRuntime(browserRuntime) {
|
|
12
|
+
return `import { createServerReference } from ${JSON.stringify(browserRuntime)};
|
|
13
|
+
|
|
14
|
+
function callServer() {
|
|
15
|
+
return new Promise(() => {
|
|
16
|
+
reportError(new Error("Server Functions cannot be called from a browser Web Worker."));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function createWorkerServerReference(id, name) {
|
|
21
|
+
return createServerReference(id, callServer, undefined, undefined, name);
|
|
22
|
+
}
|
|
23
|
+
`;
|
|
24
|
+
}
|
|
25
|
+
/** A module-local binding that cannot collide with any name in `code`. */
|
|
26
|
+
function uniqueBinding(code, base) {
|
|
27
|
+
let binding = base;
|
|
28
|
+
while (code.includes(binding)) binding += "_";
|
|
29
|
+
return binding;
|
|
30
|
+
}
|
|
31
|
+
function isPlainFilePath(id) {
|
|
32
|
+
return !/[\0?#]/.test(id) && fs.existsSync(id);
|
|
33
|
+
}
|
|
34
|
+
function withPositionedError(ctx, run) {
|
|
35
|
+
return Promise.resolve().then(run).catch((error) => {
|
|
36
|
+
if (error instanceof Error && "pos" in error && typeof error.pos === "number") ctx.error(error.message, error.pos);
|
|
37
|
+
throw error;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Replace `"use server"` modules in browser Web Worker bundles with Server
|
|
42
|
+
* Function reference proxies.
|
|
43
|
+
*
|
|
44
|
+
* Vite bundles every worker in a fresh plugin container built from
|
|
45
|
+
* `worker.plugins`, so @vitejs/plugin-rsc's `rsc:use-server` transform never
|
|
46
|
+
* sees worker modules in production builds and the module bodies would be
|
|
47
|
+
* emitted verbatim. Next.js compiles workers as part of the browser graph,
|
|
48
|
+
* where `"use server"` exports become `createServerReference(...)` proxies.
|
|
49
|
+
* This mirrors the client-environment branch of `rsc:use-server` with the
|
|
50
|
+
* same reference keys, without claiming references.
|
|
51
|
+
*
|
|
52
|
+
* The worker realm has no router to dispatch Server Function calls. Next.js's
|
|
53
|
+
* `callServer` dispatches inside `startTransition`, so the dispatch error is
|
|
54
|
+
* reported globally and the call's promise never settles; the worker
|
|
55
|
+
* references reproduce that instead of reaching the server.
|
|
56
|
+
*/
|
|
57
|
+
async function createWorkerUseServerPlugins(options) {
|
|
58
|
+
const rscRequire = createRequire(options.rscPluginPath);
|
|
59
|
+
const importRscModule = (specifier) => import(pathToFileURL(rscRequire.resolve(specifier)).href);
|
|
60
|
+
const browserRuntime = pathToFileURL(rscRequire.resolve("@vitejs/plugin-rsc/react/browser")).href;
|
|
61
|
+
const [transforms, rscCore] = await Promise.all([importRscModule("@vitejs/plugin-rsc/transforms"), importRscModule("@vitejs/plugin-rsc/core/plugin")]);
|
|
62
|
+
let manager;
|
|
63
|
+
const useServerPlugin = {
|
|
64
|
+
name: "vinext:worker-use-server",
|
|
65
|
+
async configResolved(config) {
|
|
66
|
+
// @vitejs/plugin-rsc's plugin API (and its reference manager) lives.
|
|
67
|
+
const mainConfig = config.mainConfig;
|
|
68
|
+
manager = (await options.rscPluginModule).getPluginApi(mainConfig ?? config)?.manager;
|
|
69
|
+
},
|
|
70
|
+
resolveId: {
|
|
71
|
+
filter: { id: WORKER_REFERENCE_RUNTIME_ID_RE },
|
|
72
|
+
handler: (source) => source
|
|
73
|
+
},
|
|
74
|
+
load: {
|
|
75
|
+
filter: { id: WORKER_REFERENCE_RUNTIME_ID_RE },
|
|
76
|
+
handler: () => workerReferenceRuntime(browserRuntime)
|
|
77
|
+
},
|
|
78
|
+
transform: {
|
|
79
|
+
filter: { code: "use server" },
|
|
80
|
+
async handler(code, id) {
|
|
81
|
+
let ast = await parseAstAsync(code);
|
|
82
|
+
if (!transforms.hasDirective(ast.body, "use server")) return null;
|
|
83
|
+
if (!manager) throw new Error("vinext: cannot compile a \"use server\" module in a Web Worker without @vitejs/plugin-rsc.");
|
|
84
|
+
const expanded = await withPositionedError(this, () => transforms.transformExpandExportAll({
|
|
85
|
+
code,
|
|
86
|
+
ast,
|
|
87
|
+
importer: id,
|
|
88
|
+
resolve: async (source, importer) => (await this.resolve(source, importer))?.id,
|
|
89
|
+
load: async (target) => {
|
|
90
|
+
if (!isPlainFilePath(target)) throw new Error(`vinext: a "use server" module imported by a Web Worker cannot \`export *\` from ${JSON.stringify(target)}; re-export its names explicitly.`);
|
|
91
|
+
this.addWatchFile(target);
|
|
92
|
+
const source = await fs.promises.readFile(target, "utf-8");
|
|
93
|
+
return parseAstAsync((await transformWithOxc(source, target, { sourcemap: false })).code);
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
if (expanded) {
|
|
97
|
+
code = expanded.code;
|
|
98
|
+
ast = await parseAstAsync(code);
|
|
99
|
+
}
|
|
100
|
+
const { referenceKey } = manager.serverReferences.resolve(id, "rsc");
|
|
101
|
+
const runtime = uniqueBinding(code, "$$vinextWorkerReference");
|
|
102
|
+
const result = await withPositionedError(this, () => transforms.transformDirectiveProxyExport(ast, {
|
|
103
|
+
code,
|
|
104
|
+
directive: "use server",
|
|
105
|
+
rejectNonAsyncFunction: true,
|
|
106
|
+
runtime: (name) => `${runtime}(${JSON.stringify(`${referenceKey}#${name}`)}, ${JSON.stringify(name)})`
|
|
107
|
+
}));
|
|
108
|
+
if (!result?.output.hasChanged()) return null;
|
|
109
|
+
result.output.prepend(`import { createWorkerServerReference as ${runtime} } from ${JSON.stringify(WORKER_REFERENCE_RUNTIME_ID)};\n`);
|
|
110
|
+
return magicStringTransformResult(result.output);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const patchHook = rscCore.default().find((plugin) => plugin.name === "rsc:patch-react-server-dom-webpack")?.transform;
|
|
115
|
+
if (!patchHook || typeof patchHook !== "object") throw new Error("vinext: @vitejs/plugin-rsc no longer exposes its Flight client patch plugin.");
|
|
116
|
+
const flightClientDir = path.dirname(rscRequire.resolve("@vitejs/plugin-rsc/vendor/react-server-dom/client.browser"));
|
|
117
|
+
return [{
|
|
118
|
+
name: "vinext:worker-patch-react-server-dom",
|
|
119
|
+
transform: {
|
|
120
|
+
filter: {
|
|
121
|
+
id: new RegExp(`^${escapeRegExp(`${toSlash(flightClientDir)}/`)}`),
|
|
122
|
+
code: "__webpack_require__"
|
|
123
|
+
},
|
|
124
|
+
handler: patchHook.handler
|
|
125
|
+
}
|
|
126
|
+
}, useServerPlugin];
|
|
127
|
+
}
|
|
128
|
+
//#endregion
|
|
129
|
+
export { createWorkerUseServerPlugins };
|
|
@@ -13,5 +13,6 @@ export declare function handleApiRoute(runner: ModuleImporter, req: IncomingMess
|
|
|
13
13
|
trustedRevalidateOrigin?: string;
|
|
14
14
|
allowedRevalidateHeaderKeys?: readonly string[];
|
|
15
15
|
trailingSlash?: boolean;
|
|
16
|
+
skipTrailingSlashRedirect?: boolean;
|
|
16
17
|
}): Promise<boolean>;
|
|
17
18
|
//#endregion
|
|
@@ -237,7 +237,8 @@ async function handleApiRoute(runner, req, res, url, apiRoutes, nextConfig) {
|
|
|
237
237
|
const nextRequest = new NextRequest(createEdgeApiRequest(req, res, url, params, nextConfig), nextConfig ? { nextConfig: {
|
|
238
238
|
basePath: nextConfig.basePath,
|
|
239
239
|
i18n: nextConfig.i18n ?? void 0,
|
|
240
|
-
trailingSlash: nextConfig.trailingSlash
|
|
240
|
+
trailingSlash: nextConfig.trailingSlash,
|
|
241
|
+
skipTrailingSlashRedirect: nextConfig.skipTrailingSlashRedirect
|
|
241
242
|
} } : void 0);
|
|
242
243
|
const handlerResponse = await tracePagesApiHandler(route.pattern, () => apiModule.default(nextRequest));
|
|
243
244
|
if (!(handlerResponse instanceof Response)) throw new Error("Edge API route did not return a Response");
|
|
@@ -25,7 +25,7 @@ export declare function isServerActionResult<TRoot>(value: unknown): value is Ap
|
|
|
25
25
|
export declare function shouldClearClientNavigationCachesForServerActionResult<TRoot>(result: AppBrowserServerActionResult<TRoot> | TRoot, revalidation?: ServerActionRevalidationKind): boolean;
|
|
26
26
|
export declare function parseServerActionRevalidationHeader(headers: Pick<Headers, "get">): ServerActionRevalidationKind;
|
|
27
27
|
export declare function resolveServerActionOperationLane(revalidation: ServerActionRevalidationKind): Extract<OperationLane, "refresh" | "server-action">;
|
|
28
|
-
export declare function normalizeServerActionThrownValue(data: unknown, responseStatus: number): unknown
|
|
28
|
+
export declare function normalizeServerActionThrownValue(data: unknown, responseStatus: number): Promise<unknown>;
|
|
29
29
|
export declare function shouldSyncServerActionHttpFallbackHead<TRoot>(result: AppBrowserServerActionResult<TRoot> | TRoot): boolean;
|
|
30
30
|
export declare function readInvalidServerActionResponseError(response: Pick<Response, "headers" | "status" | "text">, hasRedirectLocation: boolean): Promise<Error | null>;
|
|
31
31
|
export type ServerActionResultResponseFactsInput = {
|
|
@@ -41,8 +41,15 @@ function createServerActionHttpFallbackError(status) {
|
|
|
41
41
|
const error = /* @__PURE__ */ new Error(status === 404 ? "NEXT_NOT_FOUND" : `NEXT_HTTP_ERROR_FALLBACK;${status}`);
|
|
42
42
|
return Object.assign(error, { digest });
|
|
43
43
|
}
|
|
44
|
-
function normalizeServerActionThrownValue(data, responseStatus) {
|
|
45
|
-
|
|
44
|
+
async function normalizeServerActionThrownValue(data, responseStatus) {
|
|
45
|
+
const fallbackError = createServerActionHttpFallbackError(responseStatus);
|
|
46
|
+
if (fallbackError) return fallbackError;
|
|
47
|
+
try {
|
|
48
|
+
await data;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
return error;
|
|
51
|
+
}
|
|
52
|
+
return data;
|
|
46
53
|
}
|
|
47
54
|
function shouldSyncServerActionHttpFallbackHead(result) {
|
|
48
55
|
if (!isServerActionResult(result) || result.root !== void 0) return false;
|
|
@@ -583,7 +583,7 @@ function createAppBrowserNavigationController(deps = {}) {
|
|
|
583
583
|
} else notifyDiscardedServerActionRevalidation(lifecycleOptions);
|
|
584
584
|
} else if (decision.disposition === "no-commit") notifyDiscardedServerActionRevalidation(lifecycleOptions);
|
|
585
585
|
if (returnValue) {
|
|
586
|
-
if (!returnValue.ok) throw returnValue.data;
|
|
586
|
+
if (!returnValue.ok) throw await returnValue.data;
|
|
587
587
|
return returnValue.data;
|
|
588
588
|
}
|
|
589
589
|
}
|
|
@@ -123,7 +123,7 @@ async function invokeClientServerAction(id, args, actionInitiation, deps) {
|
|
|
123
123
|
return deps.commitSameUrlNavigatePayload(Promise.resolve(AppElementsWire.decode(result.root)), actionInitiation, returnValue, revalidation, renderedPathAndSearch);
|
|
124
124
|
}
|
|
125
125
|
if (result.returnValue) {
|
|
126
|
-
if (!result.returnValue.ok) throw normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status);
|
|
126
|
+
if (!result.returnValue.ok) throw await normalizeServerActionThrownValue(result.returnValue.data, fetchResponse.status);
|
|
127
127
|
return result.returnValue.data;
|
|
128
128
|
}
|
|
129
129
|
return;
|
|
@@ -34,6 +34,8 @@ export type ApplyAppMiddlewareOptions = {
|
|
|
34
34
|
* `trailingSlash`.
|
|
35
35
|
*/
|
|
36
36
|
trailingSlash?: boolean;
|
|
37
|
+
/** next.config `skipTrailingSlashRedirect`, forwarded to `executeMiddleware`. */
|
|
38
|
+
skipTrailingSlashRedirect?: boolean;
|
|
37
39
|
};
|
|
38
40
|
export type ApplyAppMiddlewareResult = {
|
|
39
41
|
kind: "continue";
|
|
@@ -43,6 +45,8 @@ export type ApplyAppMiddlewareResult = {
|
|
|
43
45
|
/** True when this pathname can match middleware for some request context. */
|
|
44
46
|
pathnameEligible?: boolean;
|
|
45
47
|
rewritten: boolean;
|
|
48
|
+
/** False when a same-origin rewrite target was outside the basePath. */
|
|
49
|
+
rewriteHadBasePath?: boolean;
|
|
46
50
|
search: string | null;
|
|
47
51
|
} | {
|
|
48
52
|
kind: "response";
|
|
@@ -53,6 +57,13 @@ export type ApplyAppMiddlewareResult = {
|
|
|
53
57
|
response: Response;
|
|
54
58
|
};
|
|
55
59
|
export declare function isExternalMiddlewareRewrite(rewriteUrl: string, request: Request): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The request an external rewrite forwards after middleware ran: the complete
|
|
62
|
+
* middleware request-header override, so deleted credentials stay deleted.
|
|
63
|
+
* Flight headers come from the original request, matching Next.js, which
|
|
64
|
+
* treats them as non-overridable.
|
|
65
|
+
*/
|
|
66
|
+
export declare function requestWithMiddlewareContextHeaders(request: Request, context: AppMiddlewareContext): Request;
|
|
56
67
|
export declare function proxyExternalMiddlewareRewrite(request: Request, rewriteUrl: string, context: AppMiddlewareContext): Promise<Response>;
|
|
57
68
|
export declare function applyAppMiddleware(options: ApplyAppMiddlewareOptions): Promise<ApplyAppMiddlewareResult>;
|
|
58
69
|
//#endregion
|
|
@@ -75,8 +75,17 @@ function restoreFlightHeaders(request, source) {
|
|
|
75
75
|
}
|
|
76
76
|
return changed ? cloneRequestWithHeaders(request, headers) : request;
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* The request an external rewrite forwards after middleware ran: the complete
|
|
80
|
+
* middleware request-header override, so deleted credentials stay deleted.
|
|
81
|
+
* Flight headers come from the original request, matching Next.js, which
|
|
82
|
+
* treats them as non-overridable.
|
|
83
|
+
*/
|
|
84
|
+
function requestWithMiddlewareContextHeaders(request, context) {
|
|
85
|
+
return restoreFlightHeaders(requestWithMiddlewareRequestHeaders(request, context.requestHeaders ?? context.headers), request);
|
|
86
|
+
}
|
|
78
87
|
async function proxyExternalMiddlewareRewrite(request, rewriteUrl, context) {
|
|
79
|
-
const proxyRequest =
|
|
88
|
+
const proxyRequest = requestWithMiddlewareContextHeaders(request, context);
|
|
80
89
|
setHeadersContext(null);
|
|
81
90
|
setNavigationContext(null);
|
|
82
91
|
const { proxyExternalRequest } = await import("../config/config-matchers.js");
|
|
@@ -129,6 +138,7 @@ function applyForwardedMiddlewareContext(request, context) {
|
|
|
129
138
|
if (typeof data.s === "number") context.status = data.s;
|
|
130
139
|
if (typeof data.r === "string" && data.r.length > 0) return {
|
|
131
140
|
applied: true,
|
|
141
|
+
rewriteHadBasePath: typeof data.b === "boolean" ? data.b : void 0,
|
|
132
142
|
rewriteUrl: data.r
|
|
133
143
|
};
|
|
134
144
|
return { applied: true };
|
|
@@ -143,6 +153,7 @@ async function applyAppMiddleware(options) {
|
|
|
143
153
|
let pathnameEligible = forwarded.applied;
|
|
144
154
|
let cleanPathname = options.cleanPathname;
|
|
145
155
|
let rewritten = false;
|
|
156
|
+
let rewriteHadBasePath;
|
|
146
157
|
let search = null;
|
|
147
158
|
if (forwarded.rewriteUrl) try {
|
|
148
159
|
if (isExternalMiddlewareRewrite(forwarded.rewriteUrl, options.request)) {
|
|
@@ -168,6 +179,7 @@ async function applyAppMiddleware(options) {
|
|
|
168
179
|
const rewriteParsed = new URL(forwarded.rewriteUrl, options.request.url);
|
|
169
180
|
cleanPathname = rewriteParsed.pathname;
|
|
170
181
|
rewritten = true;
|
|
182
|
+
rewriteHadBasePath = forwarded.rewriteHadBasePath;
|
|
171
183
|
search = rewriteParsed.search;
|
|
172
184
|
} catch (e) {
|
|
173
185
|
console.error("[vinext] Failed to apply forwarded middleware rewrite:", e);
|
|
@@ -194,6 +206,7 @@ async function applyAppMiddleware(options) {
|
|
|
194
206
|
},
|
|
195
207
|
requestBodyAlreadyIsolated: true,
|
|
196
208
|
request: middlewareRequest,
|
|
209
|
+
skipTrailingSlashRedirect: options.skipTrailingSlashRedirect,
|
|
197
210
|
trailingSlash: options.trailingSlash
|
|
198
211
|
});
|
|
199
212
|
} finally {
|
|
@@ -243,6 +256,7 @@ async function applyAppMiddleware(options) {
|
|
|
243
256
|
const rewriteParsed = new URL(result.rewriteUrl, middlewareRequest.url);
|
|
244
257
|
cleanPathname = rewriteParsed.pathname;
|
|
245
258
|
rewritten = true;
|
|
259
|
+
rewriteHadBasePath = result.rewriteHadBasePath;
|
|
246
260
|
search = rewriteParsed.search;
|
|
247
261
|
}
|
|
248
262
|
}
|
|
@@ -258,8 +272,9 @@ async function applyAppMiddleware(options) {
|
|
|
258
272
|
matched,
|
|
259
273
|
pathnameEligible,
|
|
260
274
|
rewritten,
|
|
275
|
+
rewriteHadBasePath,
|
|
261
276
|
search
|
|
262
277
|
};
|
|
263
278
|
}
|
|
264
279
|
//#endregion
|
|
265
|
-
export { FLIGHT_HEADERS, applyAppMiddleware, isExternalMiddlewareRewrite, proxyExternalMiddlewareRewrite };
|
|
280
|
+
export { FLIGHT_HEADERS, applyAppMiddleware, isExternalMiddlewareRewrite, proxyExternalMiddlewareRewrite, requestWithMiddlewareContextHeaders };
|
|
@@ -93,7 +93,7 @@ type ReadAppPageFallbackShellCacheResponseOptions = {
|
|
|
93
93
|
isEdgeRuntime?: boolean;
|
|
94
94
|
isrDebug?: AppPageDebugLogger;
|
|
95
95
|
isrGet: AppPageCacheGetter;
|
|
96
|
-
|
|
96
|
+
isrFallbackShellHtmlKey: (pathname: string) => string;
|
|
97
97
|
middlewareHeaders?: Headers | null;
|
|
98
98
|
middlewareStatus?: number | null;
|
|
99
99
|
revalidateSeconds: number;
|
|
@@ -375,7 +375,7 @@ see more here https://nextjs.org/docs/messages/app-static-to-dynamic-error`);
|
|
|
375
375
|
return null;
|
|
376
376
|
}
|
|
377
377
|
async function readAppPageFallbackShellCacheResponse(options) {
|
|
378
|
-
const isrKey = options.
|
|
378
|
+
const isrKey = options.isrFallbackShellHtmlKey(options.fallbackPathname);
|
|
379
379
|
try {
|
|
380
380
|
const cached = await options.isrGet(isrKey);
|
|
381
381
|
const cachedValue = getCachedAppPageValue(cached);
|
|
@@ -13,7 +13,8 @@ import { AppPageSsrHandler } from "./app-page-stream.js";
|
|
|
13
13
|
import { AppRenderErrorContextOverrides } from "./app-rsc-error-handler.js";
|
|
14
14
|
import { AppPageCacheSetter, ISRCacheEntry } from "./isr-cache.js";
|
|
15
15
|
import { PprFallbackShellState } from "../shims/ppr-fallback-shell.js";
|
|
16
|
-
import { FetchCacheMode } from "../shims/fetch-cache.js";
|
|
16
|
+
import { FetchCacheMode } from "../shims/fetch-cache-state.js";
|
|
17
|
+
import "../shims/fetch-cache.js";
|
|
17
18
|
import { AppPagePprFallbackCacheShell } from "./app-ppr-fallback-shell.js";
|
|
18
19
|
import { WarmPprFallbackShellCachesOptions } from "./app-ppr-fallback-shell-render.js";
|
|
19
20
|
import { ValidateAppPageDynamicParamsOptions } from "./app-page-request.js";
|
|
@@ -197,6 +198,7 @@ export type DispatchAppPageOptions<TRoute extends AppPageDispatchRoute> = {
|
|
|
197
198
|
isRscRequest: boolean;
|
|
198
199
|
isrDebug?: AppPageDebugLogger;
|
|
199
200
|
isrGet: AppPageCacheGetter;
|
|
201
|
+
isrFallbackShellHtmlKey: (pathname: string) => string;
|
|
200
202
|
isrHtmlKey: (pathname: string) => string;
|
|
201
203
|
isrRscKey: (pathname: string, mountedSlotsHeader?: string | null, renderMode?: AppRscRenderMode, interceptionContext?: string | null, interceptionId?: string | null) => string;
|
|
202
204
|
isrSet: AppPageCacheSetter;
|
|
@@ -3,6 +3,7 @@ import "../utils/protocol-headers.js";
|
|
|
3
3
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
4
4
|
import { VINEXT_INTERCEPTION_ID_HEADER, VINEXT_RSC_VARY_HEADER } from "./app-rsc-vary.js";
|
|
5
5
|
import "./headers.js";
|
|
6
|
+
import { runInWorkStoreScope } from "../shims/internal/work-store-scope.js";
|
|
6
7
|
import { beginRouteCacheability, isRouteCacheabilityIdentityProbe, isRouteCacheabilityProbe, markRouteCacheabilityPatternDynamic, readRouteCacheabilityState } from "../shims/cacheability-classification.js";
|
|
7
8
|
import { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL } from "./app-rsc-render-mode.js";
|
|
8
9
|
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, getAndClearPendingCookies, getDraftModeCookieHeader, getHeadersContext, isDraftModeRequest, peekDynamicUsage, peekRenderRequestApiUsage, runWithIsolatedDynamicUsage, setHeadersContext } from "../shims/headers.js";
|
|
@@ -150,7 +151,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
|
|
|
150
151
|
executionContext: getRequestExecutionContext(),
|
|
151
152
|
unstableCacheRevalidation: "foreground"
|
|
152
153
|
});
|
|
153
|
-
const revalidation = runWithRequestContext(requestContext, async () => {
|
|
154
|
+
const revalidation = runWithRequestContext(requestContext, () => runInWorkStoreScope(async () => {
|
|
154
155
|
ensureFetchPatch();
|
|
155
156
|
setRefreshStaleFetchesInForeground(process.env.VINEXT_PRERENDER === "1");
|
|
156
157
|
setCurrentFetchSoftTags(buildAppPageTags(options.cleanPathname, [], options.routeSegments));
|
|
@@ -160,7 +161,7 @@ async function runAppPageRevalidationContext(options, renderFn) {
|
|
|
160
161
|
params: options.params
|
|
161
162
|
});
|
|
162
163
|
return await runWithFetchDedupe(renderFn);
|
|
163
|
-
});
|
|
164
|
+
}));
|
|
164
165
|
try {
|
|
165
166
|
return await revalidation;
|
|
166
167
|
} finally {
|
|
@@ -313,7 +314,7 @@ async function dispatchAppPageInner(options) {
|
|
|
313
314
|
});
|
|
314
315
|
const isNeverStoredPath = options.pprRuntime === void 0 && hasNoManifestAdmissionState(route.pattern);
|
|
315
316
|
const shouldReadCache = !isRouteCacheabilityProbe() && isCacheEligibleRender && !isNeverStoredPath;
|
|
316
|
-
const isCacheCandidate = isCacheEligibleRender && isStaticEligible && options.
|
|
317
|
+
const isCacheCandidate = isCacheEligibleRender && isStaticEligible && options.pprFallbackShell === void 0 && !isNeverStoredPath;
|
|
317
318
|
if (shouldReadCache && isStaticEligible) {
|
|
318
319
|
traceOperation = resolveAppPageTraceOperation({
|
|
319
320
|
hasRequestSearchParams,
|
|
@@ -34,7 +34,7 @@ async function probePprFallbackShellCache(options, fallbackShells, currentRevali
|
|
|
34
34
|
isEdgeRuntime: options.isEdgeRuntime,
|
|
35
35
|
isrDebug: options.isrDebug,
|
|
36
36
|
isrGet: options.isrGet,
|
|
37
|
-
|
|
37
|
+
isrFallbackShellHtmlKey: options.isrFallbackShellHtmlKey,
|
|
38
38
|
middlewareHeaders: options.middlewareContext.headers,
|
|
39
39
|
middlewareStatus: options.middlewareContext.status,
|
|
40
40
|
revalidateSeconds: currentRevalidateSeconds ?? 0,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fnv1a64 } from "../utils/hash.js";
|
|
2
1
|
import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
|
|
2
|
+
import { fnv1a64 } from "../utils/hash.js";
|
|
3
3
|
import { consumeDynamicUsage, consumeInvalidDynamicUsageError, consumeRenderRequestApiUsage } from "../shims/headers.js";
|
|
4
4
|
import { _consumeRequestScopedCacheLife } from "../shims/cache-request-state.js";
|
|
5
5
|
import { consumeDynamicFetchObservations } from "../shims/fetch-cache.js";
|
|
@@ -183,24 +183,62 @@ async function generateIndependentStaticParams(sources, primaryParams, requestPa
|
|
|
183
183
|
validated
|
|
184
184
|
};
|
|
185
185
|
}
|
|
186
|
-
|
|
187
|
-
|
|
186
|
+
function isStaticParamsRowConsistentWithRequest(row, requestParams) {
|
|
187
|
+
const sharedKeys = Object.keys(row).filter((key) => requestParams[key] !== void 0);
|
|
188
|
+
return areStaticParamsAllowed(requestParams, [row], false, sharedKeys);
|
|
189
|
+
}
|
|
190
|
+
function rewritesParentParams(parentParams, item) {
|
|
191
|
+
return Object.keys(item).some((key) => Object.hasOwn(parentParams, key) && JSON.stringify(item[key]) !== JSON.stringify(parentParams[key]));
|
|
192
|
+
}
|
|
193
|
+
async function generateChainedStaticParams(sources, requestParams, results = /* @__PURE__ */ new Map()) {
|
|
194
|
+
let generatedRows = [];
|
|
195
|
+
let skippedParents = false;
|
|
196
|
+
let needsEveryCombination = false;
|
|
188
197
|
for (const source of sources) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
+
let sourceResults = results.get(source);
|
|
199
|
+
if (!sourceResults) {
|
|
200
|
+
sourceResults = /* @__PURE__ */ new Map();
|
|
201
|
+
results.set(source, sourceResults);
|
|
202
|
+
}
|
|
203
|
+
const hasParentParams = generatedRows.length > 0;
|
|
204
|
+
let parents = hasParentParams ? generatedRows : [{
|
|
205
|
+
params: {},
|
|
206
|
+
lineage: ""
|
|
207
|
+
}];
|
|
208
|
+
const nextRows = [];
|
|
209
|
+
if (requestParams) {
|
|
210
|
+
const consistent = parents.filter((row) => isStaticParamsRowConsistentWithRequest(row.params, requestParams));
|
|
211
|
+
parents = consistent.length > 0 ? consistent : parents.slice(0, 1);
|
|
212
|
+
}
|
|
213
|
+
if (hasParentParams && parents.length < generatedRows.length) skippedParents = true;
|
|
214
|
+
for (const parent of parents) {
|
|
215
|
+
let result = sourceResults.get(parent.lineage);
|
|
216
|
+
if (!sourceResults.has(parent.lineage)) {
|
|
217
|
+
result = await runWithFetchDedupe(() => source.generateStaticParams({ params: parent.params }));
|
|
218
|
+
sourceResults.set(parent.lineage, result);
|
|
219
|
+
}
|
|
220
|
+
if (Array.isArray(result) && result.length > 0) result.forEach((item, index) => {
|
|
221
|
+
if (item === null || typeof item !== "object" || Array.isArray(item)) return;
|
|
222
|
+
const row = item;
|
|
223
|
+
if (skippedParents && rewritesParentParams(parent.params, row)) needsEveryCombination = true;
|
|
224
|
+
nextRows.push({
|
|
225
|
+
params: {
|
|
226
|
+
...parent.params,
|
|
227
|
+
...row
|
|
228
|
+
},
|
|
229
|
+
lineage: `${parent.lineage}/${index}`
|
|
198
230
|
});
|
|
199
|
-
}
|
|
231
|
+
});
|
|
232
|
+
else if (hasParentParams) nextRows.push({
|
|
233
|
+
params: parent.params,
|
|
234
|
+
lineage: `${parent.lineage}/-`
|
|
235
|
+
});
|
|
200
236
|
}
|
|
201
|
-
|
|
237
|
+
if (skippedParents && nextRows.length === 0) needsEveryCombination = true;
|
|
238
|
+
generatedRows = nextRows;
|
|
202
239
|
}
|
|
203
|
-
return
|
|
240
|
+
if (needsEveryCombination) return generateChainedStaticParams(sources, null, results);
|
|
241
|
+
return generatedRows.map((row) => row.params);
|
|
204
242
|
}
|
|
205
243
|
function normalizeGenerateStaticParams(generateStaticParams) {
|
|
206
244
|
return (Array.isArray(generateStaticParams) ? generateStaticParams : [generateStaticParams]).flatMap((source) => {
|
|
@@ -218,7 +256,7 @@ async function validateAppPageDynamicParams(options) {
|
|
|
218
256
|
if (generateStaticParamsSources.length === 0) return notFoundResponse();
|
|
219
257
|
const chainedSources = generateStaticParamsSources.filter((source) => source.chained);
|
|
220
258
|
let chainedStaticParams = null;
|
|
221
|
-
if (chainedSources.length > 0) chainedStaticParams = await generateChainedStaticParams(chainedSources);
|
|
259
|
+
if (chainedSources.length > 0) chainedStaticParams = await generateChainedStaticParams(chainedSources, generateStaticParamsSources.some((source) => !source.chained) ? null : options.params);
|
|
222
260
|
const independentChains = /* @__PURE__ */ new Map();
|
|
223
261
|
for (const source of generateStaticParamsSources.filter((source) => !source.chained)) {
|
|
224
262
|
const chain = independentChains.get(source.independentChain ?? source) ?? [];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fnv1a64 } from "../utils/hash.js";
|
|
2
1
|
import { APP_RSC_RENDER_MODE_PREFETCH_EMPTY, APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL } from "./app-rsc-render-mode.js";
|
|
2
|
+
import { fnv1a64 } from "../utils/hash.js";
|
|
3
3
|
import { createInlineScriptTag, escapeHtmlAttr } from "./html.js";
|
|
4
4
|
import { createAppRenderDependency, registerAppElementRenderDependencies, renderAfterAppDependencies, renderAppComponentWithDependencyBarrier } from "./app-render-dependency.js";
|
|
5
5
|
import { APP_LAYOUT_IDS_KEY, APP_ROOT_LAYOUT_KEY, APP_STATIC_SIBLINGS_KEY, AppElementsWire, normalizeAppElementsSlotBindings } from "./app-elements-wire.js";
|
|
@@ -289,7 +289,7 @@ function createAppPageRouteBodyMetadata(metadata, pathname, metadataPlacement, t
|
|
|
289
289
|
streamedIconKey
|
|
290
290
|
});
|
|
291
291
|
const metadataKey = streamedIconKey ? createStreamedIconKey(pathname, renderedMetadataHtml) : "";
|
|
292
|
-
const parserInsertedMetadataHtml = (streamedIconKey ? renderedMetadataHtml.replaceAll(`<link data-vinext-streamed-icon="${STREAMED_ICON_KEY_PLACEHOLDER}:`, `<link data-vinext-streamed-icon="${escapeHtmlAttr(metadataKey)}:`) : renderedMetadataHtml) + createInlineScriptTag(REINSERT_STREAMED_ICONS_SCRIPT, scriptNonce);
|
|
292
|
+
const parserInsertedMetadataHtml = (streamedIconKey ? renderedMetadataHtml.replaceAll(`<link data-vinext-streamed-icon="${STREAMED_ICON_KEY_PLACEHOLDER}:`, () => `<link data-vinext-streamed-icon="${escapeHtmlAttr(metadataKey)}:`) : renderedMetadataHtml) + createInlineScriptTag(REINSERT_STREAMED_ICONS_SCRIPT, scriptNonce);
|
|
293
293
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
|
|
294
294
|
hidden: true,
|
|
295
295
|
suppressHydrationWarning: true,
|
|
@@ -24,7 +24,6 @@ type AppRouteMatch = {
|
|
|
24
24
|
type RenderPagesFallbackDependencies = {
|
|
25
25
|
loadPagesEntry: () => Promise<PagesEntry> | PagesEntry;
|
|
26
26
|
buildRequestHeaders: (requestHeaders: Headers, middlewareRequestHeaders: Headers) => Headers | null;
|
|
27
|
-
decodePathParams: (pathname: string) => string;
|
|
28
27
|
applyRouteHandlerMiddlewareContext: (response: Response, middlewareContext: AppMiddlewareContext) => Response;
|
|
29
28
|
/**
|
|
30
29
|
* Returns the `__prerender_bypass` Set-Cookie header emitted by a
|
|
@@ -51,6 +50,7 @@ type RenderPagesFallbackOptions = {
|
|
|
51
50
|
initialResponseHeaders?: Headers;
|
|
52
51
|
matchKind?: "dynamic" | "static";
|
|
53
52
|
middlewareContext: AppMiddlewareContext;
|
|
53
|
+
/** Raw (still percent-encoded) Pages route URL; defaults to `url.pathname`. */
|
|
54
54
|
pathname?: string;
|
|
55
55
|
pagesDataRequest?: Request | null;
|
|
56
56
|
request: Request;
|
|
@@ -19,7 +19,7 @@ function applyPagesMiddlewareContext(response, middlewareContext) {
|
|
|
19
19
|
*/
|
|
20
20
|
async function renderPagesFallback(options, dependencies) {
|
|
21
21
|
const { allowRscDocumentFallback = false, appRouteMatch = null, isDataRequest = false, isRscRequest, initialResponseHeaders, matchKind, middlewareContext, pathname = options.url.pathname, pagesDataRequest = null, request, url } = options;
|
|
22
|
-
const { loadPagesEntry, buildRequestHeaders,
|
|
22
|
+
const { loadPagesEntry, buildRequestHeaders, applyRouteHandlerMiddlewareContext, getDraftModeCookieHeader } = dependencies;
|
|
23
23
|
if (isRscRequest && !allowRscDocumentFallback) return null;
|
|
24
24
|
const pagesEntry = await loadPagesEntry();
|
|
25
25
|
const pagesRequestHeaders = middlewareContext.requestHeaders ? buildRequestHeaders(request.headers, middlewareContext.requestHeaders) : null;
|
|
@@ -27,8 +27,7 @@ async function renderPagesFallback(options, dependencies) {
|
|
|
27
27
|
if (pagesRequestHeaders) pagesRequest = cloneRequestWithHeaders(request, pagesRequestHeaders);
|
|
28
28
|
const queryIndex = pathname.indexOf("?");
|
|
29
29
|
const pagesPathname = queryIndex === -1 ? pathname : pathname.slice(0, queryIndex);
|
|
30
|
-
const
|
|
31
|
-
const pagesUrl = decodePathParams(pagesPathname) + pagesSearch;
|
|
30
|
+
const pagesUrl = pagesPathname + (queryIndex === -1 ? url.search || "" : pathname.slice(queryIndex));
|
|
32
31
|
if (pagesPathname.startsWith("/api/") || pagesPathname === "/api") {
|
|
33
32
|
if (typeof pagesEntry.handleApiRoute !== "function") return null;
|
|
34
33
|
const hasApiMatcher = typeof pagesEntry.matchApiRoute === "function";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import "./headers.js";
|
|
2
|
+
import { runInWorkStoreScope, runOutsideWorkStoreScope } from "../shims/internal/work-store-scope.js";
|
|
2
3
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
3
4
|
import { callAppPrerenderStaticParams } from "./app-prerender-static-params.js";
|
|
4
5
|
//#region src/server/app-prerender-endpoints.ts
|
|
@@ -39,13 +40,13 @@ async function handleStaticParamsEndpoint(request, options) {
|
|
|
39
40
|
if (typeof generateStaticParams !== "function") return jsonNullResponse();
|
|
40
41
|
try {
|
|
41
42
|
const params = parseParentParams(url.searchParams.get("parentParams"));
|
|
42
|
-
const result = await callAppPrerenderStaticParams({
|
|
43
|
+
const result = await runInWorkStoreScope(() => callAppPrerenderStaticParams({
|
|
43
44
|
fn: generateStaticParams,
|
|
44
45
|
params,
|
|
45
46
|
pattern,
|
|
46
47
|
rejectEmptyResults: url.searchParams.get("rejectEmptyResults") === "1",
|
|
47
48
|
rootParamNamesByPattern: options.rootParamNamesByPattern ?? {}
|
|
48
|
-
});
|
|
49
|
+
}));
|
|
49
50
|
if (result === null) return jsonNullResponse();
|
|
50
51
|
return jsonResponse(result);
|
|
51
52
|
} catch (error) {
|
|
@@ -63,10 +64,12 @@ async function handlePagesStaticPathsEndpoint(request, options) {
|
|
|
63
64
|
try {
|
|
64
65
|
const getStaticPaths = findPageRoute(await options.loadPagesRoutes?.(), pattern)?.module?.getStaticPaths;
|
|
65
66
|
if (typeof getStaticPaths !== "function") return jsonNullResponse();
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
const locales = parseLocales(url.searchParams.get("locales"));
|
|
68
|
+
const defaultLocale = url.searchParams.get("defaultLocale") ?? "";
|
|
69
|
+
return jsonResponse(await runOutsideWorkStoreScope(() => getStaticPaths({
|
|
70
|
+
locales,
|
|
71
|
+
defaultLocale
|
|
72
|
+
})));
|
|
70
73
|
} catch (error) {
|
|
71
74
|
return jsonResponse({ error: String(error) }, 500);
|
|
72
75
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import "../utils/protocol-headers.js";
|
|
2
2
|
import "./headers.js";
|
|
3
3
|
import { restoreStaticFileSignalFromTransport } from "./static-file-signal.js";
|
|
4
|
+
import { attachRequestCfMetadata } from "./request-pipeline.js";
|
|
4
5
|
import { isDraftModeRequest } from "../shims/headers.js";
|
|
5
6
|
import { getScriptNonceFromHeaderSources } from "./csp.js";
|
|
7
|
+
import { restoreImageOptimizationSignalFromTransport } from "./image-optimization.js";
|
|
6
8
|
import { isRouteTreePrefetchRequest } from "./app-route-tree-prefetch.js";
|
|
7
9
|
import "./app-worker-stages.js";
|
|
8
10
|
//#region src/server/app-request-stage-dispatch.ts
|
|
@@ -29,7 +31,8 @@ async function dispatchAppRequestStage(request, ctx, dispatchResponseStage, opti
|
|
|
29
31
|
if (!dispatchResponseStage) throw new Error("App request stage requires a response-stage dispatcher");
|
|
30
32
|
if (appRequestUsesFullResponseGraph(request, options)) {
|
|
31
33
|
const staticFileSignalToken = crypto.randomUUID();
|
|
32
|
-
const
|
|
34
|
+
const headRequest = request.method === "HEAD";
|
|
35
|
+
const response = await dispatchResponseStage(headRequest ? attachRequestCfMetadata(new Request(request, { method: "GET" }), request) : request, {
|
|
33
36
|
kind: "app-full-request",
|
|
34
37
|
buildId: options.buildId,
|
|
35
38
|
cacheability: {
|
|
@@ -38,6 +41,7 @@ async function dispatchAppRequestStage(request, ctx, dispatchResponseStage, opti
|
|
|
38
41
|
resolvedRoutePathname: new URL(request.url).pathname
|
|
39
42
|
},
|
|
40
43
|
draftModeCookie: null,
|
|
44
|
+
headRequest,
|
|
41
45
|
middlewareCookieOverlay: null,
|
|
42
46
|
prerenderDiscovery: options.prerenderDiscovery,
|
|
43
47
|
protocolVersion: 11,
|
|
@@ -46,7 +50,7 @@ async function dispatchAppRequestStage(request, ctx, dispatchResponseStage, opti
|
|
|
46
50
|
staticFileSignalToken,
|
|
47
51
|
trustedPrerenderState: options.trustedPrerenderState ?? null
|
|
48
52
|
}, { cache: "bypass" });
|
|
49
|
-
return restoreStaticFileSignalFromTransport(response, staticFileSignalToken);
|
|
53
|
+
return await restoreImageOptimizationSignalFromTransport(await restoreStaticFileSignalFromTransport(response, staticFileSignalToken), staticFileSignalToken);
|
|
50
54
|
}
|
|
51
55
|
return options.handleRequest(request, ctx, false, dispatchResponseStage, options.probeMode);
|
|
52
56
|
}
|