vinext 0.1.8 → 0.2.1
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 +51 -30
- package/dist/build/css-url-assets.d.ts +3 -1
- package/dist/build/css-url-assets.js +18 -1
- package/dist/build/inject-pregenerated-paths.d.ts +7 -0
- package/dist/build/inject-pregenerated-paths.js +21 -0
- package/dist/build/layout-classification.js +1 -1
- package/dist/build/nitro-route-rules.js +1 -1
- 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-server-entry.d.ts +1 -0
- package/dist/build/prerender-server-entry.js +49 -0
- package/dist/build/prerender-server-pool.d.ts +44 -0
- package/dist/build/prerender-server-pool.js +194 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +98 -27
- package/dist/build/report.d.ts +13 -2
- package/dist/build/report.js +99 -2
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +12 -2
- package/dist/build/standalone.js +2 -0
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.d.ts +4 -6
- package/dist/check.js +48 -11
- package/dist/cli-args.d.ts +1 -2
- package/dist/cli-args.js +1 -1
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +112 -96
- 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/client/navigation-runtime.d.ts +2 -0
- package/dist/client/navigation-runtime.js +3 -1
- package/dist/client/vinext-next-data.d.ts +4 -1
- package/dist/client/window-next.d.ts +2 -1
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/config/config-matchers.js +45 -19
- package/dist/config/next-config.d.ts +41 -9
- package/dist/config/next-config.js +60 -3
- package/dist/config/prerender.d.ts +34 -0
- package/dist/config/prerender.js +55 -0
- package/dist/entries/app-browser-entry.js +5 -1
- package/dist/entries/app-rsc-entry.d.ts +5 -3
- package/dist/entries/app-rsc-entry.js +44 -10
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/pages-client-entry.d.ts +3 -0
- package/dist/entries/pages-client-entry.js +28 -3
- package/dist/entries/pages-server-entry.js +23 -6
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +59 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +482 -120
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +839 -0
- package/dist/init-platform.d.ts +40 -0
- package/dist/init-platform.js +195 -0
- package/dist/init.d.ts +16 -38
- package/dist/init.js +209 -99
- 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 +9 -2
- package/dist/packages/cloudflare/src/deploy-config.js +150 -0
- package/dist/packages/cloudflare/src/deploy-help.js +55 -0
- package/dist/packages/cloudflare/src/deploy.js +272 -0
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +44 -20
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.d.ts +27 -1
- package/dist/plugins/ast-utils.js +32 -1
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/fonts.js +1 -1
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/og-assets.js +2 -1
- package/dist/plugins/optimize-imports.js +1 -1
- package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
- package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
- package/dist/plugins/sass.d.ts +17 -1
- package/dist/plugins/sass.js +74 -1
- package/dist/plugins/styled-jsx.d.ts +16 -0
- package/dist/plugins/styled-jsx.js +149 -0
- 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 +23 -2
- package/dist/routing/app-route-graph.js +138 -38
- package/dist/routing/file-matcher.d.ts +11 -1
- package/dist/routing/file-matcher.js +18 -3
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/api-handler.js +9 -14
- package/dist/server/app-browser-action-result.d.ts +4 -1
- package/dist/server/app-browser-action-result.js +8 -1
- package/dist/server/app-browser-entry.js +198 -57
- 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.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +60 -31
- package/dist/server/app-browser-server-action-client.d.ts +1 -1
- package/dist/server/app-browser-server-action-client.js +8 -7
- package/dist/server/app-browser-state.d.ts +12 -1
- package/dist/server/app-browser-state.js +25 -8
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +42 -24
- package/dist/server/app-elements-wire.d.ts +9 -2
- package/dist/server/app-elements-wire.js +8 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +4 -3
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +10 -6
- package/dist/server/app-hydration-cache-publication.d.ts +11 -0
- package/dist/server/app-hydration-cache-publication.js +43 -0
- package/dist/server/app-middleware.d.ts +4 -3
- package/dist/server/app-middleware.js +8 -3
- package/dist/server/app-optimistic-routing.js +11 -4
- package/dist/server/app-page-boundary.js +2 -1
- package/dist/server/app-page-cache-finalizer.d.ts +1 -0
- package/dist/server/app-page-cache-finalizer.js +5 -4
- 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 +27 -7
- package/dist/server/app-page-dispatch.d.ts +1 -0
- package/dist/server/app-page-dispatch.js +26 -8
- package/dist/server/app-page-element-builder.d.ts +2 -1
- package/dist/server/app-page-element-builder.js +59 -4
- package/dist/server/app-page-execution.js +2 -1
- package/dist/server/app-page-probe.js +5 -0
- package/dist/server/app-page-render-identity.d.ts +2 -0
- package/dist/server/app-page-render-identity.js +3 -2
- package/dist/server/app-page-render.d.ts +2 -0
- package/dist/server/app-page-render.js +85 -16
- package/dist/server/app-page-request.d.ts +14 -0
- package/dist/server/app-page-request.js +69 -4
- package/dist/server/app-page-response.d.ts +7 -0
- package/dist/server/app-page-response.js +16 -4
- package/dist/server/app-page-route-wiring.d.ts +8 -1
- package/dist/server/app-page-route-wiring.js +32 -18
- package/dist/server/app-page-segment-state.d.ts +2 -1
- package/dist/server/app-page-segment-state.js +3 -1
- package/dist/server/app-page-stream.d.ts +7 -1
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-route-handler-execution.js +5 -1
- 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-tree-prefetch.d.ts +43 -0
- package/dist/server/app-route-tree-prefetch.js +187 -0
- package/dist/server/app-router-entry.js +9 -2
- package/dist/server/app-rsc-cache-busting.d.ts +2 -1
- package/dist/server/app-rsc-cache-busting.js +9 -4
- package/dist/server/app-rsc-handler.d.ts +7 -0
- package/dist/server/app-rsc-handler.js +148 -39
- package/dist/server/app-rsc-render-mode.d.ts +3 -2
- package/dist/server/app-rsc-render-mode.js +4 -1
- package/dist/server/app-rsc-request-normalization.d.ts +6 -6
- package/dist/server/app-rsc-request-normalization.js +10 -8
- package/dist/server/app-segment-config.d.ts +11 -0
- package/dist/server/app-segment-config.js +62 -6
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +61 -30
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +13 -5
- package/dist/server/app-ssr-stream.d.ts +7 -3
- package/dist/server/app-ssr-stream.js +10 -6
- package/dist/server/app-visited-response-cache.d.ts +6 -0
- package/dist/server/app-visited-response-cache.js +3 -1
- package/dist/server/cache-control.d.ts +3 -1
- package/dist/server/cache-control.js +13 -1
- 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-route-files.js +4 -0
- package/dist/server/dev-server.d.ts +11 -1
- package/dist/server/dev-server.js +94 -35
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/fetch-handler.d.ts +2 -0
- package/dist/server/fetch-handler.js +18 -0
- package/dist/server/headers.d.ts +7 -15
- package/dist/server/headers.js +11 -18
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/implicit-tags.js +1 -1
- package/dist/server/isr-cache.d.ts +3 -2
- package/dist/server/isr-cache.js +9 -5
- package/dist/server/metadata-routes.d.ts +3 -1
- package/dist/server/metadata-routes.js +12 -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-api-route.js +2 -2
- 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-data-route.d.ts +4 -2
- package/dist/server/pages-data-route.js +18 -4
- package/dist/server/pages-dev-module-url.d.ts +2 -1
- package/dist/server/pages-dev-module-url.js +6 -3
- package/dist/server/pages-node-compat.d.ts +19 -1
- package/dist/server/pages-node-compat.js +81 -4
- package/dist/server/pages-page-data.d.ts +33 -1
- package/dist/server/pages-page-data.js +62 -33
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +38 -19
- package/dist/server/pages-page-response.d.ts +8 -0
- package/dist/server/pages-page-response.js +7 -3
- package/dist/server/pages-request-pipeline.d.ts +9 -5
- package/dist/server/pages-request-pipeline.js +55 -7
- package/dist/server/pages-router-entry.d.ts +30 -0
- package/dist/server/pages-router-entry.js +108 -0
- 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 +5 -3
- package/dist/server/prod-server.js +68 -39
- package/dist/server/request-pipeline.js +2 -1
- package/dist/server/seed-cache.js +4 -4
- 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-handler.js +8 -1
- package/dist/shims/cache.js +22 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/fetch-cache.d.ts +3 -1
- package/dist/shims/fetch-cache.js +77 -52
- package/dist/shims/form.d.ts +4 -2
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +7 -1
- package/dist/shims/headers.js +17 -3
- package/dist/shims/image.js +75 -14
- package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
- package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
- 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 +3 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +40 -58
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +10 -5
- package/dist/shims/internal/pages-data-fetch-dedup.js +84 -14
- package/dist/shims/internal/pages-data-target.d.ts +18 -12
- package/dist/shims/internal/pages-data-target.js +97 -13
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/layout-segment-context.d.ts +4 -1
- package/dist/shims/layout-segment-context.js +18 -4
- package/dist/shims/link.d.ts +1 -1
- package/dist/shims/link.js +224 -58
- package/dist/shims/navigation.d.ts +19 -3
- package/dist/shims/navigation.js +245 -47
- package/dist/shims/request-context.js +18 -0
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +5 -7
- package/dist/shims/router.js +387 -102
- package/dist/shims/server.js +3 -2
- package/dist/shims/slot.js +3 -6
- package/dist/shims/unified-request-context.js +1 -0
- package/dist/typegen.js +1 -1
- 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 +3 -3
- package/dist/utils/project.d.ts +48 -2
- package/dist/utils/project.js +225 -4
- package/dist/utils/protocol-headers.d.ts +23 -0
- package/dist/utils/protocol-headers.js +23 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/dist/utils/vite-version.d.ts +2 -0
- package/dist/utils/vite-version.js +11 -1
- package/package.json +47 -2
- package/dist/deploy.d.ts +0 -197
- package/dist/deploy.js +0 -1040
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
|
@@ -78,7 +78,8 @@ function parseImageParams(url, allowedWidths = [...DEFAULT_DEVICE_SIZES, ...DEFA
|
|
|
78
78
|
const allowedParamNames = new Set([
|
|
79
79
|
"url",
|
|
80
80
|
"w",
|
|
81
|
-
"q"
|
|
81
|
+
"q",
|
|
82
|
+
"dpl"
|
|
82
83
|
]);
|
|
83
84
|
for (const name of url.searchParams.keys()) if (!allowedParamNames.has(name) || url.searchParams.getAll(name).length !== 1) return null;
|
|
84
85
|
const imageUrl = url.searchParams.get("url");
|
|
@@ -225,5 +226,54 @@ async function handleImageOptimization(request, handlers, allowedWidths, imageCo
|
|
|
225
226
|
return createPassthroughImageResponse(refetchedSource, imageConfig);
|
|
226
227
|
}
|
|
227
228
|
}
|
|
229
|
+
const _IMAGE_OPTIMIZER_KEY = Symbol.for("vinext.imageOptimizer");
|
|
230
|
+
const _gImageOptimizer = globalThis;
|
|
231
|
+
/**
|
|
232
|
+
* Register the active image optimizer (transform backend). An explicit
|
|
233
|
+
* registration always wins; passing `null` clears it (falling back to
|
|
234
|
+
* unoptimized passthrough).
|
|
235
|
+
*
|
|
236
|
+
* Configure this declaratively via the `images.optimizer` option on the
|
|
237
|
+
* `vinext()` plugin in your `vite.config.ts` rather than calling it directly.
|
|
238
|
+
* On Cloudflare Workers:
|
|
239
|
+
*
|
|
240
|
+
* ```ts
|
|
241
|
+
* import { vinext } from "vinext";
|
|
242
|
+
* import { imagesOptimizer } from "@vinext/cloudflare/images/images-optimizer";
|
|
243
|
+
*
|
|
244
|
+
* export default defineConfig({
|
|
245
|
+
* plugins: [vinext({ images: { optimizer: imagesOptimizer() } })],
|
|
246
|
+
* });
|
|
247
|
+
* ```
|
|
248
|
+
*
|
|
249
|
+
* The plugin registers the optimizer across every runtime/router entry, so you
|
|
250
|
+
* don't have to wire `env.IMAGES` into a custom worker entry. This setter
|
|
251
|
+
* remains the internal registration target.
|
|
252
|
+
*/
|
|
253
|
+
function setImageOptimizer(optimizer) {
|
|
254
|
+
_gImageOptimizer[_IMAGE_OPTIMIZER_KEY] = optimizer ?? void 0;
|
|
255
|
+
}
|
|
256
|
+
/** Get the active image optimizer, or `null` when none is configured. */
|
|
257
|
+
function getImageOptimizer() {
|
|
258
|
+
return _gImageOptimizer[_IMAGE_OPTIMIZER_KEY] ?? null;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Handle an image optimization request using the configured optimizer (if any).
|
|
262
|
+
*
|
|
263
|
+
* This is the single entry point every runtime/router seam (App Router worker,
|
|
264
|
+
* Pages worker, Node prod server) should call: it reads the registered
|
|
265
|
+
* {@link ImageOptimizer} and wires its `transformImage` into
|
|
266
|
+
* {@link handleImageOptimization}, with the caller supplying the runtime's
|
|
267
|
+
* `fetchAsset` (e.g. the Cloudflare `ASSETS` binding, or filesystem reads on
|
|
268
|
+
* Node). When no optimizer is registered, the request is served unoptimized
|
|
269
|
+
* (passthrough) with the same security/cache headers.
|
|
270
|
+
*/
|
|
271
|
+
function handleConfiguredImageOptimization(request, fetchAsset, allowedWidths, imageConfig) {
|
|
272
|
+
const optimizer = getImageOptimizer();
|
|
273
|
+
return handleImageOptimization(request, {
|
|
274
|
+
fetchAsset,
|
|
275
|
+
transformImage: optimizer ? (body, options) => optimizer.transformImage(body, options) : void 0
|
|
276
|
+
}, allowedWidths, imageConfig);
|
|
277
|
+
}
|
|
228
278
|
//#endregion
|
|
229
|
-
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 };
|
|
279
|
+
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 };
|
|
@@ -33,7 +33,7 @@ function buildAppPageTags(cleanPathname, extraTags, routeSegments) {
|
|
|
33
33
|
return buildPageCacheTags(cleanPathname, extraTags, [...routeSegments], "page");
|
|
34
34
|
}
|
|
35
35
|
function buildPageCacheTags(pathname, extraTags, routeSegments, leafKind) {
|
|
36
|
-
const tags = [pathname, `${NEXT_CACHE_IMPLICIT_TAG_ID}${pathname}`];
|
|
36
|
+
const tags = [pathname, `${NEXT_CACHE_IMPLICIT_TAG_ID}${pathname.length > 1 && pathname.endsWith("/") ? pathname.slice(0, -1) : pathname}`];
|
|
37
37
|
if (pathname === "/") appendUnique(tags, `${NEXT_CACHE_IMPLICIT_TAG_ID}/index`);
|
|
38
38
|
if (pathname === "/index") appendUnique(tags, `${NEXT_CACHE_IMPLICIT_TAG_ID}/`);
|
|
39
39
|
appendDerivedTags(tags, buildRouteCachePath(routeSegments, leafKind));
|
|
@@ -34,6 +34,7 @@ declare const PRERENDER_REVALIDATE_HEADER = "x-prerender-revalidate";
|
|
|
34
34
|
*/
|
|
35
35
|
declare const PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER = "x-prerender-revalidate-if-generated";
|
|
36
36
|
declare function getRevalidateSecret(): string;
|
|
37
|
+
declare function isRevalidateSecret(value: string | null | undefined): boolean;
|
|
37
38
|
/**
|
|
38
39
|
* Authorize an incoming request as an on-demand revalidation trigger. Mirrors
|
|
39
40
|
* Next.js's `checkIsOnDemandRevalidate`: the {@link PRERENDER_REVALIDATE_HEADER}
|
|
@@ -95,7 +96,7 @@ declare function buildPagesCacheValue(html: string, pageData: object, status?: n
|
|
|
95
96
|
/**
|
|
96
97
|
* Build a CachedAppPageValue for the App Router ISR cache.
|
|
97
98
|
*/
|
|
98
|
-
declare function buildAppPageCacheValue(html: string, rscData?: ArrayBuffer, status?: number, renderObservation?: RenderObservation): CachedAppPageValue;
|
|
99
|
+
declare function buildAppPageCacheValue(html: string, rscData?: ArrayBuffer, status?: number, renderObservation?: RenderObservation, headers?: CachedAppPageValue["headers"]): CachedAppPageValue;
|
|
99
100
|
/**
|
|
100
101
|
* Compute an ISR cache key for a given router type and pathname.
|
|
101
102
|
* Long pathnames are hashed to stay within KV key-length limits (512 bytes).
|
|
@@ -124,4 +125,4 @@ declare function setRevalidateDuration(key: string, seconds: number): void;
|
|
|
124
125
|
*/
|
|
125
126
|
declare function getRevalidateDuration(key: string): number | undefined;
|
|
126
127
|
//#endregion
|
|
127
|
-
export { ISRCacheEntry, PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, getRevalidateSecret, isOnDemandRevalidateRequest, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
|
|
128
|
+
export { ISRCacheEntry, PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, getRevalidateSecret, isOnDemandRevalidateRequest, isRevalidateSecret, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
|
package/dist/server/isr-cache.js
CHANGED
|
@@ -80,6 +80,10 @@ function safeEqual(a, b) {
|
|
|
80
80
|
for (let i = 0; i < a.length; i++) mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);
|
|
81
81
|
return mismatch === 0;
|
|
82
82
|
}
|
|
83
|
+
function isRevalidateSecret(value) {
|
|
84
|
+
if (typeof value !== "string" || value.length === 0) return false;
|
|
85
|
+
return safeEqual(value, getRevalidateSecret());
|
|
86
|
+
}
|
|
83
87
|
/**
|
|
84
88
|
* Authorize an incoming request as an on-demand revalidation trigger. Mirrors
|
|
85
89
|
* Next.js's `checkIsOnDemandRevalidate`: the {@link PRERENDER_REVALIDATE_HEADER}
|
|
@@ -87,8 +91,8 @@ function safeEqual(a, b) {
|
|
|
87
91
|
* NOT sufficient — see the security note on {@link PRERENDER_REVALIDATE_HEADER}.
|
|
88
92
|
*/
|
|
89
93
|
function isOnDemandRevalidateRequest(headerValue) {
|
|
90
|
-
if (typeof headerValue !== "string"
|
|
91
|
-
return
|
|
94
|
+
if (typeof headerValue !== "string") return false;
|
|
95
|
+
return isRevalidateSecret(headerValue);
|
|
92
96
|
}
|
|
93
97
|
/**
|
|
94
98
|
* Get a cache entry with staleness information.
|
|
@@ -188,12 +192,12 @@ function buildPagesCacheValue(html, pageData, status) {
|
|
|
188
192
|
/**
|
|
189
193
|
* Build a CachedAppPageValue for the App Router ISR cache.
|
|
190
194
|
*/
|
|
191
|
-
function buildAppPageCacheValue(html, rscData, status, renderObservation) {
|
|
195
|
+
function buildAppPageCacheValue(html, rscData, status, renderObservation, headers) {
|
|
192
196
|
const value = {
|
|
193
197
|
kind: "APP_PAGE",
|
|
194
198
|
html,
|
|
195
199
|
rscData,
|
|
196
|
-
headers
|
|
200
|
+
headers,
|
|
197
201
|
postponed: void 0,
|
|
198
202
|
status
|
|
199
203
|
};
|
|
@@ -279,4 +283,4 @@ function getRevalidateDuration(key) {
|
|
|
279
283
|
return revalidateDurations.get(key);
|
|
280
284
|
}
|
|
281
285
|
//#endregion
|
|
282
|
-
export { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, getRevalidateSecret, isOnDemandRevalidateRequest, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
|
|
286
|
+
export { PRERENDER_REVALIDATE_HEADER, PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER, appIsrHtmlKey, appIsrRouteKey, appIsrRscKey, buildAppPageCacheValue, buildPagesCacheValue, getRevalidateDuration, getRevalidateSecret, isOnDemandRevalidateRequest, isRevalidateSecret, isrCacheKey, isrGet, isrSet, isrSetPrerenderedAppPage, normalizeMountedSlotsHeader, setRevalidateDuration, triggerBackgroundRegeneration };
|
|
@@ -131,9 +131,11 @@ declare function getMetadataImageRouteKind(route: Pick<MetadataFileRoute, "type"
|
|
|
131
131
|
declare function isValidMetadataImageId(id: string): boolean;
|
|
132
132
|
declare function matchMetadataRoutePattern(urlParts: string[], patternParts: string[]): Record<string, string | string[]> | null;
|
|
133
133
|
declare function matchMetadataFileBaseName(metaType: string, baseName: string): string | null;
|
|
134
|
+
/** Clear the {@link scanMetadataFiles} cache (call when app files change in dev). */
|
|
135
|
+
declare function invalidateMetadataFileCache(): void;
|
|
134
136
|
/**
|
|
135
137
|
* Scan an app directory for metadata files.
|
|
136
138
|
*/
|
|
137
139
|
declare function scanMetadataFiles(appDir: string): MetadataFileRoute[];
|
|
138
140
|
//#endregion
|
|
139
|
-
export { METADATA_FILE_MAP, ManifestConfig, MetadataFileRoute, MetadataRouteHeadData, RobotsConfig, SitemapEntry, fillStaticMetadataSegment, getMetadataImageRouteKind, getMetadataRouteKind, isValidMetadataImageId, manifestToJson, matchMetadataFileBaseName, matchMetadataRoutePattern, robotsToText, scanMetadataFiles, sitemapToXml };
|
|
141
|
+
export { METADATA_FILE_MAP, ManifestConfig, MetadataFileRoute, MetadataRouteHeadData, RobotsConfig, SitemapEntry, fillStaticMetadataSegment, getMetadataImageRouteKind, getMetadataRouteKind, invalidateMetadataFileCache, isValidMetadataImageId, manifestToJson, matchMetadataFileBaseName, matchMetadataRoutePattern, robotsToText, scanMetadataFiles, sitemapToXml };
|
|
@@ -357,10 +357,18 @@ function matchMetadataFileBaseName(metaType, baseName) {
|
|
|
357
357
|
}
|
|
358
358
|
return null;
|
|
359
359
|
}
|
|
360
|
+
let cachedMetadataRoutes = null;
|
|
361
|
+
let cachedMetadataAppDir = null;
|
|
362
|
+
/** Clear the {@link scanMetadataFiles} cache (call when app files change in dev). */
|
|
363
|
+
function invalidateMetadataFileCache() {
|
|
364
|
+
cachedMetadataRoutes = null;
|
|
365
|
+
cachedMetadataAppDir = null;
|
|
366
|
+
}
|
|
360
367
|
/**
|
|
361
368
|
* Scan an app directory for metadata files.
|
|
362
369
|
*/
|
|
363
370
|
function scanMetadataFiles(appDir) {
|
|
371
|
+
if (cachedMetadataRoutes && cachedMetadataAppDir === appDir) return cachedMetadataRoutes;
|
|
364
372
|
const routes = [];
|
|
365
373
|
function scan(dir, urlPrefix, parentSegments) {
|
|
366
374
|
if (!fs.existsSync(dir)) return;
|
|
@@ -409,7 +417,9 @@ function scanMetadataFiles(appDir) {
|
|
|
409
417
|
if (!existing) byUrl.set(route.servedUrl, route);
|
|
410
418
|
else if (route.isDynamic && !existing.isDynamic) byUrl.set(route.servedUrl, route);
|
|
411
419
|
}
|
|
412
|
-
|
|
420
|
+
cachedMetadataRoutes = Array.from(byUrl.values());
|
|
421
|
+
cachedMetadataAppDir = appDir;
|
|
422
|
+
return cachedMetadataRoutes;
|
|
413
423
|
}
|
|
414
424
|
function resolveStaticMetadataAltFilePath(dir, baseName) {
|
|
415
425
|
const altPath = path.join(dir, `${baseName}.alt.txt`);
|
|
@@ -430,4 +440,4 @@ function getStaticContentType(ext, fallback) {
|
|
|
430
440
|
}[ext] ?? fallback;
|
|
431
441
|
}
|
|
432
442
|
//#endregion
|
|
433
|
-
export { METADATA_FILE_MAP, fillStaticMetadataSegment, getMetadataImageRouteKind, getMetadataRouteKind, isValidMetadataImageId, manifestToJson, matchMetadataFileBaseName, matchMetadataRoutePattern, robotsToText, scanMetadataFiles, sitemapToXml };
|
|
443
|
+
export { METADATA_FILE_MAP, fillStaticMetadataSegment, getMetadataImageRouteKind, getMetadataRouteKind, invalidateMetadataFileCache, isValidMetadataImageId, manifestToJson, matchMetadataFileBaseName, matchMetadataRoutePattern, robotsToText, scanMetadataFiles, sitemapToXml };
|
|
@@ -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
|
|
@@ -4,10 +4,10 @@ import { NextRequest } from "../shims/server.js";
|
|
|
4
4
|
import { internalServerErrorResponse } from "./http-error-responses.js";
|
|
5
5
|
import { cloneRequestWithUrl } from "./request-pipeline.js";
|
|
6
6
|
import { mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
|
|
7
|
-
import { PagesBodyParseError } from "./pages-media-type.js";
|
|
8
|
-
import { isEdgeApiRuntime } from "./edge-api-runtime.js";
|
|
9
7
|
import { resolveBodyParserConfig } from "./pages-body-parser-config.js";
|
|
8
|
+
import { PagesBodyParseError } from "./pages-media-type.js";
|
|
10
9
|
import { createPagesReqRes, parsePagesApiBody } from "./pages-node-compat.js";
|
|
10
|
+
import { isEdgeApiRuntime } from "./edge-api-runtime.js";
|
|
11
11
|
//#region src/server/pages-api-route.ts
|
|
12
12
|
function resolveModuleRuntime(module) {
|
|
13
13
|
return module.runtime ?? module.config?.runtime;
|
|
@@ -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 };
|
|
@@ -51,6 +51,7 @@ declare function isNextDataPathname(pathname: string): boolean;
|
|
|
51
51
|
* `/_next/data/<buildId>/about` → null (missing .json suffix)
|
|
52
52
|
*/
|
|
53
53
|
declare function parseNextDataPathname(pathname: string, buildId: string): NextDataMatch | null;
|
|
54
|
+
declare function normalizeNextDataPagePathname(pagePathname: string, trailingSlash?: boolean): string;
|
|
54
55
|
/**
|
|
55
56
|
* Build the JSON envelope returned by `/_next/data/<buildId>/<page>.json`.
|
|
56
57
|
* Mirrors Next.js' `RenderResult(JSON.stringify(props))` path in
|
|
@@ -79,6 +80,7 @@ declare function buildNextDataPropsJsonResponse(props: Record<string, unknown>,
|
|
|
79
80
|
* before checking the status code.
|
|
80
81
|
*/
|
|
81
82
|
declare function buildNextDataNotFoundResponse(): Response;
|
|
83
|
+
declare function buildMiddlewarePrefetchSkipResponse(matchedPathname: string): Response;
|
|
82
84
|
type NormalizePagesDataRequestResult = {
|
|
83
85
|
isDataReq: false;
|
|
84
86
|
request: Request;
|
|
@@ -116,6 +118,6 @@ type NormalizePagesDataRequestResult = {
|
|
|
116
118
|
* Extracted from `entries/pages-server-entry.ts` so both `renderPage` and
|
|
117
119
|
* `runMiddleware` share a single implementation.
|
|
118
120
|
*/
|
|
119
|
-
declare function normalizePagesDataRequest(request: Request, buildId: string | null, basePath?: string): NormalizePagesDataRequestResult;
|
|
121
|
+
declare function normalizePagesDataRequest(request: Request, buildId: string | null, basePath?: string, trailingSlash?: boolean): NormalizePagesDataRequestResult;
|
|
120
122
|
//#endregion
|
|
121
|
-
export { buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, isNextDataPathname, normalizePagesDataRequest, parseNextDataPathname };
|
|
123
|
+
export { buildMiddlewarePrefetchSkipResponse, buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, isNextDataPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { MIDDLEWARE_SKIP_HEADER } from "../utils/protocol-headers.js";
|
|
2
3
|
import { NEXTJS_DEPLOYMENT_ID_HEADER } from "./headers.js";
|
|
3
4
|
//#region src/server/pages-data-route.ts
|
|
4
5
|
/**
|
|
@@ -58,6 +59,10 @@ function parseNextDataPathname(pathname, buildId) {
|
|
|
58
59
|
if (rest.startsWith("index/")) return { pagePathname: `/${rest.slice(6)}` };
|
|
59
60
|
return { pagePathname: `/${rest}` };
|
|
60
61
|
}
|
|
62
|
+
function normalizeNextDataPagePathname(pagePathname, trailingSlash = false) {
|
|
63
|
+
if (!trailingSlash || pagePathname === "/" || pagePathname.endsWith("/")) return pagePathname;
|
|
64
|
+
return `${pagePathname}/`;
|
|
65
|
+
}
|
|
61
66
|
/**
|
|
62
67
|
* Build the JSON envelope returned by `/_next/data/<buildId>/<page>.json`.
|
|
63
68
|
* Mirrors Next.js' `RenderResult(JSON.stringify(props))` path in
|
|
@@ -106,6 +111,14 @@ function buildNextDataNotFoundResponse() {
|
|
|
106
111
|
headers
|
|
107
112
|
});
|
|
108
113
|
}
|
|
114
|
+
function buildMiddlewarePrefetchSkipResponse(matchedPathname) {
|
|
115
|
+
return new Response("{}", { headers: {
|
|
116
|
+
"Content-Type": "application/json",
|
|
117
|
+
"x-matched-path": matchedPathname,
|
|
118
|
+
[MIDDLEWARE_SKIP_HEADER]: "1",
|
|
119
|
+
"Cache-Control": "private, no-cache, no-store, max-age=0, must-revalidate"
|
|
120
|
+
} });
|
|
121
|
+
}
|
|
109
122
|
/**
|
|
110
123
|
* Detect and normalize `/_next/data/<buildId>/<page>.json` requests in one
|
|
111
124
|
* place so the Pages Router pipeline and middleware shim do not need to know
|
|
@@ -124,7 +137,7 @@ function buildNextDataNotFoundResponse() {
|
|
|
124
137
|
* Extracted from `entries/pages-server-entry.ts` so both `renderPage` and
|
|
125
138
|
* `runMiddleware` share a single implementation.
|
|
126
139
|
*/
|
|
127
|
-
function normalizePagesDataRequest(request, buildId, basePath = "") {
|
|
140
|
+
function normalizePagesDataRequest(request, buildId, basePath = "", trailingSlash = false) {
|
|
128
141
|
const reqUrl = new URL(request.url);
|
|
129
142
|
const hadBasePath = !!basePath && hasBasePath(reqUrl.pathname, basePath);
|
|
130
143
|
const dataPathname = basePath ? stripBasePath(reqUrl.pathname, basePath) : reqUrl.pathname;
|
|
@@ -143,15 +156,16 @@ function normalizePagesDataRequest(request, buildId, basePath = "") {
|
|
|
143
156
|
search: "",
|
|
144
157
|
notFoundResponse: buildNextDataNotFoundResponse()
|
|
145
158
|
};
|
|
159
|
+
const pagePathname = normalizeNextDataPagePathname(dataMatch.pagePathname, trailingSlash);
|
|
146
160
|
const normalizedUrl = new URL(reqUrl);
|
|
147
|
-
normalizedUrl.pathname = hadBasePath ? addBasePathToPathname(
|
|
161
|
+
normalizedUrl.pathname = hadBasePath ? addBasePathToPathname(pagePathname, basePath) : pagePathname;
|
|
148
162
|
return {
|
|
149
163
|
isDataReq: true,
|
|
150
164
|
request: new Request(normalizedUrl, request),
|
|
151
|
-
normalizedPathname:
|
|
165
|
+
normalizedPathname: pagePathname,
|
|
152
166
|
search: reqUrl.search,
|
|
153
167
|
notFoundResponse: null
|
|
154
168
|
};
|
|
155
169
|
}
|
|
156
170
|
//#endregion
|
|
157
|
-
export { buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, isNextDataPathname, normalizePagesDataRequest, parseNextDataPathname };
|
|
171
|
+
export { buildMiddlewarePrefetchSkipResponse, buildNextDataJsonResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, isNextDataPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
//#region src/server/pages-dev-module-url.d.ts
|
|
2
|
+
declare function createPagesDevAssetUrl(assetPath: string): string;
|
|
2
3
|
declare function createPagesDevModuleUrl(viteRoot: string, moduleFilePath: string, viteBase: string): string;
|
|
3
4
|
//#endregion
|
|
4
|
-
export { createPagesDevModuleUrl };
|
|
5
|
+
export { createPagesDevAssetUrl, createPagesDevModuleUrl };
|
|
@@ -4,12 +4,15 @@ function normalizeBase(base) {
|
|
|
4
4
|
if (!base || base === "/") return "/";
|
|
5
5
|
return `/${base.replace(/^\/+|\/+$/g, "")}/`;
|
|
6
6
|
}
|
|
7
|
-
function
|
|
7
|
+
function encodePagesDevModulePath(modulePath) {
|
|
8
8
|
return encodeURI(modulePath).replace(/%5B/gi, "[").replace(/%5D/gi, "]").replace(/\?/g, "%3F").replace(/#/g, "%23");
|
|
9
9
|
}
|
|
10
|
+
function createPagesDevAssetUrl(assetPath) {
|
|
11
|
+
return "/" + encodePagesDevModulePath(assetPath.replace(/^\/+/, ""));
|
|
12
|
+
}
|
|
10
13
|
function createPagesDevModuleUrl(viteRoot, moduleFilePath, viteBase) {
|
|
11
14
|
const relativePath = (/^[A-Za-z]:[\\/]/.test(viteRoot) ? path.win32 : path).relative(viteRoot, moduleFilePath).replace(/\\/g, "/");
|
|
12
|
-
return normalizeBase(viteBase) +
|
|
15
|
+
return normalizeBase(viteBase) + encodePagesDevModulePath(relativePath);
|
|
13
16
|
}
|
|
14
17
|
//#endregion
|
|
15
|
-
export { createPagesDevModuleUrl };
|
|
18
|
+
export { createPagesDevAssetUrl, createPagesDevModuleUrl };
|
|
@@ -27,6 +27,16 @@ type PagesReqResResponse = Writable & {
|
|
|
27
27
|
redirect: (statusOrUrl: number | string, url?: string) => void;
|
|
28
28
|
getHeaders: () => PagesReqResHeaders;
|
|
29
29
|
revalidate: (urlPath: string, opts?: RevalidateOptions) => Promise<void>;
|
|
30
|
+
setPreviewData: (data: object | string, options?: {
|
|
31
|
+
maxAge?: number;
|
|
32
|
+
path?: string;
|
|
33
|
+
}) => PagesReqResResponse;
|
|
34
|
+
};
|
|
35
|
+
type PagesRequestCookiesCarrier = {
|
|
36
|
+
headers: {
|
|
37
|
+
cookie?: string | string[] | null | undefined;
|
|
38
|
+
};
|
|
39
|
+
cookies?: unknown;
|
|
30
40
|
};
|
|
31
41
|
type CreatePagesReqResOptions = {
|
|
32
42
|
body: unknown;
|
|
@@ -39,6 +49,7 @@ type CreatePagesReqResResult = {
|
|
|
39
49
|
res: PagesReqResResponse;
|
|
40
50
|
responsePromise: Promise<Response>;
|
|
41
51
|
};
|
|
52
|
+
type PagesPreviewData = object | string;
|
|
42
53
|
/**
|
|
43
54
|
* Read and parse a Pages Router API request body for the Workers/prod path.
|
|
44
55
|
*
|
|
@@ -50,6 +61,13 @@ type CreatePagesReqResResult = {
|
|
|
50
61
|
* @see https://nextjs.org/docs/pages/building-your-application/routing/api-routes#custom-config
|
|
51
62
|
*/
|
|
52
63
|
declare function parsePagesApiBody(request: Request, maxBytes?: number): Promise<unknown>;
|
|
64
|
+
declare function getPagesPreviewDataFromCookieHeader(cookieHeader: string | string[] | null | undefined, options?: {
|
|
65
|
+
isOnDemandRevalidate?: boolean;
|
|
66
|
+
}): PagesPreviewData | false;
|
|
67
|
+
declare function getPagesPreviewData(request: Request, options?: {
|
|
68
|
+
isOnDemandRevalidate?: boolean;
|
|
69
|
+
}): PagesPreviewData | false;
|
|
70
|
+
declare function attachPagesRequestCookies(req: PagesRequestCookiesCarrier): void;
|
|
53
71
|
declare function createPagesReqRes(options: CreatePagesReqResOptions): CreatePagesReqResResult;
|
|
54
72
|
//#endregion
|
|
55
|
-
export { PagesBodyParseError as PagesApiBodyParseError, PagesReqResRequest, PagesReqResResponse, PagesRequestQuery, createPagesReqRes, parsePagesApiBody };
|
|
73
|
+
export { PagesBodyParseError as PagesApiBodyParseError, PagesPreviewData, PagesReqResRequest, PagesReqResResponse, PagesRequestQuery, attachPagesRequestCookies, createPagesReqRes, getPagesPreviewData, getPagesPreviewDataFromCookieHeader, parsePagesApiBody };
|