vinext 1.2.0 → 1.3.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 +13 -10
- package/dist/build/client-build-config.d.ts +64 -3
- package/dist/build/client-build-config.js +131 -4
- package/dist/build/client-reference-groups.d.ts +163 -0
- package/dist/build/client-reference-groups.js +534 -0
- package/dist/build/module-dependency-cache.d.ts +31 -0
- package/dist/build/module-dependency-cache.js +51 -1
- package/dist/build/next-client-runtime-manifests.d.ts +10 -1
- package/dist/build/next-client-runtime-manifests.js +19 -4
- package/dist/build/nitro-public-files.d.ts +24 -0
- package/dist/build/nitro-public-files.js +60 -0
- package/dist/build/output-root-externals.d.ts +21 -0
- package/dist/build/output-root-externals.js +40 -0
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/prerender-paths.js +6 -3
- package/dist/build/prerender.js +1 -1
- package/dist/build/server-actions-encryption-key.d.ts +23 -0
- package/dist/build/server-actions-encryption-key.js +101 -0
- package/dist/build/ssr-manifest.d.ts +3 -0
- package/dist/build/ssr-manifest.js +10 -1
- package/dist/check.js +5 -6
- package/dist/cli-dev-config.js +3 -3
- package/dist/cli.js +1 -1
- package/dist/client/client-rewrite-params.d.ts +9 -0
- package/dist/client/client-rewrite-params.js +20 -0
- package/dist/client/dev-error-overlay.js +2 -1
- package/dist/client/navigation-runtime.d.ts +25 -2
- package/dist/client/navigation-runtime.js +42 -11
- package/dist/client/vinext-next-data.d.ts +0 -1
- package/dist/config/config-matchers.d.ts +15 -40
- package/dist/config/config-matchers.js +195 -262
- package/dist/config/config-source.d.ts +34 -0
- package/dist/config/config-source.js +141 -0
- package/dist/config/header-params.d.ts +29 -0
- package/dist/config/header-params.js +106 -0
- package/dist/config/next-config.d.ts +7 -5
- package/dist/config/next-config.js +120 -7
- package/dist/entries/app-browser-entry.d.ts +14 -1
- package/dist/entries/app-browser-entry.js +26 -36
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +92 -57
- package/dist/entries/app-rsc-manifest.d.ts +10 -0
- package/dist/entries/app-rsc-manifest.js +20 -1
- package/dist/entries/app-ssr-entry.d.ts +4 -1
- package/dist/entries/app-ssr-entry.js +9 -2
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +6 -6
- package/dist/entries/pages-server-entry.js +17 -14
- package/dist/index.d.ts +11 -0
- package/dist/index.js +350 -175
- package/dist/init.d.ts +1 -1
- package/dist/init.js +103 -6
- package/dist/plugins/ast-utils.d.ts +53 -2
- package/dist/plugins/ast-utils.js +90 -2
- package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
- package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
- package/dist/plugins/commonjs-esm-facade.js +2 -2
- package/dist/plugins/css-module-imports.js +13 -20
- package/dist/plugins/dynamic-preload-metadata.js +2 -3
- package/dist/plugins/extensionless-dynamic-import.js +2 -3
- package/dist/plugins/fonts.d.ts +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +2 -3
- package/dist/plugins/import-meta-url.js +3 -4
- package/dist/plugins/instrumentation-client.js +3 -2
- package/dist/plugins/middleware-export-validation.js +2 -3
- package/dist/plugins/og-harfbuzz.js +2 -3
- package/dist/plugins/optimize-imports.d.ts +25 -2
- package/dist/plugins/optimize-imports.js +109 -24
- package/dist/plugins/pages-node-externals.js +2 -3
- package/dist/plugins/remove-console.js +2 -18
- package/dist/plugins/require-condition-resolution.js +3 -3
- package/dist/plugins/require-context.js +2 -3
- package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
- package/dist/plugins/rsc-client-reference-loaders.js +336 -18
- package/dist/plugins/strip-server-exports.js +3 -4
- package/dist/plugins/styled-jsx.js +2 -3
- package/dist/plugins/use-cache-callable.d.ts +26 -2
- package/dist/plugins/use-cache-callable.js +101 -36
- package/dist/plugins/worker-image-imports.d.ts +1 -0
- package/dist/plugins/worker-image-imports.js +31 -34
- package/dist/plugins/worker-use-server.js +38 -14
- package/dist/routing/app-route-graph.d.ts +1 -1
- package/dist/routing/browser-route-manifest.d.ts +43 -0
- package/dist/routing/browser-route-manifest.js +195 -0
- package/dist/routing/hashed-route-patterns.d.ts +4 -0
- package/dist/routing/hashed-route-patterns.js +22 -0
- package/dist/routing/optimistic-route-trie.d.ts +27 -0
- package/dist/routing/optimistic-route-trie.js +102 -0
- package/dist/routing/route-validation.d.ts +6 -1
- package/dist/routing/route-validation.js +26 -10
- package/dist/server/api-handler.js +1 -1
- package/dist/server/app-action-forwarding.d.ts +8 -0
- package/dist/server/app-action-forwarding.js +17 -3
- package/dist/server/app-browser-entry.js +149 -62
- package/dist/server/app-browser-error.d.ts +3 -1
- package/dist/server/app-browser-error.js +7 -2
- package/dist/server/app-browser-interception-context.d.ts +2 -2
- package/dist/server/app-browser-interception-context.js +1 -1
- package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
- package/dist/server/app-browser-mpa-navigation.js +6 -5
- package/dist/server/app-browser-navigation-controller.d.ts +17 -6
- package/dist/server/app-browser-navigation-controller.js +88 -26
- package/dist/server/app-browser-prefetch-response.js +2 -2
- package/dist/server/app-browser-state.d.ts +2 -2
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-supplemental-refresh.js +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +4 -4
- package/dist/server/app-client-reference-preloader.d.ts +23 -0
- package/dist/server/app-client-reference-preloader.js +30 -7
- package/dist/server/app-fallback-renderer.js +2 -1
- package/dist/server/app-middleware.d.ts +6 -0
- package/dist/server/app-middleware.js +8 -10
- package/dist/server/app-optimistic-routing.d.ts +8 -10
- package/dist/server/app-optimistic-routing.js +4 -95
- package/dist/server/app-page-boundary-render.js +8 -1
- package/dist/server/app-page-cache-render.js +1 -0
- package/dist/server/app-page-dispatch.js +3 -1
- package/dist/server/app-page-render.js +4 -2
- package/dist/server/app-page-rsc-render-status.d.ts +1 -0
- package/dist/server/app-page-rsc-render-status.js +1 -0
- package/dist/server/app-page-search-params-observation.d.ts +1 -4
- package/dist/server/app-page-search-params-observation.js +8 -10
- package/dist/server/app-page-stream.d.ts +7 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +12 -8
- package/dist/server/app-prerender-endpoints.js +1 -1
- package/dist/server/app-prerender-static-params.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +19 -0
- package/dist/server/app-render-abort-error.js +31 -1
- package/dist/server/app-render-dependency.js +42 -2
- package/dist/server/app-request-stage-independent-entry.js +7 -7
- package/dist/server/app-response-stage-entry.js +5 -5
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-execution.d.ts +2 -0
- package/dist/server/app-route-handler-execution.js +9 -2
- package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
- package/dist/server/app-route-handler-middleware-context.js +3 -3
- package/dist/server/app-route-handler-response.d.ts +2 -1
- package/dist/server/app-route-handler-response.js +2 -2
- package/dist/server/app-route-handler-runtime.d.ts +2 -0
- package/dist/server/app-route-handler-runtime.js +21 -4
- package/dist/server/app-route-module-loader.js +7 -6
- package/dist/server/app-route-tree.d.ts +20 -0
- package/dist/server/app-route-tree.js +18 -0
- package/dist/server/app-router-entry.js +7 -7
- package/dist/server/app-rsc-cache-busting.d.ts +16 -0
- package/dist/server/app-rsc-cache-busting.js +29 -12
- package/dist/server/app-rsc-combined-handler.js +8 -1
- package/dist/server/app-rsc-errors.d.ts +7 -0
- package/dist/server/app-rsc-errors.js +9 -2
- package/dist/server/app-rsc-handler.d.ts +4 -1
- package/dist/server/app-rsc-handler.js +151 -135
- package/dist/server/app-rsc-request-normalization.js +3 -3
- package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.js +5 -3
- package/dist/server/app-rsc-route-matching.d.ts +1 -0
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +23 -6
- package/dist/server/app-server-action-execution.js +51 -57
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +21 -11
- package/dist/server/app-ssr-stream.d.ts +7 -0
- package/dist/server/app-ssr-stream.js +13 -1
- package/dist/server/app-visited-response-cache.js +2 -2
- package/dist/server/config-headers.js +13 -4
- package/dist/server/defer-until-stream-consumed.d.ts +2 -1
- package/dist/server/defer-until-stream-consumed.js +3 -1
- package/dist/server/dev-server.js +1 -1
- package/dist/server/image-optimization.js +1 -0
- package/dist/server/isolate-shared-promise.d.ts +10 -0
- package/dist/server/isolate-shared-promise.js +33 -0
- package/dist/server/isr-cache.js +3 -2
- package/dist/server/metadata-route-response.js +2 -2
- package/dist/server/middleware-matcher-pattern.d.ts +0 -1
- package/dist/server/middleware-matcher-pattern.js +11 -140
- package/dist/server/middleware-matcher.js +5 -6
- package/dist/server/middleware-response-headers.d.ts +31 -0
- package/dist/server/middleware-response-headers.js +57 -1
- package/dist/server/middleware-runtime.js +30 -17
- package/dist/server/navigation-planner.d.ts +2 -2
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/nitro-public-files-plugin.d.ts +38 -0
- package/dist/server/nitro-public-files-plugin.js +106 -0
- package/dist/server/nitro-public-files.d.ts +21 -0
- package/dist/server/nitro-public-files.js +39 -0
- package/dist/server/open-redirect.d.ts +11 -4
- package/dist/server/open-redirect.js +11 -4
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +5 -0
- package/dist/server/pages-asset-tags.js +9 -2
- package/dist/server/pages-client-assets.d.ts +4 -1
- package/dist/server/pages-data-route.js +2 -1
- package/dist/server/pages-i18n.d.ts +18 -0
- package/dist/server/pages-i18n.js +18 -2
- package/dist/server/pages-node-compat.d.ts +5 -3
- package/dist/server/pages-node-compat.js +35 -16
- package/dist/server/pages-page-data.js +1 -1
- package/dist/server/pages-page-handler.js +1 -1
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +6 -1
- package/dist/server/pages-request-pipeline.js +35 -39
- package/dist/server/pages-request-stage-entry.js +20 -10
- package/dist/server/pages-response-stage-entry.js +1 -1
- package/dist/server/pages-revalidate.js +3 -2
- package/dist/server/pages-router-entry.js +2 -2
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +74 -36
- package/dist/server/proxy-trust.d.ts +6 -0
- package/dist/server/proxy-trust.js +12 -6
- package/dist/server/request-pipeline.d.ts +5 -0
- package/dist/server/request-pipeline.js +12 -1
- package/dist/server/rsc-stream-hints.d.ts +1 -1
- package/dist/server/rsc-stream-hints.js +21 -3
- package/dist/server/server-reference-loader.js +10 -1
- package/dist/server/static-file-cache.js +15 -3
- package/dist/server/worker-image-optimization.js +19 -6
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/cache-handler.js +3 -2
- package/dist/shims/cache-request-state.d.ts +40 -3
- package/dist/shims/cache-request-state.js +70 -5
- package/dist/shims/cache-runtime.js +47 -19
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +17 -8
- package/dist/shims/cdn-purge-routes.d.ts +24 -0
- package/dist/shims/cdn-purge-routes.js +77 -0
- package/dist/shims/dynamic.js +17 -4
- package/dist/shims/form.js +8 -3
- package/dist/shims/head.js +1 -1
- package/dist/shims/headers.js +2 -2
- package/dist/shims/image-props.d.ts +93 -0
- package/dist/shims/image-props.js +323 -0
- package/dist/shims/image.d.ts +4 -18
- package/dist/shims/image.js +4 -319
- package/dist/shims/internal/headers-state.d.ts +7 -0
- package/dist/shims/internal/headers-state.js +14 -2
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +32 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -8
- package/dist/shims/link-prefetch.js +5 -4
- package/dist/shims/link.js +7 -5
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +21 -10
- package/dist/shims/og.js +35 -10
- package/dist/shims/request-context.d.ts +13 -0
- package/dist/shims/router.js +28 -52
- package/dist/shims/server.d.ts +42 -8
- package/dist/shims/server.js +99 -15
- package/dist/shims/thenable-params.d.ts +6 -1
- package/dist/shims/thenable-params.js +11 -2
- package/dist/shims/unified-request-context.d.ts +5 -0
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/url-utils.d.ts +7 -0
- package/dist/shims/url-utils.js +12 -3
- package/dist/utils/asset-prefix.d.ts +7 -0
- package/dist/utils/asset-prefix.js +10 -1
- package/dist/utils/client-build-manifest.js +12 -5
- package/dist/utils/client-runtime-metadata.d.ts +1 -0
- package/dist/utils/client-runtime-metadata.js +15 -2
- package/dist/utils/domain-locale.js +1 -1
- package/dist/utils/lazy-chunks.d.ts +4 -0
- package/dist/utils/manifest-paths.d.ts +14 -0
- package/dist/utils/manifest-paths.js +22 -1
- package/dist/utils/path-to-regexp.d.ts +21 -0
- package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
- package/dist/utils/plugin-react-version.d.ts +15 -0
- package/dist/utils/plugin-react-version.js +64 -0
- package/dist/utils/plugin-rsc-version.d.ts +2 -0
- package/dist/utils/plugin-rsc-version.js +28 -2
- package/dist/utils/public-routes.d.ts +2 -0
- package/dist/utils/public-routes.js +18 -7
- package/dist/utils/react-version.d.ts +7 -0
- package/dist/utils/react-version.js +39 -16
- package/package.json +6 -6
- package/dist/build/nitro-route-rules.d.ts +0 -47
- package/dist/build/nitro-route-rules.js +0 -79
- package/dist/plugins/cache-flight-codec.d.ts +0 -19
- package/dist/plugins/cache-flight-codec.js +0 -68
- package/dist/server/middleware-path-to-regexp.d.ts +0 -13
- package/dist/utils/regex-safety.d.ts +0 -17
- package/dist/utils/regex-safety.js +0 -789
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
|
|
2
2
|
import { requestContextFromRequest } from "../config/request-context.js";
|
|
3
|
-
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
4
|
-
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
5
3
|
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
6
|
-
import { runWithExecutionContext } from "../shims/request-context.js";
|
|
7
4
|
import { VINEXT_CACHEABILITY_PROBE_QUERY_PARAM, VINEXT_EXPECTED_WORKER_VERSION_HEADER } from "./headers.js";
|
|
8
5
|
import { notFoundStaticAssetResponse } from "./http-error-responses.js";
|
|
9
6
|
import { attachRequestCfMetadata, cloneRequestWithHeaders, cloneRequestWithUrl, filterInternalHeaders, guardProtocolRelativeUrl } from "./request-pipeline.js";
|
|
10
|
-
import {
|
|
7
|
+
import { assetPrefixPathname, isNextStaticPath } from "../utils/asset-prefix.js";
|
|
8
|
+
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
9
|
+
import { runWithExecutionContext } from "../shims/request-context.js";
|
|
10
|
+
import { normalizeDefaultLocalePathname, shouldRestoreLocaleRootTrailingSlash } from "./pages-i18n.js";
|
|
11
11
|
import { isNextDataPathname } from "./pages-data-route.js";
|
|
12
12
|
import { getExplicitCdnCacheAdapter } from "../shims/cdn-cache-state.js";
|
|
13
13
|
import { CACHEABILITY_REQUEST_STATE } from "../shims/cacheability-classification.js";
|
|
@@ -48,6 +48,10 @@ const pagesRequestStagePrerenderSecret = pagesEntry.prerenderSecret ?? null;
|
|
|
48
48
|
const basePath = vinextConfig?.basePath ?? "";
|
|
49
49
|
const assetPathPrefix = assetPrefixPathname(vinextConfig?.assetPrefix ?? "");
|
|
50
50
|
const trailingSlash = vinextConfig?.trailingSlash ?? false;
|
|
51
|
+
const localeRootTrailingSlashConfig = {
|
|
52
|
+
trailingSlash,
|
|
53
|
+
skipProxyUrlNormalize: vinextConfig?.skipProxyUrlNormalize
|
|
54
|
+
};
|
|
51
55
|
const skipTrailingSlashRedirect = vinextConfig?.skipTrailingSlashRedirect ?? false;
|
|
52
56
|
const i18nConfig = vinextConfig?.i18n ?? null;
|
|
53
57
|
const configRedirects = vinextConfig?.redirects ?? [];
|
|
@@ -88,7 +92,7 @@ function handleRequestStageLocally(request, env, ctx, dispatchResponseStage) {
|
|
|
88
92
|
function handleRequest(request, env, platformCtx, dispatchResponseStage, forceCacheBypass, defaultHostRuntime, assets) {
|
|
89
93
|
const url = new URL(request.url);
|
|
90
94
|
const trace = async () => {
|
|
91
|
-
await pagesEntry.__ensureInstrumentation?.();
|
|
95
|
+
await pagesEntry.__ensureInstrumentation?.(platformCtx);
|
|
92
96
|
return traceFrameworkRequest({
|
|
93
97
|
callback: () => handleRequestImpl(request, env, platformCtx, dispatchResponseStage, forceCacheBypass, defaultHostRuntime, assets),
|
|
94
98
|
getStatus: (response) => response?.status,
|
|
@@ -128,7 +132,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
128
132
|
probeRoute = readWorkerCacheabilityProbeRoute(request);
|
|
129
133
|
const probeUrl = new URL(request.url);
|
|
130
134
|
probeUrl.searchParams.delete(VINEXT_CACHEABILITY_PROBE_QUERY_PARAM);
|
|
131
|
-
request =
|
|
135
|
+
request = cloneRequestWithUrl(request, probeUrl.href);
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
138
|
let responseStageDispatched = false;
|
|
@@ -175,6 +179,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
175
179
|
}
|
|
176
180
|
const missingBuildAsset = isNextStaticPath(pathname, basePath, assetPathPrefix);
|
|
177
181
|
const hadBasePath = !basePath || hasBasePath(pathname, basePath);
|
|
182
|
+
const restoreLocaleRootTrailingSlash = shouldRestoreLocaleRootTrailingSlash(pathname, localeRootTrailingSlashConfig);
|
|
178
183
|
{
|
|
179
184
|
const stripped = stripBasePath(pathname, basePath);
|
|
180
185
|
if (stripped !== pathname) {
|
|
@@ -193,7 +198,10 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
193
198
|
request = dataNorm.request;
|
|
194
199
|
pathname = dataNorm.normalizedPathname;
|
|
195
200
|
}
|
|
196
|
-
const responseStagePolicyPathname = i18nConfig ? normalizeDefaultLocalePathname(pathname, i18nConfig, {
|
|
201
|
+
const responseStagePolicyPathname = i18nConfig ? normalizeDefaultLocalePathname(pathname, i18nConfig, {
|
|
202
|
+
hostname: url.hostname,
|
|
203
|
+
restoreRootTrailingSlash: restoreLocaleRootTrailingSlash
|
|
204
|
+
}) : pathname;
|
|
197
205
|
const responseStagePolicyHeaders = resolveResponseStageCachePolicy({
|
|
198
206
|
basePathState: {
|
|
199
207
|
basePath,
|
|
@@ -219,6 +227,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
219
227
|
hasMiddleware,
|
|
220
228
|
ctx,
|
|
221
229
|
recordCacheability: forceCacheBypass,
|
|
230
|
+
restoreLocaleRootTrailingSlash,
|
|
222
231
|
middlewareRequest: isDataReq && vinextConfig?.skipProxyUrlNormalize ? middlewareRequest : void 0,
|
|
223
232
|
dataNotFoundResponse: vinextConfig?.skipProxyUrlNormalize ? dataNorm.notFoundResponse : null,
|
|
224
233
|
authorizeOnDemandRevalidate: typeof authorizeOnDemandRevalidate === "function" ? authorizeOnDemandRevalidate : void 0,
|
|
@@ -320,7 +329,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
320
329
|
fetchPublicFile: (sourceRequest) => resolvePublicImageSource(sourceRequest, assets)
|
|
321
330
|
}), allowedWidths, imageConfig);
|
|
322
331
|
}
|
|
323
|
-
return fetchWorkerFilesystemRoute(filesystemRequest, requestPathname, phase, (assetRequest) => Promise.resolve(assets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix,
|
|
332
|
+
return fetchWorkerFilesystemRoute(filesystemRequest, requestPathname, phase, (assetRequest) => Promise.resolve(assets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix, resolvedPathnameHasBasePath);
|
|
324
333
|
}
|
|
325
334
|
};
|
|
326
335
|
const resolvePublicImageSource = async (sourceRequest, sourceAssets) => {
|
|
@@ -333,6 +342,7 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
333
342
|
const sourceResult = await runPagesRequest(attachRequestCfMetadata(new Request(new URL(sourcePathname + sourceUrl.search, sourceUrl), { signal: sourceRequest.signal }), sourceRequest), {
|
|
334
343
|
...deps,
|
|
335
344
|
hadBasePath: sourceHadBasePath,
|
|
345
|
+
restoreLocaleRootTrailingSlash: shouldRestoreLocaleRootTrailingSlash(sourceUrl.pathname, localeRootTrailingSlashConfig),
|
|
336
346
|
isDataReq: false,
|
|
337
347
|
isDataRequest: false,
|
|
338
348
|
middlewareRequest: void 0,
|
|
@@ -341,9 +351,9 @@ async function handleRequestImpl(request, env, platformCtx, dispatchResponseStag
|
|
|
341
351
|
runMiddleware: typeof runMiddleware === "function" ? wrapMiddlewareWithBasePath(runMiddleware, basePath, sourceHadBasePath) : null,
|
|
342
352
|
renderPage: null,
|
|
343
353
|
handleApi: null,
|
|
344
|
-
serveFilesystemRoute: async (candidate, _stagedHeaders, phase, _resolvedUrl, filesystemRequest) => {
|
|
354
|
+
serveFilesystemRoute: async (candidate, _stagedHeaders, phase, _resolvedUrl, filesystemRequest, candidateHasBasePath) => {
|
|
345
355
|
if (isImageOptimizationPath(candidate)) return false;
|
|
346
|
-
const asset = await fetchWorkerFilesystemRoute(filesystemRequest, candidate, phase, (assetRequest) => Promise.resolve(sourceAssets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix,
|
|
356
|
+
const asset = await fetchWorkerFilesystemRoute(filesystemRequest, candidate, phase, (assetRequest) => Promise.resolve(sourceAssets.fetch(assetRequest)), publicFiles, basePath, assetPathPrefix, candidateHasBasePath);
|
|
347
357
|
if (asset === false) return false;
|
|
348
358
|
sourceAsset = asset;
|
|
349
359
|
return new Response(null);
|
|
@@ -36,7 +36,7 @@ async function renderPagesResponse(request, env, platformCtx, props, stagedHeade
|
|
|
36
36
|
if (!isPagesResponseStageProps(props)) return new Response("Invalid vinext Pages response stage", { status: 400 });
|
|
37
37
|
if (props.buildId !== pagesEntry.buildId) return new Response("Vinext Pages response stage deployment mismatch", { status: 409 });
|
|
38
38
|
if (props.requestHost !== new URL(request.url).host) return new Response("Invalid vinext Pages response stage", { status: 400 });
|
|
39
|
-
await pagesEntry.__ensureInstrumentation?.();
|
|
39
|
+
await pagesEntry.__ensureInstrumentation?.(platformCtx);
|
|
40
40
|
registerConfiguredImageOptimizer(env);
|
|
41
41
|
const renderHeaders = new Headers(stagedHeaders ?? props.stagedHeaders ?? []);
|
|
42
42
|
renderHeaders.delete("Content-Length");
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, VINEXT_REVALIDATE_HOST_HEADER } from "../utils/protocol-headers.js";
|
|
2
|
-
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
3
2
|
import { VINEXT_REVALIDATED_CACHE_TAG_HEADER } from "./headers.js";
|
|
3
|
+
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
4
|
+
import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
|
|
4
5
|
import { normalizeDomainHostname } from "../utils/domain-locale.js";
|
|
5
6
|
import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
|
|
6
7
|
import { getRevalidateSecret, isOnDemandRevalidateRequest } from "./revalidation-request.js";
|
|
7
8
|
import "./isr-cache.js";
|
|
8
|
-
import { resolveRequestHost, resolveRequestProtocol } from "./proxy-trust.js";
|
|
9
9
|
//#region src/server/pages-revalidate.ts
|
|
10
10
|
async function performOnDemandRevalidate(source, urlPath, opts = {}, trustedOrigin, allowedRevalidateHeaderKeys = [], dev = false) {
|
|
11
11
|
if (typeof urlPath !== "string" || !urlPath.startsWith("/")) throw new Error(`Invalid urlPath provided to revalidate(), must be a path e.g. /blog/post-1, received ${urlPath}`);
|
|
12
12
|
if (isSourceRevalidationRequest(source)) throw new Error(`Cannot revalidate ${urlPath} from an internal revalidation request`);
|
|
13
13
|
const executionContext = getRequestExecutionContext();
|
|
14
14
|
const dispatchRevalidate = executionContext?.dispatchPagesRevalidate;
|
|
15
|
+
if (!dispatchRevalidate && !trustedOrigin) throw new Error(`Cannot revalidate ${urlPath}: no in-process dispatcher or server-owned origin is available`);
|
|
15
16
|
const target = createRevalidateTarget(source, urlPath, trustedOrigin);
|
|
16
17
|
const headers = { [PRERENDER_REVALIDATE_HEADER]: getRevalidateSecret() };
|
|
17
18
|
if (trustedOrigin && !dispatchRevalidate) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { runWithExecutionContext } from "../shims/request-context.js";
|
|
2
1
|
import { VINEXT_CACHEABILITY_PROBE_HEADER, VINEXT_CACHEABILITY_PROBE_QUERY_PARAM } from "./headers.js";
|
|
3
2
|
import { cloneRequestWithHeaders, cloneRequestWithUrl } from "./request-pipeline.js";
|
|
3
|
+
import { runWithExecutionContext } from "../shims/request-context.js";
|
|
4
4
|
import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
|
|
5
5
|
import { validateCdnRequest } from "./cache-control.js";
|
|
6
6
|
import { createWorkerRevalidationContext } from "./worker-revalidation-context.js";
|
|
@@ -20,7 +20,7 @@ async function handleSingleStageRequest(request, env, platformCtx) {
|
|
|
20
20
|
let ctx = createWorkerPrerenderDiscoveryContext(ctxWithRevalidation, request, pagesRequestStagePrerenderSecret);
|
|
21
21
|
const readinessResponse = createWorkerPrerenderReadinessResponse(ctx, request);
|
|
22
22
|
if (readinessResponse) {
|
|
23
|
-
if (readinessResponse.status === 204) await Promise.all([__ensureInstrumentation(), __ensureInstrumentation$1()]);
|
|
23
|
+
if (readinessResponse.status === 204) await Promise.all([__ensureInstrumentation(ctx), __ensureInstrumentation$1(ctx)]);
|
|
24
24
|
return await validateCdnRequest(request) ?? readinessResponse;
|
|
25
25
|
}
|
|
26
26
|
const isClientBuildFile = isPagesClientBuildFileRequest(request, env, ctx);
|
|
@@ -3,7 +3,7 @@ import { negotiateEncoding } from "./accept-encoding.js";
|
|
|
3
3
|
import { StaticFileCache } from "./static-file-cache.js";
|
|
4
4
|
import { resolveRequestHost, trustProxy, trustedHosts } from "./proxy-trust.js";
|
|
5
5
|
import { COMPRESS_THRESHOLD, isCompressibleContentType } from "./response-compression.js";
|
|
6
|
-
import { IncomingMessage, ServerResponse } from "node:http";
|
|
6
|
+
import { IncomingMessage, Server, ServerResponse } from "node:http";
|
|
7
7
|
//#region src/server/prod-server.d.ts
|
|
8
8
|
/**
|
|
9
9
|
* Import a built server entry module (App Router RSC entry or Pages Router
|
|
@@ -127,7 +127,7 @@ declare function waitForNodeResponseCompletion(res: ServerResponse): Promise<voi
|
|
|
127
127
|
* Pages Router (dist/server/entry.js) and configures the appropriate handler.
|
|
128
128
|
*/
|
|
129
129
|
export declare function startProdServer(options?: ProdServerOptions): Promise<{
|
|
130
|
-
server:
|
|
130
|
+
server: Server<typeof IncomingMessage, typeof ServerResponse>;
|
|
131
131
|
port: number;
|
|
132
132
|
}>;
|
|
133
133
|
type AppRouterPrerenderSeeder = (serverDir: string) => Promise<number>;
|
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { isUnknownRecord } from "../utils/record.js";
|
|
3
3
|
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_SPECULATIVE_HEADER } from "../utils/protocol-headers.js";
|
|
4
|
-
import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix } from "../utils/asset-prefix.js";
|
|
5
|
-
import { StaticFileCache, contentTypeForPath, etagFromFilenameHash } from "./static-file-cache.js";
|
|
6
|
-
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
7
4
|
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
8
5
|
import { VINEXT_PRERENDER_RENDER_ERROR_HEADER, VINEXT_PRERENDER_SPECIAL_ERROR_HEADER } from "./headers.js";
|
|
9
|
-
import { normalizePath } from "./normalize-path.js";
|
|
10
6
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
11
7
|
import { getRepeatedSlashRedirect, isOpenRedirectShaped, sendRepeatedSlashRedirect } from "./open-redirect.js";
|
|
12
8
|
import { readStaticFileSignal } from "./static-file-signal.js";
|
|
13
9
|
import { canonicalizeRequestPathname, filterInternalHeaders } from "./request-pipeline.js";
|
|
10
|
+
import { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix, isAssetPrefixBuildAsset } from "../utils/asset-prefix.js";
|
|
11
|
+
import { StaticFileCache, contentTypeForPath, etagFromFilenameHash } from "./static-file-cache.js";
|
|
12
|
+
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
13
|
+
import { resolveRequestHost, resolveRequestProtocol, resolveTrustedForwardedHost, trustProxy, trustedHosts } from "./proxy-trust.js";
|
|
14
|
+
import { normalizePath } from "./normalize-path.js";
|
|
15
|
+
import { shouldRestoreLocaleRootTrailingSlash } from "./pages-i18n.js";
|
|
14
16
|
import { buildNextDataNotFoundResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath } from "./pages-data-route.js";
|
|
15
17
|
import { buildCacheStateHeaders } from "./cache-headers.js";
|
|
16
18
|
import { parseHttpDate } from "./http-date.js";
|
|
17
19
|
import { evaluateStaticPreconditions } from "./http-conditional.js";
|
|
18
20
|
import { setPagesClientAssets } from "./pages-client-assets.js";
|
|
19
|
-
import { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts } from "./proxy-trust.js";
|
|
20
21
|
import { signalFromNodeResponse } from "./node-response-signal.js";
|
|
21
22
|
import { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, IMAGE_RESPONSE_CACHE_STATE, INVALID_IMAGE_SOURCE_MESSAGE, isImageOptimizationPath, isImageSourceBodyStatus, isSafeImageContentType, parseImageParams, readImageOptimizationSignal } from "./image-optimization.js";
|
|
22
23
|
import { installSocketErrorBackstop } from "./socket-error-backstop.js";
|
|
@@ -378,6 +379,19 @@ function isVinextStreamedHtmlResponse(response) {
|
|
|
378
379
|
function isVinextStreamedApiResponse(response) {
|
|
379
380
|
return response.__vinextStreamedApiResponse === true;
|
|
380
381
|
}
|
|
382
|
+
function disablePrerenderKeepAliveTimeout(server, purpose) {
|
|
383
|
+
if (purpose === "prerender") server.keepAliveTimeout = 0;
|
|
384
|
+
}
|
|
385
|
+
function listen(server, port, host) {
|
|
386
|
+
return new Promise((resolve, reject) => {
|
|
387
|
+
server.once("error", reject);
|
|
388
|
+
server.listen(port, host, () => {
|
|
389
|
+
server.off("error", reject);
|
|
390
|
+
const addr = server.address();
|
|
391
|
+
resolve(typeof addr === "object" && addr ? addr.port : port);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
}
|
|
381
395
|
function logProdServerStarted(host, port, purpose) {
|
|
382
396
|
const url = `http://${host}:${port}`;
|
|
383
397
|
if (purpose === "prerender") {
|
|
@@ -925,14 +939,16 @@ async function startProdServer(options = {}) {
|
|
|
925
939
|
silent
|
|
926
940
|
});
|
|
927
941
|
}
|
|
928
|
-
function createNodeExecutionContext(trustedRevalidateOrigin) {
|
|
942
|
+
function createNodeExecutionContext(trustedRevalidateOrigin, { middlewareOrigin, requestSignal } = {}) {
|
|
929
943
|
return {
|
|
930
944
|
hostRuntime: "node",
|
|
945
|
+
requestSignal,
|
|
931
946
|
waitUntil(promise) {
|
|
932
947
|
Promise.resolve(promise).catch(() => {});
|
|
933
948
|
},
|
|
934
949
|
passThroughOnException() {},
|
|
935
|
-
trustedRevalidateOrigin
|
|
950
|
+
trustedRevalidateOrigin,
|
|
951
|
+
middlewareOrigin
|
|
936
952
|
};
|
|
937
953
|
}
|
|
938
954
|
/**
|
|
@@ -953,8 +969,26 @@ function markPrerenderSpecialError(response, marker) {
|
|
|
953
969
|
});
|
|
954
970
|
}
|
|
955
971
|
function resolveTrustedNodeRevalidateOrigin(req, configuredHost, configuredPort) {
|
|
972
|
+
return `http://${resolveNodeServerHost(req, configuredHost, configuredPort)}`;
|
|
973
|
+
}
|
|
974
|
+
/**
|
|
975
|
+
* The origin middleware runs against. The Host header is client-controlled,
|
|
976
|
+
* so, like Next.js, which builds the middleware URL from its own hostname and
|
|
977
|
+
* port, it never counts as the server's origin. Otherwise a client could send
|
|
978
|
+
* the host of an external middleware rewrite target and turn that rewrite into
|
|
979
|
+
* an internal one, skipping middleware's checks for the target path. A trusted
|
|
980
|
+
* `X-Forwarded-Host` is operator-approved, so it keeps the request origin, and
|
|
981
|
+
* rewrites to that host stay internal.
|
|
982
|
+
*/
|
|
983
|
+
function resolveNodeMiddlewareOrigin(req, requestUrl, configuredHost, configuredPort) {
|
|
984
|
+
const url = new URL(requestUrl);
|
|
985
|
+
if (resolveTrustedForwardedHost(req) !== void 0) return url.origin;
|
|
986
|
+
return `${url.protocol}//${resolveNodeServerHost(req, configuredHost, configuredPort)}`;
|
|
987
|
+
}
|
|
988
|
+
/** The `host:port` this server is reachable at locally. */
|
|
989
|
+
function resolveNodeServerHost(req, configuredHost, configuredPort) {
|
|
956
990
|
const port = req.socket.localPort ?? configuredPort;
|
|
957
|
-
return
|
|
991
|
+
return `${normalizeInternalFetchHost(configuredHost)}:${port}`;
|
|
958
992
|
}
|
|
959
993
|
function normalizeInternalFetchHost(host) {
|
|
960
994
|
if (!host || host === "0.0.0.0" || host === "::") return "localhost";
|
|
@@ -1058,6 +1092,7 @@ function installPagesClientAssets(options) {
|
|
|
1058
1092
|
clientEntry: metadata.clientEntryFile,
|
|
1059
1093
|
appBootstrapPreinitModules: metadata.appBootstrapPreinitModules,
|
|
1060
1094
|
ssrManifest: Object.keys(ssrManifest).length > 0 ? ssrManifest : void 0,
|
|
1095
|
+
sharedChunks: metadata.sharedChunks,
|
|
1061
1096
|
cssGraph: metadata.cssGraph,
|
|
1062
1097
|
lazyChunks: metadata.lazyChunks,
|
|
1063
1098
|
dynamicPreloads: metadata.dynamicPreloads,
|
|
@@ -1154,7 +1189,7 @@ async function startAppRouterServer(options) {
|
|
|
1154
1189
|
const assetLookupPath = sourcePathname !== null ? resolveAppRouterAssetPath(sourcePathname, appAssetPathPrefix, appRouterAssetPrefix) : null;
|
|
1155
1190
|
if (assetLookupPath && await serveSource(assetLookupPath)) return;
|
|
1156
1191
|
if (sourcePathname !== null) {
|
|
1157
|
-
const sourceResponse = await rscHandler(new Request(sourceUrl, { signal: request.signal }), createNodeExecutionContext(resolveTrustedNodeRevalidateOrigin(req, host, port)));
|
|
1192
|
+
const sourceResponse = await rscHandler(new Request(sourceUrl, { signal: request.signal }), createNodeExecutionContext(resolveTrustedNodeRevalidateOrigin(req, host, port), { middlewareOrigin: resolveNodeMiddlewareOrigin(req, request.url, host, port) }));
|
|
1158
1193
|
const sourceSignal = isImageSourceBodyStatus(sourceResponse.status) ? readStaticFileSignal(sourceResponse) : null;
|
|
1159
1194
|
cancelResponseBody(sourceResponse, request.signal.reason);
|
|
1160
1195
|
if (request.signal.aborted) return;
|
|
@@ -1211,8 +1246,12 @@ async function startAppRouterServer(options) {
|
|
|
1211
1246
|
if (clientBuildFile && await tryServeStatic(req, res, clientDir, clientBuildFile, compress, staticCache)) return;
|
|
1212
1247
|
}
|
|
1213
1248
|
try {
|
|
1214
|
-
const
|
|
1215
|
-
const
|
|
1249
|
+
const signal = signalFromNodeResponse(res);
|
|
1250
|
+
const request = nodeToWebRequest(req, rawUrl, prerenderSecret, appRouterI18nConfig, appRouterAuthorizeOnDemandRevalidate, signal);
|
|
1251
|
+
const ctx = createNodeExecutionContext(resolveTrustedNodeRevalidateOrigin(req, host, port), {
|
|
1252
|
+
middlewareOrigin: resolveNodeMiddlewareOrigin(req, request.url, host, port),
|
|
1253
|
+
requestSignal: signal
|
|
1254
|
+
});
|
|
1216
1255
|
const recorded = {};
|
|
1217
1256
|
if (purpose === "prerender") ctx.recordPrerenderSpecialError = (marker) => {
|
|
1218
1257
|
recorded.marker = marker;
|
|
@@ -1282,18 +1321,12 @@ async function startAppRouterServer(options) {
|
|
|
1282
1321
|
const server = createServer((req, res) => {
|
|
1283
1322
|
runWithServerEntryRequire(rscEntryRequire, () => handleRequest(req, res));
|
|
1284
1323
|
});
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
const actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
1289
|
-
if (!silent) logProdServerStarted(host, actualPort, purpose);
|
|
1290
|
-
resolve();
|
|
1291
|
-
});
|
|
1292
|
-
});
|
|
1293
|
-
const addr = server.address();
|
|
1324
|
+
disablePrerenderKeepAliveTimeout(server, purpose);
|
|
1325
|
+
const actualPort = await listen(server, port, host);
|
|
1326
|
+
if (!silent) logProdServerStarted(host, actualPort, purpose);
|
|
1294
1327
|
return {
|
|
1295
1328
|
server,
|
|
1296
|
-
port:
|
|
1329
|
+
port: actualPort
|
|
1297
1330
|
};
|
|
1298
1331
|
}
|
|
1299
1332
|
function isPagesServerEntryPageRoute(value) {
|
|
@@ -1323,18 +1356,12 @@ async function startPagesRouterServer(options) {
|
|
|
1323
1356
|
const { port, host, purpose, silent } = options;
|
|
1324
1357
|
const handler = await createPagesRouterRequestHandler(options);
|
|
1325
1358
|
const server = createServer(handler);
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
const actualPort = typeof addr === "object" && addr ? addr.port : port;
|
|
1330
|
-
if (!silent) logProdServerStarted(host, actualPort, purpose);
|
|
1331
|
-
resolve();
|
|
1332
|
-
});
|
|
1333
|
-
});
|
|
1334
|
-
const addr = server.address();
|
|
1359
|
+
disablePrerenderKeepAliveTimeout(server, purpose);
|
|
1360
|
+
const actualPort = await listen(server, port, host);
|
|
1361
|
+
if (!silent) logProdServerStarted(host, actualPort, purpose);
|
|
1335
1362
|
return {
|
|
1336
1363
|
server,
|
|
1337
|
-
port:
|
|
1364
|
+
port: actualPort
|
|
1338
1365
|
};
|
|
1339
1366
|
}
|
|
1340
1367
|
/**
|
|
@@ -1481,6 +1508,10 @@ async function createPagesRouterRequestHandler(options) {
|
|
|
1481
1508
|
}
|
|
1482
1509
|
try {
|
|
1483
1510
|
const hadBasePath = !basePath || hasBasePath(requestPathname, basePath);
|
|
1511
|
+
const restoreLocaleRootTrailingSlash = shouldRestoreLocaleRootTrailingSlash(requestPathname, {
|
|
1512
|
+
trailingSlash,
|
|
1513
|
+
skipProxyUrlNormalize
|
|
1514
|
+
});
|
|
1484
1515
|
let configMatchPathname = stripBasePath(requestPathname, basePath);
|
|
1485
1516
|
{
|
|
1486
1517
|
const strippedPathname = stripBasePath(pathname, basePath);
|
|
@@ -1543,6 +1574,8 @@ async function createPagesRouterRequestHandler(options) {
|
|
|
1543
1574
|
duplex: hasBody ? "half" : void 0
|
|
1544
1575
|
});
|
|
1545
1576
|
const middlewareRequest = isDataReq && skipProxyUrlNormalize ? new Request(new URL(originalRenderUrl, webRequest.url), webRequest) : void 0;
|
|
1577
|
+
const middlewareCtx = createNodeExecutionContext(void 0, { middlewareOrigin: resolveNodeMiddlewareOrigin(req, webRequest.url, host, port) });
|
|
1578
|
+
const runNodeMiddleware = typeof runMiddleware === "function" ? (request, _ctx, opts) => runMiddleware(request, middlewareCtx, opts) : null;
|
|
1546
1579
|
const resolvePublicImageSource = async (sourceUrl) => {
|
|
1547
1580
|
const rawSourcePathname = sourceUrl.pathname;
|
|
1548
1581
|
if (getRepeatedSlashRedirect(rawSourcePathname) || isOpenRedirectShaped(rawSourcePathname)) return null;
|
|
@@ -1561,11 +1594,15 @@ async function createPagesRouterRequestHandler(options) {
|
|
|
1561
1594
|
recordCacheability: false,
|
|
1562
1595
|
rawSearch: sourceUrl.search,
|
|
1563
1596
|
configMatchPathname: strippedSourcePathname,
|
|
1564
|
-
|
|
1597
|
+
restoreLocaleRootTrailingSlash: shouldRestoreLocaleRootTrailingSlash(sourceRequestPathname, {
|
|
1598
|
+
trailingSlash,
|
|
1599
|
+
skipProxyUrlNormalize
|
|
1600
|
+
}),
|
|
1601
|
+
runMiddleware: runNodeMiddleware ? wrapMiddlewareWithBasePath(runNodeMiddleware, basePath, sourceHadBasePath) : null,
|
|
1565
1602
|
renderPage: null,
|
|
1566
1603
|
handleApi: null,
|
|
1567
|
-
serveFilesystemRoute: async (candidate, _stagedHeaders, phase) => {
|
|
1568
|
-
if (isImageOptimizationPath(candidate) || isPagesFilesystemExcludedPath(candidate, phase)) return false;
|
|
1604
|
+
serveFilesystemRoute: async (candidate, _stagedHeaders, phase, _resolvedUrl, _request, candidateHasBasePath) => {
|
|
1605
|
+
if (!candidateHasBasePath && !isAssetPrefixBuildAsset(candidate, pagesAssetPathPrefix) || isImageOptimizationPath(candidate) || isPagesFilesystemExcludedPath(candidate, phase)) return false;
|
|
1569
1606
|
const lookupPath = staticCacheLookupPath(candidate);
|
|
1570
1607
|
if (lookupPath === null || lookupPath === "/" || !staticCache.lookup(lookupPath)) return false;
|
|
1571
1608
|
sourcePath = candidate;
|
|
@@ -1595,9 +1632,10 @@ async function createPagesRouterRequestHandler(options) {
|
|
|
1595
1632
|
rawSearch: rawQs,
|
|
1596
1633
|
authorizeOnDemandRevalidate: typeof authorizeOnDemandRevalidate === "function" ? authorizeOnDemandRevalidate : void 0,
|
|
1597
1634
|
configMatchPathname,
|
|
1635
|
+
restoreLocaleRootTrailingSlash,
|
|
1598
1636
|
matchPageRoute: matchPageRoute ?? null,
|
|
1599
1637
|
matchApiRoute: matchApiRoute ?? null,
|
|
1600
|
-
runMiddleware:
|
|
1638
|
+
runMiddleware: runNodeMiddleware ? wrapMiddlewareWithBasePath(runNodeMiddleware, basePath, hadBasePath) : null,
|
|
1601
1639
|
renderPage: typeof renderPage === "function" ? (request, resolvedUrl, options, stagedHeaders) => renderPage(request, resolvedUrl, ssrManifest, void 0, stagedHeaders, {
|
|
1602
1640
|
...options,
|
|
1603
1641
|
originalUrl: originalRenderUrl
|
|
@@ -1648,7 +1686,7 @@ async function createPagesRouterRequestHandler(options) {
|
|
|
1648
1686
|
res.end(INVALID_IMAGE_SOURCE_MESSAGE);
|
|
1649
1687
|
return true;
|
|
1650
1688
|
}
|
|
1651
|
-
if (isPagesFilesystemExcludedPath(requestPathname, phase)) return false;
|
|
1689
|
+
if (!resolvedPathnameHasBasePath && !isAssetPrefixBuildAsset(requestPathname, pagesAssetPathPrefix) || isPagesFilesystemExcludedPath(requestPathname, phase)) return false;
|
|
1652
1690
|
return tryServeStatic(req, res, clientDir, requestPathname, compress, staticCache, stagedHeaders);
|
|
1653
1691
|
}
|
|
1654
1692
|
};
|
|
@@ -35,4 +35,10 @@ export declare function resolveRequestProtocol(source: IncomingMessage | Headers
|
|
|
35
35
|
* against `request.url`.
|
|
36
36
|
*/
|
|
37
37
|
export declare function resolveRequestHost(source: IncomingMessage | Headers, fallback: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* The `X-Forwarded-Host` value when it matches the `trustedHosts` allow-list,
|
|
40
|
+
* otherwise undefined. Unlike the raw `Host` header, this host is
|
|
41
|
+
* operator-approved.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveTrustedForwardedHost(source: IncomingMessage | Headers): string | undefined;
|
|
38
44
|
//#endregion
|
|
@@ -42,12 +42,18 @@ function resolveRequestProtocol(source) {
|
|
|
42
42
|
* against `request.url`.
|
|
43
43
|
*/
|
|
44
44
|
function resolveRequestHost(source, fallback) {
|
|
45
|
+
return resolveTrustedForwardedHost(source) ?? (readHost(source) || fallback);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The `X-Forwarded-Host` value when it matches the `trustedHosts` allow-list,
|
|
49
|
+
* otherwise undefined. Unlike the raw `Host` header, this host is
|
|
50
|
+
* operator-approved.
|
|
51
|
+
*/
|
|
52
|
+
function resolveTrustedForwardedHost(source) {
|
|
45
53
|
const rawForwarded = readForwardedHost(source);
|
|
46
|
-
if (rawForwarded
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
return readHost(source) || fallback;
|
|
54
|
+
if (!rawForwarded || trustedHosts.size === 0) return void 0;
|
|
55
|
+
const forwardedHost = rawForwarded.split(",")[0]?.trim().toLowerCase();
|
|
56
|
+
return forwardedHost && trustedHosts.has(forwardedHost) ? forwardedHost : void 0;
|
|
51
57
|
}
|
|
52
58
|
function readForwardedProto(source) {
|
|
53
59
|
if (isWebHeaders(source)) return source.get("x-forwarded-proto") ?? void 0;
|
|
@@ -65,4 +71,4 @@ function isWebHeaders(source) {
|
|
|
65
71
|
return typeof source.get === "function";
|
|
66
72
|
}
|
|
67
73
|
//#endregion
|
|
68
|
-
export { resolveRequestHost, resolveRequestProtocol, trustProxy, trustedHosts };
|
|
74
|
+
export { resolveRequestHost, resolveRequestProtocol, resolveTrustedForwardedHost, trustProxy, trustedHosts };
|
|
@@ -143,6 +143,11 @@ export declare function isOriginAllowed(origin: string, allowed: string[]): bool
|
|
|
143
143
|
*
|
|
144
144
|
* @param headers - The Headers object to modify in place
|
|
145
145
|
*/
|
|
146
|
+
/**
|
|
147
|
+
* Next.js drops each empty middleware Set-Cookie value when it converts
|
|
148
|
+
* middleware's response headers, so blank values never reach the response.
|
|
149
|
+
*/
|
|
150
|
+
export declare function dropEmptyMiddlewareSetCookie(headers: Headers): void;
|
|
146
151
|
export declare function processMiddlewareHeaders(headers: Headers): void;
|
|
147
152
|
/**
|
|
148
153
|
* Strip internal headers from an inbound request so they cannot be forged by
|
|
@@ -313,7 +313,18 @@ function isOriginAllowed(origin, allowed) {
|
|
|
313
313
|
*
|
|
314
314
|
* @param headers - The Headers object to modify in place
|
|
315
315
|
*/
|
|
316
|
+
/**
|
|
317
|
+
* Next.js drops each empty middleware Set-Cookie value when it converts
|
|
318
|
+
* middleware's response headers, so blank values never reach the response.
|
|
319
|
+
*/
|
|
320
|
+
function dropEmptyMiddlewareSetCookie(headers) {
|
|
321
|
+
const cookies = headers.getSetCookie();
|
|
322
|
+
if (!cookies.includes("")) return;
|
|
323
|
+
headers.delete("set-cookie");
|
|
324
|
+
for (const cookie of cookies) if (cookie) headers.append("set-cookie", cookie);
|
|
325
|
+
}
|
|
316
326
|
function processMiddlewareHeaders(headers) {
|
|
327
|
+
dropEmptyMiddlewareSetCookie(headers);
|
|
317
328
|
const keysToDelete = [];
|
|
318
329
|
const unconsumedRequestHeaders = getUnconsumedMiddlewareRequestHeaders(headers);
|
|
319
330
|
for (const key of headers.keys()) if (key.startsWith("x-middleware-") && key !== "x-middleware-cache" && !unconsumedRequestHeaders.has(key)) keysToDelete.push(key);
|
|
@@ -433,4 +444,4 @@ function cloneRequestWithUrl(request, url) {
|
|
|
433
444
|
return attachRequestCfMetadata(cloned, request);
|
|
434
445
|
}
|
|
435
446
|
//#endregion
|
|
436
|
-
export { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, attachRequestCfMetadata, canonicalizeRequestPathname, canonicalizeRequestUrlPathname, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, filterInternalHeaders, getRepeatedSlashRedirect, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, resolvePublicFileRoute, sendRepeatedSlashRedirect, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
|
|
447
|
+
export { INTERNAL_HEADERS, VINEXT_INTERNAL_HEADERS, attachRequestCfMetadata, canonicalizeRequestPathname, canonicalizeRequestUrlPathname, cloneRequestWithHeaders, cloneRequestWithUrl, createStaticFileSignal, dropEmptyMiddlewareSetCookie, filterInternalHeaders, getRepeatedSlashRedirect, guardProtocolRelativeUrl, hasBasePath, isOpenRedirectShaped, isOriginAllowed, normalizeTrailingSlash, normalizeTrailingSlashPathname, processMiddlewareHeaders, resolvePublicFileRoute, sendRepeatedSlashRedirect, stripBasePath, validateCsrfOrigin, validateServerActionPayload };
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* tag is `HL` are decoded and inspected. Length-prefixed bodies remain separate
|
|
12
12
|
* so binary bytes do not force adjacent text through the embed's base64 path.
|
|
13
13
|
*/
|
|
14
|
-
export declare function normalizeReactFlightPreloadHints(stream: ReadableStream<Uint8Array
|
|
14
|
+
export declare function normalizeReactFlightPreloadHints(stream: ReadableStream<Uint8Array>, onCancel?: (reason: unknown) => void): ReadableStream<Uint8Array>;
|
|
15
15
|
export type RscRawRenderer = (model: unknown, options?: unknown) => ReadableStream<Uint8Array>;
|
|
16
16
|
export type RscRawPrerenderer = (model: unknown, options?: unknown) => Promise<{
|
|
17
17
|
prelude: ReadableStream<Uint8Array>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRenderStreamCancellation } from "./app-render-abort-error.js";
|
|
1
2
|
//#region src/server/rsc-stream-hints.ts
|
|
2
3
|
const REACT_FLIGHT_STYLESHEET_PRELOAD_HINT = /^([0-9a-f]*:HL\[.*?),"stylesheet"(\]|,)/;
|
|
3
4
|
const STYLESHEET_TO_STYLE_JSON_PADDING = " ".repeat(5);
|
|
@@ -106,7 +107,7 @@ function isTagInTable(table, byte) {
|
|
|
106
107
|
* tag is `HL` are decoded and inspected. Length-prefixed bodies remain separate
|
|
107
108
|
* so binary bytes do not force adjacent text through the embed's base64 path.
|
|
108
109
|
*/
|
|
109
|
-
function normalizeReactFlightPreloadHints(stream) {
|
|
110
|
+
function normalizeReactFlightPreloadHints(stream, onCancel) {
|
|
110
111
|
let carry = null;
|
|
111
112
|
let rawBytesRemaining = 0;
|
|
112
113
|
let passThrough = false;
|
|
@@ -194,11 +195,28 @@ function normalizeReactFlightPreloadHints(stream) {
|
|
|
194
195
|
},
|
|
195
196
|
flush(controller) {
|
|
196
197
|
if (carry !== null && carry.byteLength > 0) controller.enqueue(rawBytesRemaining > 0 ? carry : normalizeReactFlightHintLine(carry));
|
|
197
|
-
}
|
|
198
|
+
},
|
|
199
|
+
cancel: onCancel
|
|
198
200
|
}));
|
|
199
201
|
}
|
|
200
202
|
function createRscRenderer(render) {
|
|
201
|
-
return (model, options) =>
|
|
203
|
+
return (model, options) => {
|
|
204
|
+
const cancellation = createRenderStreamCancellation();
|
|
205
|
+
return normalizeReactFlightPreloadHints(render(model, ignoreCancellationErrors(options, cancellation)), cancellation.record);
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/** A consumer cancelling the payload is not a render failure. */
|
|
209
|
+
function ignoreCancellationErrors(options, cancellation) {
|
|
210
|
+
if (!options || typeof options !== "object") return options;
|
|
211
|
+
const onError = Reflect.get(options, "onError");
|
|
212
|
+
if (typeof onError !== "function") return options;
|
|
213
|
+
return {
|
|
214
|
+
...options,
|
|
215
|
+
onError(error, ...rest) {
|
|
216
|
+
if (cancellation.isReason(error)) return void 0;
|
|
217
|
+
return Reflect.apply(onError, options, [error, ...rest]);
|
|
218
|
+
}
|
|
219
|
+
};
|
|
202
220
|
}
|
|
203
221
|
function createRscPrerenderer(prerender) {
|
|
204
222
|
return async (model, options) => {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { runOutsideRequestScopes } from "../shims/internal/als-registry.js";
|
|
2
|
+
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
3
|
+
import { shareIsolatePromise } from "./isolate-shared-promise.js";
|
|
2
4
|
//#region src/server/server-reference-loader.ts
|
|
3
5
|
/**
|
|
4
6
|
* Keep server-reference module evaluation out of the request that first
|
|
@@ -21,7 +23,14 @@ const ISOLATED = Symbol.for("vinext.serverReferenceRequire.isolated");
|
|
|
21
23
|
function isolateServerReferenceLoads() {
|
|
22
24
|
const load = globalThis.__vite_rsc_server_require__;
|
|
23
25
|
if (typeof load !== "function" || ISOLATED in load) return;
|
|
24
|
-
const
|
|
26
|
+
const started = /* @__PURE__ */ new WeakSet();
|
|
27
|
+
const isolated = (id) => {
|
|
28
|
+
const ctx = getRequestExecutionContext();
|
|
29
|
+
const loaded = runOutsideRequestScopes(() => load(id));
|
|
30
|
+
if (!(loaded instanceof Promise) || started.has(loaded)) return loaded;
|
|
31
|
+
started.add(loaded);
|
|
32
|
+
return shareIsolatePromise(loaded, ctx);
|
|
33
|
+
};
|
|
25
34
|
Object.defineProperty(isolated, ISOLATED, { value: true });
|
|
26
35
|
globalThis.__vite_rsc_server_require__ = isolated;
|
|
27
36
|
}
|
|
@@ -178,6 +178,15 @@ var StaticFileCache = class StaticFileCache {
|
|
|
178
178
|
return this.entries.get(pathname);
|
|
179
179
|
}
|
|
180
180
|
};
|
|
181
|
+
const MANAGED_CHUNKS_SEGMENT = `${ASSET_PREFIX_URL_DIR}/chunks/`;
|
|
182
|
+
const MANAGED_CSS_SEGMENT = `${ASSET_PREFIX_URL_DIR}/css/`;
|
|
183
|
+
const MANAGED_WORKERS_SEGMENT = `${ASSET_PREFIX_URL_DIR}/workers/`;
|
|
184
|
+
const MANAGED_MEDIA_SEGMENT = `${ASSET_PREFIX_URL_DIR}/media/`;
|
|
185
|
+
const HASH_ONLY_BASENAME_RE = /^[A-Za-z0-9_-]{8}$/;
|
|
186
|
+
const WORKER_BASENAME_RE = /^[0-9a-f]{8}-[A-Za-z0-9_-]{8}$/;
|
|
187
|
+
function isInManagedDir(normalizedPath, segment) {
|
|
188
|
+
return normalizedPath.startsWith(segment) || normalizedPath.includes(`/${segment}`);
|
|
189
|
+
}
|
|
181
190
|
/**
|
|
182
191
|
* Extract a stable weak ETag from a Vite hashed filename (e.g. `app-DqZc3R4n.js`).
|
|
183
192
|
* The hash is a content hash computed by the bundler — deterministic across
|
|
@@ -190,14 +199,17 @@ var StaticFileCache = class StaticFileCache {
|
|
|
190
199
|
*/
|
|
191
200
|
function etagFromFilenameHash(relativePath, ext) {
|
|
192
201
|
const basename = path.basename(relativePath, ext);
|
|
202
|
+
if (basename.length === 8 && HASH_ONLY_BASENAME_RE.test(basename)) {
|
|
203
|
+
const normalizedPath = toSlash(relativePath);
|
|
204
|
+
if (isInManagedDir(normalizedPath, MANAGED_CHUNKS_SEGMENT) || isInManagedDir(normalizedPath, MANAGED_CSS_SEGMENT)) return `W/"${basename}"`;
|
|
205
|
+
}
|
|
206
|
+
if (basename.length === 17 && WORKER_BASENAME_RE.test(basename) && isInManagedDir(toSlash(relativePath), MANAGED_WORKERS_SEGMENT)) return `W/"${basename}"`;
|
|
193
207
|
const lastDash = basename.lastIndexOf("-");
|
|
194
208
|
if (lastDash !== -1 && lastDash !== basename.length - 1) {
|
|
195
209
|
const suffix = basename.slice(lastDash + 1);
|
|
196
210
|
if (suffix.length >= 6 && suffix.length <= 12 && /^[A-Za-z0-9_-]+$/.test(suffix)) return `W/"${suffix}"`;
|
|
197
211
|
}
|
|
198
|
-
|
|
199
|
-
const managedMediaSegment = `${ASSET_PREFIX_URL_DIR}/media/`;
|
|
200
|
-
if (normalizedPath.startsWith(managedMediaSegment) || normalizedPath.includes(`/${managedMediaSegment}`)) {
|
|
212
|
+
if (isInManagedDir(toSlash(relativePath), MANAGED_MEDIA_SEGMENT)) {
|
|
201
213
|
const lastDot = basename.lastIndexOf(".");
|
|
202
214
|
if (lastDot !== -1) {
|
|
203
215
|
const suffix = basename.slice(lastDot + 1);
|