vinext 0.0.30 → 0.0.31

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 (435) hide show
  1. package/README.md +12 -6
  2. package/dist/build/prerender.d.ts +188 -0
  3. package/dist/build/prerender.js +675 -0
  4. package/dist/build/prerender.js.map +1 -0
  5. package/dist/build/report.d.ts +45 -46
  6. package/dist/build/report.js +247 -276
  7. package/dist/build/report.js.map +1 -1
  8. package/dist/build/run-prerender.d.ts +62 -0
  9. package/dist/build/run-prerender.js +183 -0
  10. package/dist/build/run-prerender.js.map +1 -0
  11. package/dist/build/server-manifest.d.ts +19 -0
  12. package/dist/build/server-manifest.js +29 -0
  13. package/dist/build/server-manifest.js.map +1 -0
  14. package/dist/build/static-export.d.ts +51 -66
  15. package/dist/build/static-export.js +51 -545
  16. package/dist/build/static-export.js.map +1 -1
  17. package/dist/check.d.ts +26 -24
  18. package/dist/check.js +591 -571
  19. package/dist/check.js.map +1 -1
  20. package/dist/cli.d.ts +1 -15
  21. package/dist/cli.js +430 -491
  22. package/dist/cli.js.map +1 -1
  23. package/dist/client/entry.d.ts +1 -2
  24. package/dist/client/entry.js +49 -62
  25. package/dist/client/entry.js.map +1 -1
  26. package/dist/client/validate-module-path.d.ts +4 -1
  27. package/dist/client/validate-module-path.js +23 -28
  28. package/dist/client/validate-module-path.js.map +1 -1
  29. package/dist/client/vinext-next-data.d.ts +15 -20
  30. package/dist/client/vinext-next-data.js +0 -1
  31. package/dist/cloudflare/index.d.ts +3 -8
  32. package/dist/cloudflare/index.js +3 -8
  33. package/dist/cloudflare/kv-cache-handler.d.ts +95 -105
  34. package/dist/cloudflare/kv-cache-handler.js +354 -380
  35. package/dist/cloudflare/kv-cache-handler.js.map +1 -1
  36. package/dist/cloudflare/tpr.d.ts +36 -34
  37. package/dist/cloudflare/tpr.js +460 -603
  38. package/dist/cloudflare/tpr.js.map +1 -1
  39. package/dist/config/config-matchers.d.ts +31 -40
  40. package/dist/config/config-matchers.js +727 -936
  41. package/dist/config/config-matchers.js.map +1 -1
  42. package/dist/config/dotenv.d.ts +18 -11
  43. package/dist/config/dotenv.js +79 -84
  44. package/dist/config/dotenv.js.map +1 -1
  45. package/dist/config/next-config.d.ts +156 -146
  46. package/dist/config/next-config.js +374 -464
  47. package/dist/config/next-config.js.map +1 -1
  48. package/dist/deploy.d.ts +87 -96
  49. package/dist/deploy.js +490 -628
  50. package/dist/deploy.js.map +1 -1
  51. package/dist/entries/app-browser-entry.d.ts +4 -1
  52. package/dist/entries/app-browser-entry.js +12 -8
  53. package/dist/entries/app-browser-entry.js.map +1 -1
  54. package/dist/entries/app-rsc-entry.d.ts +33 -20
  55. package/dist/entries/app-rsc-entry.js +442 -211
  56. package/dist/entries/app-rsc-entry.js.map +1 -1
  57. package/dist/entries/app-ssr-entry.d.ts +9 -1
  58. package/dist/entries/app-ssr-entry.js +61 -28
  59. package/dist/entries/app-ssr-entry.js.map +1 -1
  60. package/dist/entries/pages-client-entry.d.ts +6 -2
  61. package/dist/entries/pages-client-entry.js +30 -33
  62. package/dist/entries/pages-client-entry.js.map +1 -1
  63. package/dist/entries/pages-entry-helpers.d.ts +5 -1
  64. package/dist/entries/pages-entry-helpers.js +17 -14
  65. package/dist/entries/pages-entry-helpers.js.map +1 -1
  66. package/dist/entries/pages-server-entry.d.ts +6 -2
  67. package/dist/entries/pages-server-entry.js +84 -113
  68. package/dist/entries/pages-server-entry.js.map +1 -1
  69. package/dist/index.d.ts +82 -62
  70. package/dist/index.js +2172 -3133
  71. package/dist/index.js.map +1 -1
  72. package/dist/init.d.ts +40 -37
  73. package/dist/init.js +201 -258
  74. package/dist/init.js.map +1 -1
  75. package/dist/plugins/async-hooks-stub.d.ts +7 -3
  76. package/dist/plugins/async-hooks-stub.js +39 -42
  77. package/dist/plugins/async-hooks-stub.js.map +1 -1
  78. package/dist/plugins/client-reference-dedup.d.ts +7 -3
  79. package/dist/plugins/client-reference-dedup.js +63 -88
  80. package/dist/plugins/client-reference-dedup.js.map +1 -1
  81. package/dist/routing/app-router.d.ts +100 -96
  82. package/dist/routing/app-router.js +560 -670
  83. package/dist/routing/app-router.js.map +1 -1
  84. package/dist/routing/file-matcher.d.ts +18 -15
  85. package/dist/routing/file-matcher.js +65 -65
  86. package/dist/routing/file-matcher.js.map +1 -1
  87. package/dist/routing/pages-router.d.ts +23 -24
  88. package/dist/routing/pages-router.js +147 -172
  89. package/dist/routing/pages-router.js.map +1 -1
  90. package/dist/routing/route-trie.d.ts +23 -20
  91. package/dist/routing/route-trie.js +131 -151
  92. package/dist/routing/route-trie.js.map +1 -1
  93. package/dist/routing/route-validation.d.ts +5 -2
  94. package/dist/routing/route-validation.js +98 -130
  95. package/dist/routing/route-validation.js.map +1 -1
  96. package/dist/routing/utils.d.ts +10 -7
  97. package/dist/routing/utils.js +75 -111
  98. package/dist/routing/utils.js.map +1 -1
  99. package/dist/server/api-handler.d.ts +8 -13
  100. package/dist/server/api-handler.js +161 -193
  101. package/dist/server/api-handler.js.map +1 -1
  102. package/dist/server/app-router-entry.d.ts +6 -16
  103. package/dist/server/app-router-entry.js +26 -54
  104. package/dist/server/app-router-entry.js.map +1 -1
  105. package/dist/server/dev-module-runner.d.ts +11 -64
  106. package/dist/server/dev-module-runner.js +89 -101
  107. package/dist/server/dev-module-runner.js.map +1 -1
  108. package/dist/server/dev-origin-check.d.ts +12 -10
  109. package/dist/server/dev-origin-check.js +98 -108
  110. package/dist/server/dev-origin-check.js.map +1 -1
  111. package/dist/server/dev-server.d.ts +17 -14
  112. package/dist/server/dev-server.js +542 -869
  113. package/dist/server/dev-server.js.map +1 -1
  114. package/dist/server/html.d.ts +4 -1
  115. package/dist/server/html.js +25 -26
  116. package/dist/server/html.js.map +1 -1
  117. package/dist/server/image-optimization.d.ts +31 -28
  118. package/dist/server/image-optimization.js +181 -210
  119. package/dist/server/image-optimization.js.map +1 -1
  120. package/dist/server/instrumentation.d.ts +25 -22
  121. package/dist/server/instrumentation.js +110 -122
  122. package/dist/server/instrumentation.js.map +1 -1
  123. package/dist/server/isr-cache.d.ts +16 -26
  124. package/dist/server/isr-cache.js +106 -128
  125. package/dist/server/isr-cache.js.map +1 -1
  126. package/dist/server/metadata-routes.d.ts +85 -88
  127. package/dist/server/metadata-routes.js +270 -317
  128. package/dist/server/metadata-routes.js.map +1 -1
  129. package/dist/server/middleware-codegen.d.ts +7 -4
  130. package/dist/server/middleware-codegen.js +61 -61
  131. package/dist/server/middleware-codegen.js.map +1 -1
  132. package/dist/server/middleware-request-headers.d.ts +8 -6
  133. package/dist/server/middleware-request-headers.js +47 -65
  134. package/dist/server/middleware-request-headers.js.map +1 -1
  135. package/dist/server/middleware.d.ts +31 -47
  136. package/dist/server/middleware.js +273 -404
  137. package/dist/server/middleware.js.map +1 -1
  138. package/dist/server/normalize-path.d.ts +4 -1
  139. package/dist/server/normalize-path.js +33 -47
  140. package/dist/server/normalize-path.js.map +1 -1
  141. package/dist/server/pages-i18n.d.ts +38 -30
  142. package/dist/server/pages-i18n.js +112 -139
  143. package/dist/server/pages-i18n.js.map +1 -1
  144. package/dist/server/prod-server.d.ts +19 -31
  145. package/dist/server/prod-server.js +714 -945
  146. package/dist/server/prod-server.js.map +1 -1
  147. package/dist/server/request-log.d.ts +18 -12
  148. package/dist/server/request-log.js +45 -52
  149. package/dist/server/request-log.js.map +1 -1
  150. package/dist/server/request-pipeline.d.ts +9 -17
  151. package/dist/server/request-pipeline.js +133 -184
  152. package/dist/server/request-pipeline.js.map +1 -1
  153. package/dist/server/worker-utils.d.ts +4 -1
  154. package/dist/server/worker-utils.js +31 -37
  155. package/dist/server/worker-utils.js.map +1 -1
  156. package/dist/shims/amp.d.ts +5 -2
  157. package/dist/shims/amp.js +19 -15
  158. package/dist/shims/amp.js.map +1 -1
  159. package/dist/shims/app.d.ts +8 -10
  160. package/dist/shims/app.js +0 -1
  161. package/dist/shims/cache-runtime.d.ts +20 -45
  162. package/dist/shims/cache-runtime.js +271 -422
  163. package/dist/shims/cache-runtime.js.map +1 -1
  164. package/dist/shims/cache.d.ts +130 -121
  165. package/dist/shims/cache.js +339 -427
  166. package/dist/shims/cache.js.map +1 -1
  167. package/dist/shims/client-only.d.ts +1 -18
  168. package/dist/shims/client-only.js +0 -17
  169. package/dist/shims/compat-router.d.ts +4 -1
  170. package/dist/shims/compat-router.js +23 -19
  171. package/dist/shims/compat-router.js.map +1 -1
  172. package/dist/shims/config.d.ts +7 -5
  173. package/dist/shims/config.js +16 -23
  174. package/dist/shims/config.js.map +1 -1
  175. package/dist/shims/constants.d.ts +119 -118
  176. package/dist/shims/constants.js +159 -164
  177. package/dist/shims/constants.js.map +1 -1
  178. package/dist/shims/document.d.ts +20 -16
  179. package/dist/shims/document.js +41 -22
  180. package/dist/shims/document.js.map +1 -1
  181. package/dist/shims/dynamic.d.ts +13 -22
  182. package/dist/shims/dynamic.js +122 -136
  183. package/dist/shims/dynamic.js.map +1 -1
  184. package/dist/shims/error-boundary.d.ts +22 -15
  185. package/dist/shims/error-boundary.js +81 -79
  186. package/dist/shims/error-boundary.js.map +1 -1
  187. package/dist/shims/error.d.ts +11 -12
  188. package/dist/shims/error.js +35 -39
  189. package/dist/shims/error.js.map +1 -1
  190. package/dist/shims/fetch-cache.d.ts +16 -14
  191. package/dist/shims/fetch-cache.js +437 -645
  192. package/dist/shims/fetch-cache.js.map +1 -1
  193. package/dist/shims/font-google-base.d.ts +28 -26
  194. package/dist/shims/font-google-base.js +238 -325
  195. package/dist/shims/font-google-base.js.map +1 -1
  196. package/dist/shims/font-google.d.ts +3 -3
  197. package/dist/shims/font-google.generated.d.ts +1928 -1924
  198. package/dist/shims/font-google.generated.js +1928 -2133
  199. package/dist/shims/font-google.generated.js.map +1 -1
  200. package/dist/shims/font-google.js +3 -3
  201. package/dist/shims/font-local.d.ts +28 -26
  202. package/dist/shims/font-local.js +204 -260
  203. package/dist/shims/font-local.js.map +1 -1
  204. package/dist/shims/form.d.ts +13 -27
  205. package/dist/shims/form.js +128 -180
  206. package/dist/shims/form.js.map +1 -1
  207. package/dist/shims/head-state.d.ts +8 -13
  208. package/dist/shims/head-state.js +25 -42
  209. package/dist/shims/head-state.js.map +1 -1
  210. package/dist/shims/head.d.ts +16 -20
  211. package/dist/shims/head.js +172 -250
  212. package/dist/shims/head.js.map +1 -1
  213. package/dist/shims/headers.d.ts +84 -78
  214. package/dist/shims/headers.js +447 -575
  215. package/dist/shims/headers.js.map +1 -1
  216. package/dist/shims/i18n-context.d.ts +16 -20
  217. package/dist/shims/i18n-context.js +35 -48
  218. package/dist/shims/i18n-context.js.map +1 -1
  219. package/dist/shims/i18n-state.d.ts +8 -14
  220. package/dist/shims/i18n-state.js +34 -42
  221. package/dist/shims/i18n-state.js.map +1 -1
  222. package/dist/shims/image-config.d.ts +11 -8
  223. package/dist/shims/image-config.js +50 -83
  224. package/dist/shims/image-config.js.map +1 -1
  225. package/dist/shims/image.d.ts +37 -46
  226. package/dist/shims/image.js +283 -308
  227. package/dist/shims/image.js.map +1 -1
  228. package/dist/shims/internal/api-utils.d.ts +7 -4
  229. package/dist/shims/internal/api-utils.js +0 -6
  230. package/dist/shims/internal/app-router-context.d.ts +22 -17
  231. package/dist/shims/internal/app-router-context.js +17 -13
  232. package/dist/shims/internal/app-router-context.js.map +1 -1
  233. package/dist/shims/internal/cookies.d.ts +2 -9
  234. package/dist/shims/internal/cookies.js +2 -9
  235. package/dist/shims/internal/parse-cookie-header.d.ts +4 -1
  236. package/dist/shims/internal/parse-cookie-header.js +29 -29
  237. package/dist/shims/internal/parse-cookie-header.js.map +1 -1
  238. package/dist/shims/internal/router-context.d.ts +6 -1
  239. package/dist/shims/internal/router-context.js +11 -7
  240. package/dist/shims/internal/router-context.js.map +1 -1
  241. package/dist/shims/internal/utils.d.ts +40 -37
  242. package/dist/shims/internal/utils.js +24 -30
  243. package/dist/shims/internal/utils.js.map +1 -1
  244. package/dist/shims/internal/work-unit-async-storage.d.ts +6 -10
  245. package/dist/shims/internal/work-unit-async-storage.js +14 -11
  246. package/dist/shims/internal/work-unit-async-storage.js.map +1 -1
  247. package/dist/shims/layout-segment-context.d.ts +11 -14
  248. package/dist/shims/layout-segment-context.js +24 -23
  249. package/dist/shims/layout-segment-context.js.map +1 -1
  250. package/dist/shims/legacy-image.d.ts +39 -46
  251. package/dist/shims/legacy-image.js +47 -42
  252. package/dist/shims/legacy-image.js.map +1 -1
  253. package/dist/shims/link.d.ts +32 -36
  254. package/dist/shims/link.js +255 -391
  255. package/dist/shims/link.js.map +1 -1
  256. package/dist/shims/metadata.d.ts +210 -202
  257. package/dist/shims/metadata.js +545 -546
  258. package/dist/shims/metadata.js.map +1 -1
  259. package/dist/shims/navigation-state.d.ts +10 -18
  260. package/dist/shims/navigation-state.js +66 -74
  261. package/dist/shims/navigation-state.js.map +1 -1
  262. package/dist/shims/navigation.d.ts +59 -63
  263. package/dist/shims/navigation.js +505 -704
  264. package/dist/shims/navigation.js.map +1 -1
  265. package/dist/shims/og.d.ts +2 -20
  266. package/dist/shims/og.js +2 -19
  267. package/dist/shims/readonly-url-search-params.d.ts +8 -5
  268. package/dist/shims/readonly-url-search-params.js +26 -22
  269. package/dist/shims/readonly-url-search-params.js.map +1 -1
  270. package/dist/shims/request-context.d.ts +8 -5
  271. package/dist/shims/request-context.js +50 -60
  272. package/dist/shims/request-context.js.map +1 -1
  273. package/dist/shims/request-state-types.d.ts +11 -11
  274. package/dist/shims/request-state-types.js +0 -1
  275. package/dist/shims/router-state.d.ts +13 -10
  276. package/dist/shims/router-state.js +34 -43
  277. package/dist/shims/router-state.js.map +1 -1
  278. package/dist/shims/router.d.ts +81 -85
  279. package/dist/shims/router.js +506 -628
  280. package/dist/shims/router.js.map +1 -1
  281. package/dist/shims/script.d.ts +39 -48
  282. package/dist/shims/script.js +107 -160
  283. package/dist/shims/script.js.map +1 -1
  284. package/dist/shims/server-only.d.ts +1 -19
  285. package/dist/shims/server-only.js +0 -18
  286. package/dist/shims/server.d.ts +175 -164
  287. package/dist/shims/server.js +462 -478
  288. package/dist/shims/server.js.map +1 -1
  289. package/dist/shims/unified-request-context.d.ts +20 -20
  290. package/dist/shims/unified-request-context.js +81 -99
  291. package/dist/shims/unified-request-context.js.map +1 -1
  292. package/dist/shims/url-safety.d.ts +4 -1
  293. package/dist/shims/url-safety.js +15 -11
  294. package/dist/shims/url-safety.js.map +1 -1
  295. package/dist/shims/url-utils.d.ts +8 -5
  296. package/dist/shims/url-utils.js +62 -93
  297. package/dist/shims/url-utils.js.map +1 -1
  298. package/dist/shims/web-vitals.d.ts +10 -8
  299. package/dist/shims/web-vitals.js +9 -15
  300. package/dist/shims/web-vitals.js.map +1 -1
  301. package/dist/utils/base-path.d.ts +5 -2
  302. package/dist/utils/base-path.js +21 -19
  303. package/dist/utils/base-path.js.map +1 -1
  304. package/dist/utils/domain-locale.d.ts +17 -9
  305. package/dist/utils/domain-locale.js +36 -56
  306. package/dist/utils/domain-locale.js.map +1 -1
  307. package/dist/utils/hash.d.ts +4 -1
  308. package/dist/utils/hash.js +19 -17
  309. package/dist/utils/hash.js.map +1 -1
  310. package/dist/utils/manifest-paths.d.ts +6 -3
  311. package/dist/utils/manifest-paths.js +15 -16
  312. package/dist/utils/manifest-paths.js.map +1 -1
  313. package/dist/utils/project.d.ts +13 -11
  314. package/dist/utils/project.js +169 -216
  315. package/dist/utils/project.js.map +1 -1
  316. package/dist/utils/query.d.ts +8 -6
  317. package/dist/utils/query.js +57 -67
  318. package/dist/utils/query.js.map +1 -1
  319. package/package.json +10 -9
  320. package/dist/build/report.d.ts.map +0 -1
  321. package/dist/build/static-export.d.ts.map +0 -1
  322. package/dist/check.d.ts.map +0 -1
  323. package/dist/cli.d.ts.map +0 -1
  324. package/dist/client/entry.d.ts.map +0 -1
  325. package/dist/client/validate-module-path.d.ts.map +0 -1
  326. package/dist/client/vinext-next-data.d.ts.map +0 -1
  327. package/dist/client/vinext-next-data.js.map +0 -1
  328. package/dist/cloudflare/index.d.ts.map +0 -1
  329. package/dist/cloudflare/index.js.map +0 -1
  330. package/dist/cloudflare/kv-cache-handler.d.ts.map +0 -1
  331. package/dist/cloudflare/tpr.d.ts.map +0 -1
  332. package/dist/config/config-matchers.d.ts.map +0 -1
  333. package/dist/config/dotenv.d.ts.map +0 -1
  334. package/dist/config/next-config.d.ts.map +0 -1
  335. package/dist/deploy.d.ts.map +0 -1
  336. package/dist/entries/app-browser-entry.d.ts.map +0 -1
  337. package/dist/entries/app-rsc-entry.d.ts.map +0 -1
  338. package/dist/entries/app-ssr-entry.d.ts.map +0 -1
  339. package/dist/entries/pages-client-entry.d.ts.map +0 -1
  340. package/dist/entries/pages-entry-helpers.d.ts.map +0 -1
  341. package/dist/entries/pages-server-entry.d.ts.map +0 -1
  342. package/dist/index.d.ts.map +0 -1
  343. package/dist/init.d.ts.map +0 -1
  344. package/dist/plugins/async-hooks-stub.d.ts.map +0 -1
  345. package/dist/plugins/client-reference-dedup.d.ts.map +0 -1
  346. package/dist/routing/app-router.d.ts.map +0 -1
  347. package/dist/routing/file-matcher.d.ts.map +0 -1
  348. package/dist/routing/pages-router.d.ts.map +0 -1
  349. package/dist/routing/route-trie.d.ts.map +0 -1
  350. package/dist/routing/route-validation.d.ts.map +0 -1
  351. package/dist/routing/utils.d.ts.map +0 -1
  352. package/dist/server/api-handler.d.ts.map +0 -1
  353. package/dist/server/app-router-entry.d.ts.map +0 -1
  354. package/dist/server/dev-module-runner.d.ts.map +0 -1
  355. package/dist/server/dev-origin-check.d.ts.map +0 -1
  356. package/dist/server/dev-server.d.ts.map +0 -1
  357. package/dist/server/html.d.ts.map +0 -1
  358. package/dist/server/image-optimization.d.ts.map +0 -1
  359. package/dist/server/instrumentation.d.ts.map +0 -1
  360. package/dist/server/isr-cache.d.ts.map +0 -1
  361. package/dist/server/metadata-routes.d.ts.map +0 -1
  362. package/dist/server/middleware-codegen.d.ts.map +0 -1
  363. package/dist/server/middleware-request-headers.d.ts.map +0 -1
  364. package/dist/server/middleware.d.ts.map +0 -1
  365. package/dist/server/normalize-path.d.ts.map +0 -1
  366. package/dist/server/pages-i18n.d.ts.map +0 -1
  367. package/dist/server/prod-server.d.ts.map +0 -1
  368. package/dist/server/request-log.d.ts.map +0 -1
  369. package/dist/server/request-pipeline.d.ts.map +0 -1
  370. package/dist/server/worker-utils.d.ts.map +0 -1
  371. package/dist/shims/amp.d.ts.map +0 -1
  372. package/dist/shims/app.d.ts.map +0 -1
  373. package/dist/shims/app.js.map +0 -1
  374. package/dist/shims/cache-runtime.d.ts.map +0 -1
  375. package/dist/shims/cache.d.ts.map +0 -1
  376. package/dist/shims/client-only.d.ts.map +0 -1
  377. package/dist/shims/client-only.js.map +0 -1
  378. package/dist/shims/compat-router.d.ts.map +0 -1
  379. package/dist/shims/config.d.ts.map +0 -1
  380. package/dist/shims/constants.d.ts.map +0 -1
  381. package/dist/shims/document.d.ts.map +0 -1
  382. package/dist/shims/dynamic.d.ts.map +0 -1
  383. package/dist/shims/error-boundary.d.ts.map +0 -1
  384. package/dist/shims/error.d.ts.map +0 -1
  385. package/dist/shims/fetch-cache.d.ts.map +0 -1
  386. package/dist/shims/font-google-base.d.ts.map +0 -1
  387. package/dist/shims/font-google.d.ts.map +0 -1
  388. package/dist/shims/font-google.generated.d.ts.map +0 -1
  389. package/dist/shims/font-google.js.map +0 -1
  390. package/dist/shims/font-local.d.ts.map +0 -1
  391. package/dist/shims/form.d.ts.map +0 -1
  392. package/dist/shims/head-state.d.ts.map +0 -1
  393. package/dist/shims/head.d.ts.map +0 -1
  394. package/dist/shims/headers.d.ts.map +0 -1
  395. package/dist/shims/i18n-context.d.ts.map +0 -1
  396. package/dist/shims/i18n-state.d.ts.map +0 -1
  397. package/dist/shims/image-config.d.ts.map +0 -1
  398. package/dist/shims/image.d.ts.map +0 -1
  399. package/dist/shims/internal/api-utils.d.ts.map +0 -1
  400. package/dist/shims/internal/api-utils.js.map +0 -1
  401. package/dist/shims/internal/app-router-context.d.ts.map +0 -1
  402. package/dist/shims/internal/cookies.d.ts.map +0 -1
  403. package/dist/shims/internal/cookies.js.map +0 -1
  404. package/dist/shims/internal/parse-cookie-header.d.ts.map +0 -1
  405. package/dist/shims/internal/router-context.d.ts.map +0 -1
  406. package/dist/shims/internal/utils.d.ts.map +0 -1
  407. package/dist/shims/internal/work-unit-async-storage.d.ts.map +0 -1
  408. package/dist/shims/layout-segment-context.d.ts.map +0 -1
  409. package/dist/shims/legacy-image.d.ts.map +0 -1
  410. package/dist/shims/link.d.ts.map +0 -1
  411. package/dist/shims/metadata.d.ts.map +0 -1
  412. package/dist/shims/navigation-state.d.ts.map +0 -1
  413. package/dist/shims/navigation.d.ts.map +0 -1
  414. package/dist/shims/og.d.ts.map +0 -1
  415. package/dist/shims/og.js.map +0 -1
  416. package/dist/shims/readonly-url-search-params.d.ts.map +0 -1
  417. package/dist/shims/request-context.d.ts.map +0 -1
  418. package/dist/shims/request-state-types.d.ts.map +0 -1
  419. package/dist/shims/request-state-types.js.map +0 -1
  420. package/dist/shims/router-state.d.ts.map +0 -1
  421. package/dist/shims/router.d.ts.map +0 -1
  422. package/dist/shims/script.d.ts.map +0 -1
  423. package/dist/shims/server-only.d.ts.map +0 -1
  424. package/dist/shims/server-only.js.map +0 -1
  425. package/dist/shims/server.d.ts.map +0 -1
  426. package/dist/shims/unified-request-context.d.ts.map +0 -1
  427. package/dist/shims/url-safety.d.ts.map +0 -1
  428. package/dist/shims/url-utils.d.ts.map +0 -1
  429. package/dist/shims/web-vitals.d.ts.map +0 -1
  430. package/dist/utils/base-path.d.ts.map +0 -1
  431. package/dist/utils/domain-locale.d.ts.map +0 -1
  432. package/dist/utils/hash.d.ts.map +0 -1
  433. package/dist/utils/manifest-paths.d.ts.map +0 -1
  434. package/dist/utils/project.d.ts.map +0 -1
  435. package/dist/utils/query.d.ts.map +0 -1
package/dist/check.js CHANGED
@@ -1,595 +1,615 @@
1
- /**
2
- * vinext check — compatibility scanner for Next.js apps
3
- *
4
- * Scans an existing Next.js app and produces a compatibility report
5
- * showing what will work, what needs changes, and an overall score.
6
- */
7
1
  import { detectPackageManager } from "./utils/project.js";
8
2
  import fs from "node:fs";
9
3
  import path from "node:path";
10
- // ── Import support map ─────────────────────────────────────────────────────
4
+ //#region src/check.ts
5
+ /**
6
+ * vinext check — compatibility scanner for Next.js apps
7
+ *
8
+ * Scans an existing Next.js app and produces a compatibility report
9
+ * showing what will work, what needs changes, and an overall score.
10
+ */
11
11
  const IMPORT_SUPPORT = {
12
- next: { status: "supported", detail: "type-only exports (Metadata, NextPage, etc.)" },
13
- "next/link": { status: "supported" },
14
- "next/image": { status: "supported", detail: "uses @unpic/react (no local optimization yet)" },
15
- "next/router": { status: "supported" },
16
- "next/navigation": { status: "supported" },
17
- "next/headers": { status: "supported" },
18
- "next/server": { status: "supported", detail: "NextRequest/NextResponse shimmed" },
19
- "next/cache": {
20
- status: "supported",
21
- detail: "revalidateTag, revalidatePath, unstable_cache, cacheLife, cacheTag",
22
- },
23
- "next/dynamic": { status: "supported" },
24
- "next/head": { status: "supported" },
25
- "next/script": { status: "supported" },
26
- "next/font/google": {
27
- status: "partial",
28
- detail: "fonts loaded from CDN, not self-hosted at build time",
29
- },
30
- "next/font/local": {
31
- status: "supported",
32
- detail: "className and variable modes both work; no build-time subsetting",
33
- },
34
- "next/og": { status: "supported", detail: "ImageResponse via @vercel/og" },
35
- "next/config": { status: "supported" },
36
- "next/amp": { status: "unsupported", detail: "AMP is not supported" },
37
- "next/document": { status: "supported", detail: "custom _document.tsx" },
38
- "next/app": { status: "supported", detail: "custom _app.tsx" },
39
- "next/error": { status: "supported" },
40
- "next/third-parties/google": {
41
- status: "unsupported",
42
- detail: "third-party script optimization not implemented",
43
- },
44
- "server-only": { status: "supported" },
45
- "client-only": { status: "supported" },
12
+ next: {
13
+ status: "supported",
14
+ detail: "type-only exports (Metadata, NextPage, etc.)"
15
+ },
16
+ "next/link": { status: "supported" },
17
+ "next/image": {
18
+ status: "supported",
19
+ detail: "uses @unpic/react (no local optimization yet)"
20
+ },
21
+ "next/router": { status: "supported" },
22
+ "next/navigation": { status: "supported" },
23
+ "next/headers": { status: "supported" },
24
+ "next/server": {
25
+ status: "supported",
26
+ detail: "NextRequest/NextResponse shimmed"
27
+ },
28
+ "next/cache": {
29
+ status: "supported",
30
+ detail: "revalidateTag, revalidatePath, unstable_cache, cacheLife, cacheTag"
31
+ },
32
+ "next/dynamic": { status: "supported" },
33
+ "next/head": { status: "supported" },
34
+ "next/script": { status: "supported" },
35
+ "next/font/google": {
36
+ status: "partial",
37
+ detail: "fonts loaded from CDN, not self-hosted at build time"
38
+ },
39
+ "next/font/local": {
40
+ status: "supported",
41
+ detail: "className and variable modes both work; no build-time subsetting"
42
+ },
43
+ "next/og": {
44
+ status: "supported",
45
+ detail: "ImageResponse via @vercel/og"
46
+ },
47
+ "next/config": { status: "supported" },
48
+ "next/amp": {
49
+ status: "unsupported",
50
+ detail: "AMP is not supported"
51
+ },
52
+ "next/document": {
53
+ status: "supported",
54
+ detail: "custom _document.tsx"
55
+ },
56
+ "next/app": {
57
+ status: "supported",
58
+ detail: "custom _app.tsx"
59
+ },
60
+ "next/error": { status: "supported" },
61
+ "next/third-parties/google": {
62
+ status: "unsupported",
63
+ detail: "third-party script optimization not implemented"
64
+ },
65
+ "server-only": { status: "supported" },
66
+ "client-only": { status: "supported" }
46
67
  };
47
- // ── Config support map ─────────────────────────────────────────────────────
48
68
  const CONFIG_SUPPORT = {
49
- basePath: { status: "supported" },
50
- trailingSlash: { status: "supported" },
51
- redirects: { status: "supported" },
52
- rewrites: { status: "supported" },
53
- headers: { status: "supported" },
54
- i18n: { status: "supported", detail: "path-prefix routing; domain routing for Pages Router" },
55
- env: { status: "supported" },
56
- images: { status: "partial", detail: "remotePatterns validated, no local optimization" },
57
- allowedDevOrigins: { status: "supported", detail: "dev server cross-origin allowlist" },
58
- output: { status: "supported", detail: "'export' and 'standalone' modes" },
59
- transpilePackages: { status: "supported", detail: "Vite handles this natively" },
60
- webpack: {
61
- status: "unsupported",
62
- detail: "Vite replaces webpack — custom webpack configs need migration",
63
- },
64
- "experimental.ppr": { status: "unsupported", detail: "partial prerendering not yet implemented" },
65
- "experimental.typedRoutes": { status: "unsupported", detail: "typed routes not implemented" },
66
- "experimental.serverActions": {
67
- status: "supported",
68
- detail: "server actions via 'use server' directive",
69
- },
70
- "i18n.domains": {
71
- status: "partial",
72
- detail: "supported for Pages Router; App Router unchanged",
73
- },
74
- reactStrictMode: { status: "supported", detail: "always enabled" },
75
- poweredByHeader: {
76
- status: "supported",
77
- detail: "not sent (matching Next.js default when disabled)",
78
- },
69
+ basePath: { status: "supported" },
70
+ trailingSlash: { status: "supported" },
71
+ redirects: { status: "supported" },
72
+ rewrites: { status: "supported" },
73
+ headers: { status: "supported" },
74
+ i18n: {
75
+ status: "supported",
76
+ detail: "path-prefix routing; domain routing for Pages Router"
77
+ },
78
+ env: { status: "supported" },
79
+ images: {
80
+ status: "partial",
81
+ detail: "remotePatterns validated, no local optimization"
82
+ },
83
+ allowedDevOrigins: {
84
+ status: "supported",
85
+ detail: "dev server cross-origin allowlist"
86
+ },
87
+ output: {
88
+ status: "supported",
89
+ detail: "'export' and 'standalone' modes"
90
+ },
91
+ transpilePackages: {
92
+ status: "supported",
93
+ detail: "Vite handles this natively"
94
+ },
95
+ webpack: {
96
+ status: "unsupported",
97
+ detail: "Vite replaces webpack custom webpack configs need migration"
98
+ },
99
+ "experimental.ppr": {
100
+ status: "unsupported",
101
+ detail: "partial prerendering not yet implemented"
102
+ },
103
+ "experimental.typedRoutes": {
104
+ status: "unsupported",
105
+ detail: "typed routes not implemented"
106
+ },
107
+ "experimental.serverActions": {
108
+ status: "supported",
109
+ detail: "server actions via 'use server' directive"
110
+ },
111
+ "i18n.domains": {
112
+ status: "partial",
113
+ detail: "supported for Pages Router; App Router unchanged"
114
+ },
115
+ reactStrictMode: {
116
+ status: "supported",
117
+ detail: "always enabled"
118
+ },
119
+ poweredByHeader: {
120
+ status: "supported",
121
+ detail: "not sent (matching Next.js default when disabled)"
122
+ }
79
123
  };
80
- // ── Library support map ────────────────────────────────────────────────────
81
124
  const LIBRARY_SUPPORT = {
82
- "next-themes": { status: "supported" },
83
- nuqs: { status: "supported" },
84
- "next-view-transitions": { status: "supported" },
85
- "@vercel/analytics": { status: "supported", detail: "analytics script injected client-side" },
86
- "next-intl": {
87
- status: "supported",
88
- detail: "auto-detected from i18n/request.{ts,tsx,js,jsx}; createNextIntlPlugin wrapper not needed",
89
- },
90
- "@clerk/nextjs": {
91
- status: "unsupported",
92
- detail: "deep Next.js middleware integration not compatible",
93
- },
94
- "@auth/nextjs": {
95
- status: "unsupported",
96
- detail: "relies on Next.js internal auth handlers; consider migrating to better-auth",
97
- },
98
- "next-auth": {
99
- status: "unsupported",
100
- detail: "relies on Next.js API route internals; consider migrating to better-auth (see https://authjs.dev/getting-started/migrate-to-better-auth)",
101
- },
102
- "better-auth": {
103
- status: "supported",
104
- detail: "uses only public next/* APIs (headers, cookies, NextRequest/NextResponse)",
105
- },
106
- "@sentry/nextjs": {
107
- status: "partial",
108
- detail: "client-side works, server integration needs manual setup",
109
- },
110
- "@t3-oss/env-nextjs": { status: "supported" },
111
- tailwindcss: { status: "supported" },
112
- "styled-components": { status: "supported", detail: "SSR via useServerInsertedHTML" },
113
- "@emotion/react": { status: "supported", detail: "SSR via useServerInsertedHTML" },
114
- "lucide-react": { status: "supported" },
115
- "framer-motion": { status: "supported" },
116
- "@radix-ui/react-dialog": { status: "supported" },
117
- "shadcn-ui": { status: "supported" },
118
- zod: { status: "supported" },
119
- "react-hook-form": { status: "supported" },
120
- prisma: { status: "supported", detail: "works on Cloudflare Workers with Prisma Accelerate" },
121
- drizzle: { status: "supported", detail: "works with D1 on Cloudflare Workers" },
125
+ "next-themes": { status: "supported" },
126
+ nuqs: { status: "supported" },
127
+ "next-view-transitions": { status: "supported" },
128
+ "@vercel/analytics": {
129
+ status: "supported",
130
+ detail: "analytics script injected client-side"
131
+ },
132
+ "next-intl": {
133
+ status: "supported",
134
+ detail: "auto-detected from i18n/request.{ts,tsx,js,jsx}; createNextIntlPlugin wrapper not needed"
135
+ },
136
+ "@clerk/nextjs": {
137
+ status: "unsupported",
138
+ detail: "deep Next.js middleware integration not compatible"
139
+ },
140
+ "@auth/nextjs": {
141
+ status: "unsupported",
142
+ detail: "relies on Next.js internal auth handlers; consider migrating to better-auth"
143
+ },
144
+ "next-auth": {
145
+ status: "unsupported",
146
+ detail: "relies on Next.js API route internals; consider migrating to better-auth (see https://authjs.dev/getting-started/migrate-to-better-auth)"
147
+ },
148
+ "better-auth": {
149
+ status: "supported",
150
+ detail: "uses only public next/* APIs (headers, cookies, NextRequest/NextResponse)"
151
+ },
152
+ "@sentry/nextjs": {
153
+ status: "partial",
154
+ detail: "client-side works, server integration needs manual setup"
155
+ },
156
+ "@t3-oss/env-nextjs": { status: "supported" },
157
+ tailwindcss: { status: "supported" },
158
+ "styled-components": {
159
+ status: "supported",
160
+ detail: "SSR via useServerInsertedHTML"
161
+ },
162
+ "@emotion/react": {
163
+ status: "supported",
164
+ detail: "SSR via useServerInsertedHTML"
165
+ },
166
+ "lucide-react": { status: "supported" },
167
+ "framer-motion": { status: "supported" },
168
+ "@radix-ui/react-dialog": { status: "supported" },
169
+ "shadcn-ui": { status: "supported" },
170
+ zod: { status: "supported" },
171
+ "react-hook-form": { status: "supported" },
172
+ prisma: {
173
+ status: "supported",
174
+ detail: "works on Cloudflare Workers with Prisma Accelerate"
175
+ },
176
+ drizzle: {
177
+ status: "supported",
178
+ detail: "works with D1 on Cloudflare Workers"
179
+ }
122
180
  };
123
- // ── Scanning functions ─────────────────────────────────────────────────────
124
181
  /**
125
- * Recursively find all source files in a directory.
126
- */
127
- function findSourceFiles(dir, extensions = [".ts", ".tsx", ".js", ".jsx", ".mjs"]) {
128
- const results = [];
129
- if (!fs.existsSync(dir))
130
- return results;
131
- const entries = fs.readdirSync(dir, { withFileTypes: true });
132
- for (const entry of entries) {
133
- const fullPath = path.join(dir, entry.name);
134
- if (entry.isDirectory()) {
135
- if (entry.name === "node_modules" ||
136
- entry.name === ".next" ||
137
- entry.name === "dist" ||
138
- entry.name === ".git")
139
- continue;
140
- results.push(...findSourceFiles(fullPath, extensions));
141
- }
142
- else if (extensions.some((ext) => entry.name.endsWith(ext))) {
143
- results.push(fullPath);
144
- }
145
- }
146
- return results;
182
+ * Recursively find all source files in a directory.
183
+ */
184
+ function findSourceFiles(dir, extensions = [
185
+ ".ts",
186
+ ".tsx",
187
+ ".js",
188
+ ".jsx",
189
+ ".mjs"
190
+ ]) {
191
+ const results = [];
192
+ if (!fs.existsSync(dir)) return results;
193
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
194
+ for (const entry of entries) {
195
+ const fullPath = path.join(dir, entry.name);
196
+ if (entry.isDirectory()) {
197
+ if (entry.name === "node_modules" || entry.name === ".next" || entry.name === "dist" || entry.name === ".git") continue;
198
+ results.push(...findSourceFiles(fullPath, extensions));
199
+ } else if (extensions.some((ext) => entry.name.endsWith(ext))) results.push(fullPath);
200
+ }
201
+ return results;
147
202
  }
148
203
  /**
149
- * Scan source files for `import ... from 'next/...'` statements.
150
- */
151
- export function scanImports(root) {
152
- const files = findSourceFiles(root);
153
- const importUsage = new Map();
154
- const importRegex = /(?:import\s+(?:[\w{},\s*]+\s+from\s+)?|require\s*\()['"]([^'"]+)['"]\)?/g;
155
- // Skip `import type` and `import { type ... }` — they're erased at compile time
156
- const typeOnlyImportRegex = /import\s+type\s+/;
157
- for (const file of files) {
158
- const content = fs.readFileSync(file, "utf-8");
159
- let match;
160
- while ((match = importRegex.exec(content)) !== null) {
161
- const mod = match[1];
162
- // Skip type-only imports (no runtime effect)
163
- const lineStart = content.lastIndexOf("\n", match.index) + 1;
164
- const line = content.slice(lineStart, match.index + match[0].length);
165
- if (typeOnlyImportRegex.test(line))
166
- continue;
167
- // Only track next/* imports and server-only/client-only
168
- if (mod.startsWith("next/") ||
169
- mod === "next" ||
170
- mod === "server-only" ||
171
- mod === "client-only") {
172
- // Normalize: next/font/google -> next/font/google
173
- const normalized = mod === "next" ? "next" : mod;
174
- if (!importUsage.has(normalized))
175
- importUsage.set(normalized, []);
176
- const relFile = path.relative(root, file);
177
- const usedInFiles = importUsage.get(normalized) ?? [];
178
- if (!usedInFiles.includes(relFile)) {
179
- usedInFiles.push(relFile);
180
- }
181
- }
182
- }
183
- }
184
- const items = [];
185
- for (const [mod, usedFiles] of importUsage) {
186
- const support = IMPORT_SUPPORT[mod.startsWith("next/") && mod.endsWith(".js") ? mod.replace(/\.js$/, "") : mod];
187
- if (support) {
188
- items.push({
189
- name: mod,
190
- status: support.status,
191
- detail: support.detail,
192
- files: usedFiles,
193
- });
194
- }
195
- else {
196
- items.push({
197
- name: mod,
198
- status: "unsupported",
199
- detail: "not recognized by vinext",
200
- files: usedFiles,
201
- });
202
- }
203
- }
204
- // Sort: unsupported first, then partial, then supported
205
- items.sort((a, b) => {
206
- const order = { unsupported: 0, partial: 1, supported: 2 };
207
- return order[a.status] - order[b.status];
208
- });
209
- return items;
204
+ * Scan source files for `import ... from 'next/...'` statements.
205
+ */
206
+ function scanImports(root) {
207
+ const files = findSourceFiles(root);
208
+ const importUsage = /* @__PURE__ */ new Map();
209
+ const importRegex = /(?:import\s+(?:[\w{},\s*]+\s+from\s+)?|require\s*\()['"]([^'"]+)['"]\)?/g;
210
+ const typeOnlyImportRegex = /import\s+type\s+/;
211
+ for (const file of files) {
212
+ const content = fs.readFileSync(file, "utf-8");
213
+ let match;
214
+ while ((match = importRegex.exec(content)) !== null) {
215
+ const mod = match[1];
216
+ const lineStart = content.lastIndexOf("\n", match.index) + 1;
217
+ const line = content.slice(lineStart, match.index + match[0].length);
218
+ if (typeOnlyImportRegex.test(line)) continue;
219
+ if (mod.startsWith("next/") || mod === "next" || mod === "server-only" || mod === "client-only") {
220
+ const normalized = mod === "next" ? "next" : mod;
221
+ if (!importUsage.has(normalized)) importUsage.set(normalized, []);
222
+ const relFile = path.relative(root, file);
223
+ const usedInFiles = importUsage.get(normalized) ?? [];
224
+ if (!usedInFiles.includes(relFile)) usedInFiles.push(relFile);
225
+ }
226
+ }
227
+ }
228
+ const items = [];
229
+ for (const [mod, usedFiles] of importUsage) {
230
+ const support = IMPORT_SUPPORT[mod.startsWith("next/") && mod.endsWith(".js") ? mod.replace(/\.js$/, "") : mod];
231
+ if (support) items.push({
232
+ name: mod,
233
+ status: support.status,
234
+ detail: support.detail,
235
+ files: usedFiles
236
+ });
237
+ else items.push({
238
+ name: mod,
239
+ status: "unsupported",
240
+ detail: "not recognized by vinext",
241
+ files: usedFiles
242
+ });
243
+ }
244
+ items.sort((a, b) => {
245
+ const order = {
246
+ unsupported: 0,
247
+ partial: 1,
248
+ supported: 2
249
+ };
250
+ return order[a.status] - order[b.status];
251
+ });
252
+ return items;
210
253
  }
211
254
  /**
212
- * Analyze next.config.js/mjs/ts for supported and unsupported options.
213
- */
214
- export function analyzeConfig(root) {
215
- const configFiles = ["next.config.ts", "next.config.mjs", "next.config.js", "next.config.cjs"];
216
- let configPath = null;
217
- for (const f of configFiles) {
218
- const p = path.join(root, f);
219
- if (fs.existsSync(p)) {
220
- configPath = p;
221
- break;
222
- }
223
- }
224
- if (!configPath) {
225
- return [
226
- {
227
- name: "next.config",
228
- status: "supported",
229
- detail: "no config file found (defaults are fine)",
230
- },
231
- ];
232
- }
233
- const content = fs.readFileSync(configPath, "utf-8");
234
- const items = [];
235
- // Check for known config options by searching for property names in the config file
236
- const configOptions = [
237
- "basePath",
238
- "trailingSlash",
239
- "redirects",
240
- "rewrites",
241
- "headers",
242
- "i18n",
243
- "env",
244
- "images",
245
- "allowedDevOrigins",
246
- "output",
247
- "transpilePackages",
248
- "webpack",
249
- "reactStrictMode",
250
- "poweredByHeader",
251
- ];
252
- for (const opt of configOptions) {
253
- // Simple heuristic: check if the option name appears as a property in the config
254
- const regex = new RegExp(`\\b${opt}\\b`);
255
- if (regex.test(content)) {
256
- const support = CONFIG_SUPPORT[opt];
257
- if (support) {
258
- items.push({ name: opt, status: support.status, detail: support.detail });
259
- }
260
- else {
261
- items.push({ name: opt, status: "unsupported", detail: "not recognized" });
262
- }
263
- }
264
- }
265
- // Check for experimental options
266
- if (/experimental\s*[:=]\s*\{/.test(content)) {
267
- if (/\bppr\b/.test(content)) {
268
- items.push({ name: "experimental.ppr", ...CONFIG_SUPPORT["experimental.ppr"] });
269
- }
270
- if (/\btypedRoutes\b/.test(content)) {
271
- items.push({
272
- name: "experimental.typedRoutes",
273
- ...CONFIG_SUPPORT["experimental.typedRoutes"],
274
- });
275
- }
276
- if (/\bserverActions\b/.test(content)) {
277
- items.push({
278
- name: "experimental.serverActions",
279
- ...CONFIG_SUPPORT["experimental.serverActions"],
280
- });
281
- }
282
- }
283
- // Check for i18n.domains
284
- if (/domains\s*:/.test(content) && /i18n/.test(content)) {
285
- items.push({ name: "i18n.domains", ...CONFIG_SUPPORT["i18n.domains"] });
286
- }
287
- // Sort: unsupported first
288
- items.sort((a, b) => {
289
- const order = { unsupported: 0, partial: 1, supported: 2 };
290
- return order[a.status] - order[b.status];
291
- });
292
- return items;
255
+ * Analyze next.config.js/mjs/ts for supported and unsupported options.
256
+ */
257
+ function analyzeConfig(root) {
258
+ const configFiles = [
259
+ "next.config.ts",
260
+ "next.config.mjs",
261
+ "next.config.js",
262
+ "next.config.cjs"
263
+ ];
264
+ let configPath = null;
265
+ for (const f of configFiles) {
266
+ const p = path.join(root, f);
267
+ if (fs.existsSync(p)) {
268
+ configPath = p;
269
+ break;
270
+ }
271
+ }
272
+ if (!configPath) return [{
273
+ name: "next.config",
274
+ status: "supported",
275
+ detail: "no config file found (defaults are fine)"
276
+ }];
277
+ const content = fs.readFileSync(configPath, "utf-8");
278
+ const items = [];
279
+ for (const opt of [
280
+ "basePath",
281
+ "trailingSlash",
282
+ "redirects",
283
+ "rewrites",
284
+ "headers",
285
+ "i18n",
286
+ "env",
287
+ "images",
288
+ "allowedDevOrigins",
289
+ "output",
290
+ "transpilePackages",
291
+ "webpack",
292
+ "reactStrictMode",
293
+ "poweredByHeader"
294
+ ]) if (new RegExp(`\\b${opt}\\b`).test(content)) {
295
+ const support = CONFIG_SUPPORT[opt];
296
+ if (support) items.push({
297
+ name: opt,
298
+ status: support.status,
299
+ detail: support.detail
300
+ });
301
+ else items.push({
302
+ name: opt,
303
+ status: "unsupported",
304
+ detail: "not recognized"
305
+ });
306
+ }
307
+ if (/experimental\s*[:=]\s*\{/.test(content)) {
308
+ if (/\bppr\b/.test(content)) items.push({
309
+ name: "experimental.ppr",
310
+ ...CONFIG_SUPPORT["experimental.ppr"]
311
+ });
312
+ if (/\btypedRoutes\b/.test(content)) items.push({
313
+ name: "experimental.typedRoutes",
314
+ ...CONFIG_SUPPORT["experimental.typedRoutes"]
315
+ });
316
+ if (/\bserverActions\b/.test(content)) items.push({
317
+ name: "experimental.serverActions",
318
+ ...CONFIG_SUPPORT["experimental.serverActions"]
319
+ });
320
+ }
321
+ if (/domains\s*:/.test(content) && /i18n/.test(content)) items.push({
322
+ name: "i18n.domains",
323
+ ...CONFIG_SUPPORT["i18n.domains"]
324
+ });
325
+ items.sort((a, b) => {
326
+ const order = {
327
+ unsupported: 0,
328
+ partial: 1,
329
+ supported: 2
330
+ };
331
+ return order[a.status] - order[b.status];
332
+ });
333
+ return items;
293
334
  }
294
335
  /**
295
- * Check package.json dependencies for known libraries.
296
- */
297
- export function checkLibraries(root) {
298
- const pkgPath = path.join(root, "package.json");
299
- if (!fs.existsSync(pkgPath))
300
- return [];
301
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
302
- const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
303
- const items = [];
304
- for (const [lib, support] of Object.entries(LIBRARY_SUPPORT)) {
305
- if (allDeps[lib]) {
306
- items.push({
307
- name: lib,
308
- status: support.status,
309
- detail: support.detail,
310
- });
311
- }
312
- }
313
- // Sort: unsupported first
314
- items.sort((a, b) => {
315
- const order = { unsupported: 0, partial: 1, supported: 2 };
316
- return order[a.status] - order[b.status];
317
- });
318
- return items;
336
+ * Check package.json dependencies for known libraries.
337
+ */
338
+ function checkLibraries(root) {
339
+ const pkgPath = path.join(root, "package.json");
340
+ if (!fs.existsSync(pkgPath)) return [];
341
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
342
+ const allDeps = {
343
+ ...pkg.dependencies,
344
+ ...pkg.devDependencies
345
+ };
346
+ const items = [];
347
+ for (const [lib, support] of Object.entries(LIBRARY_SUPPORT)) if (allDeps[lib]) items.push({
348
+ name: lib,
349
+ status: support.status,
350
+ detail: support.detail
351
+ });
352
+ items.sort((a, b) => {
353
+ const order = {
354
+ unsupported: 0,
355
+ partial: 1,
356
+ supported: 2
357
+ };
358
+ return order[a.status] - order[b.status];
359
+ });
360
+ return items;
319
361
  }
320
362
  /**
321
- * Check file conventions (pages, app directory, middleware, etc.)
322
- */
323
- export function checkConventions(root) {
324
- const items = [];
325
- // Check for pages/ and app/ at root level, then fall back to src/
326
- const pagesDir = fs.existsSync(path.join(root, "pages"))
327
- ? path.join(root, "pages")
328
- : fs.existsSync(path.join(root, "src", "pages"))
329
- ? path.join(root, "src", "pages")
330
- : null;
331
- const appDirPath = fs.existsSync(path.join(root, "app"))
332
- ? path.join(root, "app")
333
- : fs.existsSync(path.join(root, "src", "app"))
334
- ? path.join(root, "src", "app")
335
- : null;
336
- const hasPages = pagesDir !== null;
337
- const hasApp = appDirPath !== null;
338
- const hasProxy = fs.existsSync(path.join(root, "proxy.ts")) || fs.existsSync(path.join(root, "proxy.js"));
339
- const hasMiddleware = fs.existsSync(path.join(root, "middleware.ts")) ||
340
- fs.existsSync(path.join(root, "middleware.js"));
341
- if (pagesDir !== null) {
342
- const isSrc = pagesDir.includes(path.join("src", "pages"));
343
- items.push({
344
- name: isSrc ? "Pages Router (src/pages/)" : "Pages Router (pages/)",
345
- status: "supported",
346
- });
347
- // Count pages
348
- const pageFiles = findSourceFiles(pagesDir);
349
- const pages = pageFiles.filter((f) => !f.includes("/api/") &&
350
- !f.includes("_app") &&
351
- !f.includes("_document") &&
352
- !f.includes("_error"));
353
- const apiRoutes = pageFiles.filter((f) => f.includes("/api/"));
354
- items.push({ name: `${pages.length} page(s)`, status: "supported" });
355
- if (apiRoutes.length) {
356
- items.push({ name: `${apiRoutes.length} API route(s)`, status: "supported" });
357
- }
358
- // Check for _app, _document
359
- if (pageFiles.some((f) => f.includes("_app"))) {
360
- items.push({ name: "Custom _app", status: "supported" });
361
- }
362
- if (pageFiles.some((f) => f.includes("_document"))) {
363
- items.push({ name: "Custom _document", status: "supported" });
364
- }
365
- }
366
- if (appDirPath !== null) {
367
- const isSrc = appDirPath.includes(path.join("src", "app"));
368
- items.push({
369
- name: isSrc ? "App Router (src/app/)" : "App Router (app/)",
370
- status: "supported",
371
- });
372
- const appFiles = findSourceFiles(appDirPath);
373
- const pages = appFiles.filter((f) => f.endsWith("page.tsx") ||
374
- f.endsWith("page.jsx") ||
375
- f.endsWith("page.ts") ||
376
- f.endsWith("page.js"));
377
- const layouts = appFiles.filter((f) => f.endsWith("layout.tsx") ||
378
- f.endsWith("layout.jsx") ||
379
- f.endsWith("layout.ts") ||
380
- f.endsWith("layout.js"));
381
- const routes = appFiles.filter((f) => f.endsWith("route.tsx") || f.endsWith("route.ts") || f.endsWith("route.js"));
382
- const loadings = appFiles.filter((f) => f.endsWith("loading.tsx") || f.endsWith("loading.jsx"));
383
- const errors = appFiles.filter((f) => f.endsWith("error.tsx") || f.endsWith("error.jsx"));
384
- const notFounds = appFiles.filter((f) => f.endsWith("not-found.tsx") || f.endsWith("not-found.jsx"));
385
- items.push({ name: `${pages.length} page(s)`, status: "supported" });
386
- if (layouts.length)
387
- items.push({ name: `${layouts.length} layout(s)`, status: "supported" });
388
- if (routes.length)
389
- items.push({ name: `${routes.length} route handler(s)`, status: "supported" });
390
- if (loadings.length)
391
- items.push({ name: `${loadings.length} loading boundary(ies)`, status: "supported" });
392
- if (errors.length)
393
- items.push({ name: `${errors.length} error boundary(ies)`, status: "supported" });
394
- if (notFounds.length)
395
- items.push({ name: `${notFounds.length} not-found page(s)`, status: "supported" });
396
- }
397
- if (hasProxy) {
398
- items.push({ name: "proxy.ts (Next.js 16)", status: "supported" });
399
- }
400
- else if (hasMiddleware) {
401
- items.push({ name: "middleware.ts (deprecated in Next.js 16)", status: "supported" });
402
- }
403
- if (!hasPages && !hasApp) {
404
- items.push({
405
- name: "No pages/ or app/ directory found",
406
- status: "unsupported",
407
- detail: "vinext requires a pages/ or app/ directory",
408
- });
409
- }
410
- // Check for "type": "module" in package.json
411
- const pkgPath = path.join(root, "package.json");
412
- if (fs.existsSync(pkgPath)) {
413
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
414
- if (pkg.type !== "module") {
415
- items.push({
416
- name: 'Missing "type": "module" in package.json',
417
- status: "unsupported",
418
- detail: "required for Vite — vinext init will add it automatically",
419
- });
420
- }
421
- }
422
- // Scan for ViewTransition import from react
423
- const allSourceFiles = findSourceFiles(root);
424
- const viewTransitionRegex = /import\s+\{[^}]*\bViewTransition\b[^}]*\}\s+from\s+['"]react['"]/;
425
- const viewTransitionFiles = [];
426
- for (const file of allSourceFiles) {
427
- const content = fs.readFileSync(file, "utf-8");
428
- if (viewTransitionRegex.test(content)) {
429
- viewTransitionFiles.push(path.relative(root, file));
430
- }
431
- }
432
- if (viewTransitionFiles.length > 0) {
433
- items.push({
434
- name: "ViewTransition (React canary API)",
435
- status: "partial",
436
- detail: "vinext auto-shims with a passthrough fallback, view transitions won't animate",
437
- files: viewTransitionFiles,
438
- });
439
- }
440
- // Check PostCSS config for string-form plugins
441
- const postcssConfigs = ["postcss.config.mjs", "postcss.config.js", "postcss.config.cjs"];
442
- for (const configFile of postcssConfigs) {
443
- const configPath = path.join(root, configFile);
444
- if (fs.existsSync(configPath)) {
445
- const content = fs.readFileSync(configPath, "utf-8");
446
- // Detect string-form plugins: plugins: ["..."] or plugins: ['...']
447
- const stringPluginRegex = /plugins\s*:\s*\[[\s\S]*?(['"][^'"]+['"])[\s\S]*?\]/;
448
- const match = stringPluginRegex.exec(content);
449
- if (match) {
450
- // Check it's not require() or import() form — just bare string literals in the array
451
- const pluginsBlock = match[0];
452
- // If plugins array contains string literals not wrapped in require()
453
- if (/plugins\s*:\s*\[[\s\n]*['"]/.test(pluginsBlock)) {
454
- items.push({
455
- name: `PostCSS string-form plugins (${configFile})`,
456
- status: "partial",
457
- detail: "string-form PostCSS plugins need resolution — vinext handles this automatically",
458
- });
459
- }
460
- }
461
- break; // Only check the first config file found
462
- }
463
- }
464
- return items;
363
+ * Check file conventions (pages, app directory, middleware, etc.)
364
+ */
365
+ function checkConventions(root) {
366
+ const items = [];
367
+ const pagesDir = fs.existsSync(path.join(root, "pages")) ? path.join(root, "pages") : fs.existsSync(path.join(root, "src", "pages")) ? path.join(root, "src", "pages") : null;
368
+ const appDirPath = fs.existsSync(path.join(root, "app")) ? path.join(root, "app") : fs.existsSync(path.join(root, "src", "app")) ? path.join(root, "src", "app") : null;
369
+ const hasPages = pagesDir !== null;
370
+ const hasApp = appDirPath !== null;
371
+ const hasProxy = fs.existsSync(path.join(root, "proxy.ts")) || fs.existsSync(path.join(root, "proxy.js"));
372
+ const hasMiddleware = fs.existsSync(path.join(root, "middleware.ts")) || fs.existsSync(path.join(root, "middleware.js"));
373
+ if (pagesDir !== null) {
374
+ const isSrc = pagesDir.includes(path.join("src", "pages"));
375
+ items.push({
376
+ name: isSrc ? "Pages Router (src/pages/)" : "Pages Router (pages/)",
377
+ status: "supported"
378
+ });
379
+ const pageFiles = findSourceFiles(pagesDir);
380
+ const pages = pageFiles.filter((f) => !f.includes("/api/") && !f.includes("_app") && !f.includes("_document") && !f.includes("_error"));
381
+ const apiRoutes = pageFiles.filter((f) => f.includes("/api/"));
382
+ items.push({
383
+ name: `${pages.length} page(s)`,
384
+ status: "supported"
385
+ });
386
+ if (apiRoutes.length) items.push({
387
+ name: `${apiRoutes.length} API route(s)`,
388
+ status: "supported"
389
+ });
390
+ if (pageFiles.some((f) => f.includes("_app"))) items.push({
391
+ name: "Custom _app",
392
+ status: "supported"
393
+ });
394
+ if (pageFiles.some((f) => f.includes("_document"))) items.push({
395
+ name: "Custom _document",
396
+ status: "supported"
397
+ });
398
+ }
399
+ if (appDirPath !== null) {
400
+ const isSrc = appDirPath.includes(path.join("src", "app"));
401
+ items.push({
402
+ name: isSrc ? "App Router (src/app/)" : "App Router (app/)",
403
+ status: "supported"
404
+ });
405
+ const appFiles = findSourceFiles(appDirPath);
406
+ const pages = appFiles.filter((f) => f.endsWith("page.tsx") || f.endsWith("page.jsx") || f.endsWith("page.ts") || f.endsWith("page.js"));
407
+ const layouts = appFiles.filter((f) => f.endsWith("layout.tsx") || f.endsWith("layout.jsx") || f.endsWith("layout.ts") || f.endsWith("layout.js"));
408
+ const routes = appFiles.filter((f) => f.endsWith("route.tsx") || f.endsWith("route.ts") || f.endsWith("route.js"));
409
+ const loadings = appFiles.filter((f) => f.endsWith("loading.tsx") || f.endsWith("loading.jsx"));
410
+ const errors = appFiles.filter((f) => f.endsWith("error.tsx") || f.endsWith("error.jsx"));
411
+ const notFounds = appFiles.filter((f) => f.endsWith("not-found.tsx") || f.endsWith("not-found.jsx"));
412
+ items.push({
413
+ name: `${pages.length} page(s)`,
414
+ status: "supported"
415
+ });
416
+ if (layouts.length) items.push({
417
+ name: `${layouts.length} layout(s)`,
418
+ status: "supported"
419
+ });
420
+ if (routes.length) items.push({
421
+ name: `${routes.length} route handler(s)`,
422
+ status: "supported"
423
+ });
424
+ if (loadings.length) items.push({
425
+ name: `${loadings.length} loading boundary(ies)`,
426
+ status: "supported"
427
+ });
428
+ if (errors.length) items.push({
429
+ name: `${errors.length} error boundary(ies)`,
430
+ status: "supported"
431
+ });
432
+ if (notFounds.length) items.push({
433
+ name: `${notFounds.length} not-found page(s)`,
434
+ status: "supported"
435
+ });
436
+ }
437
+ if (hasProxy) items.push({
438
+ name: "proxy.ts (Next.js 16)",
439
+ status: "supported"
440
+ });
441
+ else if (hasMiddleware) items.push({
442
+ name: "middleware.ts (deprecated in Next.js 16)",
443
+ status: "supported"
444
+ });
445
+ if (!hasPages && !hasApp) items.push({
446
+ name: "No pages/ or app/ directory found",
447
+ status: "unsupported",
448
+ detail: "vinext requires a pages/ or app/ directory"
449
+ });
450
+ const pkgPath = path.join(root, "package.json");
451
+ if (fs.existsSync(pkgPath)) {
452
+ if (JSON.parse(fs.readFileSync(pkgPath, "utf-8")).type !== "module") items.push({
453
+ name: "Missing \"type\": \"module\" in package.json",
454
+ status: "unsupported",
455
+ detail: "required for Vite — vinext init will add it automatically"
456
+ });
457
+ }
458
+ const allSourceFiles = findSourceFiles(root);
459
+ const viewTransitionRegex = /import\s+\{[^}]*\bViewTransition\b[^}]*\}\s+from\s+['"]react['"]/;
460
+ const viewTransitionFiles = [];
461
+ for (const file of allSourceFiles) {
462
+ const content = fs.readFileSync(file, "utf-8");
463
+ if (viewTransitionRegex.test(content)) viewTransitionFiles.push(path.relative(root, file));
464
+ }
465
+ if (viewTransitionFiles.length > 0) items.push({
466
+ name: "ViewTransition (React canary API)",
467
+ status: "partial",
468
+ detail: "vinext auto-shims with a passthrough fallback, view transitions won't animate",
469
+ files: viewTransitionFiles
470
+ });
471
+ for (const configFile of [
472
+ "postcss.config.mjs",
473
+ "postcss.config.js",
474
+ "postcss.config.cjs"
475
+ ]) {
476
+ const configPath = path.join(root, configFile);
477
+ if (fs.existsSync(configPath)) {
478
+ const content = fs.readFileSync(configPath, "utf-8");
479
+ const match = /plugins\s*:\s*\[[\s\S]*?(['"][^'"]+['"])[\s\S]*?\]/.exec(content);
480
+ if (match) {
481
+ const pluginsBlock = match[0];
482
+ if (/plugins\s*:\s*\[[\s\n]*['"]/.test(pluginsBlock)) items.push({
483
+ name: `PostCSS string-form plugins (${configFile})`,
484
+ status: "partial",
485
+ detail: "string-form PostCSS plugins need resolution — vinext handles this automatically"
486
+ });
487
+ }
488
+ break;
489
+ }
490
+ }
491
+ return items;
465
492
  }
466
493
  /**
467
- * Run the full compatibility check.
468
- */
469
- export function runCheck(root) {
470
- const imports = scanImports(root);
471
- const config = analyzeConfig(root);
472
- const libraries = checkLibraries(root);
473
- const conventions = checkConventions(root);
474
- const allItems = [...imports, ...config, ...libraries, ...conventions];
475
- const supported = allItems.filter((i) => i.status === "supported").length;
476
- const partial = allItems.filter((i) => i.status === "partial").length;
477
- const unsupported = allItems.filter((i) => i.status === "unsupported").length;
478
- const total = allItems.length;
479
- // Score: supported = 1, partial = 0.5, unsupported = 0
480
- const score = total > 0 ? Math.round(((supported + partial * 0.5) / total) * 100) : 100;
481
- return {
482
- imports,
483
- config,
484
- libraries,
485
- conventions,
486
- summary: { supported, partial, unsupported, total, score },
487
- };
494
+ * Run the full compatibility check.
495
+ */
496
+ function runCheck(root) {
497
+ const imports = scanImports(root);
498
+ const config = analyzeConfig(root);
499
+ const libraries = checkLibraries(root);
500
+ const conventions = checkConventions(root);
501
+ const allItems = [
502
+ ...imports,
503
+ ...config,
504
+ ...libraries,
505
+ ...conventions
506
+ ];
507
+ const supported = allItems.filter((i) => i.status === "supported").length;
508
+ const partial = allItems.filter((i) => i.status === "partial").length;
509
+ const unsupported = allItems.filter((i) => i.status === "unsupported").length;
510
+ const total = allItems.length;
511
+ return {
512
+ imports,
513
+ config,
514
+ libraries,
515
+ conventions,
516
+ summary: {
517
+ supported,
518
+ partial,
519
+ unsupported,
520
+ total,
521
+ score: total > 0 ? Math.round((supported + partial * .5) / total * 100) : 100
522
+ }
523
+ };
488
524
  }
489
525
  /**
490
- * Format the check result as a colored terminal report.
491
- */
492
- export function formatReport(result, opts) {
493
- const lines = [];
494
- const statusIcon = (s) => s === "supported"
495
- ? "\x1b[32m✓\x1b[0m"
496
- : s === "partial"
497
- ? "\x1b[33m~\x1b[0m"
498
- : "\x1b[31m✗\x1b[0m";
499
- lines.push("");
500
- lines.push(" \x1b[1mvinext compatibility report\x1b[0m");
501
- lines.push(" " + "=".repeat(40));
502
- lines.push("");
503
- // Imports
504
- if (result.imports.length > 0) {
505
- const importSupported = result.imports.filter((i) => i.status === "supported").length;
506
- lines.push(` \x1b[1mImports\x1b[0m: ${importSupported}/${result.imports.length} fully supported`);
507
- for (const item of result.imports) {
508
- const suffix = item.detail ? ` \x1b[90m— ${item.detail}\x1b[0m` : "";
509
- const fileCount = item.files
510
- ? ` \x1b[90m(${item.files.length} file${item.files.length === 1 ? "" : "s"})\x1b[0m`
511
- : "";
512
- lines.push(` ${statusIcon(item.status)} ${item.name}${fileCount}${suffix}`);
513
- }
514
- lines.push("");
515
- }
516
- // Config
517
- if (result.config.length > 0) {
518
- const configSupported = result.config.filter((i) => i.status === "supported").length;
519
- lines.push(` \x1b[1mConfig\x1b[0m: ${configSupported}/${result.config.length} options supported`);
520
- for (const item of result.config) {
521
- const suffix = item.detail ? ` \x1b[90m— ${item.detail}\x1b[0m` : "";
522
- lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);
523
- }
524
- lines.push("");
525
- }
526
- // Libraries
527
- if (result.libraries.length > 0) {
528
- const libSupported = result.libraries.filter((i) => i.status === "supported").length;
529
- lines.push(` \x1b[1mLibraries\x1b[0m: ${libSupported}/${result.libraries.length} compatible`);
530
- for (const item of result.libraries) {
531
- const suffix = item.detail ? ` \x1b[90m— ${item.detail}\x1b[0m` : "";
532
- lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);
533
- }
534
- lines.push("");
535
- }
536
- // Conventions
537
- if (result.conventions.length > 0) {
538
- lines.push(` \x1b[1mProject structure\x1b[0m:`);
539
- for (const item of result.conventions) {
540
- const suffix = item.detail ? ` \x1b[90m— ${item.detail}\x1b[0m` : "";
541
- lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);
542
- }
543
- lines.push("");
544
- }
545
- // Summary
546
- const { score, supported, partial, unsupported } = result.summary;
547
- const scoreColor = score >= 90 ? "\x1b[32m" : score >= 70 ? "\x1b[33m" : "\x1b[31m";
548
- lines.push(" " + "-".repeat(40));
549
- lines.push(` \x1b[1mOverall\x1b[0m: ${scoreColor}${score}% compatible\x1b[0m (${supported} supported, ${partial} partial, ${unsupported} issues)`);
550
- if (unsupported > 0) {
551
- lines.push("");
552
- lines.push(" \x1b[1mIssues to address:\x1b[0m");
553
- const allItems = [
554
- ...result.imports,
555
- ...result.config,
556
- ...result.libraries,
557
- ...result.conventions,
558
- ];
559
- for (const item of allItems) {
560
- if (item.status === "unsupported") {
561
- lines.push(` \x1b[31m✗\x1b[0m ${item.name}${item.detail ? ` — ${item.detail}` : ""}`);
562
- }
563
- }
564
- }
565
- if (result.summary.partial > 0) {
566
- lines.push("");
567
- lines.push(" \x1b[1mPartial support (may need attention):\x1b[0m");
568
- const allItems = [
569
- ...result.imports,
570
- ...result.config,
571
- ...result.libraries,
572
- ...result.conventions,
573
- ];
574
- for (const item of allItems) {
575
- if (item.status === "partial") {
576
- lines.push(` \x1b[33m~\x1b[0m ${item.name}${item.detail ? ` — ${item.detail}` : ""}`);
577
- }
578
- }
579
- }
580
- // Actionable next steps (skip when called from init — it prints its own summary)
581
- if (!opts?.calledFromInit) {
582
- lines.push("");
583
- lines.push(" \x1b[1mRecommended next steps:\x1b[0m");
584
- lines.push(` Run \x1b[36mvinext init\x1b[0m to set up your project automatically`);
585
- lines.push("");
586
- lines.push(" Or manually:");
587
- lines.push(` 1. Add \x1b[36m"type": "module"\x1b[0m to package.json`);
588
- lines.push(` 2. Install: \x1b[36m${detectPackageManager(process.cwd())} vinext vite @vitejs/plugin-rsc\x1b[0m`);
589
- lines.push(` 3. Create vite.config.ts (see docs)`);
590
- lines.push(` 4. Run: \x1b[36mnpx vite dev\x1b[0m`);
591
- }
592
- lines.push("");
593
- return lines.join("\n");
526
+ * Format the check result as a colored terminal report.
527
+ */
528
+ function formatReport(result, opts) {
529
+ const lines = [];
530
+ const hasAppRouter = result.conventions.some((item) => item.name === "App Router (app/)" || item.name === "App Router (src/app/)");
531
+ const statusIcon = (s) => s === "supported" ? "\x1B[32m✓\x1B[0m" : s === "partial" ? "\x1B[33m~\x1B[0m" : "\x1B[31m✗\x1B[0m";
532
+ lines.push("");
533
+ lines.push(" \x1B[1mvinext compatibility report\x1B[0m");
534
+ lines.push(" " + "=".repeat(40));
535
+ lines.push("");
536
+ if (result.imports.length > 0) {
537
+ const importSupported = result.imports.filter((i) => i.status === "supported").length;
538
+ lines.push(` \x1b[1mImports\x1b[0m: ${importSupported}/${result.imports.length} fully supported`);
539
+ for (const item of result.imports) {
540
+ const suffix = item.detail ? ` \x1b[90m— ${item.detail}\x1b[0m` : "";
541
+ const fileCount = item.files ? ` \x1b[90m(${item.files.length} file${item.files.length === 1 ? "" : "s"})\x1b[0m` : "";
542
+ lines.push(` ${statusIcon(item.status)} ${item.name}${fileCount}${suffix}`);
543
+ }
544
+ lines.push("");
545
+ }
546
+ if (result.config.length > 0) {
547
+ const configSupported = result.config.filter((i) => i.status === "supported").length;
548
+ lines.push(` \x1b[1mConfig\x1b[0m: ${configSupported}/${result.config.length} options supported`);
549
+ for (const item of result.config) {
550
+ const suffix = item.detail ? ` \x1b[90m— ${item.detail}\x1b[0m` : "";
551
+ lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);
552
+ }
553
+ lines.push("");
554
+ }
555
+ if (result.libraries.length > 0) {
556
+ const libSupported = result.libraries.filter((i) => i.status === "supported").length;
557
+ lines.push(` \x1b[1mLibraries\x1b[0m: ${libSupported}/${result.libraries.length} compatible`);
558
+ for (const item of result.libraries) {
559
+ const suffix = item.detail ? ` \x1b[90m— ${item.detail}\x1b[0m` : "";
560
+ lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);
561
+ }
562
+ lines.push("");
563
+ }
564
+ if (result.conventions.length > 0) {
565
+ lines.push(` \x1b[1mProject structure\x1b[0m:`);
566
+ for (const item of result.conventions) {
567
+ const suffix = item.detail ? ` \x1b[90m— ${item.detail}\x1b[0m` : "";
568
+ lines.push(` ${statusIcon(item.status)} ${item.name}${suffix}`);
569
+ }
570
+ lines.push("");
571
+ }
572
+ const { score, supported, partial, unsupported } = result.summary;
573
+ const scoreColor = score >= 90 ? "\x1B[32m" : score >= 70 ? "\x1B[33m" : "\x1B[31m";
574
+ lines.push(" " + "-".repeat(40));
575
+ lines.push(` \x1b[1mOverall\x1b[0m: ${scoreColor}${score}% compatible\x1b[0m (${supported} supported, ${partial} partial, ${unsupported} issues)`);
576
+ if (unsupported > 0) {
577
+ lines.push("");
578
+ lines.push(" \x1B[1mIssues to address:\x1B[0m");
579
+ const allItems = [
580
+ ...result.imports,
581
+ ...result.config,
582
+ ...result.libraries,
583
+ ...result.conventions
584
+ ];
585
+ for (const item of allItems) if (item.status === "unsupported") lines.push(` \x1b[31m✗\x1b[0m ${item.name}${item.detail ? ` ${item.detail}` : ""}`);
586
+ }
587
+ if (result.summary.partial > 0) {
588
+ lines.push("");
589
+ lines.push(" \x1B[1mPartial support (may need attention):\x1B[0m");
590
+ const allItems = [
591
+ ...result.imports,
592
+ ...result.config,
593
+ ...result.libraries,
594
+ ...result.conventions
595
+ ];
596
+ for (const item of allItems) if (item.status === "partial") lines.push(` \x1b[33m~\x1b[0m ${item.name}${item.detail ? ` — ${item.detail}` : ""}`);
597
+ }
598
+ if (!opts?.calledFromInit) {
599
+ lines.push("");
600
+ lines.push(" \x1B[1mRecommended next steps:\x1B[0m");
601
+ lines.push(` Run \x1b[36mvinext init\x1b[0m to set up your project automatically`);
602
+ lines.push("");
603
+ lines.push(" Or manually:");
604
+ lines.push(` 1. Add \x1b[36m"type": "module"\x1b[0m to package.json`);
605
+ lines.push(` 2. Install: \x1b[36m${detectPackageManager(process.cwd())} vinext vite @vitejs/plugin-react${hasAppRouter ? " @vitejs/plugin-rsc react-server-dom-webpack" : ""}\x1b[0m`);
606
+ lines.push(` 3. Create vite.config.ts (see docs)`);
607
+ lines.push(` 4. Run: \x1b[36mnpx vite dev\x1b[0m`);
608
+ }
609
+ lines.push("");
610
+ return lines.join("\n");
594
611
  }
612
+ //#endregion
613
+ export { analyzeConfig, checkConventions, checkLibraries, formatReport, runCheck, scanImports };
614
+
595
615
  //# sourceMappingURL=check.js.map