vinext 1.2.1 → 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 +12 -9
- 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/pages-client-assets-module.js +1 -1
- package/dist/build/prerender-paths.js +5 -2
- 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/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 +183 -255
- 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 +239 -83
- package/dist/init.js +17 -0
- package/dist/plugins/optimize-imports.d.ts +25 -2
- package/dist/plugins/optimize-imports.js +106 -20
- package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
- package/dist/plugins/rsc-client-reference-loaders.js +336 -18
- package/dist/plugins/use-cache-callable.d.ts +5 -0
- package/dist/plugins/use-cache-callable.js +30 -8
- package/dist/plugins/worker-image-imports.d.ts +1 -0
- package/dist/plugins/worker-image-imports.js +1 -1
- 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/app-action-forwarding.d.ts +8 -0
- package/dist/server/app-action-forwarding.js +15 -1
- package/dist/server/app-browser-entry.js +147 -60
- 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-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-state.d.ts +2 -2
- 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 +2 -0
- package/dist/server/app-page-render.js +3 -1
- 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 +11 -7
- package/dist/server/app-prerender-static-params.js +3 -2
- package/dist/server/app-render-dependency.js +42 -2
- package/dist/server/app-request-stage-independent-entry.js +2 -2
- package/dist/server/app-response-stage-entry.js +3 -3
- 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 +20 -3
- 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 +2 -2
- 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 +146 -130
- 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 +3 -1
- 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 +50 -56
- package/dist/server/app-ssr-entry.d.ts +6 -0
- package/dist/server/app-ssr-entry.js +16 -7
- package/dist/server/app-ssr-stream.d.ts +7 -0
- package/dist/server/app-ssr-stream.js +13 -1
- package/dist/server/config-headers.js +12 -3
- 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/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 +26 -13
- package/dist/server/navigation-planner.d.ts +2 -2
- 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/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-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-request-pipeline.d.ts +6 -1
- package/dist/server/pages-request-pipeline.js +31 -35
- package/dist/server/pages-request-stage-entry.js +16 -6
- package/dist/server/pages-response-stage-entry.js +1 -1
- package/dist/server/pages-revalidate.js +1 -0
- package/dist/server/pages-router-entry.js +1 -1
- package/dist/server/prod-server.d.ts +2 -2
- package/dist/server/prod-server.js +71 -33
- 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/server-reference-loader.js +10 -1
- package/dist/server/static-file-cache.js +15 -3
- 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/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 +31 -14
- package/dist/shims/internal/hybrid-client-route-owner.js +8 -8
- package/dist/shims/link.js +5 -3
- package/dist/shims/navigation.d.ts +1 -1
- package/dist/shims/navigation.js +17 -5
- package/dist/shims/og.js +35 -10
- package/dist/shims/request-context.d.ts +13 -0
- package/dist/shims/router.js +19 -40
- package/dist/shims/server.d.ts +31 -4
- package/dist/shims/server.js +58 -10
- 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/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/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/public-routes.d.ts +2 -0
- package/dist/utils/public-routes.js +18 -7
- package/package.json +1 -1
- 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/image.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { getDeploymentId } from "../utils/deployment-id.js";
|
|
3
2
|
import { useMergedRef } from "./use-merged-ref.js";
|
|
4
|
-
import {
|
|
3
|
+
import { RESPONSIVE_WIDTHS, __dangerouslyAllowSVG, __globallyUnoptimized, __isDev, generateImageAttributes, getFillStyle, getImageProps, imageOptimizationUrl, isRemoteUrl, isSvgUrl, resolveImageSource, sanitizeBlurDataURL, validateRemoteUrl } from "./image-props.js";
|
|
5
4
|
import { forwardRef, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
6
5
|
import { jsx } from "react/jsx-runtime";
|
|
7
6
|
import * as ReactDOM from "react-dom";
|
|
@@ -18,108 +17,11 @@ import { Image as Image$1 } from "@unpic/react";
|
|
|
18
17
|
* Remote images are validated against `images.remotePatterns` and
|
|
19
18
|
* `images.domains` from next.config.js. Unmatched URLs are blocked
|
|
20
19
|
* in production and warn in development, matching Next.js behavior.
|
|
21
|
-
*/
|
|
22
|
-
/**
|
|
23
|
-
* Image config injected at build time via Vite define.
|
|
24
|
-
* Serialized as JSON — parsed once at module level.
|
|
25
|
-
*/
|
|
26
|
-
const __imageRemotePatterns = (() => {
|
|
27
|
-
try {
|
|
28
|
-
return JSON.parse(process.env.__VINEXT_IMAGE_REMOTE_PATTERNS ?? "[]");
|
|
29
|
-
} catch {
|
|
30
|
-
return [];
|
|
31
|
-
}
|
|
32
|
-
})();
|
|
33
|
-
const __imageDomains = (() => {
|
|
34
|
-
try {
|
|
35
|
-
return JSON.parse(process.env.__VINEXT_IMAGE_DOMAINS ?? "[]");
|
|
36
|
-
} catch {
|
|
37
|
-
return [];
|
|
38
|
-
}
|
|
39
|
-
})();
|
|
40
|
-
const __hasImageConfig = __imageRemotePatterns.length > 0 || __imageDomains.length > 0;
|
|
41
|
-
const __isDev = process.env.NODE_ENV !== "production";
|
|
42
|
-
const __imageDeviceSizes = (() => {
|
|
43
|
-
try {
|
|
44
|
-
return JSON.parse(process.env.__VINEXT_IMAGE_DEVICE_SIZES ?? "[640,750,828,1080,1200,1920,2048,3840]");
|
|
45
|
-
} catch {
|
|
46
|
-
return [
|
|
47
|
-
640,
|
|
48
|
-
750,
|
|
49
|
-
828,
|
|
50
|
-
1080,
|
|
51
|
-
1200,
|
|
52
|
-
1920,
|
|
53
|
-
2048,
|
|
54
|
-
3840
|
|
55
|
-
];
|
|
56
|
-
}
|
|
57
|
-
})();
|
|
58
|
-
const __imageSizes = (() => {
|
|
59
|
-
try {
|
|
60
|
-
return JSON.parse(process.env.__VINEXT_IMAGE_SIZES ?? "[32,48,64,96,128,256,384]");
|
|
61
|
-
} catch {
|
|
62
|
-
return [
|
|
63
|
-
32,
|
|
64
|
-
48,
|
|
65
|
-
64,
|
|
66
|
-
96,
|
|
67
|
-
128,
|
|
68
|
-
256,
|
|
69
|
-
384
|
|
70
|
-
];
|
|
71
|
-
}
|
|
72
|
-
})();
|
|
73
|
-
/**
|
|
74
|
-
* Whether dangerouslyAllowSVG is enabled in next.config.js.
|
|
75
|
-
* When false (default), .svg sources auto-skip the optimization endpoint
|
|
76
|
-
* and are served directly, matching Next.js behavior.
|
|
77
|
-
* When true, .svg sources are routed through the optimizer (served as-is
|
|
78
|
-
* with security headers).
|
|
79
|
-
*/
|
|
80
|
-
const __dangerouslyAllowSVG = process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_SVG === "true";
|
|
81
|
-
/**
|
|
82
|
-
* Whether dangerouslyAllowLocalIP is enabled in next.config.js.
|
|
83
|
-
* When false (default), remote image URLs with literal private-IP hostnames
|
|
84
|
-
* are blocked to mitigate SSRF risk.
|
|
85
|
-
*/
|
|
86
|
-
const __dangerouslyAllowLocalIP = process.env.__VINEXT_IMAGE_DANGEROUSLY_ALLOW_LOCAL_IP === "true";
|
|
87
|
-
const __globallyUnoptimized = process.env.__VINEXT_IMAGE_UNOPTIMIZED === "true";
|
|
88
|
-
/**
|
|
89
|
-
* Validate that a remote URL is allowed by the configured remote patterns.
|
|
90
|
-
* Returns true if the URL is allowed, false otherwise.
|
|
91
|
-
*
|
|
92
|
-
* When no remotePatterns/domains are configured, all remote URLs are allowed
|
|
93
|
-
* (backwards-compatible — user hasn't opted into restriction).
|
|
94
|
-
*
|
|
95
|
-
* When patterns ARE configured, only matching URLs are allowed.
|
|
96
|
-
* In development, non-matching URLs produce a console warning.
|
|
97
|
-
* In production, non-matching URLs are blocked (src replaced with empty string).
|
|
98
20
|
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
21
|
+
* Prop building lives in the server-safe `image-props.ts`. In the RSC
|
|
22
|
+
* environment, next/image resolves to a server entry that exports
|
|
23
|
+
* `getImageProps` from there and this module's Image as a client reference.
|
|
101
24
|
*/
|
|
102
|
-
function validateRemoteUrl(src) {
|
|
103
|
-
let url;
|
|
104
|
-
try {
|
|
105
|
-
url = new URL(src, "http://n");
|
|
106
|
-
} catch {
|
|
107
|
-
return {
|
|
108
|
-
allowed: false,
|
|
109
|
-
reason: `Invalid URL: ${src}`
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
if (!__dangerouslyAllowLocalIP && isPrivateIp(url.hostname)) return {
|
|
113
|
-
allowed: false,
|
|
114
|
-
reason: `Image URL "${src}" resolved to private IP. If this is expected and you understand SSRF risk, use images.dangerouslyAllowLocalIP = true to continue.`
|
|
115
|
-
};
|
|
116
|
-
if (!__hasImageConfig) return { allowed: true };
|
|
117
|
-
if (hasRemoteMatch(__imageDomains, __imageRemotePatterns, url)) return { allowed: true };
|
|
118
|
-
return {
|
|
119
|
-
allowed: false,
|
|
120
|
-
reason: `Image URL "${src}" is not configured in images.remotePatterns or images.domains in next.config.js. See: https://nextjs.org/docs/messages/next-image-unconfigured-host`
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
25
|
/**
|
|
124
26
|
* A version of useLayoutEffect that doesn't warn during SSR.
|
|
125
27
|
* Do not rename this to "isomorphic layout effect". There is no such thing as
|
|
@@ -167,110 +69,6 @@ function createSyntheticLoadEvent(img) {
|
|
|
167
69
|
}
|
|
168
70
|
};
|
|
169
71
|
}
|
|
170
|
-
/**
|
|
171
|
-
* Sanitize a blurDataURL to prevent CSS injection.
|
|
172
|
-
*
|
|
173
|
-
* A crafted data URL containing `)` can break out of the `url()` CSS function,
|
|
174
|
-
* allowing injection of arbitrary CSS properties or rules. Characters like `{`,
|
|
175
|
-
* `}`, and `\` can also assist in crafting injection payloads.
|
|
176
|
-
*
|
|
177
|
-
* This validates the URL starts with `data:image/` and rejects characters that
|
|
178
|
-
* could escape the `url()` context. Semicolons are allowed since they're part
|
|
179
|
-
* of valid data URLs (`data:image/png;base64,...`) and harmless inside `url()`.
|
|
180
|
-
*
|
|
181
|
-
* Returns undefined for invalid URLs, which causes the blur placeholder to be
|
|
182
|
-
* skipped gracefully.
|
|
183
|
-
*/
|
|
184
|
-
function sanitizeBlurDataURL(url) {
|
|
185
|
-
if (!url.startsWith("data:image/")) return void 0;
|
|
186
|
-
if (/[)(}{\\'"\n\r]/.test(url)) return void 0;
|
|
187
|
-
return url;
|
|
188
|
-
}
|
|
189
|
-
/**
|
|
190
|
-
* Determine if a src is a remote URL (CDN-optimizable) or local.
|
|
191
|
-
*/
|
|
192
|
-
function isRemoteUrl(src) {
|
|
193
|
-
return src.startsWith("http://") || src.startsWith("https://") || src.startsWith("//");
|
|
194
|
-
}
|
|
195
|
-
function isSvgUrl(src) {
|
|
196
|
-
try {
|
|
197
|
-
return new URL(src, "http://vinext.local").pathname.toLowerCase().endsWith(".svg");
|
|
198
|
-
} catch {
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
function getFillStyle(style, backgroundStyle) {
|
|
203
|
-
return {
|
|
204
|
-
position: "absolute",
|
|
205
|
-
inset: 0,
|
|
206
|
-
width: "100%",
|
|
207
|
-
height: "100%",
|
|
208
|
-
objectFit: "cover",
|
|
209
|
-
...backgroundStyle,
|
|
210
|
-
...style
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* Resolve src, width, height, blurDataURL from Image props (string or StaticImageData).
|
|
215
|
-
* Shared by the Image component and getImageProps to keep behavior in sync.
|
|
216
|
-
*/
|
|
217
|
-
function resolveImageSource(v) {
|
|
218
|
-
const staticData = typeof v.src === "object" && "default" in v.src ? v.src.default : v.src;
|
|
219
|
-
const src = typeof staticData === "string" ? staticData : staticData.src;
|
|
220
|
-
const sourceWidth = v.width ?? (typeof staticData === "object" ? staticData.width : void 0);
|
|
221
|
-
const sourceHeight = v.height ?? (typeof staticData === "object" ? staticData.height : void 0);
|
|
222
|
-
return {
|
|
223
|
-
src,
|
|
224
|
-
width: typeof sourceWidth === "string" ? Number(sourceWidth) : sourceWidth,
|
|
225
|
-
height: typeof sourceHeight === "string" ? Number(sourceHeight) : sourceHeight,
|
|
226
|
-
blurDataURL: v.blurDataURL ?? (typeof staticData === "object" ? staticData.blurDataURL : void 0)
|
|
227
|
-
};
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Responsive image widths matching Next.js's device sizes config.
|
|
231
|
-
* These are the breakpoints used for srcSet generation.
|
|
232
|
-
* Configurable via `images.deviceSizes` in next.config.js.
|
|
233
|
-
*/
|
|
234
|
-
const RESPONSIVE_WIDTHS = [...__imageDeviceSizes].sort((left, right) => left - right);
|
|
235
|
-
const ALL_IMAGE_WIDTHS = [...RESPONSIVE_WIDTHS, ...__imageSizes].sort((left, right) => left - right);
|
|
236
|
-
function extractLocalDeploymentId(src) {
|
|
237
|
-
let deploymentId = getDeploymentId();
|
|
238
|
-
if (!src.startsWith("/") || src.startsWith("//")) return {
|
|
239
|
-
src,
|
|
240
|
-
deploymentId
|
|
241
|
-
};
|
|
242
|
-
const queryIndex = src.indexOf("?");
|
|
243
|
-
if (queryIndex === -1) return {
|
|
244
|
-
src,
|
|
245
|
-
deploymentId
|
|
246
|
-
};
|
|
247
|
-
const params = new URLSearchParams(src.slice(queryIndex + 1));
|
|
248
|
-
const sourceDeploymentId = params.get("dpl");
|
|
249
|
-
if (!sourceDeploymentId) return {
|
|
250
|
-
src,
|
|
251
|
-
deploymentId
|
|
252
|
-
};
|
|
253
|
-
deploymentId = sourceDeploymentId;
|
|
254
|
-
params.delete("dpl");
|
|
255
|
-
const remainingQuery = params.toString();
|
|
256
|
-
return {
|
|
257
|
-
src: src.slice(0, queryIndex) + (remainingQuery ? `?${remainingQuery}` : ""),
|
|
258
|
-
deploymentId
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
const __imageEndpoint = `${process.env.__NEXT_ROUTER_BASEPATH ?? ""}/_next/image${process.env.__VINEXT_TRAILING_SLASH === "true" ? "/" : ""}`;
|
|
262
|
-
/**
|
|
263
|
-
* Build a `/_next/image` optimization URL.
|
|
264
|
-
*
|
|
265
|
-
* In production (Cloudflare Workers), the worker intercepts this path and uses
|
|
266
|
-
* the Images binding to resize/transcode on the fly. In dev, the Vite dev
|
|
267
|
-
* server handles it as a passthrough (serves the original file).
|
|
268
|
-
*/
|
|
269
|
-
function imageOptimizationUrl(src, width, quality = 75) {
|
|
270
|
-
const source = extractLocalDeploymentId(src);
|
|
271
|
-
const deploymentQuery = source.src.startsWith("/") && source.deploymentId ? `&dpl=${source.deploymentId}` : "";
|
|
272
|
-
return `${__imageEndpoint}?url=${encodeURIComponent(source.src)}&w=${width}&q=${quality}${deploymentQuery}`;
|
|
273
|
-
}
|
|
274
72
|
function preloadImageResource(input) {
|
|
275
73
|
if (!input.shouldPreload) return;
|
|
276
74
|
if (typeof ReactDOM.preload !== "function") return;
|
|
@@ -281,31 +79,6 @@ function preloadImageResource(input) {
|
|
|
281
79
|
fetchPriority: input.fetchPriority
|
|
282
80
|
});
|
|
283
81
|
}
|
|
284
|
-
/**
|
|
285
|
-
* Generate a srcSet string for responsive images.
|
|
286
|
-
*
|
|
287
|
-
* Each width points to the `/_next/image` optimization endpoint so the
|
|
288
|
-
* server can resize and transcode the image.
|
|
289
|
-
*/
|
|
290
|
-
function getImageWidths(width) {
|
|
291
|
-
return [...new Set([width, width * 2].map((targetWidth) => ALL_IMAGE_WIDTHS.find((configuredWidth) => configuredWidth >= targetWidth) ?? ALL_IMAGE_WIDTHS[ALL_IMAGE_WIDTHS.length - 1]))];
|
|
292
|
-
}
|
|
293
|
-
function generateImageAttributes(src, width, quality = 75, sizes) {
|
|
294
|
-
if (sizes) {
|
|
295
|
-
const viewportPercentages = Array.from(sizes.matchAll(/(^|\s)(1?\d?\d)vw/g), (match) => Number.parseInt(match[2], 10));
|
|
296
|
-
const minimumWidth = viewportPercentages.length > 0 ? RESPONSIVE_WIDTHS[0] * (Math.min(...viewportPercentages) * .01) : 0;
|
|
297
|
-
const candidates = ALL_IMAGE_WIDTHS.filter((candidateWidth) => candidateWidth >= minimumWidth);
|
|
298
|
-
return {
|
|
299
|
-
src: imageOptimizationUrl(src, candidates[candidates.length - 1], quality),
|
|
300
|
-
srcSet: candidates.map((candidateWidth) => `${imageOptimizationUrl(src, candidateWidth, quality)} ${candidateWidth}w`).join(", ")
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
const widths = getImageWidths(width);
|
|
304
|
-
return {
|
|
305
|
-
src: imageOptimizationUrl(src, widths[widths.length - 1], quality),
|
|
306
|
-
srcSet: widths.map((candidateWidth, index) => `${imageOptimizationUrl(src, candidateWidth, quality)} ${index + 1}x`).join(", ")
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
82
|
const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill, preload, priority, quality, placeholder, blurDataURL, loader, sizes, className, style, onLoad, onLoadingComplete, onError, unoptimized: _unoptimized, overrideSrc, loading, ...rest }, ref) {
|
|
310
83
|
const lastLoadedSrcRef = useRef(void 0);
|
|
311
84
|
const lastErrorSrcRef = useRef(void 0);
|
|
@@ -562,93 +335,5 @@ const Image = forwardRef(function Image({ src: srcProp, alt, width, height, fill
|
|
|
562
335
|
...rest
|
|
563
336
|
});
|
|
564
337
|
});
|
|
565
|
-
/**
|
|
566
|
-
* getImageProps — for advanced use cases (picture elements, background images).
|
|
567
|
-
* Returns the props that would be passed to the underlying <img> element.
|
|
568
|
-
*/
|
|
569
|
-
function getImageProps(props) {
|
|
570
|
-
const { src: srcProp, alt, width, height, fill, preload: _preload, priority, quality: _quality, placeholder, blurDataURL: blurDataURLProp, loader, sizes, className, style, onLoad: _onLoad, onLoadingComplete: _onLoadingComplete, unoptimized: _unoptimized, overrideSrc, loading, ...rest } = props;
|
|
571
|
-
const { src, width: imgWidth, height: imgHeight, blurDataURL: imgBlurDataURL } = resolveImageSource({
|
|
572
|
-
src: srcProp,
|
|
573
|
-
width,
|
|
574
|
-
height,
|
|
575
|
-
blurDataURL: blurDataURLProp
|
|
576
|
-
});
|
|
577
|
-
const shouldPreload = _preload === true || priority === true;
|
|
578
|
-
if (_unoptimized === true || __globallyUnoptimized) {
|
|
579
|
-
const renderedSrc = overrideSrc || src;
|
|
580
|
-
const sanitizedBlurURL = imgBlurDataURL ? sanitizeBlurDataURL(imgBlurDataURL) : void 0;
|
|
581
|
-
const blurStyle = placeholder === "blur" && sanitizedBlurURL ? {
|
|
582
|
-
backgroundImage: `url(${sanitizedBlurURL})`,
|
|
583
|
-
backgroundSize: "cover",
|
|
584
|
-
backgroundRepeat: "no-repeat",
|
|
585
|
-
backgroundPosition: "center"
|
|
586
|
-
} : void 0;
|
|
587
|
-
const imageProps = {
|
|
588
|
-
src: renderedSrc,
|
|
589
|
-
alt,
|
|
590
|
-
width: fill ? void 0 : imgWidth,
|
|
591
|
-
height: fill ? void 0 : imgHeight,
|
|
592
|
-
loading: priority ? "eager" : shouldPreload ? loading : loading ?? "lazy",
|
|
593
|
-
fetchPriority: priority ? "high" : void 0,
|
|
594
|
-
decoding: "async",
|
|
595
|
-
className,
|
|
596
|
-
style: fill ? getFillStyle(style, blurStyle) : {
|
|
597
|
-
...blurStyle,
|
|
598
|
-
...style
|
|
599
|
-
},
|
|
600
|
-
...rest,
|
|
601
|
-
sizes: sizes ?? (fill ? "100vw" : void 0),
|
|
602
|
-
srcSet: void 0
|
|
603
|
-
};
|
|
604
|
-
return { props: Object.assign(imageProps, { "data-nimg": fill ? "fill" : "1" }) };
|
|
605
|
-
}
|
|
606
|
-
let blockedInProd = false;
|
|
607
|
-
if (isRemoteUrl(src)) {
|
|
608
|
-
const validation = validateRemoteUrl(src);
|
|
609
|
-
if (!validation.allowed) {
|
|
610
|
-
if (__isDev) console.warn(`[next/image] ${validation.reason}`);
|
|
611
|
-
else {
|
|
612
|
-
console.error(`[next/image] ${validation.reason}`);
|
|
613
|
-
blockedInProd = true;
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
const imgQuality = typeof _quality === "string" ? Number(_quality) : _quality ?? 75;
|
|
618
|
-
const resolvedSrc = blockedInProd ? "" : loader ? loader({
|
|
619
|
-
src,
|
|
620
|
-
width: imgWidth ?? 0,
|
|
621
|
-
quality: imgQuality
|
|
622
|
-
}) : src;
|
|
623
|
-
const skipOpt = isSvgUrl(resolvedSrc) && !__dangerouslyAllowSVG || blockedInProd || !!loader || isRemoteUrl(resolvedSrc);
|
|
624
|
-
const optimizedAttributes = imgWidth && !fill && !skipOpt ? generateImageAttributes(resolvedSrc, imgWidth, imgQuality, sizes) : null;
|
|
625
|
-
const optimizedSrc = skipOpt ? resolvedSrc : optimizedAttributes ? optimizedAttributes.src : imageOptimizationUrl(resolvedSrc, RESPONSIVE_WIDTHS[0], imgQuality);
|
|
626
|
-
const srcSet = optimizedAttributes?.srcSet;
|
|
627
|
-
const sanitizedBlurURL = imgBlurDataURL ? sanitizeBlurDataURL(imgBlurDataURL) : void 0;
|
|
628
|
-
const blurStyle = placeholder === "blur" && sanitizedBlurURL ? {
|
|
629
|
-
backgroundImage: `url(${sanitizedBlurURL})`,
|
|
630
|
-
backgroundSize: "cover",
|
|
631
|
-
backgroundRepeat: "no-repeat",
|
|
632
|
-
backgroundPosition: "center"
|
|
633
|
-
} : void 0;
|
|
634
|
-
const imageProps = {
|
|
635
|
-
src: optimizedSrc,
|
|
636
|
-
alt,
|
|
637
|
-
width: fill ? void 0 : imgWidth,
|
|
638
|
-
height: fill ? void 0 : imgHeight,
|
|
639
|
-
loading: priority ? "eager" : shouldPreload ? loading : loading ?? "lazy",
|
|
640
|
-
fetchPriority: priority ? "high" : void 0,
|
|
641
|
-
decoding: "async",
|
|
642
|
-
srcSet,
|
|
643
|
-
sizes: sizes ?? (fill ? "100vw" : void 0),
|
|
644
|
-
className,
|
|
645
|
-
style: fill ? getFillStyle(style, blurStyle) : {
|
|
646
|
-
...blurStyle,
|
|
647
|
-
...style
|
|
648
|
-
},
|
|
649
|
-
...rest
|
|
650
|
-
};
|
|
651
|
-
return { props: Object.assign(imageProps, { "data-nimg": fill ? "fill" : "1" }) };
|
|
652
|
-
}
|
|
653
338
|
//#endregion
|
|
654
339
|
export { Image as default, getImageProps, imageOptimizationUrl };
|
|
@@ -57,10 +57,17 @@ export declare function isRenderDynamicLatched(): boolean;
|
|
|
57
57
|
* already latched; check `isRenderDynamicLatched()` first.
|
|
58
58
|
*/
|
|
59
59
|
export declare function onRenderDynamicLatched(listener: () => void): () => void;
|
|
60
|
+
/**
|
|
61
|
+
* Record an invalid dynamic API use on `state`, keeping the first one, like
|
|
62
|
+
* Next.js's `workStore.invalidDynamicUsageError ??= error`.
|
|
63
|
+
*/
|
|
64
|
+
export declare function recordInvalidDynamicUsageError(state: VinextHeadersShimState, error: unknown): void;
|
|
60
65
|
export declare function markRenderRequestApiUsage(kind: RenderRequestApiKind): void;
|
|
61
66
|
export declare function throwIfStaticGenerationAccessError(): void;
|
|
62
67
|
/** Whether work is executing inside a cache boundary that owns its reuse. */
|
|
63
68
|
export declare function isInsideAnyCacheScope(): boolean;
|
|
69
|
+
/** The error a dynamic request API throws inside a public "use cache". */
|
|
70
|
+
export declare function createUseCacheAccessError(apiName: string): Error;
|
|
64
71
|
/**
|
|
65
72
|
* Throw if the current execution is inside a "use cache" or unstable_cache()
|
|
66
73
|
* scope. Called by dynamic request APIs (headers, cookies, connection) to
|
|
@@ -87,6 +87,14 @@ function propagateInvalidDynamicUsageError(state, error) {
|
|
|
87
87
|
if (target.invalidDynamicUsageError == null) target.invalidDynamicUsageError = error;
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Record an invalid dynamic API use on `state`, keeping the first one, like
|
|
92
|
+
* Next.js's `workStore.invalidDynamicUsageError ??= error`.
|
|
93
|
+
*/
|
|
94
|
+
function recordInvalidDynamicUsageError(state, error) {
|
|
95
|
+
state.invalidDynamicUsageError ??= error;
|
|
96
|
+
propagateInvalidDynamicUsageError(state, error);
|
|
97
|
+
}
|
|
90
98
|
function markRenderRequestApiUsage(kind) {
|
|
91
99
|
getHeadersShimState().renderRequestApiUsage.add(kind);
|
|
92
100
|
}
|
|
@@ -121,6 +129,10 @@ function _isInsideUnstableCache() {
|
|
|
121
129
|
function isInsideAnyCacheScope() {
|
|
122
130
|
return _getUseCacheGuardContext() !== null || _isInsideUnstableCache();
|
|
123
131
|
}
|
|
132
|
+
/** The error a dynamic request API throws inside a public "use cache". */
|
|
133
|
+
function createUseCacheAccessError(apiName) {
|
|
134
|
+
return /* @__PURE__ */ new Error(`\`${apiName}\` cannot be called inside "use cache". If you need this data inside a cached function, call \`${apiName}\` outside and pass the required data as an argument.`);
|
|
135
|
+
}
|
|
124
136
|
/**
|
|
125
137
|
* Throw if the current execution is inside a "use cache" or unstable_cache()
|
|
126
138
|
* scope. Called by dynamic request APIs (headers, cookies, connection) to
|
|
@@ -130,7 +142,7 @@ function isInsideAnyCacheScope() {
|
|
|
130
142
|
*/
|
|
131
143
|
function throwIfInsideCacheScope(apiName) {
|
|
132
144
|
if (_isInsidePublicUseCache()) {
|
|
133
|
-
const error =
|
|
145
|
+
const error = createUseCacheAccessError(apiName);
|
|
134
146
|
try {
|
|
135
147
|
const cacheCtx = _getUseCacheGuardContext();
|
|
136
148
|
if (cacheCtx) cacheCtx.invalidDynamicUsageError = error;
|
|
@@ -154,4 +166,4 @@ function getHeadersAccessPhase() {
|
|
|
154
166
|
return getHeadersShimState().phase;
|
|
155
167
|
}
|
|
156
168
|
//#endregion
|
|
157
|
-
export { createRenderDynamicLatch, getHeadersAccessPhase, getHeadersShimState, headersShimAls, isInsideAnyCacheScope, isRenderDynamicLatched, markDynamicUsage, markRenderRequestApiUsage, onRenderDynamicLatched, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|
|
169
|
+
export { createRenderDynamicLatch, createUseCacheAccessError, getHeadersAccessPhase, getHeadersShimState, headersShimAls, isInsideAnyCacheScope, isRenderDynamicLatched, markDynamicUsage, markRenderRequestApiUsage, onRenderDynamicLatched, recordInvalidDynamicUsageError, throwIfInsideCacheScope, throwIfStaticGenerationAccessError };
|
|
@@ -3,16 +3,19 @@ import { VinextLinkPrefetchRoute, VinextPagesLinkPrefetchRoute } from "../../cli
|
|
|
3
3
|
export type HybridClientOwner = "app" | "document" | "pages";
|
|
4
4
|
type HybridClientRouteMatches = {
|
|
5
5
|
appMatch: VinextLinkPrefetchRoute | null;
|
|
6
|
+
/** A Pages Router URL under `/api`, which only API routes serve. */
|
|
7
|
+
pagesApiRequest: boolean;
|
|
6
8
|
pagesMatch: VinextPagesLinkPrefetchRoute | null;
|
|
7
9
|
};
|
|
8
10
|
declare global {
|
|
9
11
|
interface Window {
|
|
12
|
+
__VINEXT_APP_ROUTE_HANDLERS__?: VinextLinkPrefetchRoute[];
|
|
10
13
|
__VINEXT_LINK_PREFETCH_ROUTES__?: VinextLinkPrefetchRoute[];
|
|
11
14
|
__VINEXT_PAGES_LINK_PREFETCH_ROUTES__?: VinextPagesLinkPrefetchRoute[];
|
|
12
15
|
}
|
|
13
16
|
}
|
|
14
17
|
export declare function resolveSameOriginAppPathname(href: string, basePath: string): string | null;
|
|
15
18
|
export declare function matchDirectHybridClientRoutes(href: string, basePath: string): HybridClientRouteMatches;
|
|
16
|
-
export declare function resolveMatchedHybridClientRouteOwner({ appMatch, pagesMatch }: HybridClientRouteMatches): HybridClientOwner | null;
|
|
19
|
+
export declare function resolveMatchedHybridClientRouteOwner({ appMatch, pagesApiRequest, pagesMatch }: HybridClientRouteMatches): HybridClientOwner | null;
|
|
17
20
|
export declare function resolveDirectHybridClientRouteOwner(href: string, basePath: string): HybridClientOwner | null;
|
|
18
21
|
//#endregion
|
|
@@ -2,11 +2,11 @@ import { stripBasePath } from "../../utils/base-path.js";
|
|
|
2
2
|
import { compareHybridRoutePatterns } from "../../routing/utils.js";
|
|
3
3
|
import { createRouteTrieCache, matchRouteWithTrie } from "../../routing/route-matching.js";
|
|
4
4
|
import { getLocalePathPrefix } from "../../utils/domain-locale.js";
|
|
5
|
+
import { hashRoutePathname } from "../../routing/hashed-route-patterns.js";
|
|
5
6
|
//#region src/shims/internal/hybrid-client-route-owner-direct.ts
|
|
6
7
|
const appRouteTrieCache = createRouteTrieCache();
|
|
8
|
+
const appRouteHandlerTrieCache = createRouteTrieCache();
|
|
7
9
|
const pagesRouteTrieCache = createRouteTrieCache();
|
|
8
|
-
const pagesPageRoutesCache = /* @__PURE__ */ new WeakMap();
|
|
9
|
-
const pagesApiRoutesCache = /* @__PURE__ */ new WeakMap();
|
|
10
10
|
function patternFromParts(parts) {
|
|
11
11
|
return "/" + parts.join("/");
|
|
12
12
|
}
|
|
@@ -32,34 +32,51 @@ function resolveSameOriginPathnames(href, basePath) {
|
|
|
32
32
|
function resolveSameOriginAppPathname(href, basePath) {
|
|
33
33
|
return resolveSameOriginPathnames(href, basePath)?.appPathname ?? null;
|
|
34
34
|
}
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
function patternPartRank(part) {
|
|
36
|
+
if (part === void 0) return 0;
|
|
37
|
+
if (!part.startsWith(":")) return 1;
|
|
38
|
+
if (part.endsWith("+")) return 3;
|
|
39
|
+
if (part.endsWith("*")) return 4;
|
|
40
|
+
return 2;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The route the App router picks when both match the same URL: the first part
|
|
44
|
+
* whose kind differs decides, static > dynamic > catch-all > optional
|
|
45
|
+
* catch-all, as in `routing/route-trie.ts`.
|
|
46
|
+
*/
|
|
47
|
+
function preferredAppRoute(page, handler) {
|
|
48
|
+
if (page === null || handler === null) return page ?? handler;
|
|
49
|
+
const length = Math.max(page.patternParts.length, handler.patternParts.length);
|
|
50
|
+
for (let index = 0; index < length; index++) {
|
|
51
|
+
const pageRank = patternPartRank(page.patternParts[index]);
|
|
52
|
+
const handlerRank = patternPartRank(handler.patternParts[index]);
|
|
53
|
+
if (pageRank !== handlerRank) return pageRank < handlerRank ? page : handler;
|
|
41
54
|
}
|
|
42
|
-
return
|
|
55
|
+
return page;
|
|
43
56
|
}
|
|
44
57
|
function matchDirectHybridClientRoutes(href, basePath) {
|
|
45
58
|
const pathnames = resolveSameOriginPathnames(href, basePath);
|
|
46
59
|
if (pathnames === null) return {
|
|
47
60
|
appMatch: null,
|
|
61
|
+
pagesApiRequest: false,
|
|
48
62
|
pagesMatch: null
|
|
49
63
|
};
|
|
50
64
|
const appRoutes = window.__VINEXT_LINK_PREFETCH_ROUTES__;
|
|
65
|
+
const appRouteHandlers = window.__VINEXT_APP_ROUTE_HANDLERS__;
|
|
51
66
|
const pagesRoutes = window.__VINEXT_PAGES_LINK_PREFETCH_ROUTES__;
|
|
52
67
|
return {
|
|
53
|
-
appMatch: appRoutes ? matchRouteWithTrie(pathnames.appPathname, appRoutes, appRouteTrieCache)?.route ?? null : null,
|
|
54
|
-
|
|
68
|
+
appMatch: preferredAppRoute(appRoutes ? matchRouteWithTrie(pathnames.appPathname, appRoutes, appRouteTrieCache)?.route ?? null : null, appRouteHandlers?.length ? matchRouteWithTrie(hashRoutePathname(pathnames.appPathname), appRouteHandlers, appRouteHandlerTrieCache)?.route ?? null : null),
|
|
69
|
+
pagesApiRequest: pathnames.pagesApiRequest,
|
|
70
|
+
pagesMatch: pagesRoutes && !pathnames.pagesApiRequest ? matchRouteWithTrie(pathnames.pagesPathname, pagesRoutes, pagesRouteTrieCache)?.route ?? null : null
|
|
55
71
|
};
|
|
56
72
|
}
|
|
57
|
-
function resolveMatchedHybridClientRouteOwner({ appMatch, pagesMatch }) {
|
|
73
|
+
function resolveMatchedHybridClientRouteOwner({ appMatch, pagesApiRequest, pagesMatch }) {
|
|
74
|
+
if (pagesApiRequest) return appMatch?.isDynamic === false && !appMatch.documentOnly ? "app" : "document";
|
|
58
75
|
if (appMatch === null && pagesMatch === null) return null;
|
|
59
76
|
if (pagesMatch === null) return appMatch.documentOnly ? "document" : "app";
|
|
60
|
-
if (appMatch === null) return
|
|
77
|
+
if (appMatch === null) return "pages";
|
|
61
78
|
const owner = compareHybridRoutePatterns(patternFromParts(pagesMatch.patternParts), pagesMatch.isDynamic, patternFromParts(appMatch.patternParts), appMatch.isDynamic);
|
|
62
|
-
return
|
|
79
|
+
return owner === "app" && appMatch.documentOnly ? "document" : owner;
|
|
63
80
|
}
|
|
64
81
|
function resolveDirectHybridClientRouteOwner(href, basePath) {
|
|
65
82
|
if (typeof window === "undefined") return null;
|
|
@@ -64,23 +64,23 @@ function resolveHybridClientRewriteHref(href, basePath) {
|
|
|
64
64
|
didRewrite = true;
|
|
65
65
|
}
|
|
66
66
|
let matches = matchDirectHybridClientRoutes(currentHref, basePath);
|
|
67
|
-
if ((matches.appMatch === null || matches.appMatch.isDynamic) && (matches.pagesMatch === null || matches.pagesMatch.isDynamic)) for (const rewrite of rewrites.afterFiles) {
|
|
67
|
+
if (!matches.pagesApiRequest && (matches.appMatch === null || matches.appMatch.isDynamic) && (matches.pagesMatch === null || matches.pagesMatch.isDynamic)) for (const rewrite of rewrites.afterFiles) {
|
|
68
68
|
const afterFilesRewrite = resolveClientRewrite(currentHref, basePath, [rewrite]);
|
|
69
69
|
if (afterFilesRewrite?.kind === "document") return didRewrite ? currentHref : null;
|
|
70
70
|
if (afterFilesRewrite?.kind !== "rewrite") continue;
|
|
71
71
|
currentHref = afterFilesRewrite.href;
|
|
72
72
|
didRewrite = true;
|
|
73
73
|
matches = matchDirectHybridClientRoutes(currentHref, basePath);
|
|
74
|
-
if (matches.appMatch || matches.pagesMatch) break;
|
|
74
|
+
if (matches.pagesApiRequest || matches.appMatch || matches.pagesMatch) break;
|
|
75
75
|
}
|
|
76
|
-
if (matches.appMatch === null && matches.pagesMatch === null) for (const rewrite of rewrites.fallback) {
|
|
76
|
+
if (!matches.pagesApiRequest && matches.appMatch === null && matches.pagesMatch === null) for (const rewrite of rewrites.fallback) {
|
|
77
77
|
const fallbackRewrite = resolveClientRewrite(currentHref, basePath, [rewrite]);
|
|
78
78
|
if (fallbackRewrite?.kind === "document") return didRewrite ? currentHref : null;
|
|
79
79
|
if (fallbackRewrite?.kind !== "rewrite") continue;
|
|
80
80
|
currentHref = fallbackRewrite.href;
|
|
81
81
|
didRewrite = true;
|
|
82
82
|
matches = matchDirectHybridClientRoutes(currentHref, basePath);
|
|
83
|
-
if (matches.appMatch || matches.pagesMatch) break;
|
|
83
|
+
if (matches.pagesApiRequest || matches.appMatch || matches.pagesMatch) break;
|
|
84
84
|
}
|
|
85
85
|
return didRewrite ? currentHref : null;
|
|
86
86
|
}
|
|
@@ -105,21 +105,21 @@ function resolveHybridClientRouteOwner(href, basePath) {
|
|
|
105
105
|
if (beforeFilesRewrite?.kind === "rewrite") href = beforeFilesRewrite.href;
|
|
106
106
|
}
|
|
107
107
|
let matches = matchDirectHybridClientRoutes(href, basePath);
|
|
108
|
-
if (rewrites && (matches.appMatch === null || matches.appMatch.isDynamic) && (matches.pagesMatch === null || matches.pagesMatch.isDynamic)) for (const rewrite of rewrites.afterFiles) {
|
|
108
|
+
if (rewrites && !matches.pagesApiRequest && (matches.appMatch === null || matches.appMatch.isDynamic) && (matches.pagesMatch === null || matches.pagesMatch.isDynamic)) for (const rewrite of rewrites.afterFiles) {
|
|
109
109
|
const afterFilesRewrite = resolveClientRewrite(href, basePath, [rewrite]);
|
|
110
110
|
if (afterFilesRewrite?.kind === "document") return "document";
|
|
111
111
|
if (afterFilesRewrite?.kind !== "rewrite") continue;
|
|
112
112
|
href = afterFilesRewrite.href;
|
|
113
113
|
matches = matchDirectHybridClientRoutes(href, basePath);
|
|
114
|
-
if (matches.appMatch || matches.pagesMatch) break;
|
|
114
|
+
if (matches.pagesApiRequest || matches.appMatch || matches.pagesMatch) break;
|
|
115
115
|
}
|
|
116
|
-
if (rewrites && matches.appMatch === null && matches.pagesMatch === null) for (const rewrite of rewrites.fallback) {
|
|
116
|
+
if (rewrites && !matches.pagesApiRequest && matches.appMatch === null && matches.pagesMatch === null) for (const rewrite of rewrites.fallback) {
|
|
117
117
|
const fallbackRewrite = resolveClientRewrite(href, basePath, [rewrite]);
|
|
118
118
|
if (fallbackRewrite?.kind === "document") return "document";
|
|
119
119
|
if (fallbackRewrite?.kind !== "rewrite") continue;
|
|
120
120
|
href = fallbackRewrite.href;
|
|
121
121
|
matches = matchDirectHybridClientRoutes(href, basePath);
|
|
122
|
-
if (matches.appMatch || matches.pagesMatch) break;
|
|
122
|
+
if (matches.pagesApiRequest || matches.appMatch || matches.pagesMatch) break;
|
|
123
123
|
}
|
|
124
124
|
return resolveMatchedHybridClientRouteOwner(matches);
|
|
125
125
|
}
|
package/dist/shims/link.js
CHANGED
|
@@ -11,7 +11,7 @@ import { formatUrlObject, formatUrlObjectWithValidation } from "./internal/forma
|
|
|
11
11
|
import { normalizeRouterHref, resolvePagesRouterHref } from "./internal/normalize-router-href.js";
|
|
12
12
|
import { getCurrentRoutePathnameForWarning } from "./internal/route-pattern-for-warning.js";
|
|
13
13
|
import { getCurrentBrowserLocale } from "./client-locale.js";
|
|
14
|
-
import { getNavigationRuntime, hasAppNavigationRuntime, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
14
|
+
import { getNavigationRuntime, hasAppNavigationRuntime, loadNavigationRuntimeRouteManifest, registerNavigationRuntimeFunctions } from "../client/navigation-runtime.js";
|
|
15
15
|
import { navigatePagesRouterLinkWithFallback, resolvePagesRouterQueryOnlyHref } from "../client/pages-router-link-navigation.js";
|
|
16
16
|
import { scheduleAppPrefetchFetch } from "./internal/app-prefetch-fetch-queue.js";
|
|
17
17
|
import { getI18nContext } from "./i18n-context.js";
|
|
@@ -139,15 +139,17 @@ function prefetchUrl(href, mode, priority = "low", pagesRouteHref, locale) {
|
|
|
139
139
|
(async () => {
|
|
140
140
|
if (hasAppNavigationRuntime()) {
|
|
141
141
|
if (isBotUserAgent(window.navigator?.userAgent ?? "")) return;
|
|
142
|
-
const [navigation, { AppElementsWire }, rscCacheBusting, { resolveAppPrefetchRscRequest }, { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL, APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL }, headersModule, hybridRouteOwner] = await Promise.all([
|
|
142
|
+
const [navigation, { AppElementsWire }, rscCacheBusting, { resolveAppPrefetchRscRequest }, { APP_RSC_RENDER_MODE_PREFETCH_DYNAMIC_SHELL, APP_RSC_RENDER_MODE_PREFETCH_LOADING_SHELL }, headersModule, hybridRouteOwner, routeManifestLoaded] = await Promise.all([
|
|
143
143
|
loadNavigationModule(),
|
|
144
144
|
import("../server/app-elements.js"),
|
|
145
145
|
import("../server/app-rsc-cache-busting.js"),
|
|
146
146
|
import("./internal/app-prefetch-rsc-request.js"),
|
|
147
147
|
import("../server/app-rsc-render-mode.js"),
|
|
148
148
|
import("../server/headers.js"),
|
|
149
|
-
HAS_PAGES_ROUTER || HAS_CLIENT_REWRITES ? loadHybridClientRouteOwnerModule() : null
|
|
149
|
+
HAS_PAGES_ROUTER || HAS_CLIENT_REWRITES ? loadHybridClientRouteOwnerModule() : null,
|
|
150
|
+
loadNavigationRuntimeRouteManifest()
|
|
150
151
|
]);
|
|
152
|
+
if (routeManifestLoaded === false) return;
|
|
151
153
|
if (navigationEpoch !== linkPrefetchNavigationEpoch) return;
|
|
152
154
|
const { getPrefetchInterceptionContext, getPrefetchCache, getPrefetchedUrls, getMountedSlotsHeader, createAppPrefetchRequestHeaders, discardLearningOnlyPrefetchCacheEntry, fetchRouteTreeGatedPrefetch, hasFreshLearningOnlyPrefetchCacheEntry, hasSearchAgnosticPrefetchShellForRoute, hasPrefetchCacheEntryForNavigation, prefetchRscResponse, prepareNavigationPrefetchSnapshot, DYNAMIC_NAVIGATION_CACHE_TTL, PREFETCH_CACHE_TTL } = navigation;
|
|
153
155
|
const { createRscRequestUrl } = rscCacheBusting;
|
|
@@ -86,7 +86,7 @@ export type PrefetchCacheEntry = {
|
|
|
86
86
|
timestamp: number;
|
|
87
87
|
};
|
|
88
88
|
export declare function getCurrentInterceptionContext(): string | null;
|
|
89
|
-
export declare function getPrefetchInterceptionContext(targetHref: string): string | null;
|
|
89
|
+
export declare function getPrefetchInterceptionContext(targetHref: string, currentPathname?: string): string | null;
|
|
90
90
|
export declare function getCurrentNextUrl(): string;
|
|
91
91
|
export declare function createAppPrefetchRequestHeaders(options: {
|
|
92
92
|
fetchPriority: "auto" | "high" | "low";
|