vinext 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -9
- package/dist/build/client-build-config.d.ts +10 -0
- package/dist/build/client-build-config.js +18 -2
- package/dist/build/pages-client-assets-module.d.ts +8 -0
- package/dist/build/pages-client-assets-module.js +21 -1
- package/dist/build/prerender-paths.js +5 -3
- package/dist/build/run-prerender.js +1 -1
- package/dist/build/ssr-manifest.d.ts +2 -0
- package/dist/build/ssr-manifest.js +6 -2
- package/dist/check.js +7 -6
- package/dist/cli.js +2 -1
- package/dist/client/client-redirect-matcher.d.ts +14 -0
- package/dist/client/client-redirect-matcher.js +37 -0
- package/dist/client/client-redirects.d.ts +27 -0
- package/dist/client/client-redirects.js +28 -0
- package/dist/client/client-rewrites.d.ts +2 -1
- package/dist/client/client-rewrites.js +1 -1
- package/dist/config/config-matchers.d.ts +26 -11
- package/dist/config/config-matchers.js +78 -81
- package/dist/config/destination-params.d.ts +47 -0
- package/dist/config/destination-params.js +116 -0
- package/dist/config/next-config.d.ts +7 -0
- package/dist/config/next-config.js +3 -0
- package/dist/entries/app-rsc-entry.d.ts +4 -0
- package/dist/entries/app-rsc-entry.js +20 -6
- package/dist/entries/pages-client-entry.js +3 -1
- package/dist/entries/pages-server-entry.js +13 -37
- package/dist/index.d.ts +3 -1
- package/dist/index.js +134 -43
- package/dist/init-cloudflare.d.ts +9 -0
- package/dist/init-cloudflare.js +107 -31
- package/dist/init-platform.d.ts +4 -0
- package/dist/init-platform.js +27 -2
- package/dist/init.d.ts +1 -0
- package/dist/init.js +67 -3
- package/dist/plugins/ast-scope.d.ts +7 -0
- package/dist/plugins/ast-scope.js +59 -3
- package/dist/plugins/cache-flight-codec.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.d.ts +1 -1
- package/dist/plugins/dynamic-preload-metadata.js +9 -8
- package/dist/plugins/ignore-dynamic-requests.d.ts +1 -1
- package/dist/plugins/ignore-dynamic-requests.js +3 -4
- package/dist/plugins/middleware-server-only.d.ts +5 -4
- package/dist/plugins/middleware-server-only.js +8 -5
- package/dist/plugins/pages-node-externals.js +1 -1
- package/dist/plugins/rsc-scan-glob-imports.d.ts +19 -0
- package/dist/plugins/rsc-scan-glob-imports.js +50 -0
- package/dist/plugins/strip-server-exports.js +262 -98
- package/dist/plugins/transform-result.d.ts +9 -5
- package/dist/plugins/transitive-externals.js +1 -1
- package/dist/plugins/typeof-window.d.ts +2 -2
- package/dist/plugins/use-cache-callable.js +8 -2
- package/dist/plugins/worker-server-only-imports.d.ts +20 -0
- package/dist/plugins/worker-server-only-imports.js +31 -0
- package/dist/plugins/worker-use-server.d.ts +25 -0
- package/dist/plugins/worker-use-server.js +129 -0
- package/dist/server/api-handler.d.ts +1 -0
- package/dist/server/api-handler.js +2 -1
- package/dist/server/app-browser-action-result.d.ts +1 -1
- package/dist/server/app-browser-action-result.js +9 -2
- package/dist/server/app-browser-navigation-controller.js +1 -1
- package/dist/server/app-browser-server-action-client.js +1 -1
- package/dist/server/app-middleware.d.ts +11 -0
- package/dist/server/app-middleware.js +17 -2
- package/dist/server/app-page-cache.d.ts +1 -1
- package/dist/server/app-page-cache.js +1 -1
- package/dist/server/app-page-dispatch.d.ts +3 -1
- package/dist/server/app-page-dispatch.js +4 -3
- package/dist/server/app-page-ppr-runtime.js +1 -1
- package/dist/server/app-page-render-observation.js +1 -1
- package/dist/server/app-page-request.js +53 -15
- package/dist/server/app-page-route-wiring.js +2 -2
- package/dist/server/app-pages-bridge.d.ts +1 -1
- package/dist/server/app-pages-bridge.js +2 -3
- package/dist/server/app-prerender-endpoints.js +9 -6
- package/dist/server/app-request-stage-dispatch.js +6 -2
- package/dist/server/app-request-stage-independent-entry.js +25 -5
- package/dist/server/app-response-stage-entry.js +10 -2
- package/dist/server/app-route-handler-cache.d.ts +1 -0
- package/dist/server/app-route-handler-cache.js +1 -0
- package/dist/server/app-route-handler-dispatch.d.ts +1 -0
- package/dist/server/app-route-handler-dispatch.js +5 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -0
- package/dist/server/app-route-handler-execution.js +1 -0
- package/dist/server/app-route-handler-runtime.d.ts +4 -1
- package/dist/server/app-route-handler-runtime.js +45 -24
- package/dist/server/app-router-entry.js +24 -5
- package/dist/server/app-rsc-cache-busting.js +1 -1
- package/dist/server/app-rsc-errors.js +20 -16
- package/dist/server/app-rsc-handler.d.ts +7 -0
- package/dist/server/app-rsc-handler.js +85 -35
- package/dist/server/app-rsc-response-stage.js +4 -2
- package/dist/server/app-segment-config.d.ts +2 -1
- package/dist/server/app-server-action-execution.d.ts +2 -1
- package/dist/server/app-server-action-execution.js +61 -22
- package/dist/server/app-ssr-entry.js +2 -1
- package/dist/server/app-worker-stages.d.ts +5 -0
- package/dist/server/app-worker-stages.js +1 -1
- package/dist/server/cacheability-request.js +2 -2
- package/dist/server/client-build-files.d.ts +16 -0
- package/dist/server/client-build-files.js +36 -0
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/dev-server.js +38 -27
- package/dist/server/dev-stack-sourcemap.js +18 -23
- package/dist/server/document-initial-head.d.ts +0 -11
- package/dist/server/document-initial-head.js +1 -1
- package/dist/server/forwarded-middleware-context.d.ts +5 -0
- package/dist/server/forwarded-middleware-context.js +22 -0
- package/dist/server/headers.d.ts +4 -1
- package/dist/server/headers.js +4 -1
- package/dist/server/http-conditional.d.ts +11 -0
- package/dist/server/http-conditional.js +10 -1
- package/dist/server/http-error-responses.d.ts +1 -1
- package/dist/server/image-optimization.d.ts +38 -0
- package/dist/server/image-optimization.js +93 -4
- package/dist/server/isr-cache.d.ts +10 -0
- package/dist/server/isr-cache.js +41 -6
- package/dist/server/metadata-route-response.js +9 -8
- package/dist/server/middleware-matcher.d.ts +2 -0
- package/dist/server/middleware-matcher.js +23 -2
- package/dist/server/middleware-runtime.d.ts +13 -0
- package/dist/server/middleware-runtime.js +33 -20
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.js +3 -1
- package/dist/server/multi-stage.d.ts +11 -0
- package/dist/server/normalize-path.d.ts +0 -13
- package/dist/server/normalize-path.js +1 -34
- package/dist/server/pages-api-route.d.ts +3 -2
- package/dist/server/pages-api-route.js +4 -3
- package/dist/server/pages-cache-tag.d.ts +12 -0
- package/dist/server/pages-cache-tag.js +19 -0
- package/dist/server/pages-client-assets.d.ts +2 -0
- package/dist/server/pages-data-route.d.ts +10 -0
- package/dist/server/pages-data-route.js +19 -2
- package/dist/server/pages-document-asset-props.d.ts +5 -1
- package/dist/server/pages-document-asset-props.js +13 -5
- package/dist/server/pages-document-splice.d.ts +19 -0
- package/dist/server/pages-document-splice.js +55 -0
- package/dist/server/pages-i18n.d.ts +12 -1
- package/dist/server/pages-i18n.js +18 -4
- package/dist/server/pages-node-compat.d.ts +16 -5
- package/dist/server/pages-node-compat.js +20 -12
- package/dist/server/pages-page-data.d.ts +32 -24
- package/dist/server/pages-page-data.js +50 -120
- package/dist/server/pages-page-handler.d.ts +0 -6
- package/dist/server/pages-page-handler.js +188 -126
- package/dist/server/pages-page-response.d.ts +12 -6
- package/dist/server/pages-page-response.js +41 -34
- package/dist/server/pages-request-pipeline.d.ts +10 -2
- package/dist/server/pages-request-pipeline.js +37 -18
- package/dist/server/pages-request-stage-entry.d.ts +6 -0
- package/dist/server/pages-request-stage-entry.js +71 -12
- package/dist/server/pages-response-stage-entry.js +4 -0
- package/dist/server/pages-revalidate.js +1 -1
- package/dist/server/pages-router-entry.js +4 -3
- package/dist/server/prerender-manifest.d.ts +3 -3
- package/dist/server/prerender-manifest.js +4 -3
- package/dist/server/prerender-work-unit-setup.js +4 -0
- package/dist/server/prod-server.d.ts +12 -0
- package/dist/server/prod-server.js +199 -69
- package/dist/server/proper-error.d.ts +4 -0
- package/dist/server/proper-error.js +31 -0
- package/dist/server/request-pipeline.d.ts +4 -1
- package/dist/server/request-pipeline.js +3 -2
- package/dist/server/revalidation-request.d.ts +1 -0
- package/dist/server/revalidation-request.js +1 -1
- package/dist/server/rsc-stream-hints.js +31 -2
- package/dist/server/seed-cache.d.ts +1 -0
- package/dist/server/seed-cache.js +5 -4
- package/dist/server/server-reference-loader.d.ts +4 -0
- package/dist/server/server-reference-loader.js +29 -0
- package/dist/server/socket-error-backstop.d.ts +9 -1
- package/dist/server/socket-error-backstop.js +46 -17
- package/dist/server/static-file-signal.d.ts +15 -4
- package/dist/server/static-file-signal.js +46 -12
- package/dist/server/worker-image-optimization.d.ts +34 -0
- package/dist/server/worker-image-optimization.js +86 -0
- package/dist/server/worker-stages.d.ts +1 -1
- package/dist/server/worker-stages.js +2 -2
- package/dist/server/worker-utils.d.ts +8 -3
- package/dist/server/worker-utils.js +12 -7
- package/dist/shims/app-router-scroll.js +4 -1
- package/dist/shims/app-router-tree-context.d.ts +5 -0
- package/dist/shims/app-router-tree-context.js +27 -0
- package/dist/shims/cache-callable-runtime.d.ts +4 -2
- package/dist/shims/cache-callable-runtime.js +21 -12
- package/dist/shims/cache-handler.js +1 -9
- package/dist/shims/cache-runtime.d.ts +6 -1
- package/dist/shims/cache-runtime.js +2 -1
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +40 -13
- package/dist/shims/cdn-cache.d.ts +8 -0
- package/dist/shims/cdn-cache.js +17 -1
- package/dist/shims/disable-smooth-scroll.d.ts +3 -0
- package/dist/shims/disable-smooth-scroll.js +36 -0
- package/dist/shims/document-placeholders.d.ts +19 -0
- package/dist/shims/document-placeholders.js +45 -0
- package/dist/shims/document.js +21 -5
- package/dist/shims/dynamic-preload-chunks.d.ts +1 -0
- package/dist/shims/dynamic-preload-chunks.js +13 -9
- package/dist/shims/dynamic.d.ts +1 -1
- package/dist/shims/dynamic.js +60 -8
- package/dist/shims/fetch-cache-state.d.ts +66 -0
- package/dist/shims/fetch-cache-state.js +92 -0
- package/dist/shims/fetch-cache.d.ts +3 -67
- package/dist/shims/fetch-cache.js +160 -125
- package/dist/shims/head.d.ts +10 -6
- package/dist/shims/head.js +15 -13
- package/dist/shims/image.js +2 -1
- package/dist/shims/internal/work-store-scope.d.ts +5 -0
- package/dist/shims/internal/work-store-scope.js +24 -0
- package/dist/shims/navigation.js +31 -5
- package/dist/shims/request-context.d.ts +2 -0
- package/dist/shims/request-state-types.d.ts +2 -1
- package/dist/shims/router.js +12 -20
- package/dist/shims/server.d.ts +16 -0
- package/dist/shims/server.js +24 -4
- package/dist/shims/unified-request-context.d.ts +1 -1
- package/dist/shims/url-utils.d.ts +2 -0
- package/dist/shims/url-utils.js +3 -1
- package/dist/utils/client-runtime-metadata.js +1 -1
- package/dist/utils/hash.d.ts +7 -0
- package/dist/utils/hash.js +11 -1
- package/dist/utils/package-name.d.ts +6 -0
- package/dist/utils/package-name.js +12 -1
- package/dist/utils/plugin-rsc-version.d.ts +4 -0
- package/dist/utils/plugin-rsc-version.js +15 -0
- package/dist/utils/prerender-output-paths.js +15 -4
- package/dist/utils/public-file-path.d.ts +10 -2
- package/dist/utils/public-file-path.js +13 -9
- package/dist/utils/public-routes.js +2 -2
- package/dist/utils/react-version.d.ts +3 -0
- package/dist/utils/react-version.js +1 -1
- package/package.json +7 -3
|
@@ -2,7 +2,7 @@ import { NextI18nConfig } from "../config/next-config.js";
|
|
|
2
2
|
import { Route } from "../routing/pages-router.js";
|
|
3
3
|
import { ExecutionContextLike } from "../shims/request-context.js";
|
|
4
4
|
import { EdgeApiExecutionRuntime } from "./edge-api-runtime.js";
|
|
5
|
-
import {
|
|
5
|
+
import { PagesApiReqResResponse, PagesReqResRequest, PagesRequestQuery } from "./pages-node-compat.js";
|
|
6
6
|
//#region src/server/pages-api-route.d.ts
|
|
7
7
|
type PagesApiRouteConfig = {
|
|
8
8
|
runtime?: string;
|
|
@@ -36,7 +36,7 @@ type PagesApiRouteConfig = {
|
|
|
36
36
|
externalResolver?: boolean;
|
|
37
37
|
};
|
|
38
38
|
};
|
|
39
|
-
type PagesNodeApiRouteHandler = (req: PagesReqResRequest, res:
|
|
39
|
+
type PagesNodeApiRouteHandler = (req: PagesReqResRequest, res: PagesApiReqResResponse) => unknown;
|
|
40
40
|
type PagesEdgeApiRouteHandler = (request: Request) => Response | Promise<Response>;
|
|
41
41
|
type PagesApiRouteModule = {
|
|
42
42
|
/**
|
|
@@ -80,6 +80,7 @@ type HandlePagesApiRouteOptions = {
|
|
|
80
80
|
allowedRevalidateHeaderKeys?: readonly string[];
|
|
81
81
|
i18n?: NextI18nConfig | null;
|
|
82
82
|
trailingSlash?: boolean;
|
|
83
|
+
skipTrailingSlashRedirect?: boolean;
|
|
83
84
|
};
|
|
84
85
|
trustedRevalidateOrigin?: string;
|
|
85
86
|
};
|
|
@@ -9,7 +9,7 @@ import { mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } f
|
|
|
9
9
|
import { tracePagesApiHandler } from "./pages-execution-tracing.js";
|
|
10
10
|
import { resolveBodyParserConfig } from "./pages-body-parser-config.js";
|
|
11
11
|
import { PagesBodyParseError } from "./pages-media-type.js";
|
|
12
|
-
import {
|
|
12
|
+
import { createPagesApiReqRes, markVinextStreamedApiResponse, parsePagesApiBody } from "./pages-node-compat.js";
|
|
13
13
|
import { finalizeEdgeApiResponse, isEdgeApiRuntime } from "./edge-api-runtime.js";
|
|
14
14
|
//#region src/server/pages-api-route.ts
|
|
15
15
|
function resolveModuleRuntime(module) {
|
|
@@ -47,7 +47,8 @@ async function _handlePagesApiRoute(options) {
|
|
|
47
47
|
const nextRequest = new NextRequest(createEdgeApiRequest(options.request, options.url, params), options.nextConfig ? { nextConfig: {
|
|
48
48
|
basePath: options.nextConfig.basePath,
|
|
49
49
|
i18n: options.nextConfig.i18n ?? void 0,
|
|
50
|
-
trailingSlash: options.nextConfig.trailingSlash
|
|
50
|
+
trailingSlash: options.nextConfig.trailingSlash,
|
|
51
|
+
skipTrailingSlashRedirect: options.nextConfig.skipTrailingSlashRedirect
|
|
51
52
|
} } : void 0);
|
|
52
53
|
const response = await tracePagesApiHandler(route.pattern, () => handler(nextRequest));
|
|
53
54
|
if (response instanceof Response) {
|
|
@@ -70,7 +71,7 @@ async function _handlePagesApiRoute(options) {
|
|
|
70
71
|
const query = buildPagesApiQuery(options.url, params);
|
|
71
72
|
const bodyParserConfig = resolveBodyParserConfig(route.module.config);
|
|
72
73
|
const body = bodyParserConfig.enabled ? await parsePagesApiBody(options.request, bodyParserConfig.sizeLimit) : void 0;
|
|
73
|
-
const { req, res, responsePromise } =
|
|
74
|
+
const { req, res, responsePromise } = createPagesApiReqRes({
|
|
74
75
|
allowedRevalidateHeaderKeys: options.nextConfig?.allowedRevalidateHeaderKeys,
|
|
75
76
|
body,
|
|
76
77
|
initialResponseHeaders: options.initialResponseHeaders,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/server/pages-cache-tag.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Build the edge path tag for a Pages ISR pathname.
|
|
4
|
+
*
|
|
5
|
+
* Every spelling of one pathname shares a single ISR entry, because
|
|
6
|
+
* `pagesIsrCacheKey()` decodes each segment first. The tag must use that same
|
|
7
|
+
* decoded identity. Otherwise `/users/%40alice` is stored at the edge under its
|
|
8
|
+
* own tag, and `res.revalidate("/users/@alice")` or
|
|
9
|
+
* `revalidatePath("/users/@alice")` never purges it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function pagesPathCacheTag(isrPathname: string): string;
|
|
12
|
+
//#endregion
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { normalizePathnameForRouteMatch } from "../routing/utils.js";
|
|
2
|
+
import { encodeCacheTag } from "../utils/encode-cache-tag.js";
|
|
3
|
+
//#region src/server/pages-cache-tag.ts
|
|
4
|
+
/**
|
|
5
|
+
* Build the edge path tag for a Pages ISR pathname.
|
|
6
|
+
*
|
|
7
|
+
* Every spelling of one pathname shares a single ISR entry, because
|
|
8
|
+
* `pagesIsrCacheKey()` decodes each segment first. The tag must use that same
|
|
9
|
+
* decoded identity. Otherwise `/users/%40alice` is stored at the edge under its
|
|
10
|
+
* own tag, and `res.revalidate("/users/@alice")` or
|
|
11
|
+
* `revalidatePath("/users/@alice")` never purges it.
|
|
12
|
+
*/
|
|
13
|
+
function pagesPathCacheTag(isrPathname) {
|
|
14
|
+
const pathname = normalizePathnameForRouteMatch(isrPathname);
|
|
15
|
+
const stem = pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
|
|
16
|
+
return encodeCacheTag(`_N_T_${stem || "/"}`);
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { pagesPathCacheTag };
|
|
@@ -14,6 +14,8 @@ export type PagesClientAssets = {
|
|
|
14
14
|
dynamicPreloads?: Record<string, string[]>;
|
|
15
15
|
/** next.config crossOrigin, defaulting to anonymous for Vite's CORS-fetched assets. */
|
|
16
16
|
crossOrigin?: AssetCrossOrigin;
|
|
17
|
+
/** Client bundle files outside `_next/static`, as URL pathnames. */
|
|
18
|
+
clientBuildFiles?: string[];
|
|
17
19
|
};
|
|
18
20
|
export declare function setPagesClientAssets(assets: PagesClientAssets | undefined): void;
|
|
19
21
|
export declare function getPagesClientAssets(): PagesClientAssets;
|
|
@@ -61,6 +61,16 @@ export declare function encodeUrlParserIgnoredCharacters(pathname: string): stri
|
|
|
61
61
|
* `/_next/data/<buildId>/about` → null (missing .json suffix)
|
|
62
62
|
*/
|
|
63
63
|
export declare function parseNextDataPathname(pathname: string, buildId: string): NextDataMatch | null;
|
|
64
|
+
/**
|
|
65
|
+
* The page pathname a `_next/data` URL addresses, whatever its buildId. Next.js
|
|
66
|
+
* compiles every middleware matcher with an optional `/_next/data/<buildId>`
|
|
67
|
+
* prefix and `.json` suffix, so a matcher written for `/admin` also guards that
|
|
68
|
+
* page's data URL, even one with a stale buildId. Middleware matching uses this
|
|
69
|
+
* when the request reaches middleware with its raw data URL
|
|
70
|
+
* (`skipProxyUrlNormalize`).
|
|
71
|
+
* https://github.com/vercel/next.js/blob/v16.2.7/packages/next/src/build/analysis/get-page-static-info.ts
|
|
72
|
+
*/
|
|
73
|
+
export declare function nextDataMiddlewareMatchPathname(pathname: string): string | null;
|
|
64
74
|
export declare function normalizeNextDataPagePathname(pagePathname: string, trailingSlash?: boolean): string;
|
|
65
75
|
/**
|
|
66
76
|
* Next.js only applies `trailingSlash` while normalizing a data URL for
|
|
@@ -67,7 +67,24 @@ function parseNextDataPathname(pathname, buildId) {
|
|
|
67
67
|
if (!isNextDataPathname(pathname)) return null;
|
|
68
68
|
const expectedPrefix = `${NEXT_DATA_PREFIX}${buildId}/`;
|
|
69
69
|
if (!pathname.startsWith(expectedPrefix)) return null;
|
|
70
|
-
|
|
70
|
+
return pageFromNextDataRest(pathname.slice(expectedPrefix.length, -5));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* The page pathname a `_next/data` URL addresses, whatever its buildId. Next.js
|
|
74
|
+
* compiles every middleware matcher with an optional `/_next/data/<buildId>`
|
|
75
|
+
* prefix and `.json` suffix, so a matcher written for `/admin` also guards that
|
|
76
|
+
* page's data URL, even one with a stale buildId. Middleware matching uses this
|
|
77
|
+
* when the request reaches middleware with its raw data URL
|
|
78
|
+
* (`skipProxyUrlNormalize`).
|
|
79
|
+
* https://github.com/vercel/next.js/blob/v16.2.7/packages/next/src/build/analysis/get-page-static-info.ts
|
|
80
|
+
*/
|
|
81
|
+
function nextDataMiddlewareMatchPathname(pathname) {
|
|
82
|
+
if (!isNextDataPathname(pathname)) return null;
|
|
83
|
+
const buildIdEnd = pathname.indexOf("/", 12);
|
|
84
|
+
if (buildIdEnd <= 12) return null;
|
|
85
|
+
return pageFromNextDataRest(pathname.slice(buildIdEnd + 1, -5))?.pagePathname ?? null;
|
|
86
|
+
}
|
|
87
|
+
function pageFromNextDataRest(rest) {
|
|
71
88
|
if (rest.length === 0) return null;
|
|
72
89
|
if (rest === "index") return { pagePathname: "/" };
|
|
73
90
|
if (rest.endsWith("/index")) return { pagePathname: `/${rest.slice(0, -6)}` };
|
|
@@ -181,4 +198,4 @@ function normalizePagesDataRequest(request, buildId, basePath = "", trailingSlas
|
|
|
181
198
|
};
|
|
182
199
|
}
|
|
183
200
|
//#endregion
|
|
184
|
-
export { buildMiddlewarePrefetchSkipResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath };
|
|
201
|
+
export { buildMiddlewarePrefetchSkipResponse, buildNextDataNotFoundResponse, buildNextDataPropsJsonResponse, encodeUrlParserIgnoredCharacters, isNextDataPathname, nextDataMiddlewareMatchPathname, normalizeNextDataPagePathname, normalizePagesDataRequest, parseNextDataPathname, shouldAddTrailingSlashToPagesDataPath, urlParserCreatesPagesDataPath };
|
|
@@ -10,7 +10,11 @@ type ApplyDocumentAssetPropsOptions = {
|
|
|
10
10
|
protectedAssetMarker?: string;
|
|
11
11
|
scriptOwner?: "head" | "next-script";
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Read and strip the nonce and crossOrigin props that `<Head>` and
|
|
15
|
+
* `<NextScript />` recorded on their tags, found by this render's token.
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractDocumentAssetProps(html: string, token: string): {
|
|
14
18
|
html: string;
|
|
15
19
|
props: DocumentAssetProps;
|
|
16
20
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { escapeRegExp } from "../utils/regex.js";
|
|
1
2
|
import { escapeHtmlAttr } from "./html.js";
|
|
3
|
+
import { getDocumentHeadOpenMarker, getDocumentScriptsPlaceholder } from "../shims/document-placeholders.js";
|
|
2
4
|
//#region src/server/pages-document-asset-props.ts
|
|
3
5
|
const HEAD_NONCE_ATTR = "data-vinext-head-nonce";
|
|
4
6
|
const HEAD_CROSS_ORIGIN_ATTR = "data-vinext-head-cross-origin";
|
|
@@ -11,9 +13,15 @@ function readAttribute(tag, name) {
|
|
|
11
13
|
function removeAttributes(tag, names) {
|
|
12
14
|
return tag.replace(new RegExp(`\\s(?:${names.join("|")})="[^"]*"`, "g"), "");
|
|
13
15
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Read and strip the nonce and crossOrigin props that `<Head>` and
|
|
18
|
+
* `<NextScript />` recorded on their tags, found by this render's token.
|
|
19
|
+
*/
|
|
20
|
+
function extractDocumentAssetProps(html, token) {
|
|
21
|
+
const headTagPattern = new RegExp(`<head\\b[^>]*${escapeRegExp(getDocumentHeadOpenMarker(token))}[^>]*>`, "i");
|
|
22
|
+
const nextScriptTagPattern = new RegExp(`<span\\b[^>]*>(?=${escapeRegExp(getDocumentScriptsPlaceholder(token))})`, "i");
|
|
23
|
+
const headTag = html.match(headTagPattern)?.[0];
|
|
24
|
+
const nextScriptTag = html.match(nextScriptTagPattern)?.[0];
|
|
17
25
|
const props = {
|
|
18
26
|
headNonce: readAttribute(headTag, HEAD_NONCE_ATTR),
|
|
19
27
|
headCrossOrigin: readAttribute(headTag, HEAD_CROSS_ORIGIN_ATTR),
|
|
@@ -21,14 +29,14 @@ function extractDocumentAssetProps(html) {
|
|
|
21
29
|
scriptCrossOrigin: readAttribute(nextScriptTag, SCRIPT_CROSS_ORIGIN_ATTR)
|
|
22
30
|
};
|
|
23
31
|
return {
|
|
24
|
-
html: html.replace(
|
|
32
|
+
html: html.replace(headTagPattern, (tag) => removeAttributes(tag, [HEAD_NONCE_ATTR, HEAD_CROSS_ORIGIN_ATTR])).replace(nextScriptTagPattern, (tag) => removeAttributes(tag, [SCRIPT_NONCE_ATTR, SCRIPT_CROSS_ORIGIN_ATTR])),
|
|
25
33
|
props
|
|
26
34
|
};
|
|
27
35
|
}
|
|
28
36
|
function addAttribute(tag, name, value, replaceExisting = false) {
|
|
29
37
|
if (value === void 0) return tag;
|
|
30
38
|
const attributePattern = new RegExp(`\\s${name}(?:="[^"]*")?`, "i");
|
|
31
|
-
if (attributePattern.test(tag)) return replaceExisting ? tag.replace(attributePattern, ` ${name}="${escapeHtmlAttr(value)}"`) : tag;
|
|
39
|
+
if (attributePattern.test(tag)) return replaceExisting ? tag.replace(attributePattern, () => ` ${name}="${escapeHtmlAttr(value)}"`) : tag;
|
|
32
40
|
if (!tag.endsWith(">")) return tag;
|
|
33
41
|
const selfClosing = tag.endsWith("/>");
|
|
34
42
|
const closingStart = selfClosing ? tag.length - 2 : tag.length - 1;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/server/pages-document-splice.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Drop `<Head>`'s marker attribute and insert `insertion` right after its
|
|
4
|
+
* opening tag. Dev HTML transforms may add attributes after the marker.
|
|
5
|
+
*/
|
|
6
|
+
export declare function spliceDocumentHeadOpen(html: string, token: string, insertion: string): string;
|
|
7
|
+
/** Insert `insertion` right before `<Head>`'s closing tag. */
|
|
8
|
+
export declare function spliceDocumentHeadClose(html: string, token: string, insertion: string): string;
|
|
9
|
+
/** Put the generated hydration scripts where `<NextScript />` rendered. */
|
|
10
|
+
export declare function spliceDocumentScripts(html: string, token: string, scripts: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* Split the Document where `<Main />` rendered. Like Next.js, a Document
|
|
13
|
+
* without `<Main />` gets the page body after its own markup.
|
|
14
|
+
*/
|
|
15
|
+
export declare function splitDocumentAtMain(html: string, token: string): {
|
|
16
|
+
prefix: string;
|
|
17
|
+
suffix: string;
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getDocumentHeadCloseMarker, getDocumentHeadOpenMarker, getDocumentMainPlaceholder, getDocumentScriptsPlaceholder } from "../shims/document-placeholders.js";
|
|
2
|
+
//#region src/server/pages-document-splice.ts
|
|
3
|
+
/**
|
|
4
|
+
* Splices framework output into a serialized custom Pages Router Document.
|
|
5
|
+
*
|
|
6
|
+
* `<Head>`, `<Main />` and `<NextScript />` mark their splice points with the
|
|
7
|
+
* per-render token from `vinext/shims/document-placeholders`, so nothing the
|
|
8
|
+
* Document renders can be taken for one. Each edit slices at a located index
|
|
9
|
+
* instead of calling `String#replace`, so inserted HTML is never parsed for
|
|
10
|
+
* `$&`-style replacement patterns. Like Next.js, a Document that leaves out
|
|
11
|
+
* one of those components gets nothing inserted for it.
|
|
12
|
+
*/
|
|
13
|
+
function spliceMarker(html, marker, insertion) {
|
|
14
|
+
const index = html.indexOf(marker);
|
|
15
|
+
if (index === -1) return html;
|
|
16
|
+
return html.slice(0, index) + insertion + html.slice(index + marker.length);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Drop `<Head>`'s marker attribute and insert `insertion` right after its
|
|
20
|
+
* opening tag. Dev HTML transforms may add attributes after the marker.
|
|
21
|
+
*/
|
|
22
|
+
function spliceDocumentHeadOpen(html, token, insertion) {
|
|
23
|
+
const marker = getDocumentHeadOpenMarker(token);
|
|
24
|
+
const index = html.indexOf(marker);
|
|
25
|
+
if (index === -1) return html;
|
|
26
|
+
const tagEnd = html.indexOf(">", index + marker.length) + 1;
|
|
27
|
+
if (tagEnd === 0) return html;
|
|
28
|
+
return html.slice(0, index) + html.slice(index + marker.length, tagEnd) + insertion + html.slice(tagEnd);
|
|
29
|
+
}
|
|
30
|
+
/** Insert `insertion` right before `<Head>`'s closing tag. */
|
|
31
|
+
function spliceDocumentHeadClose(html, token, insertion) {
|
|
32
|
+
return spliceMarker(html, getDocumentHeadCloseMarker(token), insertion);
|
|
33
|
+
}
|
|
34
|
+
/** Put the generated hydration scripts where `<NextScript />` rendered. */
|
|
35
|
+
function spliceDocumentScripts(html, token, scripts) {
|
|
36
|
+
return spliceMarker(html, getDocumentScriptsPlaceholder(token), scripts);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Split the Document where `<Main />` rendered. Like Next.js, a Document
|
|
40
|
+
* without `<Main />` gets the page body after its own markup.
|
|
41
|
+
*/
|
|
42
|
+
function splitDocumentAtMain(html, token) {
|
|
43
|
+
const placeholder = getDocumentMainPlaceholder(token);
|
|
44
|
+
const index = html.indexOf(placeholder);
|
|
45
|
+
if (index === -1) return {
|
|
46
|
+
prefix: html,
|
|
47
|
+
suffix: ""
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
prefix: html.slice(0, index),
|
|
51
|
+
suffix: html.slice(index + placeholder.length)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//#endregion
|
|
55
|
+
export { spliceDocumentHeadClose, spliceDocumentHeadOpen, spliceDocumentScripts, splitDocumentAtMain };
|
|
@@ -24,6 +24,15 @@ type PagesI18nRequestInfo = {
|
|
|
24
24
|
domainLocale?: DomainLocale;
|
|
25
25
|
redirectUrl?: string;
|
|
26
26
|
};
|
|
27
|
+
/**
|
|
28
|
+
* Return the configured locale that the first pathname segment names, compared
|
|
29
|
+
* case-insensitively (`/EN/about` -> `"en"`), or `undefined` when there is none.
|
|
30
|
+
* The configured casing is returned, not the request's.
|
|
31
|
+
*
|
|
32
|
+
* Ported from Next.js: packages/next/src/shared/lib/i18n/normalize-locale-path.ts
|
|
33
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/i18n/normalize-locale-path.ts
|
|
34
|
+
*/
|
|
35
|
+
export declare function detectPathnameLocale(pathname: string, locales: readonly string[]): string | undefined;
|
|
27
36
|
/**
|
|
28
37
|
* Prepend the default locale prefix to a pathname when i18n is configured and
|
|
29
38
|
* the path does not already carry a locale prefix. Mirrors Next.js's
|
|
@@ -42,7 +51,9 @@ type PagesI18nRequestInfo = {
|
|
|
42
51
|
* - `/__vinext/*` (vinext-internal endpoints)
|
|
43
52
|
*
|
|
44
53
|
* Returns the input unchanged when i18n is not configured or when the path
|
|
45
|
-
* already starts with one of the configured locales
|
|
54
|
+
* already starts with one of the configured locales (compared
|
|
55
|
+
* case-insensitively, like Next.js's `normalizeLocalePath`, so `/EN/about`
|
|
56
|
+
* is left alone rather than becoming `/en/EN/about`). The host-based default
|
|
46
57
|
* locale (i18n.domains[].defaultLocale) is preferred over the global default
|
|
47
58
|
* when supplied, matching Next.js's `domainLocale.defaultLocale` branch.
|
|
48
59
|
*
|
|
@@ -9,6 +9,19 @@ function readHeader(headers, name) {
|
|
|
9
9
|
}
|
|
10
10
|
const normalizeHostname = normalizeDomainHostname;
|
|
11
11
|
/**
|
|
12
|
+
* Return the configured locale that the first pathname segment names, compared
|
|
13
|
+
* case-insensitively (`/EN/about` -> `"en"`), or `undefined` when there is none.
|
|
14
|
+
* The configured casing is returned, not the request's.
|
|
15
|
+
*
|
|
16
|
+
* Ported from Next.js: packages/next/src/shared/lib/i18n/normalize-locale-path.ts
|
|
17
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/shared/lib/i18n/normalize-locale-path.ts
|
|
18
|
+
*/
|
|
19
|
+
function detectPathnameLocale(pathname, locales) {
|
|
20
|
+
const segment = pathname.split("/", 2)[1]?.toLowerCase();
|
|
21
|
+
if (!segment) return void 0;
|
|
22
|
+
return locales.find((locale) => locale.toLowerCase() === segment);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
12
25
|
* Prepend the default locale prefix to a pathname when i18n is configured and
|
|
13
26
|
* the path does not already carry a locale prefix. Mirrors Next.js's
|
|
14
27
|
* server-side path normalisation in `resolve-routes.ts` (lines ~250-263):
|
|
@@ -26,7 +39,9 @@ const normalizeHostname = normalizeDomainHostname;
|
|
|
26
39
|
* - `/__vinext/*` (vinext-internal endpoints)
|
|
27
40
|
*
|
|
28
41
|
* Returns the input unchanged when i18n is not configured or when the path
|
|
29
|
-
* already starts with one of the configured locales
|
|
42
|
+
* already starts with one of the configured locales (compared
|
|
43
|
+
* case-insensitively, like Next.js's `normalizeLocalePath`, so `/EN/about`
|
|
44
|
+
* is left alone rather than becoming `/en/EN/about`). The host-based default
|
|
30
45
|
* locale (i18n.domains[].defaultLocale) is preferred over the global default
|
|
31
46
|
* when supplied, matching Next.js's `domainLocale.defaultLocale` branch.
|
|
32
47
|
*
|
|
@@ -42,8 +57,7 @@ const normalizeHostname = normalizeDomainHostname;
|
|
|
42
57
|
function normalizeDefaultLocalePathname(pathname, i18n, options = {}) {
|
|
43
58
|
if (!i18n) return pathname;
|
|
44
59
|
if (pathname.startsWith("/_next/") || pathname.startsWith("/__vinext/")) return pathname;
|
|
45
|
-
|
|
46
|
-
if (parts[1] && i18n.locales.includes(parts[1])) return pathname;
|
|
60
|
+
if (detectPathnameLocale(pathname, i18n.locales)) return pathname;
|
|
47
61
|
const defaultLocale = detectDomainLocale(i18n.domains, options.hostname ?? void 0)?.defaultLocale ?? i18n.defaultLocale;
|
|
48
62
|
if (pathname === "/") return `/${defaultLocale}`;
|
|
49
63
|
return `/${defaultLocale}${pathname}`;
|
|
@@ -229,4 +243,4 @@ function resolvePagesI18nRequest(url, i18nConfig, headers, hostname, basePath =
|
|
|
229
243
|
};
|
|
230
244
|
}
|
|
231
245
|
//#endregion
|
|
232
|
-
export { detectDomainLocale, detectLocaleFromAcceptLanguage, extractLocaleFromUrl, getLocaleRedirect, normalizeDefaultLocalePathname, parseCookieLocaleFromHeader, resolvePagesI18nRequest, stripI18nLocaleForApiRoute };
|
|
246
|
+
export { detectDomainLocale, detectLocaleFromAcceptLanguage, detectPathnameLocale, extractLocaleFromUrl, getLocaleRedirect, normalizeDefaultLocalePathname, parseCookieLocaleFromHeader, resolvePagesI18nRequest, stripI18nLocaleForApiRoute };
|
|
@@ -29,7 +29,6 @@ export type PagesReqResResponse = Writable & {
|
|
|
29
29
|
send: (data: unknown) => void;
|
|
30
30
|
redirect: (statusOrUrl: number | string, url?: string) => PagesReqResResponse;
|
|
31
31
|
getHeaders: () => PagesReqResHeaders;
|
|
32
|
-
revalidate: (urlPath: string, opts?: RevalidateOptions) => Promise<void>;
|
|
33
32
|
setPreviewData: (data: object | string, options?: {
|
|
34
33
|
maxAge?: number;
|
|
35
34
|
path?: string;
|
|
@@ -41,6 +40,9 @@ export type PagesReqResResponse = Writable & {
|
|
|
41
40
|
enable?: boolean;
|
|
42
41
|
}) => PagesReqResResponse;
|
|
43
42
|
};
|
|
43
|
+
export type PagesApiReqResResponse = PagesReqResResponse & {
|
|
44
|
+
revalidate: (urlPath: string, opts?: RevalidateOptions) => Promise<void>;
|
|
45
|
+
};
|
|
44
46
|
type PagesRequestCookiesCarrier = {
|
|
45
47
|
headers: {
|
|
46
48
|
cookie?: string | string[] | null | undefined;
|
|
@@ -48,17 +50,19 @@ type PagesRequestCookiesCarrier = {
|
|
|
48
50
|
cookies?: unknown;
|
|
49
51
|
};
|
|
50
52
|
type CreatePagesReqResOptions = {
|
|
51
|
-
allowedRevalidateHeaderKeys?: readonly string[];
|
|
52
53
|
body: unknown;
|
|
53
54
|
initialResponseHeaders?: Headers;
|
|
54
55
|
query: PagesRequestQuery;
|
|
55
56
|
request: Request;
|
|
56
|
-
trustedRevalidateOrigin?: string;
|
|
57
57
|
url: string;
|
|
58
58
|
};
|
|
59
|
-
type
|
|
59
|
+
type CreatePagesApiReqResOptions = CreatePagesReqResOptions & {
|
|
60
|
+
allowedRevalidateHeaderKeys?: readonly string[];
|
|
61
|
+
trustedRevalidateOrigin?: string;
|
|
62
|
+
};
|
|
63
|
+
type CreatePagesReqResResult<Res extends PagesReqResResponse = PagesReqResResponse> = {
|
|
60
64
|
req: PagesReqResRequest;
|
|
61
|
-
res:
|
|
65
|
+
res: Res;
|
|
62
66
|
responsePromise: Promise<Response>;
|
|
63
67
|
};
|
|
64
68
|
/**
|
|
@@ -85,5 +89,12 @@ export declare function attachPagesPreviewApi(req: PagesReqResRequest, res: Page
|
|
|
85
89
|
export declare function markVinextStreamedApiResponse(response: Response): void;
|
|
86
90
|
export declare function isVinextStreamedApiResponse(response: Response): boolean;
|
|
87
91
|
export declare function createPagesReqRes(options: CreatePagesReqResOptions): CreatePagesReqResResult;
|
|
92
|
+
/**
|
|
93
|
+
* Create the req/res pair for a Pages API route. Only API responses get
|
|
94
|
+
* `res.revalidate()`: Next.js attaches it in apiResolver
|
|
95
|
+
* (`packages/next/src/server/api-utils/node/api-resolver.ts`), so a page's
|
|
96
|
+
* getServerSideProps `res` never carries the revalidation secret.
|
|
97
|
+
*/
|
|
98
|
+
export declare function createPagesApiReqRes(options: CreatePagesApiReqResOptions): CreatePagesReqResResult<PagesApiReqResResponse>;
|
|
88
99
|
//#endregion
|
|
89
100
|
export { PagesBodyParseError as PagesApiBodyParseError };
|
|
@@ -119,9 +119,6 @@ function attachPagesPreviewApi(req, res) {
|
|
|
119
119
|
var PagesResponseStream = class extends Writable {
|
|
120
120
|
resolveResponse;
|
|
121
121
|
rejectResponse;
|
|
122
|
-
requestHeaders;
|
|
123
|
-
trustedRevalidateOrigin;
|
|
124
|
-
allowedRevalidateHeaderKeys;
|
|
125
122
|
resStatusCode = 200;
|
|
126
123
|
resHeaders = {};
|
|
127
124
|
setCookieHeaders = [];
|
|
@@ -131,13 +128,10 @@ var PagesResponseStream = class extends Writable {
|
|
|
131
128
|
streamEnded = false;
|
|
132
129
|
pendingWrite = null;
|
|
133
130
|
discardBody = false;
|
|
134
|
-
constructor(resolveResponse, rejectResponse
|
|
131
|
+
constructor(resolveResponse, rejectResponse) {
|
|
135
132
|
super();
|
|
136
133
|
this.resolveResponse = resolveResponse;
|
|
137
134
|
this.rejectResponse = rejectResponse;
|
|
138
|
-
this.requestHeaders = requestHeaders;
|
|
139
|
-
this.trustedRevalidateOrigin = trustedRevalidateOrigin;
|
|
140
|
-
this.allowedRevalidateHeaderKeys = allowedRevalidateHeaderKeys;
|
|
141
135
|
this.once("error", (err) => {
|
|
142
136
|
if (!this.resolved) {
|
|
143
137
|
this.resolved = true;
|
|
@@ -206,9 +200,6 @@ var PagesResponseStream = class extends Writable {
|
|
|
206
200
|
if (this.setCookieHeaders.length > 0) headers["set-cookie"] = this.setCookieHeaders;
|
|
207
201
|
return headers;
|
|
208
202
|
}
|
|
209
|
-
async revalidate(urlPath, opts) {
|
|
210
|
-
await performOnDemandRevalidate(this.requestHeaders, urlPath, opts, this.trustedRevalidateOrigin, this.allowedRevalidateHeaderKeys);
|
|
211
|
-
}
|
|
212
203
|
setPreviewData(data, options = {}) {
|
|
213
204
|
setPagesPreviewData(this, data, options);
|
|
214
205
|
return this;
|
|
@@ -346,7 +337,7 @@ function createPagesReqRes(options) {
|
|
|
346
337
|
resolveResponse = resolve;
|
|
347
338
|
rejectResponse = reject;
|
|
348
339
|
});
|
|
349
|
-
const res = new PagesResponseStream(resolveResponse, rejectResponse
|
|
340
|
+
const res = new PagesResponseStream(resolveResponse, rejectResponse);
|
|
350
341
|
for (const [name, value] of options.initialResponseHeaders ?? []) {
|
|
351
342
|
if (name.toLowerCase() === "set-cookie") continue;
|
|
352
343
|
res.setHeader(name, value);
|
|
@@ -360,5 +351,22 @@ function createPagesReqRes(options) {
|
|
|
360
351
|
responsePromise
|
|
361
352
|
};
|
|
362
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Create the req/res pair for a Pages API route. Only API responses get
|
|
356
|
+
* `res.revalidate()`: Next.js attaches it in apiResolver
|
|
357
|
+
* (`packages/next/src/server/api-utils/node/api-resolver.ts`), so a page's
|
|
358
|
+
* getServerSideProps `res` never carries the revalidation secret.
|
|
359
|
+
*/
|
|
360
|
+
function createPagesApiReqRes(options) {
|
|
361
|
+
const { req, res, responsePromise } = createPagesReqRes(options);
|
|
362
|
+
const trustedRevalidateOrigin = options.trustedRevalidateOrigin ?? new URL(options.request.url).origin;
|
|
363
|
+
return {
|
|
364
|
+
req,
|
|
365
|
+
res: Object.assign(res, { async revalidate(urlPath, opts) {
|
|
366
|
+
await performOnDemandRevalidate(options.request.headers, urlPath, opts, trustedRevalidateOrigin, options.allowedRevalidateHeaderKeys);
|
|
367
|
+
} }),
|
|
368
|
+
responsePromise
|
|
369
|
+
};
|
|
370
|
+
}
|
|
363
371
|
//#endregion
|
|
364
|
-
export { PagesBodyParseError as PagesApiBodyParseError, attachPagesPreviewApi, attachPagesRequestCookies, createPagesReqRes, isVinextStreamedApiResponse, markVinextStreamedApiResponse, parsePagesApiBody };
|
|
372
|
+
export { PagesBodyParseError as PagesApiBodyParseError, attachPagesPreviewApi, attachPagesRequestCookies, createPagesApiReqRes, createPagesReqRes, isVinextStreamedApiResponse, markVinextStreamedApiResponse, parsePagesApiBody };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Route } from "../routing/pages-router.js";
|
|
2
|
-
import { VinextNextData } from "../client/vinext-next-data.js";
|
|
3
2
|
import { CachedPagesValue, CachedRedirectValue } from "../shims/cache-handler.js";
|
|
4
3
|
import { ISRCacheEntry, IsrWritePolicy } from "./isr-cache.js";
|
|
5
4
|
import { PagesPreviewData } from "./pages-preview.js";
|
|
@@ -43,6 +42,14 @@ export declare function assertPages404DoesNotReturnNotFound(routePattern: string
|
|
|
43
42
|
* - packages/next/src/server/render.tsx (`metadata.cacheControl`)
|
|
44
43
|
* - packages/next/src/server/route-modules/pages/pages-handler.ts
|
|
45
44
|
*/
|
|
45
|
+
/**
|
|
46
|
+
* Next.js renders a shared getStaticProps status page (/404, /500) for its own
|
|
47
|
+
* pathname, never for the request that reached it. Only the original
|
|
48
|
+
* request's trailing slash carries over under `trailingSlash`, read before
|
|
49
|
+
* rewrites and locale stripping.
|
|
50
|
+
* https://github.com/vercel/next.js/blob/canary/packages/next/src/server/route-modules/pages/pages-handler.ts
|
|
51
|
+
*/
|
|
52
|
+
export declare function resolvePagesStatusPageRenderPath(statusPathname: string, trailingSlash: boolean, requestPathname: string): string;
|
|
46
53
|
export declare function resolvePagesRevalidateSeconds(result: PagesPagePropsResult, routeUrl?: string): number | false;
|
|
47
54
|
type PagesMutableGsspResponse = {
|
|
48
55
|
headersSent: boolean;
|
|
@@ -115,25 +122,9 @@ export type PagesPageModule = {
|
|
|
115
122
|
revalidateReason?: "build" | "on-demand" | "stale";
|
|
116
123
|
}) => Promise<PagesPagePropsResult> | PagesPagePropsResult;
|
|
117
124
|
};
|
|
118
|
-
type RenderPagesIsrHtmlOptions = {
|
|
119
|
-
buildId: string | null;
|
|
120
|
-
cachedHtml: string;
|
|
121
|
-
collectIsrHeadHTML?: (() => string) | undefined;
|
|
122
|
-
createPageElement: (props: Record<string, unknown>) => ReactNode;
|
|
123
|
-
i18n: PagesI18nRenderContext;
|
|
124
|
-
pageProps: Record<string, unknown>;
|
|
125
|
-
props?: Record<string, unknown>;
|
|
126
|
-
params: Record<string, unknown>;
|
|
127
|
-
renderIsrPassToStringAsync: (element: ReactNode, onHeadReady?: () => Promise<void>) => Promise<string>;
|
|
128
|
-
routePattern: string;
|
|
129
|
-
safeJsonStringify: (value: unknown) => string;
|
|
130
|
-
vinext?: VinextNextData["__vinext"];
|
|
131
|
-
nextData?: PagesNextDataExtras;
|
|
132
|
-
};
|
|
133
125
|
export type ResolvePagesPageDataOptions = {
|
|
134
126
|
applyRequestContexts: () => void;
|
|
135
127
|
basePath?: string;
|
|
136
|
-
buildId: string | null;
|
|
137
128
|
/**
|
|
138
129
|
* When true, this is a `/_next/data/<buildId>/<page>.json` request. Callers
|
|
139
130
|
* that respond with a JSON envelope (`{ pageProps }`) instead of HTML must
|
|
@@ -145,6 +136,8 @@ export type ResolvePagesPageDataOptions = {
|
|
|
145
136
|
isDataReq?: boolean;
|
|
146
137
|
err?: unknown;
|
|
147
138
|
createGsspReqRes: () => PagesGsspContextResponse;
|
|
139
|
+
/** The req/res for a stale regeneration's render; defaults to `createGsspReqRes`. */
|
|
140
|
+
createRegenerationReqRes?: () => PagesGsspContextResponse;
|
|
148
141
|
createAppTree?: (props: Record<string, unknown>) => ReactNode;
|
|
149
142
|
createPageElement: (props: Record<string, unknown>) => ReactNode;
|
|
150
143
|
fontLinkHeader: string;
|
|
@@ -188,6 +181,12 @@ export type ResolvePagesPageDataOptions = {
|
|
|
188
181
|
* fallback path. Mirrors Next.js `unstable_onlyGenerated`.
|
|
189
182
|
*/
|
|
190
183
|
revalidateOnlyGenerated?: boolean;
|
|
184
|
+
/**
|
|
185
|
+
* Set when a cache adapter regenerates an entry it stores for this build.
|
|
186
|
+
* The stored entry proves the path was admitted, so `getStaticPaths()` is
|
|
187
|
+
* skipped as it is for an entry read through `isrGet`.
|
|
188
|
+
*/
|
|
189
|
+
regeneratesStoredEntry?: boolean;
|
|
191
190
|
previewData?: PagesPreviewData | false;
|
|
192
191
|
/**
|
|
193
192
|
* The deployment ID used for deployment-skew protection. When set, it is
|
|
@@ -226,14 +225,19 @@ export type ResolvePagesPageDataOptions = {
|
|
|
226
225
|
routePath: string;
|
|
227
226
|
routeType: "render";
|
|
228
227
|
}) => void;
|
|
229
|
-
renderIsrPassToStringAsync: (element: ReactNode, onHeadReady?: () => Promise<void>) => Promise<string>;
|
|
230
228
|
/**
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
*
|
|
229
|
+
* Render the whole document for regenerated props and store it as the ISR
|
|
230
|
+
* entry, through the same pipeline (and with the same cache write) as a
|
|
231
|
+
* foreground MISS. Next.js re-runs its full render on regeneration too;
|
|
232
|
+
* resolves once the entry is written.
|
|
234
233
|
*/
|
|
235
|
-
|
|
236
|
-
|
|
234
|
+
renderIsrDocument: (input: {
|
|
235
|
+
documentReqRes: PagesGsspContextResponse;
|
|
236
|
+
expireSeconds: number | undefined;
|
|
237
|
+
pageProps: Record<string, unknown>;
|
|
238
|
+
props: Record<string, unknown>;
|
|
239
|
+
revalidateSeconds: number | false;
|
|
240
|
+
}) => Promise<void>;
|
|
237
241
|
nextData?: PagesNextDataExtras;
|
|
238
242
|
/**
|
|
239
243
|
* The request's User-Agent string. When this matches a known crawler/bot
|
|
@@ -250,6 +254,11 @@ export type ResolvePagesPageDataOptions = {
|
|
|
250
254
|
* response is a `304 Not Modified` with no body.
|
|
251
255
|
*/
|
|
252
256
|
ifNoneMatch?: string;
|
|
257
|
+
/**
|
|
258
|
+
* The incoming request's `If-Modified-Since` header value. As in Next.js,
|
|
259
|
+
* which gives a page no Last-Modified, a request with it gets the page.
|
|
260
|
+
*/
|
|
261
|
+
ifModifiedSince?: string;
|
|
253
262
|
/**
|
|
254
263
|
* The incoming request's `Cache-Control` header value. When it contains
|
|
255
264
|
* `no-cache`, the 304 short-circuit is skipped and a full response is
|
|
@@ -320,6 +329,5 @@ export type PagesRouteParam = {
|
|
|
320
329
|
};
|
|
321
330
|
export declare function getPagesRouteParams(routePattern: string): PagesRouteParam[];
|
|
322
331
|
export declare function matchesPagesStaticPath(pathEntry: PagesStaticPathsEntry, params: Record<string, unknown>, routeParams: PagesRouteParam[], routeUrl: string, i18n?: Pick<PagesI18nRenderContext, "locale" | "locales" | "defaultLocale">): boolean;
|
|
323
|
-
export declare function renderPagesIsrHtml(options: RenderPagesIsrHtmlOptions): Promise<string>;
|
|
324
332
|
export declare function resolvePagesPageData(options: ResolvePagesPageDataOptions): Promise<ResolvePagesPageDataResult>;
|
|
325
333
|
//#endregion
|