@tanstack/cta-engine 0.10.0-alpha.15 → 0.10.0-alpha.16

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 (294) hide show
  1. package/dist/add-ons.js +8 -73
  2. package/dist/{add.js → add-to-app.js} +19 -19
  3. package/dist/config-file.js +6 -3
  4. package/dist/constants.js +0 -2
  5. package/dist/create-app.js +76 -460
  6. package/dist/environment.js +11 -26
  7. package/dist/file-helpers.js +59 -0
  8. package/dist/frameworks.js +78 -0
  9. package/dist/index.js +8 -3
  10. package/dist/integrations/git.js +4 -0
  11. package/dist/integrations/shadcn.js +27 -0
  12. package/dist/package-json.js +46 -0
  13. package/dist/package-manager.js +51 -6
  14. package/dist/template-file.js +108 -0
  15. package/dist/types/add-ons.d.ts +2 -6
  16. package/dist/types/add-to-app.d.ts +4 -0
  17. package/dist/types/config-file.d.ts +3 -2
  18. package/dist/types/constants.d.ts +0 -3
  19. package/dist/types/file-helpers.d.ts +5 -0
  20. package/dist/types/frameworks.d.ts +5 -0
  21. package/dist/types/index.d.ts +10 -4
  22. package/dist/types/integrations/git.d.ts +2 -0
  23. package/dist/types/integrations/shadcn.d.ts +2 -0
  24. package/dist/types/package-json.d.ts +2 -0
  25. package/dist/types/package-manager.d.ts +14 -1
  26. package/dist/types/template-file.d.ts +2 -0
  27. package/dist/types/types.d.ts +83 -62
  28. package/dist/types/utils.d.ts +5 -0
  29. package/dist/utils.js +9 -0
  30. package/package.json +3 -13
  31. package/src/add-ons.ts +11 -104
  32. package/src/{add.ts → add-to-app.ts} +29 -35
  33. package/src/config-file.ts +12 -6
  34. package/src/constants.ts +0 -5
  35. package/src/create-app.ts +126 -727
  36. package/src/environment.ts +12 -27
  37. package/src/file-helpers.ts +73 -0
  38. package/src/frameworks.ts +114 -0
  39. package/src/index.ts +35 -4
  40. package/src/integrations/git.ts +7 -0
  41. package/src/integrations/shadcn.ts +44 -0
  42. package/src/package-json.ts +62 -0
  43. package/src/package-manager.ts +80 -9
  44. package/src/template-file.ts +146 -0
  45. package/src/types.ts +97 -68
  46. package/src/utils.ts +17 -0
  47. package/tests/file-helper.test.ts +37 -0
  48. package/tests/package-manager.test.ts +154 -0
  49. package/dist/cli.js +0 -126
  50. package/dist/custom-add-on.js +0 -256
  51. package/dist/file-helper.js +0 -18
  52. package/dist/mcp.js +0 -229
  53. package/dist/options.js +0 -328
  54. package/dist/templates.js +0 -6
  55. package/dist/toolchain.js +0 -6
  56. package/dist/types/add.d.ts +0 -3
  57. package/dist/types/cli.d.ts +0 -6
  58. package/dist/types/custom-add-on.d.ts +0 -6
  59. package/dist/types/file-helper.d.ts +0 -2
  60. package/dist/types/mcp.d.ts +0 -7
  61. package/dist/types/options.d.ts +0 -6
  62. package/dist/types/templates.d.ts +0 -1
  63. package/dist/types/toolchain.d.ts +0 -3
  64. package/src/cli.ts +0 -196
  65. package/src/custom-add-on.ts +0 -327
  66. package/src/file-helper.ts +0 -20
  67. package/src/mcp.ts +0 -302
  68. package/src/options.ts +0 -399
  69. package/src/templates.ts +0 -7
  70. package/src/toolchain.ts +0 -7
  71. package/templates/react/add-on/clerk/README.md +0 -3
  72. package/templates/react/add-on/clerk/assets/_dot_env.local.append +0 -2
  73. package/templates/react/add-on/clerk/assets/src/integrations/clerk/header-user.tsx +0 -19
  74. package/templates/react/add-on/clerk/assets/src/integrations/clerk/provider.tsx +0 -18
  75. package/templates/react/add-on/clerk/assets/src/routes/demo.clerk.tsx +0 -20
  76. package/templates/react/add-on/clerk/info.json +0 -13
  77. package/templates/react/add-on/clerk/package.json +0 -5
  78. package/templates/react/add-on/convex/README.md +0 -4
  79. package/templates/react/add-on/convex/assets/_dot_cursorrules.append +0 -93
  80. package/templates/react/add-on/convex/assets/_dot_env.local.append +0 -3
  81. package/templates/react/add-on/convex/assets/convex/products.ts +0 -8
  82. package/templates/react/add-on/convex/assets/convex/schema.ts +0 -10
  83. package/templates/react/add-on/convex/assets/src/integrations/convex/provider.tsx +0 -20
  84. package/templates/react/add-on/convex/assets/src/routes/demo.convex.tsx +0 -33
  85. package/templates/react/add-on/convex/info.json +0 -13
  86. package/templates/react/add-on/convex/package.json +0 -6
  87. package/templates/react/add-on/form/assets/src/components/demo.FormComponents.tsx.ejs +0 -300
  88. package/templates/react/add-on/form/assets/src/hooks/demo.form-context.ts +0 -4
  89. package/templates/react/add-on/form/assets/src/hooks/demo.form.ts +0 -22
  90. package/templates/react/add-on/form/assets/src/routes/demo.form.address.tsx.ejs +0 -213
  91. package/templates/react/add-on/form/assets/src/routes/demo.form.simple.tsx.ejs +0 -77
  92. package/templates/react/add-on/form/info.json +0 -26
  93. package/templates/react/add-on/form/package.json +0 -6
  94. package/templates/react/add-on/module-federation/assets/module-federation.config.js.ejs +0 -31
  95. package/templates/react/add-on/module-federation/assets/src/demo-mf-component.tsx +0 -3
  96. package/templates/react/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +0 -11
  97. package/templates/react/add-on/module-federation/info.json +0 -7
  98. package/templates/react/add-on/module-federation/package.json +0 -5
  99. package/templates/react/add-on/netlify/README.md +0 -11
  100. package/templates/react/add-on/netlify/info.json +0 -7
  101. package/templates/react/add-on/sentry/assets/_dot_cursorrules.append +0 -22
  102. package/templates/react/add-on/sentry/assets/_dot_env.local.append +0 -2
  103. package/templates/react/add-on/sentry/assets/src/app/global-middleware.ts +0 -25
  104. package/templates/react/add-on/sentry/assets/src/routes/demo.sentry.testing.tsx +0 -480
  105. package/templates/react/add-on/sentry/info.json +0 -14
  106. package/templates/react/add-on/sentry/package.json +0 -7
  107. package/templates/react/add-on/shadcn/README.md +0 -7
  108. package/templates/react/add-on/shadcn/assets/_dot_cursorrules.append +0 -7
  109. package/templates/react/add-on/shadcn/assets/components.json +0 -21
  110. package/templates/react/add-on/shadcn/assets/src/lib/utils.ts +0 -6
  111. package/templates/react/add-on/shadcn/assets/src/styles.css +0 -138
  112. package/templates/react/add-on/shadcn/info.json +0 -7
  113. package/templates/react/add-on/shadcn/package.json +0 -9
  114. package/templates/react/add-on/start/assets/_dot_gitignore.append +0 -2
  115. package/templates/react/add-on/start/assets/app.config.ts.ejs +0 -19
  116. package/templates/react/add-on/start/assets/src/api.ts +0 -6
  117. package/templates/react/add-on/start/assets/src/client.tsx +0 -8
  118. package/templates/react/add-on/start/assets/src/router.tsx.ejs +0 -77
  119. package/templates/react/add-on/start/assets/src/routes/api.demo-names.ts +0 -11
  120. package/templates/react/add-on/start/assets/src/routes/demo.start.api-request.tsx.ejs +0 -33
  121. package/templates/react/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +0 -50
  122. package/templates/react/add-on/start/assets/src/ssr.tsx +0 -12
  123. package/templates/react/add-on/start/info.json +0 -18
  124. package/templates/react/add-on/start/package.json +0 -13
  125. package/templates/react/add-on/store/assets/src/lib/demo-store.ts +0 -13
  126. package/templates/react/add-on/store/assets/src/routes/demo.store.tsx.ejs +0 -75
  127. package/templates/react/add-on/store/info.json +0 -13
  128. package/templates/react/add-on/store/package.json +0 -6
  129. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/init.ts +0 -9
  130. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/react.ts +0 -4
  131. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/router.ts +0 -18
  132. package/templates/react/add-on/tRPC/assets/src/routes/api.trpc.$.tsx +0 -16
  133. package/templates/react/add-on/tRPC/info.json +0 -9
  134. package/templates/react/add-on/tRPC/package.json +0 -9
  135. package/templates/react/add-on/table/assets/src/data/demo-table-data.ts +0 -50
  136. package/templates/react/add-on/table/assets/src/routes/demo.table.tsx.ejs +0 -373
  137. package/templates/react/add-on/table/info.json +0 -13
  138. package/templates/react/add-on/table/package.json +0 -7
  139. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/layout.tsx +0 -5
  140. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/root-provider.tsx.ejs +0 -70
  141. package/templates/react/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx.ejs +0 -53
  142. package/templates/react/add-on/tanstack-query/info.json +0 -13
  143. package/templates/react/add-on/tanstack-query/package.json +0 -6
  144. package/templates/react/base/README.md.ejs +0 -558
  145. package/templates/react/base/_dot_gitignore +0 -5
  146. package/templates/react/base/_dot_vscode/settings.biome.json +0 -38
  147. package/templates/react/base/_dot_vscode/settings.json +0 -11
  148. package/templates/react/base/index.html.ejs +0 -20
  149. package/templates/react/base/package.biome.json +0 -10
  150. package/templates/react/base/package.eslintprettier.json +0 -11
  151. package/templates/react/base/package.json +0 -29
  152. package/templates/react/base/package.ts.json +0 -7
  153. package/templates/react/base/package.tw.json +0 -6
  154. package/templates/react/base/public/favicon.ico +0 -0
  155. package/templates/react/base/public/logo192.png +0 -0
  156. package/templates/react/base/public/logo512.png +0 -0
  157. package/templates/react/base/public/manifest.json +0 -25
  158. package/templates/react/base/public/robots.txt +0 -3
  159. package/templates/react/base/src/App.css +0 -38
  160. package/templates/react/base/src/App.test.tsx.ejs +0 -10
  161. package/templates/react/base/src/App.tsx.ejs +0 -74
  162. package/templates/react/base/src/components/Header.tsx.ejs +0 -27
  163. package/templates/react/base/src/logo.svg +0 -44
  164. package/templates/react/base/src/reportWebVitals.ts.ejs +0 -28
  165. package/templates/react/base/src/styles.css.ejs +0 -15
  166. package/templates/react/base/toolchain/.prettierignore +0 -3
  167. package/templates/react/base/toolchain/biome.json +0 -31
  168. package/templates/react/base/toolchain/eslint.config.js +0 -5
  169. package/templates/react/base/toolchain/prettier.config.js +0 -10
  170. package/templates/react/base/tsconfig.json.ejs +0 -29
  171. package/templates/react/base/vite.config.js.ejs +0 -23
  172. package/templates/react/code-router/src/main.tsx.ejs +0 -92
  173. package/templates/react/example/tanchat/README.md +0 -37
  174. package/templates/react/example/tanchat/assets/_dot_env.local.append +0 -2
  175. package/templates/react/example/tanchat/assets/public/example-guitar-flowers.jpg +0 -0
  176. package/templates/react/example/tanchat/assets/public/example-guitar-motherboard.jpg +0 -0
  177. package/templates/react/example/tanchat/assets/public/example-guitar-racing.jpg +0 -0
  178. package/templates/react/example/tanchat/assets/public/example-guitar-steamer-trunk.jpg +0 -0
  179. package/templates/react/example/tanchat/assets/public/example-guitar-superhero.jpg +0 -0
  180. package/templates/react/example/tanchat/assets/public/example-guitar-traveling.jpg +0 -0
  181. package/templates/react/example/tanchat/assets/public/example-guitar-video-games.jpg +0 -0
  182. package/templates/react/example/tanchat/assets/src/components/example-AIAssistant.tsx +0 -173
  183. package/templates/react/example/tanchat/assets/src/components/example-GuitarRecommendation.tsx +0 -47
  184. package/templates/react/example/tanchat/assets/src/data/example-guitars.ts +0 -83
  185. package/templates/react/example/tanchat/assets/src/demo.index.css +0 -220
  186. package/templates/react/example/tanchat/assets/src/integrations/tanchat/header-user.tsx +0 -5
  187. package/templates/react/example/tanchat/assets/src/routes/api.messages.ts +0 -24
  188. package/templates/react/example/tanchat/assets/src/routes/api.sse.ts +0 -23
  189. package/templates/react/example/tanchat/assets/src/routes/example.chat.tsx +0 -159
  190. package/templates/react/example/tanchat/assets/src/routes/example.guitars/$guitarId.tsx +0 -50
  191. package/templates/react/example/tanchat/assets/src/routes/example.guitars/index.tsx +0 -54
  192. package/templates/react/example/tanchat/assets/src/store/example-assistant.ts +0 -3
  193. package/templates/react/example/tanchat/assets/src/utils/demo.ai.ts +0 -62
  194. package/templates/react/example/tanchat/assets/src/utils/demo.sse.ts +0 -31
  195. package/templates/react/example/tanchat/assets/src/utils/demo.tools.ts +0 -47
  196. package/templates/react/example/tanchat/info.json +0 -19
  197. package/templates/react/example/tanchat/package.json +0 -16
  198. package/templates/react/file-router/package.fr.json +0 -5
  199. package/templates/react/file-router/src/main.tsx.ejs +0 -55
  200. package/templates/react/file-router/src/routes/__root.tsx.ejs +0 -82
  201. package/templates/solid/add-on/form/assets/src/routes/demo.form.tsx.ejs +0 -352
  202. package/templates/solid/add-on/form/info.json +0 -13
  203. package/templates/solid/add-on/form/package.json +0 -5
  204. package/templates/solid/add-on/module-federation/assets/module-federation.config.js.ejs +0 -27
  205. package/templates/solid/add-on/module-federation/assets/src/demo-mf-component.tsx +0 -3
  206. package/templates/solid/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +0 -9
  207. package/templates/solid/add-on/module-federation/info.json +0 -7
  208. package/templates/solid/add-on/module-federation/package.json +0 -5
  209. package/templates/solid/add-on/sentry/assets/_dot_cursorrules.append +0 -22
  210. package/templates/solid/add-on/sentry/assets/_dot_env.local.append +0 -2
  211. package/templates/solid/add-on/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +0 -20
  212. package/templates/solid/add-on/sentry/info.json +0 -13
  213. package/templates/solid/add-on/sentry/package.json +0 -5
  214. package/templates/solid/add-on/solid-ui/README.md +0 -9
  215. package/templates/solid/add-on/solid-ui/assets/src/lib/utils.ts +0 -6
  216. package/templates/solid/add-on/solid-ui/assets/src/styles.css +0 -138
  217. package/templates/solid/add-on/solid-ui/assets/ui.config.json +0 -13
  218. package/templates/solid/add-on/solid-ui/info.json +0 -11
  219. package/templates/solid/add-on/solid-ui/package.json +0 -9
  220. package/templates/solid/add-on/start/assets/app.config.ts +0 -16
  221. package/templates/solid/add-on/start/assets/src/api.ts +0 -6
  222. package/templates/solid/add-on/start/assets/src/client.tsx +0 -7
  223. package/templates/solid/add-on/start/assets/src/router.tsx.ejs +0 -24
  224. package/templates/solid/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +0 -49
  225. package/templates/solid/add-on/start/assets/src/ssr.tsx +0 -12
  226. package/templates/solid/add-on/start/info.json +0 -14
  227. package/templates/solid/add-on/start/package.json +0 -12
  228. package/templates/solid/add-on/store/assets/src/lib/demo-store.ts +0 -13
  229. package/templates/solid/add-on/store/assets/src/routes/demo.store.tsx.ejs +0 -77
  230. package/templates/solid/add-on/store/info.json +0 -13
  231. package/templates/solid/add-on/store/package.json +0 -6
  232. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/header-user.tsx +0 -5
  233. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/provider.tsx +0 -15
  234. package/templates/solid/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx +0 -30
  235. package/templates/solid/add-on/tanstack-query/info.json +0 -13
  236. package/templates/solid/add-on/tanstack-query/package.json +0 -6
  237. package/templates/solid/base/README.md.ejs +0 -215
  238. package/templates/solid/base/_dot_cursorrules.append +0 -35
  239. package/templates/solid/base/_dot_gitignore +0 -5
  240. package/templates/solid/base/_dot_vscode/settings.biome.json +0 -38
  241. package/templates/solid/base/_dot_vscode/settings.json +0 -11
  242. package/templates/solid/base/index.html.ejs +0 -20
  243. package/templates/solid/base/package.biome.json +0 -10
  244. package/templates/solid/base/package.eslintprettier.json +0 -11
  245. package/templates/solid/base/package.json +0 -22
  246. package/templates/solid/base/package.ts.json +0 -5
  247. package/templates/solid/base/package.tw.json +0 -6
  248. package/templates/solid/base/public/favicon.ico +0 -0
  249. package/templates/solid/base/public/logo192.png +0 -0
  250. package/templates/solid/base/public/logo512.png +0 -0
  251. package/templates/solid/base/public/manifest.json +0 -25
  252. package/templates/solid/base/public/robots.txt +0 -3
  253. package/templates/solid/base/src/App.css +0 -0
  254. package/templates/solid/base/src/App.tsx.ejs +0 -47
  255. package/templates/solid/base/src/components/Header.tsx.ejs +0 -26
  256. package/templates/solid/base/src/logo.svg +0 -120
  257. package/templates/solid/base/src/styles.css.ejs +0 -15
  258. package/templates/solid/base/toolchain/.prettierignore +0 -3
  259. package/templates/solid/base/toolchain/biome.json +0 -31
  260. package/templates/solid/base/toolchain/eslint.config.js +0 -5
  261. package/templates/solid/base/toolchain/prettier.config.js +0 -10
  262. package/templates/solid/base/tsconfig.json.ejs +0 -31
  263. package/templates/solid/base/vite.config.js.ejs +0 -22
  264. package/templates/solid/code-router/src/main.tsx.ejs +0 -71
  265. package/templates/solid/example/tanchat/README.md +0 -52
  266. package/templates/solid/example/tanchat/assets/ai-streaming-server/README.md +0 -110
  267. package/templates/solid/example/tanchat/assets/ai-streaming-server/_dot_env.example +0 -1
  268. package/templates/solid/example/tanchat/assets/ai-streaming-server/package.json +0 -26
  269. package/templates/solid/example/tanchat/assets/ai-streaming-server/src/index.ts +0 -102
  270. package/templates/solid/example/tanchat/assets/ai-streaming-server/tsconfig.json +0 -15
  271. package/templates/solid/example/tanchat/assets/src/components/demo.SettingsDialog.tsx +0 -149
  272. package/templates/solid/example/tanchat/assets/src/demo.index.css +0 -227
  273. package/templates/solid/example/tanchat/assets/src/lib/demo-store.ts +0 -13
  274. package/templates/solid/example/tanchat/assets/src/routes/example.chat.tsx +0 -435
  275. package/templates/solid/example/tanchat/assets/src/store/demo.hooks.ts +0 -17
  276. package/templates/solid/example/tanchat/assets/src/store/demo.store.ts +0 -133
  277. package/templates/solid/example/tanchat/info.json +0 -14
  278. package/templates/solid/example/tanchat/package.json +0 -7
  279. package/templates/solid/file-router/package.fr.json +0 -5
  280. package/templates/solid/file-router/src/main.tsx.ejs +0 -47
  281. package/templates/solid/file-router/src/routes/__root.tsx.ejs +0 -41
  282. package/templates/solid/file-router/src/routes/index.tsx +0 -43
  283. package/tests/cra.test.ts +0 -293
  284. package/tests/snapshots/cra/cr-js-npm.json +0 -33
  285. package/tests/snapshots/cra/cr-ts-npm.json +0 -34
  286. package/tests/snapshots/cra/cr-ts-start-npm.json +0 -38
  287. package/tests/snapshots/cra/fr-ts-npm.json +0 -34
  288. package/tests/snapshots/cra/fr-ts-tw-npm.json +0 -33
  289. package/tests/snapshots/cra/solid-cr-js-npm.json +0 -31
  290. package/tests/snapshots/cra/solid-cr-ts-npm.json +0 -32
  291. package/tests/snapshots/cra/solid-cr-ts-start-npm.json +0 -36
  292. package/tests/snapshots/cra/solid-fr-ts-npm.json +0 -33
  293. package/tests/snapshots/cra/solid-fr-ts-tw-npm.json +0 -32
  294. package/tests/test-utilities.ts +0 -87
package/src/types.ts CHANGED
@@ -1,20 +1,93 @@
1
1
  import type { CODE_ROUTER, FILE_ROUTER } from './constants.js'
2
2
  import type { PackageManager } from './package-manager.js'
3
- import type { ToolChain } from './toolchain.js'
4
-
5
- export type Framework = 'solid' | 'react'
6
3
 
7
4
  export type TemplateOptions = 'typescript' | 'javascript' | 'file-router'
8
5
 
9
6
  export type Mode = typeof CODE_ROUTER | typeof FILE_ROUTER
10
7
 
8
+ export type FileBundleHandler = {
9
+ getFiles: () => Promise<Array<string>>
10
+ getFileContents: (path: string) => Promise<string>
11
+ }
12
+
13
+ export type AddOnDefinition = {
14
+ id: string
15
+ name: string
16
+ description: string
17
+ type: 'add-on' | 'example' | 'starter' | 'toolchain'
18
+ link: string
19
+ templates: Array<string>
20
+ routes?: Array<{
21
+ url: string
22
+ name: string
23
+ path: string
24
+ jsName: string
25
+ }>
26
+ packageAdditions: {
27
+ dependencies?: Record<string, string>
28
+ devDependencies?: Record<string, string>
29
+ scripts?: Record<string, string>
30
+ }
31
+ command?: {
32
+ command: string
33
+ args?: Array<string>
34
+ }
35
+ readme?: string
36
+ phase: 'setup' | 'add-on'
37
+ shadcnComponents?: Array<string>
38
+ warning?: string
39
+ dependsOn?: Array<string>
40
+ integrations?: Array<{
41
+ type: 'provider' | 'root-provider' | 'layout' | 'header-user'
42
+ path: string
43
+ jsName: string
44
+ }>
45
+ variables?: Array<Variable>
46
+
47
+ files?: Record<string, string>
48
+ deletedFiles?: Array<string>
49
+ }
50
+
51
+ export type StarterDefinition = AddOnDefinition & {
52
+ type: 'starter'
53
+ version: string
54
+ author: string
55
+ link: string
56
+ license: string
57
+ mode: Mode
58
+ framework: string
59
+ typescript: boolean
60
+ tailwind: boolean
61
+ }
62
+
63
+ export type AddOn = AddOnDefinition & FileBundleHandler
64
+ export type Starter = StarterDefinition & FileBundleHandler
65
+
66
+ export type FrameworkDefinition = {
67
+ id: string
68
+ name: string
69
+ description: string
70
+ version: string
71
+
72
+ baseDirectory: string
73
+ addOnsDirectories: Array<string>
74
+ examplesDirectory: string
75
+ }
76
+
77
+ export type Framework = FrameworkDefinition &
78
+ FileBundleHandler & {
79
+ basePackageJSON: Record<string, any>
80
+ optionalPackages: Record<string, any>
81
+
82
+ getAddOns: () => Array<AddOn>
83
+ }
84
+
11
85
  export interface Options {
12
86
  framework: Framework
13
87
  projectName: string
14
88
  typescript: boolean
15
89
  tailwind: boolean
16
90
  packageManager: PackageManager
17
- toolchain: ToolChain
18
91
  mode: Mode
19
92
  addOns: boolean
20
93
  chosenAddOns: Array<AddOn>
@@ -23,39 +96,38 @@ export interface Options {
23
96
  starter?: AddOn | undefined
24
97
  }
25
98
 
26
- export interface CliOptions {
27
- template?: TemplateOptions
28
- framework?: Framework
29
- tailwind?: boolean
30
- packageManager?: PackageManager
31
- toolchain?: ToolChain
32
- projectName?: string
33
- git?: boolean
34
- addOns?: Array<string> | boolean
35
- listAddOns?: boolean
36
- mcp?: boolean
37
- mcpSse?: boolean
38
- starter?: string
39
- targetDir?: string
40
- }
41
-
42
- export type Environment = {
99
+ type ProjectEnvironment = {
43
100
  startRun: () => void
44
101
  finishRun: () => void
45
102
  getErrors: () => Array<string>
103
+ }
46
104
 
105
+ type FileEnvironment = {
47
106
  appendFile: (path: string, contents: string) => Promise<void>
48
107
  copyFile: (from: string, to: string) => Promise<void>
49
108
  writeFile: (path: string, contents: string) => Promise<void>
50
109
  execute: (command: string, args: Array<string>, cwd: string) => Promise<void>
51
110
  deleteFile: (path: string) => Promise<void>
52
-
53
- readFile: (path: string, encoding?: BufferEncoding) => Promise<string>
54
111
  exists: (path: string) => boolean
55
- readdir: (path: string) => Array<string>
56
- isDirectory: (path: string) => boolean
57
112
  }
58
113
 
114
+ type UIEnvironment = {
115
+ intro: (message: string) => void
116
+ outro: (message: string) => void
117
+
118
+ info: (title?: string, message?: string) => void
119
+ error: (title?: string, message?: string) => void
120
+ warn: (title?: string, message?: string) => void
121
+
122
+ spinner: () => {
123
+ start: (message: string) => void
124
+ stop: (message: string) => void
125
+ }
126
+ confirm: (message: string) => Promise<boolean>
127
+ }
128
+
129
+ export type Environment = ProjectEnvironment & FileEnvironment & UIEnvironment
130
+
59
131
  type BooleanVariable = {
60
132
  name: string
61
133
  default: boolean
@@ -78,46 +150,3 @@ type StringVariable = {
78
150
  }
79
151
 
80
152
  export type Variable = BooleanVariable | NumberVariable | StringVariable
81
-
82
- export type AddOn = {
83
- id: string
84
- name: string
85
- description: string
86
- type: 'add-on' | 'example' | 'starter'
87
- link: string
88
- templates: Array<string>
89
- routes: Array<{
90
- url: string
91
- name: string
92
- }>
93
- packageAdditions: {
94
- dependencies?: Record<string, string>
95
- devDependencies?: Record<string, string>
96
- scripts?: Record<string, string>
97
- }
98
- command?: {
99
- command: string
100
- args?: Array<string>
101
- }
102
- readme?: string
103
- phase: 'setup' | 'add-on'
104
- shadcnComponents?: Array<string>
105
- warning?: string
106
- dependsOn?: Array<string>
107
- variables?: Array<Variable>
108
-
109
- files?: Record<string, string>
110
- deletedFiles?: Array<string>
111
- }
112
-
113
- export type Starter = AddOn & {
114
- type: 'starter'
115
- version: string
116
- author: string
117
- link: string
118
- license: string
119
- mode: Mode
120
- framework: Framework
121
- typescript: boolean
122
- tailwind: boolean
123
- }
package/src/utils.ts CHANGED
@@ -8,3 +8,20 @@ export function sortObject(
8
8
  return acc
9
9
  }, {})
10
10
  }
11
+
12
+ export function jsSafeName(name: string) {
13
+ return name
14
+ .split(/[^a-zA-Z0-9]/)
15
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
16
+ .join('')
17
+ }
18
+
19
+ export function formatCommand({
20
+ command,
21
+ args,
22
+ }: {
23
+ command: string
24
+ args: Array<string>
25
+ }) {
26
+ return `${command} ${args.join(' ')}`.trim()
27
+ }
@@ -0,0 +1,37 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { relativePath } from '../src/file-helpers.js'
4
+
5
+ describe('relativePath', () => {
6
+ it('relative path with the same directory', () => {
7
+ expect(relativePath('src/utils.ts', 'src/index.ts')).toBe('./index.ts')
8
+ })
9
+ it('relative from a subdirectory', () => {
10
+ expect(relativePath('src/something/utils.ts', 'src/index.ts')).toBe(
11
+ '../index.ts',
12
+ )
13
+ })
14
+ it('relative to a subdirectory', () => {
15
+ expect(relativePath('src/utils.ts', 'src/something/index.ts')).toBe(
16
+ './something/index.ts',
17
+ )
18
+ })
19
+ it('same deep directory', () => {
20
+ expect(
21
+ relativePath('src/foo/bar/baz/utils.ts', 'src/foo/bar/baz/index.ts'),
22
+ ).toBe('./index.ts')
23
+ })
24
+ it('up several levels and down several levels', () => {
25
+ expect(relativePath('src/bar/baz/utils.ts', 'src/foo/bar/index.ts')).toBe(
26
+ '../../foo/bar/index.ts',
27
+ )
28
+ })
29
+ it('relative path with a different directory', () => {
30
+ expect(
31
+ relativePath(
32
+ './src/routes/__root.tsx.ejs',
33
+ 'src/integrations/tanstack-query/layout.tsx',
34
+ ),
35
+ ).toBe('../integrations/tanstack-query/layout.tsx')
36
+ })
37
+ })
@@ -0,0 +1,154 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import {
4
+ getPackageManagerExecuteCommand,
5
+ getPackageManagerInstallCommand,
6
+ getPackageManagerScriptCommand,
7
+ } from '../src/package-manager.js'
8
+ import { formatCommand } from '../src/utils.js'
9
+
10
+ describe('getPackageManagerScriptCommand', () => {
11
+ it('yarn', () => {
12
+ expect(formatCommand(getPackageManagerScriptCommand('yarn', ['dev']))).toBe(
13
+ 'yarn run dev',
14
+ )
15
+ })
16
+ it('pnpm', () => {
17
+ expect(formatCommand(getPackageManagerScriptCommand('pnpm', ['dev']))).toBe(
18
+ 'pnpm dev',
19
+ )
20
+ })
21
+ it('bun', () => {
22
+ expect(formatCommand(getPackageManagerScriptCommand('bun', ['dev']))).toBe(
23
+ 'bunx --bun run dev',
24
+ )
25
+ })
26
+ it('deno', () => {
27
+ expect(formatCommand(getPackageManagerScriptCommand('deno', ['dev']))).toBe(
28
+ 'deno task dev',
29
+ )
30
+ })
31
+ it('npm', () => {
32
+ expect(formatCommand(getPackageManagerScriptCommand('npm', ['dev']))).toBe(
33
+ 'npm run dev',
34
+ )
35
+ })
36
+ })
37
+
38
+ describe('getPackageManagerExecuteCommand', () => {
39
+ it('yarn', () => {
40
+ expect(
41
+ formatCommand(
42
+ getPackageManagerExecuteCommand('yarn', 'shadcn', ['add', 'button']),
43
+ ),
44
+ ).toBe('yarn dlx shadcn add button')
45
+ })
46
+ it('pnpm', () => {
47
+ expect(
48
+ formatCommand(
49
+ getPackageManagerExecuteCommand('pnpm', 'shadcn', ['add', 'button']),
50
+ ),
51
+ ).toBe('pnpx shadcn add button')
52
+ })
53
+ it('bun', () => {
54
+ expect(
55
+ formatCommand(
56
+ getPackageManagerExecuteCommand('bun', 'shadcn', ['add', 'button']),
57
+ ),
58
+ ).toBe('bunx --bun shadcn add button')
59
+ })
60
+ it('deno', () => {
61
+ expect(
62
+ formatCommand(
63
+ getPackageManagerExecuteCommand('deno', 'shadcn', ['add', 'button']),
64
+ ),
65
+ ).toBe('deno run npm:shadcn add button')
66
+ })
67
+ it('npm', () => {
68
+ expect(
69
+ formatCommand(
70
+ getPackageManagerExecuteCommand('npm', 'shadcn', ['add', 'button']),
71
+ ),
72
+ ).toBe('npx shadcn add button')
73
+ })
74
+ })
75
+
76
+ describe('getPackageManagerInstallCommand', () => {
77
+ it('yarn install', () => {
78
+ expect(formatCommand(getPackageManagerInstallCommand('yarn'))).toBe(
79
+ 'yarn install',
80
+ )
81
+ })
82
+ it('pnpm install', () => {
83
+ expect(formatCommand(getPackageManagerInstallCommand('pnpm'))).toBe(
84
+ 'pnpm install',
85
+ )
86
+ })
87
+ it('bun install', () => {
88
+ expect(formatCommand(getPackageManagerInstallCommand('bun'))).toBe(
89
+ 'bun install',
90
+ )
91
+ })
92
+ it('deno install', () => {
93
+ expect(formatCommand(getPackageManagerInstallCommand('deno'))).toBe(
94
+ 'deno install',
95
+ )
96
+ })
97
+ it('npm install', () => {
98
+ expect(formatCommand(getPackageManagerInstallCommand('npm'))).toBe(
99
+ 'npm install',
100
+ )
101
+ })
102
+
103
+ it('yarn install radix-ui', () => {
104
+ expect(
105
+ formatCommand(getPackageManagerInstallCommand('yarn', 'radix-ui')),
106
+ ).toBe('yarn add radix-ui')
107
+ })
108
+ it('pnpm install radix-ui', () => {
109
+ expect(
110
+ formatCommand(getPackageManagerInstallCommand('pnpm', 'radix-ui')),
111
+ ).toBe('pnpm add radix-ui')
112
+ })
113
+ it('bun install radix-ui', () => {
114
+ expect(
115
+ formatCommand(getPackageManagerInstallCommand('bun', 'radix-ui')),
116
+ ).toBe('bun install radix-ui')
117
+ })
118
+ it('deno install radix-ui', () => {
119
+ expect(
120
+ formatCommand(getPackageManagerInstallCommand('deno', 'radix-ui')),
121
+ ).toBe('deno install radix-ui')
122
+ })
123
+ it('npm install radix-ui', () => {
124
+ expect(
125
+ formatCommand(getPackageManagerInstallCommand('npm', 'radix-ui')),
126
+ ).toBe('npm install radix-ui')
127
+ })
128
+
129
+ it('yarn install vitest in dev mode', () => {
130
+ expect(
131
+ formatCommand(getPackageManagerInstallCommand('yarn', 'vitest', true)),
132
+ ).toBe('yarn add vitest --dev')
133
+ })
134
+ it('pnpm install vitest in dev mode', () => {
135
+ expect(
136
+ formatCommand(getPackageManagerInstallCommand('pnpm', 'vitest', true)),
137
+ ).toBe('pnpm add vitest --dev')
138
+ })
139
+ it('bun install vitest in dev mode', () => {
140
+ expect(
141
+ formatCommand(getPackageManagerInstallCommand('bun', 'vitest', true)),
142
+ ).toBe('bun install vitest -D')
143
+ })
144
+ it('deno install vitest in dev mode', () => {
145
+ expect(
146
+ formatCommand(getPackageManagerInstallCommand('deno', 'vitest', true)),
147
+ ).toBe('deno install vitest -D')
148
+ })
149
+ it('npm install vitest in dev mode', () => {
150
+ expect(
151
+ formatCommand(getPackageManagerInstallCommand('npm', 'vitest', true)),
152
+ ).toBe('npm install vitest -D')
153
+ })
154
+ })
package/dist/cli.js DELETED
@@ -1,126 +0,0 @@
1
- import { Command, InvalidArgumentError } from 'commander';
2
- import { intro, log } from '@clack/prompts';
3
- import { createApp } from './create-app.js';
4
- import { normalizeOptions, promptForOptions } from './options.js';
5
- import { SUPPORTED_PACKAGE_MANAGERS } from './package-manager.js';
6
- import { SUPPORTED_TOOLCHAINS } from './toolchain.js';
7
- import runServer from './mcp.js';
8
- import { listAddOns } from './add-ons.js';
9
- import { DEFAULT_FRAMEWORK, SUPPORTED_FRAMEWORKS } from './constants.js';
10
- import { initAddOn } from './custom-add-on.js';
11
- import { createDefaultEnvironment } from './environment.js';
12
- import { add } from './add.js';
13
- export function cli({ name, appName, forcedMode, forcedAddOns, }) {
14
- const program = new Command();
15
- program.name(name).description(`CLI to create a new ${appName} application`);
16
- program
17
- .command('add')
18
- .argument('add-on', 'Name of the add-on (or add-ons separated by commas)')
19
- .action(async (addOn) => {
20
- await add(addOn.split(',').map((addon) => addon.trim()));
21
- });
22
- program
23
- .command('update-add-on')
24
- .description('Create or update an add-on from the current project')
25
- .action(async () => {
26
- await initAddOn('add-on');
27
- });
28
- program
29
- .command('update-starter')
30
- .description('Create or update a project starter from the current project')
31
- .action(async () => {
32
- await initAddOn('starter');
33
- });
34
- program.argument('[project-name]', 'name of the project');
35
- if (!forcedMode) {
36
- program.option('--template <type>', 'project template (typescript, javascript, file-router)', (value) => {
37
- if (value !== 'typescript' &&
38
- value !== 'javascript' &&
39
- value !== 'file-router') {
40
- throw new InvalidArgumentError(`Invalid template: ${value}. Only the following are allowed: typescript, javascript, file-router`);
41
- }
42
- return value;
43
- });
44
- }
45
- program
46
- .option('--framework <type>', 'project framework (solid, react)', (value) => {
47
- if (!SUPPORTED_FRAMEWORKS.includes(value)) {
48
- throw new InvalidArgumentError(`Invalid framework: ${value}. Only the following are allowed: ${SUPPORTED_FRAMEWORKS.join(', ')}`);
49
- }
50
- return value;
51
- }, DEFAULT_FRAMEWORK)
52
- .option('--starter [url]', 'initialize this project from a starter URL', false)
53
- .option(`--package-manager <${SUPPORTED_PACKAGE_MANAGERS.join('|')}>`, `Explicitly tell the CLI to use this package manager`, (value) => {
54
- if (!SUPPORTED_PACKAGE_MANAGERS.includes(value)) {
55
- throw new InvalidArgumentError(`Invalid package manager: ${value}. The following are allowed: ${SUPPORTED_PACKAGE_MANAGERS.join(', ')}`);
56
- }
57
- return value;
58
- })
59
- .option(`--toolchain <${SUPPORTED_TOOLCHAINS.join('|')}>`, `Explicitly tell the CLI to use this toolchain`, (value) => {
60
- if (!SUPPORTED_TOOLCHAINS.includes(value)) {
61
- throw new InvalidArgumentError(`Invalid toolchain: ${value}. The following are allowed: ${SUPPORTED_TOOLCHAINS.join(', ')}`);
62
- }
63
- return value;
64
- })
65
- .option('--tailwind', 'add Tailwind CSS', false)
66
- .option('--add-ons [...add-ons]', 'pick from a list of available add-ons (comma separated list)', (value) => {
67
- let addOns = !!value;
68
- if (typeof value === 'string') {
69
- addOns = value.split(',').map((addon) => addon.trim());
70
- }
71
- return addOns;
72
- })
73
- .option('--list-add-ons', 'list all available add-ons', false)
74
- .option('--no-git', 'do not create a git repository')
75
- .option('--target-dir <path>', 'the target directory for the application root')
76
- .option('--mcp', 'run the MCP server', false)
77
- .option('--mcp-sse', 'run the MCP server in SSE mode', false);
78
- program.action(async (projectName, options) => {
79
- if (options.listAddOns) {
80
- await listAddOns(options, {
81
- forcedMode,
82
- forcedAddOns,
83
- });
84
- }
85
- else if (options.mcp || options.mcpSse) {
86
- await runServer(!!options.mcpSse, {
87
- forcedMode,
88
- forcedAddOns,
89
- appName,
90
- });
91
- }
92
- else {
93
- try {
94
- const cliOptions = {
95
- projectName,
96
- ...options,
97
- };
98
- if (forcedMode) {
99
- cliOptions.template = forcedMode;
100
- }
101
- let finalOptions = await normalizeOptions(cliOptions, forcedAddOns);
102
- if (finalOptions) {
103
- intro(`Creating a new ${appName} app in ${projectName}...`);
104
- }
105
- else {
106
- intro(`Let's configure your ${appName} application`);
107
- finalOptions = await promptForOptions(cliOptions, {
108
- forcedMode,
109
- forcedAddOns,
110
- });
111
- }
112
- await createApp(finalOptions, {
113
- environment: createDefaultEnvironment(),
114
- cwd: options.targetDir || undefined,
115
- name,
116
- appName,
117
- });
118
- }
119
- catch (error) {
120
- log.error(error instanceof Error ? error.message : 'An unknown error occurred');
121
- process.exit(1);
122
- }
123
- }
124
- });
125
- program.parse();
126
- }