vinext 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/README.md +13 -10
  2. package/dist/build/client-build-config.d.ts +64 -3
  3. package/dist/build/client-build-config.js +131 -4
  4. package/dist/build/client-reference-groups.d.ts +163 -0
  5. package/dist/build/client-reference-groups.js +534 -0
  6. package/dist/build/module-dependency-cache.d.ts +31 -0
  7. package/dist/build/module-dependency-cache.js +51 -1
  8. package/dist/build/next-client-runtime-manifests.d.ts +10 -1
  9. package/dist/build/next-client-runtime-manifests.js +19 -4
  10. package/dist/build/nitro-public-files.d.ts +24 -0
  11. package/dist/build/nitro-public-files.js +60 -0
  12. package/dist/build/output-root-externals.d.ts +21 -0
  13. package/dist/build/output-root-externals.js +40 -0
  14. package/dist/build/pages-client-assets-module.js +1 -1
  15. package/dist/build/prerender-paths.js +6 -3
  16. package/dist/build/prerender.js +1 -1
  17. package/dist/build/server-actions-encryption-key.d.ts +23 -0
  18. package/dist/build/server-actions-encryption-key.js +101 -0
  19. package/dist/build/ssr-manifest.d.ts +3 -0
  20. package/dist/build/ssr-manifest.js +10 -1
  21. package/dist/check.js +5 -6
  22. package/dist/cli-dev-config.js +3 -3
  23. package/dist/cli.js +1 -1
  24. package/dist/client/client-rewrite-params.d.ts +9 -0
  25. package/dist/client/client-rewrite-params.js +20 -0
  26. package/dist/client/dev-error-overlay.js +2 -1
  27. package/dist/client/navigation-runtime.d.ts +25 -2
  28. package/dist/client/navigation-runtime.js +42 -11
  29. package/dist/client/vinext-next-data.d.ts +0 -1
  30. package/dist/config/config-matchers.d.ts +15 -40
  31. package/dist/config/config-matchers.js +195 -262
  32. package/dist/config/config-source.d.ts +34 -0
  33. package/dist/config/config-source.js +141 -0
  34. package/dist/config/header-params.d.ts +29 -0
  35. package/dist/config/header-params.js +106 -0
  36. package/dist/config/next-config.d.ts +7 -5
  37. package/dist/config/next-config.js +120 -7
  38. package/dist/entries/app-browser-entry.d.ts +14 -1
  39. package/dist/entries/app-browser-entry.js +26 -36
  40. package/dist/entries/app-rsc-entry.d.ts +2 -0
  41. package/dist/entries/app-rsc-entry.js +92 -57
  42. package/dist/entries/app-rsc-manifest.d.ts +10 -0
  43. package/dist/entries/app-rsc-manifest.js +20 -1
  44. package/dist/entries/app-ssr-entry.d.ts +4 -1
  45. package/dist/entries/app-ssr-entry.js +9 -2
  46. package/dist/entries/pages-client-entry.d.ts +1 -0
  47. package/dist/entries/pages-client-entry.js +6 -6
  48. package/dist/entries/pages-server-entry.js +17 -14
  49. package/dist/index.d.ts +11 -0
  50. package/dist/index.js +350 -175
  51. package/dist/init.d.ts +1 -1
  52. package/dist/init.js +103 -6
  53. package/dist/plugins/ast-utils.d.ts +53 -2
  54. package/dist/plugins/ast-utils.js +90 -2
  55. package/dist/plugins/cloudflare-dev-module-urls.d.ts +41 -0
  56. package/dist/plugins/cloudflare-dev-module-urls.js +271 -0
  57. package/dist/plugins/commonjs-esm-facade.js +2 -2
  58. package/dist/plugins/css-module-imports.js +13 -20
  59. package/dist/plugins/dynamic-preload-metadata.js +2 -3
  60. package/dist/plugins/extensionless-dynamic-import.js +2 -3
  61. package/dist/plugins/fonts.d.ts +1 -1
  62. package/dist/plugins/fonts.js +3 -3
  63. package/dist/plugins/ignore-dynamic-requests.js +2 -3
  64. package/dist/plugins/import-meta-url.js +3 -4
  65. package/dist/plugins/instrumentation-client.js +3 -2
  66. package/dist/plugins/middleware-export-validation.js +2 -3
  67. package/dist/plugins/og-harfbuzz.js +2 -3
  68. package/dist/plugins/optimize-imports.d.ts +25 -2
  69. package/dist/plugins/optimize-imports.js +109 -24
  70. package/dist/plugins/pages-node-externals.js +2 -3
  71. package/dist/plugins/remove-console.js +2 -18
  72. package/dist/plugins/require-condition-resolution.js +3 -3
  73. package/dist/plugins/require-context.js +2 -3
  74. package/dist/plugins/rsc-client-reference-loaders.d.ts +45 -1
  75. package/dist/plugins/rsc-client-reference-loaders.js +336 -18
  76. package/dist/plugins/strip-server-exports.js +3 -4
  77. package/dist/plugins/styled-jsx.js +2 -3
  78. package/dist/plugins/use-cache-callable.d.ts +26 -2
  79. package/dist/plugins/use-cache-callable.js +101 -36
  80. package/dist/plugins/worker-image-imports.d.ts +1 -0
  81. package/dist/plugins/worker-image-imports.js +31 -34
  82. package/dist/plugins/worker-use-server.js +38 -14
  83. package/dist/routing/app-route-graph.d.ts +1 -1
  84. package/dist/routing/browser-route-manifest.d.ts +43 -0
  85. package/dist/routing/browser-route-manifest.js +195 -0
  86. package/dist/routing/hashed-route-patterns.d.ts +4 -0
  87. package/dist/routing/hashed-route-patterns.js +22 -0
  88. package/dist/routing/optimistic-route-trie.d.ts +27 -0
  89. package/dist/routing/optimistic-route-trie.js +102 -0
  90. package/dist/routing/route-validation.d.ts +6 -1
  91. package/dist/routing/route-validation.js +26 -10
  92. package/dist/server/api-handler.js +1 -1
  93. package/dist/server/app-action-forwarding.d.ts +8 -0
  94. package/dist/server/app-action-forwarding.js +17 -3
  95. package/dist/server/app-browser-entry.js +149 -62
  96. package/dist/server/app-browser-error.d.ts +3 -1
  97. package/dist/server/app-browser-error.js +7 -2
  98. package/dist/server/app-browser-interception-context.d.ts +2 -2
  99. package/dist/server/app-browser-interception-context.js +1 -1
  100. package/dist/server/app-browser-mpa-navigation.d.ts +1 -0
  101. package/dist/server/app-browser-mpa-navigation.js +6 -5
  102. package/dist/server/app-browser-navigation-controller.d.ts +17 -6
  103. package/dist/server/app-browser-navigation-controller.js +88 -26
  104. package/dist/server/app-browser-prefetch-response.js +2 -2
  105. package/dist/server/app-browser-state.d.ts +2 -2
  106. package/dist/server/app-browser-state.js +1 -1
  107. package/dist/server/app-browser-supplemental-refresh.js +1 -1
  108. package/dist/server/app-browser-visible-commit.d.ts +4 -4
  109. package/dist/server/app-client-reference-preloader.d.ts +23 -0
  110. package/dist/server/app-client-reference-preloader.js +30 -7
  111. package/dist/server/app-fallback-renderer.js +2 -1
  112. package/dist/server/app-middleware.d.ts +6 -0
  113. package/dist/server/app-middleware.js +8 -10
  114. package/dist/server/app-optimistic-routing.d.ts +8 -10
  115. package/dist/server/app-optimistic-routing.js +4 -95
  116. package/dist/server/app-page-boundary-render.js +8 -1
  117. package/dist/server/app-page-cache-render.js +1 -0
  118. package/dist/server/app-page-dispatch.js +3 -1
  119. package/dist/server/app-page-render.js +4 -2
  120. package/dist/server/app-page-rsc-render-status.d.ts +1 -0
  121. package/dist/server/app-page-rsc-render-status.js +1 -0
  122. package/dist/server/app-page-search-params-observation.d.ts +1 -4
  123. package/dist/server/app-page-search-params-observation.js +8 -10
  124. package/dist/server/app-page-stream.d.ts +7 -0
  125. package/dist/server/app-page-stream.js +1 -0
  126. package/dist/server/app-pages-bridge.d.ts +2 -1
  127. package/dist/server/app-pages-bridge.js +12 -8
  128. package/dist/server/app-prerender-endpoints.js +1 -1
  129. package/dist/server/app-prerender-static-params.js +3 -2
  130. package/dist/server/app-render-abort-error.d.ts +19 -0
  131. package/dist/server/app-render-abort-error.js +31 -1
  132. package/dist/server/app-render-dependency.js +42 -2
  133. package/dist/server/app-request-stage-independent-entry.js +7 -7
  134. package/dist/server/app-response-stage-entry.js +5 -5
  135. package/dist/server/app-route-handler-dispatch.js +3 -1
  136. package/dist/server/app-route-handler-execution.d.ts +2 -0
  137. package/dist/server/app-route-handler-execution.js +9 -2
  138. package/dist/server/app-route-handler-middleware-context.d.ts +2 -1
  139. package/dist/server/app-route-handler-middleware-context.js +3 -3
  140. package/dist/server/app-route-handler-response.d.ts +2 -1
  141. package/dist/server/app-route-handler-response.js +2 -2
  142. package/dist/server/app-route-handler-runtime.d.ts +2 -0
  143. package/dist/server/app-route-handler-runtime.js +21 -4
  144. package/dist/server/app-route-module-loader.js +7 -6
  145. package/dist/server/app-route-tree.d.ts +20 -0
  146. package/dist/server/app-route-tree.js +18 -0
  147. package/dist/server/app-router-entry.js +7 -7
  148. package/dist/server/app-rsc-cache-busting.d.ts +16 -0
  149. package/dist/server/app-rsc-cache-busting.js +29 -12
  150. package/dist/server/app-rsc-combined-handler.js +8 -1
  151. package/dist/server/app-rsc-errors.d.ts +7 -0
  152. package/dist/server/app-rsc-errors.js +9 -2
  153. package/dist/server/app-rsc-handler.d.ts +4 -1
  154. package/dist/server/app-rsc-handler.js +151 -135
  155. package/dist/server/app-rsc-request-normalization.js +3 -3
  156. package/dist/server/app-rsc-response-finalizer.d.ts +5 -0
  157. package/dist/server/app-rsc-response-finalizer.js +4 -1
  158. package/dist/server/app-rsc-response-stage.js +5 -3
  159. package/dist/server/app-rsc-route-matching.d.ts +1 -0
  160. package/dist/server/app-rsc-route-matching.js +1 -1
  161. package/dist/server/app-server-action-execution.d.ts +23 -6
  162. package/dist/server/app-server-action-execution.js +51 -57
  163. package/dist/server/app-ssr-entry.d.ts +6 -0
  164. package/dist/server/app-ssr-entry.js +21 -11
  165. package/dist/server/app-ssr-stream.d.ts +7 -0
  166. package/dist/server/app-ssr-stream.js +13 -1
  167. package/dist/server/app-visited-response-cache.js +2 -2
  168. package/dist/server/config-headers.js +13 -4
  169. package/dist/server/defer-until-stream-consumed.d.ts +2 -1
  170. package/dist/server/defer-until-stream-consumed.js +3 -1
  171. package/dist/server/dev-server.js +1 -1
  172. package/dist/server/image-optimization.js +1 -0
  173. package/dist/server/isolate-shared-promise.d.ts +10 -0
  174. package/dist/server/isolate-shared-promise.js +33 -0
  175. package/dist/server/isr-cache.js +3 -2
  176. package/dist/server/metadata-route-response.js +2 -2
  177. package/dist/server/middleware-matcher-pattern.d.ts +0 -1
  178. package/dist/server/middleware-matcher-pattern.js +11 -140
  179. package/dist/server/middleware-matcher.js +5 -6
  180. package/dist/server/middleware-response-headers.d.ts +31 -0
  181. package/dist/server/middleware-response-headers.js +57 -1
  182. package/dist/server/middleware-runtime.js +30 -17
  183. package/dist/server/navigation-planner.d.ts +2 -2
  184. package/dist/server/navigation-planner.js +1 -1
  185. package/dist/server/nitro-public-files-plugin.d.ts +38 -0
  186. package/dist/server/nitro-public-files-plugin.js +106 -0
  187. package/dist/server/nitro-public-files.d.ts +21 -0
  188. package/dist/server/nitro-public-files.js +39 -0
  189. package/dist/server/open-redirect.d.ts +11 -4
  190. package/dist/server/open-redirect.js +11 -4
  191. package/dist/server/pages-api-route.js +2 -2
  192. package/dist/server/pages-asset-tags.d.ts +5 -0
  193. package/dist/server/pages-asset-tags.js +9 -2
  194. package/dist/server/pages-client-assets.d.ts +4 -1
  195. package/dist/server/pages-data-route.js +2 -1
  196. package/dist/server/pages-i18n.d.ts +18 -0
  197. package/dist/server/pages-i18n.js +18 -2
  198. package/dist/server/pages-node-compat.d.ts +5 -3
  199. package/dist/server/pages-node-compat.js +35 -16
  200. package/dist/server/pages-page-data.js +1 -1
  201. package/dist/server/pages-page-handler.js +1 -1
  202. package/dist/server/pages-page-response.js +1 -1
  203. package/dist/server/pages-request-pipeline.d.ts +6 -1
  204. package/dist/server/pages-request-pipeline.js +35 -39
  205. package/dist/server/pages-request-stage-entry.js +20 -10
  206. package/dist/server/pages-response-stage-entry.js +1 -1
  207. package/dist/server/pages-revalidate.js +3 -2
  208. package/dist/server/pages-router-entry.js +2 -2
  209. package/dist/server/prod-server.d.ts +2 -2
  210. package/dist/server/prod-server.js +74 -36
  211. package/dist/server/proxy-trust.d.ts +6 -0
  212. package/dist/server/proxy-trust.js +12 -6
  213. package/dist/server/request-pipeline.d.ts +5 -0
  214. package/dist/server/request-pipeline.js +12 -1
  215. package/dist/server/rsc-stream-hints.d.ts +1 -1
  216. package/dist/server/rsc-stream-hints.js +21 -3
  217. package/dist/server/server-reference-loader.js +10 -1
  218. package/dist/server/static-file-cache.js +15 -3
  219. package/dist/server/worker-image-optimization.js +19 -6
  220. package/dist/server/worker-utils.js +1 -1
  221. package/dist/shims/cache-handler.js +3 -2
  222. package/dist/shims/cache-request-state.d.ts +40 -3
  223. package/dist/shims/cache-request-state.js +70 -5
  224. package/dist/shims/cache-runtime.js +47 -19
  225. package/dist/shims/cache.d.ts +2 -2
  226. package/dist/shims/cache.js +17 -8
  227. package/dist/shims/cdn-purge-routes.d.ts +24 -0
  228. package/dist/shims/cdn-purge-routes.js +77 -0
  229. package/dist/shims/dynamic.js +17 -4
  230. package/dist/shims/form.js +8 -3
  231. package/dist/shims/head.js +1 -1
  232. package/dist/shims/headers.js +2 -2
  233. package/dist/shims/image-props.d.ts +93 -0
  234. package/dist/shims/image-props.js +323 -0
  235. package/dist/shims/image.d.ts +4 -18
  236. package/dist/shims/image.js +4 -319
  237. package/dist/shims/internal/headers-state.d.ts +7 -0
  238. package/dist/shims/internal/headers-state.js +14 -2
  239. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +4 -1
  240. package/dist/shims/internal/hybrid-client-route-owner-direct.js +32 -15
  241. package/dist/shims/internal/hybrid-client-route-owner.js +9 -8
  242. package/dist/shims/link-prefetch.js +5 -4
  243. package/dist/shims/link.js +7 -5
  244. package/dist/shims/navigation.d.ts +1 -1
  245. package/dist/shims/navigation.js +21 -10
  246. package/dist/shims/og.js +35 -10
  247. package/dist/shims/request-context.d.ts +13 -0
  248. package/dist/shims/router.js +28 -52
  249. package/dist/shims/server.d.ts +42 -8
  250. package/dist/shims/server.js +99 -15
  251. package/dist/shims/thenable-params.d.ts +6 -1
  252. package/dist/shims/thenable-params.js +11 -2
  253. package/dist/shims/unified-request-context.d.ts +5 -0
  254. package/dist/shims/unified-request-context.js +2 -0
  255. package/dist/shims/url-utils.d.ts +7 -0
  256. package/dist/shims/url-utils.js +12 -3
  257. package/dist/utils/asset-prefix.d.ts +7 -0
  258. package/dist/utils/asset-prefix.js +10 -1
  259. package/dist/utils/client-build-manifest.js +12 -5
  260. package/dist/utils/client-runtime-metadata.d.ts +1 -0
  261. package/dist/utils/client-runtime-metadata.js +15 -2
  262. package/dist/utils/domain-locale.js +1 -1
  263. package/dist/utils/lazy-chunks.d.ts +4 -0
  264. package/dist/utils/manifest-paths.d.ts +14 -0
  265. package/dist/utils/manifest-paths.js +22 -1
  266. package/dist/utils/path-to-regexp.d.ts +21 -0
  267. package/dist/{server/middleware-path-to-regexp.js → utils/path-to-regexp.js} +14 -11
  268. package/dist/utils/plugin-react-version.d.ts +15 -0
  269. package/dist/utils/plugin-react-version.js +64 -0
  270. package/dist/utils/plugin-rsc-version.d.ts +2 -0
  271. package/dist/utils/plugin-rsc-version.js +28 -2
  272. package/dist/utils/public-routes.d.ts +2 -0
  273. package/dist/utils/public-routes.js +18 -7
  274. package/dist/utils/react-version.d.ts +7 -0
  275. package/dist/utils/react-version.js +39 -16
  276. package/package.json +6 -6
  277. package/dist/build/nitro-route-rules.d.ts +0 -47
  278. package/dist/build/nitro-route-rules.js +0 -79
  279. package/dist/plugins/cache-flight-codec.d.ts +0 -19
  280. package/dist/plugins/cache-flight-codec.js +0 -68
  281. package/dist/server/middleware-path-to-regexp.d.ts +0 -13
  282. package/dist/utils/regex-safety.d.ts +0 -17
  283. package/dist/utils/regex-safety.js +0 -789
@@ -0,0 +1,64 @@
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { findPackageVersion, isVersionBelow } from "./react-version.js";
3
+ import { createRequire } from "node:module";
4
+ import fs from "node:fs";
5
+ //#region src/utils/plugin-react-version.ts
6
+ const MINIMUM_PLUGIN_REACT_VERSION = [
7
+ 5,
8
+ 1,
9
+ 4
10
+ ];
11
+ function resolveFrom(from) {
12
+ try {
13
+ const resolved = createRequire(from).resolve("@vitejs/plugin-react");
14
+ return {
15
+ path: resolved,
16
+ version: findPackageVersion(resolved, "@vitejs/plugin-react")
17
+ };
18
+ } catch {
19
+ return null;
20
+ }
21
+ }
22
+ function isSupported(plugin) {
23
+ return plugin.version !== null && !isVersionBelow(plugin.version, MINIMUM_PLUGIN_REACT_VERSION);
24
+ }
25
+ /**
26
+ * Resolve @vitejs/plugin-react from the project, falling back to vinext's own
27
+ * install when the project has none or reaches an unsupported version.
28
+ * Returns null when it is not installed, and throws when every copy found is
29
+ * unsupported.
30
+ */
31
+ function resolvePluginReactPath(projectRoot, fallbackFrom = import.meta.url) {
32
+ const project = resolveFrom(path.join(projectRoot, "package.json"));
33
+ if (project && isSupported(project)) return project.path;
34
+ const fallback = resolveFrom(fallbackFrom);
35
+ if (fallback && isSupported(fallback)) {
36
+ if (project) console.warn(`[vinext] Ignoring @vitejs/plugin-react ${project.version ?? "(unknown version)"} at ${project.path}: vinext requires ${MINIMUM_PLUGIN_REACT_VERSION.join(".")} or newer. Using ${fallback.version} instead. Add @vitejs/plugin-react to your app's devDependencies to choose the version explicitly.`);
37
+ return fallback.path;
38
+ }
39
+ const found = project ?? fallback;
40
+ if (!found) return null;
41
+ throw new Error(`vinext: @vitejs/plugin-react ${MINIMUM_PLUGIN_REACT_VERSION.join(".")} or newer is required (found ${found.version ?? "an unknown version"} at ${found.path}). Add @vitejs/plugin-react@^6 to your app's devDependencies.`);
42
+ }
43
+ /**
44
+ * The @vitejs/plugin-react upgrade vinext init must install before vinext.
45
+ * A declared copy below the floor conflicts with vinext's peer range: npm stops
46
+ * with ERESOLVE, and pnpm installs but vinext refuses to start.
47
+ */
48
+ function getPluginReactUpgradeDeps(root) {
49
+ const manifest = path.join(root, "package.json");
50
+ let declared;
51
+ try {
52
+ const pkg = JSON.parse(fs.readFileSync(manifest, "utf-8"));
53
+ declared = pkg.dependencies?.["@vitejs/plugin-react"] ?? pkg.devDependencies?.["@vitejs/plugin-react"];
54
+ } catch {
55
+ return [];
56
+ }
57
+ if (typeof declared !== "string") return [];
58
+ const major = /^[~^]?(\d+)(?:\.(?:\d+|[x*])){0,2}$/.exec(declared.trim())?.[1];
59
+ if (major !== void 0 && Number(major) < MINIMUM_PLUGIN_REACT_VERSION[0]) return ["@vitejs/plugin-react@latest"];
60
+ const installed = resolveFrom(manifest);
61
+ return installed && (!isSupported(installed) || installed.version?.includes("-")) ? ["@vitejs/plugin-react@latest"] : [];
62
+ }
63
+ //#endregion
64
+ export { getPluginReactUpgradeDeps, resolvePluginReactPath };
@@ -1,4 +1,6 @@
1
1
  //#region src/utils/plugin-rsc-version.d.ts
2
2
  /** Return the installed @vitejs/plugin-rsc version, or throw if it is unsupported. */
3
3
  export declare function assertPluginRscVersion(resolvedRscPath: string): string;
4
+ /** Whether the package owning `dir` must install its own react-server-dom-webpack. */
5
+ export declare function needsAppReactServerDom(dir: string, pluginRscVersion: string): boolean;
4
6
  //#endregion
@@ -1,4 +1,7 @@
1
- import { findPackageVersion, isVersionBelow } from "./react-version.js";
1
+ import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
+ import { MINIMUM_REACT_VERSION, findPackageVersion, isVersionBelow } from "./react-version.js";
3
+ import { createRequire } from "node:module";
4
+ import fs from "node:fs";
2
5
  //#region src/utils/plugin-rsc-version.ts
3
6
  const MINIMUM_PLUGIN_RSC_VERSION = [
4
7
  0,
@@ -11,5 +14,28 @@ function assertPluginRscVersion(resolvedRscPath) {
11
14
  if (!version || isVersionBelow(version, MINIMUM_PLUGIN_RSC_VERSION)) throw new Error(`vinext: App Router requires @vitejs/plugin-rsc ${MINIMUM_PLUGIN_RSC_VERSION.join(".")} or newer (found ${version ?? "an unknown version"}). Upgrade @vitejs/plugin-rsc.`);
12
15
  return version;
13
16
  }
17
+ const FIRST_PLUGIN_RSC_WITH_SUPPORTED_RSDW = [
18
+ 0,
19
+ 5,
20
+ 38
21
+ ];
22
+ /** Whether the package owning `dir` must install its own react-server-dom-webpack. */
23
+ function needsAppReactServerDom(dir, pluginRscVersion) {
24
+ if (!isVersionBelow(pluginRscVersion, FIRST_PLUGIN_RSC_WITH_SUPPORTED_RSDW)) return false;
25
+ let manifest = path.join(dir, "package.json");
26
+ while (!fs.existsSync(manifest)) {
27
+ const parent = path.dirname(path.dirname(manifest));
28
+ if (parent === path.dirname(manifest)) return true;
29
+ manifest = path.join(parent, "package.json");
30
+ }
31
+ try {
32
+ const pkg = JSON.parse(fs.readFileSync(manifest, "utf-8"));
33
+ if (!pkg.dependencies?.["react-server-dom-webpack"] && !pkg.devDependencies?.["react-server-dom-webpack"]) return true;
34
+ const version = findPackageVersion(createRequire(manifest).resolve("react-server-dom-webpack"), "react-server-dom-webpack");
35
+ return !version || isVersionBelow(version, MINIMUM_REACT_VERSION);
36
+ } catch {
37
+ return true;
38
+ }
39
+ }
14
40
  //#endregion
15
- export { assertPluginRscVersion };
41
+ export { assertPluginRscVersion, needsAppReactServerDom };
@@ -1,3 +1,5 @@
1
1
  //#region src/utils/public-routes.d.ts
2
2
  export declare function scanPublicFileRoutes(root: string, configuredPublicDir?: string | false): string[];
3
+ /** List the files in the public directory as `/`-prefixed relative paths. */
4
+ export declare function scanPublicFiles(root: string, configuredPublicDir?: string | false): string[];
3
5
  //#endregion
@@ -3,10 +3,14 @@ import { publicFileRouteKey } from "./public-file-path.js";
3
3
  import fs from "node:fs";
4
4
  //#region src/utils/public-routes.ts
5
5
  function scanPublicFileRoutes(root, configuredPublicDir = "public") {
6
+ return [...new Set(scanPublicFiles(root, configuredPublicDir).map(publicFileRouteKey))].sort();
7
+ }
8
+ /** List the files in the public directory as `/`-prefixed relative paths. */
9
+ function scanPublicFiles(root, configuredPublicDir = "public") {
6
10
  if (configuredPublicDir === false || configuredPublicDir === "") return [];
7
11
  const publicDir = path.resolve(root, configuredPublicDir);
8
- const routes = [];
9
- const visitedDirs = /* @__PURE__ */ new Set();
12
+ const files = [];
13
+ const ancestorDirs = /* @__PURE__ */ new Set();
10
14
  function walk(dir) {
11
15
  let realDir;
12
16
  try {
@@ -14,8 +18,15 @@ function scanPublicFileRoutes(root, configuredPublicDir = "public") {
14
18
  } catch {
15
19
  return;
16
20
  }
17
- if (visitedDirs.has(realDir)) return;
18
- visitedDirs.add(realDir);
21
+ if (ancestorDirs.has(realDir)) return;
22
+ ancestorDirs.add(realDir);
23
+ try {
24
+ walkEntries(dir);
25
+ } finally {
26
+ ancestorDirs.delete(realDir);
27
+ }
28
+ }
29
+ function walkEntries(dir) {
19
30
  const entries = fs.readdirSync(dir, { withFileTypes: true });
20
31
  for (const entry of entries) {
21
32
  const fullPath = path.join(dir, entry.name);
@@ -37,13 +48,13 @@ function scanPublicFileRoutes(root, configuredPublicDir = "public") {
37
48
  if (!stat.isFile()) continue;
38
49
  } else if (!entry.isFile()) continue;
39
50
  const relativePath = path.relative(publicDir, fullPath);
40
- routes.push(publicFileRouteKey("/" + relativePath));
51
+ files.push("/" + relativePath);
41
52
  }
42
53
  }
43
54
  if (fs.existsSync(publicDir)) try {
44
55
  walk(publicDir);
45
56
  } catch {}
46
- return [...new Set(routes)].sort();
57
+ return files;
47
58
  }
48
59
  //#endregion
49
- export { scanPublicFileRoutes };
60
+ export { scanPublicFileRoutes, scanPublicFiles };
@@ -1,7 +1,14 @@
1
1
  //#region src/utils/react-version.d.ts
2
+ /**
3
+ * Lowest React accepted for App Router builds. react-server-dom-webpack 19.3.0
4
+ * shares typed-array buffers across Flight chunks, fixed in 19.3.1.
5
+ */
6
+ export declare const MINIMUM_REACT_VERSION: [number, number, number];
2
7
  export declare function getReactUpgradeDeps(root: string, options?: {
3
8
  fromManifest?: boolean;
9
+ installing?: boolean;
4
10
  }): string[];
11
+ export declare function reactUpgradeRequiredMessage(installCommand: string, upgrades: string[], pluginRscVersion?: string): string;
5
12
  export declare function isVersionBelow(version: string, minimum: [number, number, number]): boolean;
6
13
  /** Walk up from a resolved module entry to find its package version. */
7
14
  export declare function findPackageVersion(resolvedEntry: string, packageName: string): string | null;
@@ -12,17 +12,27 @@ function getDependencyUpgradeDeps(root, recommendations) {
12
12
  }
13
13
  return [];
14
14
  }
15
+ /**
16
+ * Lowest React accepted for App Router builds. react-server-dom-webpack 19.3.0
17
+ * shares typed-array buffers across Flight chunks, fixed in 19.3.1.
18
+ */
19
+ const MINIMUM_REACT_VERSION = [
20
+ 19,
21
+ 3,
22
+ 1
23
+ ];
15
24
  function getReactUpgradeDeps(root, options = {}) {
16
25
  if (options.fromManifest) {
17
26
  const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf-8"));
18
- for (const name of ["react", "react-dom"]) {
27
+ for (const name of [
28
+ "react",
29
+ "react-dom",
30
+ "react-server-dom-webpack"
31
+ ]) {
19
32
  const declared = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];
20
- const version = /^[~^]?([0-9]+(?:\.[0-9]+){0,2}(?:-[0-9A-Za-z.*-]+)?)(?:\.[x*])?$/.exec(declared ?? "")?.[1];
21
- if (version && (version.includes("-") || isVersionBelow(version, [
22
- 19,
23
- 2,
24
- 6
25
- ]))) {
33
+ const version = (options.installing ? /^([0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?)$/ : /^[~^]?([0-9]+(?:\.[0-9]+){0,2}(?:-[0-9A-Za-z.*-]+)?)(?:\.[x*])?$/).exec(declared ?? "")?.[1];
34
+ const canary = !options.installing && version?.includes("-");
35
+ if (version && (canary || isVersionBelow(version, MINIMUM_REACT_VERSION))) {
26
36
  const upgrades = ["react@latest", "react-dom@latest"];
27
37
  const rsdw = pkg.dependencies?.["react-server-dom-webpack"] ?? pkg.devDependencies?.["react-server-dom-webpack"];
28
38
  if (rsdw && rsdw !== "latest") upgrades.push("react-server-dom-webpack@latest");
@@ -31,14 +41,27 @@ function getReactUpgradeDeps(root, options = {}) {
31
41
  }
32
42
  return [];
33
43
  }
34
- return getDependencyUpgradeDeps(root, { react: {
35
- minimumVersion: [
36
- 19,
37
- 2,
38
- 6
39
- ],
40
- upgrades: ["react@latest", "react-dom@latest"]
41
- } });
44
+ return getDependencyUpgradeDeps(root, {
45
+ "react-server-dom-webpack": {
46
+ minimumVersion: MINIMUM_REACT_VERSION,
47
+ upgrades: [
48
+ "react@latest",
49
+ "react-dom@latest",
50
+ "react-server-dom-webpack@latest"
51
+ ]
52
+ },
53
+ react: {
54
+ minimumVersion: MINIMUM_REACT_VERSION,
55
+ upgrades: ["react@latest", "react-dom@latest"]
56
+ },
57
+ "react-dom": {
58
+ minimumVersion: MINIMUM_REACT_VERSION,
59
+ upgrades: ["react@latest", "react-dom@latest"]
60
+ }
61
+ });
62
+ }
63
+ function reactUpgradeRequiredMessage(installCommand, upgrades, pluginRscVersion) {
64
+ return `vinext: App Router requires react, react-dom, and react-server-dom-webpack ${MINIMUM_REACT_VERSION.join(".")} or later.\n` + (pluginRscVersion ? `@vitejs/plugin-rsc ${pluginRscVersion} bundles an older react-server-dom-webpack, so install the latest in your app.\n` : "") + `Run: ${installCommand} ${upgrades.join(" ")}`;
42
65
  }
43
66
  function isVersionBelow(version, minimum) {
44
67
  const current = version.split(".").map((part) => parseInt(part, 10));
@@ -59,4 +82,4 @@ function findPackageVersion(resolvedEntry, packageName) {
59
82
  return null;
60
83
  }
61
84
  //#endregion
62
- export { findPackageVersion, getReactUpgradeDeps, isVersionBelow };
85
+ export { MINIMUM_REACT_VERSION, findPackageVersion, getReactUpgradeDeps, isVersionBelow, reactUpgradeRequiredMessage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vinext",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "Run Next.js apps on Vite. Drop-in replacement for the next CLI.",
5
5
  "homepage": "https://vinext.dev/",
6
6
  "license": "MIT",
@@ -238,12 +238,12 @@
238
238
  "@types/react-dom": "^19.2.3",
239
239
  "@types/ua-parser-js": "0.7.36",
240
240
  "@vitejs/plugin-react": "^6.1.0",
241
- "@vitejs/plugin-rsc": "^0.5.37",
241
+ "@vitejs/plugin-rsc": "^0.5.38",
242
242
  "am-i-vibing": "^0.5.0",
243
243
  "ignore": "5.3.2",
244
244
  "image-size": "2.0.2",
245
245
  "pathslash": "^0.1.0",
246
- "react-server-dom-webpack": "^19.2.7",
246
+ "react-server-dom-webpack": "^19.3.1",
247
247
  "ua-parser-js": "1.0.35",
248
248
  "vite": "npm:@voidzero-dev/vite-plus-core@1.1.0",
249
249
  "vite-plus": "1.1.0"
@@ -252,9 +252,9 @@
252
252
  "@mdx-js/rollup": "^3.0.0",
253
253
  "@vitejs/plugin-react": "^5.1.4 || ^6.0.0",
254
254
  "@vitejs/plugin-rsc": "^0.5.37",
255
- "react": "^19.2.6",
256
- "react-dom": "^19.2.6",
257
- "react-server-dom-webpack": "^19.2.6",
255
+ "react": "^19.3.1",
256
+ "react-dom": "^19.3.1",
257
+ "react-server-dom-webpack": "^19.3.1",
258
258
  "vite": "^8.0.0"
259
259
  },
260
260
  "peerDependenciesMeta": {
@@ -1,47 +0,0 @@
1
- import { RouteRow } from "./report.js";
2
- //#region src/build/nitro-route-rules.d.ts
3
- export type NitroRouteRuleConfig = Record<string, unknown> & {
4
- swr?: boolean | number;
5
- cache?: unknown;
6
- static?: boolean;
7
- isr?: boolean | number;
8
- prerender?: boolean;
9
- };
10
- type NitroRouteRules = Record<string, {
11
- swr: number;
12
- }>;
13
- /**
14
- * Scans the filesystem for route files and generates Nitro `routeRules` for ISR routes.
15
- *
16
- * Note: this duplicates the filesystem scanning that `printBuildReport` also performs.
17
- * The `nitro.setup` hook runs during Nitro initialization (before the build), while
18
- * `printBuildReport` runs after the build, so sharing results is non-trivial. This is
19
- * a future optimization target.
20
- *
21
- * Unlike `printBuildReport`, this path does not receive `prerenderResult`, so routes
22
- * classified as `unknown` by static analysis (which `printBuildReport` might upgrade
23
- * to `static` via speculative prerender) are skipped here.
24
- */
25
- export declare function collectNitroRouteRules(options: {
26
- appDir?: string | null;
27
- pagesDir?: string | null;
28
- pageExtensions: string[];
29
- }): Promise<NitroRouteRules>;
30
- export declare function generateNitroRouteRules(rows: RouteRow[]): NitroRouteRules;
31
- /**
32
- * Converts vinext's internal `:param` route syntax to Nitro's rou3
33
- * pattern format. Nitro uses `rou3` for routeRules matching, which
34
- * supports `*` (single-segment) and `**` (multi-segment) wildcards.
35
- *
36
- * /blog/:slug -> /blog/* (single segment)
37
- * /docs/:slug+ -> /docs/** (one or more segments — catch-all)
38
- * /docs/:slug* -> /docs/** (zero or more segments — optional catch-all)
39
- * /about -> /about (unchanged)
40
- * /:a/:b produces `/*`/`/*` (consecutive single-segment params)
41
- */
42
- export declare function convertToNitroPattern(pattern: string): string;
43
- export declare function mergeNitroRouteRules(existingRouteRules: Record<string, NitroRouteRuleConfig> | undefined, generatedRouteRules: NitroRouteRules): {
44
- routeRules: Record<string, NitroRouteRuleConfig>;
45
- skippedRoutes: string[];
46
- };
47
- //#endregion
@@ -1,79 +0,0 @@
1
- import { appRouter } from "../routing/app-router.js";
2
- import { apiRouter, pagesRouter } from "../routing/pages-router.js";
3
- import { buildReportRows } from "./report.js";
4
- //#region src/build/nitro-route-rules.ts
5
- /**
6
- * Scans the filesystem for route files and generates Nitro `routeRules` for ISR routes.
7
- *
8
- * Note: this duplicates the filesystem scanning that `printBuildReport` also performs.
9
- * The `nitro.setup` hook runs during Nitro initialization (before the build), while
10
- * `printBuildReport` runs after the build, so sharing results is non-trivial. This is
11
- * a future optimization target.
12
- *
13
- * Unlike `printBuildReport`, this path does not receive `prerenderResult`, so routes
14
- * classified as `unknown` by static analysis (which `printBuildReport` might upgrade
15
- * to `static` via speculative prerender) are skipped here.
16
- */
17
- async function collectNitroRouteRules(options) {
18
- const { appDir, pageExtensions, pagesDir } = options;
19
- let appRoutes = [];
20
- let pageRoutes = [];
21
- let apiRoutes = [];
22
- if (appDir) appRoutes = await appRouter(appDir, pageExtensions);
23
- if (pagesDir) {
24
- const [pages, apis] = await Promise.all([pagesRouter(pagesDir, pageExtensions), apiRouter(pagesDir, pageExtensions)]);
25
- pageRoutes = pages;
26
- apiRoutes = apis;
27
- }
28
- return generateNitroRouteRules(buildReportRows({
29
- appRoutes,
30
- pageRoutes,
31
- apiRoutes
32
- }));
33
- }
34
- function generateNitroRouteRules(rows) {
35
- const rules = {};
36
- for (const row of rows) if (row.type === "isr" && typeof row.revalidate === "number" && Number.isFinite(row.revalidate) && row.revalidate > 0) rules[convertToNitroPattern(row.pattern)] = { swr: row.revalidate };
37
- return rules;
38
- }
39
- /**
40
- * Converts vinext's internal `:param` route syntax to Nitro's rou3
41
- * pattern format. Nitro uses `rou3` for routeRules matching, which
42
- * supports `*` (single-segment) and `**` (multi-segment) wildcards.
43
- *
44
- * /blog/:slug -> /blog/* (single segment)
45
- * /docs/:slug+ -> /docs/** (one or more segments — catch-all)
46
- * /docs/:slug* -> /docs/** (zero or more segments — optional catch-all)
47
- * /about -> /about (unchanged)
48
- * /:a/:b produces `/*`/`/*` (consecutive single-segment params)
49
- */
50
- function convertToNitroPattern(pattern) {
51
- return pattern.split("/").map((segment) => {
52
- if (segment.startsWith(":")) return segment.endsWith("+") || segment.endsWith("*") ? "**" : "*";
53
- return segment;
54
- }).join("/");
55
- }
56
- function mergeNitroRouteRules(existingRouteRules, generatedRouteRules) {
57
- const routeRules = { ...existingRouteRules };
58
- const skippedRoutes = [];
59
- for (const [route, generatedRule] of Object.entries(generatedRouteRules)) {
60
- const existingRule = routeRules[route];
61
- if (existingRule && hasUserDefinedCacheRule(existingRule)) {
62
- skippedRoutes.push(route);
63
- continue;
64
- }
65
- routeRules[route] = {
66
- ...existingRule,
67
- ...generatedRule
68
- };
69
- }
70
- return {
71
- routeRules,
72
- skippedRoutes
73
- };
74
- }
75
- function hasUserDefinedCacheRule(rule) {
76
- return rule.swr !== void 0 || rule.cache !== void 0 || rule.static !== void 0 || rule.isr !== void 0 || rule.prerender !== void 0;
77
- }
78
- //#endregion
79
- export { collectNitroRouteRules, convertToNitroPattern, generateNitroRouteRules, mergeNitroRouteRules };
@@ -1,19 +0,0 @@
1
- import { MagicStringTransformResult } from "./transform-result.js";
2
- import { Plugin } from "vite";
3
- //#region src/plugins/cache-flight-codec.d.ts
4
- /**
5
- * Version of the Flight codec package that owns `id`. plugin-rsc resolves the
6
- * app's own react-server-dom-webpack when installed and its vendored copy
7
- * otherwise; reading the codec file's own package.json follows that choice.
8
- */
9
- export declare function readFlightCodecVersion(id: string): string;
10
- /**
11
- * Backport React 19.3's root-element temporary reference branch to older Flight
12
- * codecs, so a "use cache" argument like `Promise<ReactElement>` encodes as a
13
- * temporary reference instead of throwing. Remove it once React 19.3 is the
14
- * minimum supported version.
15
- * https://github.com/facebook/react/blob/v19.3.0/packages/react-client/src/ReactFlightReplyClient.js#L486
16
- */
17
- export declare function patchCacheFlightCodec(code: string, id: string, version?: string): MagicStringTransformResult<import("magic-string").SourceMap> | null;
18
- export declare function cacheFlightCodecPlugin(): Plugin;
19
- //#endregion
@@ -1,68 +0,0 @@
1
- import path from "../deps/.pnpm/pathslash@0.1.0/deps/pathslash/dist/index.js";
2
- import { magicStringTransformResult } from "./transform-result.js";
3
- import fs from "node:fs";
4
- import MagicString from "magic-string";
5
- //#region src/plugins/cache-flight-codec.ts
6
- const CLIENT_CODEC = /\/react-server-dom-(?:webpack|turbopack)-client\.edge\.(?:development|production)\.js$/;
7
- const ELEMENT_CASE = /case REACT_ELEMENT_TYPE:[\s\S]*?throw Error\(\s*"React Element cannot be passed/;
8
- /**
9
- * Version of the Flight codec package that owns `id`. plugin-rsc resolves the
10
- * app's own react-server-dom-webpack when installed and its vendored copy
11
- * otherwise; reading the codec file's own package.json follows that choice.
12
- */
13
- function readFlightCodecVersion(id) {
14
- for (let dir = path.dirname(id);; dir = path.dirname(dir)) {
15
- const manifest = path.join(dir, "package.json");
16
- if (fs.existsSync(manifest)) {
17
- const pkg = JSON.parse(fs.readFileSync(manifest, "utf8"));
18
- if (/^react-server-dom-(?:webpack|turbopack)$/.test(pkg.name ?? "") && pkg.version) return pkg.version;
19
- }
20
- if (path.dirname(dir) === dir) throw new Error(`vinext: cannot find the react-server-dom package version for ${id}`);
21
- }
22
- }
23
- /** React 19.3 ships the branch; 0.0.0-* experimental builds track main. */
24
- function needsElementTemporaryReferenceBackport(version) {
25
- const match = /^(\d+)\.(\d+)\./.exec(version);
26
- if (!match || version.startsWith("0.0.0-")) return false;
27
- const [major, minor] = [Number(match[1]), Number(match[2])];
28
- return major < 19 || major === 19 && minor < 3;
29
- }
30
- /**
31
- * Backport React 19.3's root-element temporary reference branch to older Flight
32
- * codecs, so a "use cache" argument like `Promise<ReactElement>` encodes as a
33
- * temporary reference instead of throwing. Remove it once React 19.3 is the
34
- * minimum supported version.
35
- * https://github.com/facebook/react/blob/v19.3.0/packages/react-client/src/ReactFlightReplyClient.js#L486
36
- */
37
- function patchCacheFlightCodec(code, id, version = readFlightCodecVersion(id)) {
38
- if (!needsElementTemporaryReferenceBackport(version)) return null;
39
- const elementCase = ELEMENT_CASE.exec(code);
40
- if (!elementCase) throw new Error(`vinext: react-server-dom-webpack ${version} (${id}) is not supported. Upgrade react, react-dom, and react-server-dom-webpack to 19.3 or later. If your app does not depend on react-server-dom-webpack directly, upgrade @vitejs/plugin-rsc to 0.5.35 or later instead.`);
41
- const output = new MagicString(code);
42
- output.appendLeft(elementCase.index + elementCase[0].lastIndexOf("throw Error("), "if (void 0 !== temporaryReferences && modelRoot === value) return (modelRoot = null), \"$T\";\n");
43
- return magicStringTransformResult(output, {
44
- hires: "boundary",
45
- source: id
46
- });
47
- }
48
- function cacheFlightCodecPlugin() {
49
- const transform = {
50
- filter: { id: CLIENT_CODEC },
51
- handler: (code, id) => patchCacheFlightCodec(code, id)
52
- };
53
- return {
54
- name: "vinext:cache-flight-codec",
55
- enforce: "pre",
56
- applyToEnvironment: (environment) => environment.name === "rsc",
57
- configEnvironment(name) {
58
- if (name !== "rsc") return;
59
- return { optimizeDeps: { rolldownOptions: { plugins: [{
60
- name: "vinext:cache-flight-codec-optimizer",
61
- transform
62
- }] } } };
63
- },
64
- transform
65
- };
66
- }
67
- //#endregion
68
- export { cacheFlightCodecPlugin, patchCacheFlightCodec, readFlightCodecVersion };
@@ -1,13 +0,0 @@
1
- //#region src/server/middleware-path-to-regexp.d.ts
2
- export type MiddlewarePathToken = string | MiddlewarePathKey;
3
- export type MiddlewarePathKey = {
4
- name: string | number;
5
- prefix: string;
6
- suffix: string;
7
- pattern: string;
8
- modifier: string;
9
- };
10
- export declare function parseMiddlewarePath(value: string): MiddlewarePathToken[];
11
- export declare function normalizeMiddlewarePathTokens(tokens: MiddlewarePathToken[]): MiddlewarePathToken[];
12
- export declare function middlewarePathTokensToRegExp(tokens: MiddlewarePathToken[]): RegExp;
13
- //#endregion
@@ -1,17 +0,0 @@
1
- //#region src/utils/regex-safety.d.ts
2
- export type RegexSafetyIssue = "nested repetition" | "ambiguous alternatives under repetition" | "ambiguous sequence expansion" | "overlapping sequential repetition" | "analysis budget exceeded";
3
- /**
4
- * Whether a RegExp source declares a named group, which turns `\k<name>` into
5
- * a backreference. Escaped characters and character classes cannot open one.
6
- */
7
- export declare function mayHaveNamedGroups(pattern: string): boolean;
8
- /**
9
- * `namedGroups` must describe the whole compiled RegExp when `pattern` is only
10
- * a fragment of it. It defaults to scanning `pattern` itself.
11
- */
12
- export declare function analyzeRegexSafety(pattern: string, options?: {
13
- ignoreCase?: boolean;
14
- namedGroups?: boolean;
15
- }): RegexSafetyIssue | null;
16
- export declare function regexAtomsMayOverlap(left: string, right: string, ignoreCase?: boolean): boolean;
17
- //#endregion