vinext 0.1.8 → 0.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 +51 -30
- package/dist/build/inject-pregenerated-paths.d.ts +4 -0
- package/dist/build/inject-pregenerated-paths.js +18 -0
- package/dist/build/layout-classification.js +1 -1
- package/dist/build/nitro-route-rules.js +1 -1
- package/dist/build/pages-client-assets-module.d.ts +11 -0
- package/dist/build/pages-client-assets-module.js +27 -0
- package/dist/build/prerender.d.ts +2 -1
- package/dist/build/prerender.js +13 -6
- package/dist/build/report.d.ts +13 -2
- package/dist/build/report.js +99 -2
- package/dist/build/run-prerender.d.ts +7 -0
- package/dist/build/run-prerender.js +10 -1
- package/dist/build/standalone.js +2 -0
- package/dist/cache/cache-adapters-virtual.js +3 -3
- package/dist/check.js +40 -2
- package/dist/cli-args.d.ts +1 -2
- package/dist/cli-args.js +1 -1
- package/dist/cli-dev-config.d.ts +12 -0
- package/dist/cli-dev-config.js +23 -0
- package/dist/cli.js +111 -95
- package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay-store.js +1 -1
- package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
- package/dist/{server → client}/dev-error-overlay.js +2 -2
- package/dist/client/navigation-runtime.d.ts +2 -0
- package/dist/client/navigation-runtime.js +3 -1
- package/dist/client/window-next.d.ts +2 -1
- package/dist/cloudflare/index.d.ts +2 -2
- package/dist/cloudflare/index.js +2 -2
- package/dist/config/config-matchers.js +14 -10
- package/dist/config/next-config.d.ts +5 -3
- package/dist/config/next-config.js +44 -1
- package/dist/config/prerender.d.ts +34 -0
- package/dist/config/prerender.js +55 -0
- package/dist/entries/app-rsc-entry.d.ts +2 -1
- package/dist/entries/app-rsc-entry.js +40 -10
- package/dist/entries/app-rsc-manifest.js +2 -0
- package/dist/entries/pages-client-entry.d.ts +3 -0
- package/dist/entries/pages-client-entry.js +15 -1
- package/dist/entries/pages-server-entry.js +5 -2
- package/dist/image/image-adapters-virtual.d.ts +59 -0
- package/dist/image/image-adapters-virtual.js +59 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +167 -100
- package/dist/init-cloudflare.d.ts +43 -0
- package/dist/init-cloudflare.js +839 -0
- package/dist/init-platform.d.ts +40 -0
- package/dist/init-platform.js +195 -0
- package/dist/init.d.ts +16 -38
- package/dist/init.js +209 -99
- package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
- package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
- package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
- package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
- package/dist/packages/cloudflare/src/deploy-config.js +150 -0
- package/dist/packages/cloudflare/src/deploy-help.js +55 -0
- package/dist/packages/cloudflare/src/deploy.js +276 -0
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
- package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
- package/dist/plugins/ast-scope.d.ts +16 -0
- package/dist/plugins/ast-scope.js +62 -0
- package/dist/plugins/ast-utils.d.ts +27 -1
- package/dist/plugins/ast-utils.js +32 -1
- package/dist/plugins/css-module-imports.d.ts +14 -0
- package/dist/plugins/css-module-imports.js +59 -0
- package/dist/plugins/extensionless-dynamic-import.js +2 -2
- package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
- package/dist/plugins/ignore-dynamic-requests.js +530 -0
- package/dist/plugins/typeof-window.d.ts +1 -1
- package/dist/plugins/typeof-window.js +28 -56
- package/dist/routing/app-route-graph.d.ts +23 -2
- package/dist/routing/app-route-graph.js +126 -32
- package/dist/routing/file-matcher.d.ts +3 -0
- package/dist/routing/file-matcher.js +3 -0
- package/dist/routing/pages-router.js +2 -2
- package/dist/server/api-handler.js +9 -14
- package/dist/server/app-browser-action-result.d.ts +4 -1
- package/dist/server/app-browser-action-result.js +8 -1
- package/dist/server/app-browser-entry.js +161 -52
- package/dist/server/app-browser-interception-context.d.ts +1 -0
- package/dist/server/app-browser-interception-context.js +4 -2
- package/dist/server/app-browser-navigation-controller.d.ts +2 -0
- package/dist/server/app-browser-navigation-controller.js +60 -31
- package/dist/server/app-browser-server-action-client.d.ts +1 -1
- package/dist/server/app-browser-server-action-client.js +3 -4
- package/dist/server/app-browser-state.d.ts +11 -1
- package/dist/server/app-browser-state.js +25 -8
- package/dist/server/app-browser-visible-commit.d.ts +6 -1
- package/dist/server/app-browser-visible-commit.js +43 -25
- package/dist/server/app-elements-wire.d.ts +9 -2
- package/dist/server/app-elements-wire.js +8 -1
- package/dist/server/app-elements.d.ts +2 -2
- package/dist/server/app-elements.js +4 -3
- package/dist/server/app-fallback-renderer.d.ts +2 -1
- package/dist/server/app-fallback-renderer.js +10 -6
- package/dist/server/app-hydration-cache-publication.d.ts +11 -0
- package/dist/server/app-hydration-cache-publication.js +43 -0
- package/dist/server/app-middleware.d.ts +4 -3
- package/dist/server/app-middleware.js +8 -3
- package/dist/server/app-optimistic-routing.js +11 -4
- package/dist/server/app-page-cache-finalizer.js +2 -1
- package/dist/server/app-page-cache-render.d.ts +1 -0
- package/dist/server/app-page-cache-render.js +8 -4
- package/dist/server/app-page-cache.d.ts +1 -0
- package/dist/server/app-page-cache.js +5 -2
- package/dist/server/app-page-dispatch.js +1 -0
- package/dist/server/app-page-element-builder.d.ts +2 -1
- package/dist/server/app-page-element-builder.js +58 -4
- package/dist/server/app-page-probe.js +5 -0
- package/dist/server/app-page-render-identity.d.ts +1 -0
- package/dist/server/app-page-render-identity.js +1 -1
- package/dist/server/app-page-render.js +18 -0
- package/dist/server/app-page-request.d.ts +14 -0
- package/dist/server/app-page-request.js +69 -4
- package/dist/server/app-page-route-wiring.d.ts +8 -1
- package/dist/server/app-page-route-wiring.js +32 -18
- package/dist/server/app-page-segment-state.d.ts +2 -1
- package/dist/server/app-page-segment-state.js +3 -1
- package/dist/server/app-page-stream.d.ts +5 -0
- package/dist/server/app-page-stream.js +3 -1
- package/dist/server/app-route-handler-execution.js +5 -1
- package/dist/server/app-route-handler-response.js +1 -0
- package/dist/server/app-route-handler-runtime.js +1 -1
- package/dist/server/app-router-entry.js +9 -2
- package/dist/server/app-rsc-handler.d.ts +1 -0
- package/dist/server/app-rsc-handler.js +62 -31
- package/dist/server/app-rsc-request-normalization.d.ts +3 -2
- package/dist/server/app-rsc-request-normalization.js +6 -3
- package/dist/server/app-segment-config.d.ts +11 -0
- package/dist/server/app-segment-config.js +62 -6
- package/dist/server/app-server-action-execution.d.ts +1 -0
- package/dist/server/app-server-action-execution.js +58 -28
- package/dist/server/app-ssr-entry.d.ts +3 -0
- package/dist/server/app-ssr-entry.js +15 -7
- package/dist/server/app-ssr-stream.d.ts +7 -3
- package/dist/server/app-ssr-stream.js +10 -6
- package/dist/server/app-visited-response-cache.d.ts +6 -0
- package/dist/server/app-visited-response-cache.js +3 -1
- package/dist/server/client-trace-metadata.js +26 -0
- package/dist/server/default-global-not-found-module.d.ts +14 -0
- package/dist/server/default-global-not-found-module.js +14 -0
- package/dist/server/dev-route-files.js +4 -0
- package/dist/server/dev-server.js +19 -18
- package/dist/server/dev-stack-sourcemap.d.ts +1 -1
- package/dist/server/dev-stack-sourcemap.js +1 -1
- package/dist/server/fetch-handler.d.ts +2 -0
- package/dist/server/fetch-handler.js +18 -0
- package/dist/server/headers.d.ts +3 -15
- package/dist/server/headers.js +2 -15
- package/dist/server/image-optimization.d.ts +51 -1
- package/dist/server/image-optimization.js +52 -2
- package/dist/server/implicit-tags.js +1 -1
- package/dist/server/isr-cache.d.ts +1 -1
- package/dist/server/isr-cache.js +2 -2
- package/dist/server/metadata-routes.d.ts +3 -1
- package/dist/server/metadata-routes.js +12 -2
- package/dist/server/middleware-runtime.js +6 -1
- package/dist/server/navigation-planner.d.ts +1 -0
- package/dist/server/navigation-planner.js +14 -3
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +4 -6
- package/dist/server/pages-asset-tags.js +12 -12
- package/dist/server/pages-client-assets.d.ts +12 -0
- package/dist/server/pages-client-assets.js +10 -0
- package/dist/server/pages-node-compat.d.ts +8 -1
- package/dist/server/pages-node-compat.js +32 -4
- package/dist/server/pages-page-data.d.ts +24 -1
- package/dist/server/pages-page-data.js +45 -24
- package/dist/server/pages-page-handler.d.ts +2 -1
- package/dist/server/pages-page-handler.js +19 -12
- package/dist/server/pages-page-response.d.ts +7 -0
- package/dist/server/pages-page-response.js +4 -1
- package/dist/server/pages-request-pipeline.d.ts +2 -0
- package/dist/server/pages-request-pipeline.js +25 -1
- package/dist/server/pages-router-entry.d.ts +30 -0
- package/dist/server/pages-router-entry.js +108 -0
- package/dist/server/prerender-manifest.d.ts +3 -1
- package/dist/server/prerender-route-params.js +1 -1
- package/dist/server/prod-server.d.ts +1 -1
- package/dist/server/prod-server.js +33 -20
- package/dist/server/request-pipeline.js +1 -0
- package/dist/server/seed-cache.js +4 -4
- package/dist/shims/app-router-scroll-state.d.ts +1 -0
- package/dist/shims/app-router-scroll-state.js +1 -0
- package/dist/shims/app-router-scroll.js +2 -1
- package/dist/shims/cache.js +19 -15
- package/dist/shims/cdn-cache.js +1 -1
- package/dist/shims/dynamic-preload-chunks.js +2 -1
- package/dist/shims/form.d.ts +3 -1
- package/dist/shims/form.js +37 -43
- package/dist/shims/headers.d.ts +7 -1
- package/dist/shims/headers.js +17 -3
- package/dist/shims/image.js +75 -14
- package/dist/shims/internal/app-route-detection.d.ts +2 -17
- package/dist/shims/internal/app-route-detection.js +4 -17
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
- package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
- package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
- package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
- package/dist/shims/internal/pages-data-target.d.ts +10 -9
- package/dist/shims/internal/pages-data-target.js +91 -12
- package/dist/shims/internal/pages-router-components.d.ts +7 -0
- package/dist/shims/internal/pages-router-components.js +13 -0
- package/dist/shims/layout-segment-context.d.ts +4 -1
- package/dist/shims/layout-segment-context.js +18 -4
- package/dist/shims/link.js +55 -26
- package/dist/shims/navigation.d.ts +5 -1
- package/dist/shims/navigation.js +45 -10
- package/dist/shims/navigation.react-server.js +1 -1
- package/dist/shims/root-params.d.ts +15 -1
- package/dist/shims/root-params.js +21 -1
- package/dist/shims/router.d.ts +5 -7
- package/dist/shims/router.js +362 -93
- package/dist/shims/server.js +3 -2
- package/dist/shims/slot.js +3 -6
- package/dist/utils/client-runtime-metadata.d.ts +2 -18
- package/dist/utils/client-runtime-metadata.js +31 -22
- package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
- package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
- package/dist/utils/domain-locale.d.ts +6 -3
- package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
- package/dist/{server → utils}/middleware-request-headers.js +2 -2
- package/dist/utils/project.d.ts +48 -2
- package/dist/utils/project.js +225 -4
- package/dist/utils/protocol-headers.d.ts +17 -0
- package/dist/utils/protocol-headers.js +17 -0
- package/dist/utils/react-version.d.ts +4 -0
- package/dist/utils/react-version.js +44 -0
- package/package.json +47 -2
- package/dist/deploy.d.ts +0 -197
- package/dist/deploy.js +0 -1040
- package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
- /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
package/dist/shims/router.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import { splitPathSegments } from "../routing/utils.js";
|
|
2
|
-
import { removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
2
|
+
import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
3
|
+
import { parseCookieHeader } from "../utils/parse-cookie.js";
|
|
3
4
|
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
4
|
-
import { fillRoutePatternSegments, matchRoutePattern, routePatternParts } from "../routing/route-pattern.js";
|
|
5
5
|
import { isUnknownRecord } from "../utils/record.js";
|
|
6
6
|
import { AppRouterContext } from "./internal/app-router-context.js";
|
|
7
7
|
import { RouterContext } from "./internal/router-context.js";
|
|
8
8
|
import { applyVinextLocaleGlobals, extractVinextNextDataJson, parseVinextNextDataJson } from "../client/vinext-next-data.js";
|
|
9
9
|
import { isValidModulePath } from "../client/validate-module-path.js";
|
|
10
10
|
import { addLocalePrefix, getDomainLocaleUrl, getLocalePathPrefix } from "../utils/domain-locale.js";
|
|
11
|
-
import {
|
|
11
|
+
import { fillRoutePatternSegments, matchRoutePattern, routePatternParts } from "../routing/route-pattern.js";
|
|
12
12
|
import { NEXT_DEPLOYMENT_ID_HEADER, getDeploymentId } from "../utils/deployment-id.js";
|
|
13
|
-
import { dedupedPagesDataFetch } from "./internal/pages-data-fetch-dedup.js";
|
|
14
|
-
import { prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
13
|
+
import { dedupedPagesDataFetch, evictPagesDataCache, fetchCachedPagesData, fetchStaticPagesData, getPagesStaticDataCache } from "./internal/pages-data-fetch-dedup.js";
|
|
14
|
+
import { getPagesMiddlewareDataHref, prefetchPagesData, resolvePagesDataNavigationTarget } from "./internal/pages-data-target.js";
|
|
15
|
+
import { getPagesRouterComponentsMap } from "./internal/pages-router-components.js";
|
|
16
|
+
import { markAppRouteDetectedOnPrefetch } from "./internal/app-route-detection.js";
|
|
17
|
+
import { resolveDirectHybridClientRouteOwner } from "./internal/hybrid-client-route-owner-direct.js";
|
|
18
18
|
import { installWindowNext } from "../client/window-next.js";
|
|
19
19
|
import { getWindowOrigin, isAbsoluteOrProtocolRelativeUrl, isHashOnlyBrowserUrlChange, normalizePathTrailingSlash, toBrowserNavigationHref, toSameOriginAppPath, withBasePath } from "./url-utils.js";
|
|
20
|
+
import { addQueryParam, appendSearchParamsToUrl, mergeRewriteQuery, mergeRouteParamsIntoQuery, parseQueryString, urlQueryToSearchParams } from "../utils/query.js";
|
|
20
21
|
import { scrollToHashTarget } from "./hash-scroll.js";
|
|
21
22
|
import { installPagesRouterRuntime, setPagesRouterPopStateHandler, setStampInitialHistoryState } from "./pages-router-runtime.js";
|
|
22
23
|
import { interpolateDynamicRouteHref } from "./internal/interpolate-as.js";
|
|
@@ -841,31 +842,185 @@ function resolveLocalRedirectUrl(location) {
|
|
|
841
842
|
if (appPath === null) return null;
|
|
842
843
|
return normalizePathTrailingSlash(toBrowserNavigationHref(stripLocalePrefixForApiRedirect(appPath), window.location.href, __basePath), __trailingSlash);
|
|
843
844
|
}
|
|
844
|
-
function
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
return isUnknownRecord(vinext) && vinext.hasMiddleware === true;
|
|
845
|
+
function hasClientRewriteRules() {
|
|
846
|
+
const rewrites = window.__VINEXT_CLIENT_REWRITES__;
|
|
847
|
+
return Boolean(rewrites && (rewrites.beforeFiles.length > 0 || rewrites.afterFiles.length > 0 || rewrites.fallback.length > 0));
|
|
848
848
|
}
|
|
849
|
-
function
|
|
850
|
-
const
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
849
|
+
function hasClientRedirectRules() {
|
|
850
|
+
const redirects = window.__VINEXT_CLIENT_REDIRECTS__;
|
|
851
|
+
return Array.isArray(redirects) && redirects.length > 0;
|
|
852
|
+
}
|
|
853
|
+
function hasClientAppRouteManifest() {
|
|
854
|
+
const routes = window.__VINEXT_LINK_PREFETCH_ROUTES__;
|
|
855
|
+
return Array.isArray(routes) && routes.length > 0;
|
|
856
|
+
}
|
|
857
|
+
function getClientConfigRouteContext(href) {
|
|
854
858
|
let parsed;
|
|
855
859
|
try {
|
|
856
|
-
parsed = new URL(
|
|
860
|
+
parsed = new URL(href, window.location.href);
|
|
857
861
|
} catch {
|
|
858
862
|
return null;
|
|
859
863
|
}
|
|
860
864
|
if (parsed.origin !== getWindowOrigin()) return null;
|
|
861
|
-
|
|
865
|
+
const hadBasePath = __basePath ? hasBasePath(parsed.pathname, __basePath) : true;
|
|
866
|
+
const pathname = hadBasePath ? stripBasePath(parsed.pathname, __basePath) : parsed.pathname;
|
|
867
|
+
const headers = new Headers({ "user-agent": globalThis.navigator?.userAgent ?? "" });
|
|
868
|
+
return {
|
|
869
|
+
basePathState: {
|
|
870
|
+
basePath: __basePath,
|
|
871
|
+
hadBasePath
|
|
872
|
+
},
|
|
873
|
+
context: {
|
|
874
|
+
cookies: parseCookieHeader(globalThis.document?.cookie ?? ""),
|
|
875
|
+
headers,
|
|
876
|
+
host: parsed.hostname,
|
|
877
|
+
query: parsed.searchParams
|
|
878
|
+
},
|
|
879
|
+
pathname,
|
|
880
|
+
search: parsed.search
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
async function resolveClientConfigRedirect(href) {
|
|
884
|
+
const redirects = window.__VINEXT_CLIENT_REDIRECTS__;
|
|
885
|
+
if (!redirects || redirects.length === 0) return null;
|
|
886
|
+
const routeContext = getClientConfigRouteContext(href);
|
|
887
|
+
if (!routeContext) return null;
|
|
888
|
+
const { isExternalUrl, matchRedirect, preserveRedirectDestinationQuery } = await import("../config/config-matchers.js");
|
|
889
|
+
const redirect = matchRedirect(routeContext.pathname, redirects, routeContext.context, routeContext.basePathState);
|
|
890
|
+
if (!redirect) return null;
|
|
891
|
+
return preserveRedirectDestinationQuery(__basePath && routeContext.basePathState.hadBasePath && !isExternalUrl(redirect.destination) && !hasBasePath(redirect.destination, __basePath) ? __basePath + redirect.destination : redirect.destination, routeContext.search);
|
|
892
|
+
}
|
|
893
|
+
async function applyClientConfigRewrite(href, rewrite) {
|
|
894
|
+
const routeContext = getClientConfigRouteContext(href);
|
|
895
|
+
if (!routeContext) return null;
|
|
896
|
+
const { isExternalUrl, matchRewrite } = await import("../config/config-matchers.js");
|
|
897
|
+
const rewritten = matchRewrite(routeContext.pathname, [rewrite], routeContext.context, routeContext.basePathState);
|
|
898
|
+
if (rewritten === null) return null;
|
|
899
|
+
if (isExternalUrl(rewritten)) return { kind: "document" };
|
|
900
|
+
return {
|
|
901
|
+
href: mergeRewriteQuery(href, rewritten),
|
|
902
|
+
kind: "rewrite"
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
function shouldEvaluateClientConfigRule(ruleBasePath, state) {
|
|
906
|
+
if (!state.basePath) return true;
|
|
907
|
+
return ruleBasePath === false ? !state.hadBasePath : state.hadBasePath;
|
|
908
|
+
}
|
|
909
|
+
function matchSimpleClientConfigPattern(pathname, source) {
|
|
910
|
+
if (source.includes("(") || source.includes("\\") || /:[\w-]+[*+][^/]/.test(source)) return;
|
|
911
|
+
const sourceParts = removeTrailingSlash(source).split("/");
|
|
912
|
+
const pathParts = removeTrailingSlash(pathname).split("/");
|
|
913
|
+
const params = {};
|
|
914
|
+
let pathIndex = 0;
|
|
915
|
+
for (let sourceIndex = 0; sourceIndex < sourceParts.length; sourceIndex++) {
|
|
916
|
+
const sourcePart = sourceParts[sourceIndex];
|
|
917
|
+
const pathPart = pathParts[pathIndex];
|
|
918
|
+
if (sourcePart.startsWith(":")) {
|
|
919
|
+
const catchAll = sourcePart.match(/^:([\w-]+)([*+])$/);
|
|
920
|
+
if (catchAll) {
|
|
921
|
+
const rest = pathParts.slice(pathIndex).join("/");
|
|
922
|
+
if (catchAll[2] === "+" && rest === "") return null;
|
|
923
|
+
params[catchAll[1]] = rest;
|
|
924
|
+
return sourceIndex === sourceParts.length - 1 ? params : void 0;
|
|
925
|
+
}
|
|
926
|
+
if (pathPart === void 0) return null;
|
|
927
|
+
params[sourcePart.slice(1)] = pathPart;
|
|
928
|
+
pathIndex++;
|
|
929
|
+
continue;
|
|
930
|
+
}
|
|
931
|
+
if (pathPart !== sourcePart) return null;
|
|
932
|
+
pathIndex++;
|
|
933
|
+
}
|
|
934
|
+
return pathIndex === pathParts.length ? params : null;
|
|
935
|
+
}
|
|
936
|
+
function simpleClientConfigSourceCouldMatch(pathname, source) {
|
|
937
|
+
const wildcardIndex = source.search(/[:(\\*+?]/);
|
|
938
|
+
const normalizedPrefix = removeTrailingSlash(wildcardIndex === -1 ? source : source.slice(0, wildcardIndex));
|
|
939
|
+
if (!normalizedPrefix || normalizedPrefix === "/") return true;
|
|
940
|
+
const normalizedPathname = removeTrailingSlash(pathname);
|
|
941
|
+
return normalizedPathname === normalizedPrefix || normalizedPathname.startsWith(`${normalizedPrefix}/`);
|
|
942
|
+
}
|
|
943
|
+
function substituteSimpleClientConfigDestination(destination, params) {
|
|
944
|
+
const keys = Object.keys(params);
|
|
945
|
+
if (keys.length === 0) return destination;
|
|
946
|
+
const alternation = keys.sort((a, b) => b.length - a.length).map((key) => key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("|");
|
|
947
|
+
return destination.replace(new RegExp(`:(${alternation})([+*])?(?![A-Za-z0-9_])`, "g"), (_token, key) => params[key] ?? _token);
|
|
948
|
+
}
|
|
949
|
+
function isExternalClientConfigUrl(url) {
|
|
950
|
+
return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith("//");
|
|
951
|
+
}
|
|
952
|
+
function clientConfigRedirectCouldMatch(href) {
|
|
953
|
+
const redirects = window.__VINEXT_CLIENT_REDIRECTS__;
|
|
954
|
+
if (!redirects || redirects.length === 0) return false;
|
|
955
|
+
const routeContext = getClientConfigRouteContext(href);
|
|
956
|
+
if (!routeContext) return false;
|
|
957
|
+
for (const redirect of redirects) {
|
|
958
|
+
if (!shouldEvaluateClientConfigRule(redirect.basePath, routeContext.basePathState)) continue;
|
|
959
|
+
if (!simpleClientConfigSourceCouldMatch(routeContext.pathname, redirect.source)) continue;
|
|
960
|
+
if (matchSimpleClientConfigPattern(routeContext.pathname, redirect.source) !== null) return true;
|
|
961
|
+
}
|
|
962
|
+
return false;
|
|
963
|
+
}
|
|
964
|
+
function resolveClientConfigRewriteSync(href) {
|
|
965
|
+
const rewrites = window.__VINEXT_CLIENT_REWRITES__;
|
|
966
|
+
if (!rewrites) return null;
|
|
967
|
+
let currentHref = href;
|
|
968
|
+
let matched = false;
|
|
969
|
+
for (const rewrite of rewrites.beforeFiles) {
|
|
970
|
+
const routeContext = getClientConfigRouteContext(currentHref);
|
|
971
|
+
if (!routeContext) return null;
|
|
972
|
+
if (!shouldEvaluateClientConfigRule(rewrite.basePath, routeContext.basePathState)) continue;
|
|
973
|
+
if (!simpleClientConfigSourceCouldMatch(routeContext.pathname, rewrite.source)) continue;
|
|
974
|
+
if (rewrite.has || rewrite.missing) return void 0;
|
|
975
|
+
const params = matchSimpleClientConfigPattern(routeContext.pathname, rewrite.source);
|
|
976
|
+
if (params === void 0) return void 0;
|
|
977
|
+
if (params === null) continue;
|
|
978
|
+
const rewritten = substituteSimpleClientConfigDestination(rewrite.destination, params);
|
|
979
|
+
if (isExternalClientConfigUrl(rewritten)) return { kind: "document" };
|
|
980
|
+
currentHref = mergeRewriteQuery(currentHref, rewritten);
|
|
981
|
+
matched = true;
|
|
982
|
+
}
|
|
983
|
+
return matched ? {
|
|
984
|
+
href: currentHref,
|
|
985
|
+
kind: "rewrite"
|
|
986
|
+
} : null;
|
|
987
|
+
}
|
|
988
|
+
async function resolveClientConfigRewrite(href) {
|
|
989
|
+
const rewrites = window.__VINEXT_CLIENT_REWRITES__;
|
|
990
|
+
if (!rewrites) return null;
|
|
991
|
+
let currentHref = href;
|
|
992
|
+
let matched = false;
|
|
993
|
+
for (const rewrite of rewrites.beforeFiles) {
|
|
994
|
+
const result = await applyClientConfigRewrite(currentHref, rewrite);
|
|
995
|
+
if (result?.kind === "document") return result;
|
|
996
|
+
if (result?.kind !== "rewrite") continue;
|
|
997
|
+
currentHref = result.href;
|
|
998
|
+
matched = true;
|
|
999
|
+
}
|
|
1000
|
+
return matched ? {
|
|
1001
|
+
href: currentHref,
|
|
1002
|
+
kind: "rewrite"
|
|
1003
|
+
} : null;
|
|
1004
|
+
}
|
|
1005
|
+
function getMiddlewarePagesDataFetchUrl(browserUrl) {
|
|
1006
|
+
return getPagesMiddlewareDataHref(browserUrl, __basePath);
|
|
1007
|
+
}
|
|
1008
|
+
function getPagesDataCacheHref(dataHref) {
|
|
1009
|
+
try {
|
|
1010
|
+
return new URL(dataHref, window.location.href).href;
|
|
1011
|
+
} catch {
|
|
1012
|
+
return dataHref;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
function shouldEvictMiddlewareDataCache(middlewareEffect, dataTarget) {
|
|
1016
|
+
return middlewareEffect?.redirectLocation != null || dataTarget?.dataKind !== "static";
|
|
862
1017
|
}
|
|
863
1018
|
async function resolveMiddlewareDataEffect(browserUrl, signal) {
|
|
864
1019
|
const dataUrl = getMiddlewarePagesDataFetchUrl(browserUrl);
|
|
865
1020
|
if (!dataUrl) return null;
|
|
866
1021
|
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
|
|
867
1022
|
try {
|
|
868
|
-
const res = await
|
|
1023
|
+
const res = await fetchCachedPagesData(dataUrl, {
|
|
869
1024
|
headers: {
|
|
870
1025
|
Accept: "application/json",
|
|
871
1026
|
"x-nextjs-data": "1"
|
|
@@ -873,6 +1028,7 @@ async function resolveMiddlewareDataEffect(browserUrl, signal) {
|
|
|
873
1028
|
signal
|
|
874
1029
|
});
|
|
875
1030
|
return {
|
|
1031
|
+
dataHref: getPagesDataCacheHref(dataUrl),
|
|
876
1032
|
redirectLocation: res.headers.get("x-nextjs-redirect"),
|
|
877
1033
|
rewriteTarget: res.headers.get("x-nextjs-rewrite"),
|
|
878
1034
|
response: res
|
|
@@ -900,6 +1056,110 @@ function handleDataRedirect(destination, redirectBasePath, mode = "push") {
|
|
|
900
1056
|
if (!(destination.startsWith("/") && redirectBasePath !== false)) scheduleHardNavigationAndThrow(destination, "Navigation redirected externally");
|
|
901
1057
|
performNavigation(destination, void 0, { locale: false }, mode);
|
|
902
1058
|
}
|
|
1059
|
+
async function loadTargetPageModule(target, url, failurePrefix) {
|
|
1060
|
+
try {
|
|
1061
|
+
return await target.loader();
|
|
1062
|
+
} catch (err) {
|
|
1063
|
+
console.error("[vinext] Page loader threw during navigation:", err);
|
|
1064
|
+
scheduleHardNavigationAndThrow(url, `${failurePrefix}: page loader threw`);
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
async function loadPagesAppComponent() {
|
|
1068
|
+
let AppComponent = window.__VINEXT_APP__;
|
|
1069
|
+
if (!AppComponent && typeof window.__VINEXT_APP_LOADER__ === "function") try {
|
|
1070
|
+
const appModule = await window.__VINEXT_APP_LOADER__();
|
|
1071
|
+
AppComponent = isAppComponent(appModule.default) ? appModule.default : void 0;
|
|
1072
|
+
if (AppComponent) window.__VINEXT_APP__ = AppComponent;
|
|
1073
|
+
} catch {}
|
|
1074
|
+
return AppComponent;
|
|
1075
|
+
}
|
|
1076
|
+
function buildPagesNavigationNextData(target, props) {
|
|
1077
|
+
const mergedQuery = mergeRouteParamsIntoQuery(parseQueryString(target.search), target.params);
|
|
1078
|
+
const prev = window.__NEXT_DATA__;
|
|
1079
|
+
const nextLocale = (window.__VINEXT_LOCALES__?.length ?? 0) > 0 ? target.locale ?? window.__VINEXT_DEFAULT_LOCALE__ : prev?.locale;
|
|
1080
|
+
return {
|
|
1081
|
+
...prev,
|
|
1082
|
+
props,
|
|
1083
|
+
page: target.pattern,
|
|
1084
|
+
query: mergedQuery,
|
|
1085
|
+
buildId: target.buildId,
|
|
1086
|
+
isFallback: false,
|
|
1087
|
+
...nextLocale !== void 0 ? { locale: nextLocale } : {}
|
|
1088
|
+
};
|
|
1089
|
+
}
|
|
1090
|
+
function propsObject(value) {
|
|
1091
|
+
return isUnknownRecord(value) ? value : {};
|
|
1092
|
+
}
|
|
1093
|
+
async function loadComponentOnlyProps(PageComponent, AppComponent, target, asPath) {
|
|
1094
|
+
const query = mergeRouteParamsIntoQuery(parseQueryString(target.search), target.params);
|
|
1095
|
+
const ctx = {
|
|
1096
|
+
pathname: target.pattern,
|
|
1097
|
+
query,
|
|
1098
|
+
asPath,
|
|
1099
|
+
locale: target.locale ?? window.__VINEXT_LOCALE__,
|
|
1100
|
+
locales: window.__VINEXT_LOCALES__,
|
|
1101
|
+
defaultLocale: window.__VINEXT_DEFAULT_LOCALE__
|
|
1102
|
+
};
|
|
1103
|
+
if (typeof AppComponent?.getInitialProps === "function") {
|
|
1104
|
+
const AppTree = (appProps) => createElement(AppComponent, {
|
|
1105
|
+
...appProps,
|
|
1106
|
+
Component: PageComponent,
|
|
1107
|
+
router: Router
|
|
1108
|
+
});
|
|
1109
|
+
return propsObject(await AppComponent.getInitialProps({
|
|
1110
|
+
Component: PageComponent,
|
|
1111
|
+
AppTree,
|
|
1112
|
+
ctx,
|
|
1113
|
+
router: Router
|
|
1114
|
+
}));
|
|
1115
|
+
}
|
|
1116
|
+
if (typeof PageComponent.getInitialProps === "function") return { pageProps: propsObject(await PageComponent.getInitialProps(ctx)) };
|
|
1117
|
+
return { pageProps: {} };
|
|
1118
|
+
}
|
|
1119
|
+
async function renderPagesNavigationTarget(url, target, props, options, assertStillCurrent, preloaded) {
|
|
1120
|
+
const pageModule = preloaded?.pageModule ?? await loadTargetPageModule(target, url, "Navigation failed");
|
|
1121
|
+
assertStillCurrent();
|
|
1122
|
+
const PageComponent = pageModule.default;
|
|
1123
|
+
if (!isPageComponent(PageComponent)) scheduleHardNavigationAndThrow(url, "Navigation failed: page module default export is not a component");
|
|
1124
|
+
const AppComponent = preloaded?.appComponent ?? await loadPagesAppComponent();
|
|
1125
|
+
assertStillCurrent();
|
|
1126
|
+
const React = (await import("react")).default;
|
|
1127
|
+
assertStillCurrent();
|
|
1128
|
+
const rawPageProps = props.pageProps;
|
|
1129
|
+
const pageProps = isUnknownRecord(rawPageProps) ? rawPageProps : {};
|
|
1130
|
+
let element;
|
|
1131
|
+
if (AppComponent) element = React.createElement(AppComponent, {
|
|
1132
|
+
...props,
|
|
1133
|
+
Component: PageComponent,
|
|
1134
|
+
pageProps: rawPageProps,
|
|
1135
|
+
router: Router
|
|
1136
|
+
});
|
|
1137
|
+
else element = React.createElement(PageComponent, pageProps);
|
|
1138
|
+
const nextData = buildPagesNavigationNextData(target, props);
|
|
1139
|
+
window.__NEXT_DATA__ = nextData;
|
|
1140
|
+
applyVinextLocaleGlobals(window, nextData);
|
|
1141
|
+
await renderPagesRouterElement(element, options.scroll);
|
|
1142
|
+
assertStillCurrent();
|
|
1143
|
+
}
|
|
1144
|
+
async function navigateClientNoData(url, target, controller, assertStillCurrent, options = {}) {
|
|
1145
|
+
if (!window.__VINEXT_ROOT__) {
|
|
1146
|
+
window.location.href = url;
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
if (controller.signal.aborted) throw new NavigationCancelledError(url);
|
|
1150
|
+
const pageModule = await loadTargetPageModule(target, url, "Navigation failed");
|
|
1151
|
+
assertStillCurrent();
|
|
1152
|
+
const PageComponent = pageModule.default;
|
|
1153
|
+
if (!isPageComponent(PageComponent)) scheduleHardNavigationAndThrow(url, "Navigation failed: page module default export is not a component");
|
|
1154
|
+
const AppComponent = await loadPagesAppComponent();
|
|
1155
|
+
assertStillCurrent();
|
|
1156
|
+
const props = await loadComponentOnlyProps(PageComponent, AppComponent, target, url);
|
|
1157
|
+
assertStillCurrent();
|
|
1158
|
+
await renderPagesNavigationTarget(url, target, props, options, assertStillCurrent, {
|
|
1159
|
+
appComponent: AppComponent,
|
|
1160
|
+
pageModule
|
|
1161
|
+
});
|
|
1162
|
+
}
|
|
903
1163
|
/**
|
|
904
1164
|
* Perform client-side navigation via the `/_next/data/<id>/<page>.json`
|
|
905
1165
|
* endpoint. Used when `__VINEXT_PAGE_LOADERS__` has a matching code-split
|
|
@@ -927,7 +1187,7 @@ async function navigateClientData(url, initialTarget, controller, navId, assertS
|
|
|
927
1187
|
};
|
|
928
1188
|
const deploymentId = getDeploymentId();
|
|
929
1189
|
if (deploymentId) headers[NEXT_DEPLOYMENT_ID_HEADER] = deploymentId;
|
|
930
|
-
res = await dedupedPagesDataFetch(initialTarget.dataHref, {
|
|
1190
|
+
res = await (initialTarget.dataKind === "static" ? fetchStaticPagesData : dedupedPagesDataFetch)(initialTarget.dataHref, {
|
|
931
1191
|
headers,
|
|
932
1192
|
signal: controller.signal
|
|
933
1193
|
});
|
|
@@ -936,6 +1196,9 @@ async function navigateClientData(url, initialTarget, controller, navId, assertS
|
|
|
936
1196
|
throw err;
|
|
937
1197
|
}
|
|
938
1198
|
assertStillCurrent();
|
|
1199
|
+
const responseDeploymentId = res.headers.get("x-nextjs-deployment-id");
|
|
1200
|
+
const currentDeploymentId = getDeploymentId() ?? null;
|
|
1201
|
+
if (responseDeploymentId !== null && responseDeploymentId !== currentDeploymentId) scheduleHardNavigationAndThrow(url, "Loaded static props were from an outdated deployment");
|
|
939
1202
|
const softRedirect = res.headers.get("x-nextjs-redirect");
|
|
940
1203
|
if (softRedirect) {
|
|
941
1204
|
const redirectedUrl = resolveLocalRedirectUrl(softRedirect);
|
|
@@ -960,54 +1223,13 @@ async function navigateClientData(url, initialTarget, controller, navId, assertS
|
|
|
960
1223
|
const props = isUnknownRecord(body) ? body : {};
|
|
961
1224
|
const rawPageProps = props.pageProps;
|
|
962
1225
|
const pageProps = isUnknownRecord(rawPageProps) ? rawPageProps : {};
|
|
1226
|
+
if (initialTarget.dataKind === "server") evictPagesDataCache(initialTarget.dataHref);
|
|
963
1227
|
const redirectDestination = pageProps.__N_REDIRECT;
|
|
964
1228
|
if (typeof redirectDestination === "string") {
|
|
965
1229
|
handleDataRedirect(redirectDestination, pageProps.__N_REDIRECT_BASE_PATH, options.mode);
|
|
966
1230
|
throw new NavigationCancelledError(url);
|
|
967
1231
|
}
|
|
968
|
-
|
|
969
|
-
try {
|
|
970
|
-
pageModule = await target.loader();
|
|
971
|
-
} catch (err) {
|
|
972
|
-
console.error("[vinext] Page loader threw during navigation:", err);
|
|
973
|
-
scheduleHardNavigationAndThrow(url, "Data navigation failed: page loader threw");
|
|
974
|
-
}
|
|
975
|
-
assertStillCurrent();
|
|
976
|
-
const PageComponent = pageModule.default;
|
|
977
|
-
if (!isPageComponent(PageComponent)) scheduleHardNavigationAndThrow(url, "Data navigation failed: page module default export is not a component");
|
|
978
|
-
let AppComponent = window.__VINEXT_APP__;
|
|
979
|
-
if (!AppComponent && typeof window.__VINEXT_APP_LOADER__ === "function") try {
|
|
980
|
-
const appModule = await window.__VINEXT_APP_LOADER__();
|
|
981
|
-
AppComponent = isAppComponent(appModule.default) ? appModule.default : void 0;
|
|
982
|
-
if (AppComponent) window.__VINEXT_APP__ = AppComponent;
|
|
983
|
-
} catch {}
|
|
984
|
-
assertStillCurrent();
|
|
985
|
-
const React = (await import("react")).default;
|
|
986
|
-
assertStillCurrent();
|
|
987
|
-
let element;
|
|
988
|
-
if (AppComponent) element = React.createElement(AppComponent, {
|
|
989
|
-
...props,
|
|
990
|
-
Component: PageComponent,
|
|
991
|
-
pageProps: rawPageProps,
|
|
992
|
-
router: Router
|
|
993
|
-
});
|
|
994
|
-
else element = React.createElement(PageComponent, pageProps);
|
|
995
|
-
const mergedQuery = mergeRouteParamsIntoQuery(parseQueryString(target.search), target.params);
|
|
996
|
-
const prev = window.__NEXT_DATA__;
|
|
997
|
-
const nextLocale = (window.__VINEXT_LOCALES__?.length ?? 0) > 0 ? target.locale ?? window.__VINEXT_DEFAULT_LOCALE__ : prev?.locale;
|
|
998
|
-
const nextData = {
|
|
999
|
-
...prev,
|
|
1000
|
-
props,
|
|
1001
|
-
page: target.pattern,
|
|
1002
|
-
query: mergedQuery,
|
|
1003
|
-
buildId: target.buildId,
|
|
1004
|
-
isFallback: false,
|
|
1005
|
-
...nextLocale !== void 0 ? { locale: nextLocale } : {}
|
|
1006
|
-
};
|
|
1007
|
-
window.__NEXT_DATA__ = nextData;
|
|
1008
|
-
applyVinextLocaleGlobals(window, nextData);
|
|
1009
|
-
await renderPagesRouterElement(element, options.scroll);
|
|
1010
|
-
assertStillCurrent();
|
|
1232
|
+
await renderPagesNavigationTarget(url, target, props, options, assertStillCurrent);
|
|
1011
1233
|
}
|
|
1012
1234
|
/**
|
|
1013
1235
|
* Perform client-side navigation by fetching the page's full HTML and
|
|
@@ -1130,6 +1352,7 @@ async function navigateClient(url, fetchUrl = url, options = {}, routeUrl = url)
|
|
|
1130
1352
|
const controller = new AbortController();
|
|
1131
1353
|
routerRuntimeState.activeAbortController = controller;
|
|
1132
1354
|
const navId = ++routerRuntimeState.navigationId;
|
|
1355
|
+
let middlewareDataCacheEvictHref = null;
|
|
1133
1356
|
/** Check if this navigation is still the active one. If not, throw. */
|
|
1134
1357
|
function assertStillCurrent() {
|
|
1135
1358
|
if (navId !== routerRuntimeState.navigationId) throw new NavigationCancelledError(url);
|
|
@@ -1139,36 +1362,70 @@ async function navigateClient(url, fetchUrl = url, options = {}, routeUrl = url)
|
|
|
1139
1362
|
else {
|
|
1140
1363
|
let browserUrl = url;
|
|
1141
1364
|
let htmlFetchUrl = fetchUrl;
|
|
1142
|
-
|
|
1365
|
+
const configRedirect = hasClientRedirectRules() && clientConfigRedirectCouldMatch(browserUrl) ? await resolveClientConfigRedirect(browserUrl) : null;
|
|
1366
|
+
if (configRedirect) {
|
|
1367
|
+
const redirectedUrl = resolveLocalRedirectUrl(configRedirect);
|
|
1368
|
+
if (!redirectedUrl) scheduleHardNavigationAndThrow(configRedirect, "Navigation redirected externally");
|
|
1369
|
+
window.history.replaceState(window.history.state ?? {}, "", redirectedUrl);
|
|
1370
|
+
routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
|
|
1371
|
+
routerRuntimeState.lastHash = window.location.hash;
|
|
1372
|
+
browserUrl = redirectedUrl;
|
|
1373
|
+
htmlFetchUrl = redirectedUrl;
|
|
1374
|
+
}
|
|
1375
|
+
let routeLookupUrl = configRedirect ? browserUrl : routeUrl;
|
|
1376
|
+
if (routeUrl === url && hasClientRewriteRules()) {
|
|
1377
|
+
const syncConfigRewrite = hasClientAppRouteManifest() ? void 0 : resolveClientConfigRewriteSync(browserUrl);
|
|
1378
|
+
const configRewrite = syncConfigRewrite === void 0 ? await resolveClientConfigRewrite(browserUrl) : syncConfigRewrite;
|
|
1379
|
+
if (configRewrite?.kind === "document") scheduleHardNavigationAndThrow(browserUrl, "Navigation rewritten to a document route");
|
|
1380
|
+
else if (configRewrite?.kind === "rewrite") {
|
|
1381
|
+
routeLookupUrl = configRewrite.href;
|
|
1382
|
+
htmlFetchUrl = configRewrite.href;
|
|
1383
|
+
}
|
|
1384
|
+
}
|
|
1385
|
+
let dataTarget = resolvePagesDataNavigationTarget(routeLookupUrl, __basePath);
|
|
1143
1386
|
let middlewareDataResponse;
|
|
1144
|
-
|
|
1145
|
-
|
|
1387
|
+
let middlewareEffect = null;
|
|
1388
|
+
let middlewareRewrittenTarget;
|
|
1389
|
+
const middlewareProbeDataHref = getMiddlewarePagesDataFetchUrl(browserUrl);
|
|
1390
|
+
if (middlewareProbeDataHref !== null) {
|
|
1391
|
+
middlewareDataCacheEvictHref = getPagesDataCacheHref(middlewareProbeDataHref);
|
|
1146
1392
|
try {
|
|
1147
1393
|
middlewareEffect = await resolveMiddlewareDataEffect(browserUrl, controller.signal);
|
|
1148
1394
|
} catch (err) {
|
|
1149
1395
|
if (err instanceof DOMException && err.name === "AbortError") throw new NavigationCancelledError(browserUrl);
|
|
1150
1396
|
throw err;
|
|
1151
1397
|
}
|
|
1398
|
+
if (middlewareEffect?.rewriteTarget) middlewareRewrittenTarget = resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath);
|
|
1399
|
+
if (middlewareEffect) if (shouldEvictMiddlewareDataCache(middlewareEffect, middlewareRewrittenTarget !== void 0 ? middlewareRewrittenTarget : dataTarget)) middlewareDataCacheEvictHref = middlewareEffect.dataHref;
|
|
1400
|
+
else middlewareDataCacheEvictHref = null;
|
|
1152
1401
|
assertStillCurrent();
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1402
|
+
}
|
|
1403
|
+
const redirectLocation = middlewareEffect?.redirectLocation ?? null;
|
|
1404
|
+
if (redirectLocation) {
|
|
1405
|
+
const redirectedUrl = resolveLocalRedirectUrl(redirectLocation);
|
|
1406
|
+
if (!redirectedUrl) scheduleHardNavigationAndThrow(redirectLocation, "Navigation redirected externally");
|
|
1407
|
+
window.history.replaceState(window.history.state ?? {}, "", redirectedUrl);
|
|
1408
|
+
routerRuntimeState.lastPathnameAndSearch = window.location.pathname + window.location.search;
|
|
1409
|
+
routerRuntimeState.lastHash = window.location.hash;
|
|
1410
|
+
browserUrl = redirectedUrl;
|
|
1411
|
+
htmlFetchUrl = redirectedUrl;
|
|
1412
|
+
} else if (middlewareEffect) {
|
|
1413
|
+
if (middlewareEffect.rewriteTarget || routeUrl === url) middlewareDataResponse = middlewareEffect.response;
|
|
1414
|
+
if (middlewareEffect.rewriteTarget) {
|
|
1415
|
+
const rewrittenTarget = middlewareRewrittenTarget ?? resolvePagesDataNavigationTarget(middlewareEffect.rewriteTarget, __basePath);
|
|
1416
|
+
if (!rewrittenTarget) scheduleHardNavigationAndThrow(browserUrl, "Navigation rewritten to a non-Pages route");
|
|
1417
|
+
dataTarget = rewrittenTarget;
|
|
1165
1418
|
}
|
|
1166
1419
|
}
|
|
1167
|
-
if (
|
|
1420
|
+
if (middlewareEffect && shouldEvictMiddlewareDataCache(middlewareEffect, dataTarget)) middlewareDataCacheEvictHref = middlewareEffect.dataHref;
|
|
1421
|
+
else if (middlewareEffect) middlewareDataCacheEvictHref = null;
|
|
1422
|
+
if (dataTarget?.dataKind === "static" || dataTarget?.dataKind === "server") await navigateClientData(browserUrl, dataTarget, controller, navId, assertStillCurrent, options, middlewareDataResponse);
|
|
1423
|
+
else if (dataTarget) await navigateClientNoData(browserUrl, dataTarget, controller, assertStillCurrent, options);
|
|
1168
1424
|
else await navigateClientHtml(browserUrl, htmlFetchUrl, controller, navId, assertStillCurrent, options);
|
|
1169
1425
|
}
|
|
1170
1426
|
} finally {
|
|
1171
1427
|
if (navId === routerRuntimeState.navigationId) routerRuntimeState.activeAbortController = null;
|
|
1428
|
+
if (middlewareDataCacheEvictHref !== null) evictPagesDataCache(middlewareDataCacheEvictHref);
|
|
1172
1429
|
}
|
|
1173
1430
|
}
|
|
1174
1431
|
/**
|
|
@@ -1391,7 +1648,14 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
|
|
|
1391
1648
|
const appPath = getLocalPathname(resolved);
|
|
1392
1649
|
const appPathNorm = appPath !== null ? removeTrailingSlash(appPath) : null;
|
|
1393
1650
|
const appPathEntry = appPathNorm !== null ? getPagesRouterComponentsMap()[appPathNorm] : void 0;
|
|
1394
|
-
if (appPathEntry !== void 0 && "__appRouter" in appPathEntry && appPathEntry.__appRouter
|
|
1651
|
+
if (appPathEntry !== void 0 && "__appRouter" in appPathEntry && appPathEntry.__appRouter) {
|
|
1652
|
+
if (mode === "push") window.location.assign(full);
|
|
1653
|
+
else window.location.replace(full);
|
|
1654
|
+
return new Promise(() => {});
|
|
1655
|
+
}
|
|
1656
|
+
const rewrites = window.__VINEXT_CLIENT_REWRITES__;
|
|
1657
|
+
const hybridOwner = rewrites && (rewrites.beforeFiles.length > 0 || rewrites.afterFiles.length > 0 || rewrites.fallback.length > 0) && hasClientAppRouteManifest() ? (await import("./internal/hybrid-client-route-owner.js")).resolveHybridClientRouteOwner(resolved, __basePath) : resolveDirectHybridClientRouteOwner(resolved, __basePath);
|
|
1658
|
+
if (["app", "document"].includes(hybridOwner ?? "")) {
|
|
1395
1659
|
if (mode === "push") window.location.assign(full);
|
|
1396
1660
|
else window.location.replace(full);
|
|
1397
1661
|
return new Promise(() => {});
|
|
@@ -1417,12 +1681,11 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
|
|
|
1417
1681
|
* Prefetch the resources needed for a future Pages Router navigation.
|
|
1418
1682
|
*
|
|
1419
1683
|
* When the client has a registered code-split loader for the target route
|
|
1420
|
-
* (the prod hot path), we
|
|
1421
|
-
*
|
|
1422
|
-
*
|
|
1423
|
-
*
|
|
1424
|
-
*
|
|
1425
|
-
* the returned Promise is intentionally discarded.
|
|
1684
|
+
* (the prod hot path), we warm the page's JS chunk by invoking the loader
|
|
1685
|
+
* thunk now. Vite's dynamic `import()` machinery is responsible for fetching
|
|
1686
|
+
* and caching it; the returned Promise is intentionally discarded. SSG routes
|
|
1687
|
+
* also prefetch their `/_next/data/<buildId>/<page>.json` payload, matching
|
|
1688
|
+
* Next.js's Pages Router `_isSsg(route)` gate.
|
|
1426
1689
|
*
|
|
1427
1690
|
* When no loader is registered (dev server, or an unmapped route), we fall
|
|
1428
1691
|
* back to the legacy `<link rel="prefetch" as="document">` hint, which lets
|
|
@@ -1432,17 +1695,22 @@ async function performNavigation(url, as, options, mode, onStateUpdate) {
|
|
|
1432
1695
|
* Ported from Next.js: `packages/next/src/client/page-loader.ts` `prefetch`
|
|
1433
1696
|
* (the data + chunk parallel prefetch shape).
|
|
1434
1697
|
*/
|
|
1435
|
-
async function prefetchUrl(url) {
|
|
1698
|
+
async function prefetchUrl(url, as) {
|
|
1436
1699
|
if (typeof document === "undefined") return;
|
|
1700
|
+
const displayUrl = as ?? url;
|
|
1437
1701
|
const dataTarget = resolvePagesDataNavigationTarget(url, __basePath);
|
|
1438
1702
|
if (dataTarget) {
|
|
1439
|
-
|
|
1703
|
+
const middlewareDataHref = displayUrl === url ? dataTarget.middlewareDataHref : getPagesMiddlewareDataHref(displayUrl, __basePath) ?? void 0;
|
|
1704
|
+
prefetchPagesData({
|
|
1705
|
+
...dataTarget,
|
|
1706
|
+
middlewareDataHref
|
|
1707
|
+
});
|
|
1440
1708
|
return;
|
|
1441
1709
|
}
|
|
1442
|
-
markAppRouteDetectedOnPrefetch(
|
|
1710
|
+
await markAppRouteDetectedOnPrefetch(displayUrl, __basePath);
|
|
1443
1711
|
const link = document.createElement("link");
|
|
1444
1712
|
link.rel = "prefetch";
|
|
1445
|
-
link.href =
|
|
1713
|
+
link.href = displayUrl;
|
|
1446
1714
|
link.as = "document";
|
|
1447
1715
|
document.head.appendChild(link);
|
|
1448
1716
|
}
|
|
@@ -1654,6 +1922,7 @@ function withRouter(ComposedComponent) {
|
|
|
1654
1922
|
const RouterMethods = {
|
|
1655
1923
|
/** See `_components` comment above for the dual role this map plays. */
|
|
1656
1924
|
components: getPagesRouterComponentsMap(),
|
|
1925
|
+
sdc: getPagesStaticDataCache(),
|
|
1657
1926
|
push: (url, as, options) => {
|
|
1658
1927
|
if (typeof window === "undefined") throwNoRouterInstance();
|
|
1659
1928
|
assertSafeNavigationUrl(resolveUrl(url));
|
|
@@ -1674,9 +1943,9 @@ const RouterMethods = {
|
|
|
1674
1943
|
if (typeof window === "undefined") throwNoRouterInstance();
|
|
1675
1944
|
window.location.reload();
|
|
1676
1945
|
},
|
|
1677
|
-
prefetch: (url) => {
|
|
1946
|
+
prefetch: (url, as) => {
|
|
1678
1947
|
if (typeof window === "undefined") throwNoRouterInstance();
|
|
1679
|
-
return prefetchUrl(url);
|
|
1948
|
+
return prefetchUrl(url, as);
|
|
1680
1949
|
},
|
|
1681
1950
|
beforePopState: (cb) => {
|
|
1682
1951
|
if (typeof window === "undefined") throwNoRouterInstance();
|
package/dist/shims/server.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { hasBasePath, stripBasePath } from "../utils/base-path.js";
|
|
2
2
|
import { getRequestExecutionContext } from "./request-context.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { MIDDLEWARE_SET_COOKIE_HEADER } from "../utils/protocol-headers.js";
|
|
4
|
+
import { MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER } from "../server/headers.js";
|
|
5
|
+
import { encodeMiddlewareRequestHeaders } from "../utils/middleware-request-headers.js";
|
|
5
6
|
import { serializeSetCookie, validateCookieName } from "./internal/cookie-serialize.js";
|
|
6
7
|
import { parseEdgeRequestCookieHeader } from "../utils/parse-cookie.js";
|
|
7
8
|
import { assertSafeNavigationUrl } from "./url-safety.js";
|
package/dist/shims/slot.js
CHANGED
|
@@ -166,12 +166,9 @@ function mergeElements(prev, next, options = {}) {
|
|
|
166
166
|
const preserveElementIds = typeof options === "boolean" ? [] : options.preserveElementIds ?? [];
|
|
167
167
|
const preservePreviousSlotIds = typeof options === "boolean" ? [] : options.preservePreviousSlotIds ?? [];
|
|
168
168
|
const merged = { ...next };
|
|
169
|
-
for (const id of preserveElementIds) {
|
|
170
|
-
|
|
171
|
-
if (
|
|
172
|
-
const value = prev[id];
|
|
173
|
-
if (value !== void 0) merged[id] = value;
|
|
174
|
-
}
|
|
169
|
+
for (const id of preserveElementIds) if (Object.hasOwn(prev, id)) {
|
|
170
|
+
const value = prev[id];
|
|
171
|
+
if (value !== void 0) merged[id] = value;
|
|
175
172
|
}
|
|
176
173
|
const slotKeys = new Set([...Object.keys(prev), ...Object.keys(next)].filter((key) => AppElementsWire.isSlotId(key)));
|
|
177
174
|
if (clearAbsentSlots) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
//#region src/utils/client-runtime-metadata.d.ts
|
|
2
2
|
type ClientRuntimeMetadata = {
|
|
3
3
|
clientEntryFile?: string;
|
|
4
|
+
appBootstrapPreinitModules?: string[];
|
|
4
5
|
lazyChunks?: string[];
|
|
5
6
|
dynamicPreloads?: Record<string, string[]>;
|
|
6
7
|
};
|
|
@@ -24,22 +25,5 @@ declare function computeClientRuntimeMetadata(opts: {
|
|
|
24
25
|
assetPrefix: string;
|
|
25
26
|
includeClientEntry?: boolean | "pages-client-entry";
|
|
26
27
|
}): ClientRuntimeMetadata;
|
|
27
|
-
/**
|
|
28
|
-
* Serialize runtime metadata into the `globalThis.__VINEXT_*` assignment script
|
|
29
|
-
* that the Cloudflare `closeBundle` hook prepends to the worker entry. Returns
|
|
30
|
-
* `""` when there is nothing to inject.
|
|
31
|
-
*
|
|
32
|
-
* Both the App Router and Pages Router closeBundle paths call this (and the
|
|
33
|
-
* deploy tests mirror it), so the injection shape stays in one place. The caller
|
|
34
|
-
* decides which fields to pass — e.g. App Router only forwards `clientEntryFile`
|
|
35
|
-
* for mixed app+pages builds (where `computeClientRuntimeMetadata` was asked for
|
|
36
|
-
* the Pages client entry); pure App Router leaves it undefined.
|
|
37
|
-
*/
|
|
38
|
-
declare function buildRuntimeGlobalsScript(input: {
|
|
39
|
-
clientEntryFile?: string | null;
|
|
40
|
-
ssrManifest?: Record<string, string[]> | null;
|
|
41
|
-
lazyChunks?: string[] | null;
|
|
42
|
-
dynamicPreloads?: Record<string, string[]> | null;
|
|
43
|
-
}): string;
|
|
44
28
|
//#endregion
|
|
45
|
-
export {
|
|
29
|
+
export { computeClientRuntimeMetadata };
|