vinext 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -5
- package/dist/build/client-build-config.d.ts +7 -1
- package/dist/build/client-build-config.js +9 -1
- package/dist/build/prerender.d.ts +9 -1
- package/dist/build/prerender.js +41 -12
- package/dist/build/run-prerender.d.ts +10 -2
- package/dist/build/run-prerender.js +15 -1
- package/dist/check.js +4 -3
- package/dist/client/app-nav-failure-handler.d.ts +8 -0
- package/dist/client/app-nav-failure-handler.js +44 -0
- package/dist/client/navigation-runtime.d.ts +3 -2
- package/dist/client/vinext-next-data.d.ts +18 -1
- package/dist/client/window-next.d.ts +8 -5
- package/dist/client/window-next.js +12 -1
- package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
- package/dist/config/config-matchers.d.ts +11 -4
- package/dist/config/config-matchers.js +88 -16
- package/dist/config/next-config.d.ts +59 -4
- package/dist/config/next-config.js +149 -48
- package/dist/deploy.d.ts +30 -11
- package/dist/deploy.js +189 -101
- package/dist/entries/app-browser-entry.d.ts +9 -3
- package/dist/entries/app-browser-entry.js +21 -3
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +71 -6
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/app-ssr-entry.js +1 -1
- package/dist/entries/pages-client-entry.js +54 -9
- package/dist/entries/pages-server-entry.js +48 -11
- package/dist/index.d.ts +0 -2
- package/dist/index.js +285 -139
- package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
- package/dist/plugins/dynamic-preload-metadata.js +415 -0
- package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
- package/dist/plugins/extensionless-dynamic-import.js +152 -0
- package/dist/plugins/og-assets.js +2 -2
- package/dist/plugins/optimize-imports.d.ts +10 -5
- package/dist/plugins/optimize-imports.js +27 -21
- package/dist/plugins/postcss.js +7 -7
- package/dist/plugins/sass.d.ts +53 -24
- package/dist/plugins/sass.js +249 -1
- package/dist/plugins/typeof-window.d.ts +14 -0
- package/dist/plugins/typeof-window.js +150 -0
- package/dist/plugins/wasm-module-import.d.ts +15 -0
- package/dist/plugins/wasm-module-import.js +50 -0
- package/dist/routing/app-route-graph.d.ts +25 -2
- package/dist/routing/app-route-graph.js +91 -22
- package/dist/routing/file-matcher.d.ts +10 -1
- package/dist/routing/file-matcher.js +23 -2
- package/dist/routing/pages-router.js +3 -3
- package/dist/routing/utils.d.ts +35 -6
- package/dist/routing/utils.js +59 -7
- package/dist/server/api-handler.d.ts +6 -1
- package/dist/server/api-handler.js +21 -15
- package/dist/server/app-browser-action-result.d.ts +19 -6
- package/dist/server/app-browser-action-result.js +19 -10
- package/dist/server/app-browser-entry.js +269 -297
- package/dist/server/app-browser-error.d.ts +10 -3
- package/dist/server/app-browser-error.js +47 -6
- package/dist/server/app-browser-history-controller.d.ts +104 -0
- package/dist/server/app-browser-history-controller.js +210 -0
- package/dist/server/app-browser-hydration.d.ts +2 -0
- package/dist/server/app-browser-hydration.js +1 -0
- package/dist/server/app-browser-navigation-controller.d.ts +7 -4
- package/dist/server/app-browser-navigation-controller.js +33 -9
- package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
- package/dist/server/app-browser-rsc-redirect.js +30 -8
- package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
- package/dist/server/app-browser-server-action-navigation.js +9 -0
- package/dist/server/app-browser-state.js +4 -7
- package/dist/server/app-browser-stream.js +86 -43
- package/dist/server/app-browser-visible-commit.js +1 -1
- package/dist/server/app-elements-wire.d.ts +6 -1
- package/dist/server/app-elements-wire.js +14 -4
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +2 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -1
- package/dist/server/app-fallback-renderer.js +6 -2
- package/dist/server/app-middleware.js +1 -0
- package/dist/server/app-optimistic-routing.js +24 -3
- package/dist/server/app-page-boundary-render.d.ts +3 -1
- package/dist/server/app-page-boundary-render.js +31 -16
- package/dist/server/app-page-cache-render.d.ts +53 -0
- package/dist/server/app-page-cache-render.js +91 -0
- package/dist/server/app-page-cache.d.ts +16 -2
- package/dist/server/app-page-cache.js +71 -8
- package/dist/server/app-page-dispatch.d.ts +34 -0
- package/dist/server/app-page-dispatch.js +167 -97
- package/dist/server/app-page-element-builder.d.ts +23 -2
- package/dist/server/app-page-element-builder.js +42 -10
- package/dist/server/app-page-execution.d.ts +7 -2
- package/dist/server/app-page-execution.js +53 -18
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +4 -0
- package/dist/server/app-page-render-observation.d.ts +3 -1
- package/dist/server/app-page-render-observation.js +17 -1
- package/dist/server/app-page-render.d.ts +13 -2
- package/dist/server/app-page-render.js +48 -17
- package/dist/server/app-page-request.d.ts +3 -0
- package/dist/server/app-page-request.js +5 -3
- package/dist/server/app-page-response.js +1 -1
- package/dist/server/app-page-route-wiring.d.ts +5 -1
- package/dist/server/app-page-route-wiring.js +21 -11
- package/dist/server/app-page-stream.d.ts +16 -9
- package/dist/server/app-page-stream.js +12 -9
- package/dist/server/app-pages-bridge.d.ts +18 -0
- package/dist/server/app-pages-bridge.js +22 -5
- package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
- package/dist/server/app-ppr-fallback-shell-render.js +26 -0
- package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
- package/dist/server/app-ppr-fallback-shell.js +8 -1
- package/dist/server/app-route-handler-dispatch.js +9 -2
- package/dist/server/app-route-handler-policy.d.ts +1 -0
- package/dist/server/app-route-handler-response.js +11 -10
- package/dist/server/app-route-handler-runtime.js +12 -1
- package/dist/server/app-router-entry.js +5 -0
- package/dist/server/app-rsc-cache-busting.js +2 -0
- package/dist/server/app-rsc-handler.d.ts +25 -0
- package/dist/server/app-rsc-handler.js +153 -53
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +3 -0
- package/dist/server/app-rsc-route-matching.js +2 -0
- package/dist/server/app-segment-config.d.ts +9 -1
- package/dist/server/app-segment-config.js +12 -3
- package/dist/server/app-server-action-execution.d.ts +12 -0
- package/dist/server/app-server-action-execution.js +47 -15
- package/dist/server/app-ssr-entry.d.ts +2 -0
- package/dist/server/app-ssr-entry.js +81 -8
- package/dist/server/app-ssr-stream.js +9 -1
- package/dist/server/cache-control.js +4 -0
- package/dist/server/dev-lockfile.js +2 -1
- package/dist/server/dev-server.d.ts +2 -2
- package/dist/server/dev-server.js +287 -63
- package/dist/server/headers.d.ts +8 -1
- package/dist/server/headers.js +8 -1
- package/dist/server/hybrid-route-priority.d.ts +22 -0
- package/dist/server/hybrid-route-priority.js +33 -0
- package/dist/server/image-optimization.d.ts +18 -9
- package/dist/server/image-optimization.js +37 -23
- package/dist/server/implicit-tags.d.ts +2 -1
- package/dist/server/implicit-tags.js +4 -1
- package/dist/server/instrumentation-runtime.d.ts +6 -0
- package/dist/server/instrumentation-runtime.js +8 -0
- package/dist/server/isr-decision.d.ts +79 -0
- package/dist/server/isr-decision.js +70 -0
- package/dist/server/metadata-route-response.js +5 -3
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +11 -7
- package/dist/server/middleware.js +1 -0
- package/dist/server/navigation-planner.d.ts +186 -22
- package/dist/server/navigation-planner.js +302 -0
- package/dist/server/navigation-trace.d.ts +18 -1
- package/dist/server/navigation-trace.js +18 -1
- package/dist/server/normalize-path.d.ts +0 -8
- package/dist/server/normalize-path.js +3 -1
- package/dist/server/otel-tracer-extension.d.ts +45 -0
- package/dist/server/otel-tracer-extension.js +89 -0
- package/dist/server/pages-api-route.d.ts +20 -3
- package/dist/server/pages-api-route.js +19 -3
- package/dist/server/pages-asset-tags.d.ts +16 -4
- package/dist/server/pages-asset-tags.js +22 -12
- package/dist/server/pages-data-route.d.ts +8 -1
- package/dist/server/pages-data-route.js +16 -3
- package/dist/server/pages-get-initial-props.d.ts +54 -4
- package/dist/server/pages-get-initial-props.js +43 -1
- package/dist/server/pages-node-compat.d.ts +3 -11
- package/dist/server/pages-node-compat.js +175 -122
- package/dist/server/pages-page-data.d.ts +39 -2
- package/dist/server/pages-page-data.js +261 -46
- package/dist/server/pages-page-handler.d.ts +5 -2
- package/dist/server/pages-page-handler.js +78 -25
- package/dist/server/pages-page-response.d.ts +47 -2
- package/dist/server/pages-page-response.js +73 -9
- package/dist/server/pages-readiness.d.ts +1 -1
- package/dist/server/pages-request-pipeline.d.ts +16 -1
- package/dist/server/pages-request-pipeline.js +96 -38
- package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
- package/dist/server/pregenerated-concrete-paths.js +2 -19
- package/dist/server/prerender-manifest.d.ts +33 -0
- package/dist/server/prerender-manifest.js +54 -0
- package/dist/server/prerender-route-params.d.ts +1 -2
- package/dist/server/prod-server.d.ts +39 -1
- package/dist/server/prod-server.js +107 -37
- package/dist/server/request-pipeline.d.ts +3 -15
- package/dist/server/request-pipeline.js +58 -47
- package/dist/server/rsc-stream-hints.d.ts +5 -1
- package/dist/server/rsc-stream-hints.js +6 -1
- package/dist/server/seed-cache.js +10 -18
- package/dist/shims/app-router-scroll-state.d.ts +3 -1
- package/dist/shims/app-router-scroll-state.js +14 -2
- package/dist/shims/app-router-scroll.d.ts +3 -0
- package/dist/shims/app-router-scroll.js +28 -18
- package/dist/shims/cache-runtime.js +12 -4
- package/dist/shims/cache.d.ts +1 -0
- package/dist/shims/cache.js +1 -1
- package/dist/shims/cdn-cache.d.ts +5 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
- package/dist/shims/dynamic-preload-chunks.js +79 -0
- package/dist/shims/dynamic.d.ts +4 -0
- package/dist/shims/dynamic.js +4 -2
- package/dist/shims/error-boundary.d.ts +6 -4
- package/dist/shims/error-boundary.js +7 -0
- package/dist/shims/error.js +38 -11
- package/dist/shims/error.react-server.d.ts +9 -0
- package/dist/shims/error.react-server.js +6 -0
- package/dist/shims/fetch-cache.d.ts +11 -1
- package/dist/shims/fetch-cache.js +55 -20
- package/dist/shims/hash-scroll.js +6 -1
- package/dist/shims/head.js +6 -1
- package/dist/shims/headers.d.ts +16 -2
- package/dist/shims/headers.js +66 -5
- package/dist/shims/image-config.js +7 -1
- package/dist/shims/internal/als-registry.js +28 -1
- package/dist/shims/internal/app-route-detection.d.ts +6 -3
- package/dist/shims/internal/app-route-detection.js +18 -23
- package/dist/shims/internal/app-router-context.d.ts +5 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
- package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
- package/dist/shims/internal/navigation-untracked.d.ts +35 -0
- package/dist/shims/internal/navigation-untracked.js +55 -0
- package/dist/shims/internal/pages-data-target.d.ts +7 -2
- package/dist/shims/internal/pages-data-target.js +17 -8
- package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
- package/dist/shims/internal/pages-router-accessor.js +13 -0
- package/dist/shims/internal/router-context.d.ts +2 -1
- package/dist/shims/internal/router-context.js +3 -1
- package/dist/shims/link.js +12 -5
- package/dist/shims/metadata.d.ts +6 -2
- package/dist/shims/metadata.js +32 -14
- package/dist/shims/navigation.d.ts +14 -17
- package/dist/shims/navigation.js +93 -46
- package/dist/shims/ppr-fallback-shell.d.ts +5 -1
- package/dist/shims/ppr-fallback-shell.js +28 -7
- package/dist/shims/router.d.ts +13 -2
- package/dist/shims/router.js +434 -116
- package/dist/shims/script-nonce-context.d.ts +1 -1
- package/dist/shims/script-nonce-context.js +11 -3
- package/dist/shims/server.d.ts +33 -2
- package/dist/shims/server.js +75 -18
- package/dist/shims/slot.js +1 -1
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/typegen.js +1 -0
- package/dist/utils/built-asset-url.d.ts +4 -0
- package/dist/utils/built-asset-url.js +11 -0
- package/dist/utils/client-build-manifest.js +15 -5
- package/dist/utils/client-runtime-metadata.d.ts +45 -0
- package/dist/utils/client-runtime-metadata.js +63 -0
- package/dist/utils/commonjs-loader.d.ts +16 -0
- package/dist/utils/commonjs-loader.js +100 -0
- package/dist/utils/deployment-id.d.ts +8 -0
- package/dist/utils/deployment-id.js +22 -0
- package/dist/utils/hash.d.ts +17 -1
- package/dist/utils/hash.js +36 -1
- package/dist/utils/html-limited-bots.d.ts +18 -1
- package/dist/utils/html-limited-bots.js +23 -1
- package/dist/utils/lazy-chunks.d.ts +27 -1
- package/dist/utils/lazy-chunks.js +65 -1
- package/dist/utils/manifest-paths.d.ts +20 -2
- package/dist/utils/manifest-paths.js +38 -3
- package/dist/utils/parse-cookie.d.ts +13 -0
- package/dist/utils/parse-cookie.js +52 -0
- package/dist/utils/path.d.ts +8 -1
- package/dist/utils/path.js +13 -1
- package/package.json +2 -2
- package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
- package/dist/shims/internal/parse-cookie-header.js +0 -30
|
@@ -1,11 +1,32 @@
|
|
|
1
|
-
import { hasBasePath } from "../utils/base-path.js";
|
|
1
|
+
import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { applyMiddlewareRequestHeaders, isExternalUrl, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
3
|
-
import { applyConfigHeadersToHeaderRecord, normalizeTrailingSlash } from "./request-pipeline.js";
|
|
3
|
+
import { applyConfigHeadersToHeaderRecord, cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
|
|
4
4
|
import { mergeRewriteQuery } from "../utils/query.js";
|
|
5
5
|
import { normalizeDefaultLocalePathname, stripI18nLocaleForApiRoute } from "./pages-i18n.js";
|
|
6
6
|
import { mergeHeaders } from "./worker-utils.js";
|
|
7
7
|
//#region src/server/pages-request-pipeline.ts
|
|
8
8
|
/**
|
|
9
|
+
* Wrap an adapter's `runMiddleware` callback so middleware receives the original
|
|
10
|
+
* (pre-basePath-stripping) URL. Adapters strip the basePath before handing the
|
|
11
|
+
* request to `runPagesRequest`, but Next.js passes the un-stripped URL to the
|
|
12
|
+
* middleware adapter so `request.nextUrl.basePath` reflects whether the URL
|
|
13
|
+
* actually had the basePath prefix. Requests outside the basePath
|
|
14
|
+
* (`hadBasePath === false`) are passed through untouched so middleware sees
|
|
15
|
+
* `nextUrl.basePath === ""` and can redirect them into the basePath
|
|
16
|
+
* (see the middleware-base-path e2e test / #1830).
|
|
17
|
+
*
|
|
18
|
+
* Shared by the Node prod server (prod-server.ts) and the generated Pages
|
|
19
|
+
* Router worker entry (deploy.ts) to keep the two adapters in sync.
|
|
20
|
+
*/
|
|
21
|
+
function wrapMiddlewareWithBasePath(runMiddleware, basePath, hadBasePath) {
|
|
22
|
+
if (!hadBasePath || !basePath) return runMiddleware;
|
|
23
|
+
return (request, ctx, opts) => {
|
|
24
|
+
const mwUrl = new URL(request.url);
|
|
25
|
+
mwUrl.pathname = addBasePathToPathname(mwUrl.pathname, basePath);
|
|
26
|
+
return runMiddleware(new Request(mwUrl, request), ctx, opts);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
9
30
|
* Run the Pages Router request pipeline.
|
|
10
31
|
*
|
|
11
32
|
* ASSUMPTION: request already has internal headers filtered and basePath stripped.
|
|
@@ -47,7 +68,8 @@ async function runPagesRequest(request, deps) {
|
|
|
47
68
|
};
|
|
48
69
|
}
|
|
49
70
|
}
|
|
50
|
-
|
|
71
|
+
const originalResolvedUrl = pathname + search;
|
|
72
|
+
let resolvedUrl = originalResolvedUrl;
|
|
51
73
|
const middlewareHeaders = {};
|
|
52
74
|
let middlewareStatus;
|
|
53
75
|
if (typeof deps.runMiddleware === "function") {
|
|
@@ -93,7 +115,12 @@ async function runPagesRequest(request, deps) {
|
|
|
93
115
|
}
|
|
94
116
|
const { postMwReqCtx, request: postMwReq } = applyMiddlewareRequestHeaders(middlewareHeaders, request, { preserveCredentialHeaders: isExternalUrl(resolvedUrl) });
|
|
95
117
|
request = postMwReq;
|
|
96
|
-
|
|
118
|
+
const pathnameForResolvedUrl = (value) => value.split("#", 1)[0].split("?", 1)[0];
|
|
119
|
+
const rewriteRequestContext = () => ({
|
|
120
|
+
...postMwReqCtx,
|
|
121
|
+
query: new URL(resolvedUrl, url).searchParams
|
|
122
|
+
});
|
|
123
|
+
let resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
97
124
|
const matchResolvedPathname = (p) => i18nConfig ? normalizeDefaultLocalePathname(p, i18nConfig, { hostname: requestHostname }) : p;
|
|
98
125
|
if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
|
|
99
126
|
configHeaders,
|
|
@@ -109,15 +136,15 @@ async function runPagesRequest(request, deps) {
|
|
|
109
136
|
if (await deps.serveStaticFile(pathname, middlewareHeaders)) return { type: "handled" };
|
|
110
137
|
}
|
|
111
138
|
let configRewriteFired = false;
|
|
112
|
-
|
|
113
|
-
const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname),
|
|
139
|
+
for (const rewrite of configRewrites.beforeFiles ?? []) {
|
|
140
|
+
const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
|
|
114
141
|
if (rewritten) {
|
|
115
142
|
if (isExternalUrl(rewritten)) return {
|
|
116
143
|
type: "response",
|
|
117
144
|
response: await proxyExternal(request, rewritten)
|
|
118
145
|
};
|
|
119
146
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
|
|
120
|
-
resolvedPathname = resolvedUrl
|
|
147
|
+
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
121
148
|
configRewriteFired = true;
|
|
122
149
|
}
|
|
123
150
|
}
|
|
@@ -130,34 +157,61 @@ async function runPagesRequest(request, deps) {
|
|
|
130
157
|
};
|
|
131
158
|
const apiLookupUrl = stripI18nLocaleForApiRoute(resolvedUrl, i18nConfig);
|
|
132
159
|
const apiLookupPathname = apiLookupUrl.split("?")[0];
|
|
133
|
-
if (apiLookupPathname.startsWith("/api/") || apiLookupPathname === "/api") if (typeof deps.handleApi === "function")
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
160
|
+
if (apiLookupPathname.startsWith("/api/") || apiLookupPathname === "/api") if (typeof deps.handleApi === "function") {
|
|
161
|
+
let apiRequest = request;
|
|
162
|
+
if (basePath && hadBasePath) {
|
|
163
|
+
const apiRequestUrl = new URL(request.url);
|
|
164
|
+
apiRequestUrl.pathname = addBasePathToPathname(apiRequestUrl.pathname, basePath);
|
|
165
|
+
apiRequest = cloneRequestWithUrl(request, apiRequestUrl.toString());
|
|
166
|
+
}
|
|
167
|
+
return {
|
|
168
|
+
type: "response",
|
|
169
|
+
defaultContentType: "application/octet-stream",
|
|
170
|
+
response: mergeHeaders(await deps.handleApi(apiRequest, apiLookupUrl, deps.ctx ?? null), middlewareHeaders, middlewareStatus)
|
|
171
|
+
};
|
|
172
|
+
} else return {
|
|
139
173
|
type: "api",
|
|
140
174
|
apiUrl: apiLookupUrl,
|
|
141
175
|
stagedHeaders: middlewareHeaders,
|
|
142
176
|
requestHeaders: request.headers,
|
|
143
177
|
middlewareStatus
|
|
144
178
|
};
|
|
145
|
-
|
|
179
|
+
let pageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
|
|
146
180
|
let resolvedPathnameChanged = false;
|
|
147
|
-
if (
|
|
148
|
-
const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname),
|
|
181
|
+
if (!pageMatch || pageMatch.route.isDynamic) for (const rewrite of configRewrites.afterFiles ?? []) {
|
|
182
|
+
const rewritten = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
|
|
149
183
|
if (rewritten) {
|
|
150
184
|
if (isExternalUrl(rewritten)) return {
|
|
151
185
|
type: "response",
|
|
152
186
|
response: await proxyExternal(request, rewritten)
|
|
153
187
|
};
|
|
154
188
|
resolvedUrl = mergeRewriteQuery(resolvedUrl, rewritten);
|
|
155
|
-
resolvedPathname = resolvedUrl
|
|
189
|
+
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
156
190
|
resolvedPathnameChanged = true;
|
|
191
|
+
pageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
|
|
192
|
+
if (pageMatch) break;
|
|
157
193
|
}
|
|
158
194
|
}
|
|
195
|
+
const refreshDataRewriteHeader = () => {
|
|
196
|
+
if ((isDataReq || isDataRequest) && resolvedUrl !== originalResolvedUrl && !isExternalUrl(resolvedUrl)) middlewareHeaders["x-nextjs-rewrite"] = resolvedUrl;
|
|
197
|
+
else delete middlewareHeaders["x-nextjs-rewrite"];
|
|
198
|
+
};
|
|
199
|
+
refreshDataRewriteHeader();
|
|
159
200
|
if (typeof deps.renderPage === "function") {
|
|
160
|
-
|
|
201
|
+
let renderPageMatch = pageMatch;
|
|
202
|
+
if ((isDataReq || isDataRequest) && !renderPageMatch && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
203
|
+
const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
|
|
204
|
+
if (!fallbackRewrite) continue;
|
|
205
|
+
if (isExternalUrl(fallbackRewrite)) return {
|
|
206
|
+
type: "response",
|
|
207
|
+
response: await proxyExternal(request, fallbackRewrite)
|
|
208
|
+
};
|
|
209
|
+
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
210
|
+
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
211
|
+
renderPageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
|
|
212
|
+
refreshDataRewriteHeader();
|
|
213
|
+
if (renderPageMatch) break;
|
|
214
|
+
}
|
|
161
215
|
const shouldDeferErrorPageOnMiss = !isDataReq && !isDataRequest && !!deps.matchPageRoute && !renderPageMatch;
|
|
162
216
|
const initialRenderOptions = shouldDeferErrorPageOnMiss ? { renderErrorPageOnMiss: false } : isDataReq ? { isDataReq: true } : void 0;
|
|
163
217
|
const stagedHeaders = new Headers();
|
|
@@ -165,16 +219,18 @@ async function runPagesRequest(request, deps) {
|
|
|
165
219
|
else stagedHeaders.set(k, v);
|
|
166
220
|
let response = await deps.renderPage(request, resolvedUrl, initialRenderOptions, stagedHeaders);
|
|
167
221
|
let matchedFallbackRewrite = false;
|
|
168
|
-
if (response.status === 404 && shouldDeferErrorPageOnMiss && configRewrites.fallback?.length) {
|
|
169
|
-
const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname),
|
|
170
|
-
if (fallbackRewrite)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
222
|
+
if (response.status === 404 && shouldDeferErrorPageOnMiss && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
223
|
+
const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
|
|
224
|
+
if (!fallbackRewrite) continue;
|
|
225
|
+
if (isExternalUrl(fallbackRewrite)) return {
|
|
226
|
+
type: "response",
|
|
227
|
+
response: await proxyExternal(request, fallbackRewrite)
|
|
228
|
+
};
|
|
229
|
+
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
230
|
+
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
231
|
+
response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
232
|
+
matchedFallbackRewrite = true;
|
|
233
|
+
if (response.status !== 404) break;
|
|
178
234
|
}
|
|
179
235
|
if (response.status === 404 && shouldDeferErrorPageOnMiss && !matchedFallbackRewrite) response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
180
236
|
const merged = mergeHeaders(response, middlewareHeaders, middlewareStatus);
|
|
@@ -185,16 +241,18 @@ async function runPagesRequest(request, deps) {
|
|
|
185
241
|
defaultContentType: "text/html"
|
|
186
242
|
};
|
|
187
243
|
}
|
|
188
|
-
if (!(resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch) && configRewrites.fallback?.length) {
|
|
189
|
-
const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname),
|
|
190
|
-
if (fallbackRewrite)
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
244
|
+
if (!(resolvedPathnameChanged ? deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null : pageMatch) && configRewrites.fallback?.length) for (const rewrite of configRewrites.fallback) {
|
|
245
|
+
const fallbackRewrite = matchRewrite(matchResolvedPathname(resolvedPathname), [rewrite], rewriteRequestContext(), basePathState);
|
|
246
|
+
if (!fallbackRewrite) continue;
|
|
247
|
+
if (isExternalUrl(fallbackRewrite)) return {
|
|
248
|
+
type: "response",
|
|
249
|
+
response: await proxyExternal(request, fallbackRewrite)
|
|
250
|
+
};
|
|
251
|
+
resolvedUrl = mergeRewriteQuery(resolvedUrl, fallbackRewrite);
|
|
252
|
+
resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
253
|
+
if (deps.matchPageRoute?.(resolvedPathname, request)) break;
|
|
197
254
|
}
|
|
255
|
+
refreshDataRewriteHeader();
|
|
198
256
|
return {
|
|
199
257
|
type: "render",
|
|
200
258
|
resolvedUrl,
|
|
@@ -206,4 +264,4 @@ async function runPagesRequest(request, deps) {
|
|
|
206
264
|
};
|
|
207
265
|
}
|
|
208
266
|
//#endregion
|
|
209
|
-
export { runPagesRequest };
|
|
267
|
+
export { runPagesRequest, wrapMiddlewareWithBasePath };
|
|
@@ -4,28 +4,12 @@ declare global {
|
|
|
4
4
|
}
|
|
5
5
|
declare function normalizePregeneratedPathname(pathname: string): string;
|
|
6
6
|
declare function clearPregeneratedConcretePaths(): void;
|
|
7
|
-
/**
|
|
8
|
-
* Records a concrete URL path for a route pattern. The pathname is normalized
|
|
9
|
-
* here so this is the single source of truth: every caller — the Worker global
|
|
10
|
-
* table and the Node `seed-cache.ts` path — stores the canonical form that
|
|
11
|
-
* matches the runtime `cleanPathname` lookup without having to pre-normalize.
|
|
12
|
-
*/
|
|
13
7
|
declare function addPregeneratedConcretePath(routePattern: string, pathname: string): void;
|
|
14
|
-
/**
|
|
15
|
-
* Returns the live backing `Set` for a route pattern (not a copy) to keep
|
|
16
|
-
* lookups allocation-free on the serving hot path. The `ReadonlySet` type
|
|
17
|
-
* forbids mutation at compile time. Callers must treat the result as
|
|
18
|
-
* point-in-time and must NOT retain it across a re-seed: each
|
|
19
|
-
* `initPregeneratedPathsFromGlobals` call runs `clearPregeneratedConcretePaths`,
|
|
20
|
-
* which empties the map, leaving any previously-returned reference stale. Read
|
|
21
|
-
* it, use it, drop it — never cache the reference.
|
|
22
|
-
*/
|
|
23
8
|
declare function getRenderedConcreteUrlPathsForRoute(routePattern: string): ReadonlySet<string> | undefined;
|
|
24
9
|
/**
|
|
25
10
|
* Populate the registry from `globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS`.
|
|
26
11
|
* No-op when the global is not set (Node path — seed-cache handles it later).
|
|
27
|
-
*
|
|
28
|
-
* runtime `cleanPathname`.
|
|
12
|
+
* Pathnames are normalised so they match the runtime `cleanPathname`.
|
|
29
13
|
*/
|
|
30
14
|
declare function initPregeneratedPathsFromGlobals(): void;
|
|
31
15
|
//#endregion
|
|
@@ -16,38 +16,21 @@ const concreteUrlPathsByRoute = /* @__PURE__ */ new Map();
|
|
|
16
16
|
function clearPregeneratedConcretePaths() {
|
|
17
17
|
concreteUrlPathsByRoute.clear();
|
|
18
18
|
}
|
|
19
|
-
/**
|
|
20
|
-
* Records a concrete URL path for a route pattern. The pathname is normalized
|
|
21
|
-
* here so this is the single source of truth: every caller — the Worker global
|
|
22
|
-
* table and the Node `seed-cache.ts` path — stores the canonical form that
|
|
23
|
-
* matches the runtime `cleanPathname` lookup without having to pre-normalize.
|
|
24
|
-
*/
|
|
25
19
|
function addPregeneratedConcretePath(routePattern, pathname) {
|
|
26
|
-
const normalized = normalizePregeneratedPathname(pathname);
|
|
27
20
|
let paths = concreteUrlPathsByRoute.get(routePattern);
|
|
28
21
|
if (!paths) {
|
|
29
22
|
paths = /* @__PURE__ */ new Set();
|
|
30
23
|
concreteUrlPathsByRoute.set(routePattern, paths);
|
|
31
24
|
}
|
|
32
|
-
paths.add(
|
|
25
|
+
paths.add(normalizePregeneratedPathname(pathname));
|
|
33
26
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Returns the live backing `Set` for a route pattern (not a copy) to keep
|
|
36
|
-
* lookups allocation-free on the serving hot path. The `ReadonlySet` type
|
|
37
|
-
* forbids mutation at compile time. Callers must treat the result as
|
|
38
|
-
* point-in-time and must NOT retain it across a re-seed: each
|
|
39
|
-
* `initPregeneratedPathsFromGlobals` call runs `clearPregeneratedConcretePaths`,
|
|
40
|
-
* which empties the map, leaving any previously-returned reference stale. Read
|
|
41
|
-
* it, use it, drop it — never cache the reference.
|
|
42
|
-
*/
|
|
43
27
|
function getRenderedConcreteUrlPathsForRoute(routePattern) {
|
|
44
28
|
return concreteUrlPathsByRoute.get(routePattern);
|
|
45
29
|
}
|
|
46
30
|
/**
|
|
47
31
|
* Populate the registry from `globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS`.
|
|
48
32
|
* No-op when the global is not set (Node path — seed-cache handles it later).
|
|
49
|
-
*
|
|
50
|
-
* runtime `cleanPathname`.
|
|
33
|
+
* Pathnames are normalised so they match the runtime `cleanPathname`.
|
|
51
34
|
*/
|
|
52
35
|
function initPregeneratedPathsFromGlobals() {
|
|
53
36
|
const raw = globalThis.__VINEXT_PREGENERATED_CONCRETE_PATHS;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/server/prerender-manifest.d.ts
|
|
2
|
+
type PrerenderManifestRoute = {
|
|
3
|
+
route: string;
|
|
4
|
+
status?: string;
|
|
5
|
+
revalidate?: number | false;
|
|
6
|
+
expire?: number;
|
|
7
|
+
path?: string;
|
|
8
|
+
router?: string;
|
|
9
|
+
fallback?: boolean;
|
|
10
|
+
};
|
|
11
|
+
type PrerenderManifest = {
|
|
12
|
+
buildId?: string;
|
|
13
|
+
trailingSlash?: boolean;
|
|
14
|
+
routes?: PrerenderManifestRoute[];
|
|
15
|
+
};
|
|
16
|
+
declare function readPrerenderManifest(manifestPath: string): PrerenderManifest | null;
|
|
17
|
+
declare function getRenderedAppRoutes(routes: PrerenderManifestRoute[]): PrerenderManifestRoute[];
|
|
18
|
+
/**
|
|
19
|
+
* Returns true when `pathname` contains bracket-delimited route params,
|
|
20
|
+
* indicating it is a fallback-shell placeholder (e.g. `/en/blog/[slug]`)
|
|
21
|
+
* rather than a concrete rendered URL.
|
|
22
|
+
*/
|
|
23
|
+
declare function isFallbackShellArtifactPath(pathname: string, route?: PrerenderManifestRoute): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Build the pregenerated concrete-path payload table from a prerender manifest.
|
|
26
|
+
*
|
|
27
|
+
* Filters out fallback-shell placeholder paths and groups remaining concrete
|
|
28
|
+
* paths by route pattern. Returns an empty array when the manifest has no
|
|
29
|
+
* rendered App routes or all routes are fallback-shell artifacts.
|
|
30
|
+
*/
|
|
31
|
+
declare function buildPregeneratedConcretePathTable(manifest: PrerenderManifest): Array<[string, string[]]>;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
//#region src/server/prerender-manifest.ts
|
|
3
|
+
function readPrerenderManifest(manifestPath) {
|
|
4
|
+
if (!fs.existsSync(manifestPath)) return null;
|
|
5
|
+
try {
|
|
6
|
+
return JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
7
|
+
} catch (error) {
|
|
8
|
+
console.warn(`[vinext] Failed to read prerender manifest at ${manifestPath}:`, error);
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function getRenderedAppRoutes(routes) {
|
|
13
|
+
return routes.filter((r) => r.status === "rendered" && r.router === "app");
|
|
14
|
+
}
|
|
15
|
+
function groupRoutesByPattern(routes) {
|
|
16
|
+
const byPattern = /* @__PURE__ */ new Map();
|
|
17
|
+
for (const r of routes) {
|
|
18
|
+
const pathname = r.path ?? r.route;
|
|
19
|
+
const existing = byPattern.get(r.route);
|
|
20
|
+
if (existing) existing.push(pathname);
|
|
21
|
+
else byPattern.set(r.route, [pathname]);
|
|
22
|
+
}
|
|
23
|
+
return byPattern;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Returns true when `pathname` contains bracket-delimited route params,
|
|
27
|
+
* indicating it is a fallback-shell placeholder (e.g. `/en/blog/[slug]`)
|
|
28
|
+
* rather than a concrete rendered URL.
|
|
29
|
+
*/
|
|
30
|
+
function isFallbackShellArtifactPath(pathname, route) {
|
|
31
|
+
if (route?.fallback === true) return true;
|
|
32
|
+
if (route?.fallback === void 0) {
|
|
33
|
+
if (process.env.NODE_ENV !== "production") console.warn("[vinext] Legacy manifest detected: missing `fallback` flag for route. Using bracket heuristic for fallback-shell detection. A concrete URL containing literal brackets may be misclassified as a fallback shell.");
|
|
34
|
+
return pathname.includes("[") || pathname.includes("]");
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Build the pregenerated concrete-path payload table from a prerender manifest.
|
|
40
|
+
*
|
|
41
|
+
* Filters out fallback-shell placeholder paths and groups remaining concrete
|
|
42
|
+
* paths by route pattern. Returns an empty array when the manifest has no
|
|
43
|
+
* rendered App routes or all routes are fallback-shell artifacts.
|
|
44
|
+
*/
|
|
45
|
+
function buildPregeneratedConcretePathTable(manifest) {
|
|
46
|
+
const routes = manifest?.routes;
|
|
47
|
+
if (!routes?.length) return [];
|
|
48
|
+
const concreteRoutes = getRenderedAppRoutes(routes).filter((r) => {
|
|
49
|
+
return !isFallbackShellArtifactPath(r.path ?? r.route, r);
|
|
50
|
+
});
|
|
51
|
+
return Array.from(groupRoutesByPattern(concreteRoutes).entries());
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
export { buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
|
|
@@ -5,7 +5,6 @@ type PrerenderRouteParamsPayload = {
|
|
|
5
5
|
params: PrerenderRouteParams;
|
|
6
6
|
routePattern: string;
|
|
7
7
|
};
|
|
8
|
-
/** @public exported for #1716 serving consumers; not yet referenced in-repo */
|
|
9
8
|
type PrerenderRouteParamsRouteMatch = {
|
|
10
9
|
kind: "exact";
|
|
11
10
|
params: PrerenderRouteParams;
|
|
@@ -21,4 +20,4 @@ declare function prerenderRouteParamsPayloadMatchesRoute(payload: PrerenderRoute
|
|
|
21
20
|
declare function matchPrerenderRouteParamsPayload(payload: PrerenderRouteParamsPayload | null, routePattern: string, params: PrerenderRouteParams): PrerenderRouteParamsRouteMatch | null;
|
|
22
21
|
declare function encodePrerenderRouteParams(pattern: string, params: PrerenderRouteParams, fallbackParamNames?: readonly string[]): PrerenderRouteParamsPayload | null;
|
|
23
22
|
//#endregion
|
|
24
|
-
export { PrerenderRouteParams, PrerenderRouteParamsPayload,
|
|
23
|
+
export { PrerenderRouteParams, PrerenderRouteParamsPayload, encodePrerenderRouteParams, matchPrerenderRouteParamsPayload, prerenderRouteParamsPayloadMatchesRoute, readTrustedPrerenderRouteParams, readTrustedPrerenderRouteParamsFromHeaders, serializePrerenderRouteParamsHeader };
|
|
@@ -3,6 +3,44 @@ import { resolveRequestHost, trustProxy, trustedHosts } from "./proxy-trust.js";
|
|
|
3
3
|
import { IncomingMessage, ServerResponse } from "node:http";
|
|
4
4
|
|
|
5
5
|
//#region src/server/prod-server.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Import a built server entry module (App Router RSC entry or Pages Router
|
|
8
|
+
* server entry) by absolute file path.
|
|
9
|
+
*
|
|
10
|
+
* The first import of a given path uses the plain file:// URL with NO query
|
|
11
|
+
* string. This is load-bearing: code-split builds emit lazy chunks that
|
|
12
|
+
* import the entry back by bare specifier (default Vite builds on both
|
|
13
|
+
* supported majors — Rollup on Vite 7 and Rolldown on Vite 8 — hoist modules
|
|
14
|
+
* shared between the entry's static graph and lazy route chunks into the
|
|
15
|
+
* entry chunk, which the chunks then import as e.g. "../../index.js").
|
|
16
|
+
* Node keys its ESM cache on the full URL including the query string, so if
|
|
17
|
+
* the server imported the entry as `index.js?t=<mtime>`, a chunk's bare
|
|
18
|
+
* back-import would evaluate the entire server bundle a second time and
|
|
19
|
+
* module-level singletons (db pools, service registries) would silently
|
|
20
|
+
* diverge between the two copies. See
|
|
21
|
+
* https://github.com/cloudflare/vinext/issues/1923.
|
|
22
|
+
*
|
|
23
|
+
* A `?t=<mtime>` query string is appended only when the same path is
|
|
24
|
+
* imported again after a rebuild (different mtime) — e.g. test suites that
|
|
25
|
+
* rebuild a fixture to the same output path within one process — where the
|
|
26
|
+
* bare URL's cache entry would return the stale previous build. Note this
|
|
27
|
+
* rebuild branch trades the single-instance guarantee back: chunks that
|
|
28
|
+
* import the entry by bare path still resolve to the FIRST build's cache
|
|
29
|
+
* entry, so freshness and single-instance only hold together on the first
|
|
30
|
+
* import of a path. Production processes import each entry path exactly
|
|
31
|
+
* once and always get both.
|
|
32
|
+
*
|
|
33
|
+
* The entry is imported via its canonical real path: the bundler
|
|
34
|
+
* canonicalizes module ids with fs.realpathSync.native, so chunks evaluate
|
|
35
|
+
* under realpath-based URLs and their relative imports resolve to realpath
|
|
36
|
+
* URLs too. Importing the entry through a symlinked path (macOS /var/...
|
|
37
|
+
* tmpdirs, symlinked deploy directories) would otherwise create a second
|
|
38
|
+
* instance keyed on the symlinked URL.
|
|
39
|
+
*
|
|
40
|
+
* Exported for direct unit testing of the URL choice.
|
|
41
|
+
*/
|
|
42
|
+
declare function resolveServerEntryImportUrl(entryPath: string): string;
|
|
43
|
+
declare function importServerEntryModule(entryPath: string): Promise<any>;
|
|
6
44
|
type ProdServerOptions = {
|
|
7
45
|
/** Port to listen on */port?: number; /** Host to bind to */
|
|
8
46
|
host?: string; /** Path to the build output directory */
|
|
@@ -105,4 +143,4 @@ declare function resolveAppRouterPrerenderSeeder(entryModule: unknown): AppRoute
|
|
|
105
143
|
*/
|
|
106
144
|
declare function resolveAppRouterAssetPath(pathname: string, assetPathPrefix: string, assetPrefix: string): string | null;
|
|
107
145
|
//#endregion
|
|
108
|
-
export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, ProdServerOptions, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
|
|
146
|
+
export { COMPRESSIBLE_TYPES, COMPRESS_THRESHOLD, ProdServerOptions, importServerEntryModule, mergeResponseHeaders, mergeWebResponse, negotiateEncoding, nodeToWebRequest, resolveAppRouterAssetPath, resolveAppRouterPrerenderSeeder, resolveRequestHost as resolveHost, resolveServerEntryImportUrl, sendCompressed, sendWebResponse, startProdServer, trustProxy, trustedHosts, tryServeStatic };
|