vinext 1.2.0 → 1.3.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 +13 -10
- package/dist/build/client-build-config.d.ts +64 -3
- package/dist/build/client-build-config.js +131 -4
- package/dist/build/client-reference-groups.d.ts +163 -0
- package/dist/build/client-reference-groups.js +534 -0
- package/dist/build/module-dependency-cache.d.ts +31 -0
- package/dist/build/module-dependency-cache.js +51 -1
- package/dist/build/next-client-runtime-manifests.d.ts +10 -1
- package/dist/build/next-client-runtime-manifests.js +19 -4
- package/dist/build/nitro-public-files.d.ts +24 -0
- package/dist/build/nitro-public-files.js +60 -0
- package/dist/build/output-root-externals.d.ts +21 -0
- package/dist/build/output-root-externals.js +40 -0
- package/dist/build/pages-client-assets-module.js +1 -1
- package/dist/build/prerender-paths.js +6 -3
- package/dist/build/prerender.js +1 -1
- package/dist/build/server-actions-encryption-key.d.ts +23 -0
- package/dist/build/server-actions-encryption-key.js +101 -0
- package/dist/build/ssr-manifest.d.ts +3 -0
- package/dist/build/ssr-manifest.js +10 -1
- package/dist/check.js +5 -6
- package/dist/cli-dev-config.js +3 -3
- package/dist/cli.js +1 -1
- package/dist/client/client-rewrite-params.d.ts +9 -0
- package/dist/client/client-rewrite-params.js +20 -0
- package/dist/client/dev-error-overlay.js +2 -1
- package/dist/client/navigation-runtime.d.ts +25 -2
- package/dist/client/navigation-runtime.js +42 -11
- package/dist/client/vinext-next-data.d.ts +0 -1
- package/dist/config/config-matchers.d.ts +15 -40
- package/dist/config/config-matchers.js +195 -262
- package/dist/config/config-source.d.ts +34 -0
- package/dist/config/config-source.js +141 -0
- package/dist/config/header-params.d.ts +29 -0
- package/dist/config/header-params.js +106 -0
- package/dist/config/next-config.d.ts +7 -5
- package/dist/config/next-config.js +120 -7
- package/dist/entries/app-browser-entry.d.ts +14 -1
- package/dist/entries/app-browser-entry.js +26 -36
- package/dist/entries/app-rsc-entry.d.ts +2 -0
- package/dist/entries/app-rsc-entry.js +92 -57
- package/dist/entries/app-rsc-manifest.d.ts +10 -0
- package/dist/entries/app-rsc-manifest.js +20 -1
- package/dist/entries/app-ssr-entry.d.ts +4 -1
- package/dist/entries/app-ssr-entry.js +9 -2
- package/dist/entries/pages-client-entry.d.ts +1 -0
- package/dist/entries/pages-client-entry.js +6 -6
- package/dist/entries/pages-server-entry.js +17 -14
- package/dist/index.d.ts +11 -0
- package/dist/index.js +350 -175
- package/dist/init.d.ts +1 -1
- package/dist/init.js +103 -6
- package/dist/plugins/ast-utils.d.ts +53 -2
- package/dist/plugins/ast-utils.js +90 -2
- package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
- package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
- package/dist/plugins/commonjs-esm-facade.js +2 -2
- package/dist/plugins/css-module-imports.js +13 -20
- package/dist/plugins/dynamic-preload-metadata.js +2 -3
- package/dist/plugins/extensionless-dynamic-import.js +2 -3
- package/dist/plugins/fonts.d.ts +1 -1
- package/dist/plugins/fonts.js +3 -3
- package/dist/plugins/ignore-dynamic-requests.js +2 -3
- package/dist/plugins/import-meta-url.js +3 -4
- package/dist/plugins/instrumentation-client.js +3 -2
- package/dist/plugins/middleware-export-validation.js +2 -3
- package/dist/plugins/og-harfbuzz.js +2 -3
- package/dist/plugins/optimize-imports.d.ts +25 -2
- package/dist/plugins/optimize-imports.js +109 -24
- package/dist/plugins/pages-node-externals.js +2 -3
- package/dist/plugins/remove-console.js +2 -18
- package/dist/plugins/require-condition-resolution.js +3 -3
- package/dist/plugins/require-context.js +2 -3
- package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
- package/dist/plugins/rsc-client-reference-loaders.js +336 -18
- package/dist/plugins/strip-server-exports.js +3 -4
- package/dist/plugins/styled-jsx.js +2 -3
- package/dist/plugins/use-cache-callable.d.ts +26 -2
- package/dist/plugins/use-cache-callable.js +101 -36
- package/dist/plugins/worker-image-imports.d.ts +1 -0
- package/dist/plugins/worker-image-imports.js +31 -34
- package/dist/plugins/worker-use-server.js +38 -14
- package/dist/routing/app-route-graph.d.ts +1 -1
- package/dist/routing/browser-route-manifest.d.ts +43 -0
- package/dist/routing/browser-route-manifest.js +195 -0
- package/dist/routing/hashed-route-patterns.d.ts +4 -0
- package/dist/routing/hashed-route-patterns.js +22 -0
- package/dist/routing/optimistic-route-trie.d.ts +27 -0
- package/dist/routing/optimistic-route-trie.js +102 -0
- package/dist/routing/route-validation.d.ts +6 -1
- package/dist/routing/route-validation.js +26 -10
- package/dist/server/api-handler.js +1 -1
- package/dist/server/app-action-forwarding.d.ts +8 -0
- package/dist/server/app-action-forwarding.js +17 -3
- package/dist/server/app-browser-entry.js +149 -62
- package/dist/server/app-browser-error.d.ts +3 -1
- package/dist/server/app-browser-error.js +7 -2
- package/dist/server/app-browser-interception-context.d.ts +2 -2
- package/dist/server/app-browser-interception-context.js +1 -1
- package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
- package/dist/server/app-browser-mpa-navigation.js +6 -5
- package/dist/server/app-browser-navigation-controller.d.ts +17 -6
- package/dist/server/app-browser-navigation-controller.js +88 -26
- package/dist/server/app-browser-prefetch-response.js +2 -2
- package/dist/server/app-browser-state.d.ts +2 -2
- package/dist/server/app-browser-state.js +1 -1
- package/dist/server/app-browser-supplemental-refresh.js +1 -1
- package/dist/server/app-browser-visible-commit.d.ts +4 -4
- package/dist/server/app-client-reference-preloader.d.ts +23 -0
- package/dist/server/app-client-reference-preloader.js +30 -7
- package/dist/server/app-fallback-renderer.js +2 -1
- package/dist/server/app-middleware.d.ts +6 -0
- package/dist/server/app-middleware.js +8 -10
- package/dist/server/app-optimistic-routing.d.ts +8 -10
- package/dist/server/app-optimistic-routing.js +4 -95
- package/dist/server/app-page-boundary-render.js +8 -1
- package/dist/server/app-page-cache-render.js +1 -0
- package/dist/server/app-page-dispatch.js +3 -1
- package/dist/server/app-page-render.js +4 -2
- package/dist/server/app-page-rsc-render-status.d.ts +1 -0
- package/dist/server/app-page-rsc-render-status.js +1 -0
- package/dist/server/app-page-search-params-observation.d.ts +1 -4
- package/dist/server/app-page-search-params-observation.js +8 -10
- package/dist/server/app-page-stream.d.ts +7 -0
- package/dist/server/app-page-stream.js +1 -0
- package/dist/server/app-pages-bridge.d.ts +2 -1
- package/dist/server/app-pages-bridge.js +12 -8
- package/dist/server/app-prerender-endpoints.js +1 -1
- package/dist/server/app-prerender-static-params.js +3 -2
- package/dist/server/app-render-abort-error.d.ts +19 -0
- package/dist/server/app-render-abort-error.js +31 -1
- package/dist/server/app-render-dependency.js +42 -2
- package/dist/server/app-request-stage-independent-entry.js +7 -7
- package/dist/server/app-response-stage-entry.js +5 -5
- package/dist/server/app-route-handler-dispatch.js +3 -1
- package/dist/server/app-route-handler-execution.d.ts +2 -0
- package/dist/server/app-route-handler-execution.js +9 -2
- package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
- package/dist/server/app-route-handler-middleware-context.js +3 -3
- package/dist/server/app-route-handler-response.d.ts +2 -1
- package/dist/server/app-route-handler-response.js +2 -2
- package/dist/server/app-route-handler-runtime.d.ts +2 -0
- package/dist/server/app-route-handler-runtime.js +21 -4
- package/dist/server/app-route-module-loader.js +7 -6
- package/dist/server/app-route-tree.d.ts +20 -0
- package/dist/server/app-route-tree.js +18 -0
- package/dist/server/app-router-entry.js +7 -7
- package/dist/server/app-rsc-cache-busting.d.ts +16 -0
- package/dist/server/app-rsc-cache-busting.js +29 -12
- package/dist/server/app-rsc-combined-handler.js +8 -1
- package/dist/server/app-rsc-errors.d.ts +7 -0
- package/dist/server/app-rsc-errors.js +9 -2
- package/dist/server/app-rsc-handler.d.ts +4 -1
- package/dist/server/app-rsc-handler.js +151 -135
- package/dist/server/app-rsc-request-normalization.js +3 -3
- package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
- package/dist/server/app-rsc-response-finalizer.js +4 -1
- package/dist/server/app-rsc-response-stage.js +5 -3
- package/dist/server/app-rsc-route-matching.d.ts +1 -0
- package/dist/server/app-rsc-route-matching.js +1 -1
- package/dist/server/app-server-action-execution.d.ts +23 -6
- package/dist/server/app-server-action-execution.js +51 -57
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +21 -11
- package/dist/server/app-ssr-stream.d.ts +7 -0
- package/dist/server/app-ssr-stream.js +13 -1
- package/dist/server/app-visited-response-cache.js +2 -2
- package/dist/server/config-headers.js +13 -4
- package/dist/server/defer-until-stream-consumed.d.ts +2 -1
- package/dist/server/defer-until-stream-consumed.js +3 -1
- package/dist/server/dev-server.js +1 -1
- package/dist/server/image-optimization.js +1 -0
- package/dist/server/isolate-shared-promise.d.ts +10 -0
- package/dist/server/isolate-shared-promise.js +33 -0
- package/dist/server/isr-cache.js +3 -2
- package/dist/server/metadata-route-response.js +2 -2
- package/dist/server/middleware-matcher-pattern.d.ts +0 -1
- package/dist/server/middleware-matcher-pattern.js +11 -140
- package/dist/server/middleware-matcher.js +5 -6
- package/dist/server/middleware-response-headers.d.ts +31 -0
- package/dist/server/middleware-response-headers.js +57 -1
- package/dist/server/middleware-runtime.js +30 -17
- package/dist/server/navigation-planner.d.ts +2 -2
- package/dist/server/navigation-planner.js +1 -1
- package/dist/server/nitro-public-files-plugin.d.ts +38 -0
- package/dist/server/nitro-public-files-plugin.js +106 -0
- package/dist/server/nitro-public-files.d.ts +21 -0
- package/dist/server/nitro-public-files.js +39 -0
- package/dist/server/open-redirect.d.ts +11 -4
- package/dist/server/open-redirect.js +11 -4
- package/dist/server/pages-api-route.js +2 -2
- package/dist/server/pages-asset-tags.d.ts +5 -0
- package/dist/server/pages-asset-tags.js +9 -2
- package/dist/server/pages-client-assets.d.ts +4 -1
- package/dist/server/pages-data-route.js +2 -1
- package/dist/server/pages-i18n.d.ts +18 -0
- package/dist/server/pages-i18n.js +18 -2
- package/dist/server/pages-node-compat.d.ts +5 -3
- package/dist/server/pages-node-compat.js +35 -16
- package/dist/server/pages-page-data.js +1 -1
- package/dist/server/pages-page-handler.js +1 -1
- package/dist/server/pages-page-response.js +1 -1
- package/dist/server/pages-request-pipeline.d.ts +6 -1
- package/dist/server/pages-request-pipeline.js +35 -39
- package/dist/server/pages-request-stage-entry.js +20 -10
- package/dist/server/pages-response-stage-entry.js +1 -1
- package/dist/server/pages-revalidate.js +3 -2
- package/dist/server/pages-router-entry.js +2 -2
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +74 -36
- package/dist/server/proxy-trust.d.ts +6 -0
- package/dist/server/proxy-trust.js +12 -6
- package/dist/server/request-pipeline.d.ts +5 -0
- package/dist/server/request-pipeline.js +12 -1
- package/dist/server/rsc-stream-hints.d.ts +1 -1
- package/dist/server/rsc-stream-hints.js +21 -3
- package/dist/server/server-reference-loader.js +10 -1
- package/dist/server/static-file-cache.js +15 -3
- package/dist/server/worker-image-optimization.js +19 -6
- package/dist/server/worker-utils.js +1 -1
- package/dist/shims/cache-handler.js +3 -2
- package/dist/shims/cache-request-state.d.ts +40 -3
- package/dist/shims/cache-request-state.js +70 -5
- package/dist/shims/cache-runtime.js +47 -19
- package/dist/shims/cache.d.ts +2 -2
- package/dist/shims/cache.js +17 -8
- package/dist/shims/cdn-purge-routes.d.ts +24 -0
- package/dist/shims/cdn-purge-routes.js +77 -0
- package/dist/shims/dynamic.js +17 -4
- package/dist/shims/form.js +8 -3
- package/dist/shims/head.js +1 -1
- package/dist/shims/headers.js +2 -2
- package/dist/shims/image-props.d.ts +93 -0
- package/dist/shims/image-props.js +323 -0
- package/dist/shims/image.d.ts +4 -18
- package/dist/shims/image.js +4 -319
- package/dist/shims/internal/headers-state.d.ts +7 -0
- package/dist/shims/internal/headers-state.js +14 -2
- package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
- package/dist/shims/internal/hybrid-client-route-owner-direct.js +32 -15
- package/dist/shims/internal/hybrid-client-route-owner.js +9 -8
- package/dist/shims/link-prefetch.js +5 -4
- package/dist/shims/link.js +7 -5
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +21 -10
- package/dist/shims/og.js +35 -10
- package/dist/shims/request-context.d.ts +13 -0
- package/dist/shims/router.js +28 -52
- package/dist/shims/server.d.ts +42 -8
- package/dist/shims/server.js +99 -15
- package/dist/shims/thenable-params.d.ts +6 -1
- package/dist/shims/thenable-params.js +11 -2
- package/dist/shims/unified-request-context.d.ts +5 -0
- package/dist/shims/unified-request-context.js +2 -0
- package/dist/shims/url-utils.d.ts +7 -0
- package/dist/shims/url-utils.js +12 -3
- package/dist/utils/asset-prefix.d.ts +7 -0
- package/dist/utils/asset-prefix.js +10 -1
- package/dist/utils/client-build-manifest.js +12 -5
- package/dist/utils/client-runtime-metadata.d.ts +1 -0
- package/dist/utils/client-runtime-metadata.js +15 -2
- package/dist/utils/domain-locale.js +1 -1
- package/dist/utils/lazy-chunks.d.ts +4 -0
- package/dist/utils/manifest-paths.d.ts +14 -0
- package/dist/utils/manifest-paths.js +22 -1
- package/dist/utils/path-to-regexp.d.ts +21 -0
- package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
- package/dist/utils/plugin-react-version.d.ts +15 -0
- package/dist/utils/plugin-react-version.js +64 -0
- package/dist/utils/plugin-rsc-version.d.ts +2 -0
- package/dist/utils/plugin-rsc-version.js +28 -2
- package/dist/utils/public-routes.d.ts +2 -0
- package/dist/utils/public-routes.js +18 -7
- package/dist/utils/react-version.d.ts +7 -0
- package/dist/utils/react-version.js +39 -16
- package/package.json +6 -6
- package/dist/build/nitro-route-rules.d.ts +0 -47
- package/dist/build/nitro-route-rules.js +0 -79
- package/dist/plugins/cache-flight-codec.d.ts +0 -19
- package/dist/plugins/cache-flight-codec.js +0 -68
- package/dist/server/middleware-path-to-regexp.d.ts +0 -13
- package/dist/utils/regex-safety.d.ts +0 -17
- package/dist/utils/regex-safety.js +0 -789
package/dist/shims/server.js
CHANGED
|
@@ -3,10 +3,11 @@ import { MIDDLEWARE_SET_COOKIE_HEADER } from "../utils/protocol-headers.js";
|
|
|
3
3
|
import { encodeMiddlewareRequestHeaders } from "../utils/middleware-request-headers.js";
|
|
4
4
|
import { parseEdgeRequestCookieHeader } from "../utils/parse-cookie.js";
|
|
5
5
|
import { hasBasePath, removeTrailingSlash, stripBasePath } from "../utils/base-path.js";
|
|
6
|
-
import { getRequestExecutionContext } from "./request-context.js";
|
|
7
6
|
import { MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER } from "../server/headers.js";
|
|
7
|
+
import { getRequestExecutionContext } from "./request-context.js";
|
|
8
8
|
import { validateCookieAttributeValue, validateCookieName } from "./internal/cookie-serialize.js";
|
|
9
9
|
import { assertSafeNavigationUrl } from "./url-safety.js";
|
|
10
|
+
import { trustProxy } from "../server/proxy-trust.js";
|
|
10
11
|
import { userAgent, userAgentFromString } from "./user-agent.js";
|
|
11
12
|
//#region src/shims/server.ts
|
|
12
13
|
/**
|
|
@@ -97,13 +98,26 @@ function initWithoutInputBody(input, init) {
|
|
|
97
98
|
body: null
|
|
98
99
|
};
|
|
99
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* workerd's `request.cf` metadata. Only the Workers runtime sets it, so its
|
|
103
|
+
* presence means the request came through Cloudflare's edge rather than
|
|
104
|
+
* straight from a client.
|
|
105
|
+
*/
|
|
106
|
+
function readCloudflareMetadata(request) {
|
|
107
|
+
const cf = Reflect.get(request, "cf");
|
|
108
|
+
return cf !== null && typeof cf === "object" ? cf : void 0;
|
|
109
|
+
}
|
|
110
|
+
function readStringField(source, key) {
|
|
111
|
+
const value = Reflect.get(source, key);
|
|
112
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
113
|
+
}
|
|
100
114
|
var NextRequest = class extends Request {
|
|
101
115
|
_nextUrl;
|
|
102
116
|
_url;
|
|
103
117
|
_cookies;
|
|
104
118
|
constructor(input, init) {
|
|
105
119
|
validateURL(typeof input !== "string" && "url" in input ? input.url : String(input));
|
|
106
|
-
const { nextConfig: _nextConfig, ...plainInit } = init ?? {};
|
|
120
|
+
const { nextConfig: _nextConfig, requestHost, ...plainInit } = init ?? {};
|
|
107
121
|
const requestInit = init instanceof Request ? requestInitFromRequest(init) : plainInit;
|
|
108
122
|
if (input instanceof Request) {
|
|
109
123
|
super(input, initWithoutInputBody(input, requestInit));
|
|
@@ -129,6 +143,7 @@ var NextRequest = class extends Request {
|
|
|
129
143
|
} : void 0;
|
|
130
144
|
const urlConfig = _nextConfig ? {
|
|
131
145
|
basePath: _nextConfig.basePath,
|
|
146
|
+
headers: requestHost === void 0 ? void 0 : { host: requestHost },
|
|
132
147
|
nextConfig: {
|
|
133
148
|
i18n,
|
|
134
149
|
trailingSlash: _nextConfig.trailingSlash,
|
|
@@ -155,17 +170,39 @@ var NextRequest = class extends Request {
|
|
|
155
170
|
throw new Error("NextRequest.ua has been removed; use userAgent() instead");
|
|
156
171
|
}
|
|
157
172
|
/**
|
|
158
|
-
* Client IP address.
|
|
159
|
-
*
|
|
173
|
+
* Client IP address. Next.js removed `ip` in v15; vinext keeps it as an
|
|
174
|
+
* extension. Returns undefined unless the value comes from a trusted source.
|
|
175
|
+
*
|
|
176
|
+
* On Cloudflare Workers (the request carries `cf` metadata), Cloudflare's
|
|
177
|
+
* edge sets `CF-Connecting-IP`. Elsewhere these headers are client-supplied
|
|
178
|
+
* and are only honored behind a trusted proxy (`VINEXT_TRUST_PROXY` /
|
|
179
|
+
* `VINEXT_TRUSTED_HOSTS`), matching the `X-Forwarded-*` policy.
|
|
160
180
|
*/
|
|
161
181
|
get ip() {
|
|
182
|
+
if (readCloudflareMetadata(this)) return this.headers.get("cf-connecting-ip") ?? void 0;
|
|
183
|
+
if (!trustProxy) return void 0;
|
|
162
184
|
return this.headers.get("cf-connecting-ip") ?? this.headers.get("x-real-ip") ?? this.headers.get("x-forwarded-for")?.split(",")[0]?.trim() ?? void 0;
|
|
163
185
|
}
|
|
164
186
|
/**
|
|
165
|
-
* Geolocation data.
|
|
166
|
-
*
|
|
187
|
+
* Geolocation data. Next.js removed `geo` in v15; vinext keeps it as an
|
|
188
|
+
* extension. Read from Cloudflare's `request.cf` metadata on Workers, or
|
|
189
|
+
* from platform geo headers behind a trusted proxy. Returns undefined
|
|
190
|
+
* otherwise, because any client can send these headers.
|
|
167
191
|
*/
|
|
168
192
|
get geo() {
|
|
193
|
+
const cf = readCloudflareMetadata(this);
|
|
194
|
+
if (cf) {
|
|
195
|
+
const country = readStringField(cf, "country");
|
|
196
|
+
if (!country) return void 0;
|
|
197
|
+
return {
|
|
198
|
+
country,
|
|
199
|
+
city: readStringField(cf, "city"),
|
|
200
|
+
region: readStringField(cf, "region"),
|
|
201
|
+
latitude: readStringField(cf, "latitude"),
|
|
202
|
+
longitude: readStringField(cf, "longitude")
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
if (!trustProxy) return void 0;
|
|
169
206
|
const country = this.headers.get("cf-ipcountry") ?? this.headers.get("x-vercel-ip-country") ?? void 0;
|
|
170
207
|
if (!country) return void 0;
|
|
171
208
|
return {
|
|
@@ -257,6 +294,9 @@ var NextResponse = class NextResponse extends Response {
|
|
|
257
294
|
});
|
|
258
295
|
}
|
|
259
296
|
};
|
|
297
|
+
function isRawDataPathname(pathname) {
|
|
298
|
+
return pathname.startsWith("/_next/data/") && pathname.endsWith(".json");
|
|
299
|
+
}
|
|
260
300
|
var NextURL = class NextURL {
|
|
261
301
|
/** Internal URL stores the pathname WITHOUT basePath or locale prefix. */
|
|
262
302
|
_url;
|
|
@@ -276,8 +316,15 @@ var NextURL = class NextURL {
|
|
|
276
316
|
_locales;
|
|
277
317
|
_domains;
|
|
278
318
|
_domainLocale;
|
|
319
|
+
_headers;
|
|
320
|
+
_buildId;
|
|
321
|
+
/** First page segment of a raw data pathname, where its locale sits. */
|
|
322
|
+
_dataPathSegment;
|
|
323
|
+
/** The locale parsed from that segment, if it is one. */
|
|
324
|
+
_dataPathLocale;
|
|
279
325
|
constructor(input, base, config) {
|
|
280
326
|
this._url = new URL(input.toString(), base);
|
|
327
|
+
this._headers = config?.headers;
|
|
281
328
|
this._configBasePath = config?.basePath ?? "";
|
|
282
329
|
this._basePath = this._configBasePath;
|
|
283
330
|
this._configTrailingSlash = config?.nextConfig?.trailingSlash ?? false;
|
|
@@ -285,6 +332,7 @@ var NextURL = class NextURL {
|
|
|
285
332
|
this._trailingSlash = this._configTrailingSlash;
|
|
286
333
|
this._analyzeTrailingSlash();
|
|
287
334
|
this._stripBasePath();
|
|
335
|
+
this._parseBuildId();
|
|
288
336
|
const i18n = config?.nextConfig?.i18n;
|
|
289
337
|
if (i18n) {
|
|
290
338
|
this._locales = [...i18n.locales];
|
|
@@ -325,6 +373,22 @@ var NextURL = class NextURL {
|
|
|
325
373
|
this._basePath = this._configBasePath;
|
|
326
374
|
this._url.pathname = stripBasePath(this._url.pathname, this._configBasePath);
|
|
327
375
|
}
|
|
376
|
+
/**
|
|
377
|
+
* Take the build ID from a raw `/_next/data/<buildId>/….json` pathname, as
|
|
378
|
+
* getNextPathnameInfo does. Middleware only sees one when proxy URL
|
|
379
|
+
* normalization is skipped; the pathname is left as is.
|
|
380
|
+
*/
|
|
381
|
+
_parseBuildId() {
|
|
382
|
+
const { pathname } = this._url;
|
|
383
|
+
if (!isRawDataPathname(pathname)) {
|
|
384
|
+
this._buildId = void 0;
|
|
385
|
+
this._dataPathSegment = void 0;
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const [buildId, pageSegment] = pathname.slice(12, -5).split("/");
|
|
389
|
+
this._buildId = buildId;
|
|
390
|
+
this._dataPathSegment = pageSegment === "index" ? void 0 : pageSegment;
|
|
391
|
+
}
|
|
328
392
|
/** Extract locale from pathname, stripping it from the internal URL. */
|
|
329
393
|
_detectPathnameLocale(locales) {
|
|
330
394
|
const segments = this._url.pathname.split("/");
|
|
@@ -336,11 +400,29 @@ var NextURL = class NextURL {
|
|
|
336
400
|
_analyzeI18n() {
|
|
337
401
|
if (!this._locales || !this._configDefaultLocale) return;
|
|
338
402
|
const detectedLocale = this._detectPathnameLocale(this._locales);
|
|
403
|
+
this._dataPathLocale = void 0;
|
|
404
|
+
if (!detectedLocale && this._buildId && this._dataPathSegment) {
|
|
405
|
+
const candidate = this._dataPathSegment.toLowerCase();
|
|
406
|
+
this._dataPathLocale = this._locales.find((l) => l.toLowerCase() === candidate);
|
|
407
|
+
}
|
|
339
408
|
const detectedLocaleLower = detectedLocale?.toLowerCase();
|
|
340
|
-
const
|
|
409
|
+
const hostHeader = this._headers?.host;
|
|
410
|
+
const hostname = (typeof hostHeader === "string" && hostHeader ? hostHeader.split(":", 1)[0] : this._url.hostname).toLowerCase();
|
|
341
411
|
this._domainLocale = this._domains?.find((domain) => domain.domain.split(":", 1)[0].toLowerCase() === hostname || detectedLocaleLower === domain.defaultLocale.toLowerCase() || domain.locales?.some((locale) => locale.toLowerCase() === detectedLocaleLower));
|
|
342
412
|
this._defaultLocale = this._domainLocale?.defaultLocale ?? this._configDefaultLocale;
|
|
343
|
-
this._locale = detectedLocale ?? this._defaultLocale;
|
|
413
|
+
this._locale = detectedLocale ?? this._dataPathLocale ?? this._defaultLocale;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* A raw data pathname keeps its locale segment, replaced by the current
|
|
417
|
+
* locale once it has been changed.
|
|
418
|
+
*/
|
|
419
|
+
_formatDataPathLocale(pathname) {
|
|
420
|
+
if (!this._dataPathLocale || this._locale === this._dataPathLocale) return pathname;
|
|
421
|
+
if (!this._locale || !isRawDataPathname(pathname)) return pathname;
|
|
422
|
+
const segments = pathname.slice(12, -5).split("/");
|
|
423
|
+
if (segments[1]?.toLowerCase() !== this._dataPathLocale.toLowerCase()) return pathname;
|
|
424
|
+
segments[1] = this._locale;
|
|
425
|
+
return "/_next/data/" + segments.join("/") + ".json";
|
|
344
426
|
}
|
|
345
427
|
/**
|
|
346
428
|
* Reconstruct the full pathname with basePath + locale prefix and apply
|
|
@@ -349,9 +431,9 @@ var NextURL = class NextURL {
|
|
|
349
431
|
*/
|
|
350
432
|
_formatPathname() {
|
|
351
433
|
let prefix = this._basePath;
|
|
352
|
-
const inner = this._url.pathname;
|
|
434
|
+
const inner = this._formatDataPathLocale(this._url.pathname);
|
|
353
435
|
const innerLower = inner.toLowerCase();
|
|
354
|
-
if (!(innerLower === "/api" || innerLower.startsWith("/api/")) && this._locale && this._locale !== this._defaultLocale) prefix += "/" + this._locale;
|
|
436
|
+
if (!(innerLower === "/api" || innerLower.startsWith("/api/")) && !isRawDataPathname(inner) && this._locale && this._locale !== this._defaultLocale) prefix += "/" + this._locale;
|
|
355
437
|
const composed = !prefix ? inner : inner === "/" ? prefix : prefix + inner;
|
|
356
438
|
return this._applyTrailingSlash(composed);
|
|
357
439
|
}
|
|
@@ -379,6 +461,7 @@ var NextURL = class NextURL {
|
|
|
379
461
|
this._url.href = value;
|
|
380
462
|
this._analyzeTrailingSlash();
|
|
381
463
|
this._stripBasePath();
|
|
464
|
+
this._parseBuildId();
|
|
382
465
|
this._analyzeI18n();
|
|
383
466
|
}
|
|
384
467
|
get origin() {
|
|
@@ -490,6 +573,7 @@ var NextURL = class NextURL {
|
|
|
490
573
|
} else if (this._trailingSlash) nextConfig.trailingSlash = true;
|
|
491
574
|
const config = {
|
|
492
575
|
basePath: this._configBasePath,
|
|
576
|
+
headers: this._headers,
|
|
493
577
|
nextConfig: Object.keys(nextConfig).length > 0 ? nextConfig : void 0
|
|
494
578
|
};
|
|
495
579
|
return new NextURL(this.href, void 0, config);
|
|
@@ -501,13 +585,13 @@ var NextURL = class NextURL {
|
|
|
501
585
|
return this.href;
|
|
502
586
|
}
|
|
503
587
|
/**
|
|
504
|
-
*
|
|
505
|
-
*
|
|
506
|
-
*
|
|
507
|
-
*
|
|
588
|
+
* Matches the Next.js API: `request.nextUrl.buildId`. Next.js derives it
|
|
589
|
+
* from the URL (only `/_next/data/<buildId>/…` paths carry one) and never
|
|
590
|
+
* from the deployment, so a Client Component reads the same value on the
|
|
591
|
+
* server and in the browser.
|
|
508
592
|
*/
|
|
509
593
|
get buildId() {
|
|
510
|
-
return
|
|
594
|
+
return this._buildId;
|
|
511
595
|
}
|
|
512
596
|
};
|
|
513
597
|
var RequestCookies = class {
|
|
@@ -3,7 +3,12 @@ import { WellKnownProperty } from "./internal/thenable-well-known-properties.js"
|
|
|
3
3
|
export type ThenableParams<T extends Record<string, unknown>> = Promise<T> & Omit<T, WellKnownProperty>;
|
|
4
4
|
export type ThenableParamsObserver = Readonly<{
|
|
5
5
|
observeParamAccess: (keys: readonly string[]) => void;
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Runs when `then` is read, and when `catch` or `finally` is called (they
|
|
8
|
+
* read `then` on a native promise). Throwing here fails the read itself
|
|
9
|
+
* before React counts any pending work, as Next.js does.
|
|
10
|
+
*/
|
|
11
|
+
observeThenRead?: () => void;
|
|
7
12
|
}>;
|
|
8
13
|
/** Serialize backing values without reading a framework fallback-key proxy. */
|
|
9
14
|
export declare function getFallbackParamsSnapshot(value: unknown): Promise<Record<string, unknown>> | undefined;
|
|
@@ -117,14 +117,20 @@ function createThenableParams(obj, observer, fallbackShellState) {
|
|
|
117
117
|
const params = createThenableParamsProxy(promise, {
|
|
118
118
|
get(target, prop, receiver) {
|
|
119
119
|
if (isPromiseContinuation(prop)) {
|
|
120
|
+
if (prop === "then") observer?.observeThenRead?.();
|
|
120
121
|
const value = Reflect.get(target, prop, receiver);
|
|
121
122
|
if (typeof value !== "function") return value;
|
|
122
123
|
return (...args) => {
|
|
123
|
-
if (
|
|
124
|
+
if (prop !== "then") observer?.observeThenRead?.();
|
|
125
|
+
if (!fallbackParamNames) try {
|
|
126
|
+
observeAllParamKeys(observer, plain);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
return Reflect.apply(value, Promise.reject(error), args);
|
|
129
|
+
}
|
|
124
130
|
return Reflect.apply(value, target, args);
|
|
125
131
|
};
|
|
126
132
|
}
|
|
127
|
-
if (prop === "
|
|
133
|
+
if (prop === "reason" && Object.hasOwn(target, prop)) return Reflect.get(target, prop);
|
|
128
134
|
if (typeof prop === "string" && !isWellKnownProperty(prop)) observeParamKeys(observer, [prop]);
|
|
129
135
|
if (!isWellKnownProperty(prop) && hasParamProperty(plain, prop)) {
|
|
130
136
|
if (isFallbackParam(prop)) {
|
|
@@ -164,6 +170,9 @@ function createThenableParams(obj, observer, fallbackShellState) {
|
|
|
164
170
|
ownKeys() {
|
|
165
171
|
observeReadableParamKeys(observer, plain);
|
|
166
172
|
return Reflect.ownKeys(plain).filter((prop) => !isWellKnownProperty(prop));
|
|
173
|
+
},
|
|
174
|
+
set(target, prop, value) {
|
|
175
|
+
return Reflect.set(target, prop, value);
|
|
167
176
|
}
|
|
168
177
|
});
|
|
169
178
|
paramsState.set(params, {
|
|
@@ -21,6 +21,11 @@ import "./request-state-types.js";
|
|
|
21
21
|
export type UnifiedRequestContext = {
|
|
22
22
|
/** Cloudflare Workers ExecutionContext, or null on Node.js dev. */
|
|
23
23
|
executionContext: ExecutionContextLike | null;
|
|
24
|
+
/**
|
|
25
|
+
* The host's client-connection signal for the incoming request, before any
|
|
26
|
+
* clone follows it. Null for requests vinext creates itself (regeneration).
|
|
27
|
+
*/
|
|
28
|
+
requestSignal: AbortSignal | null;
|
|
24
29
|
/** Per-request cache for cacheForRequest(). Keyed by factory function reference. */
|
|
25
30
|
requestCache: WeakMap<(...args: any[]) => any, unknown>;
|
|
26
31
|
/** Shared lifecycle state for work deferred until the response closes. */
|
|
@@ -18,6 +18,7 @@ function createRequestContext(opts) {
|
|
|
18
18
|
headersContext: null,
|
|
19
19
|
actionRevalidationKind: 0,
|
|
20
20
|
cacheLifeSink: null,
|
|
21
|
+
pendingCdnTagInvalidations: [],
|
|
21
22
|
pendingRevalidatedTags: /* @__PURE__ */ new Set(),
|
|
22
23
|
pendingRevalidations: /* @__PURE__ */ new Set(),
|
|
23
24
|
dynamicUsageDetected: false,
|
|
@@ -50,6 +51,7 @@ function createRequestContext(opts) {
|
|
|
50
51
|
currentFetchDedupeEntries: /* @__PURE__ */ new Map(),
|
|
51
52
|
nextFetchId: 1,
|
|
52
53
|
executionContext: _getInheritedExecutionContext(),
|
|
54
|
+
requestSignal: null,
|
|
53
55
|
requestCache: /* @__PURE__ */ new WeakMap(),
|
|
54
56
|
afterContext: {
|
|
55
57
|
callbacks: [],
|
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
export declare function isAbsoluteUrl(url: string): boolean;
|
|
3
3
|
export declare function isAbsoluteOrProtocolRelativeUrl(url: string): boolean;
|
|
4
4
|
export declare function getWindowOrigin(): string | null;
|
|
5
|
+
/**
|
|
6
|
+
* A same-origin pathname can start with "//" (e.g. `https://app.com//evil.com`),
|
|
7
|
+
* and as a local path that is a protocol-relative reference to another host.
|
|
8
|
+
* Collapse the leading slashes: Next.js does the same for these URLs, on the
|
|
9
|
+
* client (`resolveHref`) or with its server's repeated-slash 308.
|
|
10
|
+
*/
|
|
11
|
+
export declare function collapseLeadingSlashes(pathname: string): string;
|
|
5
12
|
/**
|
|
6
13
|
* If `url` is an absolute same-origin URL, return the local path
|
|
7
14
|
* (pathname + search + hash). Returns null for truly external URLs
|
package/dist/shims/url-utils.js
CHANGED
|
@@ -25,6 +25,15 @@ function getWindowOrigin() {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
28
|
+
* A same-origin pathname can start with "//" (e.g. `https://app.com//evil.com`),
|
|
29
|
+
* and as a local path that is a protocol-relative reference to another host.
|
|
30
|
+
* Collapse the leading slashes: Next.js does the same for these URLs, on the
|
|
31
|
+
* client (`resolveHref`) or with its server's repeated-slash 308.
|
|
32
|
+
*/
|
|
33
|
+
function collapseLeadingSlashes(pathname) {
|
|
34
|
+
return pathname.replace(/^\/{2,}/, "/");
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
28
37
|
* If `url` is an absolute same-origin URL, return the local path
|
|
29
38
|
* (pathname + search + hash). Returns null for truly external URLs
|
|
30
39
|
* or on the server (where origin is unknown).
|
|
@@ -34,7 +43,7 @@ function toSameOriginPath(url) {
|
|
|
34
43
|
if (!origin) return null;
|
|
35
44
|
try {
|
|
36
45
|
const parsed = url.startsWith("//") ? new URL(url, origin) : new URL(url);
|
|
37
|
-
if (parsed.origin === origin) return parsed.pathname + parsed.search + parsed.hash;
|
|
46
|
+
if (parsed.origin === origin) return collapseLeadingSlashes(parsed.pathname) + parsed.search + parsed.hash;
|
|
38
47
|
} catch {}
|
|
39
48
|
return null;
|
|
40
49
|
}
|
|
@@ -49,7 +58,7 @@ function toSameOriginAppPath(url, basePath) {
|
|
|
49
58
|
try {
|
|
50
59
|
const parsed = new URL(localPath, "http://vinext.local");
|
|
51
60
|
if (!hasBasePath(parsed.pathname, basePath)) return null;
|
|
52
|
-
return stripBasePath(parsed.pathname, basePath) + parsed.search + parsed.hash;
|
|
61
|
+
return collapseLeadingSlashes(stripBasePath(parsed.pathname, basePath)) + parsed.search + parsed.hash;
|
|
53
62
|
} catch {
|
|
54
63
|
return localPath;
|
|
55
64
|
}
|
|
@@ -164,4 +173,4 @@ function isHashOnlyBrowserUrlChange(href, currentHref, basePath = "") {
|
|
|
164
173
|
}
|
|
165
174
|
}
|
|
166
175
|
//#endregion
|
|
167
|
-
export { getWindowOrigin, isAbsoluteOrProtocolRelativeUrl, isAbsoluteUrl, isHashOnlyBrowserUrlChange, normalizePathTrailingSlash, resolveRelativeHref, toBrowserNavigationHref, toCanonicalBrowserNavigationHref, toSameOriginAppPath, toSameOriginPath, withBasePath };
|
|
176
|
+
export { collapseLeadingSlashes, getWindowOrigin, isAbsoluteOrProtocolRelativeUrl, isAbsoluteUrl, isHashOnlyBrowserUrlChange, normalizePathTrailingSlash, resolveRelativeHref, toBrowserNavigationHref, toCanonicalBrowserNavigationHref, toSameOriginAppPath, toSameOriginPath, withBasePath };
|
|
@@ -92,4 +92,11 @@ export declare function assetPrefixPathname(assetPrefix: string): string;
|
|
|
92
92
|
* @see https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/router-server.ts
|
|
93
93
|
*/
|
|
94
94
|
export declare function isNextStaticPath(pathname: string, basePath: string, assetPathPrefix: string): boolean;
|
|
95
|
+
/**
|
|
96
|
+
* Whether `pathname` is a build asset under a path `assetPrefix`. Next.js adds
|
|
97
|
+
* a built-in beforeFiles rewrite from `${assetPrefix}/_next/:path+` into the
|
|
98
|
+
* basePath (`loadRewrites` in `packages/next/src/lib/load-custom-routes.ts`),
|
|
99
|
+
* so such a path resolves even when it lies outside the basePath.
|
|
100
|
+
*/
|
|
101
|
+
export declare function isAssetPrefixBuildAsset(pathname: string, assetPathPrefix: string): boolean;
|
|
95
102
|
//#endregion
|
|
@@ -118,5 +118,14 @@ function isNextStaticPath(pathname, basePath, assetPathPrefix) {
|
|
|
118
118
|
if (assetPathPrefix && (p === assetPathPrefix || p.startsWith(assetPathPrefix + "/"))) p = p.slice(assetPathPrefix.length) || "/";
|
|
119
119
|
return p.startsWith(`/${ASSET_PREFIX_URL_DIR}/`);
|
|
120
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Whether `pathname` is a build asset under a path `assetPrefix`. Next.js adds
|
|
123
|
+
* a built-in beforeFiles rewrite from `${assetPrefix}/_next/:path+` into the
|
|
124
|
+
* basePath (`loadRewrites` in `packages/next/src/lib/load-custom-routes.ts`),
|
|
125
|
+
* so such a path resolves even when it lies outside the basePath.
|
|
126
|
+
*/
|
|
127
|
+
function isAssetPrefixBuildAsset(pathname, assetPathPrefix) {
|
|
128
|
+
return !!assetPathPrefix && (pathname === assetPathPrefix || pathname.startsWith(assetPathPrefix + "/")) && isNextStaticPath(pathname, "", assetPathPrefix);
|
|
129
|
+
}
|
|
121
130
|
//#endregion
|
|
122
|
-
export { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix, isNextStaticPath, resolveAssetUrlPrefix, resolveAssetsDir };
|
|
131
|
+
export { ASSET_PREFIX_URL_DIR, assetPrefixPathname, isAbsoluteAssetPrefix, isAssetPrefixBuildAsset, isNextStaticPath, resolveAssetUrlPrefix, resolveAssetsDir };
|
|
@@ -19,6 +19,8 @@ function readClientBuildManifest(manifestPath) {
|
|
|
19
19
|
const assets = readStringArray(entry.assets);
|
|
20
20
|
manifest[key] = {
|
|
21
21
|
file: entry.file,
|
|
22
|
+
...typeof entry.src === "string" ? { src: entry.src } : {},
|
|
23
|
+
...typeof entry.name === "string" ? { name: entry.name } : {},
|
|
22
24
|
...entry.isEntry === true ? { isEntry: true } : {},
|
|
23
25
|
...entry.isDynamicEntry === true ? { isDynamicEntry: true } : {},
|
|
24
26
|
...imports ? { imports } : {},
|
|
@@ -39,14 +41,19 @@ function findPagesClientEntryFileFromManifest(buildManifest, assetBase) {
|
|
|
39
41
|
return findEntryFileFromManifest(buildManifest, assetBase, PAGES_CLIENT_ENTRY_MARKERS, false);
|
|
40
42
|
}
|
|
41
43
|
function findEntryFileFromManifest(buildManifest, assetBase, markers, fallbackToFirstEntry) {
|
|
42
|
-
const entries = Object.
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
const entries = Object.entries(buildManifest).filter(([, entry]) => entry.isEntry && entry.file);
|
|
45
|
+
const matchers = [(marker, key, entry) => entry.name === marker || isVirtualEntryId(key, marker) || entry.src !== void 0 && isVirtualEntryId(entry.src, marker), (marker, _key, entry) => entry.file.includes(marker)];
|
|
46
|
+
for (const matches of matchers) for (const marker of markers) {
|
|
47
|
+
const markedEntry = entries.find(([key, entry]) => matches(marker, key, entry));
|
|
48
|
+
if (markedEntry) return manifestFileWithBase(markedEntry[1].file, assetBase);
|
|
46
49
|
}
|
|
47
|
-
const chosen = fallbackToFirstEntry ? entries[0] : void 0;
|
|
50
|
+
const chosen = fallbackToFirstEntry ? entries[0]?.[1] : void 0;
|
|
48
51
|
return chosen ? manifestFileWithBase(chosen.file, assetBase) : void 0;
|
|
49
52
|
}
|
|
53
|
+
function isVirtualEntryId(id, marker) {
|
|
54
|
+
const virtualId = `virtual:${marker}`;
|
|
55
|
+
return id === virtualId || id.endsWith(`/${virtualId}`);
|
|
56
|
+
}
|
|
50
57
|
function listFilesRecursive(dir) {
|
|
51
58
|
const out = [];
|
|
52
59
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
|
|
2
2
|
import { isAbsoluteAssetPrefix, resolveAssetsDir } from "./asset-prefix.js";
|
|
3
|
-
import { manifestFileWithAssetPrefix, manifestFileWithBase } from "./manifest-paths.js";
|
|
3
|
+
import { isSharedClientChunkName, manifestFileWithAssetPrefix, manifestFileWithBase } from "./manifest-paths.js";
|
|
4
4
|
import { findClientEntryFileFromVinextManifest, findPagesClientEntryFileFromVinextManifest, readClientEntryManifest } from "./client-entry-manifest.js";
|
|
5
5
|
import { findClientEntryFile, findPagesClientEntryFile, readClientBuildManifest } from "./client-build-manifest.js";
|
|
6
6
|
import { computeDynamicImportPreloads, computeLazyChunks, dynamicImportPreloadsWithBase } from "./lazy-chunks.js";
|
|
7
7
|
//#region src/utils/client-runtime-metadata.ts
|
|
8
|
+
/**
|
|
9
|
+
* Shared Pages Router chunk files, keyed on Rolldown chunk names rather than
|
|
10
|
+
* emitted file names so user-configured `chunkFileNames` (e.g. hash-only
|
|
11
|
+
* patterns) keep their modulepreload/script tags.
|
|
12
|
+
*/
|
|
13
|
+
function collectSharedChunkFiles(buildManifest, applyBase) {
|
|
14
|
+
const files = /* @__PURE__ */ new Set();
|
|
15
|
+
for (const chunk of Object.values(buildManifest)) if (chunk.file.endsWith(".js") && isSharedClientChunkName(chunk.name)) files.add(applyBase(chunk.file));
|
|
16
|
+
return files.size > 0 ? [...files] : void 0;
|
|
17
|
+
}
|
|
8
18
|
function collectCssGraph(buildManifest, applyBase) {
|
|
9
19
|
const cssGraph = {};
|
|
10
20
|
for (const [key, chunk] of Object.entries(buildManifest)) {
|
|
@@ -74,7 +84,10 @@ function computeClientRuntimeMetadata(opts) {
|
|
|
74
84
|
if (entry) metadata.clientEntryFile = entry;
|
|
75
85
|
}
|
|
76
86
|
if (!buildManifest) return metadata;
|
|
77
|
-
if (opts.includeClientEntry)
|
|
87
|
+
if (opts.includeClientEntry) {
|
|
88
|
+
metadata.cssGraph = collectCssGraph(buildManifest, (file) => manifestFileWithBase(file, opts.assetBase));
|
|
89
|
+
metadata.sharedChunks = collectSharedChunkFiles(buildManifest, (file) => manifestFileWithBase(file, opts.assetBase));
|
|
90
|
+
}
|
|
78
91
|
metadata.appBootstrapPreinitModules = collectAppBootstrapPreinitModules(buildManifest, clientEntryManifest?.appBrowserEntry, (file) => {
|
|
79
92
|
const url = manifestFileWithAssetPrefix(file, opts.assetBase, opts.assetPrefix);
|
|
80
93
|
return isAbsoluteAssetPrefix(opts.assetPrefix) ? url : "/" + url;
|
|
@@ -42,7 +42,7 @@ function getDomainLocaleUrl(url, locale, { basePath, currentHostname, domainItem
|
|
|
42
42
|
const targetDomain = detectDomainLocale(domainItems, void 0, locale);
|
|
43
43
|
if (!targetDomain) return void 0;
|
|
44
44
|
const currentDomain = detectDomainLocale(domainItems, currentHostname ?? void 0);
|
|
45
|
-
const localizedPath = addLocalePrefix(url
|
|
45
|
+
const localizedPath = addLocalePrefix(/^[/?#]/.test(url) ? url : `/${url}`, locale, targetDomain.defaultLocale);
|
|
46
46
|
if (currentDomain && normalizeDomainHostname(currentDomain.domain) === normalizeDomainHostname(targetDomain.domain)) return;
|
|
47
47
|
return `${`http${targetDomain.http ? "" : "s"}://`}${targetDomain.domain}${prefixBasePath(localizedPath, basePath)}`;
|
|
48
48
|
}
|
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export type BuildManifestChunk = {
|
|
6
6
|
file: string;
|
|
7
|
+
/** Source module id (or virtual id) of an entry chunk. */
|
|
8
|
+
src?: string;
|
|
9
|
+
/** Rolldown chunk name, independent of the configured output file name. */
|
|
10
|
+
name?: string;
|
|
7
11
|
isEntry?: boolean;
|
|
8
12
|
isDynamicEntry?: boolean;
|
|
9
13
|
imports?: string[];
|
|
@@ -26,4 +26,18 @@ export declare function assetServingUrlFromBaseAnchored(value: string, basePath:
|
|
|
26
26
|
* `<base>/<base>/` prefix is collapsed; a single prefix is left untouched.
|
|
27
27
|
*/
|
|
28
28
|
export declare function collapseDuplicateBase(file: string, base: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Whether a Rolldown chunk belongs to the shared Pages Router runtime, judged
|
|
31
|
+
* by its exact chunk name rather than its emitted file name so user-configured
|
|
32
|
+
* or hash-only `chunkFileNames` keep their modulepreload/script tags.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isSharedClientChunkName(name: string | undefined): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Reserved `ssr-manifest.json` key listing the shared runtime chunk files.
|
|
37
|
+
* Consumers that pass the on-disk manifest straight to `renderPage()` (the
|
|
38
|
+
* legacy two-call Pages build) have no registered build metadata, and file
|
|
39
|
+
* names alone can't identify these chunks. The `\0` prefix keeps it from
|
|
40
|
+
* matching any module id.
|
|
41
|
+
*/
|
|
42
|
+
export declare const SSR_MANIFEST_SHARED_CHUNKS_KEY = "\0vinext:shared-chunks";
|
|
29
43
|
//#endregion
|
|
@@ -62,5 +62,26 @@ function collapseDuplicateBase(file, base) {
|
|
|
62
62
|
const doubledPrefix = `${normalizedBase}/${normalizedBase}/`;
|
|
63
63
|
return normalizedFile.startsWith(doubledPrefix) ? normalizedFile.slice(normalizedBase.length + 1) : normalizedFile;
|
|
64
64
|
}
|
|
65
|
+
const SHARED_CHUNK_NAMES = /* @__PURE__ */ new Set([
|
|
66
|
+
"framework",
|
|
67
|
+
"vinext",
|
|
68
|
+
"vinext-client-entry"
|
|
69
|
+
]);
|
|
70
|
+
/**
|
|
71
|
+
* Whether a Rolldown chunk belongs to the shared Pages Router runtime, judged
|
|
72
|
+
* by its exact chunk name rather than its emitted file name so user-configured
|
|
73
|
+
* or hash-only `chunkFileNames` keep their modulepreload/script tags.
|
|
74
|
+
*/
|
|
75
|
+
function isSharedClientChunkName(name) {
|
|
76
|
+
return name !== void 0 && SHARED_CHUNK_NAMES.has(name);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Reserved `ssr-manifest.json` key listing the shared runtime chunk files.
|
|
80
|
+
* Consumers that pass the on-disk manifest straight to `renderPage()` (the
|
|
81
|
+
* legacy two-call Pages build) have no registered build metadata, and file
|
|
82
|
+
* names alone can't identify these chunks. The `\0` prefix keeps it from
|
|
83
|
+
* matching any module id.
|
|
84
|
+
*/
|
|
85
|
+
const SSR_MANIFEST_SHARED_CHUNKS_KEY = "\0vinext:shared-chunks";
|
|
65
86
|
//#endregion
|
|
66
|
-
export { assetServingUrlFromBaseAnchored, collapseDuplicateBase, manifestFileWithAssetPrefix, manifestFileWithBase };
|
|
87
|
+
export { SSR_MANIFEST_SHARED_CHUNKS_KEY, assetServingUrlFromBaseAnchored, collapseDuplicateBase, isSharedClientChunkName, manifestFileWithAssetPrefix, manifestFileWithBase };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/utils/path-to-regexp.d.ts
|
|
2
|
+
export type PathToken = string | PathKey;
|
|
3
|
+
export type PathKey = {
|
|
4
|
+
name: string | number;
|
|
5
|
+
prefix: string;
|
|
6
|
+
suffix: string;
|
|
7
|
+
pattern: string;
|
|
8
|
+
modifier: string;
|
|
9
|
+
};
|
|
10
|
+
export type ParsePathPatternOptions = {
|
|
11
|
+
/** Characters a default param cannot contain. path-to-regexp defaults to `/#?`. */
|
|
12
|
+
delimiter?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function parsePathPattern(value: string, options?: ParsePathPatternOptions): PathToken[];
|
|
15
|
+
export declare function normalizePathTokens(tokens: PathToken[]): PathToken[];
|
|
16
|
+
/**
|
|
17
|
+
* path-to-regexp's `tokensToRegexp` with `strict: true`, without the closing
|
|
18
|
+
* `$`. Callers append the ending their Next.js matcher uses.
|
|
19
|
+
*/
|
|
20
|
+
export declare function pathTokensToRegExpSource(tokens: PathToken[]): string;
|
|
21
|
+
//#endregion
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/utils/path-to-regexp.ts
|
|
2
2
|
function lexer(value) {
|
|
3
3
|
const tokens = [];
|
|
4
4
|
let index = 0;
|
|
@@ -101,11 +101,12 @@ function lexer(value) {
|
|
|
101
101
|
});
|
|
102
102
|
return tokens;
|
|
103
103
|
}
|
|
104
|
-
function
|
|
104
|
+
function parsePathPattern(value, options = {}) {
|
|
105
105
|
const tokens = lexer(value);
|
|
106
106
|
const result = [];
|
|
107
107
|
const prefixes = "./";
|
|
108
|
-
const delimiter = "/#?";
|
|
108
|
+
const delimiter = options.delimiter ?? "/#?";
|
|
109
|
+
const delimiterClass = `[^${escapeRegex(delimiter)}]`;
|
|
109
110
|
let key = 0;
|
|
110
111
|
let index = 0;
|
|
111
112
|
let path = "";
|
|
@@ -135,8 +136,8 @@ function parseMiddlewarePath(value) {
|
|
|
135
136
|
const name = typeof previous === "string" ? previous : previous.name;
|
|
136
137
|
throw new TypeError(`Must have text between two parameters, missing text after "${name}"`);
|
|
137
138
|
}
|
|
138
|
-
if (!previousText || containsDelimiter(previousText)) return
|
|
139
|
-
return `(?:(?!${escapeRegex(previousText)})
|
|
139
|
+
if (!previousText || containsDelimiter(previousText)) return `${delimiterClass}+?`;
|
|
140
|
+
return `(?:(?!${escapeRegex(previousText)})${delimiterClass})+?`;
|
|
140
141
|
};
|
|
141
142
|
while (index < tokens.length) {
|
|
142
143
|
const character = tryConsume("CHAR");
|
|
@@ -192,7 +193,7 @@ function parseMiddlewarePath(value) {
|
|
|
192
193
|
function escapeRegex(value) {
|
|
193
194
|
return value.replace(/([.+*?=^!:${}()[\]|/\\])/g, "\\$1");
|
|
194
195
|
}
|
|
195
|
-
function
|
|
196
|
+
function normalizePathTokens(tokens) {
|
|
196
197
|
return tokens.map((token) => {
|
|
197
198
|
if (typeof token === "object" && (token.modifier === "*" || token.modifier === "+") && token.prefix === "" && token.suffix === "") return {
|
|
198
199
|
...token,
|
|
@@ -201,8 +202,11 @@ function normalizeMiddlewarePathTokens(tokens) {
|
|
|
201
202
|
return token;
|
|
202
203
|
});
|
|
203
204
|
}
|
|
204
|
-
|
|
205
|
-
|
|
205
|
+
/**
|
|
206
|
+
* path-to-regexp's `tokensToRegexp` with `strict: true`, without the closing
|
|
207
|
+
* `$`. Callers append the ending their Next.js matcher uses.
|
|
208
|
+
*/
|
|
209
|
+
function pathTokensToRegExpSource(tokens) {
|
|
206
210
|
let route = "^";
|
|
207
211
|
for (const token of tokens) {
|
|
208
212
|
if (typeof token === "string") {
|
|
@@ -223,8 +227,7 @@ function middlewarePathTokensToRegExp(tokens) {
|
|
|
223
227
|
}
|
|
224
228
|
} else route += `(?:${prefix}${suffix})${token.modifier}`;
|
|
225
229
|
}
|
|
226
|
-
route
|
|
227
|
-
return new RegExp(route, "i");
|
|
230
|
+
return route;
|
|
228
231
|
}
|
|
229
232
|
//#endregion
|
|
230
|
-
export {
|
|
233
|
+
export { normalizePathTokens, parsePathPattern, pathTokensToRegExpSource };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/utils/plugin-react-version.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Resolve @vitejs/plugin-react from the project, falling back to vinext's own
|
|
4
|
+
* install when the project has none or reaches an unsupported version.
|
|
5
|
+
* Returns null when it is not installed, and throws when every copy found is
|
|
6
|
+
* unsupported.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolvePluginReactPath(projectRoot: string, fallbackFrom?: string): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* The @vitejs/plugin-react upgrade vinext init must install before vinext.
|
|
11
|
+
* A declared copy below the floor conflicts with vinext's peer range: npm stops
|
|
12
|
+
* with ERESOLVE, and pnpm installs but vinext refuses to start.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getPluginReactUpgradeDeps(root: string): string[];
|
|
15
|
+
//#endregion
|