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,16 +1,20 @@
|
|
|
1
1
|
import { createRequestContext, runWithRequestContext } from "../shims/unified-request-context.js";
|
|
2
2
|
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
3
3
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
4
|
+
import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
|
|
4
5
|
import { reportRequestError } from "./instrumentation.js";
|
|
6
|
+
import { NEVER_CACHE_CONTROL } from "./cache-control.js";
|
|
7
|
+
import "./isr-decision.js";
|
|
5
8
|
import { PRERENDER_REVALIDATE_HEADER, isOnDemandRevalidateRequest, isrCacheKey, isrGet, isrSet, triggerBackgroundRegeneration } from "./isr-cache.js";
|
|
6
9
|
import { ensureFetchPatch } from "../shims/fetch-cache.js";
|
|
10
|
+
import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
7
11
|
import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
|
|
8
12
|
import { getScriptNonceFromHeaderSources } from "./csp.js";
|
|
9
13
|
import { resolvePagesI18nRequest } from "./pages-i18n.js";
|
|
10
14
|
import { buildDefaultPagesNotFoundResponse } from "./pages-default-404.js";
|
|
11
15
|
import { buildPagesReadinessNextData } from "./pages-readiness.js";
|
|
12
16
|
import { resolvePagesPageMethodResponse } from "./pages-page-method.js";
|
|
13
|
-
import {
|
|
17
|
+
import { buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, normalizePagesDataRequest, parseNextDataPathname } from "./pages-data-route.js";
|
|
14
18
|
import { createPagesReqRes } from "./pages-node-compat.js";
|
|
15
19
|
import { collectAssetTags, resolveClientModuleUrl } from "./pages-asset-tags.js";
|
|
16
20
|
import { renderPagesPageResponse } from "./pages-page-response.js";
|
|
@@ -45,19 +49,38 @@ function createPagesPageHandler(opts) {
|
|
|
45
49
|
}
|
|
46
50
|
async function renderPage(request, url, manifest, middlewareHeaders, options) {
|
|
47
51
|
let isDataReq = !!(options && options.isDataReq);
|
|
52
|
+
const requestUrl = new URL(request.url);
|
|
53
|
+
const rawOriginalUrl = options && typeof options.originalUrl === "string" ? options.originalUrl : requestUrl.pathname + requestUrl.search;
|
|
54
|
+
const originalRequestUrl = new URL(rawOriginalUrl, requestUrl);
|
|
55
|
+
const originalRequestPathAndSearch = originalRequestUrl.pathname + originalRequestUrl.search;
|
|
56
|
+
let dataRequestPathname = null;
|
|
57
|
+
let dataRequestSearch = "";
|
|
58
|
+
const initialDataNorm = normalizePagesDataRequest(request, buildId);
|
|
48
59
|
if (!isDataReq) {
|
|
49
|
-
|
|
50
|
-
if (
|
|
51
|
-
if (dataNorm.isDataReq) {
|
|
60
|
+
if (initialDataNorm.notFoundResponse) return initialDataNorm.notFoundResponse;
|
|
61
|
+
if (initialDataNorm.isDataReq) {
|
|
52
62
|
isDataReq = true;
|
|
63
|
+
dataRequestPathname = initialDataNorm.normalizedPathname;
|
|
64
|
+
dataRequestSearch = initialDataNorm.search;
|
|
53
65
|
if (url && url.startsWith("/_next/data/")) {
|
|
54
66
|
const qs = url.includes("?") ? url.slice(url.indexOf("?")) : "";
|
|
55
|
-
url =
|
|
67
|
+
url = initialDataNorm.normalizedPathname + qs;
|
|
56
68
|
}
|
|
57
69
|
}
|
|
70
|
+
} else if (initialDataNorm.isDataReq) {
|
|
71
|
+
dataRequestPathname = initialDataNorm.normalizedPathname;
|
|
72
|
+
dataRequestSearch = initialDataNorm.search;
|
|
73
|
+
}
|
|
74
|
+
if (isDataReq && dataRequestPathname === null && buildId) {
|
|
75
|
+
const originalDataMatch = parseNextDataPathname(originalRequestUrl.pathname, buildId);
|
|
76
|
+
if (originalDataMatch) {
|
|
77
|
+
dataRequestPathname = originalDataMatch.pagePathname;
|
|
78
|
+
dataRequestSearch = originalRequestUrl.search;
|
|
79
|
+
}
|
|
58
80
|
}
|
|
59
81
|
const statusCode = options && typeof options.statusCode === "number" ? options.statusCode : void 0;
|
|
60
|
-
const
|
|
82
|
+
const defaultAsPath = isDataReq && dataRequestPathname ? dataRequestPathname + dataRequestSearch : originalRequestPathAndSearch;
|
|
83
|
+
const asPath = options && typeof options.asPath === "string" ? options.asPath : defaultAsPath;
|
|
61
84
|
const renderErrorPageOnMiss = !(options && options.renderErrorPageOnMiss === false);
|
|
62
85
|
const isInternalErrorRender = !!(options && options.__isInternalErrorRender);
|
|
63
86
|
const err = options && options.err;
|
|
@@ -140,8 +163,8 @@ function createPagesPageHandler(opts) {
|
|
|
140
163
|
});
|
|
141
164
|
if (methodResponse) return methodResponse;
|
|
142
165
|
}
|
|
143
|
-
const pageModuleUrl = resolveClientModuleUrl(manifest, route.filePath);
|
|
144
|
-
const appModuleUrl = resolveClientModuleUrl(manifest, appAssetPath);
|
|
166
|
+
const pageModuleUrl = resolveClientModuleUrl(manifest, route.filePath, vinextConfig.basePath, vinextConfig.assetPrefix, process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID);
|
|
167
|
+
const appModuleUrl = resolveClientModuleUrl(manifest, appAssetPath, vinextConfig.basePath, vinextConfig.assetPrefix, process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID);
|
|
145
168
|
const serializedPagesNextData = {
|
|
146
169
|
...pagesNextData,
|
|
147
170
|
__vinext: {
|
|
@@ -156,23 +179,30 @@ function createPagesPageHandler(opts) {
|
|
|
156
179
|
let allFontPreloads = [];
|
|
157
180
|
try {
|
|
158
181
|
allFontPreloads = getFontPreloads();
|
|
159
|
-
if (allFontPreloads.length > 0) fontLinkHeader = allFontPreloads.map((p) => "<" + p.href + ">; rel=preload; as=font; type=" + p.type + "; crossorigin").join(", ");
|
|
182
|
+
if (allFontPreloads.length > 0) fontLinkHeader = allFontPreloads.map((p) => "<" + appendAssetDeploymentIdQuery(p.href) + ">; rel=preload; as=font; type=" + p.type + "; crossorigin").join(", ");
|
|
160
183
|
} catch {}
|
|
184
|
+
const pagesResolvedUrl = (new URL(routeUrl, originalRequestUrl).pathname || "/") + originalRequestUrl.search;
|
|
161
185
|
const pageDataResult = await resolvePagesPageData({
|
|
162
186
|
isDataReq,
|
|
163
187
|
err,
|
|
164
188
|
applyRequestContexts: applySSRContext,
|
|
165
189
|
buildId,
|
|
190
|
+
deploymentId: process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID,
|
|
191
|
+
htmlLimitedBots: vinextConfig.htmlLimitedBots,
|
|
166
192
|
createGsspReqRes() {
|
|
167
193
|
return createPagesReqRes({
|
|
168
194
|
body: void 0,
|
|
169
195
|
query,
|
|
170
196
|
request,
|
|
171
|
-
url:
|
|
197
|
+
url: originalRequestPathAndSearch
|
|
172
198
|
});
|
|
173
199
|
},
|
|
174
|
-
|
|
175
|
-
const el = createPageElement(PageComponent, AppComponent,
|
|
200
|
+
createAppTree(appTreeProps) {
|
|
201
|
+
const el = createPageElement(PageComponent, AppComponent, appTreeProps);
|
|
202
|
+
return typeof wrapWithRouterContext === "function" ? wrapWithRouterContext(el) : el;
|
|
203
|
+
},
|
|
204
|
+
createPageElement(currentProps) {
|
|
205
|
+
const el = createPageElement(PageComponent, AppComponent, currentProps);
|
|
176
206
|
return typeof wrapWithRouterContext === "function" ? wrapWithRouterContext(el) : el;
|
|
177
207
|
},
|
|
178
208
|
fontLinkHeader,
|
|
@@ -184,15 +214,17 @@ function createPagesPageHandler(opts) {
|
|
|
184
214
|
isBuildTimePrerendering: typeof process !== "undefined" && process.env && process.env.VINEXT_PRERENDER === "1",
|
|
185
215
|
isOnDemandRevalidate: isOnDemandRevalidateRequest(request.headers.get(PRERENDER_REVALIDATE_HEADER)),
|
|
186
216
|
pageModule,
|
|
217
|
+
AppComponent,
|
|
187
218
|
params,
|
|
188
219
|
query,
|
|
189
220
|
asPath: renderAsPath ?? routeUrl,
|
|
221
|
+
resolvedUrl: pagesResolvedUrl,
|
|
190
222
|
renderIsrPassToStringAsync,
|
|
191
223
|
route: { isDynamic: route.isDynamic },
|
|
192
224
|
routePattern,
|
|
193
225
|
routeUrl,
|
|
194
226
|
runInFreshUnifiedContext(callback) {
|
|
195
|
-
return runWithRequestContext(createRequestContext({ executionContext:
|
|
227
|
+
return runWithRequestContext(createRequestContext({ executionContext: null }), async () => {
|
|
196
228
|
ensureFetchPatch();
|
|
197
229
|
return callback();
|
|
198
230
|
});
|
|
@@ -203,7 +235,10 @@ function createPagesPageHandler(opts) {
|
|
|
203
235
|
statusCode: renderStatusCode,
|
|
204
236
|
triggerBackgroundRegeneration,
|
|
205
237
|
vinext: serializedPagesNextData.__vinext,
|
|
206
|
-
nextData: serializedPagesNextData
|
|
238
|
+
nextData: serializedPagesNextData,
|
|
239
|
+
userAgent: request.headers.get("user-agent") ?? void 0,
|
|
240
|
+
ifNoneMatch: request.headers.get("if-none-match") ?? void 0,
|
|
241
|
+
requestCacheControl: request.headers.get("cache-control") ?? void 0
|
|
207
242
|
});
|
|
208
243
|
if (pageDataResult.kind === "notFound") {
|
|
209
244
|
const notFoundRoute = findNotFoundRoute();
|
|
@@ -217,10 +252,17 @@ function createPagesPageHandler(opts) {
|
|
|
217
252
|
}
|
|
218
253
|
if (pageDataResult.kind === "response") return pageDataResult.response;
|
|
219
254
|
let pageProps = pageDataResult.pageProps;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
255
|
+
let renderProps = pageDataResult.props;
|
|
256
|
+
if (routePattern === "/_error" && typeof renderStatusCode === "number") {
|
|
257
|
+
pageProps = {
|
|
258
|
+
...pageProps,
|
|
259
|
+
statusCode: renderStatusCode
|
|
260
|
+
};
|
|
261
|
+
renderProps = {
|
|
262
|
+
...renderProps,
|
|
263
|
+
pageProps
|
|
264
|
+
};
|
|
265
|
+
}
|
|
224
266
|
const gsspRes = pageDataResult.gsspRes;
|
|
225
267
|
const isrRevalidateSeconds = pageDataResult.isrRevalidateSeconds;
|
|
226
268
|
const isFallbackRender = pageDataResult.isFallback === true;
|
|
@@ -251,9 +293,13 @@ function createPagesPageHandler(opts) {
|
|
|
251
293
|
hasUserCacheControl = true;
|
|
252
294
|
break;
|
|
253
295
|
}
|
|
254
|
-
if (!hasUserCacheControl) init.headers["Cache-Control"] =
|
|
296
|
+
if (!hasUserCacheControl) init.headers["Cache-Control"] = NEVER_CACHE_CONTROL;
|
|
297
|
+
}
|
|
298
|
+
if (routePattern !== "/_error" && routePattern !== "/500") {
|
|
299
|
+
const deploymentId = process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID;
|
|
300
|
+
if (deploymentId) init.headers[NEXTJS_DEPLOYMENT_ID_HEADER] = deploymentId;
|
|
255
301
|
}
|
|
256
|
-
return
|
|
302
|
+
return buildNextDataPropsJsonResponse(renderProps, safeJsonStringify, init);
|
|
257
303
|
}
|
|
258
304
|
const pageModuleIds = [];
|
|
259
305
|
if (route.filePath) pageModuleIds.push(route.filePath);
|
|
@@ -263,18 +309,21 @@ function createPagesPageHandler(opts) {
|
|
|
263
309
|
manifest,
|
|
264
310
|
moduleIds: pageModuleIds,
|
|
265
311
|
scriptNonce,
|
|
266
|
-
disableOptimizedLoading: vinextConfig.disableOptimizedLoading
|
|
312
|
+
disableOptimizedLoading: vinextConfig.disableOptimizedLoading,
|
|
313
|
+
basePath: vinextConfig.basePath,
|
|
314
|
+
assetPrefix: vinextConfig.assetPrefix,
|
|
315
|
+
deploymentId: process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID
|
|
267
316
|
}),
|
|
268
317
|
buildId,
|
|
269
318
|
clearSsrContext() {
|
|
270
319
|
if (typeof setSSRContext === "function") setSSRContext(null);
|
|
271
320
|
},
|
|
272
|
-
createPageElement(
|
|
273
|
-
const el = createPageElement(PageComponent, AppComponent,
|
|
321
|
+
createPageElement(currentProps) {
|
|
322
|
+
const el = createPageElement(PageComponent, AppComponent, currentProps);
|
|
274
323
|
return typeof wrapWithRouterContext === "function" ? wrapWithRouterContext(el) : el;
|
|
275
324
|
},
|
|
276
325
|
enhancePageElement(renderPageOpts) {
|
|
277
|
-
const el = enhancePageElement(PageComponent, AppComponent,
|
|
326
|
+
const el = enhancePageElement(PageComponent, AppComponent, renderProps, renderPageOpts);
|
|
278
327
|
return typeof wrapWithRouterContext === "function" ? wrapWithRouterContext(el) : el;
|
|
279
328
|
},
|
|
280
329
|
DocumentComponent,
|
|
@@ -293,6 +342,7 @@ function createPagesPageHandler(opts) {
|
|
|
293
342
|
i18n: buildI18nRenderContext(i18nConfig, locale, currentDefaultLocale, domainLocales),
|
|
294
343
|
isFallback: isFallbackRender,
|
|
295
344
|
pageProps,
|
|
345
|
+
props: renderProps,
|
|
296
346
|
params,
|
|
297
347
|
renderDocumentToString(element) {
|
|
298
348
|
return renderToStringAsync(element);
|
|
@@ -305,7 +355,10 @@ function createPagesPageHandler(opts) {
|
|
|
305
355
|
safeJsonStringify,
|
|
306
356
|
scriptNonce,
|
|
307
357
|
statusCode: renderStatusCode,
|
|
308
|
-
nextData: serializedPagesNextData
|
|
358
|
+
nextData: serializedPagesNextData,
|
|
359
|
+
userAgent: request.headers.get("user-agent") ?? void 0,
|
|
360
|
+
ifNoneMatch: request.headers.get("if-none-match") ?? void 0,
|
|
361
|
+
requestCacheControl: request.headers.get("cache-control") ?? void 0
|
|
309
362
|
});
|
|
310
363
|
} catch (e) {
|
|
311
364
|
console.error("[vinext] SSR error:", e);
|
|
@@ -4,6 +4,28 @@ import { RenderPageEnhancers } from "./pages-document-initial-props.js";
|
|
|
4
4
|
import { ComponentType, ReactNode } from "react";
|
|
5
5
|
|
|
6
6
|
//#region src/server/pages-page-response.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* Returns true when the User-Agent belongs to a bot or crawler that cannot
|
|
9
|
+
* reliably consume a streamed HTML response.
|
|
10
|
+
*/
|
|
11
|
+
declare function isPagesStreamingBot(userAgent: string): boolean;
|
|
12
|
+
declare function generatePagesETag(payload: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Mirrors Next.js `sendEtagResponse` semantics (weak/strong comparison).
|
|
15
|
+
*
|
|
16
|
+
* A weak ETag `W/"..."` matches both `W/"..."` and `"..."` in `If-None-Match`.
|
|
17
|
+
* A strong ETag `"..."` only matches the same strong token.
|
|
18
|
+
* `*` always matches.
|
|
19
|
+
*/
|
|
20
|
+
declare function etagMatches(etag: string, ifNoneMatch: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Returns true when a request `Cache-Control` header asks to bypass the 304
|
|
23
|
+
* short-circuit. Mirrors the `fresh` package's check used by Next.js's
|
|
24
|
+
* `sendEtagResponse` (`/(?:^|,)\s*?no-cache\s*?(?:,|$)/`). Shared by the
|
|
25
|
+
* fresh-MISS bot path here and the ISR HIT/STALE paths in
|
|
26
|
+
* `pages-page-data.ts` so the two cannot drift.
|
|
27
|
+
*/
|
|
28
|
+
declare function requestsNoCache(cacheControl: string | undefined): boolean;
|
|
7
29
|
type PagesFontPreload = {
|
|
8
30
|
href: string;
|
|
9
31
|
type: string;
|
|
@@ -71,6 +93,7 @@ type RenderPagesPageResponseOptions = {
|
|
|
71
93
|
*/
|
|
72
94
|
isFallback?: boolean;
|
|
73
95
|
pageProps: Record<string, unknown>;
|
|
96
|
+
props?: Record<string, unknown>;
|
|
74
97
|
params: Record<string, unknown>;
|
|
75
98
|
renderDocumentToString: (element: ReactNode) => Promise<string>;
|
|
76
99
|
renderToReadableStream: (element: ReactNode) => Promise<ReadableStream<Uint8Array>>;
|
|
@@ -82,10 +105,32 @@ type RenderPagesPageResponseOptions = {
|
|
|
82
105
|
statusCode?: number;
|
|
83
106
|
vinext?: VinextNextData["__vinext"];
|
|
84
107
|
nextData?: PagesNextDataExtras;
|
|
108
|
+
/**
|
|
109
|
+
* The request's User-Agent string (from `request.headers.get('user-agent')`).
|
|
110
|
+
* When this matches a known crawler / bot pattern, the response is fully
|
|
111
|
+
* buffered before sending so bots receive a single complete HTML chunk with
|
|
112
|
+
* an ETag header. Omitting this field disables bot-detection (streaming as
|
|
113
|
+
* normal), which is the correct behaviour for non-HTML requests and tests.
|
|
114
|
+
*/
|
|
115
|
+
userAgent?: string;
|
|
116
|
+
/**
|
|
117
|
+
* The incoming request's `If-None-Match` header value. When set and the
|
|
118
|
+
* computed ETag matches (weak-ETag semantics, mirroring Next.js's
|
|
119
|
+
* `sendEtagResponse`), a `304 Not Modified` is returned with an empty body.
|
|
120
|
+
* Only evaluated on bot/buffered responses that carry an ETag.
|
|
121
|
+
*/
|
|
122
|
+
ifNoneMatch?: string;
|
|
123
|
+
/**
|
|
124
|
+
* The incoming request's `Cache-Control` header value. When the value
|
|
125
|
+
* contains `no-cache`, the 304 short-circuit is skipped and a full 200
|
|
126
|
+
* response is always returned — mirroring the `fresh` package used by
|
|
127
|
+
* Next.js's `sendEtagResponse`.
|
|
128
|
+
*/
|
|
129
|
+
requestCacheControl?: string;
|
|
85
130
|
};
|
|
86
|
-
declare function buildPagesNextDataScript(options: Pick<RenderPagesPageResponseOptions, "buildId" | "i18n" | "isFallback" | "pageProps" | "params" | "routePattern" | "safeJsonStringify" | "scriptNonce" | "nextData"> & {
|
|
131
|
+
declare function buildPagesNextDataScript(options: Pick<RenderPagesPageResponseOptions, "buildId" | "i18n" | "isFallback" | "pageProps" | "props" | "params" | "routePattern" | "safeJsonStringify" | "scriptNonce" | "nextData"> & {
|
|
87
132
|
vinext?: VinextNextData["__vinext"];
|
|
88
133
|
}): string;
|
|
89
134
|
declare function renderPagesPageResponse(options: RenderPagesPageResponseOptions): Promise<Response>;
|
|
90
135
|
//#endregion
|
|
91
|
-
export { PagesGsspResponse, PagesI18nRenderContext, PagesNextDataExtras, buildPagesNextDataScript, renderPagesPageResponse };
|
|
136
|
+
export { PagesGsspResponse, PagesI18nRenderContext, PagesNextDataExtras, buildPagesNextDataScript, etagMatches, generatePagesETag, isPagesStreamingBot, renderPagesPageResponse, requestsNoCache };
|
|
@@ -1,27 +1,76 @@
|
|
|
1
1
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
2
2
|
import { reportRequestError } from "./instrumentation.js";
|
|
3
3
|
import { setCacheStateHeaders } from "./cache-headers.js";
|
|
4
|
+
import { fnv1a52 } from "../utils/hash.js";
|
|
4
5
|
import { encodeCacheTag } from "../utils/encode-cache-tag.js";
|
|
6
|
+
import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL, applyCdnResponseHeaders } from "./cache-control.js";
|
|
7
|
+
import { buildMissIsrCacheControl } from "./isr-decision.js";
|
|
8
|
+
import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
5
9
|
import { withScriptNonce } from "../shims/script-nonce-context.js";
|
|
6
10
|
import { createInlineScriptTag, createNonceAttribute, escapeHtmlAttr } from "./html.js";
|
|
7
11
|
import { getClientTraceMetadataHTML } from "./client-trace-metadata.js";
|
|
8
12
|
import { readStreamAsText } from "../utils/text-stream.js";
|
|
9
13
|
import { loadUserDocumentInitialProps, runDocumentRenderPage } from "./pages-document-initial-props.js";
|
|
10
14
|
import { callDocumentGetInitialProps } from "./document-initial-head.js";
|
|
11
|
-
import { applyCdnResponseHeaders, buildRevalidateCacheControl } from "./cache-control.js";
|
|
12
15
|
import React from "react";
|
|
13
16
|
//#region src/server/pages-page-response.ts
|
|
17
|
+
/**
|
|
18
|
+
* Crawlers that cannot handle streamed HTML: they read metadata only from
|
|
19
|
+
* the first network chunk, so streaming would give them an incomplete <head>.
|
|
20
|
+
* Pattern sourced from Next.js html-bots.ts (updated to match the canary).
|
|
21
|
+
*/
|
|
22
|
+
const HTML_LIMITED_BOT_UA_RE = /[\w-]+-Google|Google-[\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight/i;
|
|
23
|
+
/**
|
|
24
|
+
* Googlebot (the main search crawler) executes JavaScript via a headless
|
|
25
|
+
* browser, so it too cannot safely handle mid-stream HTML mutations.
|
|
26
|
+
* Matches "Googlebot" but NOT suffixed variants like "Googlebot-Image".
|
|
27
|
+
*/
|
|
28
|
+
const HEADLESS_BROWSER_BOT_UA_RE = /Googlebot(?!-)|Googlebot$/i;
|
|
29
|
+
/**
|
|
30
|
+
* Returns true when the User-Agent belongs to a bot or crawler that cannot
|
|
31
|
+
* reliably consume a streamed HTML response.
|
|
32
|
+
*/
|
|
33
|
+
function isPagesStreamingBot(userAgent) {
|
|
34
|
+
return HEADLESS_BROWSER_BOT_UA_RE.test(userAgent) || HTML_LIMITED_BOT_UA_RE.test(userAgent);
|
|
35
|
+
}
|
|
36
|
+
function generatePagesETag(payload) {
|
|
37
|
+
return "\"" + fnv1a52(payload).toString(36) + payload.length.toString(36) + "\"";
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Mirrors Next.js `sendEtagResponse` semantics (weak/strong comparison).
|
|
41
|
+
*
|
|
42
|
+
* A weak ETag `W/"..."` matches both `W/"..."` and `"..."` in `If-None-Match`.
|
|
43
|
+
* A strong ETag `"..."` only matches the same strong token.
|
|
44
|
+
* `*` always matches.
|
|
45
|
+
*/
|
|
46
|
+
function etagMatches(etag, ifNoneMatch) {
|
|
47
|
+
if (ifNoneMatch === "*") return true;
|
|
48
|
+
const normalize = (t) => t.replace(/^W\//, "");
|
|
49
|
+
const etagNorm = normalize(etag.trim());
|
|
50
|
+
for (const token of ifNoneMatch.split(",")) if (normalize(token.trim()) === etagNorm) return true;
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Returns true when a request `Cache-Control` header asks to bypass the 304
|
|
55
|
+
* short-circuit. Mirrors the `fresh` package's check used by Next.js's
|
|
56
|
+
* `sendEtagResponse` (`/(?:^|,)\s*?no-cache\s*?(?:,|$)/`). Shared by the
|
|
57
|
+
* fresh-MISS bot path here and the ISR HIT/STALE paths in
|
|
58
|
+
* `pages-page-data.ts` so the two cannot drift.
|
|
59
|
+
*/
|
|
60
|
+
function requestsNoCache(cacheControl) {
|
|
61
|
+
return /(?:^|,)\s*no-cache\s*(?:,|$)/.test(cacheControl ?? "");
|
|
62
|
+
}
|
|
14
63
|
function buildPagesFontHeadHtml(fontLinks, fontPreloads, fontStyles, scriptNonce) {
|
|
15
64
|
let html = "";
|
|
16
65
|
const nonceAttr = createNonceAttribute(scriptNonce);
|
|
17
|
-
for (const link of fontLinks) html += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(link)}" />\n `;
|
|
18
|
-
for (const preload of fontPreloads) html += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(preload.href)}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n `;
|
|
66
|
+
for (const link of fontLinks) html += `<link rel="stylesheet"${nonceAttr} href="${escapeHtmlAttr(appendAssetDeploymentIdQuery(link))}" />\n `;
|
|
67
|
+
for (const preload of fontPreloads) html += `<link rel="preload"${nonceAttr} href="${escapeHtmlAttr(appendAssetDeploymentIdQuery(preload.href))}" as="font" type="${escapeHtmlAttr(preload.type)}" crossorigin />\n `;
|
|
19
68
|
if (fontStyles.length > 0) html += `<style data-vinext-fonts${nonceAttr}>${fontStyles.join("\n")}</style>\n `;
|
|
20
69
|
return html;
|
|
21
70
|
}
|
|
22
71
|
function buildPagesNextDataScript(options) {
|
|
23
72
|
const nextDataPayload = {
|
|
24
|
-
props: { pageProps: options.pageProps },
|
|
73
|
+
props: options.props ?? { pageProps: options.pageProps },
|
|
25
74
|
page: options.routePattern,
|
|
26
75
|
query: options.params,
|
|
27
76
|
buildId: options.buildId,
|
|
@@ -123,6 +172,7 @@ function applyGsspHeaders(headers, gsspRes, statusCode) {
|
|
|
123
172
|
return statusCode ?? gsspRes.statusCode;
|
|
124
173
|
}
|
|
125
174
|
async function renderPagesPageResponse(options) {
|
|
175
|
+
const renderProps = options.props ?? { pageProps: options.pageProps };
|
|
126
176
|
options.resetSSRHead?.();
|
|
127
177
|
await options.flushPreloads?.();
|
|
128
178
|
const fontHeadHTML = buildPagesFontHeadHtml(options.getFontLinks(), options.fontPreloads, options.getFontStyles(), options.scriptNonce);
|
|
@@ -131,6 +181,7 @@ async function renderPagesPageResponse(options) {
|
|
|
131
181
|
i18n: options.i18n,
|
|
132
182
|
isFallback: options.isFallback,
|
|
133
183
|
pageProps: options.pageProps,
|
|
184
|
+
props: renderProps,
|
|
134
185
|
params: options.params,
|
|
135
186
|
routePattern: options.routePattern,
|
|
136
187
|
safeJsonStringify: options.safeJsonStringify,
|
|
@@ -157,7 +208,7 @@ async function renderPagesPageResponse(options) {
|
|
|
157
208
|
controller.close();
|
|
158
209
|
} });
|
|
159
210
|
else {
|
|
160
|
-
const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(
|
|
211
|
+
const pageElement = withScriptNonce(React.createElement(React.Fragment, null, options.createPageElement(renderProps)), options.scriptNonce);
|
|
161
212
|
bodyStream = await options.renderToReadableStream(pageElement);
|
|
162
213
|
}
|
|
163
214
|
if (documentRenderPage.status === "skipped") await callDocumentGetInitialProps(options.DocumentComponent, options.setDocumentInitialHead);
|
|
@@ -201,21 +252,34 @@ async function renderPagesPageResponse(options) {
|
|
|
201
252
|
}
|
|
202
253
|
const compositeStream = await buildPagesCompositeStream(responseBodyStream, shellPrefix, shellSuffix);
|
|
203
254
|
const userSetCacheControl = responseHeaders.has("Cache-Control");
|
|
204
|
-
if (options.scriptNonce) responseHeaders.set("Cache-Control",
|
|
255
|
+
if (options.scriptNonce) responseHeaders.set("Cache-Control", NO_STORE_CACHE_CONTROL);
|
|
205
256
|
else if (options.isrRevalidateSeconds) {
|
|
206
257
|
const isrPathname = options.routeUrl.split("?")[0];
|
|
207
258
|
const stem = isrPathname.endsWith("/") ? isrPathname.slice(0, -1) : isrPathname;
|
|
208
259
|
applyCdnResponseHeaders(responseHeaders, {
|
|
209
|
-
cacheControl:
|
|
260
|
+
cacheControl: buildMissIsrCacheControl(options.isrRevalidateSeconds, options.expireSeconds),
|
|
210
261
|
tags: [encodeCacheTag(`_N_T_${stem || "/"}`)]
|
|
211
262
|
});
|
|
212
263
|
setCacheStateHeaders(responseHeaders, "MISS");
|
|
213
|
-
} else if (options.gsspRes && !userSetCacheControl) responseHeaders.set("Cache-Control",
|
|
264
|
+
} else if (options.gsspRes && !userSetCacheControl) responseHeaders.set("Cache-Control", NEVER_CACHE_CONTROL);
|
|
214
265
|
if (options.fontLinkHeader) responseHeaders.set("Link", options.fontLinkHeader);
|
|
266
|
+
if (options.userAgent && isPagesStreamingBot(options.userAgent)) {
|
|
267
|
+
const fullHtml = await readStreamAsText(compositeStream);
|
|
268
|
+
const etag = generatePagesETag(fullHtml);
|
|
269
|
+
responseHeaders.set("ETag", etag);
|
|
270
|
+
if (!requestsNoCache(options.requestCacheControl) && options.ifNoneMatch && etagMatches(etag, options.ifNoneMatch)) return new Response(null, {
|
|
271
|
+
status: 304,
|
|
272
|
+
headers: responseHeaders
|
|
273
|
+
});
|
|
274
|
+
return new Response(fullHtml, {
|
|
275
|
+
status: finalStatus,
|
|
276
|
+
headers: responseHeaders
|
|
277
|
+
});
|
|
278
|
+
}
|
|
215
279
|
return Object.assign(new Response(compositeStream, {
|
|
216
280
|
status: finalStatus,
|
|
217
281
|
headers: responseHeaders
|
|
218
282
|
}), { __vinextStreamedHtmlResponse: true });
|
|
219
283
|
}
|
|
220
284
|
//#endregion
|
|
221
|
-
export { buildPagesNextDataScript, renderPagesPageResponse };
|
|
285
|
+
export { buildPagesNextDataScript, etagMatches, generatePagesETag, isPagesStreamingBot, renderPagesPageResponse, requestsNoCache };
|
|
@@ -5,6 +5,7 @@ import { HeaderRecord } from "./request-pipeline.js";
|
|
|
5
5
|
type PagesRenderOptions = {
|
|
6
6
|
isDataReq?: boolean;
|
|
7
7
|
renderErrorPageOnMiss?: boolean;
|
|
8
|
+
originalUrl?: string;
|
|
8
9
|
};
|
|
9
10
|
type MiddlewareResult = {
|
|
10
11
|
continue: boolean;
|
|
@@ -62,6 +63,20 @@ type PagesPipelineDeps = {
|
|
|
62
63
|
*/
|
|
63
64
|
serveStaticFile?: ((requestPathname: string, stagedHeaders: HeaderRecord) => Promise<boolean>) | null;
|
|
64
65
|
};
|
|
66
|
+
/**
|
|
67
|
+
* Wrap an adapter's `runMiddleware` callback so middleware receives the original
|
|
68
|
+
* (pre-basePath-stripping) URL. Adapters strip the basePath before handing the
|
|
69
|
+
* request to `runPagesRequest`, but Next.js passes the un-stripped URL to the
|
|
70
|
+
* middleware adapter so `request.nextUrl.basePath` reflects whether the URL
|
|
71
|
+
* actually had the basePath prefix. Requests outside the basePath
|
|
72
|
+
* (`hadBasePath === false`) are passed through untouched so middleware sees
|
|
73
|
+
* `nextUrl.basePath === ""` and can redirect them into the basePath
|
|
74
|
+
* (see the middleware-base-path e2e test / #1830).
|
|
75
|
+
*
|
|
76
|
+
* Shared by the Node prod server (prod-server.ts) and the generated Pages
|
|
77
|
+
* Router worker entry (deploy.ts) to keep the two adapters in sync.
|
|
78
|
+
*/
|
|
79
|
+
declare function wrapMiddlewareWithBasePath(runMiddleware: NonNullable<PagesPipelineDeps["runMiddleware"]>, basePath: string, hadBasePath: boolean): NonNullable<PagesPipelineDeps["runMiddleware"]>;
|
|
65
80
|
type PagesPipelineResult = {
|
|
66
81
|
type: "response";
|
|
67
82
|
response: Response;
|
|
@@ -96,4 +111,4 @@ type PagesPipelineResult = {
|
|
|
96
111
|
*/
|
|
97
112
|
declare function runPagesRequest(request: Request, deps: PagesPipelineDeps): Promise<PagesPipelineResult>;
|
|
98
113
|
//#endregion
|
|
99
|
-
export { MiddlewareResult, PagesPipelineDeps, PagesPipelineResult, PagesRenderOptions, runPagesRequest };
|
|
114
|
+
export { MiddlewareResult, PagesPipelineDeps, PagesPipelineResult, PagesRenderOptions, runPagesRequest, wrapMiddlewareWithBasePath };
|