vinext 0.1.8 → 0.2.1

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 (285) hide show
  1. package/README.md +51 -30
  2. package/dist/build/css-url-assets.d.ts +3 -1
  3. package/dist/build/css-url-assets.js +18 -1
  4. package/dist/build/inject-pregenerated-paths.d.ts +7 -0
  5. package/dist/build/inject-pregenerated-paths.js +21 -0
  6. package/dist/build/layout-classification.js +1 -1
  7. package/dist/build/nitro-route-rules.js +1 -1
  8. package/dist/build/pages-client-assets-module.d.ts +11 -0
  9. package/dist/build/pages-client-assets-module.js +27 -0
  10. package/dist/build/prerender-server-entry.d.ts +1 -0
  11. package/dist/build/prerender-server-entry.js +49 -0
  12. package/dist/build/prerender-server-pool.d.ts +44 -0
  13. package/dist/build/prerender-server-pool.js +194 -0
  14. package/dist/build/prerender.d.ts +2 -1
  15. package/dist/build/prerender.js +98 -27
  16. package/dist/build/report.d.ts +13 -2
  17. package/dist/build/report.js +99 -2
  18. package/dist/build/run-prerender.d.ts +7 -0
  19. package/dist/build/run-prerender.js +12 -2
  20. package/dist/build/standalone.js +2 -0
  21. package/dist/cache/cache-adapters-virtual.js +3 -3
  22. package/dist/check.d.ts +4 -6
  23. package/dist/check.js +48 -11
  24. package/dist/cli-args.d.ts +1 -2
  25. package/dist/cli-args.js +1 -1
  26. package/dist/cli-dev-config.d.ts +12 -0
  27. package/dist/cli-dev-config.js +23 -0
  28. package/dist/cli.js +112 -96
  29. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  30. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  31. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  32. package/dist/{server → client}/dev-error-overlay.js +2 -2
  33. package/dist/client/navigation-runtime.d.ts +2 -0
  34. package/dist/client/navigation-runtime.js +3 -1
  35. package/dist/client/vinext-next-data.d.ts +4 -1
  36. package/dist/client/window-next.d.ts +2 -1
  37. package/dist/cloudflare/index.d.ts +2 -2
  38. package/dist/cloudflare/index.js +2 -2
  39. package/dist/config/config-matchers.js +45 -19
  40. package/dist/config/next-config.d.ts +41 -9
  41. package/dist/config/next-config.js +60 -3
  42. package/dist/config/prerender.d.ts +34 -0
  43. package/dist/config/prerender.js +55 -0
  44. package/dist/entries/app-browser-entry.js +5 -1
  45. package/dist/entries/app-rsc-entry.d.ts +5 -3
  46. package/dist/entries/app-rsc-entry.js +44 -10
  47. package/dist/entries/app-rsc-manifest.js +2 -0
  48. package/dist/entries/pages-client-entry.d.ts +3 -0
  49. package/dist/entries/pages-client-entry.js +28 -3
  50. package/dist/entries/pages-server-entry.js +23 -6
  51. package/dist/image/image-adapters-virtual.d.ts +59 -0
  52. package/dist/image/image-adapters-virtual.js +59 -0
  53. package/dist/index.d.ts +33 -0
  54. package/dist/index.js +482 -120
  55. package/dist/init-cloudflare.d.ts +43 -0
  56. package/dist/init-cloudflare.js +839 -0
  57. package/dist/init-platform.d.ts +40 -0
  58. package/dist/init-platform.js +195 -0
  59. package/dist/init.d.ts +16 -38
  60. package/dist/init.js +209 -99
  61. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  62. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  63. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  64. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  65. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +9 -2
  66. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  67. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  68. package/dist/packages/cloudflare/src/deploy.js +272 -0
  69. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  70. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +44 -20
  71. package/dist/plugins/ast-scope.d.ts +16 -0
  72. package/dist/plugins/ast-scope.js +62 -0
  73. package/dist/plugins/ast-utils.d.ts +27 -1
  74. package/dist/plugins/ast-utils.js +32 -1
  75. package/dist/plugins/css-module-imports.d.ts +14 -0
  76. package/dist/plugins/css-module-imports.js +59 -0
  77. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  78. package/dist/plugins/fonts.js +1 -1
  79. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  80. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  81. package/dist/plugins/og-assets.js +2 -1
  82. package/dist/plugins/optimize-imports.js +1 -1
  83. package/dist/plugins/rsc-reference-validation-normalizer.d.ts +12 -0
  84. package/dist/plugins/rsc-reference-validation-normalizer.js +48 -0
  85. package/dist/plugins/sass.d.ts +17 -1
  86. package/dist/plugins/sass.js +74 -1
  87. package/dist/plugins/styled-jsx.d.ts +16 -0
  88. package/dist/plugins/styled-jsx.js +149 -0
  89. package/dist/plugins/typeof-window.d.ts +1 -1
  90. package/dist/plugins/typeof-window.js +28 -56
  91. package/dist/routing/app-route-graph.d.ts +23 -2
  92. package/dist/routing/app-route-graph.js +138 -38
  93. package/dist/routing/file-matcher.d.ts +11 -1
  94. package/dist/routing/file-matcher.js +18 -3
  95. package/dist/routing/pages-router.js +2 -2
  96. package/dist/server/api-handler.js +9 -14
  97. package/dist/server/app-browser-action-result.d.ts +4 -1
  98. package/dist/server/app-browser-action-result.js +8 -1
  99. package/dist/server/app-browser-entry.js +198 -57
  100. package/dist/server/app-browser-interception-context.d.ts +1 -0
  101. package/dist/server/app-browser-interception-context.js +4 -2
  102. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  103. package/dist/server/app-browser-navigation-controller.js +60 -31
  104. package/dist/server/app-browser-server-action-client.d.ts +1 -1
  105. package/dist/server/app-browser-server-action-client.js +8 -7
  106. package/dist/server/app-browser-state.d.ts +12 -1
  107. package/dist/server/app-browser-state.js +25 -8
  108. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  109. package/dist/server/app-browser-visible-commit.js +42 -24
  110. package/dist/server/app-elements-wire.d.ts +9 -2
  111. package/dist/server/app-elements-wire.js +8 -1
  112. package/dist/server/app-elements.d.ts +2 -2
  113. package/dist/server/app-elements.js +4 -3
  114. package/dist/server/app-fallback-renderer.d.ts +2 -1
  115. package/dist/server/app-fallback-renderer.js +10 -6
  116. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  117. package/dist/server/app-hydration-cache-publication.js +43 -0
  118. package/dist/server/app-middleware.d.ts +4 -3
  119. package/dist/server/app-middleware.js +8 -3
  120. package/dist/server/app-optimistic-routing.js +11 -4
  121. package/dist/server/app-page-boundary.js +2 -1
  122. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  123. package/dist/server/app-page-cache-finalizer.js +5 -4
  124. package/dist/server/app-page-cache-render.d.ts +1 -0
  125. package/dist/server/app-page-cache-render.js +8 -4
  126. package/dist/server/app-page-cache.d.ts +1 -0
  127. package/dist/server/app-page-cache.js +27 -7
  128. package/dist/server/app-page-dispatch.d.ts +1 -0
  129. package/dist/server/app-page-dispatch.js +26 -8
  130. package/dist/server/app-page-element-builder.d.ts +2 -1
  131. package/dist/server/app-page-element-builder.js +59 -4
  132. package/dist/server/app-page-execution.js +2 -1
  133. package/dist/server/app-page-probe.js +5 -0
  134. package/dist/server/app-page-render-identity.d.ts +2 -0
  135. package/dist/server/app-page-render-identity.js +3 -2
  136. package/dist/server/app-page-render.d.ts +2 -0
  137. package/dist/server/app-page-render.js +85 -16
  138. package/dist/server/app-page-request.d.ts +14 -0
  139. package/dist/server/app-page-request.js +69 -4
  140. package/dist/server/app-page-response.d.ts +7 -0
  141. package/dist/server/app-page-response.js +16 -4
  142. package/dist/server/app-page-route-wiring.d.ts +8 -1
  143. package/dist/server/app-page-route-wiring.js +32 -18
  144. package/dist/server/app-page-segment-state.d.ts +2 -1
  145. package/dist/server/app-page-segment-state.js +3 -1
  146. package/dist/server/app-page-stream.d.ts +7 -1
  147. package/dist/server/app-page-stream.js +3 -1
  148. package/dist/server/app-route-handler-execution.js +5 -1
  149. package/dist/server/app-route-handler-response.js +1 -0
  150. package/dist/server/app-route-handler-runtime.js +1 -1
  151. package/dist/server/app-route-tree-prefetch.d.ts +43 -0
  152. package/dist/server/app-route-tree-prefetch.js +187 -0
  153. package/dist/server/app-router-entry.js +9 -2
  154. package/dist/server/app-rsc-cache-busting.d.ts +2 -1
  155. package/dist/server/app-rsc-cache-busting.js +9 -4
  156. package/dist/server/app-rsc-handler.d.ts +7 -0
  157. package/dist/server/app-rsc-handler.js +148 -39
  158. package/dist/server/app-rsc-render-mode.d.ts +3 -2
  159. package/dist/server/app-rsc-render-mode.js +4 -1
  160. package/dist/server/app-rsc-request-normalization.d.ts +6 -6
  161. package/dist/server/app-rsc-request-normalization.js +10 -8
  162. package/dist/server/app-segment-config.d.ts +11 -0
  163. package/dist/server/app-segment-config.js +62 -6
  164. package/dist/server/app-server-action-execution.d.ts +1 -0
  165. package/dist/server/app-server-action-execution.js +61 -30
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +13 -5
  168. package/dist/server/app-ssr-stream.d.ts +7 -3
  169. package/dist/server/app-ssr-stream.js +10 -6
  170. package/dist/server/app-visited-response-cache.d.ts +6 -0
  171. package/dist/server/app-visited-response-cache.js +3 -1
  172. package/dist/server/cache-control.d.ts +3 -1
  173. package/dist/server/cache-control.js +13 -1
  174. package/dist/server/client-trace-metadata.js +26 -0
  175. package/dist/server/default-global-not-found-module.d.ts +14 -0
  176. package/dist/server/default-global-not-found-module.js +14 -0
  177. package/dist/server/dev-route-files.js +4 -0
  178. package/dist/server/dev-server.d.ts +11 -1
  179. package/dist/server/dev-server.js +94 -35
  180. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  181. package/dist/server/dev-stack-sourcemap.js +1 -1
  182. package/dist/server/fetch-handler.d.ts +2 -0
  183. package/dist/server/fetch-handler.js +18 -0
  184. package/dist/server/headers.d.ts +7 -15
  185. package/dist/server/headers.js +11 -18
  186. package/dist/server/image-optimization.d.ts +51 -1
  187. package/dist/server/image-optimization.js +52 -2
  188. package/dist/server/implicit-tags.js +1 -1
  189. package/dist/server/isr-cache.d.ts +3 -2
  190. package/dist/server/isr-cache.js +9 -5
  191. package/dist/server/metadata-routes.d.ts +3 -1
  192. package/dist/server/metadata-routes.js +12 -2
  193. package/dist/server/middleware-runtime.js +6 -1
  194. package/dist/server/navigation-planner.d.ts +1 -0
  195. package/dist/server/navigation-planner.js +14 -3
  196. package/dist/server/pages-api-route.js +2 -2
  197. package/dist/server/pages-asset-tags.d.ts +4 -6
  198. package/dist/server/pages-asset-tags.js +12 -12
  199. package/dist/server/pages-client-assets.d.ts +12 -0
  200. package/dist/server/pages-client-assets.js +10 -0
  201. package/dist/server/pages-data-route.d.ts +4 -2
  202. package/dist/server/pages-data-route.js +18 -4
  203. package/dist/server/pages-dev-module-url.d.ts +2 -1
  204. package/dist/server/pages-dev-module-url.js +6 -3
  205. package/dist/server/pages-node-compat.d.ts +19 -1
  206. package/dist/server/pages-node-compat.js +81 -4
  207. package/dist/server/pages-page-data.d.ts +33 -1
  208. package/dist/server/pages-page-data.js +62 -33
  209. package/dist/server/pages-page-handler.d.ts +2 -1
  210. package/dist/server/pages-page-handler.js +38 -19
  211. package/dist/server/pages-page-response.d.ts +8 -0
  212. package/dist/server/pages-page-response.js +7 -3
  213. package/dist/server/pages-request-pipeline.d.ts +9 -5
  214. package/dist/server/pages-request-pipeline.js +55 -7
  215. package/dist/server/pages-router-entry.d.ts +30 -0
  216. package/dist/server/pages-router-entry.js +108 -0
  217. package/dist/server/prerender-manifest.d.ts +3 -1
  218. package/dist/server/prerender-route-params.js +1 -1
  219. package/dist/server/prod-server.d.ts +5 -3
  220. package/dist/server/prod-server.js +68 -39
  221. package/dist/server/request-pipeline.js +2 -1
  222. package/dist/server/seed-cache.js +4 -4
  223. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  224. package/dist/shims/app-router-scroll-state.js +1 -0
  225. package/dist/shims/app-router-scroll.js +2 -1
  226. package/dist/shims/cache-handler.js +8 -1
  227. package/dist/shims/cache.js +22 -15
  228. package/dist/shims/cdn-cache.js +1 -1
  229. package/dist/shims/dynamic-preload-chunks.js +2 -1
  230. package/dist/shims/fetch-cache.d.ts +3 -1
  231. package/dist/shims/fetch-cache.js +77 -52
  232. package/dist/shims/form.d.ts +4 -2
  233. package/dist/shims/form.js +37 -43
  234. package/dist/shims/headers.d.ts +7 -1
  235. package/dist/shims/headers.js +17 -3
  236. package/dist/shims/image.js +75 -14
  237. package/dist/shims/internal/app-prefetch-fetch-queue.d.ts +10 -0
  238. package/dist/shims/internal/app-prefetch-fetch-queue.js +61 -0
  239. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  240. package/dist/shims/internal/app-route-detection.js +4 -17
  241. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  242. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  243. package/dist/shims/internal/hybrid-client-route-owner.d.ts +3 -15
  244. package/dist/shims/internal/hybrid-client-route-owner.js +40 -58
  245. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +10 -5
  246. package/dist/shims/internal/pages-data-fetch-dedup.js +84 -14
  247. package/dist/shims/internal/pages-data-target.d.ts +18 -12
  248. package/dist/shims/internal/pages-data-target.js +97 -13
  249. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  250. package/dist/shims/internal/pages-router-components.js +13 -0
  251. package/dist/shims/layout-segment-context.d.ts +4 -1
  252. package/dist/shims/layout-segment-context.js +18 -4
  253. package/dist/shims/link.d.ts +1 -1
  254. package/dist/shims/link.js +224 -58
  255. package/dist/shims/navigation.d.ts +19 -3
  256. package/dist/shims/navigation.js +245 -47
  257. package/dist/shims/request-context.js +18 -0
  258. package/dist/shims/root-params.d.ts +15 -1
  259. package/dist/shims/root-params.js +21 -1
  260. package/dist/shims/router.d.ts +5 -7
  261. package/dist/shims/router.js +387 -102
  262. package/dist/shims/server.js +3 -2
  263. package/dist/shims/slot.js +3 -6
  264. package/dist/shims/unified-request-context.js +1 -0
  265. package/dist/typegen.js +1 -1
  266. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  267. package/dist/utils/client-runtime-metadata.js +31 -22
  268. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  269. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  270. package/dist/utils/domain-locale.d.ts +6 -3
  271. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  272. package/dist/{server → utils}/middleware-request-headers.js +3 -3
  273. package/dist/utils/project.d.ts +48 -2
  274. package/dist/utils/project.js +225 -4
  275. package/dist/utils/protocol-headers.d.ts +23 -0
  276. package/dist/utils/protocol-headers.js +23 -0
  277. package/dist/utils/react-version.d.ts +4 -0
  278. package/dist/utils/react-version.js +44 -0
  279. package/dist/utils/vite-version.d.ts +2 -0
  280. package/dist/utils/vite-version.js +11 -1
  281. package/package.json +47 -2
  282. package/dist/deploy.d.ts +0 -197
  283. package/dist/deploy.js +0 -1040
  284. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  285. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
package/dist/init.js CHANGED
@@ -1,10 +1,10 @@
1
- import { detectPackageManager, detectPackageManagerName, ensureESModule, hasAppDir, hasViteConfig, renameCJSConfigs } from "./utils/project.js";
1
+ import { detectPackageManager, detectPackageManagerName, detectProject, ensureESModule, findViteConfigPath, hasViteConfig, renameCJSConfigs } from "./utils/project.js";
2
2
  import { formatReport, runCheck } from "./check.js";
3
- import { normalizePathSeparators } from "./utils/path.js";
4
- import { createRequire } from "node:module";
3
+ import { setupCloudflarePlatform, usesCommonJsViteConfig, validateCloudflarePlatformSetup } from "./init-cloudflare.js";
4
+ import { getReactUpgradeDeps } from "./utils/react-version.js";
5
5
  import fs from "node:fs";
6
6
  import path from "node:path";
7
- import { execFileSync } from "node:child_process";
7
+ import { spawn, spawnSync } from "node:child_process";
8
8
  //#region src/init.ts
9
9
  /**
10
10
  * vinext init — one-command project migration for Next.js apps.
@@ -12,23 +12,58 @@ import { execFileSync } from "node:child_process";
12
12
  * Automates the steps needed to run a Next.js app under vinext:
13
13
  *
14
14
  * 1. Run `vinext check` to show compatibility report
15
- * 2. Install dependencies (vite, @vitejs/plugin-react, and App Router deps)
16
- * 3. Add "type": "module" to package.json
17
- * 4. Rename CJS config files to .cjs
18
- * 5. Add vinext scripts to package.json
19
- * 6. Generate vite.config.ts
20
- * 7. Update .gitignore to include /dist/ and .vinext/
15
+ * 2. Add "type": "module" to package.json
16
+ * 3. Rename CJS config files to .cjs
17
+ * 4. Add vinext scripts to package.json
18
+ * 5. Generate vite.config.ts and platform files
19
+ * 6. Update .gitignore to include /dist/ and .vinext/
20
+ * 7. Install dependencies (vite, @vitejs/plugin-react, and App Router deps)
21
21
  * 8. Print summary
22
22
  *
23
23
  * Non-destructive: does NOT modify next.config, tsconfig, or source files.
24
24
  * The project should work with both Next.js and vinext simultaneously.
25
25
  */
26
- function generateViteConfig(_isAppRouter) {
26
+ const terminalStyle = {
27
+ bold: (value) => process.stdout.isTTY ? `\x1b[1m${value}\x1b[0m` : value,
28
+ cyan: (value) => process.stdout.isTTY ? `\x1b[36m${value}\x1b[0m` : value,
29
+ green: (value) => process.stdout.isTTY ? `\x1b[32m${value}\x1b[0m` : value,
30
+ yellow: (value) => process.stdout.isTTY ? `\x1b[33m${value}\x1b[0m` : value
31
+ };
32
+ function formatList(items, indent) {
33
+ return items.map((item) => `${indent}- ${item}`).join("\n");
34
+ }
35
+ function isApproveBuildsError(error) {
36
+ const details = [
37
+ error instanceof Error ? error.message : String(error),
38
+ typeof error === "object" && error && "output" in error ? String(error.output) : "",
39
+ typeof error === "object" && error && "stdout" in error ? String(error.stdout) : "",
40
+ typeof error === "object" && error && "stderr" in error ? String(error.stderr) : ""
41
+ ].join("\n");
42
+ return /approve-builds|ERR_PNPM_.*BUILD/i.test(details) || /pnpm/i.test(details) && /(ignored build scripts|blocked build scripts)/i.test(details);
43
+ }
44
+ function hasAutomaticallyIgnoredBuilds(output) {
45
+ const automaticallyIgnored = output.match(/Automatically ignored builds during installation:\s*\n([\s\S]*?)(?:\n\s*\n|$)/i)?.[1];
46
+ if (!automaticallyIgnored) return false;
47
+ return automaticallyIgnored.split("\n").map((line) => line.trim()).some((line) => line.length > 0 && !/^none\.?$/i.test(line) && !/^cannot identify\b/i.test(line));
48
+ }
49
+ function inspectPnpmIgnoredBuilds(root) {
50
+ const result = spawnSync("pnpm", ["ignored-builds"], {
51
+ cwd: root,
52
+ encoding: "utf-8",
53
+ stdio: [
54
+ "ignore",
55
+ "pipe",
56
+ "pipe"
57
+ ]
58
+ });
59
+ return `${result.stdout ?? ""}\n${result.stderr ?? ""}`;
60
+ }
61
+ function generateViteConfig(_isAppRouter, prerender = false) {
27
62
  return `import vinext from "vinext";
28
63
  import { defineConfig } from "vite";
29
64
 
30
65
  export default defineConfig({
31
- plugins: [vinext()],
66
+ plugins: [${prerender ? `vinext({ prerender: { routes: "*" } })` : "vinext()"}],
32
67
  });
33
68
  `;
34
69
  }
@@ -62,7 +97,7 @@ function addScripts(root, port) {
62
97
  return [];
63
98
  }
64
99
  }
65
- function getInitDeps(isAppRouter) {
100
+ function getInitDeps(isAppRouter, platform) {
66
101
  const deps = [
67
102
  "vinext",
68
103
  "vite",
@@ -72,6 +107,7 @@ function getInitDeps(isAppRouter) {
72
107
  deps.push("@vitejs/plugin-rsc");
73
108
  deps.push("react-server-dom-webpack");
74
109
  }
110
+ if (platform === "cloudflare") deps.push("@cloudflare/vite-plugin", "@vinext/cloudflare", "wrangler");
75
111
  return deps;
76
112
  }
77
113
  function isDepInstalled(root, dep) {
@@ -102,68 +138,50 @@ function isDepInstalled(root, dep) {
102
138
  *
103
139
  * Returns ["react@latest", "react-dom@latest"] if upgrade is needed, [] otherwise.
104
140
  */
105
- function getReactUpgradeDeps(root) {
106
- try {
107
- const version = findPackageVersion(createRequire(path.join(root, "package.json")).resolve("react"), "react");
108
- if (!version) return [];
109
- const parts = version.split(".");
110
- const major = parseInt(parts[0], 10);
111
- const minor = parseInt(parts[1], 10);
112
- const patch = parseInt(parts[2], 10);
113
- if (major < 19 || major === 19 && minor < 2 || major === 19 && minor === 2 && patch < 6) return ["react@latest", "react-dom@latest"];
114
- return [];
115
- } catch {
116
- return [];
117
- }
118
- }
119
- /**
120
- * Walk up from a resolved module entry to find its package.json and return
121
- * the version field. Uses the same approach as PR #18's findReactServerPackages.
122
- */
123
- function findPackageVersion(resolvedEntry, packageName) {
124
- let dir = path.dirname(resolvedEntry);
125
- while (dir !== path.dirname(dir)) {
126
- const candidate = path.join(dir, "package.json");
127
- try {
128
- const pkg = JSON.parse(fs.readFileSync(candidate, "utf-8"));
129
- if (pkg.name === packageName) return pkg.version ?? null;
130
- } catch {}
131
- dir = path.dirname(dir);
132
- }
133
- return null;
134
- }
135
- function installDeps(root, deps, exec, { dev = true } = {}) {
136
- if (deps.length === 0) return;
141
+ async function installDeps(root, deps, exec, { dev = true } = {}) {
142
+ if (deps.length === 0) return "";
137
143
  const baseCmd = detectPackageManager(root);
138
- exec(`${dev ? baseCmd : baseCmd.replace(/ -D$/, "")} ${deps.join(" ")}`, {
144
+ return await exec(`${dev ? baseCmd : baseCmd.replace(/ -D$/, "")} ${deps.join(" ")}`, {
139
145
  cwd: root,
140
146
  stdio: "inherit"
141
- });
147
+ }) ?? "";
142
148
  }
143
149
  /**
144
150
  * Ensure vinext-generated output directories are listed in .gitignore.
145
151
  * Creates the file if it doesn't exist. Returns true if the file was modified
146
152
  * (or created), false if all entries were already present.
147
153
  */
148
- function updateGitignore(root) {
154
+ function updateGitignore(root, platform = "node") {
149
155
  const gitignorePath = path.join(root, ".gitignore");
150
- const entries = [{
151
- entry: "/dist/",
152
- coveredBy: new Set([
153
- "/dist/",
154
- "/dist",
155
- "dist/",
156
- "dist"
157
- ])
158
- }, {
159
- entry: ".vinext/",
160
- coveredBy: new Set([
161
- "/.vinext/",
162
- "/.vinext",
163
- ".vinext/",
164
- ".vinext"
165
- ])
166
- }];
156
+ const entries = [
157
+ {
158
+ entry: "/dist/",
159
+ coveredBy: new Set([
160
+ "/dist/",
161
+ "/dist",
162
+ "dist/",
163
+ "dist"
164
+ ])
165
+ },
166
+ {
167
+ entry: ".vinext/",
168
+ coveredBy: new Set([
169
+ "/.vinext/",
170
+ "/.vinext",
171
+ ".vinext/",
172
+ ".vinext"
173
+ ])
174
+ },
175
+ ...platform === "cloudflare" ? [{
176
+ entry: ".wrangler/",
177
+ coveredBy: new Set([
178
+ "/.wrangler/",
179
+ "/.wrangler",
180
+ ".wrangler/",
181
+ ".wrangler"
182
+ ])
183
+ }] : []
184
+ ];
167
185
  let content = "";
168
186
  let lines = [];
169
187
  if (fs.existsSync(gitignorePath)) {
@@ -176,78 +194,170 @@ function updateGitignore(root) {
176
194
  fs.writeFileSync(gitignorePath, content + separator + missingEntries.join("\n") + "\n", "utf-8");
177
195
  return true;
178
196
  }
197
+ function setupNodePlatform(context) {
198
+ if (context.viteConfigExists && !context.force) return {
199
+ generatedViteConfig: false,
200
+ skippedViteConfig: true,
201
+ generatedPlatformFiles: [],
202
+ nextSteps: []
203
+ };
204
+ fs.writeFileSync(context.existingViteConfigPath ?? path.join(context.root, "vite.config.ts"), generateViteConfig(context.isAppRouter, context.prerender), "utf-8");
205
+ return {
206
+ generatedViteConfig: true,
207
+ skippedViteConfig: false,
208
+ generatedPlatformFiles: [],
209
+ nextSteps: []
210
+ };
211
+ }
179
212
  async function init(options) {
180
- const root = normalizePathSeparators(path.resolve(options.root));
213
+ const root = path.resolve(options.root);
181
214
  const port = options.port ?? 3001;
182
- const exec = options._exec ?? ((cmd, opts) => {
183
- const [program, ...args] = cmd.split(" ");
184
- execFileSync(program, args, {
185
- ...opts,
186
- shell: true
215
+ if (!options.platform) throw new Error("A deployment platform must be selected before running vinext init.");
216
+ const platform = options.platform;
217
+ if (platform === "cloudflare" && !options.cloudflare) throw new Error("Cloudflare init options must be resolved before running vinext init.");
218
+ const exec = options._exec ?? ((cmd, opts) => new Promise((resolve, reject) => {
219
+ const child = spawn(cmd, {
220
+ cwd: opts.cwd,
221
+ shell: true,
222
+ stdio: [
223
+ "inherit",
224
+ "pipe",
225
+ "pipe"
226
+ ]
187
227
  });
188
- });
228
+ let output = "";
229
+ child.stdout.on("data", (chunk) => {
230
+ const text = chunk.toString();
231
+ output += text;
232
+ process.stdout.write(text);
233
+ });
234
+ child.stderr.on("data", (chunk) => {
235
+ const text = chunk.toString();
236
+ output += text;
237
+ process.stderr.write(text);
238
+ });
239
+ child.on("error", (error) => reject(Object.assign(error, { output })));
240
+ child.on("close", (status) => {
241
+ if (status === 0) resolve(output);
242
+ else reject(Object.assign(/* @__PURE__ */ new Error(`Command failed with exit code ${status}: ${cmd}`), {
243
+ status,
244
+ output
245
+ }));
246
+ });
247
+ }));
189
248
  const pkgPath = path.join(root, "package.json");
190
249
  if (!fs.existsSync(pkgPath)) {
191
250
  console.error(" Error: No package.json found in the current directory.");
192
251
  console.error(" Run this command from the root of a Next.js project.\n");
193
252
  process.exit(1);
194
253
  }
254
+ let existingViteConfigPath = findViteConfigPath(root);
255
+ if (existingViteConfigPath?.endsWith("vite.config.js")) {
256
+ const existingConfig = fs.readFileSync(existingViteConfigPath, "utf-8");
257
+ const cjsPath = existingViteConfigPath.replace(/\.js$/, ".cjs");
258
+ if (usesCommonJsViteConfig(existingViteConfigPath, existingConfig) && fs.existsSync(cjsPath)) throw new Error("Cannot rename CommonJS vite.config.js because vite.config.cjs already exists. Remove or consolidate one of the files, then rerun vinext init.");
259
+ }
195
260
  const viteConfigExists = hasViteConfig(root);
196
- const isApp = hasAppDir(root);
261
+ const isApp = detectProject(root).isAppRouter;
197
262
  const pmName = detectPackageManagerName(root);
263
+ if (platform === "cloudflare") validateCloudflarePlatformSetup({
264
+ root,
265
+ isAppRouter: isApp,
266
+ existingViteConfigPath,
267
+ prerender: options.prerender,
268
+ today: options._today
269
+ }, options.cloudflare);
198
270
  if (!options.skipCheck) {
199
271
  console.log(" Running compatibility check...\n");
200
272
  const checkResult = runCheck(root);
201
273
  console.log(formatReport(checkResult, { calledFromInit: true }));
202
274
  console.log();
203
275
  }
204
- const missingDeps = getInitDeps(isApp).filter((dep) => !isDepInstalled(root, dep));
276
+ const renamedConfigs = renameCJSConfigs(root);
277
+ if (existingViteConfigPath?.endsWith("vite.config.js") && usesCommonJsViteConfig(existingViteConfigPath, fs.readFileSync(existingViteConfigPath, "utf-8"))) {
278
+ const renamedPath = existingViteConfigPath.replace(/\.js$/, ".cjs");
279
+ fs.renameSync(existingViteConfigPath, renamedPath);
280
+ renamedConfigs.push([path.basename(existingViteConfigPath), path.basename(renamedPath)]);
281
+ existingViteConfigPath = renamedPath;
282
+ }
283
+ const addedTypeModule = ensureESModule(root);
284
+ const addedScripts = addScripts(root, port);
285
+ const setupContext = {
286
+ root,
287
+ isAppRouter: isApp,
288
+ existingViteConfigPath,
289
+ viteConfigExists,
290
+ force: options.force ?? false,
291
+ prerender: options.prerender,
292
+ today: options._today
293
+ };
294
+ const platformSetup = platform === "cloudflare" ? setupCloudflarePlatform(setupContext, options.cloudflare) : setupNodePlatform(setupContext);
295
+ const { generatedViteConfig, skippedViteConfig, generatedPlatformFiles } = platformSetup;
296
+ const updatedGitignore = updateGitignore(root, platform);
297
+ const missingDeps = getInitDeps(isApp, platform).filter((dep) => !isDepInstalled(root, dep));
298
+ let dependencyInstallNeedsApproval = false;
299
+ let dependenciesAdded = false;
205
300
  if (isApp && missingDeps.includes("react-server-dom-webpack")) {
206
301
  const reactUpgrade = getReactUpgradeDeps(root);
207
302
  if (reactUpgrade.length > 0) {
208
- console.log(` Upgrading ${reactUpgrade.map((d) => d.replace(/@latest$/, "")).join(", ")}...`);
209
- installDeps(root, reactUpgrade, exec, { dev: false });
303
+ console.log(` ${terminalStyle.cyan(terminalStyle.bold("Upgrading dependencies:"))}`);
304
+ console.log(formatList(reactUpgrade.map((dep) => dep.replace(/@latest$/, "")), " "));
305
+ try {
306
+ if (isApproveBuildsError(await installDeps(root, reactUpgrade, exec, { dev: false }))) dependencyInstallNeedsApproval = true;
307
+ } catch (error) {
308
+ if (pmName !== "pnpm" || !isApproveBuildsError(error)) throw error;
309
+ dependencyInstallNeedsApproval = true;
310
+ }
210
311
  }
211
312
  }
212
313
  if (missingDeps.length > 0) {
213
- console.log(` Installing ${missingDeps.join(", ")}...`);
214
- installDeps(root, missingDeps, exec);
314
+ console.log(` ${terminalStyle.cyan(terminalStyle.bold("Installing dependencies:"))}`);
315
+ console.log(formatList(missingDeps, " "));
316
+ try {
317
+ const installOutput = await installDeps(root, missingDeps, exec);
318
+ dependenciesAdded = true;
319
+ if (isApproveBuildsError(installOutput)) dependencyInstallNeedsApproval = true;
320
+ } catch (error) {
321
+ if (pmName !== "pnpm" || !isApproveBuildsError(error)) throw error;
322
+ dependencyInstallNeedsApproval = true;
323
+ }
215
324
  console.log();
216
325
  }
217
- const renamedConfigs = renameCJSConfigs(root);
218
- const addedTypeModule = ensureESModule(root);
219
- const addedScripts = addScripts(root, port);
220
- let generatedViteConfig = false;
221
- const skippedViteConfig = viteConfigExists && !options.force;
222
- if (!skippedViteConfig) {
223
- const configContent = generateViteConfig(isApp);
224
- fs.writeFileSync(path.join(root, "vite.config.ts"), configContent, "utf-8");
225
- generatedViteConfig = true;
326
+ if (pmName === "pnpm" && !dependencyInstallNeedsApproval && !options._exec && hasAutomaticallyIgnoredBuilds(inspectPnpmIgnoredBuilds(root))) dependencyInstallNeedsApproval = true;
327
+ else if (pmName === "pnpm" && !dependencyInstallNeedsApproval && options._inspectPnpmIgnoredBuilds && hasAutomaticallyIgnoredBuilds(options._inspectPnpmIgnoredBuilds(root))) dependencyInstallNeedsApproval = true;
328
+ console.log(` ${terminalStyle.green(terminalStyle.bold("vinext init complete!"))}\n`);
329
+ if (dependenciesAdded) {
330
+ console.log(` ${terminalStyle.green("✓")} Added dependencies to devDependencies:`);
331
+ console.log(formatList(missingDeps, " "));
226
332
  }
227
- const updatedGitignore = updateGitignore(root);
228
- console.log(" vinext init complete!\n");
229
- if (missingDeps.length > 0) console.log(` \u2713 Added ${missingDeps.join(", ")} to devDependencies`);
230
- if (addedTypeModule) console.log(` \u2713 Added "type": "module" to package.json`);
231
- for (const [oldName, newName] of renamedConfigs) console.log(` \u2713 Renamed ${oldName} \u2192 ${newName}`);
232
- for (const script of addedScripts) console.log(` \u2713 Added ${script} script`);
233
- if (generatedViteConfig) console.log(` \u2713 Generated vite.config.ts`);
234
- if (skippedViteConfig) console.log(` - Skipped vite.config.ts (already exists, use --force to overwrite)`);
235
- if (updatedGitignore) console.log(` \u2713 Added vinext output directories to .gitignore`);
333
+ if (dependencyInstallNeedsApproval) console.log(` ${terminalStyle.yellow("!")} Dependency installation is waiting for build-script approval`);
334
+ if (addedTypeModule) console.log(` ${terminalStyle.green("✓")} Added "type": "module" to package.json`);
335
+ for (const [oldName, newName] of renamedConfigs) console.log(` ${terminalStyle.green("")} Renamed ${oldName} \u2192 ${newName}`);
336
+ for (const script of addedScripts) console.log(` ${terminalStyle.green("")} Added ${script} script`);
337
+ if (generatedViteConfig) console.log(` ${terminalStyle.green("✓")} Generated vite.config.ts`);
338
+ for (const file of generatedPlatformFiles) console.log(` ${terminalStyle.green("✓")} Generated ${file}`);
339
+ if (skippedViteConfig) console.log(` ${terminalStyle.yellow("-")} Skipped vite.config.ts (already exists, use --force to overwrite)`);
340
+ if (updatedGitignore) console.log(` ${terminalStyle.green("✓")} Added vinext output directories to .gitignore`);
341
+ const nextSteps = [...platformSetup.nextSteps];
342
+ if (dependencyInstallNeedsApproval) nextSteps.push("Dependency installation is incomplete because pnpm blocked dependency build scripts:", "1. Review and approve the required build scripts:", " pnpm approve-builds", "2. Finish installing dependencies:", " pnpm install");
236
343
  console.log(`
237
- Next steps:
344
+ ${terminalStyle.cyan(terminalStyle.bold("Next steps:"))}
345
+ ${nextSteps.map((step) => ` ${step}`).join("\n")}${nextSteps.length > 0 ? "\n" : ""}
238
346
  ${pmName} run dev:vinext Start the vinext dev server
239
347
  ${pmName} run build:vinext Build production output
240
348
  ${pmName} run start:vinext Start vinext production server
241
349
  ${pmName} run dev Start Next.js (still works as before)
242
350
  `);
243
351
  return {
244
- installedDeps: missingDeps,
352
+ installedDeps: dependenciesAdded ? missingDeps : [],
245
353
  addedTypeModule,
246
354
  renamedConfigs,
247
355
  addedScripts,
248
356
  generatedViteConfig,
249
357
  skippedViteConfig,
250
- updatedGitignore
358
+ updatedGitignore,
359
+ platform,
360
+ generatedPlatformFiles
251
361
  };
252
362
  }
253
363
  //#endregion