vinext 0.1.1 → 0.1.3

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.
Files changed (266) hide show
  1. package/README.md +2 -5
  2. package/dist/build/client-build-config.d.ts +7 -1
  3. package/dist/build/client-build-config.js +9 -1
  4. package/dist/build/prerender.d.ts +9 -1
  5. package/dist/build/prerender.js +41 -12
  6. package/dist/build/run-prerender.d.ts +10 -2
  7. package/dist/build/run-prerender.js +15 -1
  8. package/dist/check.js +4 -3
  9. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  10. package/dist/client/app-nav-failure-handler.js +44 -0
  11. package/dist/client/navigation-runtime.d.ts +3 -2
  12. package/dist/client/vinext-next-data.d.ts +18 -1
  13. package/dist/client/window-next.d.ts +8 -5
  14. package/dist/client/window-next.js +12 -1
  15. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  16. package/dist/config/config-matchers.d.ts +11 -4
  17. package/dist/config/config-matchers.js +88 -16
  18. package/dist/config/next-config.d.ts +59 -4
  19. package/dist/config/next-config.js +149 -48
  20. package/dist/deploy.d.ts +30 -11
  21. package/dist/deploy.js +189 -101
  22. package/dist/entries/app-browser-entry.d.ts +9 -3
  23. package/dist/entries/app-browser-entry.js +21 -3
  24. package/dist/entries/app-rsc-entry.d.ts +2 -0
  25. package/dist/entries/app-rsc-entry.js +71 -6
  26. package/dist/entries/app-rsc-manifest.js +2 -0
  27. package/dist/entries/app-ssr-entry.js +1 -1
  28. package/dist/entries/pages-client-entry.js +54 -9
  29. package/dist/entries/pages-server-entry.js +48 -11
  30. package/dist/index.d.ts +0 -2
  31. package/dist/index.js +285 -139
  32. package/dist/plugins/dynamic-preload-metadata.d.ts +13 -0
  33. package/dist/plugins/dynamic-preload-metadata.js +415 -0
  34. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  35. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  36. package/dist/plugins/og-assets.js +2 -2
  37. package/dist/plugins/optimize-imports.d.ts +10 -5
  38. package/dist/plugins/optimize-imports.js +27 -21
  39. package/dist/plugins/postcss.js +7 -7
  40. package/dist/plugins/sass.d.ts +53 -24
  41. package/dist/plugins/sass.js +249 -1
  42. package/dist/plugins/typeof-window.d.ts +14 -0
  43. package/dist/plugins/typeof-window.js +150 -0
  44. package/dist/plugins/wasm-module-import.d.ts +15 -0
  45. package/dist/plugins/wasm-module-import.js +50 -0
  46. package/dist/routing/app-route-graph.d.ts +25 -2
  47. package/dist/routing/app-route-graph.js +91 -22
  48. package/dist/routing/file-matcher.d.ts +10 -1
  49. package/dist/routing/file-matcher.js +23 -2
  50. package/dist/routing/pages-router.js +3 -3
  51. package/dist/routing/utils.d.ts +35 -6
  52. package/dist/routing/utils.js +59 -7
  53. package/dist/server/api-handler.d.ts +6 -1
  54. package/dist/server/api-handler.js +21 -15
  55. package/dist/server/app-browser-action-result.d.ts +19 -6
  56. package/dist/server/app-browser-action-result.js +19 -10
  57. package/dist/server/app-browser-entry.js +269 -297
  58. package/dist/server/app-browser-error.d.ts +10 -3
  59. package/dist/server/app-browser-error.js +47 -6
  60. package/dist/server/app-browser-history-controller.d.ts +104 -0
  61. package/dist/server/app-browser-history-controller.js +210 -0
  62. package/dist/server/app-browser-hydration.d.ts +2 -0
  63. package/dist/server/app-browser-hydration.js +1 -0
  64. package/dist/server/app-browser-navigation-controller.d.ts +7 -4
  65. package/dist/server/app-browser-navigation-controller.js +33 -9
  66. package/dist/server/app-browser-rsc-redirect.d.ts +11 -2
  67. package/dist/server/app-browser-rsc-redirect.js +30 -8
  68. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  69. package/dist/server/app-browser-server-action-navigation.js +9 -0
  70. package/dist/server/app-browser-state.js +4 -7
  71. package/dist/server/app-browser-stream.js +86 -43
  72. package/dist/server/app-browser-visible-commit.js +1 -1
  73. package/dist/server/app-elements-wire.d.ts +6 -1
  74. package/dist/server/app-elements-wire.js +14 -4
  75. package/dist/server/app-elements.d.ts +2 -2
  76. package/dist/server/app-elements.js +2 -2
  77. package/dist/server/app-fallback-renderer.d.ts +3 -1
  78. package/dist/server/app-fallback-renderer.js +6 -2
  79. package/dist/server/app-middleware.js +1 -0
  80. package/dist/server/app-optimistic-routing.js +24 -3
  81. package/dist/server/app-page-boundary-render.d.ts +3 -1
  82. package/dist/server/app-page-boundary-render.js +31 -16
  83. package/dist/server/app-page-cache-render.d.ts +53 -0
  84. package/dist/server/app-page-cache-render.js +91 -0
  85. package/dist/server/app-page-cache.d.ts +16 -2
  86. package/dist/server/app-page-cache.js +71 -8
  87. package/dist/server/app-page-dispatch.d.ts +34 -0
  88. package/dist/server/app-page-dispatch.js +167 -97
  89. package/dist/server/app-page-element-builder.d.ts +23 -2
  90. package/dist/server/app-page-element-builder.js +42 -10
  91. package/dist/server/app-page-execution.d.ts +7 -2
  92. package/dist/server/app-page-execution.js +53 -18
  93. package/dist/server/app-page-probe.d.ts +1 -0
  94. package/dist/server/app-page-probe.js +4 -0
  95. package/dist/server/app-page-render-observation.d.ts +3 -1
  96. package/dist/server/app-page-render-observation.js +17 -1
  97. package/dist/server/app-page-render.d.ts +13 -2
  98. package/dist/server/app-page-render.js +48 -17
  99. package/dist/server/app-page-request.d.ts +3 -0
  100. package/dist/server/app-page-request.js +5 -3
  101. package/dist/server/app-page-response.js +1 -1
  102. package/dist/server/app-page-route-wiring.d.ts +5 -1
  103. package/dist/server/app-page-route-wiring.js +21 -11
  104. package/dist/server/app-page-stream.d.ts +16 -9
  105. package/dist/server/app-page-stream.js +12 -9
  106. package/dist/server/app-pages-bridge.d.ts +18 -0
  107. package/dist/server/app-pages-bridge.js +22 -5
  108. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  109. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  110. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  111. package/dist/server/app-ppr-fallback-shell.js +8 -1
  112. package/dist/server/app-route-handler-dispatch.js +9 -2
  113. package/dist/server/app-route-handler-policy.d.ts +1 -0
  114. package/dist/server/app-route-handler-response.js +11 -10
  115. package/dist/server/app-route-handler-runtime.js +12 -1
  116. package/dist/server/app-router-entry.js +5 -0
  117. package/dist/server/app-rsc-cache-busting.js +2 -0
  118. package/dist/server/app-rsc-handler.d.ts +25 -0
  119. package/dist/server/app-rsc-handler.js +153 -53
  120. package/dist/server/app-rsc-response-finalizer.js +1 -1
  121. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  122. package/dist/server/app-rsc-route-matching.js +2 -0
  123. package/dist/server/app-segment-config.d.ts +9 -1
  124. package/dist/server/app-segment-config.js +12 -3
  125. package/dist/server/app-server-action-execution.d.ts +12 -0
  126. package/dist/server/app-server-action-execution.js +47 -15
  127. package/dist/server/app-ssr-entry.d.ts +2 -0
  128. package/dist/server/app-ssr-entry.js +81 -8
  129. package/dist/server/app-ssr-stream.js +9 -1
  130. package/dist/server/cache-control.js +4 -0
  131. package/dist/server/dev-lockfile.js +2 -1
  132. package/dist/server/dev-server.d.ts +2 -2
  133. package/dist/server/dev-server.js +287 -63
  134. package/dist/server/headers.d.ts +8 -1
  135. package/dist/server/headers.js +8 -1
  136. package/dist/server/hybrid-route-priority.d.ts +22 -0
  137. package/dist/server/hybrid-route-priority.js +33 -0
  138. package/dist/server/image-optimization.d.ts +18 -9
  139. package/dist/server/image-optimization.js +37 -23
  140. package/dist/server/implicit-tags.d.ts +2 -1
  141. package/dist/server/implicit-tags.js +4 -1
  142. package/dist/server/instrumentation-runtime.d.ts +6 -0
  143. package/dist/server/instrumentation-runtime.js +8 -0
  144. package/dist/server/isr-decision.d.ts +79 -0
  145. package/dist/server/isr-decision.js +70 -0
  146. package/dist/server/metadata-route-response.js +5 -3
  147. package/dist/server/middleware-runtime.d.ts +13 -0
  148. package/dist/server/middleware-runtime.js +11 -7
  149. package/dist/server/middleware.js +1 -0
  150. package/dist/server/navigation-planner.d.ts +186 -22
  151. package/dist/server/navigation-planner.js +302 -0
  152. package/dist/server/navigation-trace.d.ts +18 -1
  153. package/dist/server/navigation-trace.js +18 -1
  154. package/dist/server/normalize-path.d.ts +0 -8
  155. package/dist/server/normalize-path.js +3 -1
  156. package/dist/server/otel-tracer-extension.d.ts +45 -0
  157. package/dist/server/otel-tracer-extension.js +89 -0
  158. package/dist/server/pages-api-route.d.ts +20 -3
  159. package/dist/server/pages-api-route.js +19 -3
  160. package/dist/server/pages-asset-tags.d.ts +16 -4
  161. package/dist/server/pages-asset-tags.js +22 -12
  162. package/dist/server/pages-data-route.d.ts +8 -1
  163. package/dist/server/pages-data-route.js +16 -3
  164. package/dist/server/pages-get-initial-props.d.ts +54 -4
  165. package/dist/server/pages-get-initial-props.js +43 -1
  166. package/dist/server/pages-node-compat.d.ts +3 -11
  167. package/dist/server/pages-node-compat.js +175 -122
  168. package/dist/server/pages-page-data.d.ts +39 -2
  169. package/dist/server/pages-page-data.js +261 -46
  170. package/dist/server/pages-page-handler.d.ts +5 -2
  171. package/dist/server/pages-page-handler.js +78 -25
  172. package/dist/server/pages-page-response.d.ts +47 -2
  173. package/dist/server/pages-page-response.js +73 -9
  174. package/dist/server/pages-readiness.d.ts +1 -1
  175. package/dist/server/pages-request-pipeline.d.ts +16 -1
  176. package/dist/server/pages-request-pipeline.js +96 -38
  177. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  178. package/dist/server/pregenerated-concrete-paths.js +2 -19
  179. package/dist/server/prerender-manifest.d.ts +33 -0
  180. package/dist/server/prerender-manifest.js +54 -0
  181. package/dist/server/prerender-route-params.d.ts +1 -2
  182. package/dist/server/prod-server.d.ts +39 -1
  183. package/dist/server/prod-server.js +107 -37
  184. package/dist/server/request-pipeline.d.ts +3 -15
  185. package/dist/server/request-pipeline.js +58 -47
  186. package/dist/server/rsc-stream-hints.d.ts +5 -1
  187. package/dist/server/rsc-stream-hints.js +6 -1
  188. package/dist/server/seed-cache.js +10 -18
  189. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  190. package/dist/shims/app-router-scroll-state.js +14 -2
  191. package/dist/shims/app-router-scroll.d.ts +3 -0
  192. package/dist/shims/app-router-scroll.js +28 -18
  193. package/dist/shims/cache-runtime.js +12 -4
  194. package/dist/shims/cache.d.ts +1 -0
  195. package/dist/shims/cache.js +1 -1
  196. package/dist/shims/cdn-cache.d.ts +5 -5
  197. package/dist/shims/dynamic-preload-chunks.d.ts +8 -0
  198. package/dist/shims/dynamic-preload-chunks.js +79 -0
  199. package/dist/shims/dynamic.d.ts +4 -0
  200. package/dist/shims/dynamic.js +4 -2
  201. package/dist/shims/error-boundary.d.ts +6 -4
  202. package/dist/shims/error-boundary.js +7 -0
  203. package/dist/shims/error.js +38 -11
  204. package/dist/shims/error.react-server.d.ts +9 -0
  205. package/dist/shims/error.react-server.js +6 -0
  206. package/dist/shims/fetch-cache.d.ts +11 -1
  207. package/dist/shims/fetch-cache.js +55 -20
  208. package/dist/shims/hash-scroll.js +6 -1
  209. package/dist/shims/head.js +6 -1
  210. package/dist/shims/headers.d.ts +16 -2
  211. package/dist/shims/headers.js +66 -5
  212. package/dist/shims/image-config.js +7 -1
  213. package/dist/shims/internal/als-registry.js +28 -1
  214. package/dist/shims/internal/app-route-detection.d.ts +6 -3
  215. package/dist/shims/internal/app-route-detection.js +18 -23
  216. package/dist/shims/internal/app-router-context.d.ts +5 -0
  217. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  218. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  219. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  220. package/dist/shims/internal/navigation-untracked.js +55 -0
  221. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  222. package/dist/shims/internal/pages-data-target.js +17 -8
  223. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  224. package/dist/shims/internal/pages-router-accessor.js +13 -0
  225. package/dist/shims/internal/router-context.d.ts +2 -1
  226. package/dist/shims/internal/router-context.js +3 -1
  227. package/dist/shims/link.js +12 -5
  228. package/dist/shims/metadata.d.ts +6 -2
  229. package/dist/shims/metadata.js +32 -14
  230. package/dist/shims/navigation.d.ts +14 -17
  231. package/dist/shims/navigation.js +93 -46
  232. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  233. package/dist/shims/ppr-fallback-shell.js +28 -7
  234. package/dist/shims/router.d.ts +13 -2
  235. package/dist/shims/router.js +434 -116
  236. package/dist/shims/script-nonce-context.d.ts +1 -1
  237. package/dist/shims/script-nonce-context.js +11 -3
  238. package/dist/shims/server.d.ts +33 -2
  239. package/dist/shims/server.js +75 -18
  240. package/dist/shims/slot.js +1 -1
  241. package/dist/shims/unified-request-context.js +2 -0
  242. package/dist/typegen.js +1 -0
  243. package/dist/utils/built-asset-url.d.ts +4 -0
  244. package/dist/utils/built-asset-url.js +11 -0
  245. package/dist/utils/client-build-manifest.js +15 -5
  246. package/dist/utils/client-runtime-metadata.d.ts +45 -0
  247. package/dist/utils/client-runtime-metadata.js +63 -0
  248. package/dist/utils/commonjs-loader.d.ts +16 -0
  249. package/dist/utils/commonjs-loader.js +100 -0
  250. package/dist/utils/deployment-id.d.ts +8 -0
  251. package/dist/utils/deployment-id.js +22 -0
  252. package/dist/utils/hash.d.ts +17 -1
  253. package/dist/utils/hash.js +36 -1
  254. package/dist/utils/html-limited-bots.d.ts +18 -1
  255. package/dist/utils/html-limited-bots.js +23 -1
  256. package/dist/utils/lazy-chunks.d.ts +27 -1
  257. package/dist/utils/lazy-chunks.js +65 -1
  258. package/dist/utils/manifest-paths.d.ts +20 -2
  259. package/dist/utils/manifest-paths.js +38 -3
  260. package/dist/utils/parse-cookie.d.ts +13 -0
  261. package/dist/utils/parse-cookie.js +52 -0
  262. package/dist/utils/path.d.ts +8 -1
  263. package/dist/utils/path.js +13 -1
  264. package/package.json +2 -2
  265. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  266. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
 
3
3
  //#region src/shims/script-nonce-context.d.ts
4
- declare const ScriptNonceContext: React.Context<string | undefined>;
4
+ declare const ScriptNonceContext: React.Context<string | undefined> | null;
5
5
  declare function ScriptNonceProvider(props: React.PropsWithChildren<{
6
6
  nonce?: string;
7
7
  }>): React.ReactElement;
@@ -1,15 +1,23 @@
1
1
  import React from "react";
2
2
  //#region src/shims/script-nonce-context.tsx
3
- const ScriptNonceContext = React.createContext(void 0);
3
+ const ScriptNonceContext = typeof React.createContext === "function" ? React.createContext(void 0) : null;
4
4
  function ScriptNonceProvider(props) {
5
+ if (!ScriptNonceContext) return React.createElement(React.Fragment, null, props.children);
5
6
  return React.createElement(ScriptNonceContext.Provider, { value: props.nonce }, props.children);
6
7
  }
7
8
  function withScriptNonce(element, nonce) {
8
- if (!nonce) return element;
9
+ if (!nonce || !ScriptNonceContext) return element;
9
10
  return React.createElement(ScriptNonceProvider, { nonce }, element);
10
11
  }
12
+ function createScriptNonceHook(context) {
13
+ if (!context || typeof React.useContext !== "function") return function useScriptNonceFromContext() {};
14
+ return function useScriptNonceFromContext() {
15
+ return React.useContext(context);
16
+ };
17
+ }
18
+ const useScriptNonceFromContext = createScriptNonceHook(ScriptNonceContext);
11
19
  function useScriptNonce() {
12
- return React.useContext(ScriptNonceContext);
20
+ return useScriptNonceFromContext();
13
21
  }
14
22
  //#endregion
15
23
  export { ScriptNonceContext, ScriptNonceProvider, useScriptNonce, withScriptNonce };
@@ -19,6 +19,11 @@ declare class NextRequest extends Request {
19
19
  i18n?: {
20
20
  locales: string[];
21
21
  defaultLocale: string;
22
+ domains?: Array<{
23
+ domain: string;
24
+ defaultLocale: string;
25
+ locales?: string[];
26
+ }>;
22
27
  };
23
28
  trailingSlash?: boolean;
24
29
  };
@@ -78,6 +83,11 @@ type NextURLConfig = {
78
83
  i18n?: {
79
84
  locales: string[];
80
85
  defaultLocale: string;
86
+ domains?: Array<{
87
+ domain: string;
88
+ defaultLocale: string;
89
+ locales?: string[];
90
+ }>;
81
91
  };
82
92
  /**
83
93
  * When true, `href`/`toString()` formats non-root, non-file-like pathnames
@@ -91,16 +101,36 @@ type NextURLConfig = {
91
101
  declare class NextURL {
92
102
  /** Internal URL stores the pathname WITHOUT basePath or locale prefix. */
93
103
  private _url;
104
+ /**
105
+ * The configured basePath (from nextConfig). May differ from the active
106
+ * `_basePath`: parsing only activates basePath when the URL's pathname
107
+ * actually carries the configured prefix.
108
+ */
109
+ private _configBasePath;
94
110
  private _basePath;
95
111
  private _trailingSlash;
96
112
  private _locale;
113
+ private _configDefaultLocale;
97
114
  private _defaultLocale;
98
115
  private _locales;
116
+ private _domains;
117
+ private _domainLocale;
99
118
  constructor(input: string | URL, base?: string | URL, config?: NextURLConfig);
100
- /** Strip basePath prefix from the internal pathname. */
119
+ /** Strip basePath prefix from the internal pathname.
120
+ * Mirrors Next.js's getNextPathnameInfo (re-run by NextURL.analyze() on
121
+ * every parse, including `href` reassignment): basePath is only considered
122
+ * active when the URL's pathname actually starts with the configured
123
+ * basePath prefix. If the pathname is outside the basePath, the active
124
+ * basePath is cleared to "" so that request.nextUrl.basePath reflects the
125
+ * actual URL rather than the config value; if a later `href` assignment
126
+ * moves the URL back inside the basePath, it is re-activated from the
127
+ * configured value. This matches the Next.js behavior tested by
128
+ * middleware-base-path's "should execute from absolute paths" case.
129
+ */
101
130
  private _stripBasePath;
102
131
  /** Extract locale from pathname, stripping it from the internal URL. */
103
- private _analyzeLocale;
132
+ private _detectPathnameLocale;
133
+ private _analyzeI18n;
104
134
  /**
105
135
  * Reconstruct the full pathname with basePath + locale prefix and apply
106
136
  * the configured trailingSlash policy.
@@ -142,6 +172,7 @@ declare class NextURL {
142
172
  get locale(): string;
143
173
  set locale(value: string | undefined);
144
174
  get defaultLocale(): string | undefined;
175
+ get domainLocale(): typeof this._domainLocale;
145
176
  get locales(): string[] | undefined;
146
177
  clone(): NextURL;
147
178
  toString(): string;
@@ -1,9 +1,9 @@
1
- import { stripBasePath } from "../utils/base-path.js";
1
+ import { hasBasePath, stripBasePath } from "../utils/base-path.js";
2
2
  import { getRequestExecutionContext } from "./request-context.js";
3
3
  import { MIDDLEWARE_NEXT_HEADER, MIDDLEWARE_REWRITE_HEADER, MIDDLEWARE_SET_COOKIE_HEADER } from "../server/headers.js";
4
4
  import { encodeMiddlewareRequestHeaders } from "../server/middleware-request-headers.js";
5
5
  import { serializeSetCookie, validateCookieName } from "./internal/cookie-serialize.js";
6
- import { parseCookieHeader } from "./internal/parse-cookie-header.js";
6
+ import { parseEdgeRequestCookieHeader } from "../utils/parse-cookie.js";
7
7
  import { assertSafeNavigationUrl } from "./url-safety.js";
8
8
  //#region src/shims/server.ts
9
9
  /**
@@ -51,6 +51,12 @@ var NextRequest = class extends Request {
51
51
  if (input instanceof Request) {
52
52
  const requestInput = requestInit.body === void 0 && input.body && !input.bodyUsed ? input.clone() : input;
53
53
  super(requestInput, requestInit);
54
+ const cf = Reflect.get(input, "cf");
55
+ if (cf !== void 0) Object.defineProperty(this, "cf", {
56
+ value: cf,
57
+ enumerable: true,
58
+ configurable: true
59
+ });
54
60
  } else super(input, requestInit);
55
61
  const url = typeof input === "string" ? new URL(input, "http://localhost") : input instanceof URL ? input : new URL(input.url, "http://localhost");
56
62
  const urlConfig = _nextConfig ? {
@@ -183,37 +189,73 @@ var NextResponse = class NextResponse extends Response {
183
189
  var NextURL = class NextURL {
184
190
  /** Internal URL stores the pathname WITHOUT basePath or locale prefix. */
185
191
  _url;
192
+ /**
193
+ * The configured basePath (from nextConfig). May differ from the active
194
+ * `_basePath`: parsing only activates basePath when the URL's pathname
195
+ * actually carries the configured prefix.
196
+ */
197
+ _configBasePath;
186
198
  _basePath;
187
199
  _trailingSlash;
188
200
  _locale;
201
+ _configDefaultLocale;
189
202
  _defaultLocale;
190
203
  _locales;
204
+ _domains;
205
+ _domainLocale;
191
206
  constructor(input, base, config) {
192
207
  this._url = new URL(input.toString(), base);
193
- this._basePath = config?.basePath ?? "";
208
+ this._configBasePath = config?.basePath ?? "";
209
+ this._basePath = this._configBasePath;
194
210
  this._trailingSlash = config?.nextConfig?.trailingSlash ?? false;
195
211
  this._stripBasePath();
196
212
  const i18n = config?.nextConfig?.i18n;
197
213
  if (i18n) {
198
214
  this._locales = [...i18n.locales];
199
- this._defaultLocale = i18n.defaultLocale;
200
- this._analyzeLocale(this._locales);
215
+ this._domains = i18n.domains?.map((domain) => ({
216
+ ...domain,
217
+ locales: domain.locales ? [...domain.locales] : void 0
218
+ }));
219
+ this._configDefaultLocale = i18n.defaultLocale;
220
+ this._analyzeI18n();
201
221
  }
202
222
  }
203
- /** Strip basePath prefix from the internal pathname. */
223
+ /** Strip basePath prefix from the internal pathname.
224
+ * Mirrors Next.js's getNextPathnameInfo (re-run by NextURL.analyze() on
225
+ * every parse, including `href` reassignment): basePath is only considered
226
+ * active when the URL's pathname actually starts with the configured
227
+ * basePath prefix. If the pathname is outside the basePath, the active
228
+ * basePath is cleared to "" so that request.nextUrl.basePath reflects the
229
+ * actual URL rather than the config value; if a later `href` assignment
230
+ * moves the URL back inside the basePath, it is re-activated from the
231
+ * configured value. This matches the Next.js behavior tested by
232
+ * middleware-base-path's "should execute from absolute paths" case.
233
+ */
204
234
  _stripBasePath() {
205
- if (!this._basePath) return;
206
- this._url.pathname = stripBasePath(this._url.pathname, this._basePath);
235
+ if (!this._configBasePath) return;
236
+ if (!hasBasePath(this._url.pathname, this._configBasePath)) {
237
+ this._basePath = "";
238
+ return;
239
+ }
240
+ this._basePath = this._configBasePath;
241
+ this._url.pathname = stripBasePath(this._url.pathname, this._configBasePath);
207
242
  }
208
243
  /** Extract locale from pathname, stripping it from the internal URL. */
209
- _analyzeLocale(locales) {
244
+ _detectPathnameLocale(locales) {
210
245
  const segments = this._url.pathname.split("/");
211
246
  const candidate = segments[1]?.toLowerCase();
212
247
  const match = locales.find((l) => l.toLowerCase() === candidate);
213
- if (match) {
214
- this._locale = match;
215
- this._url.pathname = "/" + segments.slice(2).join("/");
216
- } else this._locale = this._defaultLocale;
248
+ if (match) this._url.pathname = "/" + segments.slice(2).join("/");
249
+ return match;
250
+ }
251
+ _analyzeI18n() {
252
+ if (!this._locales || !this._configDefaultLocale) return;
253
+ const detectedLocale = this._detectPathnameLocale(this._locales);
254
+ const detectedLocaleLower = detectedLocale?.toLowerCase();
255
+ const hostname = this._url.hostname.toLowerCase();
256
+ this._domainLocale = this._domains?.find((domain) => domain.domain.split(":", 1)[0].toLowerCase() === hostname || detectedLocaleLower === domain.defaultLocale.toLowerCase() || domain.locales?.some((locale) => locale.toLowerCase() === detectedLocaleLower));
257
+ this._defaultLocale = this._domainLocale?.defaultLocale ?? this._configDefaultLocale;
258
+ this._locale = detectedLocale ?? this._defaultLocale;
217
259
  }
218
260
  /**
219
261
  * Reconstruct the full pathname with basePath + locale prefix and apply
@@ -222,8 +264,9 @@ var NextURL = class NextURL {
222
264
  */
223
265
  _formatPathname() {
224
266
  let prefix = this._basePath;
225
- if (this._locale && this._locale !== this._defaultLocale) prefix += "/" + this._locale;
226
267
  const inner = this._url.pathname;
268
+ const innerLower = inner.toLowerCase();
269
+ if (!(innerLower === "/api" || innerLower.startsWith("/api/")) && this._locale && this._locale !== this._defaultLocale) prefix += "/" + this._locale;
227
270
  const composed = !prefix ? inner : inner === "/" ? prefix : prefix + inner;
228
271
  return this._applyTrailingSlash(composed);
229
272
  }
@@ -248,7 +291,7 @@ var NextURL = class NextURL {
248
291
  set href(value) {
249
292
  this._url.href = value;
250
293
  this._stripBasePath();
251
- if (this._locales) this._analyzeLocale(this._locales);
294
+ this._analyzeI18n();
252
295
  }
253
296
  get origin() {
254
297
  return this._url.origin;
@@ -333,6 +376,13 @@ var NextURL = class NextURL {
333
376
  get defaultLocale() {
334
377
  return this._defaultLocale;
335
378
  }
379
+ get domainLocale() {
380
+ if (!this._domainLocale) return void 0;
381
+ return {
382
+ ...this._domainLocale,
383
+ locales: this._domainLocale.locales ? [...this._domainLocale.locales] : void 0
384
+ };
385
+ }
336
386
  get locales() {
337
387
  return this._locales ? [...this._locales] : void 0;
338
388
  }
@@ -340,7 +390,11 @@ var NextURL = class NextURL {
340
390
  const nextConfig = {};
341
391
  if (this._locales) nextConfig.i18n = {
342
392
  locales: [...this._locales],
343
- defaultLocale: this._defaultLocale
393
+ defaultLocale: this._configDefaultLocale,
394
+ domains: this._domains?.map((domain) => ({
395
+ ...domain,
396
+ locales: domain.locales ? [...domain.locales] : void 0
397
+ }))
344
398
  };
345
399
  if (this._trailingSlash) nextConfig.trailingSlash = true;
346
400
  const config = {
@@ -367,7 +421,7 @@ var RequestCookies = class {
367
421
  _parsed;
368
422
  constructor(headers) {
369
423
  this._headers = headers;
370
- this._parsed = parseCookieHeader(headers.get("cookie") ?? "");
424
+ this._parsed = parseEdgeRequestCookieHeader(headers.get("cookie") ?? "");
371
425
  }
372
426
  get(name) {
373
427
  const value = this._parsed.get(name);
@@ -655,10 +709,13 @@ function after(task) {
655
709
  * and sets Cache-Control: no-store on the response.
656
710
  */
657
711
  async function connection() {
658
- const { markDynamicUsage, markRenderRequestApiUsage, throwIfInsideCacheScope } = await import("./headers.js");
712
+ const { getHeadersContext, markDynamicUsage, markRenderRequestApiUsage, suspendConnectionProbe, throwIfInsideCacheScope } = await import("./headers.js");
713
+ if (getHeadersContext()?.forceStatic) return;
659
714
  markRenderRequestApiUsage("connection");
660
715
  throwIfInsideCacheScope("connection()");
661
716
  markDynamicUsage();
717
+ const pendingProbe = suspendConnectionProbe();
718
+ if (pendingProbe) await pendingProbe;
662
719
  }
663
720
  /**
664
721
  * URLPattern re-export — used in middleware for route matching.
@@ -23,7 +23,7 @@ const MAX_BFCACHE_SLOT_ENTRIES_WITH_CACHE_COMPONENTS = 3;
23
23
  const MAX_BFCACHE_SLOT_ENTRIES_WITHOUT_CACHE_COMPONENTS = 1;
24
24
  const BfcacheStateKeyMapContext = React$1.createContext(EMPTY_BFCACHE_STATE_KEYS);
25
25
  function isCacheComponentsEnabled() {
26
- return process.env.__NEXT_CACHE_COMPONENTS === "true";
26
+ return String(process.env.__NEXT_CACHE_COMPONENTS) === "true";
27
27
  }
28
28
  function getBfcacheSlotEntryLimit() {
29
29
  return isCacheComponentsEnabled() ? MAX_BFCACHE_SLOT_ENTRIES_WITH_CACHE_COMPONENTS : MAX_BFCACHE_SLOT_ENTRIES_WITHOUT_CACHE_COMPONENTS;
@@ -18,6 +18,7 @@ function createRequestContext(opts) {
18
18
  actionRevalidationKind: 0,
19
19
  dynamicUsageDetected: false,
20
20
  renderRequestApiUsage: /* @__PURE__ */ new Set(),
21
+ connectionProbe: null,
21
22
  invalidDynamicUsageError: null,
22
23
  pendingSetCookies: [],
23
24
  draftModeCookieHeader: null,
@@ -33,6 +34,7 @@ function createRequestContext(opts) {
33
34
  currentRequestTags: [],
34
35
  currentFetchSoftTags: [],
35
36
  currentFetchCacheMode: null,
37
+ currentForceDynamicFetchDefault: false,
36
38
  dynamicFetchUrls: /* @__PURE__ */ new Set(),
37
39
  isFetchDedupeActive: false,
38
40
  currentFetchDedupeEntries: /* @__PURE__ */ new Map(),
package/dist/typegen.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { decodeRouteSegment, isInvisibleSegment } from "./routing/utils.js";
2
2
  import { patternToNextFormat } from "./routing/route-validation.js";
3
3
  import { compareStrings } from "./utils/compare.js";
4
+ import "./routing/app-route-graph.js";
4
5
  import { appRouteGraph } from "./routing/app-router.js";
5
6
  import path from "node:path";
6
7
  import fs from "node:fs/promises";
@@ -0,0 +1,4 @@
1
+ //#region src/utils/built-asset-url.d.ts
2
+ declare function renderVinextBuiltUrl(filename: string, assetPrefix: string, deploymentId?: string, hostType?: "js" | "css" | "html"): string;
3
+ //#endregion
4
+ export { renderVinextBuiltUrl };
@@ -0,0 +1,11 @@
1
+ import { appendDeploymentIdQuery } from "./deployment-id.js";
2
+ import { ASSET_PREFIX_URL_DIR, resolveAssetUrlPrefix, resolveAssetsDir } from "./asset-prefix.js";
3
+ //#region src/utils/built-asset-url.ts
4
+ function renderVinextBuiltUrl(filename, assetPrefix, deploymentId, hostType) {
5
+ const urlPrefix = resolveAssetUrlPrefix(assetPrefix);
6
+ const dirPrefix = resolveAssetsDir(assetPrefix) + "/";
7
+ const url = urlPrefix + (filename.startsWith(dirPrefix) ? filename.slice(dirPrefix.length) : filename.startsWith(`_next/static/`) ? filename.slice(ASSET_PREFIX_URL_DIR.length + 1) : filename);
8
+ return hostType === "js" ? url : appendDeploymentIdQuery(url, deploymentId);
9
+ }
10
+ //#endregion
11
+ export { renderVinextBuiltUrl };
@@ -47,16 +47,26 @@ function findEntryFileFromManifest(buildManifest, assetBase, markers, fallbackTo
47
47
  const chosen = fallbackToFirstEntry ? entries[0] : void 0;
48
48
  return chosen ? manifestFileWithBase(chosen.file, assetBase) : void 0;
49
49
  }
50
+ function listFilesRecursive(dir) {
51
+ const out = [];
52
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
53
+ const full = path.join(dir, entry.name);
54
+ if (entry.isDirectory()) out.push(...listFilesRecursive(full));
55
+ else if (entry.isFile()) out.push(full);
56
+ }
57
+ return out;
58
+ }
50
59
  function findClientEntryFileInAssetsDir(options) {
51
60
  const assetsDir = path.join(options.clientDir, options.assetsSubdir);
52
61
  if (!fs.existsSync(assetsDir)) return void 0;
53
- const files = fs.readdirSync(assetsDir);
54
- let entry;
62
+ const files = listFilesRecursive(assetsDir);
63
+ let entryFull;
55
64
  for (const marker of options.markers) {
56
- entry = files.find((file) => file.includes(marker) && file.endsWith(".js"));
57
- if (entry) break;
65
+ entryFull = files.find((file) => path.basename(file).includes(marker) && file.endsWith(".js"));
66
+ if (entryFull) break;
58
67
  }
59
- return entry ? manifestFileWithBase(`${options.assetsSubdir}/${entry}`, options.assetBase) : void 0;
68
+ if (!entryFull) return void 0;
69
+ return manifestFileWithBase(path.relative(options.clientDir, entryFull).split(path.sep).join("/"), options.assetBase);
60
70
  }
61
71
  function findClientEntryFile(options) {
62
72
  return (options.buildManifest ? findClientEntryFileFromManifest(options.buildManifest, options.assetBase) : void 0) ?? findClientEntryFileInAssetsDir({
@@ -0,0 +1,45 @@
1
+ //#region src/utils/client-runtime-metadata.d.ts
2
+ type ClientRuntimeMetadata = {
3
+ clientEntryFile?: string;
4
+ lazyChunks?: string[];
5
+ dynamicPreloads?: Record<string, string[]>;
6
+ };
7
+ /**
8
+ * Read the client build manifest and compute runtime metadata used by
9
+ * Cloudflare worker entry injection and Node production server startup.
10
+ *
11
+ * - `lazyChunks` — chunks only reachable through dynamic `import()`, excluded
12
+ * from modulepreload hints.
13
+ * - `dynamicPreloads` — per-module JS/CSS files for rendered `next/dynamic()`
14
+ * boundaries, injected as preload links during SSR.
15
+ * - `clientEntryFile` — the client entry chunk filename (optional, only
16
+ * needed for Pages Router).
17
+ *
18
+ * All file paths are normalised with the configured `assetBase` (basePath)
19
+ * and `assetPrefix`.
20
+ */
21
+ declare function computeClientRuntimeMetadata(opts: {
22
+ clientDir: string;
23
+ assetBase: string;
24
+ assetPrefix: string;
25
+ includeClientEntry?: boolean | "pages-client-entry";
26
+ }): ClientRuntimeMetadata;
27
+ /**
28
+ * Serialize runtime metadata into the `globalThis.__VINEXT_*` assignment script
29
+ * that the Cloudflare `closeBundle` hook prepends to the worker entry. Returns
30
+ * `""` when there is nothing to inject.
31
+ *
32
+ * Both the App Router and Pages Router closeBundle paths call this (and the
33
+ * deploy tests mirror it), so the injection shape stays in one place. The caller
34
+ * decides which fields to pass — e.g. App Router only forwards `clientEntryFile`
35
+ * for mixed app+pages builds (where `computeClientRuntimeMetadata` was asked for
36
+ * the Pages client entry); pure App Router leaves it undefined.
37
+ */
38
+ declare function buildRuntimeGlobalsScript(input: {
39
+ clientEntryFile?: string | null;
40
+ ssrManifest?: Record<string, string[]> | null;
41
+ lazyChunks?: string[] | null;
42
+ dynamicPreloads?: Record<string, string[]> | null;
43
+ }): string;
44
+ //#endregion
45
+ export { buildRuntimeGlobalsScript, computeClientRuntimeMetadata };
@@ -0,0 +1,63 @@
1
+ import { resolveAssetsDir } from "./asset-prefix.js";
2
+ import { manifestFileWithAssetPrefix, manifestFileWithBase } from "./manifest-paths.js";
3
+ import { findClientEntryFile, findPagesClientEntryFile, readClientBuildManifest } from "./client-build-manifest.js";
4
+ import { findClientEntryFileFromVinextManifest, findPagesClientEntryFileFromVinextManifest, readClientEntryManifest } from "./client-entry-manifest.js";
5
+ import { computeDynamicImportPreloads, computeLazyChunks, dynamicImportPreloadsWithBase } from "./lazy-chunks.js";
6
+ import path from "node:path";
7
+ //#region src/utils/client-runtime-metadata.ts
8
+ /**
9
+ * Read the client build manifest and compute runtime metadata used by
10
+ * Cloudflare worker entry injection and Node production server startup.
11
+ *
12
+ * - `lazyChunks` — chunks only reachable through dynamic `import()`, excluded
13
+ * from modulepreload hints.
14
+ * - `dynamicPreloads` — per-module JS/CSS files for rendered `next/dynamic()`
15
+ * boundaries, injected as preload links during SSR.
16
+ * - `clientEntryFile` — the client entry chunk filename (optional, only
17
+ * needed for Pages Router).
18
+ *
19
+ * All file paths are normalised with the configured `assetBase` (basePath)
20
+ * and `assetPrefix`.
21
+ */
22
+ function computeClientRuntimeMetadata(opts) {
23
+ const buildManifest = readClientBuildManifest(path.join(opts.clientDir, ".vite", "manifest.json"));
24
+ const metadata = {};
25
+ if (opts.includeClientEntry) {
26
+ const clientEntryManifest = readClientEntryManifest(opts.clientDir);
27
+ const entryOptions = {
28
+ buildManifest,
29
+ clientDir: opts.clientDir,
30
+ assetsSubdir: resolveAssetsDir(opts.assetPrefix),
31
+ assetBase: opts.assetBase
32
+ };
33
+ const entry = opts.includeClientEntry === "pages-client-entry" ? findPagesClientEntryFileFromVinextManifest(clientEntryManifest, opts.assetBase) ?? findPagesClientEntryFile(entryOptions) : findClientEntryFileFromVinextManifest(clientEntryManifest, opts.assetBase) ?? findClientEntryFile(entryOptions);
34
+ if (entry) metadata.clientEntryFile = entry;
35
+ }
36
+ if (!buildManifest) return metadata;
37
+ const lazyChunks = computeLazyChunks(buildManifest).map((file) => manifestFileWithBase(file, opts.assetBase));
38
+ if (lazyChunks.length > 0) metadata.lazyChunks = lazyChunks;
39
+ const dynamicPreloads = dynamicImportPreloadsWithBase(computeDynamicImportPreloads(buildManifest), (file) => manifestFileWithAssetPrefix(file, opts.assetBase, opts.assetPrefix));
40
+ if (Object.keys(dynamicPreloads).length > 0) metadata.dynamicPreloads = dynamicPreloads;
41
+ return metadata;
42
+ }
43
+ /**
44
+ * Serialize runtime metadata into the `globalThis.__VINEXT_*` assignment script
45
+ * that the Cloudflare `closeBundle` hook prepends to the worker entry. Returns
46
+ * `""` when there is nothing to inject.
47
+ *
48
+ * Both the App Router and Pages Router closeBundle paths call this (and the
49
+ * deploy tests mirror it), so the injection shape stays in one place. The caller
50
+ * decides which fields to pass — e.g. App Router only forwards `clientEntryFile`
51
+ * for mixed app+pages builds (where `computeClientRuntimeMetadata` was asked for
52
+ * the Pages client entry); pure App Router leaves it undefined.
53
+ */
54
+ function buildRuntimeGlobalsScript(input) {
55
+ const globals = [];
56
+ if (input.clientEntryFile) globals.push(`globalThis.__VINEXT_CLIENT_ENTRY__ = ${JSON.stringify(input.clientEntryFile)};`);
57
+ if (input.ssrManifest && Object.keys(input.ssrManifest).length > 0) globals.push(`globalThis.__VINEXT_SSR_MANIFEST__ = ${JSON.stringify(input.ssrManifest)};`);
58
+ if (input.lazyChunks && input.lazyChunks.length > 0) globals.push(`globalThis.__VINEXT_LAZY_CHUNKS__ = ${JSON.stringify(input.lazyChunks)};`);
59
+ if (input.dynamicPreloads && Object.keys(input.dynamicPreloads).length > 0) globals.push(`globalThis.__VINEXT_DYNAMIC_PRELOADS__ = ${JSON.stringify(input.dynamicPreloads)};`);
60
+ return globals.join("\n");
61
+ }
62
+ //#endregion
63
+ export { buildRuntimeGlobalsScript, computeClientRuntimeMetadata };
@@ -0,0 +1,16 @@
1
+ //#region src/utils/commonjs-loader.d.ts
2
+ declare function shouldRetryAsCommonJs(error: unknown, resolvedPath: string): boolean;
3
+ /**
4
+ * Load a `.js` file as CommonJS even when a surrounding `package.json`
5
+ * declares `"type": "module"`. Nested misclassified `.js` dependencies are
6
+ * compiled the same way, while Node keeps handling builtins, JSON, native
7
+ * addons, and correctly classified modules through its normal loader.
8
+ */
9
+ declare function loadCommonJsModule(resolvedPath: string): unknown;
10
+ /**
11
+ * Import a module normally, retrying only `.js` files that fail because Node
12
+ * classified CommonJS source as ESM.
13
+ */
14
+ declare function importExportWithCommonJsFallback(resolvedPath: string): Promise<unknown>;
15
+ //#endregion
16
+ export { importExportWithCommonJsFallback, loadCommonJsModule, shouldRetryAsCommonJs };
@@ -0,0 +1,100 @@
1
+ import { Module, createRequire } from "node:module";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
+ //#region src/utils/commonjs-loader.ts
6
+ const CommonJsModule = Module;
7
+ function canonicalPath(filePath) {
8
+ const normalizedPath = filePath.startsWith("/@fs/") ? filePath.slice(4) : filePath;
9
+ const resolvedPath = normalizedPath.startsWith("file://") ? fileURLToPath(normalizedPath) : normalizedPath;
10
+ try {
11
+ return fs.realpathSync.native(resolvedPath);
12
+ } catch {
13
+ return path.resolve(resolvedPath);
14
+ }
15
+ }
16
+ function shouldRetryAsCommonJs(error, resolvedPath) {
17
+ if (!resolvedPath.endsWith(".js") || !(error instanceof Error)) return false;
18
+ if ("code" in error && error.code === "ERR_REQUIRE_ESM") {
19
+ const canonicalResolvedPath = canonicalPath(resolvedPath);
20
+ return error.message.includes(canonicalResolvedPath) || error.message.includes(pathToFileURL(canonicalResolvedPath).href);
21
+ }
22
+ if (!(error instanceof ReferenceError)) return false;
23
+ const match = error.message.match(/^(module|exports|require|__dirname|__filename) is not defined(?: in ES module scope)?/);
24
+ if (!match || !error.stack) return false;
25
+ const identifier = match[1];
26
+ for (const line of error.stack.split("\n").slice(1)) {
27
+ const location = line.match(/(?:\(|at )(.+):(\d+):(\d+)\)?$/);
28
+ if (!location) continue;
29
+ const [, framePath, lineNumberText, columnNumberText] = location;
30
+ const canonicalFramePath = canonicalPath(framePath);
31
+ if (!canonicalFramePath.endsWith(".js")) continue;
32
+ let sourceLine;
33
+ try {
34
+ sourceLine = fs.readFileSync(canonicalFramePath, "utf8").split(/\r?\n/)[Number(lineNumberText) - 1];
35
+ } catch {
36
+ continue;
37
+ }
38
+ const column = Number(columnNumberText) - 1;
39
+ if (sourceLine?.slice(column, column + identifier.length) === identifier) return true;
40
+ }
41
+ return false;
42
+ }
43
+ function compileCommonJsModule(resolvedPath, parent) {
44
+ resolvedPath = canonicalPath(resolvedPath);
45
+ const req = createRequire(resolvedPath);
46
+ const cached = req.cache[resolvedPath];
47
+ if (cached) return cached.exports;
48
+ const mod = new CommonJsModule(resolvedPath, parent);
49
+ mod.filename = resolvedPath;
50
+ mod.paths = CommonJsModule._nodeModulePaths(path.dirname(resolvedPath));
51
+ req.cache[resolvedPath] = mod;
52
+ const originalRequire = mod.require.bind(mod);
53
+ mod.require = ((specifier) => {
54
+ let dependencyPath;
55
+ try {
56
+ dependencyPath = req.resolve(specifier);
57
+ } catch {
58
+ return originalRequire(specifier);
59
+ }
60
+ if (dependencyPath.endsWith(".cjs")) return compileCommonJsModule(dependencyPath, mod);
61
+ try {
62
+ return originalRequire(specifier);
63
+ } catch (error) {
64
+ if (!shouldRetryAsCommonJs(error, dependencyPath)) throw error;
65
+ return compileCommonJsModule(dependencyPath, mod);
66
+ }
67
+ });
68
+ try {
69
+ mod._compile(fs.readFileSync(resolvedPath, "utf8"), resolvedPath);
70
+ mod.loaded = true;
71
+ return mod.exports;
72
+ } catch (error) {
73
+ if (req.cache[resolvedPath] === mod) delete req.cache[resolvedPath];
74
+ throw error;
75
+ }
76
+ }
77
+ /**
78
+ * Load a `.js` file as CommonJS even when a surrounding `package.json`
79
+ * declares `"type": "module"`. Nested misclassified `.js` dependencies are
80
+ * compiled the same way, while Node keeps handling builtins, JSON, native
81
+ * addons, and correctly classified modules through its normal loader.
82
+ */
83
+ function loadCommonJsModule(resolvedPath) {
84
+ return compileCommonJsModule(resolvedPath);
85
+ }
86
+ /**
87
+ * Import a module normally, retrying only `.js` files that fail because Node
88
+ * classified CommonJS source as ESM.
89
+ */
90
+ async function importExportWithCommonJsFallback(resolvedPath) {
91
+ try {
92
+ const mod = await import(pathToFileURL(resolvedPath).href);
93
+ return mod.default ?? mod;
94
+ } catch (error) {
95
+ if (!shouldRetryAsCommonJs(error, resolvedPath)) throw error;
96
+ return loadCommonJsModule(resolvedPath);
97
+ }
98
+ }
99
+ //#endregion
100
+ export { importExportWithCommonJsFallback, loadCommonJsModule, shouldRetryAsCommonJs };
@@ -0,0 +1,8 @@
1
+ //#region src/utils/deployment-id.d.ts
2
+ declare const NEXT_DEPLOYMENT_ID_HEADER = "x-deployment-id";
3
+ declare function getDeploymentId(): string | undefined;
4
+ declare function appendDeploymentIdQuery(value: string, deploymentId?: string | undefined): string;
5
+ declare function appendAssetDeploymentIdQuery(value: string, deploymentId?: string | undefined): string;
6
+ declare function applyDeploymentIdHeader(headers: Headers, deploymentId?: string | undefined): void;
7
+ //#endregion
8
+ export { NEXT_DEPLOYMENT_ID_HEADER, appendAssetDeploymentIdQuery, appendDeploymentIdQuery, applyDeploymentIdHeader, getDeploymentId };
@@ -0,0 +1,22 @@
1
+ //#region src/utils/deployment-id.ts
2
+ const NEXT_DEPLOYMENT_ID_HEADER = "x-deployment-id";
3
+ function getDeploymentId() {
4
+ return process.env.__VINEXT_DEPLOYMENT_ID || process.env.NEXT_DEPLOYMENT_ID || void 0;
5
+ }
6
+ function appendDeploymentIdQuery(value, deploymentId = getDeploymentId()) {
7
+ if (!deploymentId) return value;
8
+ const hashIndex = value.indexOf("#");
9
+ const url = hashIndex === -1 ? value : value.slice(0, hashIndex);
10
+ const fragment = hashIndex === -1 ? "" : value.slice(hashIndex);
11
+ if (new URL(url, "http://vinext.local").searchParams.has("dpl")) return value;
12
+ return `${url}${url.includes("?") ? "&" : "?"}dpl=${deploymentId}${fragment}`;
13
+ }
14
+ function appendAssetDeploymentIdQuery(value, deploymentId = getDeploymentId()) {
15
+ if (!new URL(value, "http://vinext.local").pathname.includes("/_next/static/")) return value;
16
+ return appendDeploymentIdQuery(value, deploymentId);
17
+ }
18
+ function applyDeploymentIdHeader(headers, deploymentId = getDeploymentId()) {
19
+ if (deploymentId) headers.set(NEXT_DEPLOYMENT_ID_HEADER, deploymentId);
20
+ }
21
+ //#endregion
22
+ export { NEXT_DEPLOYMENT_ID_HEADER, appendAssetDeploymentIdQuery, appendDeploymentIdQuery, applyDeploymentIdHeader, getDeploymentId };
@@ -2,7 +2,23 @@
2
2
  /**
3
3
  * FNV-1a hash producing a 64-bit result (two 32-bit rounds with different seeds).
4
4
  * Used for deterministic key generation where collisions must be rare.
5
+ *
6
+ * This is a vinext-internal format: nothing outside vinext ever compares
7
+ * these values, so the algorithm only needs to be deterministic. For values
8
+ * that must be byte-for-byte identical to what Next.js emits (ETags), use
9
+ * `fnv1a52` below instead — the two are NOT interchangeable.
5
10
  */
6
11
  declare function fnv1a64(input: string): string;
12
+ /**
13
+ * FNV-1a hash producing a 52-bit result, a byte-for-byte port of Next.js's
14
+ * `fnv1a52` in packages/next/src/server/lib/etag.ts (itself derived from
15
+ * fnv-plus). Used for ETag generation, where matching Next.js's exact output
16
+ * matters: clients and CDNs holding `If-None-Match` values from a Next.js
17
+ * deployment keep revalidating (304) against vinext for unchanged payloads.
18
+ *
19
+ * Deliberately separate from `fnv1a64` above — that one is a vinext-internal
20
+ * key format and produces different values. Do not swap one for the other.
21
+ */
22
+ declare function fnv1a52(str: string): number;
7
23
  //#endregion
8
- export { fnv1a64 };
24
+ export { fnv1a52, fnv1a64 };