@tanstack/cta-engine 0.10.0-alpha.14 → 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 (291) 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 +10 -1
  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 +13 -1
  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 +86 -64
  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 +42 -1
  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 +101 -70
  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 -254
  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 -3
  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 -189
  65. package/src/custom-add-on.ts +0 -325
  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/example.chat.tsx +0 -159
  188. package/templates/react/example/tanchat/assets/src/routes/example.guitars/$guitarId.tsx +0 -50
  189. package/templates/react/example/tanchat/assets/src/routes/example.guitars/index.tsx +0 -54
  190. package/templates/react/example/tanchat/assets/src/store/example-assistant.ts +0 -3
  191. package/templates/react/example/tanchat/assets/src/utils/demo.ai.ts +0 -62
  192. package/templates/react/example/tanchat/assets/src/utils/demo.tools.ts +0 -47
  193. package/templates/react/example/tanchat/info.json +0 -19
  194. package/templates/react/example/tanchat/package.json +0 -15
  195. package/templates/react/file-router/package.fr.json +0 -5
  196. package/templates/react/file-router/src/main.tsx.ejs +0 -55
  197. package/templates/react/file-router/src/routes/__root.tsx.ejs +0 -82
  198. package/templates/solid/add-on/form/assets/src/routes/demo.form.tsx.ejs +0 -352
  199. package/templates/solid/add-on/form/info.json +0 -13
  200. package/templates/solid/add-on/form/package.json +0 -5
  201. package/templates/solid/add-on/module-federation/assets/module-federation.config.js.ejs +0 -27
  202. package/templates/solid/add-on/module-federation/assets/src/demo-mf-component.tsx +0 -3
  203. package/templates/solid/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +0 -9
  204. package/templates/solid/add-on/module-federation/info.json +0 -7
  205. package/templates/solid/add-on/module-federation/package.json +0 -5
  206. package/templates/solid/add-on/sentry/assets/_dot_cursorrules.append +0 -22
  207. package/templates/solid/add-on/sentry/assets/_dot_env.local.append +0 -2
  208. package/templates/solid/add-on/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +0 -20
  209. package/templates/solid/add-on/sentry/info.json +0 -13
  210. package/templates/solid/add-on/sentry/package.json +0 -5
  211. package/templates/solid/add-on/solid-ui/README.md +0 -9
  212. package/templates/solid/add-on/solid-ui/assets/src/lib/utils.ts +0 -6
  213. package/templates/solid/add-on/solid-ui/assets/src/styles.css +0 -138
  214. package/templates/solid/add-on/solid-ui/assets/ui.config.json +0 -13
  215. package/templates/solid/add-on/solid-ui/info.json +0 -11
  216. package/templates/solid/add-on/solid-ui/package.json +0 -9
  217. package/templates/solid/add-on/start/assets/app.config.ts +0 -16
  218. package/templates/solid/add-on/start/assets/src/api.ts +0 -6
  219. package/templates/solid/add-on/start/assets/src/client.tsx +0 -7
  220. package/templates/solid/add-on/start/assets/src/router.tsx.ejs +0 -24
  221. package/templates/solid/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +0 -49
  222. package/templates/solid/add-on/start/assets/src/ssr.tsx +0 -12
  223. package/templates/solid/add-on/start/info.json +0 -14
  224. package/templates/solid/add-on/start/package.json +0 -12
  225. package/templates/solid/add-on/store/assets/src/lib/demo-store.ts +0 -13
  226. package/templates/solid/add-on/store/assets/src/routes/demo.store.tsx.ejs +0 -77
  227. package/templates/solid/add-on/store/info.json +0 -13
  228. package/templates/solid/add-on/store/package.json +0 -6
  229. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/header-user.tsx +0 -5
  230. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/provider.tsx +0 -15
  231. package/templates/solid/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx +0 -30
  232. package/templates/solid/add-on/tanstack-query/info.json +0 -13
  233. package/templates/solid/add-on/tanstack-query/package.json +0 -6
  234. package/templates/solid/base/README.md.ejs +0 -215
  235. package/templates/solid/base/_dot_cursorrules.append +0 -35
  236. package/templates/solid/base/_dot_gitignore +0 -5
  237. package/templates/solid/base/_dot_vscode/settings.biome.json +0 -38
  238. package/templates/solid/base/_dot_vscode/settings.json +0 -11
  239. package/templates/solid/base/index.html.ejs +0 -20
  240. package/templates/solid/base/package.biome.json +0 -10
  241. package/templates/solid/base/package.eslintprettier.json +0 -11
  242. package/templates/solid/base/package.json +0 -22
  243. package/templates/solid/base/package.ts.json +0 -5
  244. package/templates/solid/base/package.tw.json +0 -6
  245. package/templates/solid/base/public/favicon.ico +0 -0
  246. package/templates/solid/base/public/logo192.png +0 -0
  247. package/templates/solid/base/public/logo512.png +0 -0
  248. package/templates/solid/base/public/manifest.json +0 -25
  249. package/templates/solid/base/public/robots.txt +0 -3
  250. package/templates/solid/base/src/App.css +0 -0
  251. package/templates/solid/base/src/App.tsx.ejs +0 -47
  252. package/templates/solid/base/src/components/Header.tsx.ejs +0 -26
  253. package/templates/solid/base/src/logo.svg +0 -120
  254. package/templates/solid/base/src/styles.css.ejs +0 -15
  255. package/templates/solid/base/toolchain/.prettierignore +0 -3
  256. package/templates/solid/base/toolchain/biome.json +0 -31
  257. package/templates/solid/base/toolchain/eslint.config.js +0 -5
  258. package/templates/solid/base/toolchain/prettier.config.js +0 -10
  259. package/templates/solid/base/tsconfig.json.ejs +0 -31
  260. package/templates/solid/base/vite.config.js.ejs +0 -22
  261. package/templates/solid/code-router/src/main.tsx.ejs +0 -71
  262. package/templates/solid/example/tanchat/README.md +0 -52
  263. package/templates/solid/example/tanchat/assets/ai-streaming-server/README.md +0 -110
  264. package/templates/solid/example/tanchat/assets/ai-streaming-server/_dot_env.example +0 -1
  265. package/templates/solid/example/tanchat/assets/ai-streaming-server/package.json +0 -26
  266. package/templates/solid/example/tanchat/assets/ai-streaming-server/src/index.ts +0 -102
  267. package/templates/solid/example/tanchat/assets/ai-streaming-server/tsconfig.json +0 -15
  268. package/templates/solid/example/tanchat/assets/src/components/demo.SettingsDialog.tsx +0 -149
  269. package/templates/solid/example/tanchat/assets/src/demo.index.css +0 -227
  270. package/templates/solid/example/tanchat/assets/src/lib/demo-store.ts +0 -13
  271. package/templates/solid/example/tanchat/assets/src/routes/example.chat.tsx +0 -435
  272. package/templates/solid/example/tanchat/assets/src/store/demo.hooks.ts +0 -17
  273. package/templates/solid/example/tanchat/assets/src/store/demo.store.ts +0 -133
  274. package/templates/solid/example/tanchat/info.json +0 -14
  275. package/templates/solid/example/tanchat/package.json +0 -7
  276. package/templates/solid/file-router/package.fr.json +0 -5
  277. package/templates/solid/file-router/src/main.tsx.ejs +0 -47
  278. package/templates/solid/file-router/src/routes/__root.tsx.ejs +0 -41
  279. package/templates/solid/file-router/src/routes/index.tsx +0 -43
  280. package/tests/cra.test.ts +0 -293
  281. package/tests/snapshots/cra/cr-js-npm.json +0 -33
  282. package/tests/snapshots/cra/cr-ts-npm.json +0 -34
  283. package/tests/snapshots/cra/cr-ts-start-npm.json +0 -38
  284. package/tests/snapshots/cra/fr-ts-npm.json +0 -34
  285. package/tests/snapshots/cra/fr-ts-tw-npm.json +0 -33
  286. package/tests/snapshots/cra/solid-cr-js-npm.json +0 -31
  287. package/tests/snapshots/cra/solid-cr-ts-npm.json +0 -32
  288. package/tests/snapshots/cra/solid-cr-ts-start-npm.json +0 -36
  289. package/tests/snapshots/cra/solid-fr-ts-npm.json +0 -33
  290. package/tests/snapshots/cra/solid-fr-ts-tw-npm.json +0 -32
  291. package/tests/test-utilities.ts +0 -87
package/src/types.ts CHANGED
@@ -1,59 +1,133 @@
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
 
6
+ export type Mode = typeof CODE_ROUTER | typeof FILE_ROUTER
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
+
9
85
  export interface Options {
10
86
  framework: Framework
11
87
  projectName: string
12
88
  typescript: boolean
13
89
  tailwind: boolean
14
90
  packageManager: PackageManager
15
- toolchain: ToolChain
16
- mode: typeof CODE_ROUTER | typeof FILE_ROUTER
91
+ mode: Mode
17
92
  addOns: boolean
18
93
  chosenAddOns: Array<AddOn>
19
94
  git: boolean
20
95
  variableValues: Record<string, string | number | boolean>
21
- overlay?: AddOn | undefined
22
- }
23
-
24
- export interface CliOptions {
25
- template?: TemplateOptions
26
- framework?: Framework
27
- tailwind?: boolean
28
- packageManager?: PackageManager
29
- toolchain?: ToolChain
30
- projectName?: string
31
- git?: boolean
32
- addOns?: Array<string> | boolean
33
- listAddOns?: boolean
34
- mcp?: boolean
35
- mcpSse?: boolean
36
- overlay?: string
37
- targetDir?: string
96
+ starter?: AddOn | undefined
38
97
  }
39
98
 
40
- export type Environment = {
99
+ type ProjectEnvironment = {
41
100
  startRun: () => void
42
101
  finishRun: () => void
43
102
  getErrors: () => Array<string>
103
+ }
44
104
 
105
+ type FileEnvironment = {
45
106
  appendFile: (path: string, contents: string) => Promise<void>
46
107
  copyFile: (from: string, to: string) => Promise<void>
47
108
  writeFile: (path: string, contents: string) => Promise<void>
48
109
  execute: (command: string, args: Array<string>, cwd: string) => Promise<void>
49
110
  deleteFile: (path: string) => Promise<void>
50
-
51
- readFile: (path: string, encoding?: BufferEncoding) => Promise<string>
52
111
  exists: (path: string) => boolean
53
- readdir: (path: string) => Array<string>
54
- isDirectory: (path: string) => boolean
55
112
  }
56
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
+
57
131
  type BooleanVariable = {
58
132
  name: string
59
133
  default: boolean
@@ -76,46 +150,3 @@ type StringVariable = {
76
150
  }
77
151
 
78
152
  export type Variable = BooleanVariable | NumberVariable | StringVariable
79
-
80
- export type AddOn = {
81
- id: string
82
- name: string
83
- description: string
84
- type: 'add-on' | 'example' | 'overlay'
85
- link: string
86
- templates: Array<string>
87
- routes: Array<{
88
- url: string
89
- name: string
90
- }>
91
- packageAdditions: {
92
- dependencies?: Record<string, string>
93
- devDependencies?: Record<string, string>
94
- scripts?: Record<string, string>
95
- }
96
- command?: {
97
- command: string
98
- args?: Array<string>
99
- }
100
- readme?: string
101
- phase: 'setup' | 'add-on'
102
- shadcnComponents?: Array<string>
103
- warning?: string
104
- dependsOn?: Array<string>
105
- variables?: Array<Variable>
106
-
107
- files?: Record<string, string>
108
- deletedFiles?: Array<string>
109
- }
110
-
111
- export type Overlay = AddOn & {
112
- type: 'overlay'
113
- version: string
114
- author: string
115
- link: string
116
- license: string
117
- mode: typeof CODE_ROUTER | typeof FILE_ROUTER
118
- framework: Framework
119
- typescript: boolean
120
- tailwind: boolean
121
- }
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-overlay')
30
- .description('Create or update a project overlay from the current project')
31
- .action(async () => {
32
- await initAddOn('overlay');
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('--overlay [url]', 'add an overlay from a 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 directory to create the project in')
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
- }