@qzsy/vinext 0.1.11 → 0.1.80
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 +19 -5
- package/dist/build/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -0
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +11 -4
- package/dist/build/report.d.ts +2 -1
- package/dist/build/report.js +2 -1
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +9 -0
- package/dist/build/standalone.js +2 -0
- package/dist/check.d.ts +18 -0
- package/dist/check.js +77 -19
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +64 -28
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/cloudflare/deploy-config.d.ts +51 -0
- package/dist/cloudflare/deploy-config.js +153 -0
- package/dist/cloudflare/index.d.ts +1 -1
- package/dist/cloudflare/index.js +1 -1
- package/dist/cloudflare/project.d.ts +41 -0
- package/dist/cloudflare/project.js +243 -0
- package/dist/cloudflare/tpr.js +1 -1
- package/dist/config/config-matchers.js +14 -10
- package/dist/config/next-config.d.ts +6 -3
- package/dist/config/next-config.js +47 -1
- package/dist/config/server-external-packages.d.ts +4 -0
- package/dist/config/server-external-packages.js +91 -0
- package/dist/deploy.d.ts +2 -122
- package/dist/deploy.js +20 -793
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +70 -12
- package/dist/entries/app-rsc-manifest.js +8 -0
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +2 -1
- package/dist/entries/pages-server-entry.js +6 -2
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +50 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +158 -109
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +1000 -0
- package/dist/init-platform.d.ts +38 -0
- package/dist/init-platform.js +150 -0
- package/dist/init.d.ts +14 -37
- package/dist/init.js +205 -95
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.js +3 -0
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/middleware-server-only.d.ts +8 -6
- package/dist/plugins/middleware-server-only.js +8 -7
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +13 -2
- package/dist/routing/app-route-graph.js +116 -32
- package/dist/routing/app-router.d.ts +5 -0
- package/dist/routing/app-router.js +5 -0
- package/dist/routing/file-matcher.d.ts +8 -0
- package/dist/routing/file-matcher.js +10 -1
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/app-browser-action-result.d.ts +2 -1
- package/dist/server/app-browser-action-result.js +5 -1
- package/dist/server/app-browser-entry.js +17 -12
- package/dist/server/app-browser-history-controller.d.ts +2 -1
- package/dist/server/app-browser-history-controller.js +6 -2
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.js +1 -0
- package/dist/server/app-browser-server-action-client.js +2 -3
- package/dist/server/app-browser-state.d.ts +1 -0
- package/dist/server/app-browser-state.js +3 -2
- package/dist/server/app-fallback-renderer.d.ts +3 -2
- package/dist/server/app-fallback-renderer.js +12 -7
- package/dist/server/app-middleware.d.ts +2 -3
- package/dist/server/app-middleware.js +3 -2
- package/dist/server/app-optimistic-routing.js +1 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -0
- package/dist/server/app-page-boundary-render.js +12 -3
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +10 -3
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +4 -1
- package/dist/server/app-page-dispatch.d.ts +11 -3
- package/dist/server/app-page-dispatch.js +55 -15
- package/dist/server/app-page-element-builder.d.ts +5 -1
- package/dist/server/app-page-element-builder.js +57 -20
- package/dist/server/app-page-head.d.ts +12 -0
- package/dist/server/app-page-head.js +42 -19
- package/dist/server/app-page-params.d.ts +2 -1
- package/dist/server/app-page-params.js +8 -1
- package/dist/server/app-page-probe.d.ts +1 -0
- package/dist/server/app-page-probe.js +6 -1
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render.d.ts +4 -1
- package/dist/server/app-page-render.js +8 -3
- package/dist/server/app-page-request.d.ts +22 -1
- package/dist/server/app-page-request.js +89 -13
- package/dist/server/app-page-route-wiring.d.ts +6 -1
- package/dist/server/app-page-route-wiring.js +31 -15
- package/dist/server/app-page-search-params-observation.d.ts +4 -2
- package/dist/server/app-page-search-params-observation.js +11 -7
- package/dist/server/app-page-segment-state.js +2 -0
- package/dist/server/app-route-handler-dispatch.js +1 -0
- package/dist/server/app-route-handler-execution.js +7 -2
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-route-module-loader.d.ts +2 -0
- package/dist/server/app-route-module-loader.js +1 -0
- package/dist/server/app-router-entry.d.ts +12 -0
- package/dist/server/app-router-entry.js +22 -8
- package/dist/server/app-router-image-optimization.d.ts +37 -0
- package/dist/server/app-router-image-optimization.js +40 -0
- package/dist/server/app-rsc-errors.js +7 -1
- package/dist/server/app-rsc-handler.js +27 -14
- package/dist/server/app-rsc-route-matching.d.ts +7 -0
- package/dist/server/app-rsc-route-matching.js +36 -3
- package/dist/server/app-segment-config.d.ts +12 -0
- package/dist/server/app-segment-config.js +91 -5
- package/dist/server/app-server-action-execution.d.ts +5 -0
- package/dist/server/app-server-action-execution.js +94 -33
- package/dist/server/app-ssr-entry.js +12 -1
- package/dist/server/app-static-generation.d.ts +1 -0
- package/dist/server/app-static-generation.js +1 -0
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-server.js +8 -15
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/headers.d.ts +5 -15
- package/dist/server/headers.js +4 -15
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +2 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-page-data.d.ts +23 -1
- package/dist/server/pages-page-data.js +43 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +10 -4
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +47 -25
- package/dist/server/request-pipeline.js +1 -0
- package/dist/server/seed-cache.js +4 -4
- package/dist/server/worker-utils.d.ts +2 -1
- package/dist/server/worker-utils.js +7 -1
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache.js +19 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/error-boundary.d.ts +19 -1
- package/dist/shims/error-boundary.js +11 -1
- package/dist/shims/form.d.ts +3 -1
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +9 -1
- package/dist/shims/headers.js +31 -6
- package/dist/shims/image-optimization-url.d.ts +4 -0
- package/dist/shims/image-optimization-url.js +33 -1
- package/dist/shims/image.js +46 -13
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -5
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/link.js +23 -16
- package/dist/shims/metadata.d.ts +3 -2
- package/dist/shims/metadata.js +8 -4
- package/dist/shims/navigation.js +4 -2
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +2 -5
- package/dist/shims/router.js +41 -22
- package/dist/shims/server.js +3 -2
- package/dist/typegen.js +6 -5
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +2 -2
- package/dist/utils/path.d.ts +2 -1
- package/dist/utils/path.js +1 -1
- package/dist/utils/project.d.ts +9 -1
- package/dist/utils/project.js +21 -4
- package/dist/utils/protocol-headers.d.ts +17 -0
- package/dist/utils/protocol-headers.js +17 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/package.json +28 -24
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -95,7 +95,8 @@ function parseImageParams(url, allowedWidths = [...DEFAULT_DEVICE_SIZES, ...DEFA
|
|
|
95
95
|
const allowedParamNames = new Set([
|
|
96
96
|
"url",
|
|
97
97
|
"w",
|
|
98
|
-
"q"
|
|
98
|
+
"q",
|
|
99
|
+
"dpl"
|
|
99
100
|
]);
|
|
100
101
|
for (const name of url.searchParams.keys()) if (!allowedParamNames.has(name) || url.searchParams.getAll(name).length !== 1) return null;
|
|
101
102
|
const imageUrl = url.searchParams.get("url");
|
|
@@ -243,5 +244,54 @@ async function handleImageOptimization(request, handlers, allowedWidths, imageCo
|
|
|
243
244
|
return createPassthroughImageResponse(refetchedSource, imageConfig);
|
|
244
245
|
}
|
|
245
246
|
}
|
|
247
|
+
const _IMAGE_OPTIMIZER_KEY = Symbol.for("vinext.imageOptimizer");
|
|
248
|
+
const _gImageOptimizer = globalThis;
|
|
249
|
+
/**
|
|
250
|
+
* Register the active image optimizer (transform backend). An explicit
|
|
251
|
+
* registration always wins; passing `null` clears it (falling back to
|
|
252
|
+
* unoptimized passthrough).
|
|
253
|
+
*
|
|
254
|
+
* Configure this declaratively via the `images.optimizer` option on the
|
|
255
|
+
* `vinext()` plugin in your `vite.config.ts` rather than calling it directly.
|
|
256
|
+
* On Cloudflare Workers:
|
|
257
|
+
*
|
|
258
|
+
* ```ts
|
|
259
|
+
* import { vinext } from "vinext";
|
|
260
|
+
* import { imagesOptimizer } from "@vinext/cloudflare/images/images-optimizer";
|
|
261
|
+
*
|
|
262
|
+
* export default defineConfig({
|
|
263
|
+
* plugins: [vinext({ images: { optimizer: imagesOptimizer() } })],
|
|
264
|
+
* });
|
|
265
|
+
* ```
|
|
266
|
+
*
|
|
267
|
+
* The plugin registers the optimizer across every runtime/router entry, so you
|
|
268
|
+
* don't have to wire `env.IMAGES` into a custom worker entry. This setter
|
|
269
|
+
* remains the internal registration target.
|
|
270
|
+
*/
|
|
271
|
+
function setImageOptimizer(optimizer) {
|
|
272
|
+
_gImageOptimizer[_IMAGE_OPTIMIZER_KEY] = optimizer ?? void 0;
|
|
273
|
+
}
|
|
274
|
+
/** Get the active image optimizer, or `null` when none is configured. */
|
|
275
|
+
function getImageOptimizer() {
|
|
276
|
+
return _gImageOptimizer[_IMAGE_OPTIMIZER_KEY] ?? null;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Handle an image optimization request using the configured optimizer (if any).
|
|
280
|
+
*
|
|
281
|
+
* This is the single entry point every runtime/router seam (App Router worker,
|
|
282
|
+
* Pages worker, Node prod server) should call: it reads the registered
|
|
283
|
+
* {@link ImageOptimizer} and wires its `transformImage` into
|
|
284
|
+
* {@link handleImageOptimization}, with the caller supplying the runtime's
|
|
285
|
+
* `fetchAsset` (e.g. the Cloudflare `ASSETS` binding, or filesystem reads on
|
|
286
|
+
* Node). When no optimizer is registered, the request is served unoptimized
|
|
287
|
+
* (passthrough) with the same security/cache headers.
|
|
288
|
+
*/
|
|
289
|
+
function handleConfiguredImageOptimization(request, fetchAsset, allowedWidths, imageConfig) {
|
|
290
|
+
const optimizer = getImageOptimizer();
|
|
291
|
+
return handleImageOptimization(request, {
|
|
292
|
+
fetchAsset,
|
|
293
|
+
transformImage: optimizer ? (body, options) => optimizer.transformImage(body, options) : void 0
|
|
294
|
+
}, allowedWidths, imageConfig);
|
|
295
|
+
}
|
|
246
296
|
//#endregion
|
|
247
|
-
export { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, IMAGE_CACHE_CONTROL, IMAGE_CONTENT_SECURITY_POLICY, IMAGE_OPTIMIZATION_PATH, VINEXT_IMAGE_OPTIMIZATION_PATH, handleImageOptimization, isImageOptimizationPath, isSafeImageContentType, negotiateImageFormat, parseImageParams, resolveDevImageRedirect, snapToNearestAllowedWidth };
|
|
297
|
+
export { DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, IMAGE_CACHE_CONTROL, IMAGE_CONTENT_SECURITY_POLICY, IMAGE_OPTIMIZATION_PATH, VINEXT_IMAGE_OPTIMIZATION_PATH, getImageOptimizer, handleConfiguredImageOptimization, handleImageOptimization, isImageOptimizationPath, isSafeImageContentType, negotiateImageFormat, parseImageParams, resolveDevImageRedirect, setImageOptimizer, snapToNearestAllowedWidth };
|
|
@@ -95,7 +95,7 @@ declare function buildPagesCacheValue(html: string, pageData: object, status?: n
|
|
|
95
95
|
/**
|
|
96
96
|
* Build a CachedAppPageValue for the App Router ISR cache.
|
|
97
97
|
*/
|
|
98
|
-
declare function buildAppPageCacheValue(html: string, rscData?: ArrayBuffer, status?: number, renderObservation?: RenderObservation): CachedAppPageValue;
|
|
98
|
+
declare function buildAppPageCacheValue(html: string, rscData?: ArrayBuffer, status?: number, renderObservation?: RenderObservation, headers?: CachedAppPageValue["headers"]): CachedAppPageValue;
|
|
99
99
|
/**
|
|
100
100
|
* Compute an ISR cache key for a given router type and pathname.
|
|
101
101
|
* Long pathnames are hashed to stay within KV key-length limits (512 bytes).
|
package/dist/server/isr-cache.js
CHANGED
|
@@ -188,12 +188,12 @@ function buildPagesCacheValue(html, pageData, status) {
|
|
|
188
188
|
/**
|
|
189
189
|
* Build a CachedAppPageValue for the App Router ISR cache.
|
|
190
190
|
*/
|
|
191
|
-
function buildAppPageCacheValue(html, rscData, status, renderObservation) {
|
|
191
|
+
function buildAppPageCacheValue(html, rscData, status, renderObservation, headers) {
|
|
192
192
|
const value = {
|
|
193
193
|
kind: "APP_PAGE",
|
|
194
194
|
html,
|
|
195
195
|
rscData,
|
|
196
|
-
headers
|
|
196
|
+
headers,
|
|
197
197
|
postponed: void 0,
|
|
198
198
|
status
|
|
199
199
|
};
|
|
@@ -2,8 +2,9 @@ import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
|
2
2
|
import { addBasePathToPathname, hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
3
3
|
import "./server-globals.js";
|
|
4
4
|
import { getRequestExecutionContext, runWithExecutionContext } from "../shims/request-context.js";
|
|
5
|
+
import "../utils/protocol-headers.js";
|
|
5
6
|
import { MIDDLEWARE_REWRITE_HEADER } from "./headers.js";
|
|
6
|
-
import { shouldKeepMiddlewareHeader } from "
|
|
7
|
+
import { shouldKeepMiddlewareHeader } from "../utils/middleware-request-headers.js";
|
|
7
8
|
import { NextFetchEvent, NextRequest } from "../shims/server.js";
|
|
8
9
|
import { normalizePath } from "./normalize-path.js";
|
|
9
10
|
import { matchesMiddleware } from "./middleware-matcher.js";
|
|
@@ -141,6 +142,10 @@ async function executeMiddleware(options) {
|
|
|
141
142
|
const matchPathname = options.basePath ? stripBasePath(normalizedPathname, options.basePath) : normalizedPathname;
|
|
142
143
|
if (!matchesMiddleware(matchPathname, middlewareMatcher(options.module), options.request, options.i18nConfig)) return { continue: true };
|
|
143
144
|
const nextRequest = createNextRequest(options.request, normalizedPathname, options.i18nConfig, options.basePath, options.trailingSlash, hadBasePath);
|
|
145
|
+
if (options.isDataRequest) Object.defineProperty(nextRequest, "__isData", {
|
|
146
|
+
enumerable: false,
|
|
147
|
+
value: true
|
|
148
|
+
});
|
|
144
149
|
const fetchEvent = new NextFetchEvent({ page: removeTrailingSlash(matchPathname) });
|
|
145
150
|
let response;
|
|
146
151
|
try {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { splitPathnameForRouteMatch } from "../routing/utils.js";
|
|
2
2
|
import { stripBasePath } from "../utils/base-path.js";
|
|
3
|
-
import { matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments } from "../routing/route-pattern.js";
|
|
4
3
|
import { compareAppElementsSlotIds } from "./app-elements-wire.js";
|
|
5
4
|
import "./app-elements.js";
|
|
5
|
+
import { matchRoutePattern, matchRoutePatternPrefix, matchRoutePatternWithOptionalDynamicSegments } from "../routing/route-pattern.js";
|
|
6
6
|
import { resolveHardNavigationTargetFromRscResponse, resolveRscCompatibilityNavigationDecision } from "./app-rsc-cache-busting.js";
|
|
7
7
|
import { resolveRscRedirectLifecycleHop, resolveStreamedRscRedirectLifecycleHop } from "./app-browser-rsc-redirect.js";
|
|
8
8
|
import { NavigationTraceReasonCodes, createNavigationLifecycleTraceFields, createNavigationTrace } from "./navigation-trace.js";
|
|
@@ -291,6 +291,11 @@ function stripInterceptionContextFromRouteId(routeId) {
|
|
|
291
291
|
const separatorIndex = routeId.indexOf(ROUTE_INTERCEPTION_CONTEXT_SEPARATOR);
|
|
292
292
|
return separatorIndex === -1 ? routeId : routeId.slice(0, separatorIndex);
|
|
293
293
|
}
|
|
294
|
+
function matchedUrlFromConcreteRouteId(routeId) {
|
|
295
|
+
const normalizedRouteId = stripInterceptionContextFromRouteId(routeId);
|
|
296
|
+
if (!normalizedRouteId.startsWith("route:/")) return null;
|
|
297
|
+
return normalizedRouteId.slice(6);
|
|
298
|
+
}
|
|
294
299
|
function getMatchedUrlPathname(matchedUrl) {
|
|
295
300
|
try {
|
|
296
301
|
return new URL(matchedUrl, "https://vinext.local").pathname;
|
|
@@ -315,6 +320,11 @@ function findRouteManifestRouteByIdOrMatchedUrl(options) {
|
|
|
315
320
|
const routeId = stripInterceptionContextFromRouteId(options.routeId);
|
|
316
321
|
const route = options.routeManifest.segmentGraph.routes.get(routeId);
|
|
317
322
|
if (route && routeManifestRouteMatchesUrl(route, options.matchedUrl)) return route;
|
|
323
|
+
const concreteRouteMatchedUrl = route === void 0 ? matchedUrlFromConcreteRouteId(options.routeId) : null;
|
|
324
|
+
if (concreteRouteMatchedUrl !== null) {
|
|
325
|
+
const concreteRoute = findRouteManifestRouteByMatchedUrl(options.routeManifest, concreteRouteMatchedUrl);
|
|
326
|
+
if (concreteRoute !== null) return concreteRoute;
|
|
327
|
+
}
|
|
318
328
|
return findRouteManifestRouteByMatchedUrl(options.routeManifest, options.matchedUrl);
|
|
319
329
|
}
|
|
320
330
|
function findRouteManifestRouteForSnapshot(routeManifest, snapshot) {
|
|
@@ -480,7 +490,7 @@ function getVisibleInterceptionSourceIdentity(snapshot) {
|
|
|
480
490
|
routeId: snapshot.interception.sourceRouteId
|
|
481
491
|
};
|
|
482
492
|
return {
|
|
483
|
-
matchedUrl: snapshot.matchedUrl,
|
|
493
|
+
matchedUrl: matchedUrlFromConcreteRouteId(snapshot.routeId) ?? snapshot.matchedUrl,
|
|
484
494
|
routeId: snapshot.routeId
|
|
485
495
|
};
|
|
486
496
|
}
|
|
@@ -567,7 +577,7 @@ function validateInterceptedPreservation(options) {
|
|
|
567
577
|
reasonCode: NavigationTraceReasonCodes.interceptedRejectedTargetMismatch
|
|
568
578
|
};
|
|
569
579
|
const sourceIdentity = getVisibleInterceptionSourceIdentity(options.currentSnapshot);
|
|
570
|
-
if (proof.sourceMatchedUrl !== sourceIdentity.matchedUrl || proof.sourceRouteId !== sourceIdentity.routeId) return {
|
|
580
|
+
if (!options.restoredHistorySnapshot && (proof.sourceMatchedUrl !== sourceIdentity.matchedUrl || proof.sourceRouteId !== sourceIdentity.routeId)) return {
|
|
571
581
|
kind: "rejected",
|
|
572
582
|
reasonCode: NavigationTraceReasonCodes.interceptedRejectedUnknownSource
|
|
573
583
|
};
|
|
@@ -654,6 +664,7 @@ function planFlightResponseArrived(options) {
|
|
|
654
664
|
const validation = validateInterceptedPreservation({
|
|
655
665
|
currentSnapshot: options.state.visibleSnapshot,
|
|
656
666
|
currentTopology: currentTopology.topology,
|
|
667
|
+
restoredHistorySnapshot: options.event.result.restoredHistorySnapshot === true,
|
|
657
668
|
routeManifest: options.routeManifest,
|
|
658
669
|
targetSnapshot,
|
|
659
670
|
targetTopology: targetTopology.topology
|
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
* template string.
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
|
-
* Resolve the effective SSR manifest: prefer the caller-supplied object
|
|
14
|
-
*
|
|
15
|
-
* injected by `vinext:cloudflare-build` at build time.
|
|
13
|
+
* Resolve the effective SSR manifest: prefer the caller-supplied object and
|
|
14
|
+
* fall back to the registered client build metadata.
|
|
16
15
|
*/
|
|
17
16
|
declare function resolveSsrManifest(manifest: Record<string, string[]> | null | undefined): Record<string, string[]> | null;
|
|
18
17
|
/**
|
|
@@ -34,7 +33,7 @@ declare function resolveClientModuleUrl(manifest: Record<string, string[]> | nul
|
|
|
34
33
|
type CollectAssetTagsOptions = {
|
|
35
34
|
/**
|
|
36
35
|
* SSR manifest mapping module file paths to their associated asset list.
|
|
37
|
-
* When empty/null the
|
|
36
|
+
* When empty/null the registered client build manifest is used.
|
|
38
37
|
*/
|
|
39
38
|
manifest: Record<string, string[]> | null | undefined;
|
|
40
39
|
/**
|
|
@@ -66,8 +65,7 @@ type CollectAssetTagsOptions = {
|
|
|
66
65
|
* - CSS files → `<link rel="stylesheet">`.
|
|
67
66
|
* - JS files → `<link rel="modulepreload">` + `<script type="module" defer>`.
|
|
68
67
|
* - Lazy chunks (behind `React.lazy` / `next/dynamic`) are skipped.
|
|
69
|
-
* - The
|
|
70
|
-
* injected first so hydration starts as early as possible.
|
|
68
|
+
* - The registered client-entry bootstrap is injected first.
|
|
71
69
|
* - Shared framework / vinext runtime chunks are always included alongside
|
|
72
70
|
* page-specific chunks.
|
|
73
71
|
*
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { appendDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
2
2
|
import { createNonceAttribute } from "./html.js";
|
|
3
3
|
import { assetServingUrlFromBaseAnchored } from "../utils/manifest-paths.js";
|
|
4
|
+
import { getPagesClientAssets } from "./pages-client-assets.js";
|
|
4
5
|
//#region src/server/pages-asset-tags.ts
|
|
5
6
|
/**
|
|
6
7
|
* Pages Router SSR asset-tag helpers.
|
|
@@ -13,13 +14,12 @@ import { assetServingUrlFromBaseAnchored } from "../utils/manifest-paths.js";
|
|
|
13
14
|
* template string.
|
|
14
15
|
*/
|
|
15
16
|
/**
|
|
16
|
-
* Resolve the effective SSR manifest: prefer the caller-supplied object
|
|
17
|
-
*
|
|
18
|
-
* injected by `vinext:cloudflare-build` at build time.
|
|
17
|
+
* Resolve the effective SSR manifest: prefer the caller-supplied object and
|
|
18
|
+
* fall back to the registered client build metadata.
|
|
19
19
|
*/
|
|
20
20
|
function resolveSsrManifest(manifest) {
|
|
21
21
|
if (manifest && Object.keys(manifest).length > 0) return manifest;
|
|
22
|
-
return (
|
|
22
|
+
return getPagesClientAssets().ssrManifest ?? null;
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Look up the asset-file list for a module ID in the SSR manifest.
|
|
@@ -58,8 +58,7 @@ function resolveClientModuleUrl(manifest, moduleId, basePath = "", assetPrefix =
|
|
|
58
58
|
* - CSS files → `<link rel="stylesheet">`.
|
|
59
59
|
* - JS files → `<link rel="modulepreload">` + `<script type="module" defer>`.
|
|
60
60
|
* - Lazy chunks (behind `React.lazy` / `next/dynamic`) are skipped.
|
|
61
|
-
* - The
|
|
62
|
-
* injected first so hydration starts as early as possible.
|
|
61
|
+
* - The registered client-entry bootstrap is injected first.
|
|
63
62
|
* - Shared framework / vinext runtime chunks are always included alongside
|
|
64
63
|
* page-specific chunks.
|
|
65
64
|
*
|
|
@@ -77,13 +76,14 @@ function collectAssetTags(options) {
|
|
|
77
76
|
const url = assetServingUrlFromBaseAnchored(value, basePath, assetPrefix);
|
|
78
77
|
return value.endsWith(".js") ? url : appendDeploymentIdQuery(url, options.deploymentId);
|
|
79
78
|
};
|
|
80
|
-
const
|
|
79
|
+
const runtimeAssets = getPagesClientAssets();
|
|
80
|
+
const lazyChunks = runtimeAssets.lazyChunks ?? null;
|
|
81
81
|
const lazySet = lazyChunks && lazyChunks.length > 0 ? new Set(lazyChunks) : null;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
seen.add(
|
|
85
|
-
tags.push("<link rel=\"modulepreload\"" + nonceAttr + " href=\"" + href(
|
|
86
|
-
tags.push("<script type=\"module\"" + deferAttr + nonceAttr + " src=\"" + href(
|
|
82
|
+
const clientEntry = runtimeAssets.clientEntry;
|
|
83
|
+
if (clientEntry) {
|
|
84
|
+
seen.add(clientEntry);
|
|
85
|
+
tags.push("<link rel=\"modulepreload\"" + nonceAttr + " href=\"" + href(clientEntry) + "\" />");
|
|
86
|
+
tags.push("<script type=\"module\"" + deferAttr + nonceAttr + " src=\"" + href(clientEntry) + "\" crossorigin><\/script>");
|
|
87
87
|
}
|
|
88
88
|
if (m) {
|
|
89
89
|
const allFiles = [];
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/server/pages-client-assets.d.ts
|
|
2
|
+
type PagesClientAssets = {
|
|
3
|
+
clientEntry?: string;
|
|
4
|
+
appBootstrapPreinitModules?: string[];
|
|
5
|
+
ssrManifest?: Record<string, string[]>;
|
|
6
|
+
lazyChunks?: string[];
|
|
7
|
+
dynamicPreloads?: Record<string, string[]>;
|
|
8
|
+
};
|
|
9
|
+
declare function setPagesClientAssets(assets: PagesClientAssets | undefined): void;
|
|
10
|
+
declare function getPagesClientAssets(): PagesClientAssets;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { PagesClientAssets, getPagesClientAssets, setPagesClientAssets };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/server/pages-client-assets.ts
|
|
2
|
+
let pagesClientAssets = {};
|
|
3
|
+
function setPagesClientAssets(assets) {
|
|
4
|
+
pagesClientAssets = assets ?? {};
|
|
5
|
+
}
|
|
6
|
+
function getPagesClientAssets() {
|
|
7
|
+
return pagesClientAssets;
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
export { getPagesClientAssets, setPagesClientAssets };
|
|
@@ -217,7 +217,29 @@ type ResolvePagesPageDataNotFoundResult = {
|
|
|
217
217
|
kind: "notFound";
|
|
218
218
|
};
|
|
219
219
|
type ResolvePagesPageDataResult = ResolvePagesPageDataRenderResult | ResolvePagesPageDataResponseResult | ResolvePagesPageDataNotFoundResult;
|
|
220
|
+
/**
|
|
221
|
+
* Compare a `getStaticPaths` entry against the actual request params.
|
|
222
|
+
*
|
|
223
|
+
* Handles both shapes Next.js allows:
|
|
224
|
+
* - { params: { ... } }
|
|
225
|
+
* - "string-path"
|
|
226
|
+
*
|
|
227
|
+
* For a string entry, compare the entry against the current request URL using
|
|
228
|
+
* the shared `normalizeStaticPathname` helper from
|
|
229
|
+
* `../routing/route-pattern.ts` (which mirrors the Next.js
|
|
230
|
+
* `removeTrailingSlash` behaviour in
|
|
231
|
+
* `.nextjs-ref/packages/next/src/build/static-paths/pages.ts`). For an object
|
|
232
|
+
* entry with a missing `params` key, return false rather than throwing — the
|
|
233
|
+
* caller will respond with a 404 just like Next.js does for unlisted paths.
|
|
234
|
+
*/
|
|
235
|
+
type PagesRouteParam = {
|
|
236
|
+
key: string;
|
|
237
|
+
repeat: boolean;
|
|
238
|
+
optional: boolean;
|
|
239
|
+
};
|
|
240
|
+
declare function getPagesRouteParams(routePattern: string): PagesRouteParam[];
|
|
241
|
+
declare function matchesPagesStaticPath(pathEntry: PagesStaticPathsEntry, params: Record<string, unknown>, routeParams: PagesRouteParam[], routeUrl: string): boolean;
|
|
220
242
|
declare function renderPagesIsrHtml(options: RenderPagesIsrHtmlOptions): Promise<string>;
|
|
221
243
|
declare function resolvePagesPageData(options: ResolvePagesPageDataOptions): Promise<ResolvePagesPageDataResult>;
|
|
222
244
|
//#endregion
|
|
223
|
-
export { PagesPageModule, ResolvePagesPageDataOptions, renderPagesIsrHtml, resolvePagesPageData };
|
|
245
|
+
export { PagesPageModule, PagesRouteParam, PagesStaticPathsEntry, ResolvePagesPageDataOptions, getPagesRouteParams, matchesPagesStaticPath, renderPagesIsrHtml, resolvePagesPageData };
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
|
|
2
|
-
import { normalizeStaticPathname } from "../routing/route-pattern.js";
|
|
3
2
|
import { buildCacheStateHeaders } from "./cache-headers.js";
|
|
4
3
|
import { isUnknownRecord } from "../utils/record.js";
|
|
5
4
|
import { applyCdnResponseHeaders } from "./cache-control.js";
|
|
6
5
|
import { decideIsr } from "./isr-decision.js";
|
|
7
6
|
import { buildPagesCacheValue } from "./isr-cache.js";
|
|
8
|
-
import {
|
|
7
|
+
import { normalizeStaticPathname } from "../routing/route-pattern.js";
|
|
8
|
+
import { buildPagesNextDataScript, etagMatches, generatePagesETag, isPagesStreamingBot, requestsNoCache } from "./pages-page-response.js";
|
|
9
9
|
import { hasPagesGetInitialProps, isResponseSent, loadPagesGetInitialProps } from "./pages-get-initial-props.js";
|
|
10
|
-
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
11
10
|
import { buildNextDataPropsJsonResponse } from "./pages-data-route.js";
|
|
12
|
-
import {
|
|
11
|
+
import { isSerializableProps } from "./pages-serializable-props.js";
|
|
12
|
+
import { isBotUserAgent } from "../utils/html-limited-bots.js";
|
|
13
13
|
//#region src/server/pages-page-data.ts
|
|
14
14
|
function buildPagesDataNotFoundResponse(deploymentId) {
|
|
15
15
|
const headers = { "Content-Type": "application/json" };
|
|
@@ -128,28 +128,45 @@ function buildPagesRedirectResponse(redirect, options, props = { pageProps: {} }
|
|
|
128
128
|
headers: { Location: destination }
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
131
|
+
function getPagesRouteParams(routePattern) {
|
|
132
|
+
return routePattern.split("/").map((segment) => {
|
|
133
|
+
const optionalCatchAll = segment.match(/^\[\[\.\.\.(.+)\]\]$/);
|
|
134
|
+
if (optionalCatchAll) return {
|
|
135
|
+
key: optionalCatchAll[1],
|
|
136
|
+
repeat: true,
|
|
137
|
+
optional: true
|
|
138
|
+
};
|
|
139
|
+
const requiredCatchAll = segment.match(/^\[\.\.\.(.+)\]$/);
|
|
140
|
+
if (requiredCatchAll) return {
|
|
141
|
+
key: requiredCatchAll[1],
|
|
142
|
+
repeat: true,
|
|
143
|
+
optional: false
|
|
144
|
+
};
|
|
145
|
+
const dynamic = segment.match(/^\[(.+)\]$/);
|
|
146
|
+
if (dynamic) return {
|
|
147
|
+
key: dynamic[1],
|
|
148
|
+
repeat: false,
|
|
149
|
+
optional: false
|
|
150
|
+
};
|
|
151
|
+
return null;
|
|
152
|
+
}).filter((param) => param !== null);
|
|
153
|
+
}
|
|
154
|
+
function matchesPagesStaticPath(pathEntry, params, routeParams, routeUrl) {
|
|
147
155
|
if (typeof pathEntry === "string") return normalizeStaticPathname(pathEntry) === normalizeStaticPathname(routeUrl);
|
|
148
156
|
const entryParams = pathEntry.params;
|
|
149
157
|
if (entryParams === void 0 || entryParams === null) return false;
|
|
150
|
-
return
|
|
158
|
+
return routeParams.every(({ key, repeat, optional }) => {
|
|
159
|
+
if (!Object.hasOwn(entryParams, key)) return false;
|
|
160
|
+
let value = entryParams[key];
|
|
161
|
+
if (optional && (value === null || value === void 0 || value === false)) value = [];
|
|
162
|
+
if (repeat) {
|
|
163
|
+
if (!Array.isArray(value) || !optional && value.length === 0) return false;
|
|
164
|
+
} else if (typeof value !== "string") return false;
|
|
151
165
|
const actual = params[key];
|
|
152
|
-
if (Array.isArray(value))
|
|
166
|
+
if (Array.isArray(value)) {
|
|
167
|
+
if (optional && value.length === 0 && actual === void 0) return true;
|
|
168
|
+
return Array.isArray(actual) && value.join("/") === actual.join("/");
|
|
169
|
+
}
|
|
153
170
|
return String(value) === String(actual);
|
|
154
171
|
});
|
|
155
172
|
}
|
|
@@ -237,7 +254,9 @@ async function resolvePagesPageData(options) {
|
|
|
237
254
|
defaultLocale: options.i18n.defaultLocale ?? ""
|
|
238
255
|
});
|
|
239
256
|
const fallback = pathsResult?.fallback ?? false;
|
|
240
|
-
const
|
|
257
|
+
const paths = pathsResult?.paths ?? [];
|
|
258
|
+
const routeParams = getPagesRouteParams(options.routePattern);
|
|
259
|
+
const isValidPath = paths.some((pathEntry) => matchesPagesStaticPath(pathEntry, options.params, routeParams, options.routeUrl));
|
|
241
260
|
if (fallback === false && !isValidPath) return buildPagesNotFoundResult(options);
|
|
242
261
|
const isBotRequest = !!options.userAgent && isBotUserAgent(options.userAgent, options.htmlLimitedBots);
|
|
243
262
|
if (fallback === true && !isValidPath && !options.isDataReq && !isBotRequest) isFallback = true;
|
|
@@ -481,4 +500,4 @@ async function resolvePagesPageData(options) {
|
|
|
481
500
|
};
|
|
482
501
|
}
|
|
483
502
|
//#endregion
|
|
484
|
-
export { renderPagesIsrHtml, resolvePagesPageData };
|
|
503
|
+
export { getPagesRouteParams, matchesPagesStaticPath, renderPagesIsrHtml, resolvePagesPageData };
|
|
@@ -35,6 +35,7 @@ type VinextConfigSubset = {
|
|
|
35
35
|
clientTraceMetadata?: readonly string[];
|
|
36
36
|
disableOptimizedLoading: boolean;
|
|
37
37
|
};
|
|
38
|
+
declare function shouldEmitPagesClientTraceMetadata(pageModule: PagesPageModule, appComponent: unknown): boolean;
|
|
38
39
|
/**
|
|
39
40
|
* Options accepted by `createPagesPageHandler`.
|
|
40
41
|
*
|
|
@@ -97,4 +98,4 @@ type RenderPageOptions = {
|
|
|
97
98
|
*/
|
|
98
99
|
declare function createPagesPageHandler(opts: CreatePagesPageHandlerOptions): (request: Request, url: string, manifest: Record<string, string[]> | null | undefined, middlewareHeaders: Headers | null | undefined, options: RenderPageOptions | null | undefined) => Promise<Response>;
|
|
99
100
|
//#endregion
|
|
100
|
-
export { CreatePagesPageHandlerOptions, createPagesPageHandler };
|
|
101
|
+
export { CreatePagesPageHandlerOptions, createPagesPageHandler, shouldEmitPagesClientTraceMetadata };
|
|
@@ -14,12 +14,18 @@ import { resolvePagesI18nRequest } from "./pages-i18n.js";
|
|
|
14
14
|
import { buildDefaultPagesNotFoundResponse } from "./pages-default-404.js";
|
|
15
15
|
import { buildPagesReadinessNextData } from "./pages-readiness.js";
|
|
16
16
|
import { resolvePagesPageMethodResponse } from "./pages-page-method.js";
|
|
17
|
+
import { renderPagesPageResponse } from "./pages-page-response.js";
|
|
18
|
+
import { hasPagesGetInitialProps } from "./pages-get-initial-props.js";
|
|
17
19
|
import { buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, normalizePagesDataRequest, parseNextDataPathname } from "./pages-data-route.js";
|
|
20
|
+
import { resolvePagesPageData } from "./pages-page-data.js";
|
|
18
21
|
import { createPagesReqRes } from "./pages-node-compat.js";
|
|
19
22
|
import { collectAssetTags, resolveClientModuleUrl } from "./pages-asset-tags.js";
|
|
20
|
-
import { renderPagesPageResponse } from "./pages-page-response.js";
|
|
21
|
-
import { resolvePagesPageData } from "./pages-page-data.js";
|
|
22
23
|
//#region src/server/pages-page-handler.ts
|
|
24
|
+
function shouldEmitPagesClientTraceMetadata(pageModule, appComponent) {
|
|
25
|
+
if (typeof pageModule.getServerSideProps === "function") return true;
|
|
26
|
+
if (typeof pageModule.getStaticProps === "function") return false;
|
|
27
|
+
return hasPagesGetInitialProps(pageModule.default) || hasPagesGetInitialProps(appComponent);
|
|
28
|
+
}
|
|
23
29
|
function buildI18nRenderContext(i18nConfig, locale, currentDefaultLocale, domainLocales) {
|
|
24
30
|
return {
|
|
25
31
|
locale,
|
|
@@ -334,7 +340,7 @@ function createPagesPageHandler(opts) {
|
|
|
334
340
|
getFontLinks,
|
|
335
341
|
getFontStyles,
|
|
336
342
|
getSSRHeadHTML: typeof getSSRHeadHTML === "function" ? getSSRHeadHTML : void 0,
|
|
337
|
-
clientTraceMetadata: vinextConfig.clientTraceMetadata,
|
|
343
|
+
clientTraceMetadata: shouldEmitPagesClientTraceMetadata(pageModule, AppComponent) ? vinextConfig.clientTraceMetadata : void 0,
|
|
338
344
|
gsspRes,
|
|
339
345
|
isrCacheKey: pageIsrCacheKey,
|
|
340
346
|
expireSeconds: vinextConfig.expireTime,
|
|
@@ -400,4 +406,4 @@ function createPagesPageHandler(opts) {
|
|
|
400
406
|
return renderPage;
|
|
401
407
|
}
|
|
402
408
|
//#endregion
|
|
403
|
-
export { createPagesPageHandler };
|
|
409
|
+
export { createPagesPageHandler, shouldEmitPagesClientTraceMetadata };
|
|
@@ -34,11 +34,13 @@ type PagesPipelineDeps = {
|
|
|
34
34
|
hadBasePath: boolean;
|
|
35
35
|
isDataReq: boolean;
|
|
36
36
|
isDataRequest: boolean;
|
|
37
|
+
hasMiddleware: boolean;
|
|
37
38
|
ctx?: unknown;
|
|
38
39
|
rawSearch?: string;
|
|
39
40
|
matchPageRoute?: ((pathname: string, request: Request) => {
|
|
40
41
|
route: {
|
|
41
42
|
isDynamic: boolean;
|
|
43
|
+
pattern?: string;
|
|
42
44
|
};
|
|
43
45
|
} | null) | null;
|
|
44
46
|
runMiddleware?: ((request: Request, ctx: unknown, opts: {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { addBasePathToPathname, hasBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { patternToNextFormat } from "../routing/route-validation.js";
|
|
2
3
|
import { applyMiddlewareRequestHeaders, isExternalUrl, matchRedirect, matchRewrite, preserveRedirectDestinationQuery, proxyExternalRequest, requestContextFromRequest, sanitizeDestination } from "../config/config-matchers.js";
|
|
3
4
|
import { applyConfigHeadersToHeaderRecord, cloneRequestWithUrl, normalizeTrailingSlash } from "./request-pipeline.js";
|
|
4
5
|
import { mergeRewriteQuery } from "../utils/query.js";
|
|
@@ -141,6 +142,13 @@ async function runPagesRequest(request, deps) {
|
|
|
141
142
|
});
|
|
142
143
|
let resolvedPathname = pathnameForResolvedUrl(resolvedUrl);
|
|
143
144
|
const matchResolvedPathname = (p) => i18nConfig ? normalizeDefaultLocalePathname(p, i18nConfig, { hostname: requestHostname }) : p;
|
|
145
|
+
const matchedPathnameForRoute = (routePattern) => {
|
|
146
|
+
const matchedPathname = routePattern ? patternToNextFormat(routePattern) : resolvedPathname;
|
|
147
|
+
if (!i18nConfig) return matchedPathname;
|
|
148
|
+
const resolvedLocale = resolvedPathname.split("/", 3)[1];
|
|
149
|
+
if (resolvedLocale && i18nConfig.locales.includes(resolvedLocale)) return matchedPathname === "/" ? `/${resolvedLocale}` : `/${resolvedLocale}${matchedPathname}`;
|
|
150
|
+
return matchResolvedPathname(matchedPathname);
|
|
151
|
+
};
|
|
144
152
|
if (configHeaders.length) applyConfigHeadersToHeaderRecord(middlewareHeaders, {
|
|
145
153
|
configHeaders,
|
|
146
154
|
pathname: matchPathname,
|
|
@@ -268,12 +276,28 @@ async function runPagesRequest(request, deps) {
|
|
|
268
276
|
if (fallbackFilesystemResult) return fallbackFilesystemResult;
|
|
269
277
|
const fallbackApiResult = await handleResolvedApiRoute();
|
|
270
278
|
if (fallbackApiResult) return fallbackApiResult;
|
|
279
|
+
renderPageMatch = deps.matchPageRoute ? deps.matchPageRoute(resolvedPathname, request) : null;
|
|
271
280
|
response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
272
281
|
matchedFallbackRewrite = true;
|
|
273
282
|
if (response.status !== 404) break;
|
|
274
283
|
}
|
|
275
284
|
if (response.status === 404 && shouldDeferErrorPageOnMiss && !matchedFallbackRewrite) response = await deps.renderPage(request, resolvedUrl, void 0, stagedHeaders);
|
|
276
|
-
const
|
|
285
|
+
const matchedPathHeaders = { ...middlewareHeaders };
|
|
286
|
+
if ((isDataReq || isDataRequest) && deps.hasMiddleware && !renderPageMatch && response.status === 404 && (middlewareStatus === void 0 || middlewareStatus === 200 || middlewareStatus === 404)) {
|
|
287
|
+
const headers = new Headers(response.headers);
|
|
288
|
+
headers.set("content-type", "application/json");
|
|
289
|
+
headers.set("x-nextjs-matched-path", matchResolvedPathname(pathname));
|
|
290
|
+
return {
|
|
291
|
+
type: "response",
|
|
292
|
+
response: mergeHeaders(new Response("{}", {
|
|
293
|
+
status: 200,
|
|
294
|
+
headers
|
|
295
|
+
}), matchedPathHeaders, void 0),
|
|
296
|
+
defaultContentType: "application/json"
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
if ((isDataReq || isDataRequest) && renderPageMatch && (middlewareStatus ?? response.status) === 200) matchedPathHeaders["x-nextjs-matched-path"] = matchedPathnameForRoute(renderPageMatch?.route.pattern);
|
|
300
|
+
const merged = mergeHeaders(response, matchedPathHeaders, middlewareStatus);
|
|
277
301
|
if (merged !== response) merged.__vinextStreamedHtmlResponse = response.__vinextStreamedHtmlResponse;
|
|
278
302
|
return {
|
|
279
303
|
type: "response",
|
|
@@ -7,11 +7,13 @@ type PrerenderManifestRoute = {
|
|
|
7
7
|
path?: string;
|
|
8
8
|
router?: string;
|
|
9
9
|
fallback?: boolean;
|
|
10
|
+
headers?: Record<string, string>;
|
|
10
11
|
};
|
|
11
12
|
type PrerenderManifest = {
|
|
12
13
|
buildId?: string;
|
|
13
14
|
trailingSlash?: boolean;
|
|
14
15
|
routes?: PrerenderManifestRoute[];
|
|
16
|
+
pregeneratedConcretePaths?: Array<[string, string[]]>;
|
|
15
17
|
};
|
|
16
18
|
declare function readPrerenderManifest(manifestPath: string): PrerenderManifest | null;
|
|
17
19
|
declare function getRenderedAppRoutes(routes: PrerenderManifestRoute[]): PrerenderManifestRoute[];
|
|
@@ -30,4 +32,4 @@ declare function isFallbackShellArtifactPath(pathname: string, route?: Prerender
|
|
|
30
32
|
*/
|
|
31
33
|
declare function buildPregeneratedConcretePathTable(manifest: PrerenderManifest): Array<[string, string[]]>;
|
|
32
34
|
//#endregion
|
|
33
|
-
export { buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
|
|
35
|
+
export { PrerenderManifest, buildPregeneratedConcretePathTable, getRenderedAppRoutes, isFallbackShellArtifactPath, readPrerenderManifest };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "
|
|
1
|
+
import { VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER } from "../utils/protocol-headers.js";
|
|
2
2
|
import { isUnknownRecord } from "../utils/record.js";
|
|
3
3
|
//#region src/server/prerender-route-params.ts
|
|
4
4
|
function isPrerenderRouteParams(value) {
|
|
@@ -74,7 +74,7 @@ declare function mergeResponseHeaders(middlewareHeaders: Record<string, string |
|
|
|
74
74
|
* arguments in (headers, response) order. The request path now calls
|
|
75
75
|
* `runPagesRequest`, which uses `mergeHeaders` directly; this wrapper is retained
|
|
76
76
|
* only for its existing tests and any external callers, so there is a single
|
|
77
|
-
* implementation to keep in sync.
|
|
77
|
+
* implementation to keep in sync. The init-owned Cloudflare Worker template delegates here.
|
|
78
78
|
*/
|
|
79
79
|
declare function mergeWebResponse(middlewareHeaders: Record<string, string | string[]>, response: Response, statusOverride?: number): Response;
|
|
80
80
|
/**
|