vinext 0.1.2 → 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 (199) hide show
  1. package/dist/build/prerender.d.ts +9 -1
  2. package/dist/build/prerender.js +41 -12
  3. package/dist/build/run-prerender.d.ts +10 -2
  4. package/dist/build/run-prerender.js +15 -1
  5. package/dist/client/app-nav-failure-handler.d.ts +8 -0
  6. package/dist/client/app-nav-failure-handler.js +44 -0
  7. package/dist/client/vinext-next-data.d.ts +18 -1
  8. package/dist/client/window-next.d.ts +2 -1
  9. package/dist/client/window-next.js +12 -1
  10. package/dist/cloudflare/src/cache/cdn-adapter.runtime.js +6 -1
  11. package/dist/config/config-matchers.js +73 -14
  12. package/dist/config/next-config.d.ts +46 -4
  13. package/dist/config/next-config.js +147 -48
  14. package/dist/deploy.d.ts +30 -11
  15. package/dist/deploy.js +180 -99
  16. package/dist/entries/app-browser-entry.d.ts +9 -3
  17. package/dist/entries/app-browser-entry.js +21 -3
  18. package/dist/entries/app-rsc-entry.d.ts +2 -0
  19. package/dist/entries/app-rsc-entry.js +64 -5
  20. package/dist/entries/app-rsc-manifest.js +2 -0
  21. package/dist/entries/app-ssr-entry.js +1 -1
  22. package/dist/entries/pages-client-entry.js +53 -8
  23. package/dist/entries/pages-server-entry.js +41 -5
  24. package/dist/index.js +200 -62
  25. package/dist/plugins/extensionless-dynamic-import.d.ts +6 -0
  26. package/dist/plugins/extensionless-dynamic-import.js +152 -0
  27. package/dist/plugins/optimize-imports.d.ts +2 -1
  28. package/dist/plugins/optimize-imports.js +11 -9
  29. package/dist/plugins/postcss.js +7 -7
  30. package/dist/plugins/typeof-window.d.ts +14 -0
  31. package/dist/plugins/typeof-window.js +150 -0
  32. package/dist/routing/app-route-graph.d.ts +2 -1
  33. package/dist/routing/app-route-graph.js +44 -14
  34. package/dist/routing/file-matcher.d.ts +10 -1
  35. package/dist/routing/file-matcher.js +22 -1
  36. package/dist/routing/pages-router.js +3 -3
  37. package/dist/routing/utils.d.ts +35 -6
  38. package/dist/routing/utils.js +59 -7
  39. package/dist/server/api-handler.d.ts +6 -1
  40. package/dist/server/api-handler.js +21 -15
  41. package/dist/server/app-browser-action-result.d.ts +19 -6
  42. package/dist/server/app-browser-action-result.js +19 -10
  43. package/dist/server/app-browser-entry.js +167 -90
  44. package/dist/server/app-browser-error.d.ts +10 -6
  45. package/dist/server/app-browser-error.js +43 -8
  46. package/dist/server/app-browser-hydration.d.ts +2 -0
  47. package/dist/server/app-browser-hydration.js +1 -0
  48. package/dist/server/app-browser-navigation-controller.d.ts +4 -2
  49. package/dist/server/app-browser-navigation-controller.js +23 -2
  50. package/dist/server/app-browser-server-action-navigation.d.ts +6 -0
  51. package/dist/server/app-browser-server-action-navigation.js +9 -0
  52. package/dist/server/app-browser-stream.js +86 -43
  53. package/dist/server/app-elements-wire.d.ts +6 -1
  54. package/dist/server/app-elements-wire.js +14 -4
  55. package/dist/server/app-elements.d.ts +2 -2
  56. package/dist/server/app-elements.js +2 -2
  57. package/dist/server/app-fallback-renderer.d.ts +1 -0
  58. package/dist/server/app-fallback-renderer.js +3 -1
  59. package/dist/server/app-optimistic-routing.js +2 -2
  60. package/dist/server/app-page-boundary-render.d.ts +1 -0
  61. package/dist/server/app-page-boundary-render.js +27 -14
  62. package/dist/server/app-page-cache-render.d.ts +53 -0
  63. package/dist/server/app-page-cache-render.js +91 -0
  64. package/dist/server/app-page-cache.d.ts +16 -2
  65. package/dist/server/app-page-cache.js +62 -1
  66. package/dist/server/app-page-dispatch.d.ts +26 -0
  67. package/dist/server/app-page-dispatch.js +149 -92
  68. package/dist/server/app-page-element-builder.d.ts +1 -0
  69. package/dist/server/app-page-element-builder.js +5 -2
  70. package/dist/server/app-page-execution.d.ts +6 -1
  71. package/dist/server/app-page-execution.js +21 -1
  72. package/dist/server/app-page-probe.d.ts +1 -0
  73. package/dist/server/app-page-probe.js +4 -0
  74. package/dist/server/app-page-render-observation.d.ts +3 -1
  75. package/dist/server/app-page-render-observation.js +17 -1
  76. package/dist/server/app-page-render.d.ts +12 -1
  77. package/dist/server/app-page-render.js +42 -4
  78. package/dist/server/app-page-request.d.ts +2 -0
  79. package/dist/server/app-page-request.js +2 -1
  80. package/dist/server/app-page-route-wiring.d.ts +3 -1
  81. package/dist/server/app-page-route-wiring.js +14 -5
  82. package/dist/server/app-page-stream.d.ts +15 -3
  83. package/dist/server/app-page-stream.js +11 -5
  84. package/dist/server/app-pages-bridge.d.ts +18 -0
  85. package/dist/server/app-pages-bridge.js +22 -5
  86. package/dist/server/app-ppr-fallback-shell-render.d.ts +17 -0
  87. package/dist/server/app-ppr-fallback-shell-render.js +26 -0
  88. package/dist/server/app-ppr-fallback-shell.d.ts +13 -1
  89. package/dist/server/app-ppr-fallback-shell.js +8 -1
  90. package/dist/server/app-route-handler-dispatch.js +9 -2
  91. package/dist/server/app-route-handler-policy.d.ts +1 -0
  92. package/dist/server/app-router-entry.js +5 -0
  93. package/dist/server/app-rsc-cache-busting.js +2 -0
  94. package/dist/server/app-rsc-handler.d.ts +25 -0
  95. package/dist/server/app-rsc-handler.js +154 -54
  96. package/dist/server/app-rsc-route-matching.d.ts +3 -0
  97. package/dist/server/app-rsc-route-matching.js +2 -0
  98. package/dist/server/app-segment-config.d.ts +9 -1
  99. package/dist/server/app-segment-config.js +12 -3
  100. package/dist/server/app-server-action-execution.d.ts +1 -0
  101. package/dist/server/app-server-action-execution.js +42 -13
  102. package/dist/server/app-ssr-entry.d.ts +2 -0
  103. package/dist/server/app-ssr-entry.js +83 -10
  104. package/dist/server/cache-control.js +4 -0
  105. package/dist/server/dev-server.d.ts +2 -2
  106. package/dist/server/dev-server.js +244 -51
  107. package/dist/server/hybrid-route-priority.d.ts +22 -0
  108. package/dist/server/hybrid-route-priority.js +33 -0
  109. package/dist/server/image-optimization.d.ts +18 -9
  110. package/dist/server/image-optimization.js +37 -23
  111. package/dist/server/implicit-tags.d.ts +2 -1
  112. package/dist/server/implicit-tags.js +4 -1
  113. package/dist/server/navigation-planner.d.ts +133 -30
  114. package/dist/server/navigation-planner.js +114 -0
  115. package/dist/server/navigation-trace.d.ts +8 -1
  116. package/dist/server/navigation-trace.js +8 -1
  117. package/dist/server/pages-api-route.d.ts +6 -0
  118. package/dist/server/pages-api-route.js +13 -2
  119. package/dist/server/pages-asset-tags.d.ts +2 -1
  120. package/dist/server/pages-asset-tags.js +6 -2
  121. package/dist/server/pages-data-route.d.ts +8 -1
  122. package/dist/server/pages-data-route.js +11 -2
  123. package/dist/server/pages-get-initial-props.d.ts +54 -4
  124. package/dist/server/pages-get-initial-props.js +43 -1
  125. package/dist/server/pages-node-compat.js +2 -2
  126. package/dist/server/pages-page-data.d.ts +11 -2
  127. package/dist/server/pages-page-data.js +204 -33
  128. package/dist/server/pages-page-handler.d.ts +4 -2
  129. package/dist/server/pages-page-handler.js +59 -22
  130. package/dist/server/pages-page-response.d.ts +2 -1
  131. package/dist/server/pages-page-response.js +7 -4
  132. package/dist/server/pages-request-pipeline.d.ts +1 -0
  133. package/dist/server/pages-request-pipeline.js +73 -36
  134. package/dist/server/pregenerated-concrete-paths.d.ts +1 -17
  135. package/dist/server/pregenerated-concrete-paths.js +2 -19
  136. package/dist/server/prerender-manifest.d.ts +33 -0
  137. package/dist/server/prerender-manifest.js +54 -0
  138. package/dist/server/prerender-route-params.d.ts +1 -2
  139. package/dist/server/prod-server.js +9 -3
  140. package/dist/server/request-pipeline.d.ts +3 -15
  141. package/dist/server/request-pipeline.js +58 -47
  142. package/dist/server/rsc-stream-hints.d.ts +5 -1
  143. package/dist/server/rsc-stream-hints.js +6 -1
  144. package/dist/server/seed-cache.js +10 -18
  145. package/dist/shims/app-router-scroll-state.d.ts +3 -1
  146. package/dist/shims/app-router-scroll-state.js +14 -2
  147. package/dist/shims/app-router-scroll.d.ts +3 -0
  148. package/dist/shims/app-router-scroll.js +28 -18
  149. package/dist/shims/cache-runtime.js +3 -2
  150. package/dist/shims/cache.d.ts +1 -0
  151. package/dist/shims/cache.js +1 -1
  152. package/dist/shims/cdn-cache.d.ts +5 -5
  153. package/dist/shims/dynamic-preload-chunks.js +6 -4
  154. package/dist/shims/error-boundary.d.ts +2 -0
  155. package/dist/shims/error-boundary.js +7 -0
  156. package/dist/shims/error.js +3 -2
  157. package/dist/shims/error.react-server.d.ts +9 -0
  158. package/dist/shims/error.react-server.js +6 -0
  159. package/dist/shims/fetch-cache.d.ts +3 -1
  160. package/dist/shims/fetch-cache.js +45 -20
  161. package/dist/shims/hash-scroll.js +6 -1
  162. package/dist/shims/headers.js +29 -4
  163. package/dist/shims/internal/als-registry.js +28 -1
  164. package/dist/shims/internal/app-route-detection.js +8 -17
  165. package/dist/shims/internal/hybrid-client-route-owner.d.ts +31 -0
  166. package/dist/shims/internal/hybrid-client-route-owner.js +143 -0
  167. package/dist/shims/internal/navigation-untracked.d.ts +35 -0
  168. package/dist/shims/internal/navigation-untracked.js +55 -0
  169. package/dist/shims/internal/pages-data-target.d.ts +7 -2
  170. package/dist/shims/internal/pages-data-target.js +17 -8
  171. package/dist/shims/internal/pages-router-accessor.d.ts +19 -0
  172. package/dist/shims/internal/pages-router-accessor.js +13 -0
  173. package/dist/shims/internal/router-context.d.ts +2 -1
  174. package/dist/shims/internal/router-context.js +3 -1
  175. package/dist/shims/link.js +12 -5
  176. package/dist/shims/navigation.d.ts +8 -2
  177. package/dist/shims/navigation.js +61 -31
  178. package/dist/shims/ppr-fallback-shell.d.ts +5 -1
  179. package/dist/shims/ppr-fallback-shell.js +28 -7
  180. package/dist/shims/router.d.ts +13 -2
  181. package/dist/shims/router.js +419 -128
  182. package/dist/shims/server.d.ts +16 -1
  183. package/dist/shims/server.js +44 -12
  184. package/dist/shims/unified-request-context.js +1 -0
  185. package/dist/utils/built-asset-url.d.ts +4 -0
  186. package/dist/utils/built-asset-url.js +11 -0
  187. package/dist/utils/commonjs-loader.d.ts +16 -0
  188. package/dist/utils/commonjs-loader.js +100 -0
  189. package/dist/utils/deployment-id.d.ts +8 -0
  190. package/dist/utils/deployment-id.js +22 -0
  191. package/dist/utils/html-limited-bots.d.ts +18 -1
  192. package/dist/utils/html-limited-bots.js +23 -1
  193. package/dist/utils/parse-cookie.d.ts +13 -0
  194. package/dist/utils/parse-cookie.js +52 -0
  195. package/dist/utils/path.d.ts +7 -1
  196. package/dist/utils/path.js +9 -1
  197. package/package.json +2 -2
  198. package/dist/shims/internal/parse-cookie-header.d.ts +0 -14
  199. package/dist/shims/internal/parse-cookie-header.js +0 -30
@@ -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
@@ -100,8 +110,11 @@ declare class NextURL {
100
110
  private _basePath;
101
111
  private _trailingSlash;
102
112
  private _locale;
113
+ private _configDefaultLocale;
103
114
  private _defaultLocale;
104
115
  private _locales;
116
+ private _domains;
117
+ private _domainLocale;
105
118
  constructor(input: string | URL, base?: string | URL, config?: NextURLConfig);
106
119
  /** Strip basePath prefix from the internal pathname.
107
120
  * Mirrors Next.js's getNextPathnameInfo (re-run by NextURL.analyze() on
@@ -116,7 +129,8 @@ declare class NextURL {
116
129
  */
117
130
  private _stripBasePath;
118
131
  /** Extract locale from pathname, stripping it from the internal URL. */
119
- private _analyzeLocale;
132
+ private _detectPathnameLocale;
133
+ private _analyzeI18n;
120
134
  /**
121
135
  * Reconstruct the full pathname with basePath + locale prefix and apply
122
136
  * the configured trailingSlash policy.
@@ -158,6 +172,7 @@ declare class NextURL {
158
172
  get locale(): string;
159
173
  set locale(value: string | undefined);
160
174
  get defaultLocale(): string | undefined;
175
+ get domainLocale(): typeof this._domainLocale;
161
176
  get locales(): string[] | undefined;
162
177
  clone(): NextURL;
163
178
  toString(): string;
@@ -3,7 +3,7 @@ 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 ? {
@@ -192,8 +198,11 @@ var NextURL = class NextURL {
192
198
  _basePath;
193
199
  _trailingSlash;
194
200
  _locale;
201
+ _configDefaultLocale;
195
202
  _defaultLocale;
196
203
  _locales;
204
+ _domains;
205
+ _domainLocale;
197
206
  constructor(input, base, config) {
198
207
  this._url = new URL(input.toString(), base);
199
208
  this._configBasePath = config?.basePath ?? "";
@@ -203,8 +212,12 @@ var NextURL = class NextURL {
203
212
  const i18n = config?.nextConfig?.i18n;
204
213
  if (i18n) {
205
214
  this._locales = [...i18n.locales];
206
- this._defaultLocale = i18n.defaultLocale;
207
- 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();
208
221
  }
209
222
  }
210
223
  /** Strip basePath prefix from the internal pathname.
@@ -228,14 +241,21 @@ var NextURL = class NextURL {
228
241
  this._url.pathname = stripBasePath(this._url.pathname, this._configBasePath);
229
242
  }
230
243
  /** Extract locale from pathname, stripping it from the internal URL. */
231
- _analyzeLocale(locales) {
244
+ _detectPathnameLocale(locales) {
232
245
  const segments = this._url.pathname.split("/");
233
246
  const candidate = segments[1]?.toLowerCase();
234
247
  const match = locales.find((l) => l.toLowerCase() === candidate);
235
- if (match) {
236
- this._locale = match;
237
- this._url.pathname = "/" + segments.slice(2).join("/");
238
- } 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;
239
259
  }
240
260
  /**
241
261
  * Reconstruct the full pathname with basePath + locale prefix and apply
@@ -244,8 +264,9 @@ var NextURL = class NextURL {
244
264
  */
245
265
  _formatPathname() {
246
266
  let prefix = this._basePath;
247
- if (this._locale && this._locale !== this._defaultLocale) prefix += "/" + this._locale;
248
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;
249
270
  const composed = !prefix ? inner : inner === "/" ? prefix : prefix + inner;
250
271
  return this._applyTrailingSlash(composed);
251
272
  }
@@ -270,7 +291,7 @@ var NextURL = class NextURL {
270
291
  set href(value) {
271
292
  this._url.href = value;
272
293
  this._stripBasePath();
273
- if (this._locales) this._analyzeLocale(this._locales);
294
+ this._analyzeI18n();
274
295
  }
275
296
  get origin() {
276
297
  return this._url.origin;
@@ -355,6 +376,13 @@ var NextURL = class NextURL {
355
376
  get defaultLocale() {
356
377
  return this._defaultLocale;
357
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
+ }
358
386
  get locales() {
359
387
  return this._locales ? [...this._locales] : void 0;
360
388
  }
@@ -362,7 +390,11 @@ var NextURL = class NextURL {
362
390
  const nextConfig = {};
363
391
  if (this._locales) nextConfig.i18n = {
364
392
  locales: [...this._locales],
365
- defaultLocale: this._defaultLocale
393
+ defaultLocale: this._configDefaultLocale,
394
+ domains: this._domains?.map((domain) => ({
395
+ ...domain,
396
+ locales: domain.locales ? [...domain.locales] : void 0
397
+ }))
366
398
  };
367
399
  if (this._trailingSlash) nextConfig.trailingSlash = true;
368
400
  const config = {
@@ -389,7 +421,7 @@ var RequestCookies = class {
389
421
  _parsed;
390
422
  constructor(headers) {
391
423
  this._headers = headers;
392
- this._parsed = parseCookieHeader(headers.get("cookie") ?? "");
424
+ this._parsed = parseEdgeRequestCookieHeader(headers.get("cookie") ?? "");
393
425
  }
394
426
  get(name) {
395
427
  const value = this._parsed.get(name);
@@ -34,6 +34,7 @@ function createRequestContext(opts) {
34
34
  currentRequestTags: [],
35
35
  currentFetchSoftTags: [],
36
36
  currentFetchCacheMode: null,
37
+ currentForceDynamicFetchDefault: false,
37
38
  dynamicFetchUrls: /* @__PURE__ */ new Set(),
38
39
  isFetchDedupeActive: false,
39
40
  currentFetchDedupeEntries: /* @__PURE__ */ new Map(),
@@ -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 };
@@ -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 };
@@ -1,4 +1,21 @@
1
1
  //#region src/utils/html-limited-bots.d.ts
2
2
  declare function getHtmlLimitedBotRegex(htmlLimitedBots: string | undefined): RegExp;
3
+ /**
4
+ * Returns true when the User-Agent matches a known crawler/bot. Combines
5
+ * Next.js's "headless browser bot" check (Googlebot proper) with the
6
+ * "HTML-limited bot" list (Bingbot, DuckDuckBot, facebookexternalhit, …).
7
+ *
8
+ * Used by the Pages Router fallback path: a bot hitting an unlisted
9
+ * `fallback: true` route should get a synchronous render (real content) and
10
+ * not the loading shell, so the crawler indexes the actual page. Mirrors
11
+ * Next.js's `isBot()` in `.nextjs-ref/packages/next/src/shared/lib/router/utils/is-bot.ts`
12
+ * and the bot-aware fallback flip in
13
+ * `.nextjs-ref/packages/next/src/server/route-modules/pages/pages-handler.ts`.
14
+ *
15
+ * `htmlLimitedBots` allows next.config to override the HTML-limited list
16
+ * (same flag that drives `getHtmlLimitedBotRegex`), so a custom list applies
17
+ * to both streaming metadata gating and bot-aware fallback rendering.
18
+ */
19
+ declare function isBotUserAgent(userAgent: string, htmlLimitedBots?: string): boolean;
3
20
  //#endregion
4
- export { getHtmlLimitedBotRegex };
21
+ export { getHtmlLimitedBotRegex, isBotUserAgent };
@@ -1,5 +1,6 @@
1
1
  //#region src/utils/html-limited-bots.ts
2
2
  const HTML_LIMITED_BOT_UA_RE_STRING = String.raw`[\w-]+-Google|Google-[\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight`;
3
+ const HEADLESS_BROWSER_BOT_UA_RE = /Googlebot(?!-)|Googlebot$/i;
3
4
  const htmlLimitedBotRegexCache = /* @__PURE__ */ new Map();
4
5
  function getHtmlLimitedBotRegex(htmlLimitedBots) {
5
6
  const source = htmlLimitedBots || HTML_LIMITED_BOT_UA_RE_STRING;
@@ -9,5 +10,26 @@ function getHtmlLimitedBotRegex(htmlLimitedBots) {
9
10
  htmlLimitedBotRegexCache.set(source, regex);
10
11
  return regex;
11
12
  }
13
+ /**
14
+ * Returns true when the User-Agent matches a known crawler/bot. Combines
15
+ * Next.js's "headless browser bot" check (Googlebot proper) with the
16
+ * "HTML-limited bot" list (Bingbot, DuckDuckBot, facebookexternalhit, …).
17
+ *
18
+ * Used by the Pages Router fallback path: a bot hitting an unlisted
19
+ * `fallback: true` route should get a synchronous render (real content) and
20
+ * not the loading shell, so the crawler indexes the actual page. Mirrors
21
+ * Next.js's `isBot()` in `.nextjs-ref/packages/next/src/shared/lib/router/utils/is-bot.ts`
22
+ * and the bot-aware fallback flip in
23
+ * `.nextjs-ref/packages/next/src/server/route-modules/pages/pages-handler.ts`.
24
+ *
25
+ * `htmlLimitedBots` allows next.config to override the HTML-limited list
26
+ * (same flag that drives `getHtmlLimitedBotRegex`), so a custom list applies
27
+ * to both streaming metadata gating and bot-aware fallback rendering.
28
+ */
29
+ function isBotUserAgent(userAgent, htmlLimitedBots) {
30
+ if (!userAgent) return false;
31
+ if (HEADLESS_BROWSER_BOT_UA_RE.test(userAgent)) return true;
32
+ return getHtmlLimitedBotRegex(htmlLimitedBots).test(userAgent);
33
+ }
12
34
  //#endregion
13
- export { getHtmlLimitedBotRegex };
35
+ export { getHtmlLimitedBotRegex, isBotUserAgent };
@@ -0,0 +1,13 @@
1
+ //#region src/utils/parse-cookie.d.ts
2
+ type ParsedCookies = Record<string, string>;
3
+ /**
4
+ * Parse a Cookie header using the semantics of Next.js's compiled `cookie`
5
+ * package.
6
+ */
7
+ declare function parseCookieHeader(cookieHeader: string | null | undefined): ParsedCookies;
8
+ /**
9
+ * Parse a Cookie header using Next.js/@edge-runtime RequestCookies semantics.
10
+ */
11
+ declare function parseEdgeRequestCookieHeader(cookieHeader: string): Map<string, string>;
12
+ //#endregion
13
+ export { ParsedCookies, parseCookieHeader, parseEdgeRequestCookieHeader };
@@ -0,0 +1,52 @@
1
+ //#region src/utils/parse-cookie.ts
2
+ function decodeCookieValue(value) {
3
+ try {
4
+ return {
5
+ ok: true,
6
+ value: decodeURIComponent(value)
7
+ };
8
+ } catch {
9
+ return { ok: false };
10
+ }
11
+ }
12
+ function forEachCookieHeaderPart(cookieHeader, visit) {
13
+ for (const part of cookieHeader.split(/; */)) {
14
+ if (!part) continue;
15
+ visit(part, part.indexOf("="));
16
+ }
17
+ }
18
+ /**
19
+ * Parse a Cookie header using the semantics of Next.js's compiled `cookie`
20
+ * package.
21
+ */
22
+ function parseCookieHeader(cookieHeader) {
23
+ const cookies = {};
24
+ if (!cookieHeader) return cookies;
25
+ forEachCookieHeaderPart(cookieHeader, (part, separator) => {
26
+ if (separator < 0) return;
27
+ const key = part.slice(0, separator).trim();
28
+ let value = part.slice(separator + 1).trim();
29
+ if (cookies[key] !== void 0) return;
30
+ if (value.startsWith("\"")) value = value.slice(1, -1);
31
+ const decoded = decodeCookieValue(value);
32
+ cookies[key] = decoded.ok ? decoded.value : value;
33
+ });
34
+ return cookies;
35
+ }
36
+ /**
37
+ * Parse a Cookie header using Next.js/@edge-runtime RequestCookies semantics.
38
+ */
39
+ function parseEdgeRequestCookieHeader(cookieHeader) {
40
+ const cookies = /* @__PURE__ */ new Map();
41
+ forEachCookieHeaderPart(cookieHeader, (part, separator) => {
42
+ if (separator === -1) {
43
+ cookies.set(part, "true");
44
+ return;
45
+ }
46
+ const decoded = decodeCookieValue(part.slice(separator + 1));
47
+ if (decoded.ok) cookies.set(part.slice(0, separator), decoded.value);
48
+ });
49
+ return cookies;
50
+ }
51
+ //#endregion
52
+ export { parseCookieHeader, parseEdgeRequestCookieHeader };
@@ -12,5 +12,11 @@
12
12
  */
13
13
  declare function normalizePathSeparators(p: string): string;
14
14
  declare function stripViteModuleQuery(id: string): string;
15
+ /** Strip a trailing `.js` extension from a module specifier so
16
+ * `resolveShimModulePath` looks for the correct base name (e.g. `headers.js`
17
+ * → `headers`). Public and internal shim imports may carry extensionful
18
+ * subpaths; normalising before resolution prevents looking for non-existent
19
+ * files like `headers.js.ts`. */
20
+ declare function stripJsExtension(name: string): string;
15
21
  //#endregion
16
- export { normalizePathSeparators, stripViteModuleQuery };
22
+ export { normalizePathSeparators, stripJsExtension, stripViteModuleQuery };
@@ -18,5 +18,13 @@ function stripViteModuleQuery(id) {
18
18
  const queryIndex = id.search(/[?#]/);
19
19
  return queryIndex === -1 ? id : id.slice(0, queryIndex);
20
20
  }
21
+ /** Strip a trailing `.js` extension from a module specifier so
22
+ * `resolveShimModulePath` looks for the correct base name (e.g. `headers.js`
23
+ * → `headers`). Public and internal shim imports may carry extensionful
24
+ * subpaths; normalising before resolution prevents looking for non-existent
25
+ * files like `headers.js.ts`. */
26
+ function stripJsExtension(name) {
27
+ return name.endsWith(".js") ? name.slice(0, -3) : name;
28
+ }
21
29
  //#endregion
22
- export { normalizePathSeparators, stripViteModuleQuery };
30
+ export { normalizePathSeparators, stripJsExtension, stripViteModuleQuery };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vinext",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -101,7 +101,7 @@
101
101
  "react-server-dom-webpack": "^19.2.7",
102
102
  "vite": "npm:@voidzero-dev/vite-plus-core@0.1.24",
103
103
  "vite-plus": "0.1.24",
104
- "@vinext/cloudflare": "0.1.1"
104
+ "@vinext/cloudflare": "0.1.2"
105
105
  },
106
106
  "peerDependencies": {
107
107
  "@mdx-js/rollup": "^3.0.0",
@@ -1,14 +0,0 @@
1
- //#region src/shims/internal/parse-cookie-header.d.ts
2
- /**
3
- * Port of the current Next.js/@edge-runtime request cookie parser semantics.
4
- *
5
- * Important details:
6
- * - split on a semicolon-plus-optional-spaces pattern
7
- * - preserve whitespace around names/values otherwise
8
- * - bare tokens become "true"
9
- * - malformed percent-encoded values are skipped
10
- * - duplicate names collapse to the last value via Map.set()
11
- */
12
- declare function parseCookieHeader(cookieHeader: string): Map<string, string>;
13
- //#endregion
14
- export { parseCookieHeader };
@@ -1,30 +0,0 @@
1
- //#region src/shims/internal/parse-cookie-header.ts
2
- /**
3
- * Port of the current Next.js/@edge-runtime request cookie parser semantics.
4
- *
5
- * Important details:
6
- * - split on a semicolon-plus-optional-spaces pattern
7
- * - preserve whitespace around names/values otherwise
8
- * - bare tokens become "true"
9
- * - malformed percent-encoded values are skipped
10
- * - duplicate names collapse to the last value via Map.set()
11
- */
12
- function parseCookieHeader(cookieHeader) {
13
- const cookies = /* @__PURE__ */ new Map();
14
- for (const pair of cookieHeader.split(/; */)) {
15
- if (!pair) continue;
16
- const splitAt = pair.indexOf("=");
17
- if (splitAt === -1) {
18
- cookies.set(pair, "true");
19
- continue;
20
- }
21
- const key = pair.slice(0, splitAt);
22
- const value = pair.slice(splitAt + 1);
23
- try {
24
- cookies.set(key, decodeURIComponent(value));
25
- } catch {}
26
- }
27
- return cookies;
28
- }
29
- //#endregion
30
- export { parseCookieHeader };