vinext 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/build/css-url-assets.d.ts +1 -1
- package/dist/build/css-url-assets.js +9 -7
- package/dist/build/google-fonts/find-font-files-in-css.d.ts +16 -0
- package/dist/build/google-fonts/find-font-files-in-css.js +28 -0
- package/dist/build/prerender.js +2 -1
- package/dist/build/report.d.ts +1 -2
- package/dist/build/report.js +2 -11
- package/dist/build/run-prerender.js +1 -1
- package/dist/cache/cache-adapters-virtual.js +1 -1
- package/dist/check.js +3 -3
- package/dist/client/pages-router-link-navigation.d.ts +10 -0
- package/dist/client/pages-router-link-navigation.js +3 -3
- package/dist/cloudflare/src/cache/kv-data-adapter.runtime.d.ts +1 -1
- package/dist/deploy.js +3 -3
- package/dist/entries/app-rsc-entry.js +25 -20
- package/dist/entries/app-rsc-manifest.js +76 -46
- package/dist/entries/pages-server-entry.js +3 -1
- package/dist/index.js +254 -198
- package/dist/init.d.ts +5 -4
- package/dist/init.js +27 -8
- package/dist/plugins/css-data-url.js +30 -26
- package/dist/plugins/extensionless-dynamic-import.js +27 -24
- package/dist/plugins/fonts.js +3 -1
- package/dist/plugins/import-meta-url.js +21 -15
- package/dist/plugins/instrumentation-client.js +1 -1
- package/dist/plugins/middleware-export-validation.d.ts +5 -0
- package/dist/plugins/middleware-export-validation.js +36 -0
- package/dist/plugins/middleware-server-only.js +7 -6
- package/dist/plugins/og-asset-ownership.d.ts +27 -0
- package/dist/plugins/og-asset-ownership.js +285 -0
- package/dist/plugins/og-assets.js +66 -46
- package/dist/plugins/optimize-imports.js +9 -3
- package/dist/plugins/remove-console.d.ts +7 -1
- package/dist/plugins/remove-console.js +4 -1
- package/dist/plugins/require-context.js +21 -20
- package/dist/plugins/strip-server-exports.d.ts +7 -1
- package/dist/plugins/strip-server-exports.js +4 -1
- package/dist/server/accept-encoding.d.ts +29 -0
- package/dist/server/accept-encoding.js +95 -0
- package/dist/server/app-bfcache-identity.d.ts +26 -0
- package/dist/server/app-bfcache-identity.js +127 -0
- package/dist/server/app-browser-entry.js +17 -11
- package/dist/server/app-browser-rsc-redirect.d.ts +2 -1
- package/dist/server/app-browser-rsc-redirect.js +8 -1
- package/dist/server/app-browser-state.d.ts +2 -21
- package/dist/server/app-browser-state.js +4 -128
- package/dist/server/app-browser-stream.js +1 -1
- package/dist/server/app-browser-visible-commit.js +3 -2
- package/dist/server/app-fallback-renderer.d.ts +1 -1
- package/dist/server/app-layout-param-observation.d.ts +1 -1
- package/dist/server/app-layout-param-observation.js +1 -1
- package/dist/server/app-middleware.d.ts +1 -0
- package/dist/server/app-middleware.js +3 -1
- package/dist/server/app-page-boundary-render.d.ts +1 -1
- package/dist/server/app-page-boundary.js +1 -1
- package/dist/server/app-page-cache-finalizer.d.ts +62 -0
- package/dist/server/app-page-cache-finalizer.js +122 -0
- package/dist/server/app-page-cache-render.d.ts +2 -2
- package/dist/server/app-page-cache-render.js +1 -1
- package/dist/server/app-page-cache.d.ts +2 -53
- package/dist/server/app-page-cache.js +5 -131
- package/dist/server/app-page-dispatch.d.ts +4 -4
- package/dist/server/app-page-dispatch.js +10 -8
- package/dist/server/app-page-head.js +2 -2
- package/dist/server/app-page-probe.js +3 -2
- package/dist/server/app-page-render-observation.js +2 -2
- package/dist/server/app-page-render.d.ts +3 -3
- package/dist/server/app-page-render.js +3 -2
- package/dist/server/app-page-request.d.ts +7 -0
- package/dist/server/app-page-request.js +19 -1
- package/dist/server/app-page-stream.d.ts +2 -9
- package/dist/server/app-page-stream.js +1 -35
- package/dist/server/app-prerender-endpoints.d.ts +3 -3
- package/dist/server/app-prerender-endpoints.js +3 -4
- package/dist/server/app-request-context.d.ts +1 -2
- package/dist/server/app-request-context.js +2 -1
- package/dist/server/app-route-handler-dispatch.js +3 -2
- package/dist/server/app-route-handler-execution.d.ts +1 -1
- package/dist/server/app-route-handler-execution.js +1 -1
- package/dist/server/app-route-handler-response.d.ts +1 -1
- package/dist/server/app-route-module-loader.d.ts +62 -14
- package/dist/server/app-route-module-loader.js +61 -10
- package/dist/server/app-router-entry.js +2 -1
- package/dist/server/app-rsc-handler.d.ts +7 -6
- package/dist/server/app-rsc-handler.js +51 -40
- package/dist/server/app-rsc-response-finalizer.js +1 -1
- package/dist/server/app-rsc-route-matching.d.ts +9 -0
- package/dist/server/app-rsc-route-matching.js +13 -0
- package/dist/server/app-server-action-execution.d.ts +1 -1
- package/dist/server/app-server-action-execution.js +5 -4
- package/dist/server/app-ssr-entry.d.ts +1 -1
- package/dist/server/app-ssr-entry.js +9 -7
- package/dist/server/app-ssr-router-instance.d.ts +6 -0
- package/dist/server/app-ssr-router-instance.js +24 -0
- package/dist/server/app-ssr-stream.js +1 -1
- package/dist/server/artifact-compatibility.js +1 -1
- package/dist/server/client-reuse-manifest.js +1 -1
- package/dist/server/defer-until-stream-consumed.d.ts +7 -0
- package/dist/server/defer-until-stream-consumed.js +34 -0
- package/dist/server/dev-server.js +1 -1
- package/dist/server/headers.d.ts +5 -1
- package/dist/server/headers.js +5 -1
- package/dist/server/instrumentation.js +1 -1
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +1 -1
- package/dist/server/isr-decision.d.ts +1 -1
- package/dist/server/metadata-route-response.d.ts +3 -3
- package/dist/server/middleware-matcher.js +8 -6
- package/dist/server/middleware-runtime.d.ts +2 -1
- package/dist/server/middleware-runtime.js +21 -10
- package/dist/server/middleware.d.ts +2 -2
- package/dist/server/middleware.js +26 -11
- package/dist/server/open-redirect.d.ts +12 -0
- package/dist/server/open-redirect.js +21 -0
- package/dist/server/pages-page-data.d.ts +1 -1
- package/dist/server/pages-page-response.d.ts +1 -1
- package/dist/server/pages-page-response.js +2 -2
- package/dist/server/pages-request-pipeline.d.ts +3 -1
- package/dist/server/pages-request-pipeline.js +4 -2
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +87 -73
- package/dist/server/request-pipeline.d.ts +1 -24
- package/dist/server/request-pipeline.js +1 -33
- package/dist/server/seed-cache.d.ts +1 -1
- package/dist/shims/cache-handler.d.ts +106 -0
- package/dist/shims/cache-handler.js +176 -0
- package/dist/shims/cache-request-state.d.ts +47 -0
- package/dist/shims/cache-request-state.js +126 -0
- package/dist/shims/cache-runtime.d.ts +2 -2
- package/dist/shims/cache-runtime.js +3 -14
- package/dist/shims/cache.d.ts +3 -231
- package/dist/shims/cache.js +17 -383
- package/dist/shims/cdn-cache.d.ts +1 -1
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/error-boundary-navigation.d.ts +7 -0
- package/dist/shims/error-boundary-navigation.js +44 -0
- package/dist/shims/error-boundary.js +10 -8
- package/dist/shims/error.js +2 -1
- package/dist/shims/fetch-cache.js +1 -1
- package/dist/shims/font-google-base.d.ts +1 -0
- package/dist/shims/font-google-base.js +6 -21
- package/dist/shims/form.js +1 -1
- package/dist/shims/image.js +67 -9
- package/dist/shims/internal/app-page-props-cache-key.d.ts +5 -0
- package/dist/shims/internal/app-page-props-cache-key.js +16 -0
- package/dist/shims/internal/interpolate-as.d.ts +25 -0
- package/dist/shims/internal/interpolate-as.js +196 -0
- package/dist/shims/internal/navigation-untracked.js +2 -1
- package/dist/shims/layout-segment-context.d.ts +1 -1
- package/dist/shims/layout-segment-context.js +2 -1
- package/dist/shims/link.js +26 -3
- package/dist/shims/navigation-context-state.d.ts +40 -0
- package/dist/shims/navigation-context-state.js +116 -0
- package/dist/shims/navigation-errors.d.ts +55 -0
- package/dist/shims/navigation-errors.js +110 -0
- package/dist/shims/navigation-server.d.ts +3 -0
- package/dist/shims/navigation-server.js +3 -0
- package/dist/shims/navigation-state.d.ts +1 -2
- package/dist/shims/navigation-state.js +2 -1
- package/dist/shims/navigation.d.ts +3 -291
- package/dist/shims/navigation.js +13 -444
- package/dist/shims/navigation.react-server.d.ts +2 -2
- package/dist/shims/navigation.react-server.js +4 -2
- package/dist/shims/request-state-types.d.ts +3 -3
- package/dist/shims/router.d.ts +1 -3
- package/dist/shims/router.js +62 -18
- package/dist/shims/script.js +1 -1
- package/dist/shims/slot.js +3 -1
- package/dist/shims/unified-request-context.d.ts +2 -2
- package/dist/typegen.js +2 -10
- package/dist/utils/project.d.ts +7 -1
- package/dist/utils/project.js +16 -2
- package/dist/utils/virtual-module.d.ts +5 -0
- package/dist/utils/virtual-module.js +0 -0
- package/package.json +7 -3
|
@@ -31,6 +31,7 @@ type AppRscInterceptForMatching = {
|
|
|
31
31
|
sourceMatchPattern?: string;
|
|
32
32
|
sourcePageSegments?: readonly string[];
|
|
33
33
|
interceptLayouts: readonly unknown[];
|
|
34
|
+
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
34
35
|
page: unknown;
|
|
35
36
|
__pageLoader?: (() => Promise<unknown>) | null;
|
|
36
37
|
params: readonly string[];
|
|
@@ -45,6 +46,7 @@ type AppRscSiblingInterceptForMatching = {
|
|
|
45
46
|
sourcePageSegments?: readonly string[];
|
|
46
47
|
slotId: string | null;
|
|
47
48
|
interceptLayouts: readonly unknown[];
|
|
49
|
+
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
48
50
|
page: unknown;
|
|
49
51
|
__pageLoader?: (() => Promise<unknown>) | null;
|
|
50
52
|
params: readonly string[];
|
|
@@ -58,6 +60,11 @@ type AppRscRouteForMatching = {
|
|
|
58
60
|
type AppRscInterceptMatch = AppRscInterceptLookupEntry & {
|
|
59
61
|
matchedParams: AppRscRouteParams;
|
|
60
62
|
};
|
|
63
|
+
type AppRscInterceptLoadState = {
|
|
64
|
+
page: unknown;
|
|
65
|
+
pageLoading: Promise<unknown> | null;
|
|
66
|
+
interceptLayoutsLoading: Promise<readonly unknown[]> | null;
|
|
67
|
+
};
|
|
61
68
|
type AppRscInterceptLookupEntry = {
|
|
62
69
|
sourceRouteIndex: number;
|
|
63
70
|
slotKey: string;
|
|
@@ -67,8 +74,10 @@ type AppRscInterceptLookupEntry = {
|
|
|
67
74
|
sourceMatchPatternParts: string[] | null;
|
|
68
75
|
sourcePageSegments: readonly string[] | null;
|
|
69
76
|
interceptLayouts: readonly unknown[];
|
|
77
|
+
__loadInterceptLayouts?: readonly (() => Promise<unknown>)[] | null;
|
|
70
78
|
page: unknown;
|
|
71
79
|
__pageLoader?: (() => Promise<unknown>) | null;
|
|
80
|
+
__loadState: AppRscInterceptLoadState;
|
|
72
81
|
params: readonly string[];
|
|
73
82
|
slotId: string | null;
|
|
74
83
|
};
|
|
@@ -39,6 +39,7 @@ function createAppRscRouteMatcher(routes) {
|
|
|
39
39
|
const sourceParams = matchedSourceParams ?? createRouteParams();
|
|
40
40
|
return {
|
|
41
41
|
...entry,
|
|
42
|
+
page: entry.__loadState.page,
|
|
42
43
|
sourceRouteIndex: concreteSourceRouteIndex,
|
|
43
44
|
matchedParams: mergeMatchedParams(sourceParams, params)
|
|
44
45
|
};
|
|
@@ -84,8 +85,14 @@ function createInterceptLookup(routes) {
|
|
|
84
85
|
sourceMatchPatternParts,
|
|
85
86
|
sourcePageSegments: intercept.sourcePageSegments ?? null,
|
|
86
87
|
interceptLayouts: intercept.interceptLayouts,
|
|
88
|
+
__loadInterceptLayouts: intercept.__loadInterceptLayouts,
|
|
87
89
|
page: intercept.page,
|
|
88
90
|
__pageLoader: intercept.__pageLoader,
|
|
91
|
+
__loadState: {
|
|
92
|
+
page: intercept.page,
|
|
93
|
+
pageLoading: null,
|
|
94
|
+
interceptLayoutsLoading: null
|
|
95
|
+
},
|
|
89
96
|
params: intercept.params
|
|
90
97
|
});
|
|
91
98
|
}
|
|
@@ -103,8 +110,14 @@ function createInterceptLookup(routes) {
|
|
|
103
110
|
sourceMatchPatternParts,
|
|
104
111
|
sourcePageSegments: intercept.sourcePageSegments ?? null,
|
|
105
112
|
interceptLayouts: intercept.interceptLayouts,
|
|
113
|
+
__loadInterceptLayouts: intercept.__loadInterceptLayouts,
|
|
106
114
|
page: intercept.page,
|
|
107
115
|
__pageLoader: intercept.__pageLoader,
|
|
116
|
+
__loadState: {
|
|
117
|
+
page: intercept.page,
|
|
118
|
+
pageLoading: null,
|
|
119
|
+
interceptLayoutsLoading: null
|
|
120
|
+
},
|
|
108
121
|
params: intercept.params
|
|
109
122
|
});
|
|
110
123
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionRevalidationKind } from "../shims/cache.js";
|
|
1
|
+
import { ActionRevalidationKind } from "../shims/cache-request-state.js";
|
|
2
2
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
|
3
3
|
import { FetchCacheMode } from "../shims/fetch-cache.js";
|
|
4
4
|
import { HeadersAccessPhase } from "../shims/headers.js";
|
|
@@ -4,17 +4,18 @@ import { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS
|
|
|
4
4
|
import { isExternalUrl } from "../config/config-matchers.js";
|
|
5
5
|
import { internalServerErrorResponse, payloadTooLargeResponse } from "./http-error-responses.js";
|
|
6
6
|
import { validateCsrfOrigin, validateServerActionPayload } from "./request-pipeline.js";
|
|
7
|
-
import { headersContextFromRequest, setHeadersContext } from "../shims/headers.js";
|
|
8
|
-
import { getAndClearActionRevalidationKind } from "../shims/cache.js";
|
|
9
7
|
import { APP_RSC_RENDER_MODE_ACTION_RERENDER_PRESERVE_UI } from "./app-rsc-render-mode.js";
|
|
8
|
+
import { headersContextFromRequest, setHeadersContext } from "../shims/headers.js";
|
|
9
|
+
import { getAndClearActionRevalidationKind } from "../shims/cache-request-state.js";
|
|
10
10
|
import { setCurrentFetchCacheMode, setCurrentFetchSoftTags, setCurrentForceDynamicFetchDefault } from "../shims/fetch-cache.js";
|
|
11
|
-
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
12
11
|
import { readStreamAsTextWithLimit } from "../utils/text-stream.js";
|
|
12
|
+
import { VINEXT_RSC_CONTENT_TYPE, VINEXT_RSC_VARY_HEADER, applyRscCompatibilityIdHeader } from "./app-rsc-cache-busting.js";
|
|
13
13
|
import { mergeMiddlewareResponseHeaders } from "./middleware-response-headers.js";
|
|
14
14
|
import { applyEdgeRuntimeHeader } from "./app-page-response.js";
|
|
15
15
|
import { getNextErrorDigest, parseNextHttpErrorDigest, parseNextRedirectDigest } from "./next-error-digest.js";
|
|
16
16
|
import { createServerActionNotFoundResponse, getServerActionNotFoundMessage, isServerActionNotFoundError } from "./server-action-not-found.js";
|
|
17
|
-
import { deferUntilStreamConsumed } from "./
|
|
17
|
+
import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
|
|
18
|
+
import "./app-page-stream.js";
|
|
18
19
|
import { buildAppPageTags } from "./implicit-tags.js";
|
|
19
20
|
import { resolveAppPageNavigationParams } from "./app-page-element-builder.js";
|
|
20
21
|
import { resolveAppPageActionRerenderTarget } from "./app-page-request.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NavigationContext } from "../shims/navigation.js";
|
|
1
|
+
import { NavigationContext } from "../shims/navigation-context-state.js";
|
|
2
2
|
import { RootParams } from "../shims/root-params.js";
|
|
3
3
|
import { AppSsrRenderResult } from "./app-page-stream.js";
|
|
4
4
|
import { ReactFormState } from "react-dom/client";
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import "./server-globals.js";
|
|
2
2
|
import { notFoundResponse } from "./http-error-responses.js";
|
|
3
|
-
import { isOpenRedirectShaped } from "./
|
|
4
|
-
import { isPprFallbackShellAbortError } from "../shims/ppr-fallback-shell.js";
|
|
3
|
+
import { isOpenRedirectShaped } from "./open-redirect.js";
|
|
5
4
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
6
5
|
import "./app-elements.js";
|
|
6
|
+
import { isPprFallbackShellAbortError } from "../shims/ppr-fallback-shell.js";
|
|
7
7
|
import { AppRouterContext } from "../shims/internal/app-router-context.js";
|
|
8
8
|
import { appendAssetDeploymentIdQuery } from "../utils/deployment-id.js";
|
|
9
|
-
import { ServerInsertedHTMLContext,
|
|
9
|
+
import { ServerInsertedHTMLContext, clearServerInsertedHTML, getBfcacheIdMapContext, registerServerInsertedHTMLCallback, renderServerInsertedHTML, setNavigationContext } from "../shims/navigation-context-state.js";
|
|
10
|
+
import "../shims/navigation-server.js";
|
|
10
11
|
import { runWithNavigationContext } from "../shims/navigation-state.js";
|
|
11
12
|
import { withScriptNonce } from "../shims/script-nonce-context.js";
|
|
12
13
|
import { createInlineScriptTag, createNonceAttribute, escapeHtmlAttr, safeJsonStringify } from "./html.js";
|
|
@@ -17,12 +18,13 @@ import { createSsrErrorMetaRenderer } from "./app-ssr-error-meta.js";
|
|
|
17
18
|
import { createNavigationRuntimeRscMetadataScript, createRscEmbedTransform, createTickBufferedTransform } from "./app-ssr-stream.js";
|
|
18
19
|
import { BeforeInteractiveContext } from "../shims/before-interactive-context.js";
|
|
19
20
|
import { runWithRootParamsScope } from "../shims/root-params.js";
|
|
20
|
-
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-
|
|
21
|
+
import { createBfcacheSegmentStateKeyMap, createInitialBfcacheIdMap } from "./app-bfcache-identity.js";
|
|
21
22
|
import { RSC_FORM_STATE_GLOBAL } from "./app-browser-hydration.js";
|
|
22
23
|
import { createClientReferencePreloader } from "./app-client-reference-preloader.js";
|
|
23
|
-
import { deferUntilStreamConsumed } from "./
|
|
24
|
+
import { deferUntilStreamConsumed } from "./defer-until-stream-consumed.js";
|
|
24
25
|
import { renderBeforeInteractiveInlineScripts } from "./before-interactive-head.js";
|
|
25
26
|
import { createInitialDevServerErrorScript } from "./dev-initial-server-error.js";
|
|
27
|
+
import { ssrAppRouterInstance } from "./app-ssr-router-instance.js";
|
|
26
28
|
import { Fragment, createElement, use } from "react";
|
|
27
29
|
import { renderToReadableStream, renderToStaticMarkup } from "react-dom/server.edge";
|
|
28
30
|
import { createFromReadableStream } from "@vitejs/plugin-rsc/ssr";
|
|
@@ -192,8 +194,8 @@ async function handleSsr(rscStream, navContext, fontData, options) {
|
|
|
192
194
|
return BfcacheIdMapContext ? createElement(BfcacheIdMapContext.Provider, { value: createInitialBfcacheIdMap(elements) }, stateKeyTree) : stateKeyTree;
|
|
193
195
|
}
|
|
194
196
|
const flightRootElement = createElement(VinextFlightRoot);
|
|
195
|
-
const root = AppRouterContext ? createElement(AppRouterContext.Provider, { value:
|
|
196
|
-
const ssrTree = ServerInsertedHTMLContext ? createElement(ServerInsertedHTMLContext.Provider, { value:
|
|
197
|
+
const root = AppRouterContext ? createElement(AppRouterContext.Provider, { value: ssrAppRouterInstance }, flightRootElement) : flightRootElement;
|
|
198
|
+
const ssrTree = ServerInsertedHTMLContext ? createElement(ServerInsertedHTMLContext.Provider, { value: registerServerInsertedHTMLCallback }, root) : root;
|
|
197
199
|
const beforeInteractiveInlineScripts = [];
|
|
198
200
|
const registerBeforeInteractiveInlineScript = (script) => {
|
|
199
201
|
beforeInteractiveInlineScripts.push(script);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { assertSafeNavigationUrl } from "../shims/url-safety.js";
|
|
2
|
+
import "./app-bfcache-id.js";
|
|
3
|
+
//#region src/server/app-ssr-router-instance.ts
|
|
4
|
+
function validateNavigationHref(href) {
|
|
5
|
+
assertSafeNavigationUrl(href);
|
|
6
|
+
}
|
|
7
|
+
const ssrAppRouterInstance = {
|
|
8
|
+
bfcacheId: "0",
|
|
9
|
+
back() {},
|
|
10
|
+
forward() {},
|
|
11
|
+
refresh() {},
|
|
12
|
+
push(href, _options) {
|
|
13
|
+
validateNavigationHref(href);
|
|
14
|
+
},
|
|
15
|
+
replace(href, _options) {
|
|
16
|
+
validateNavigationHref(href);
|
|
17
|
+
},
|
|
18
|
+
prefetch(href) {
|
|
19
|
+
validateNavigationHref(href);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
if (process.env.__NEXT_GESTURE_TRANSITION) ssrAppRouterInstance.experimental_gesturePush = validateNavigationHref;
|
|
23
|
+
//#endregion
|
|
24
|
+
export { ssrAppRouterInstance };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { NAVIGATION_RUNTIME_SYMBOL_DESCRIPTION } from "../client/navigation-runtime.js";
|
|
2
1
|
import { createInlineScriptTag, escapeHtmlAttr, htmlTokenListContains, safeJsonStringify } from "./html.js";
|
|
3
2
|
import { bytesToBase64, concatUint8Arrays } from "./app-rsc-embedded-chunks.js";
|
|
3
|
+
import { NAVIGATION_RUNTIME_SYMBOL_DESCRIPTION } from "../client/navigation-runtime.js";
|
|
4
4
|
//#region src/server/app-ssr-stream.ts
|
|
5
5
|
const NAVIGATION_RUNTIME_REFERENCE = `self[Symbol.for(${safeJsonStringify(NAVIGATION_RUNTIME_SYMBOL_DESCRIPTION)})]`;
|
|
6
6
|
function navigationRuntimeRscBootstrapExpression() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fnv1a64 } from "../utils/hash.js";
|
|
2
1
|
import { isUnknownRecord } from "../utils/record.js";
|
|
2
|
+
import { fnv1a64 } from "../utils/hash.js";
|
|
3
3
|
//#region src/server/artifact-compatibility.ts
|
|
4
4
|
const ARTIFACT_COMPATIBILITY_SCHEMA_VERSION = 1;
|
|
5
5
|
const APP_ELEMENTS_SCHEMA_VERSION = 1;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { fnv1a64 } from "../utils/hash.js";
|
|
2
1
|
import { isUnknownRecord } from "../utils/record.js";
|
|
2
|
+
import { fnv1a64 } from "../utils/hash.js";
|
|
3
3
|
import { parseArtifactCompatibilityEnvelope } from "./artifact-compatibility.js";
|
|
4
4
|
import { AppElementsWire } from "./app-elements-wire.js";
|
|
5
5
|
import { isNonNegativeSafeInteger } from "../utils/number.js";
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/server/defer-until-stream-consumed.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Defers cleanup until the downstream consumer drains or cancels the stream.
|
|
4
|
+
*/
|
|
5
|
+
declare function deferUntilStreamConsumed(stream: ReadableStream<Uint8Array>, onFlush: () => void): ReadableStream<Uint8Array>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { deferUntilStreamConsumed };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/server/defer-until-stream-consumed.ts
|
|
2
|
+
/**
|
|
3
|
+
* Defers cleanup until the downstream consumer drains or cancels the stream.
|
|
4
|
+
*/
|
|
5
|
+
function deferUntilStreamConsumed(stream, onFlush) {
|
|
6
|
+
let called = false;
|
|
7
|
+
const once = () => {
|
|
8
|
+
if (!called) {
|
|
9
|
+
called = true;
|
|
10
|
+
onFlush();
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const cleanup = new TransformStream({ flush() {
|
|
14
|
+
once();
|
|
15
|
+
} });
|
|
16
|
+
const reader = stream.pipeThrough(cleanup).getReader();
|
|
17
|
+
return new ReadableStream({
|
|
18
|
+
pull(controller) {
|
|
19
|
+
return reader.read().then(({ done, value }) => {
|
|
20
|
+
if (done) controller.close();
|
|
21
|
+
else controller.enqueue(value);
|
|
22
|
+
}, (error) => {
|
|
23
|
+
once();
|
|
24
|
+
controller.error(error);
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
cancel(reason) {
|
|
28
|
+
once();
|
|
29
|
+
return reader.cancel(reason);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { deferUntilStreamConsumed };
|
|
@@ -7,10 +7,10 @@ import { normalizeStaticPathname } from "../routing/route-pattern.js";
|
|
|
7
7
|
import { importModule, reportRequestError } from "./instrumentation.js";
|
|
8
8
|
import { buildCacheStateHeaders } from "./cache-headers.js";
|
|
9
9
|
import { isUnknownRecord } from "../utils/record.js";
|
|
10
|
-
import { _runWithCacheState } from "../shims/cache.js";
|
|
11
10
|
import { NEVER_CACHE_CONTROL, NO_STORE_CACHE_CONTROL } from "./cache-control.js";
|
|
12
11
|
import { buildMissIsrCacheControl, decideIsr } from "./isr-decision.js";
|
|
13
12
|
import { PRERENDER_REVALIDATE_HEADER, buildPagesCacheValue, getRevalidateDuration, isOnDemandRevalidateRequest, isrCacheKey, isrGet, isrSet, setRevalidateDuration, triggerBackgroundRegeneration } from "./isr-cache.js";
|
|
13
|
+
import { _runWithCacheState } from "../shims/cache-request-state.js";
|
|
14
14
|
import { ensureFetchPatch, runWithFetchCache } from "../shims/fetch-cache.js";
|
|
15
15
|
import { runWithPrivateCache } from "../shims/cache-runtime.js";
|
|
16
16
|
import { mergeRouteParamsIntoQuery, parseQueryString } from "../utils/query.js";
|
package/dist/server/headers.d.ts
CHANGED
|
@@ -23,6 +23,10 @@ declare const VINEXT_TIMING_HEADER = "x-vinext-timing";
|
|
|
23
23
|
declare const VINEXT_PRERENDER_SECRET_HEADER = "x-vinext-prerender-secret";
|
|
24
24
|
/** URL-encoded JSON route params for build-time prerender renders. */
|
|
25
25
|
declare const VINEXT_PRERENDER_ROUTE_PARAMS_HEADER = "x-vinext-prerender-route-params";
|
|
26
|
+
/** Internal endpoint used to evaluate App Router generateStaticParams exports. */
|
|
27
|
+
declare const VINEXT_PRERENDER_STATIC_PARAMS_PATH = "/__vinext/prerender/static-params";
|
|
28
|
+
/** Internal endpoint used to evaluate Pages Router getStaticPaths exports. */
|
|
29
|
+
declare const VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH = "/__vinext/prerender/pages-static-paths";
|
|
26
30
|
/** TPR (Tailored Per-Request) revalidation interval in seconds. */
|
|
27
31
|
declare const VINEXT_REVALIDATE_HEADER = "x-vinext-revalidate";
|
|
28
32
|
/** Marker on cached ISR entries indicating RSC payload (value "1"). */
|
|
@@ -107,4 +111,4 @@ declare const INTERNAL_HEADERS: string[];
|
|
|
107
111
|
/** Vinext-only internal headers stripped alongside Next.js protocol internals. */
|
|
108
112
|
declare const VINEXT_INTERNAL_HEADERS: string[];
|
|
109
113
|
//#endregion
|
|
110
|
-
export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
|
|
114
|
+
export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
|
package/dist/server/headers.js
CHANGED
|
@@ -23,6 +23,10 @@ const VINEXT_TIMING_HEADER = "x-vinext-timing";
|
|
|
23
23
|
const VINEXT_PRERENDER_SECRET_HEADER = "x-vinext-prerender-secret";
|
|
24
24
|
/** URL-encoded JSON route params for build-time prerender renders. */
|
|
25
25
|
const VINEXT_PRERENDER_ROUTE_PARAMS_HEADER = "x-vinext-prerender-route-params";
|
|
26
|
+
/** Internal endpoint used to evaluate App Router generateStaticParams exports. */
|
|
27
|
+
const VINEXT_PRERENDER_STATIC_PARAMS_PATH = "/__vinext/prerender/static-params";
|
|
28
|
+
/** Internal endpoint used to evaluate Pages Router getStaticPaths exports. */
|
|
29
|
+
const VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH = "/__vinext/prerender/pages-static-paths";
|
|
26
30
|
/** TPR (Tailored Per-Request) revalidation interval in seconds. */
|
|
27
31
|
const VINEXT_REVALIDATE_HEADER = "x-vinext-revalidate";
|
|
28
32
|
/** Marker on cached ISR entries indicating RSC payload (value "1"). */
|
|
@@ -129,4 +133,4 @@ const INTERNAL_HEADERS = [
|
|
|
129
133
|
/** Vinext-only internal headers stripped alongside Next.js protocol internals. */
|
|
130
134
|
const VINEXT_INTERNAL_HEADERS = [VINEXT_PRERENDER_ROUTE_PARAMS_HEADER];
|
|
131
135
|
//#endregion
|
|
132
|
-
export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
|
|
136
|
+
export { ACTION_FORWARDED_HEADER, ACTION_REDIRECT_HEADER, ACTION_REDIRECT_STATUS_HEADER, ACTION_REDIRECT_TYPE_HEADER, ACTION_REVALIDATED_HEADER, FLIGHT_HEADERS, INTERNAL_HEADERS, MIDDLEWARE_HEADER_PREFIX, MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_OVERRIDE_HEADERS, MIDDLEWARE_REQUEST_HEADER_PREFIX, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER, NEXTJS_ACTION_NOT_FOUND_HEADER, NEXTJS_CACHE_HEADER, NEXTJS_DEPLOYMENT_ID_HEADER, NEXT_ACTION_HEADER, NEXT_ROUTER_PREFETCH_HEADER, NEXT_ROUTER_SEGMENT_PREFETCH_HEADER, NEXT_ROUTER_STATE_TREE_HEADER, NEXT_URL_HEADER, RSC_ACTION_HEADER, RSC_HEADER, VINEXT_CACHE_HEADER, VINEXT_CLIENT_REUSE_MANIFEST_HEADER, VINEXT_DYNAMIC_STALE_TIME_HEADER, VINEXT_INTERCEPTION_CONTEXT_HEADER, VINEXT_INTERNAL_HEADERS, VINEXT_MOUNTED_SLOTS_HEADER, VINEXT_MW_CTX_HEADER, VINEXT_PARAMS_HEADER, VINEXT_PRERENDER_PAGES_STATIC_PATHS_PATH, VINEXT_PRERENDER_ROUTE_PARAMS_HEADER, VINEXT_PRERENDER_SECRET_HEADER, VINEXT_PRERENDER_STATIC_PARAMS_PATH, VINEXT_REVALIDATE_HEADER, VINEXT_RSC_MARKER_HEADER, VINEXT_RSC_REDIRECT_HEADER, VINEXT_RSC_RENDER_MODE_HEADER, VINEXT_STATIC_FILE_HEADER, VINEXT_TIMING_HEADER };
|
|
@@ -51,7 +51,7 @@ async function importModule(runner, id) {
|
|
|
51
51
|
const INSTRUMENTATION_LOCATIONS = ["", "src/"];
|
|
52
52
|
function findInstrumentationHookFile(root, basename, fileMatcher) {
|
|
53
53
|
for (const dir of INSTRUMENTATION_LOCATIONS) for (const ext of fileMatcher.dottedExtensions) {
|
|
54
|
-
const fullPath = path.join(root, dir, `${basename}${ext}`);
|
|
54
|
+
const fullPath = path.posix.join(root, dir, `${basename}${ext}`);
|
|
55
55
|
if (fs.existsSync(fullPath)) return fullPath;
|
|
56
56
|
}
|
|
57
57
|
return null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RenderObservation } from "./cache-proof.js";
|
|
2
|
-
import { CacheHandlerValue, CachedAppPageValue, CachedPagesValue, IncrementalCacheValue } from "../shims/cache.js";
|
|
2
|
+
import { CacheHandlerValue, CachedAppPageValue, CachedPagesValue, IncrementalCacheValue } from "../shims/cache-handler.js";
|
|
3
3
|
import { OnRequestErrorContext } from "./instrumentation.js";
|
|
4
4
|
import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
|
|
5
5
|
import { AppRscRenderMode } from "./app-rsc-render-mode.js";
|
package/dist/server/isr-cache.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getRequestExecutionContext } from "../shims/request-context.js";
|
|
2
2
|
import { reportRequestError } from "./instrumentation.js";
|
|
3
|
-
import { fnv1a64 } from "../utils/hash.js";
|
|
4
3
|
import { getCdnCacheAdapter } from "../shims/cdn-cache.js";
|
|
4
|
+
import { fnv1a64 } from "../utils/hash.js";
|
|
5
5
|
import { normalizeMountedSlotsHeader } from "./app-mounted-slots-header.js";
|
|
6
6
|
import { APP_RSC_RENDER_MODE_NAVIGATION, getRscRenderModeCacheVariant } from "./app-rsc-render-mode.js";
|
|
7
7
|
import { normalizeAppPageInterceptionProofPathname } from "./app-page-render-identity.js";
|
|
@@ -2,15 +2,15 @@ import { MetadataFileRoute } from "./metadata-routes.js";
|
|
|
2
2
|
|
|
3
3
|
//#region src/server/metadata-route-response.d.ts
|
|
4
4
|
type AppPageParams = Record<string, string | string[]>;
|
|
5
|
-
type
|
|
5
|
+
type MetadataRouteMakeThenableParams = (params: AppPageParams) => unknown;
|
|
6
6
|
type MetadataRuntimeRoute = MetadataFileRoute & {
|
|
7
7
|
fileDataBase64?: string;
|
|
8
8
|
};
|
|
9
9
|
type MetadataRouteRequestOptions = {
|
|
10
10
|
metadataRoutes: readonly MetadataRuntimeRoute[];
|
|
11
11
|
cleanPathname: string;
|
|
12
|
-
makeThenableParams:
|
|
12
|
+
makeThenableParams: MetadataRouteMakeThenableParams;
|
|
13
13
|
};
|
|
14
14
|
declare function handleMetadataRouteRequest(options: MetadataRouteRequestOptions): Promise<Response | null>;
|
|
15
15
|
//#endregion
|
|
16
|
-
export { handleMetadataRouteRequest };
|
|
16
|
+
export { MetadataRouteMakeThenableParams, MetadataRuntimeRoute, handleMetadataRouteRequest };
|
|
@@ -48,17 +48,19 @@ function stripLocalePrefix(pathname, i18nConfig) {
|
|
|
48
48
|
const segments = pathname.split("/");
|
|
49
49
|
const firstSegment = segments[1];
|
|
50
50
|
if (!firstSegment || !i18nConfig.locales.includes(firstSegment)) return null;
|
|
51
|
-
return
|
|
51
|
+
return "/" + segments.slice(2).join("/");
|
|
52
52
|
}
|
|
53
53
|
function matchPattern(pathname, pattern) {
|
|
54
|
-
|
|
54
|
+
const normalizedPattern = /[\\():*+?]/.test(pattern) ? pattern : removeTrailingSlash(pattern);
|
|
55
|
+
let cached = _mwPatternCache.get(normalizedPattern);
|
|
55
56
|
if (cached === void 0) {
|
|
56
|
-
cached = compileMatcherPattern(
|
|
57
|
-
_mwPatternCache.set(
|
|
57
|
+
cached = compileMatcherPattern(normalizedPattern);
|
|
58
|
+
_mwPatternCache.set(normalizedPattern, cached);
|
|
58
59
|
}
|
|
59
60
|
if (cached === UNSAFE_MATCHER_PATTERN) return true;
|
|
60
|
-
if (cached === null) return pathname ===
|
|
61
|
-
|
|
61
|
+
if (cached === null) return removeTrailingSlash(pathname) === normalizedPattern;
|
|
62
|
+
if (cached.test(pathname)) return true;
|
|
63
|
+
return pathname.endsWith("/") && cached.test(removeTrailingSlash(pathname));
|
|
62
64
|
}
|
|
63
65
|
function extractConstraint(str, re) {
|
|
64
66
|
if (str[re.lastIndex] !== "(") return null;
|
|
@@ -56,6 +56,7 @@ type ExecuteMiddlewareOptions = {
|
|
|
56
56
|
type RunGeneratedMiddlewareOptions = ExecuteMiddlewareOptions & {
|
|
57
57
|
ctx?: ExecutionContextLike;
|
|
58
58
|
};
|
|
59
|
+
declare function createMiddlewareMissingExportError(filePath: string | undefined, isProxy: boolean): Error;
|
|
59
60
|
declare function resolveMiddlewareModuleHandler(mod: MiddlewareModule, options: {
|
|
60
61
|
filePath?: string;
|
|
61
62
|
isProxy: boolean;
|
|
@@ -63,4 +64,4 @@ declare function resolveMiddlewareModuleHandler(mod: MiddlewareModule, options:
|
|
|
63
64
|
declare function executeMiddleware(options: ExecuteMiddlewareOptions): Promise<MiddlewareResult>;
|
|
64
65
|
declare function runGeneratedMiddleware(options: RunGeneratedMiddlewareOptions): Promise<MiddlewareResult>;
|
|
65
66
|
//#endregion
|
|
66
|
-
export { MiddlewareModule, MiddlewareResult, executeMiddleware, resolveMiddlewareModuleHandler, runGeneratedMiddleware };
|
|
67
|
+
export { MiddlewareModule, MiddlewareResult, createMiddlewareMissingExportError, executeMiddleware, resolveMiddlewareModuleHandler, runGeneratedMiddleware };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { normalizePathnameForRouteMatchStrict } from "../routing/utils.js";
|
|
2
|
-
import { addBasePathToPathname, hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
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
5
|
import { MIDDLEWARE_REWRITE_HEADER } from "./headers.js";
|
|
@@ -9,6 +9,7 @@ import { normalizePath } from "./normalize-path.js";
|
|
|
9
9
|
import { matchesMiddleware } from "./middleware-matcher.js";
|
|
10
10
|
import { badRequestResponse, internalServerErrorResponse } from "./http-error-responses.js";
|
|
11
11
|
import { processMiddlewareHeaders } from "./request-pipeline.js";
|
|
12
|
+
import path from "node:path";
|
|
12
13
|
//#region src/server/middleware-runtime.ts
|
|
13
14
|
function isMiddlewareHandler(value) {
|
|
14
15
|
return typeof value === "function";
|
|
@@ -16,19 +17,29 @@ function isMiddlewareHandler(value) {
|
|
|
16
17
|
function isMiddlewareConfigExport(value) {
|
|
17
18
|
return !!value && typeof value === "object";
|
|
18
19
|
}
|
|
19
|
-
function middlewareFileLabel(isProxy) {
|
|
20
|
-
return isProxy ? "Proxy" : "Middleware";
|
|
21
|
-
}
|
|
22
20
|
function middlewareExpectedExport(isProxy) {
|
|
23
21
|
return isProxy ? "proxy" : "middleware";
|
|
24
22
|
}
|
|
23
|
+
function middlewareDisplayPath(filePath) {
|
|
24
|
+
const fileName = path.basename(filePath);
|
|
25
|
+
return path.basename(path.dirname(filePath)) === "src" ? `./src/${fileName}` : `./${fileName}`;
|
|
26
|
+
}
|
|
27
|
+
function createMiddlewareMissingExportError(filePath, isProxy) {
|
|
28
|
+
const expectedExport = middlewareExpectedExport(isProxy);
|
|
29
|
+
const displayPath = filePath ? middlewareDisplayPath(filePath) : void 0;
|
|
30
|
+
const resolvedPath = displayPath ? ` "${displayPath}"` : "";
|
|
31
|
+
const migrationReason = isProxy ? "- You are migrating from `middleware` to `proxy`, but haven't updated the exported function.\n" : "";
|
|
32
|
+
return /* @__PURE__ */ new Error(`The file${resolvedPath} must export a function, either as a default export or as a named "${expectedExport}" export.\nThis function is what Next.js runs for every request handled by this ${isProxy ? "proxy (previously called middleware)" : "middleware"}.\n\nWhy this happens:\n` + migrationReason + `- The file exists but doesn't export a function.
|
|
33
|
+
- The export is not a function (e.g., an object or constant).
|
|
34
|
+
- There's a syntax error preventing the export from being recognized.
|
|
35
|
+
|
|
36
|
+
To fix it:
|
|
37
|
+
- Ensure this file has either a default or "${expectedExport}" function export.\n\nLearn more: https://nextjs.org/docs/messages/middleware-to-proxy`);
|
|
38
|
+
}
|
|
25
39
|
function resolveMiddlewareModuleHandler(mod, options) {
|
|
26
40
|
const handler = options.isProxy ? mod.proxy ?? mod.default : mod.middleware ?? mod.default;
|
|
27
41
|
if (isMiddlewareHandler(handler)) return handler;
|
|
28
|
-
|
|
29
|
-
const expectedExport = middlewareExpectedExport(options.isProxy);
|
|
30
|
-
const fileSuffix = options.filePath ? ` "${options.filePath}"` : "";
|
|
31
|
-
throw new Error(`The ${fileLabel} file${fileSuffix} must export a function named \`${expectedExport}\` or a \`default\` function.`);
|
|
42
|
+
throw createMiddlewareMissingExportError(options.filePath, options.isProxy);
|
|
32
43
|
}
|
|
33
44
|
function middlewareMatcher(mod) {
|
|
34
45
|
const config = mod.config;
|
|
@@ -130,7 +141,7 @@ async function executeMiddleware(options) {
|
|
|
130
141
|
const matchPathname = options.basePath ? stripBasePath(normalizedPathname, options.basePath) : normalizedPathname;
|
|
131
142
|
if (!matchesMiddleware(matchPathname, middlewareMatcher(options.module), options.request, options.i18nConfig)) return { continue: true };
|
|
132
143
|
const nextRequest = createNextRequest(options.request, normalizedPathname, options.i18nConfig, options.basePath, options.trailingSlash, hadBasePath);
|
|
133
|
-
const fetchEvent = new NextFetchEvent({ page: matchPathname });
|
|
144
|
+
const fetchEvent = new NextFetchEvent({ page: removeTrailingSlash(matchPathname) });
|
|
134
145
|
let response;
|
|
135
146
|
try {
|
|
136
147
|
response = await middlewareFn(nextRequest, fetchEvent);
|
|
@@ -226,4 +237,4 @@ async function runGeneratedMiddleware(options) {
|
|
|
226
237
|
return options.ctx ? runWithExecutionContext(options.ctx, run) : run();
|
|
227
238
|
}
|
|
228
239
|
//#endregion
|
|
229
|
-
export { executeMiddleware, resolveMiddlewareModuleHandler, runGeneratedMiddleware };
|
|
240
|
+
export { createMiddlewareMissingExportError, executeMiddleware, resolveMiddlewareModuleHandler, runGeneratedMiddleware };
|
|
@@ -28,7 +28,7 @@ declare function isProxyFile(filePath: string): boolean;
|
|
|
28
28
|
*/
|
|
29
29
|
declare function resolveMiddlewareHandler(mod: MiddlewareModule, filePath: string): (request: NextRequest, event: NextFetchEvent) => Response | undefined | void | Promise<Response | undefined | void>;
|
|
30
30
|
/**
|
|
31
|
-
* Find the proxy or middleware file
|
|
31
|
+
* Find the proxy or middleware file at the selected app/pages convention level.
|
|
32
32
|
* Checks for proxy.ts (Next.js 16) first, then falls back to middleware.ts.
|
|
33
33
|
* If middleware.ts is found, logs a deprecation warning.
|
|
34
34
|
*
|
|
@@ -44,7 +44,7 @@ declare function resolveMiddlewareHandler(mod: MiddlewareModule, filePath: strin
|
|
|
44
44
|
* @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/index.ts
|
|
45
45
|
* (search for "MIDDLEWARE_FILENAME" + "file convention is deprecated")
|
|
46
46
|
*/
|
|
47
|
-
declare function findMiddlewareFile(root: string, fileMatcher: ValidFileMatcher): string | null;
|
|
47
|
+
declare function findMiddlewareFile(root: string, fileMatcher: ValidFileMatcher, conventionDir?: string): string | null;
|
|
48
48
|
/**
|
|
49
49
|
* Load and execute middleware for a given request.
|
|
50
50
|
*
|
|
@@ -13,7 +13,8 @@ import path from "node:path";
|
|
|
13
13
|
* https://github.com/vercel/next.js/blob/canary/packages/next/src/build/templates/middleware.ts
|
|
14
14
|
*/
|
|
15
15
|
function isProxyFile(filePath) {
|
|
16
|
-
|
|
16
|
+
const base = path.basename(filePath);
|
|
17
|
+
return base === "proxy" || base.startsWith("proxy.");
|
|
17
18
|
}
|
|
18
19
|
/**
|
|
19
20
|
* Resolve the middleware/proxy handler function from a module's exports.
|
|
@@ -32,9 +33,8 @@ function resolveMiddlewareHandler(mod, filePath) {
|
|
|
32
33
|
isProxy: isProxyFile(filePath)
|
|
33
34
|
});
|
|
34
35
|
}
|
|
35
|
-
const MIDDLEWARE_LOCATIONS = ["", "src/"];
|
|
36
36
|
/**
|
|
37
|
-
* Find the proxy or middleware file
|
|
37
|
+
* Find the proxy or middleware file at the selected app/pages convention level.
|
|
38
38
|
* Checks for proxy.ts (Next.js 16) first, then falls back to middleware.ts.
|
|
39
39
|
* If middleware.ts is found, logs a deprecation warning.
|
|
40
40
|
*
|
|
@@ -50,18 +50,33 @@ const MIDDLEWARE_LOCATIONS = ["", "src/"];
|
|
|
50
50
|
* @see https://github.com/vercel/next.js/blob/canary/packages/next/src/build/index.ts
|
|
51
51
|
* (search for "MIDDLEWARE_FILENAME" + "file convention is deprecated")
|
|
52
52
|
*/
|
|
53
|
-
function findMiddlewareFile(root, fileMatcher) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
function findMiddlewareFile(root, fileMatcher, conventionDir = root) {
|
|
54
|
+
let proxyPath = null;
|
|
55
|
+
for (const ext of fileMatcher.dottedExtensions) {
|
|
56
|
+
const fullPath = path.join(conventionDir, `proxy${ext}`);
|
|
57
|
+
if (fs.existsSync(fullPath)) {
|
|
58
|
+
proxyPath = fullPath;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
57
61
|
}
|
|
58
|
-
|
|
59
|
-
|
|
62
|
+
let middlewarePath = null;
|
|
63
|
+
for (const ext of fileMatcher.dottedExtensions) {
|
|
64
|
+
const fullPath = path.join(conventionDir, `middleware${ext}`);
|
|
60
65
|
if (fs.existsSync(fullPath)) {
|
|
61
|
-
|
|
62
|
-
|
|
66
|
+
middlewarePath = fullPath;
|
|
67
|
+
break;
|
|
63
68
|
}
|
|
64
69
|
}
|
|
70
|
+
if (proxyPath && middlewarePath) {
|
|
71
|
+
const relativeProxyPath = `./${path.relative(root, proxyPath)}`;
|
|
72
|
+
const relativeMiddlewarePath = `./${path.relative(root, middlewarePath)}`;
|
|
73
|
+
throw new Error(`Both middleware file "${relativeMiddlewarePath}" and proxy file "${relativeProxyPath}" are detected. Please use "${relativeProxyPath}" only. Learn more: https://nextjs.org/docs/messages/middleware-to-proxy`);
|
|
74
|
+
}
|
|
75
|
+
if (proxyPath) return proxyPath;
|
|
76
|
+
if (middlewarePath) {
|
|
77
|
+
console.warn("The \"middleware\" file convention is deprecated. Please use \"proxy\" instead.\n\n To migrate automatically, run:\n npx @next/codemod@canary middleware-to-proxy .\n\n Learn more: https://nextjs.org/docs/messages/middleware-to-proxy");
|
|
78
|
+
return middlewarePath;
|
|
79
|
+
}
|
|
65
80
|
return null;
|
|
66
81
|
}
|
|
67
82
|
function isMiddlewareModule(value) {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/server/open-redirect.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if a request pathname looks like a protocol-relative open
|
|
4
|
+
* redirect, in either literal or percent-encoded form.
|
|
5
|
+
*
|
|
6
|
+
* A pathname is considered "open redirect shaped" when its first segment,
|
|
7
|
+
* after decoding backslashes and encoded delimiters, would cause a browser
|
|
8
|
+
* to resolve a `Location` containing the pathname as protocol-relative.
|
|
9
|
+
*/
|
|
10
|
+
declare function isOpenRedirectShaped(rawPathname: string): boolean;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { isOpenRedirectShaped };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/server/open-redirect.ts
|
|
2
|
+
/**
|
|
3
|
+
* Returns true if a request pathname looks like a protocol-relative open
|
|
4
|
+
* redirect, in either literal or percent-encoded form.
|
|
5
|
+
*
|
|
6
|
+
* A pathname is considered "open redirect shaped" when its first segment,
|
|
7
|
+
* after decoding backslashes and encoded delimiters, would cause a browser
|
|
8
|
+
* to resolve a `Location` containing the pathname as protocol-relative.
|
|
9
|
+
*/
|
|
10
|
+
function isOpenRedirectShaped(rawPathname) {
|
|
11
|
+
if (!rawPathname.startsWith("/")) return false;
|
|
12
|
+
const afterSlash = rawPathname.slice(1);
|
|
13
|
+
if (afterSlash.startsWith("/") || afterSlash.startsWith("\\")) return true;
|
|
14
|
+
if (afterSlash.length >= 3 && afterSlash[0] === "%") {
|
|
15
|
+
const encoded = afterSlash.slice(0, 3).toLowerCase();
|
|
16
|
+
if (encoded === "%5c" || encoded === "%2f") return true;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
export { isOpenRedirectShaped };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Route } from "../routing/pages-router.js";
|
|
2
2
|
import { VinextNextData } from "../client/vinext-next-data.js";
|
|
3
|
-
import { CachedPagesValue } from "../shims/cache.js";
|
|
3
|
+
import { CachedPagesValue } from "../shims/cache-handler.js";
|
|
4
4
|
import { ISRCacheEntry } from "./isr-cache.js";
|
|
5
5
|
import { PagesGsspResponse, PagesI18nRenderContext, PagesNextDataExtras } from "./pages-page-response.js";
|
|
6
6
|
import { ReactNode } from "react";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VinextNextData } from "../client/vinext-next-data.js";
|
|
2
|
-
import { CachedPagesValue } from "../shims/cache.js";
|
|
2
|
+
import { CachedPagesValue } from "../shims/cache-handler.js";
|
|
3
3
|
import { RenderPageEnhancers } from "./pages-document-initial-props.js";
|
|
4
4
|
import { ComponentType, ReactNode } from "react";
|
|
5
5
|
|