vinext 0.1.7 → 0.2.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 (279) hide show
  1. package/README.md +51 -30
  2. package/dist/build/inject-pregenerated-paths.d.ts +4 -0
  3. package/dist/build/inject-pregenerated-paths.js +18 -0
  4. package/dist/build/layout-classification.js +1 -1
  5. package/dist/build/nitro-route-rules.js +1 -1
  6. package/dist/build/pages-client-assets-module.d.ts +11 -0
  7. package/dist/build/pages-client-assets-module.js +27 -0
  8. package/dist/build/prerender.d.ts +2 -1
  9. package/dist/build/prerender.js +13 -6
  10. package/dist/build/report.d.ts +13 -2
  11. package/dist/build/report.js +99 -2
  12. package/dist/build/run-prerender.d.ts +7 -0
  13. package/dist/build/run-prerender.js +10 -1
  14. package/dist/build/standalone.js +2 -0
  15. package/dist/cache/cache-adapters-virtual.js +3 -3
  16. package/dist/check.d.ts +18 -0
  17. package/dist/check.js +77 -19
  18. package/dist/cli-args.d.ts +1 -2
  19. package/dist/cli-args.js +1 -1
  20. package/dist/cli-dev-config.d.ts +12 -0
  21. package/dist/cli-dev-config.js +23 -0
  22. package/dist/cli.js +113 -97
  23. package/dist/{server → client}/dev-error-overlay-store.d.ts +1 -1
  24. package/dist/{server → client}/dev-error-overlay-store.js +1 -1
  25. package/dist/{server → client}/dev-error-overlay.d.ts +1 -1
  26. package/dist/{server → client}/dev-error-overlay.js +2 -2
  27. package/dist/client/navigation-runtime.d.ts +2 -0
  28. package/dist/client/navigation-runtime.js +3 -1
  29. package/dist/client/window-next.d.ts +2 -1
  30. package/dist/cloudflare/index.d.ts +2 -2
  31. package/dist/cloudflare/index.js +2 -2
  32. package/dist/config/config-matchers.js +14 -10
  33. package/dist/config/next-config.d.ts +6 -3
  34. package/dist/config/next-config.js +47 -1
  35. package/dist/config/prerender.d.ts +34 -0
  36. package/dist/config/prerender.js +55 -0
  37. package/dist/config/server-external-packages.d.ts +4 -0
  38. package/dist/config/server-external-packages.js +91 -0
  39. package/dist/entries/app-rsc-entry.d.ts +2 -1
  40. package/dist/entries/app-rsc-entry.js +89 -15
  41. package/dist/entries/app-rsc-manifest.js +10 -0
  42. package/dist/entries/pages-client-entry.d.ts +3 -0
  43. package/dist/entries/pages-client-entry.js +16 -1
  44. package/dist/entries/pages-server-entry.js +6 -2
  45. package/dist/image/image-adapters-virtual.d.ts +59 -0
  46. package/dist/image/image-adapters-virtual.js +59 -0
  47. package/dist/index.d.ts +33 -0
  48. package/dist/index.js +211 -118
  49. package/dist/init-cloudflare.d.ts +43 -0
  50. package/dist/init-cloudflare.js +839 -0
  51. package/dist/init-platform.d.ts +40 -0
  52. package/dist/init-platform.js +195 -0
  53. package/dist/init.d.ts +16 -38
  54. package/dist/init.js +208 -97
  55. package/dist/node_modules/.pnpm/am-i-vibing@0.5.0/node_modules/am-i-vibing/dist/detector-1yx2Hoe0.js +294 -0
  56. package/dist/node_modules/.pnpm/process-ancestry@0.1.0/node_modules/process-ancestry/dist/index.js +94 -0
  57. package/dist/{cloudflare → packages/cloudflare}/src/cache/cdn-adapter.runtime.js +1 -1
  58. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.d.ts +2 -2
  59. package/dist/{cloudflare → packages/cloudflare}/src/cache/kv-data-adapter.runtime.js +1 -1
  60. package/dist/packages/cloudflare/src/deploy-config.js +150 -0
  61. package/dist/packages/cloudflare/src/deploy-help.js +55 -0
  62. package/dist/packages/cloudflare/src/deploy.js +276 -0
  63. package/dist/{cloudflare → packages/cloudflare/src}/tpr.d.ts +4 -41
  64. package/dist/{cloudflare → packages/cloudflare/src}/tpr.js +18 -15
  65. package/dist/plugins/ast-scope.d.ts +16 -0
  66. package/dist/plugins/ast-scope.js +62 -0
  67. package/dist/plugins/ast-utils.d.ts +27 -1
  68. package/dist/plugins/ast-utils.js +32 -1
  69. package/dist/plugins/css-module-imports.d.ts +14 -0
  70. package/dist/plugins/css-module-imports.js +59 -0
  71. package/dist/plugins/extensionless-dynamic-import.js +2 -2
  72. package/dist/plugins/ignore-dynamic-requests.d.ts +11 -0
  73. package/dist/plugins/ignore-dynamic-requests.js +530 -0
  74. package/dist/plugins/middleware-server-only.d.ts +8 -6
  75. package/dist/plugins/middleware-server-only.js +8 -7
  76. package/dist/plugins/optimize-imports.js +1 -1
  77. package/dist/plugins/typeof-window.d.ts +1 -1
  78. package/dist/plugins/typeof-window.js +28 -56
  79. package/dist/routing/app-route-graph.d.ts +29 -4
  80. package/dist/routing/app-route-graph.js +182 -40
  81. package/dist/routing/app-router.d.ts +5 -0
  82. package/dist/routing/app-router.js +5 -0
  83. package/dist/routing/file-matcher.d.ts +8 -0
  84. package/dist/routing/file-matcher.js +10 -1
  85. package/dist/routing/pages-router.js +2 -2
  86. package/dist/server/api-handler.js +9 -14
  87. package/dist/server/app-browser-action-result.d.ts +4 -1
  88. package/dist/server/app-browser-action-result.js +8 -1
  89. package/dist/server/app-browser-entry.js +194 -190
  90. package/dist/server/app-browser-history-controller.d.ts +2 -1
  91. package/dist/server/app-browser-history-controller.js +6 -2
  92. package/dist/server/app-browser-interception-context.d.ts +1 -0
  93. package/dist/server/app-browser-interception-context.js +4 -2
  94. package/dist/server/app-browser-navigation-controller.d.ts +2 -0
  95. package/dist/server/app-browser-navigation-controller.js +60 -31
  96. package/dist/server/app-browser-server-action-client.d.ts +32 -0
  97. package/dist/server/app-browser-server-action-client.js +127 -0
  98. package/dist/server/app-browser-state.d.ts +11 -1
  99. package/dist/server/app-browser-state.js +25 -8
  100. package/dist/server/app-browser-visible-commit.d.ts +6 -1
  101. package/dist/server/app-browser-visible-commit.js +43 -25
  102. package/dist/server/app-elements-wire.d.ts +9 -2
  103. package/dist/server/app-elements-wire.js +8 -1
  104. package/dist/server/app-elements.d.ts +2 -2
  105. package/dist/server/app-elements.js +4 -3
  106. package/dist/server/app-fallback-renderer.d.ts +5 -2
  107. package/dist/server/app-fallback-renderer.js +15 -7
  108. package/dist/server/app-hydration-cache-publication.d.ts +11 -0
  109. package/dist/server/app-hydration-cache-publication.js +43 -0
  110. package/dist/server/app-middleware.d.ts +4 -3
  111. package/dist/server/app-middleware.js +8 -3
  112. package/dist/server/app-optimistic-routing.js +11 -4
  113. package/dist/server/app-page-boundary-render.d.ts +3 -0
  114. package/dist/server/app-page-boundary-render.js +14 -3
  115. package/dist/server/app-page-cache-finalizer.d.ts +1 -0
  116. package/dist/server/app-page-cache-finalizer.js +10 -3
  117. package/dist/server/app-page-cache-render.d.ts +1 -0
  118. package/dist/server/app-page-cache-render.js +8 -4
  119. package/dist/server/app-page-cache.d.ts +1 -0
  120. package/dist/server/app-page-cache.js +5 -2
  121. package/dist/server/app-page-dispatch.d.ts +33 -4
  122. package/dist/server/app-page-dispatch.js +63 -90
  123. package/dist/server/app-page-element-builder.d.ts +9 -2
  124. package/dist/server/app-page-element-builder.js +114 -23
  125. package/dist/server/app-page-head.d.ts +16 -1
  126. package/dist/server/app-page-head.js +44 -22
  127. package/dist/server/app-page-params.d.ts +2 -1
  128. package/dist/server/app-page-params.js +8 -1
  129. package/dist/server/app-page-ppr-runtime.d.ts +7 -0
  130. package/dist/server/app-page-ppr-runtime.js +70 -0
  131. package/dist/server/app-page-probe.d.ts +1 -0
  132. package/dist/server/app-page-probe.js +6 -1
  133. package/dist/server/app-page-render-identity.d.ts +1 -0
  134. package/dist/server/app-page-render-identity.js +1 -1
  135. package/dist/server/app-page-render.d.ts +4 -1
  136. package/dist/server/app-page-render.js +26 -3
  137. package/dist/server/app-page-request.d.ts +22 -1
  138. package/dist/server/app-page-request.js +92 -15
  139. package/dist/server/app-page-route-wiring.d.ts +14 -2
  140. package/dist/server/app-page-route-wiring.js +61 -25
  141. package/dist/server/app-page-search-params-observation.d.ts +4 -2
  142. package/dist/server/app-page-search-params-observation.js +11 -7
  143. package/dist/server/app-page-segment-state.d.ts +2 -1
  144. package/dist/server/app-page-segment-state.js +3 -1
  145. package/dist/server/app-page-stream.d.ts +5 -0
  146. package/dist/server/app-page-stream.js +3 -1
  147. package/dist/server/app-ppr-fallback-shell-render.d.ts +4 -3
  148. package/dist/server/app-route-handler-dispatch.js +1 -0
  149. package/dist/server/app-route-handler-execution.js +7 -2
  150. package/dist/server/app-route-handler-response.js +1 -0
  151. package/dist/server/app-route-handler-runtime.js +1 -1
  152. package/dist/server/app-route-module-loader.d.ts +2 -0
  153. package/dist/server/app-route-module-loader.js +1 -0
  154. package/dist/server/app-router-entry.js +16 -8
  155. package/dist/server/app-rsc-errors.js +7 -1
  156. package/dist/server/app-rsc-handler.d.ts +3 -1
  157. package/dist/server/app-rsc-handler.js +67 -39
  158. package/dist/server/app-rsc-request-normalization.d.ts +3 -2
  159. package/dist/server/app-rsc-request-normalization.js +6 -3
  160. package/dist/server/app-rsc-route-matching.d.ts +7 -0
  161. package/dist/server/app-rsc-route-matching.js +36 -3
  162. package/dist/server/app-segment-config.d.ts +12 -0
  163. package/dist/server/app-segment-config.js +91 -5
  164. package/dist/server/app-server-action-execution.d.ts +5 -0
  165. package/dist/server/app-server-action-execution.js +94 -33
  166. package/dist/server/app-ssr-entry.d.ts +3 -0
  167. package/dist/server/app-ssr-entry.js +19 -8
  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-static-generation.d.ts +1 -0
  171. package/dist/server/app-static-generation.js +1 -0
  172. package/dist/server/app-visited-response-cache.d.ts +6 -0
  173. package/dist/server/app-visited-response-cache.js +3 -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.js +19 -18
  179. package/dist/server/dev-stack-sourcemap.d.ts +1 -1
  180. package/dist/server/dev-stack-sourcemap.js +1 -1
  181. package/dist/server/fetch-handler.d.ts +2 -0
  182. package/dist/server/fetch-handler.js +18 -0
  183. package/dist/server/headers.d.ts +5 -15
  184. package/dist/server/headers.js +4 -15
  185. package/dist/server/image-optimization.d.ts +51 -1
  186. package/dist/server/image-optimization.js +52 -2
  187. package/dist/server/implicit-tags.js +1 -1
  188. package/dist/server/isr-cache.d.ts +1 -1
  189. package/dist/server/isr-cache.js +2 -2
  190. package/dist/server/metadata-routes.d.ts +3 -1
  191. package/dist/server/metadata-routes.js +12 -2
  192. package/dist/server/middleware-runtime.js +6 -1
  193. package/dist/server/navigation-planner.d.ts +1 -0
  194. package/dist/server/navigation-planner.js +14 -3
  195. package/dist/server/pages-api-route.js +2 -2
  196. package/dist/server/pages-asset-tags.d.ts +4 -6
  197. package/dist/server/pages-asset-tags.js +12 -12
  198. package/dist/server/pages-client-assets.d.ts +12 -0
  199. package/dist/server/pages-client-assets.js +10 -0
  200. package/dist/server/pages-node-compat.d.ts +8 -1
  201. package/dist/server/pages-node-compat.js +32 -4
  202. package/dist/server/pages-page-data.d.ts +24 -1
  203. package/dist/server/pages-page-data.js +45 -24
  204. package/dist/server/pages-page-handler.d.ts +2 -1
  205. package/dist/server/pages-page-handler.js +19 -12
  206. package/dist/server/pages-page-response.d.ts +7 -0
  207. package/dist/server/pages-page-response.js +4 -1
  208. package/dist/server/pages-request-pipeline.d.ts +2 -0
  209. package/dist/server/pages-request-pipeline.js +25 -1
  210. package/dist/server/pages-router-entry.d.ts +30 -0
  211. package/dist/server/pages-router-entry.js +108 -0
  212. package/dist/server/prerender-manifest.d.ts +3 -1
  213. package/dist/server/prerender-route-params.js +1 -1
  214. package/dist/server/prod-server.d.ts +1 -1
  215. package/dist/server/prod-server.js +48 -26
  216. package/dist/server/request-pipeline.js +1 -0
  217. package/dist/server/seed-cache.js +4 -4
  218. package/dist/server/worker-utils.d.ts +2 -1
  219. package/dist/server/worker-utils.js +7 -1
  220. package/dist/shims/app-router-scroll-state.d.ts +1 -0
  221. package/dist/shims/app-router-scroll-state.js +1 -0
  222. package/dist/shims/app-router-scroll.js +2 -1
  223. package/dist/shims/cache.js +19 -15
  224. package/dist/shims/cdn-cache.js +1 -1
  225. package/dist/shims/dynamic-preload-chunks.js +2 -1
  226. package/dist/shims/error-boundary.d.ts +19 -1
  227. package/dist/shims/error-boundary.js +11 -1
  228. package/dist/shims/form.d.ts +3 -1
  229. package/dist/shims/form.js +37 -43
  230. package/dist/shims/headers.d.ts +9 -1
  231. package/dist/shims/headers.js +31 -6
  232. package/dist/shims/image.js +75 -14
  233. package/dist/shims/internal/app-route-detection.d.ts +2 -17
  234. package/dist/shims/internal/app-route-detection.js +4 -17
  235. package/dist/shims/internal/hybrid-client-route-owner-direct.d.ts +23 -0
  236. package/dist/shims/internal/hybrid-client-route-owner-direct.js +51 -0
  237. package/dist/shims/internal/hybrid-client-route-owner.d.ts +2 -15
  238. package/dist/shims/internal/hybrid-client-route-owner.js +9 -60
  239. package/dist/shims/internal/pages-data-fetch-dedup.d.ts +9 -5
  240. package/dist/shims/internal/pages-data-fetch-dedup.js +73 -14
  241. package/dist/shims/internal/pages-data-target.d.ts +10 -9
  242. package/dist/shims/internal/pages-data-target.js +91 -12
  243. package/dist/shims/internal/pages-router-components.d.ts +7 -0
  244. package/dist/shims/internal/pages-router-components.js +13 -0
  245. package/dist/shims/layout-segment-context.d.ts +4 -1
  246. package/dist/shims/layout-segment-context.js +18 -4
  247. package/dist/shims/link.js +70 -37
  248. package/dist/shims/metadata.d.ts +3 -2
  249. package/dist/shims/metadata.js +8 -4
  250. package/dist/shims/navigation.d.ts +5 -1
  251. package/dist/shims/navigation.js +45 -10
  252. package/dist/shims/navigation.react-server.js +1 -1
  253. package/dist/shims/root-params.d.ts +15 -1
  254. package/dist/shims/root-params.js +21 -1
  255. package/dist/shims/router.d.ts +5 -7
  256. package/dist/shims/router.js +374 -94
  257. package/dist/shims/server.js +3 -2
  258. package/dist/shims/slot.js +3 -6
  259. package/dist/typegen.js +6 -5
  260. package/dist/utils/client-runtime-metadata.d.ts +2 -18
  261. package/dist/utils/client-runtime-metadata.js +31 -22
  262. package/dist/utils/dev-stack-sourcemap-endpoint.d.ts +4 -0
  263. package/dist/{server → utils}/dev-stack-sourcemap-endpoint.js +1 -1
  264. package/dist/utils/domain-locale.d.ts +6 -3
  265. package/dist/{server → utils}/middleware-request-headers.d.ts +1 -1
  266. package/dist/{server → utils}/middleware-request-headers.js +2 -2
  267. package/dist/utils/path.d.ts +2 -1
  268. package/dist/utils/path.js +1 -1
  269. package/dist/utils/project.d.ts +52 -2
  270. package/dist/utils/project.js +230 -5
  271. package/dist/utils/protocol-headers.d.ts +17 -0
  272. package/dist/utils/protocol-headers.js +17 -0
  273. package/dist/utils/react-version.d.ts +4 -0
  274. package/dist/utils/react-version.js +44 -0
  275. package/package.json +53 -4
  276. package/dist/deploy.d.ts +0 -190
  277. package/dist/deploy.js +0 -1033
  278. package/dist/server/dev-stack-sourcemap-endpoint.d.ts +0 -4
  279. /package/dist/{cloudflare → packages/cloudflare}/src/utils/cache-control-metadata.js +0 -0
package/dist/init.js CHANGED
@@ -1,9 +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 { createRequire } from "node:module";
3
+ import { setupCloudflarePlatform, usesCommonJsViteConfig, validateCloudflarePlatformSetup } from "./init-cloudflare.js";
4
+ import { getReactUpgradeDeps } from "./utils/react-version.js";
4
5
  import fs from "node:fs";
5
6
  import path from "node:path";
6
- import { execFileSync } from "node:child_process";
7
+ import { spawn, spawnSync } from "node:child_process";
7
8
  //#region src/init.ts
8
9
  /**
9
10
  * vinext init — one-command project migration for Next.js apps.
@@ -11,23 +12,58 @@ import { execFileSync } from "node:child_process";
11
12
  * Automates the steps needed to run a Next.js app under vinext:
12
13
  *
13
14
  * 1. Run `vinext check` to show compatibility report
14
- * 2. Install dependencies (vite, @vitejs/plugin-react, and App Router deps)
15
- * 3. Add "type": "module" to package.json
16
- * 4. Rename CJS config files to .cjs
17
- * 5. Add vinext scripts to package.json
18
- * 6. Generate vite.config.ts
19
- * 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)
20
21
  * 8. Print summary
21
22
  *
22
23
  * Non-destructive: does NOT modify next.config, tsconfig, or source files.
23
24
  * The project should work with both Next.js and vinext simultaneously.
24
25
  */
25
- 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) {
26
62
  return `import vinext from "vinext";
27
63
  import { defineConfig } from "vite";
28
64
 
29
65
  export default defineConfig({
30
- plugins: [vinext()],
66
+ plugins: [${prerender ? `vinext({ prerender: { routes: "*" } })` : "vinext()"}],
31
67
  });
32
68
  `;
33
69
  }
@@ -61,7 +97,7 @@ function addScripts(root, port) {
61
97
  return [];
62
98
  }
63
99
  }
64
- function getInitDeps(isAppRouter) {
100
+ function getInitDeps(isAppRouter, platform) {
65
101
  const deps = [
66
102
  "vinext",
67
103
  "vite",
@@ -71,6 +107,7 @@ function getInitDeps(isAppRouter) {
71
107
  deps.push("@vitejs/plugin-rsc");
72
108
  deps.push("react-server-dom-webpack");
73
109
  }
110
+ if (platform === "cloudflare") deps.push("@cloudflare/vite-plugin", "@vinext/cloudflare", "wrangler");
74
111
  return deps;
75
112
  }
76
113
  function isDepInstalled(root, dep) {
@@ -101,68 +138,50 @@ function isDepInstalled(root, dep) {
101
138
  *
102
139
  * Returns ["react@latest", "react-dom@latest"] if upgrade is needed, [] otherwise.
103
140
  */
104
- function getReactUpgradeDeps(root) {
105
- try {
106
- const version = findPackageVersion(createRequire(path.join(root, "package.json")).resolve("react"), "react");
107
- if (!version) return [];
108
- const parts = version.split(".");
109
- const major = parseInt(parts[0], 10);
110
- const minor = parseInt(parts[1], 10);
111
- const patch = parseInt(parts[2], 10);
112
- if (major < 19 || major === 19 && minor < 2 || major === 19 && minor === 2 && patch < 6) return ["react@latest", "react-dom@latest"];
113
- return [];
114
- } catch {
115
- return [];
116
- }
117
- }
118
- /**
119
- * Walk up from a resolved module entry to find its package.json and return
120
- * the version field. Uses the same approach as PR #18's findReactServerPackages.
121
- */
122
- function findPackageVersion(resolvedEntry, packageName) {
123
- let dir = path.dirname(resolvedEntry);
124
- while (dir !== path.dirname(dir)) {
125
- const candidate = path.join(dir, "package.json");
126
- try {
127
- const pkg = JSON.parse(fs.readFileSync(candidate, "utf-8"));
128
- if (pkg.name === packageName) return pkg.version ?? null;
129
- } catch {}
130
- dir = path.dirname(dir);
131
- }
132
- return null;
133
- }
134
- function installDeps(root, deps, exec, { dev = true } = {}) {
135
- if (deps.length === 0) return;
141
+ async function installDeps(root, deps, exec, { dev = true } = {}) {
142
+ if (deps.length === 0) return "";
136
143
  const baseCmd = detectPackageManager(root);
137
- exec(`${dev ? baseCmd : baseCmd.replace(/ -D$/, "")} ${deps.join(" ")}`, {
144
+ return await exec(`${dev ? baseCmd : baseCmd.replace(/ -D$/, "")} ${deps.join(" ")}`, {
138
145
  cwd: root,
139
146
  stdio: "inherit"
140
- });
147
+ }) ?? "";
141
148
  }
142
149
  /**
143
150
  * Ensure vinext-generated output directories are listed in .gitignore.
144
151
  * Creates the file if it doesn't exist. Returns true if the file was modified
145
152
  * (or created), false if all entries were already present.
146
153
  */
147
- function updateGitignore(root) {
154
+ function updateGitignore(root, platform = "node") {
148
155
  const gitignorePath = path.join(root, ".gitignore");
149
- const entries = [{
150
- entry: "/dist/",
151
- coveredBy: new Set([
152
- "/dist/",
153
- "/dist",
154
- "dist/",
155
- "dist"
156
- ])
157
- }, {
158
- entry: ".vinext/",
159
- coveredBy: new Set([
160
- "/.vinext/",
161
- "/.vinext",
162
- ".vinext/",
163
- ".vinext"
164
- ])
165
- }];
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
+ ];
166
185
  let content = "";
167
186
  let lines = [];
168
187
  if (fs.existsSync(gitignorePath)) {
@@ -175,78 +194,170 @@ function updateGitignore(root) {
175
194
  fs.writeFileSync(gitignorePath, content + separator + missingEntries.join("\n") + "\n", "utf-8");
176
195
  return true;
177
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
+ }
178
212
  async function init(options) {
179
213
  const root = path.resolve(options.root);
180
214
  const port = options.port ?? 3001;
181
- const exec = options._exec ?? ((cmd, opts) => {
182
- const [program, ...args] = cmd.split(" ");
183
- execFileSync(program, args, {
184
- ...opts,
185
- 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
+ ]
186
227
  });
187
- });
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
+ }));
188
248
  const pkgPath = path.join(root, "package.json");
189
249
  if (!fs.existsSync(pkgPath)) {
190
250
  console.error(" Error: No package.json found in the current directory.");
191
251
  console.error(" Run this command from the root of a Next.js project.\n");
192
252
  process.exit(1);
193
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
+ }
194
260
  const viteConfigExists = hasViteConfig(root);
195
- const isApp = hasAppDir(root);
261
+ const isApp = detectProject(root).isAppRouter;
196
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);
197
270
  if (!options.skipCheck) {
198
271
  console.log(" Running compatibility check...\n");
199
272
  const checkResult = runCheck(root);
200
273
  console.log(formatReport(checkResult, { calledFromInit: true }));
201
274
  console.log();
202
275
  }
203
- 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;
204
300
  if (isApp && missingDeps.includes("react-server-dom-webpack")) {
205
301
  const reactUpgrade = getReactUpgradeDeps(root);
206
302
  if (reactUpgrade.length > 0) {
207
- console.log(` Upgrading ${reactUpgrade.map((d) => d.replace(/@latest$/, "")).join(", ")}...`);
208
- 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
+ }
209
311
  }
210
312
  }
211
313
  if (missingDeps.length > 0) {
212
- console.log(` Installing ${missingDeps.join(", ")}...`);
213
- 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
+ }
214
324
  console.log();
215
325
  }
216
- const renamedConfigs = renameCJSConfigs(root);
217
- const addedTypeModule = ensureESModule(root);
218
- const addedScripts = addScripts(root, port);
219
- let generatedViteConfig = false;
220
- const skippedViteConfig = viteConfigExists && !options.force;
221
- if (!skippedViteConfig) {
222
- const configContent = generateViteConfig(isApp);
223
- fs.writeFileSync(path.join(root, "vite.config.ts"), configContent, "utf-8");
224
- 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, " "));
225
332
  }
226
- const updatedGitignore = updateGitignore(root);
227
- console.log(" vinext init complete!\n");
228
- if (missingDeps.length > 0) console.log(` \u2713 Added ${missingDeps.join(", ")} to devDependencies`);
229
- if (addedTypeModule) console.log(` \u2713 Added "type": "module" to package.json`);
230
- for (const [oldName, newName] of renamedConfigs) console.log(` \u2713 Renamed ${oldName} \u2192 ${newName}`);
231
- for (const script of addedScripts) console.log(` \u2713 Added ${script} script`);
232
- if (generatedViteConfig) console.log(` \u2713 Generated vite.config.ts`);
233
- if (skippedViteConfig) console.log(` - Skipped vite.config.ts (already exists, use --force to overwrite)`);
234
- 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");
235
343
  console.log(`
236
- Next steps:
344
+ ${terminalStyle.cyan(terminalStyle.bold("Next steps:"))}
345
+ ${nextSteps.map((step) => ` ${step}`).join("\n")}${nextSteps.length > 0 ? "\n" : ""}
237
346
  ${pmName} run dev:vinext Start the vinext dev server
238
347
  ${pmName} run build:vinext Build production output
239
348
  ${pmName} run start:vinext Start vinext production server
240
349
  ${pmName} run dev Start Next.js (still works as before)
241
350
  `);
242
351
  return {
243
- installedDeps: missingDeps,
352
+ installedDeps: dependenciesAdded ? missingDeps : [],
244
353
  addedTypeModule,
245
354
  renamedConfigs,
246
355
  addedScripts,
247
356
  generatedViteConfig,
248
357
  skippedViteConfig,
249
- updatedGitignore
358
+ updatedGitignore,
359
+ platform,
360
+ generatedPlatformFiles
250
361
  };
251
362
  }
252
363
  //#endregion