@tanstack/cta-engine 0.14.3 → 0.15.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 (343) hide show
  1. package/dist/add-ons.js +5 -91
  2. package/dist/add-to-app.js +171 -0
  3. package/dist/config-file.js +34 -11
  4. package/dist/constants.js +0 -2
  5. package/dist/create-app.js +142 -451
  6. package/dist/custom-add-ons/add-on.js +175 -0
  7. package/dist/custom-add-ons/shared.js +116 -0
  8. package/dist/custom-add-ons/starter.js +84 -0
  9. package/dist/environment.js +67 -44
  10. package/dist/file-helpers.js +165 -0
  11. package/dist/frameworks.js +92 -0
  12. package/dist/index.js +18 -1
  13. package/dist/integrations/git.js +4 -0
  14. package/dist/integrations/shadcn.js +33 -0
  15. package/dist/options.js +9 -333
  16. package/dist/package-json.js +48 -0
  17. package/dist/package-manager.js +51 -6
  18. package/dist/registry.js +56 -0
  19. package/dist/special-steps/index.js +24 -0
  20. package/dist/special-steps/rimraf-node-modules.js +16 -0
  21. package/dist/template-file.js +112 -0
  22. package/dist/types/add-ons.d.ts +3 -8
  23. package/dist/types/add-to-app.d.ts +17 -0
  24. package/dist/types/config-file.d.ts +7 -4
  25. package/dist/types/constants.d.ts +0 -3
  26. package/dist/types/create-app.d.ts +1 -7
  27. package/dist/types/custom-add-ons/add-on.d.ts +69 -0
  28. package/dist/types/custom-add-ons/shared.d.ts +15 -0
  29. package/dist/types/custom-add-ons/starter.d.ts +7 -0
  30. package/dist/types/environment.d.ts +2 -1
  31. package/dist/types/file-helpers.d.ts +15 -0
  32. package/dist/types/frameworks.d.ts +7 -0
  33. package/dist/types/index.d.ts +21 -1
  34. package/dist/types/integrations/git.d.ts +2 -0
  35. package/dist/types/integrations/shadcn.d.ts +2 -0
  36. package/dist/types/options.d.ts +2 -6
  37. package/dist/types/package-json.d.ts +7 -0
  38. package/dist/types/package-manager.d.ts +18 -1
  39. package/dist/types/registry.d.ts +25 -0
  40. package/dist/types/special-steps/index.d.ts +2 -0
  41. package/dist/types/special-steps/rimraf-node-modules.d.ts +2 -0
  42. package/dist/types/template-file.d.ts +2 -0
  43. package/dist/types/types.d.ts +788 -85
  44. package/dist/types/utils.d.ts +5 -0
  45. package/dist/types.js +65 -1
  46. package/dist/utils.js +9 -0
  47. package/package.json +9 -12
  48. package/src/add-ons.ts +7 -123
  49. package/src/add-to-app.ts +276 -0
  50. package/src/config-file.ts +51 -20
  51. package/src/constants.ts +0 -5
  52. package/src/create-app.ts +180 -730
  53. package/src/custom-add-ons/add-on.ts +261 -0
  54. package/src/custom-add-ons/shared.ts +160 -0
  55. package/src/custom-add-ons/starter.ts +126 -0
  56. package/src/environment.ts +80 -45
  57. package/src/file-helpers.ts +235 -0
  58. package/src/frameworks.ts +134 -0
  59. package/src/index.ts +85 -1
  60. package/src/integrations/git.ts +7 -0
  61. package/src/integrations/shadcn.ts +54 -0
  62. package/src/options.ts +8 -409
  63. package/src/package-json.ts +69 -0
  64. package/src/package-manager.ts +80 -9
  65. package/src/registry.ts +92 -0
  66. package/src/special-steps/index.ts +36 -0
  67. package/src/special-steps/rimraf-node-modules.ts +25 -0
  68. package/src/template-file.ts +150 -0
  69. package/src/types.ts +175 -87
  70. package/src/utils.ts +17 -0
  71. package/tests/add-ons.test.ts +67 -0
  72. package/tests/add-to-app.test.ts +358 -0
  73. package/tests/config-file.test.ts +105 -0
  74. package/tests/create-app.test.ts +120 -0
  75. package/tests/custom-add-ons/add-on.test.ts +12 -0
  76. package/tests/custom-add-ons/shared.test.ts +253 -0
  77. package/tests/custom-add-ons/starter.test.ts +58 -0
  78. package/tests/environment.test.ts +115 -0
  79. package/tests/file-helper.test.ts +90 -0
  80. package/tests/frameworks.test.ts +95 -0
  81. package/tests/index.test.ts +9 -0
  82. package/tests/integrations/git.test.ts +20 -0
  83. package/tests/integrations/shadcn.test.ts +91 -0
  84. package/tests/options.test.ts +42 -0
  85. package/tests/package-json.test.ts +63 -0
  86. package/tests/package-manager.test.ts +154 -0
  87. package/tests/setupVitest.ts +6 -0
  88. package/tests/template-file.test.ts +178 -0
  89. package/tests/utils.test.ts +23 -0
  90. package/vitest.config.ts +21 -0
  91. package/dist/add.js +0 -125
  92. package/dist/cli.js +0 -132
  93. package/dist/custom-add-on.js +0 -254
  94. package/dist/file-helper.js +0 -18
  95. package/dist/mcp.js +0 -229
  96. package/dist/templates.js +0 -6
  97. package/dist/toolchain.js +0 -6
  98. package/dist/types/add.d.ts +0 -3
  99. package/dist/types/cli.d.ts +0 -7
  100. package/dist/types/custom-add-on.d.ts +0 -3
  101. package/dist/types/file-helper.d.ts +0 -2
  102. package/dist/types/mcp.d.ts +0 -7
  103. package/dist/types/templates.d.ts +0 -1
  104. package/dist/types/toolchain.d.ts +0 -3
  105. package/src/add.ts +0 -186
  106. package/src/cli.ts +0 -210
  107. package/src/custom-add-on.ts +0 -325
  108. package/src/file-helper.ts +0 -20
  109. package/src/mcp.ts +0 -302
  110. package/src/templates.ts +0 -7
  111. package/src/toolchain.ts +0 -7
  112. package/templates/react/add-on/clerk/README.md +0 -3
  113. package/templates/react/add-on/clerk/assets/_dot_env.local.append +0 -2
  114. package/templates/react/add-on/clerk/assets/src/integrations/clerk/header-user.tsx +0 -19
  115. package/templates/react/add-on/clerk/assets/src/integrations/clerk/provider.tsx +0 -18
  116. package/templates/react/add-on/clerk/assets/src/routes/demo.clerk.tsx +0 -20
  117. package/templates/react/add-on/clerk/info.json +0 -13
  118. package/templates/react/add-on/clerk/package.json +0 -5
  119. package/templates/react/add-on/convex/README.md +0 -4
  120. package/templates/react/add-on/convex/assets/_dot_cursorrules.append +0 -93
  121. package/templates/react/add-on/convex/assets/_dot_env.local.append +0 -3
  122. package/templates/react/add-on/convex/assets/convex/products.ts +0 -8
  123. package/templates/react/add-on/convex/assets/convex/schema.ts +0 -10
  124. package/templates/react/add-on/convex/assets/src/integrations/convex/provider.tsx +0 -20
  125. package/templates/react/add-on/convex/assets/src/routes/demo.convex.tsx +0 -33
  126. package/templates/react/add-on/convex/info.json +0 -13
  127. package/templates/react/add-on/convex/package.json +0 -6
  128. package/templates/react/add-on/form/assets/src/components/demo.FormComponents.tsx.ejs +0 -300
  129. package/templates/react/add-on/form/assets/src/hooks/demo.form-context.ts +0 -4
  130. package/templates/react/add-on/form/assets/src/hooks/demo.form.ts +0 -22
  131. package/templates/react/add-on/form/assets/src/routes/demo.form.address.tsx.ejs +0 -213
  132. package/templates/react/add-on/form/assets/src/routes/demo.form.simple.tsx.ejs +0 -77
  133. package/templates/react/add-on/form/info.json +0 -26
  134. package/templates/react/add-on/form/package.json +0 -6
  135. package/templates/react/add-on/module-federation/assets/module-federation.config.js.ejs +0 -31
  136. package/templates/react/add-on/module-federation/assets/src/demo-mf-component.tsx +0 -3
  137. package/templates/react/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +0 -11
  138. package/templates/react/add-on/module-federation/info.json +0 -7
  139. package/templates/react/add-on/module-federation/package.json +0 -5
  140. package/templates/react/add-on/netlify/README.md +0 -11
  141. package/templates/react/add-on/netlify/info.json +0 -7
  142. package/templates/react/add-on/sentry/assets/_dot_cursorrules.append +0 -22
  143. package/templates/react/add-on/sentry/assets/_dot_env.local.append +0 -11
  144. package/templates/react/add-on/sentry/assets/src/app/global-middleware.ts +0 -11
  145. package/templates/react/add-on/sentry/assets/src/routes/demo.sentry.testing.tsx +0 -489
  146. package/templates/react/add-on/sentry/info.json +0 -14
  147. package/templates/react/add-on/sentry/package.json +0 -5
  148. package/templates/react/add-on/shadcn/README.md +0 -7
  149. package/templates/react/add-on/shadcn/assets/_dot_cursorrules.append +0 -7
  150. package/templates/react/add-on/shadcn/assets/components.json +0 -21
  151. package/templates/react/add-on/shadcn/assets/src/lib/utils.ts +0 -6
  152. package/templates/react/add-on/shadcn/assets/src/styles.css +0 -138
  153. package/templates/react/add-on/shadcn/info.json +0 -7
  154. package/templates/react/add-on/shadcn/package.json +0 -9
  155. package/templates/react/add-on/start/assets/_dot_gitignore.append +0 -2
  156. package/templates/react/add-on/start/assets/app.config.ts.ejs +0 -32
  157. package/templates/react/add-on/start/assets/src/api.ts +0 -6
  158. package/templates/react/add-on/start/assets/src/client.tsx.ejs +0 -33
  159. package/templates/react/add-on/start/assets/src/router.tsx.ejs +0 -48
  160. package/templates/react/add-on/start/assets/src/routes/api.demo-names.ts +0 -11
  161. package/templates/react/add-on/start/assets/src/routes/demo.start.api-request.tsx.ejs +0 -33
  162. package/templates/react/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +0 -50
  163. package/templates/react/add-on/start/assets/src/ssr.tsx.ejs +0 -30
  164. package/templates/react/add-on/start/info.json +0 -18
  165. package/templates/react/add-on/start/package.json +0 -13
  166. package/templates/react/add-on/store/assets/src/lib/demo-store.ts +0 -13
  167. package/templates/react/add-on/store/assets/src/routes/demo.store.tsx.ejs +0 -75
  168. package/templates/react/add-on/store/info.json +0 -13
  169. package/templates/react/add-on/store/package.json +0 -6
  170. package/templates/react/add-on/t3env/README.md +0 -16
  171. package/templates/react/add-on/t3env/assets/src/env.ts +0 -39
  172. package/templates/react/add-on/t3env/info.json +0 -10
  173. package/templates/react/add-on/t3env/package.json +0 -6
  174. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/init.ts +0 -9
  175. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/react.ts +0 -4
  176. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/router.ts +0 -18
  177. package/templates/react/add-on/tRPC/assets/src/routes/api.trpc.$.tsx +0 -16
  178. package/templates/react/add-on/tRPC/info.json +0 -9
  179. package/templates/react/add-on/tRPC/package.json +0 -9
  180. package/templates/react/add-on/table/assets/src/data/demo-table-data.ts +0 -50
  181. package/templates/react/add-on/table/assets/src/routes/demo.table.tsx.ejs +0 -373
  182. package/templates/react/add-on/table/info.json +0 -13
  183. package/templates/react/add-on/table/package.json +0 -7
  184. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/layout.tsx +0 -5
  185. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/root-provider.tsx.ejs +0 -70
  186. package/templates/react/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx.ejs +0 -53
  187. package/templates/react/add-on/tanstack-query/info.json +0 -13
  188. package/templates/react/add-on/tanstack-query/package.json +0 -6
  189. package/templates/react/base/README.md.ejs +0 -558
  190. package/templates/react/base/_dot_gitignore +0 -5
  191. package/templates/react/base/_dot_vscode/settings.biome.json +0 -38
  192. package/templates/react/base/_dot_vscode/settings.json +0 -11
  193. package/templates/react/base/index.html.ejs +0 -20
  194. package/templates/react/base/package.biome.json +0 -10
  195. package/templates/react/base/package.eslintprettier.json +0 -11
  196. package/templates/react/base/package.json +0 -30
  197. package/templates/react/base/package.ts.json +0 -7
  198. package/templates/react/base/package.tw.json +0 -6
  199. package/templates/react/base/public/favicon.ico +0 -0
  200. package/templates/react/base/public/logo192.png +0 -0
  201. package/templates/react/base/public/logo512.png +0 -0
  202. package/templates/react/base/public/manifest.json +0 -25
  203. package/templates/react/base/public/robots.txt +0 -3
  204. package/templates/react/base/src/App.css +0 -38
  205. package/templates/react/base/src/App.test.tsx.ejs +0 -10
  206. package/templates/react/base/src/App.tsx.ejs +0 -74
  207. package/templates/react/base/src/components/Header.tsx.ejs +0 -27
  208. package/templates/react/base/src/logo.svg +0 -44
  209. package/templates/react/base/src/reportWebVitals.ts.ejs +0 -28
  210. package/templates/react/base/src/styles.css.ejs +0 -15
  211. package/templates/react/base/toolchain/.prettierignore +0 -3
  212. package/templates/react/base/toolchain/biome.json +0 -31
  213. package/templates/react/base/toolchain/eslint.config.js +0 -5
  214. package/templates/react/base/toolchain/prettier.config.js +0 -10
  215. package/templates/react/base/tsconfig.json.ejs +0 -29
  216. package/templates/react/base/vite.config.js.ejs +0 -23
  217. package/templates/react/code-router/src/main.tsx.ejs +0 -92
  218. package/templates/react/example/tanchat/README.md +0 -37
  219. package/templates/react/example/tanchat/assets/_dot_env.local.append +0 -2
  220. package/templates/react/example/tanchat/assets/public/example-guitar-flowers.jpg +0 -0
  221. package/templates/react/example/tanchat/assets/public/example-guitar-motherboard.jpg +0 -0
  222. package/templates/react/example/tanchat/assets/public/example-guitar-racing.jpg +0 -0
  223. package/templates/react/example/tanchat/assets/public/example-guitar-steamer-trunk.jpg +0 -0
  224. package/templates/react/example/tanchat/assets/public/example-guitar-superhero.jpg +0 -0
  225. package/templates/react/example/tanchat/assets/public/example-guitar-traveling.jpg +0 -0
  226. package/templates/react/example/tanchat/assets/public/example-guitar-video-games.jpg +0 -0
  227. package/templates/react/example/tanchat/assets/src/components/example-AIAssistant.tsx +0 -173
  228. package/templates/react/example/tanchat/assets/src/components/example-GuitarRecommendation.tsx +0 -47
  229. package/templates/react/example/tanchat/assets/src/data/example-guitars.ts +0 -83
  230. package/templates/react/example/tanchat/assets/src/demo.index.css +0 -220
  231. package/templates/react/example/tanchat/assets/src/integrations/tanchat/header-user.tsx +0 -5
  232. package/templates/react/example/tanchat/assets/src/routes/api.messages.ts +0 -24
  233. package/templates/react/example/tanchat/assets/src/routes/api.sse.ts +0 -23
  234. package/templates/react/example/tanchat/assets/src/routes/example.chat.tsx +0 -159
  235. package/templates/react/example/tanchat/assets/src/routes/example.guitars/$guitarId.tsx +0 -50
  236. package/templates/react/example/tanchat/assets/src/routes/example.guitars/index.tsx +0 -54
  237. package/templates/react/example/tanchat/assets/src/store/example-assistant.ts +0 -3
  238. package/templates/react/example/tanchat/assets/src/utils/demo.ai.ts +0 -62
  239. package/templates/react/example/tanchat/assets/src/utils/demo.sse.ts +0 -31
  240. package/templates/react/example/tanchat/assets/src/utils/demo.tools.ts +0 -47
  241. package/templates/react/example/tanchat/info.json +0 -19
  242. package/templates/react/example/tanchat/package.json +0 -16
  243. package/templates/react/file-router/package.fr.json +0 -5
  244. package/templates/react/file-router/src/main.tsx.ejs +0 -55
  245. package/templates/react/file-router/src/routes/__root.tsx.ejs +0 -82
  246. package/templates/solid/add-on/form/assets/src/routes/demo.form.tsx.ejs +0 -352
  247. package/templates/solid/add-on/form/info.json +0 -13
  248. package/templates/solid/add-on/form/package.json +0 -5
  249. package/templates/solid/add-on/module-federation/assets/module-federation.config.js.ejs +0 -27
  250. package/templates/solid/add-on/module-federation/assets/src/demo-mf-component.tsx +0 -3
  251. package/templates/solid/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +0 -9
  252. package/templates/solid/add-on/module-federation/info.json +0 -7
  253. package/templates/solid/add-on/module-federation/package.json +0 -5
  254. package/templates/solid/add-on/sentry/assets/_dot_cursorrules.append +0 -22
  255. package/templates/solid/add-on/sentry/assets/_dot_env.local.append +0 -2
  256. package/templates/solid/add-on/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +0 -20
  257. package/templates/solid/add-on/sentry/info.json +0 -13
  258. package/templates/solid/add-on/sentry/package.json +0 -5
  259. package/templates/solid/add-on/solid-ui/README.md +0 -9
  260. package/templates/solid/add-on/solid-ui/assets/src/lib/utils.ts +0 -6
  261. package/templates/solid/add-on/solid-ui/assets/src/styles.css +0 -138
  262. package/templates/solid/add-on/solid-ui/assets/ui.config.json +0 -13
  263. package/templates/solid/add-on/solid-ui/info.json +0 -11
  264. package/templates/solid/add-on/solid-ui/package.json +0 -9
  265. package/templates/solid/add-on/start/assets/app.config.ts +0 -16
  266. package/templates/solid/add-on/start/assets/src/api.ts +0 -6
  267. package/templates/solid/add-on/start/assets/src/client.tsx +0 -7
  268. package/templates/solid/add-on/start/assets/src/router.tsx.ejs +0 -24
  269. package/templates/solid/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +0 -49
  270. package/templates/solid/add-on/start/assets/src/ssr.tsx +0 -12
  271. package/templates/solid/add-on/start/info.json +0 -14
  272. package/templates/solid/add-on/start/package.json +0 -12
  273. package/templates/solid/add-on/store/assets/src/lib/demo-store.ts +0 -13
  274. package/templates/solid/add-on/store/assets/src/routes/demo.store.tsx.ejs +0 -77
  275. package/templates/solid/add-on/store/info.json +0 -13
  276. package/templates/solid/add-on/store/package.json +0 -6
  277. package/templates/solid/add-on/t3env/README.md +0 -16
  278. package/templates/solid/add-on/t3env/assets/src/env.ts +0 -39
  279. package/templates/solid/add-on/t3env/info.json +0 -10
  280. package/templates/solid/add-on/t3env/package.json +0 -6
  281. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/header-user.tsx +0 -5
  282. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/provider.tsx +0 -15
  283. package/templates/solid/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx +0 -30
  284. package/templates/solid/add-on/tanstack-query/info.json +0 -13
  285. package/templates/solid/add-on/tanstack-query/package.json +0 -6
  286. package/templates/solid/base/README.md.ejs +0 -215
  287. package/templates/solid/base/_dot_cursorrules.append +0 -35
  288. package/templates/solid/base/_dot_gitignore +0 -5
  289. package/templates/solid/base/_dot_vscode/settings.biome.json +0 -38
  290. package/templates/solid/base/_dot_vscode/settings.json +0 -11
  291. package/templates/solid/base/index.html.ejs +0 -20
  292. package/templates/solid/base/package.biome.json +0 -10
  293. package/templates/solid/base/package.eslintprettier.json +0 -11
  294. package/templates/solid/base/package.json +0 -23
  295. package/templates/solid/base/package.ts.json +0 -5
  296. package/templates/solid/base/package.tw.json +0 -6
  297. package/templates/solid/base/public/favicon.ico +0 -0
  298. package/templates/solid/base/public/logo192.png +0 -0
  299. package/templates/solid/base/public/logo512.png +0 -0
  300. package/templates/solid/base/public/manifest.json +0 -25
  301. package/templates/solid/base/public/robots.txt +0 -3
  302. package/templates/solid/base/src/App.css +0 -0
  303. package/templates/solid/base/src/App.tsx.ejs +0 -47
  304. package/templates/solid/base/src/components/Header.tsx.ejs +0 -26
  305. package/templates/solid/base/src/logo.svg +0 -120
  306. package/templates/solid/base/src/styles.css.ejs +0 -15
  307. package/templates/solid/base/toolchain/.prettierignore +0 -3
  308. package/templates/solid/base/toolchain/biome.json +0 -31
  309. package/templates/solid/base/toolchain/eslint.config.js +0 -5
  310. package/templates/solid/base/toolchain/prettier.config.js +0 -10
  311. package/templates/solid/base/tsconfig.json.ejs +0 -31
  312. package/templates/solid/base/vite.config.js.ejs +0 -22
  313. package/templates/solid/code-router/src/main.tsx.ejs +0 -71
  314. package/templates/solid/example/tanchat/README.md +0 -52
  315. package/templates/solid/example/tanchat/assets/ai-streaming-server/README.md +0 -110
  316. package/templates/solid/example/tanchat/assets/ai-streaming-server/_dot_env.example +0 -1
  317. package/templates/solid/example/tanchat/assets/ai-streaming-server/package.json +0 -26
  318. package/templates/solid/example/tanchat/assets/ai-streaming-server/src/index.ts +0 -102
  319. package/templates/solid/example/tanchat/assets/ai-streaming-server/tsconfig.json +0 -15
  320. package/templates/solid/example/tanchat/assets/src/components/demo.SettingsDialog.tsx +0 -149
  321. package/templates/solid/example/tanchat/assets/src/demo.index.css +0 -227
  322. package/templates/solid/example/tanchat/assets/src/lib/demo-store.ts +0 -13
  323. package/templates/solid/example/tanchat/assets/src/routes/example.chat.tsx +0 -435
  324. package/templates/solid/example/tanchat/assets/src/store/demo.hooks.ts +0 -17
  325. package/templates/solid/example/tanchat/assets/src/store/demo.store.ts +0 -133
  326. package/templates/solid/example/tanchat/info.json +0 -14
  327. package/templates/solid/example/tanchat/package.json +0 -7
  328. package/templates/solid/file-router/package.fr.json +0 -5
  329. package/templates/solid/file-router/src/main.tsx.ejs +0 -47
  330. package/templates/solid/file-router/src/routes/__root.tsx.ejs +0 -41
  331. package/templates/solid/file-router/src/routes/index.tsx +0 -43
  332. package/tests/cra.test.ts +0 -293
  333. package/tests/snapshots/cra/cr-js-npm.json +0 -33
  334. package/tests/snapshots/cra/cr-ts-npm.json +0 -34
  335. package/tests/snapshots/cra/cr-ts-start-npm.json +0 -38
  336. package/tests/snapshots/cra/fr-ts-npm.json +0 -34
  337. package/tests/snapshots/cra/fr-ts-tw-npm.json +0 -33
  338. package/tests/snapshots/cra/solid-cr-js-npm.json +0 -31
  339. package/tests/snapshots/cra/solid-cr-ts-npm.json +0 -32
  340. package/tests/snapshots/cra/solid-cr-ts-start-npm.json +0 -36
  341. package/tests/snapshots/cra/solid-fr-ts-npm.json +0 -33
  342. package/tests/snapshots/cra/solid-fr-ts-tw-npm.json +0 -32
  343. package/tests/test-utilities.ts +0 -87
@@ -0,0 +1,165 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
3
+ import { basename, extname, resolve } from 'node:path';
4
+ import parseGitignore from 'parse-gitignore';
5
+ import ignore from 'ignore';
6
+ const BINARY_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico'];
7
+ export function readFileHelper(path) {
8
+ if (isBinaryFile(path)) {
9
+ return `base64::${readFileSync(path).toString('base64')}`;
10
+ }
11
+ else {
12
+ return readFileSync(path, 'utf-8').toString();
13
+ }
14
+ }
15
+ export function isBinaryFile(path) {
16
+ return BINARY_EXTENSIONS.includes(extname(path));
17
+ }
18
+ export function convertBinaryContentsToBase64(contents) {
19
+ return `base64::${Buffer.from(contents).toString('base64')}`;
20
+ }
21
+ export function isBase64(content) {
22
+ return content.startsWith('base64::');
23
+ }
24
+ export function getBinaryFile(content) {
25
+ if (content.startsWith('base64::')) {
26
+ const binaryContent = Buffer.from(content.replace('base64::', ''), 'base64');
27
+ return binaryContent;
28
+ }
29
+ return null;
30
+ }
31
+ export function relativePath(from, to) {
32
+ const cleanedFrom = from.startsWith('./') ? from.slice(2) : from;
33
+ const cleanedTo = to.startsWith('./') ? to.slice(2) : to;
34
+ const fromSegments = cleanedFrom.split('/');
35
+ const toSegments = cleanedTo.split('/');
36
+ fromSegments.pop();
37
+ toSegments.pop();
38
+ let commonIndex = 0;
39
+ while (commonIndex < fromSegments.length &&
40
+ commonIndex < toSegments.length &&
41
+ fromSegments[commonIndex] === toSegments[commonIndex]) {
42
+ commonIndex++;
43
+ }
44
+ const upLevels = fromSegments.length - commonIndex;
45
+ const downLevels = toSegments.slice(commonIndex);
46
+ if (upLevels === 0 && downLevels.length === 0) {
47
+ return `./${basename(to)}`;
48
+ }
49
+ else if (upLevels === 0 && downLevels.length > 0) {
50
+ return `./${downLevels.join('/')}/${basename(to)}`;
51
+ }
52
+ else {
53
+ const relativePath = [...Array(upLevels).fill('..'), ...downLevels].join('/');
54
+ return `${relativePath}/${basename(to)}`;
55
+ }
56
+ }
57
+ export function isDirectory(path) {
58
+ return statSync(path).isDirectory();
59
+ }
60
+ export function findFilesRecursively(path, files) {
61
+ const dirFiles = readdirSync(path);
62
+ for (const file of dirFiles) {
63
+ const filePath = resolve(path, file);
64
+ if (isDirectory(filePath)) {
65
+ findFilesRecursively(filePath, files);
66
+ }
67
+ else {
68
+ files[filePath] = readFileHelper(filePath);
69
+ }
70
+ }
71
+ }
72
+ async function recursivelyGatherFilesHelper(basePath, path, files, ignore) {
73
+ const dirFiles = await readdir(path, { withFileTypes: true });
74
+ for (const file of dirFiles) {
75
+ if (ignore(file.name)) {
76
+ continue;
77
+ }
78
+ if (file.isDirectory()) {
79
+ await recursivelyGatherFilesHelper(basePath, resolve(path, file.name), files, ignore);
80
+ }
81
+ else {
82
+ const filePath = resolve(path, file.name);
83
+ files[filePath.replace(basePath, '.')] = await readFileHelper(filePath);
84
+ }
85
+ }
86
+ }
87
+ export async function recursivelyGatherFiles(path, includeProjectFiles = true) {
88
+ const ignore = createIgnore(path, includeProjectFiles);
89
+ const files = {};
90
+ await recursivelyGatherFilesHelper(path, path, files, ignore);
91
+ return files;
92
+ }
93
+ async function recursivelyGatherFilesFromEnvironmentHelper(environment, basePath, path, files, ignore) {
94
+ const dirFiles = await environment.readdir(path);
95
+ for (const file of dirFiles) {
96
+ if (ignore(file)) {
97
+ continue;
98
+ }
99
+ if (environment.isDirectory(resolve(path, file))) {
100
+ await recursivelyGatherFilesFromEnvironmentHelper(environment, basePath, resolve(path, file), files, ignore);
101
+ }
102
+ else {
103
+ const filePath = resolve(path, file);
104
+ files[filePath.replace(basePath, '.')] =
105
+ await environment.readFile(filePath);
106
+ }
107
+ }
108
+ }
109
+ export async function recursivelyGatherFilesFromEnvironment(environment, path, includeProjectFiles = true) {
110
+ const ignore = createIgnore(path, includeProjectFiles);
111
+ const files = {};
112
+ await recursivelyGatherFilesFromEnvironmentHelper(environment, path, path, files, ignore);
113
+ return files;
114
+ }
115
+ export const IGNORE_FILES = [
116
+ '.starter',
117
+ '.add-on',
118
+ '.cta.json',
119
+ '.git',
120
+ 'add-on-info.json',
121
+ 'add-on.json',
122
+ 'build',
123
+ 'bun.lock',
124
+ 'bun.lockb',
125
+ 'deno.lock',
126
+ 'dist',
127
+ 'node_modules',
128
+ 'package-lock.json',
129
+ 'pnpm-lock.yaml',
130
+ 'starter.json',
131
+ 'starter-info.json',
132
+ 'yarn.lock',
133
+ ];
134
+ const PROJECT_FILES = ['package.json'];
135
+ export function createIgnore(path, includeProjectFiles = true) {
136
+ const ignoreList = existsSync(resolve(path, '.gitignore'))
137
+ ? parseGitignore(readFileSync(resolve(path, '.gitignore'))).patterns
138
+ : [];
139
+ const ig = ignore().add(ignoreList);
140
+ return (filePath) => {
141
+ const fileName = basename(filePath);
142
+ if (IGNORE_FILES.includes(fileName) ||
143
+ (includeProjectFiles && PROJECT_FILES.includes(fileName))) {
144
+ return true;
145
+ }
146
+ const nameWithoutDotSlash = fileName.replace(/^\.\//, '');
147
+ return ig.ignores(nameWithoutDotSlash);
148
+ };
149
+ }
150
+ export function cleanUpFiles(files, targetDir) {
151
+ return Object.keys(files).reduce((acc, file) => {
152
+ if (basename(file) !== '.cta.json') {
153
+ acc[targetDir ? file.replace(targetDir, '.') : file] = files[file];
154
+ }
155
+ return acc;
156
+ }, {});
157
+ }
158
+ export function cleanUpFileArray(files, targetDir) {
159
+ return files.reduce((acc, file) => {
160
+ if (basename(file) !== '.cta.json') {
161
+ acc.push(targetDir ? file.replace(targetDir, '.') : file);
162
+ }
163
+ return acc;
164
+ }, []);
165
+ }
@@ -0,0 +1,92 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { resolve } from 'node:path';
3
+ import { findFilesRecursively, isDirectory, readFileHelper, } from './file-helpers.js';
4
+ const frameworks = [];
5
+ function getAddOns(framework) {
6
+ const addOns = [];
7
+ for (const addOnsBase of framework.addOnsDirectories) {
8
+ for (const dir of readdirSync(addOnsBase).filter((file) => isDirectory(resolve(addOnsBase, file)))) {
9
+ const filePath = resolve(addOnsBase, dir, 'info.json');
10
+ const fileContent = readFileSync(filePath, 'utf-8');
11
+ const info = JSON.parse(fileContent);
12
+ let packageAdditions = {};
13
+ if (existsSync(resolve(addOnsBase, dir, 'package.json'))) {
14
+ packageAdditions = JSON.parse(readFileSync(resolve(addOnsBase, dir, 'package.json'), 'utf-8'));
15
+ }
16
+ let readme;
17
+ if (existsSync(resolve(addOnsBase, dir, 'README.md'))) {
18
+ readme = readFileSync(resolve(addOnsBase, dir, 'README.md'), 'utf-8');
19
+ }
20
+ let smallLogo;
21
+ if (existsSync(resolve(addOnsBase, dir, 'small-logo.svg'))) {
22
+ smallLogo = readFileSync(resolve(addOnsBase, dir, 'small-logo.svg'), 'utf-8');
23
+ }
24
+ const absoluteFiles = {};
25
+ const assetsDir = resolve(addOnsBase, dir, 'assets');
26
+ if (existsSync(assetsDir)) {
27
+ findFilesRecursively(assetsDir, absoluteFiles);
28
+ }
29
+ const files = {};
30
+ for (const file of Object.keys(absoluteFiles)) {
31
+ files[file.replace(assetsDir, '.')] = readFileHelper(file);
32
+ }
33
+ const getFiles = () => {
34
+ return Promise.resolve(Object.keys(files));
35
+ };
36
+ const getFileContents = (path) => {
37
+ return Promise.resolve(files[path]);
38
+ };
39
+ addOns.push({
40
+ ...info,
41
+ id: dir,
42
+ packageAdditions,
43
+ readme,
44
+ files,
45
+ smallLogo,
46
+ getFiles,
47
+ getFileContents,
48
+ getDeletedFiles: () => Promise.resolve(info.deletedFiles ?? []),
49
+ });
50
+ }
51
+ }
52
+ return addOns;
53
+ }
54
+ export function __testRegisterFramework(framework) {
55
+ frameworks.push(framework);
56
+ }
57
+ export function __testClearFrameworks() {
58
+ frameworks.length = 0;
59
+ }
60
+ export function registerFramework(framework) {
61
+ const baseAssetsDirectory = resolve(framework.baseDirectory, 'base');
62
+ const basePackageJSON = JSON.parse(readFileSync(resolve(baseAssetsDirectory, 'package.json'), 'utf8'));
63
+ const optionalPackages = JSON.parse(readFileSync(resolve(framework.baseDirectory, 'packages.json'), 'utf8'));
64
+ const addOns = getAddOns(framework);
65
+ const frameworkWithBundler = {
66
+ ...framework,
67
+ getFiles: () => {
68
+ const files = {};
69
+ findFilesRecursively(baseAssetsDirectory, files);
70
+ return Promise.resolve(Object.keys(files).map((path) => path.replace(baseAssetsDirectory, '.')));
71
+ },
72
+ getFileContents: (path) => {
73
+ return Promise.resolve(readFileHelper(resolve(baseAssetsDirectory, path)));
74
+ },
75
+ getDeletedFiles: () => {
76
+ return Promise.resolve([]);
77
+ },
78
+ basePackageJSON,
79
+ optionalPackages,
80
+ getAddOns: () => addOns,
81
+ };
82
+ frameworks.push(frameworkWithBundler);
83
+ }
84
+ export function getFrameworkById(id) {
85
+ return frameworks.find((framework) => framework.id === id);
86
+ }
87
+ export function getFrameworkByName(name) {
88
+ return frameworks.find((framework) => framework.name === name);
89
+ }
90
+ export function getFrameworks() {
91
+ return frameworks;
92
+ }
package/dist/index.js CHANGED
@@ -1 +1,18 @@
1
- export { cli } from './cli.js';
1
+ export { createApp } from './create-app.js';
2
+ export { addToApp } from './add-to-app.js';
3
+ export { finalizeAddOns, getAllAddOns } from './add-ons.js';
4
+ export { loadRemoteAddOn } from './custom-add-ons/add-on.js';
5
+ export { loadStarter } from './custom-add-ons/starter.js';
6
+ export { createMemoryEnvironment, createDefaultEnvironment, } from './environment.js';
7
+ export { CODE_ROUTER, CONFIG_FILE, FILE_ROUTER } from './constants.js';
8
+ export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, } from './package-manager.js';
9
+ export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, } from './frameworks.js';
10
+ export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfigFile, } from './config-file.js';
11
+ export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, } from './file-helpers.js';
12
+ export { formatCommand } from './utils.js';
13
+ export { initStarter, compileStarter } from './custom-add-ons/starter.js';
14
+ export { initAddOn, compileAddOn } from './custom-add-ons/add-on.js';
15
+ export { createAppOptionsFromPersisted, createSerializedOptionsFromPersisted, } from './custom-add-ons/shared.js';
16
+ export { createSerializedOptions } from './options.js';
17
+ export { getRawRegistry, getRegistry, getRegistryAddOns, getRegistryStarters, } from './registry.js';
18
+ export { StarterCompiledSchema, AddOnCompiledSchema, AddOnInfoSchema, IntegrationSchema, } from './types.js';
@@ -0,0 +1,4 @@
1
+ import { resolve } from 'node:path';
2
+ export async function setupGit(environment, targetDir) {
3
+ await environment.execute('git', ['init'], resolve(targetDir));
4
+ }
@@ -0,0 +1,33 @@
1
+ import { resolve } from 'node:path';
2
+ import { packageManagerExecute } from '../package-manager.js';
3
+ export async function installShadcnComponents(environment, targetDir, options) {
4
+ const s = environment.spinner();
5
+ if (options.chosenAddOns.find((a) => a.id === 'shadcn')) {
6
+ const shadcnComponents = new Set();
7
+ for (const addOn of options.chosenAddOns) {
8
+ if (addOn.shadcnComponents) {
9
+ for (const component of addOn.shadcnComponents) {
10
+ shadcnComponents.add(component);
11
+ }
12
+ }
13
+ }
14
+ if (options.starter) {
15
+ if (options.starter.shadcnComponents) {
16
+ for (const component of options.starter.shadcnComponents) {
17
+ shadcnComponents.add(component);
18
+ }
19
+ }
20
+ }
21
+ if (shadcnComponents.size > 0) {
22
+ s.start(`Installing shadcn components (${Array.from(shadcnComponents).join(', ')})...`);
23
+ environment.startStep({
24
+ id: 'install-shadcn-components',
25
+ type: 'command',
26
+ message: `Installing shadcn components (${Array.from(shadcnComponents).join(', ')})...`,
27
+ });
28
+ await packageManagerExecute(environment, resolve(targetDir), options.packageManager, 'shadcn@latest', ['add', '--silent', '--yes', ...Array.from(shadcnComponents)]);
29
+ environment.finishStep('install-shadcn-components', 'Shadcn components installed');
30
+ s.stop(`Installed additional shadcn components`);
31
+ }
32
+ }
33
+ }
package/dist/options.js CHANGED
@@ -1,333 +1,9 @@
1
- import { cancel, confirm, isCancel, multiselect, select, text, } from '@clack/prompts';
2
- import { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, } from './package-manager.js';
3
- import { DEFAULT_TOOLCHAIN, SUPPORTED_TOOLCHAINS } from './toolchain.js';
4
- import { CODE_ROUTER, DEFAULT_FRAMEWORK, FILE_ROUTER } from './constants.js';
5
- import { finalizeAddOns, getAllAddOns, loadRemoteAddOn } from './add-ons.js';
6
- // If all CLI options are provided, use them directly
7
- export async function normalizeOptions(cliOptions, forcedMode, forcedAddOns) {
8
- // in some cases, if you use windows/powershell, the argument for addons
9
- // if sepparated by comma is not really passed as an array, but as a string
10
- // with spaces, We need to normalize this edge case.
11
- if (Array.isArray(cliOptions.addOns) && cliOptions.addOns.length === 1) {
12
- const parseSeparatedArgs = cliOptions.addOns[0].split(' ');
13
- if (parseSeparatedArgs.length > 1) {
14
- cliOptions.addOns = parseSeparatedArgs;
15
- }
16
- }
17
- if (cliOptions.projectName) {
18
- let typescript = cliOptions.template === 'typescript' ||
19
- cliOptions.template === 'file-router' ||
20
- cliOptions.framework === 'solid';
21
- let tailwind = !!cliOptions.tailwind;
22
- if (cliOptions.framework === 'solid') {
23
- tailwind = true;
24
- }
25
- let mode = cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER;
26
- const overlay = cliOptions.overlay
27
- ? (await loadRemoteAddOn(cliOptions.overlay))
28
- : undefined;
29
- if (overlay) {
30
- tailwind = overlay.tailwind;
31
- typescript = overlay.typescript;
32
- cliOptions.framework = overlay.framework;
33
- mode = overlay.mode;
34
- }
35
- let addOns = false;
36
- let chosenAddOns = [];
37
- if (Array.isArray(cliOptions.addOns) ||
38
- overlay?.dependsOn ||
39
- forcedAddOns) {
40
- addOns = true;
41
- let finalAddOns = Array.from(new Set([...(overlay?.dependsOn || []), ...(forcedAddOns || [])]));
42
- if (cliOptions.addOns && Array.isArray(cliOptions.addOns)) {
43
- finalAddOns = Array.from(new Set([
44
- ...(forcedAddOns || []),
45
- ...finalAddOns,
46
- ...cliOptions.addOns,
47
- ]));
48
- }
49
- chosenAddOns = await finalizeAddOns(cliOptions.framework || DEFAULT_FRAMEWORK, forcedMode || cliOptions.template === 'file-router'
50
- ? FILE_ROUTER
51
- : CODE_ROUTER, finalAddOns);
52
- tailwind = true;
53
- typescript = true;
54
- }
55
- return {
56
- framework: cliOptions.framework || 'react',
57
- projectName: cliOptions.projectName,
58
- typescript,
59
- tailwind,
60
- packageManager: cliOptions.packageManager ||
61
- getPackageManager() ||
62
- DEFAULT_PACKAGE_MANAGER,
63
- toolchain: cliOptions.toolchain || DEFAULT_TOOLCHAIN,
64
- mode,
65
- git: !!cliOptions.git,
66
- addOns,
67
- chosenAddOns,
68
- variableValues: {},
69
- overlay,
70
- };
71
- }
72
- }
73
- async function collectVariables(variables) {
74
- const responses = {};
75
- for (const variable of variables) {
76
- if (variable.type === 'string') {
77
- const response = await text({
78
- message: variable.description,
79
- initialValue: variable.default,
80
- });
81
- if (isCancel(response)) {
82
- cancel('Operation cancelled.');
83
- process.exit(0);
84
- }
85
- responses[variable.name] = response;
86
- }
87
- else if (variable.type === 'number') {
88
- const response = await text({
89
- message: variable.description,
90
- initialValue: variable.default.toString(),
91
- });
92
- if (isCancel(response)) {
93
- cancel('Operation cancelled.');
94
- process.exit(0);
95
- }
96
- responses[variable.name] = Number(response);
97
- }
98
- else {
99
- const response = await confirm({
100
- message: variable.description,
101
- initialValue: variable.default === true,
102
- });
103
- if (isCancel(response)) {
104
- cancel('Operation cancelled.');
105
- process.exit(0);
106
- }
107
- responses[variable.name] = response;
108
- }
109
- }
110
- return responses;
111
- }
112
- export async function promptForOptions(cliOptions, { forcedAddOns = [], forcedMode, }) {
113
- const options = {};
114
- options.framework = cliOptions.framework || DEFAULT_FRAMEWORK;
115
- if (options.framework === 'solid') {
116
- options.typescript = true;
117
- options.tailwind = true;
118
- }
119
- if (cliOptions.addOns) {
120
- options.typescript = true;
121
- }
122
- if (!cliOptions.projectName) {
123
- const value = await text({
124
- message: 'What would you like to name your project?',
125
- defaultValue: 'my-app',
126
- validate(value) {
127
- if (!value) {
128
- return 'Please enter a name';
129
- }
130
- },
131
- });
132
- if (isCancel(value)) {
133
- cancel('Operation cancelled.');
134
- process.exit(0);
135
- }
136
- options.projectName = value;
137
- }
138
- else {
139
- options.projectName = cliOptions.projectName;
140
- }
141
- // Router type selection
142
- if (!cliOptions.template && !forcedMode) {
143
- const routerType = await select({
144
- message: 'Select the router type:',
145
- options: [
146
- {
147
- value: FILE_ROUTER,
148
- label: 'File Router - File-based routing structure',
149
- },
150
- {
151
- value: CODE_ROUTER,
152
- label: 'Code Router - Traditional code-based routing',
153
- },
154
- ],
155
- initialValue: FILE_ROUTER,
156
- });
157
- if (isCancel(routerType)) {
158
- cancel('Operation cancelled.');
159
- process.exit(0);
160
- }
161
- options.mode = routerType;
162
- }
163
- else if (forcedMode) {
164
- options.mode = forcedMode === 'file-router' ? FILE_ROUTER : CODE_ROUTER;
165
- options.typescript = options.mode === FILE_ROUTER;
166
- }
167
- else {
168
- options.mode =
169
- cliOptions.template === 'file-router' ? FILE_ROUTER : CODE_ROUTER;
170
- if (options.mode === FILE_ROUTER) {
171
- options.typescript = true;
172
- }
173
- }
174
- // TypeScript selection (if using Code Router)
175
- if (!options.typescript) {
176
- if (options.mode === CODE_ROUTER) {
177
- const typescriptEnable = await confirm({
178
- message: 'Would you like to use TypeScript?',
179
- initialValue: true,
180
- });
181
- if (isCancel(typescriptEnable)) {
182
- cancel('Operation cancelled.');
183
- process.exit(0);
184
- }
185
- options.typescript = typescriptEnable;
186
- }
187
- else {
188
- options.typescript = true;
189
- }
190
- }
191
- // Tailwind selection
192
- if (!cliOptions.tailwind && options.framework === 'react') {
193
- const tailwind = await confirm({
194
- message: 'Would you like to use Tailwind CSS?',
195
- initialValue: true,
196
- });
197
- if (isCancel(tailwind)) {
198
- cancel('Operation cancelled.');
199
- process.exit(0);
200
- }
201
- options.tailwind = tailwind;
202
- }
203
- else {
204
- options.tailwind = options.framework === 'solid' || !!cliOptions.tailwind;
205
- }
206
- // Package manager selection
207
- if (cliOptions.packageManager === undefined) {
208
- const detectedPackageManager = getPackageManager();
209
- if (!detectedPackageManager) {
210
- const pm = await select({
211
- message: 'Select package manager:',
212
- options: SUPPORTED_PACKAGE_MANAGERS.map((pm) => ({
213
- value: pm,
214
- label: pm,
215
- })),
216
- initialValue: DEFAULT_PACKAGE_MANAGER,
217
- });
218
- if (isCancel(pm)) {
219
- cancel('Operation cancelled.');
220
- process.exit(0);
221
- }
222
- options.packageManager = pm;
223
- }
224
- else {
225
- options.packageManager = detectedPackageManager;
226
- }
227
- }
228
- else {
229
- options.packageManager = cliOptions.packageManager;
230
- }
231
- // Toolchain selection
232
- if (cliOptions.toolchain === undefined) {
233
- const tc = await select({
234
- message: 'Select toolchain',
235
- options: SUPPORTED_TOOLCHAINS.map((tc) => ({
236
- value: tc,
237
- label: tc,
238
- })),
239
- initialValue: DEFAULT_TOOLCHAIN,
240
- });
241
- if (isCancel(tc)) {
242
- cancel('Operation cancelled.');
243
- process.exit(0);
244
- }
245
- options.toolchain = tc;
246
- }
247
- else {
248
- options.toolchain = cliOptions.toolchain;
249
- }
250
- options.chosenAddOns = [];
251
- if (Array.isArray(cliOptions.addOns)) {
252
- options.chosenAddOns = await finalizeAddOns(options.framework, options.mode, Array.from(new Set([...cliOptions.addOns, ...forcedAddOns])));
253
- options.tailwind = true;
254
- }
255
- else if (cliOptions.addOns) {
256
- // Select any add-ons
257
- const allAddOns = await getAllAddOns(options.framework, options.mode);
258
- const addOns = allAddOns.filter((addOn) => addOn.type === 'add-on');
259
- let selectedAddOns = [];
260
- if (options.typescript && addOns.length > 0) {
261
- const value = await multiselect({
262
- message: 'What add-ons would you like for your project:',
263
- options: addOns
264
- .filter((addOn) => !forcedAddOns.includes(addOn.id))
265
- .map((addOn) => ({
266
- value: addOn.id,
267
- label: addOn.name,
268
- hint: addOn.description,
269
- })),
270
- required: false,
271
- });
272
- if (isCancel(value)) {
273
- cancel('Operation cancelled.');
274
- process.exit(0);
275
- }
276
- selectedAddOns = value;
277
- }
278
- // Select any examples
279
- let selectedExamples = [];
280
- const examples = allAddOns.filter((addOn) => addOn.type === 'example');
281
- if (options.typescript && examples.length > 0) {
282
- const value = await multiselect({
283
- message: 'Would you like any examples?',
284
- options: examples
285
- .filter((addOn) => !forcedAddOns.includes(addOn.id))
286
- .map((addOn) => ({
287
- value: addOn.id,
288
- label: addOn.name,
289
- hint: addOn.description,
290
- })),
291
- required: false,
292
- });
293
- if (isCancel(value)) {
294
- cancel('Operation cancelled.');
295
- process.exit(0);
296
- }
297
- selectedExamples = value;
298
- }
299
- if (selectedAddOns.length > 0 ||
300
- selectedExamples.length > 0 ||
301
- forcedAddOns.length > 0) {
302
- options.chosenAddOns = await finalizeAddOns(options.framework, options.mode, Array.from(new Set([...selectedAddOns, ...selectedExamples, ...forcedAddOns])));
303
- options.tailwind = true;
304
- }
305
- }
306
- else if (forcedAddOns.length > 0) {
307
- options.chosenAddOns = await finalizeAddOns(options.framework, options.mode, forcedAddOns);
308
- }
309
- // Collect variables
310
- const variables = [];
311
- for (const addOn of options.chosenAddOns) {
312
- for (const variable of addOn.variables ?? []) {
313
- variables.push(variable);
314
- }
315
- }
316
- options.variableValues = await collectVariables(variables);
317
- // Git selection
318
- if (cliOptions.git === undefined) {
319
- const git = await confirm({
320
- message: 'Would you like to initialize a new git repository?',
321
- initialValue: true,
322
- });
323
- if (isCancel(git)) {
324
- cancel('Operation cancelled.');
325
- process.exit(0);
326
- }
327
- options.git = git;
328
- }
329
- else {
330
- options.git = !!cliOptions.git;
331
- }
332
- return options;
333
- }
1
+ export const createSerializedOptions = (options) => {
2
+ const serializedOptions = {
3
+ ...options,
4
+ chosenAddOns: options.chosenAddOns.map((addOn) => addOn.id),
5
+ framework: options.framework.id,
6
+ starter: options.starter?.id,
7
+ };
8
+ return serializedOptions;
9
+ };