@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
@@ -0,0 +1,59 @@
1
+ import { readFileSync, readdirSync, statSync } from 'node:fs';
2
+ import { basename, extname, resolve } from 'node:path';
3
+ const BINARY_EXTENSIONS = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico'];
4
+ export function readFileHelper(path) {
5
+ if (BINARY_EXTENSIONS.includes(extname(path))) {
6
+ return `base64::${readFileSync(path).toString('base64')}`;
7
+ }
8
+ else {
9
+ return readFileSync(path, 'utf-8').toString();
10
+ }
11
+ }
12
+ export function getBinaryFile(content) {
13
+ if (content.startsWith('base64::')) {
14
+ const binaryContent = Buffer.from(content.replace('base64::', ''), 'base64');
15
+ return binaryContent;
16
+ }
17
+ return null;
18
+ }
19
+ export function relativePath(from, to) {
20
+ const cleanedFrom = from.startsWith('./') ? from.slice(2) : from;
21
+ const cleanedTo = to.startsWith('./') ? to.slice(2) : to;
22
+ const fromSegments = cleanedFrom.split('/');
23
+ const toSegments = cleanedTo.split('/');
24
+ fromSegments.pop();
25
+ toSegments.pop();
26
+ let commonIndex = 0;
27
+ while (commonIndex < fromSegments.length &&
28
+ commonIndex < toSegments.length &&
29
+ fromSegments[commonIndex] === toSegments[commonIndex]) {
30
+ commonIndex++;
31
+ }
32
+ const upLevels = fromSegments.length - commonIndex;
33
+ const downLevels = toSegments.slice(commonIndex);
34
+ if (upLevels === 0 && downLevels.length === 0) {
35
+ return `./${basename(to)}`;
36
+ }
37
+ else if (upLevels === 0 && downLevels.length > 0) {
38
+ return `./${downLevels.join('/')}/${basename(to)}`;
39
+ }
40
+ else {
41
+ const relativePath = [...Array(upLevels).fill('..'), ...downLevels].join('/');
42
+ return `${relativePath}/${basename(to)}`;
43
+ }
44
+ }
45
+ export function isDirectory(path) {
46
+ return statSync(path).isDirectory();
47
+ }
48
+ export function findFilesRecursively(path, files) {
49
+ const dirFiles = readdirSync(path);
50
+ for (const file of dirFiles) {
51
+ const filePath = resolve(path, file);
52
+ if (isDirectory(filePath)) {
53
+ findFilesRecursively(filePath, files);
54
+ }
55
+ else {
56
+ files[filePath] = readFileHelper(filePath);
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,78 @@
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
+ const absoluteFiles = {};
21
+ const assetsDir = resolve(addOnsBase, dir, 'assets');
22
+ if (existsSync(assetsDir)) {
23
+ findFilesRecursively(assetsDir, absoluteFiles);
24
+ }
25
+ const files = {};
26
+ for (const file of Object.keys(absoluteFiles)) {
27
+ files[file.replace(assetsDir, '.')] = readFileHelper(file);
28
+ }
29
+ const getFiles = () => {
30
+ return Promise.resolve(Object.keys(files));
31
+ };
32
+ const getFileContents = (path) => {
33
+ return Promise.resolve(files[path]);
34
+ };
35
+ addOns.push({
36
+ ...info,
37
+ id: dir,
38
+ packageAdditions,
39
+ readme,
40
+ files,
41
+ deletedFiles: [],
42
+ getFiles,
43
+ getFileContents,
44
+ });
45
+ }
46
+ }
47
+ return addOns;
48
+ }
49
+ export function registerFramework(framework) {
50
+ const baseAssetsDirectory = resolve(framework.baseDirectory, 'base');
51
+ const basePackageJSON = JSON.parse(readFileSync(resolve(baseAssetsDirectory, 'package.json'), 'utf8'));
52
+ const optionalPackages = JSON.parse(readFileSync(resolve(framework.baseDirectory, 'packages.json'), 'utf8'));
53
+ const addOns = getAddOns(framework);
54
+ const frameworkWithBundler = {
55
+ ...framework,
56
+ getFiles: () => {
57
+ const files = {};
58
+ findFilesRecursively(baseAssetsDirectory, files);
59
+ return Promise.resolve(Object.keys(files).map((path) => path.replace(baseAssetsDirectory, '.')));
60
+ },
61
+ getFileContents: (path) => {
62
+ return Promise.resolve(readFileHelper(resolve(baseAssetsDirectory, path)));
63
+ },
64
+ basePackageJSON,
65
+ optionalPackages,
66
+ getAddOns: () => addOns,
67
+ };
68
+ frameworks.push(frameworkWithBundler);
69
+ }
70
+ export function getFrameworkById(id) {
71
+ return frameworks.find((framework) => framework.id === id);
72
+ }
73
+ export function getFrameworkByName(name) {
74
+ return frameworks.find((framework) => framework.name === name);
75
+ }
76
+ export function getFrameworks() {
77
+ return frameworks;
78
+ }
package/dist/index.js CHANGED
@@ -1,5 +1,10 @@
1
- export { cli } from './cli.js';
2
- export { getAllAddOns } from './add-ons.js';
3
1
  export { createApp } from './create-app.js';
4
- export { createAppOptionsFromPersisted } from './custom-add-on.js';
2
+ export { addToApp } from './add-to-app.js';
3
+ export { finalizeAddOns, getAllAddOns, loadRemoteAddOn } from './add-ons.js';
5
4
  export { createMemoryEnvironment, createDefaultEnvironment, } from './environment.js';
5
+ export { CODE_ROUTER, CONFIG_FILE, FILE_ROUTER } from './constants.js';
6
+ export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, getPackageManagerInstallCommand, getPackageManagerExecuteCommand, getPackageManagerScriptCommand, packageManagerInstall, packageManagerExecute, } from './package-manager.js';
7
+ export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, } from './frameworks.js';
8
+ export { formatCommand, jsSafeName, sortObject } from './utils.js';
9
+ export { writeConfigFile, readConfigFile } from './config-file.js';
10
+ export { readFileHelper, getBinaryFile, relativePath } from './file-helpers.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,27 @@
1
+ import { resolve } from 'node:path';
2
+ import { packageManagerExecute } from '../package-manager.js';
3
+ export async function installShadcnComponents(environment, targetDir, options, silent) {
4
+ const s = silent ? null : 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
+ await packageManagerExecute(environment, resolve(targetDir), options.packageManager, 'shadcn@latest', ['add', '--silent', '--yes', ...Array.from(shadcnComponents)]);
24
+ s?.stop(`Installed additional shadcn components`);
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,46 @@
1
+ import { FILE_ROUTER } from './constants.js';
2
+ import { sortObject } from './utils.js';
3
+ function mergePackageJSON(packageJSON, overlayPackageJSON) {
4
+ return {
5
+ ...packageJSON,
6
+ dependencies: {
7
+ ...packageJSON.dependencies,
8
+ ...overlayPackageJSON.dependencies,
9
+ },
10
+ devDependencies: {
11
+ ...packageJSON.devDependencies,
12
+ ...overlayPackageJSON.devDependencies,
13
+ },
14
+ scripts: {
15
+ ...packageJSON.scripts,
16
+ ...overlayPackageJSON.scripts,
17
+ },
18
+ };
19
+ }
20
+ export function createPackageJSON(options) {
21
+ const addOns = options.chosenAddOns.map((addOn) => addOn.packageAdditions);
22
+ let packageJSON = {
23
+ ...JSON.parse(JSON.stringify(options.framework.basePackageJSON)),
24
+ name: options.projectName,
25
+ };
26
+ const additions = [
27
+ options.typescript
28
+ ? options.framework.optionalPackages.typescript
29
+ : undefined,
30
+ options.tailwind
31
+ ? options.framework.optionalPackages.tailwindcss
32
+ : undefined,
33
+ options.mode === FILE_ROUTER
34
+ ? options.framework.optionalPackages['file-router']
35
+ : undefined,
36
+ ];
37
+ for (const addition of additions.filter(Boolean)) {
38
+ packageJSON = mergePackageJSON(packageJSON, addition);
39
+ }
40
+ for (const addOn of addOns) {
41
+ packageJSON = mergePackageJSON(packageJSON, addOn);
42
+ }
43
+ packageJSON.dependencies = sortObject(packageJSON.dependencies);
44
+ packageJSON.devDependencies = sortObject(packageJSON.devDependencies);
45
+ return packageJSON;
46
+ }
@@ -14,17 +14,62 @@ export function getPackageManager() {
14
14
  const packageManager = SUPPORTED_PACKAGE_MANAGERS.find((manager) => userAgent.startsWith(manager));
15
15
  return packageManager;
16
16
  }
17
- export function packageManagerExecute(environment, packagerManager, pkg, args, cwd) {
17
+ export function getPackageManagerScriptCommand(packagerManager, args = []) {
18
18
  switch (packagerManager) {
19
19
  case 'yarn':
20
- return environment.execute('yarn', ['dlx', pkg, ...args], cwd);
20
+ return { command: 'yarn', args: ['run', ...args] };
21
21
  case 'pnpm':
22
- return environment.execute('pnpx', [pkg, ...args], cwd);
22
+ return { command: 'pnpm', args: [...args] };
23
23
  case 'bun':
24
- return environment.execute('bunx', ['--bun', pkg, ...args], cwd);
24
+ return { command: 'bunx', args: ['--bun', 'run', ...args] };
25
25
  case 'deno':
26
- return environment.execute('deno', ['run', `npm:${pkg}`, ...args], cwd);
26
+ return { command: 'deno', args: ['task', ...args] };
27
27
  default:
28
- return environment.execute('npx', [pkg, ...args], cwd);
28
+ return { command: 'npm', args: ['run', ...args] };
29
29
  }
30
30
  }
31
+ export function getPackageManagerExecuteCommand(packagerManager, pkg, args = []) {
32
+ switch (packagerManager) {
33
+ case 'yarn':
34
+ return { command: 'yarn', args: ['dlx', pkg, ...args] };
35
+ case 'pnpm':
36
+ return { command: 'pnpx', args: [pkg, ...args] };
37
+ case 'bun':
38
+ return { command: 'bunx', args: ['--bun', pkg, ...args] };
39
+ case 'deno':
40
+ return { command: 'deno', args: ['run', `npm:${pkg}`, ...args] };
41
+ default:
42
+ return { command: 'npx', args: [pkg, ...args] };
43
+ }
44
+ }
45
+ export function getPackageManagerInstallCommand(packagerManager, pkg, isDev = false) {
46
+ if (pkg) {
47
+ switch (packagerManager) {
48
+ case 'yarn':
49
+ case 'pnpm':
50
+ return {
51
+ command: packagerManager,
52
+ args: ['add', pkg, isDev ? '--dev' : ''],
53
+ };
54
+ default:
55
+ return {
56
+ command: packagerManager,
57
+ args: ['install', pkg, isDev ? '-D' : ''],
58
+ };
59
+ }
60
+ }
61
+ else {
62
+ return {
63
+ command: packagerManager,
64
+ args: ['install'],
65
+ };
66
+ }
67
+ }
68
+ export function packageManagerInstall(environment, cwd, packagerManager, pkg) {
69
+ const { command, args: commandArgs } = getPackageManagerInstallCommand(packagerManager, pkg);
70
+ return environment.execute(command, commandArgs, cwd);
71
+ }
72
+ export function packageManagerExecute(environment, cwd, packagerManager, pkg, args) {
73
+ const { command, args: commandArgs } = getPackageManagerExecuteCommand(packagerManager, pkg, args);
74
+ return environment.execute(command, commandArgs, cwd);
75
+ }
@@ -0,0 +1,108 @@
1
+ import { resolve } from 'node:path';
2
+ import { render } from 'ejs';
3
+ import { format } from 'prettier';
4
+ import { CODE_ROUTER, FILE_ROUTER } from './constants.js';
5
+ import { formatCommand } from './utils.js';
6
+ import { getPackageManagerExecuteCommand, getPackageManagerInstallCommand, } from './package-manager.js';
7
+ import { relativePath } from './file-helpers.js';
8
+ function convertDotFilesAndPaths(path) {
9
+ return path
10
+ .split('/')
11
+ .map((segment) => segment.replace(/^_dot_/, '.'))
12
+ .join('/');
13
+ }
14
+ export function createTemplateFile(environment, options, targetDir) {
15
+ function getPackageManagerAddScript(packageName, isDev = false) {
16
+ return formatCommand(getPackageManagerInstallCommand(options.packageManager, packageName, isDev));
17
+ }
18
+ function getPackageManagerRunScript(scriptName) {
19
+ return formatCommand(getPackageManagerExecuteCommand(options.packageManager, scriptName));
20
+ }
21
+ class IgnoreFileError extends Error {
22
+ constructor() {
23
+ super('ignoreFile');
24
+ this.name = 'IgnoreFileError';
25
+ }
26
+ }
27
+ const integrations = [];
28
+ for (const addOn of options.chosenAddOns) {
29
+ if (addOn.integrations) {
30
+ for (const integration of addOn.integrations) {
31
+ integrations.push(integration);
32
+ }
33
+ }
34
+ }
35
+ const routes = [];
36
+ for (const addOn of options.chosenAddOns) {
37
+ if (addOn.routes) {
38
+ routes.push(...addOn.routes);
39
+ }
40
+ }
41
+ return async function templateFile(file, content) {
42
+ const templateValues = {
43
+ packageManager: options.packageManager,
44
+ projectName: options.projectName,
45
+ typescript: options.typescript,
46
+ tailwind: options.tailwind,
47
+ js: options.typescript ? 'ts' : 'js',
48
+ jsx: options.typescript ? 'tsx' : 'jsx',
49
+ fileRouter: options.mode === FILE_ROUTER,
50
+ codeRouter: options.mode === CODE_ROUTER,
51
+ addOnEnabled: options.chosenAddOns.reduce((acc, addOn) => {
52
+ acc[addOn.id] = true;
53
+ return acc;
54
+ }, {}),
55
+ addOns: options.chosenAddOns,
56
+ integrations,
57
+ routes,
58
+ getPackageManagerAddScript,
59
+ getPackageManagerRunScript,
60
+ relativePath: (path) => relativePath(file, path),
61
+ ignoreFile: () => {
62
+ throw new IgnoreFileError();
63
+ },
64
+ };
65
+ let ignoreFile = false;
66
+ if (file.endsWith('.ejs')) {
67
+ try {
68
+ content = render(content, templateValues);
69
+ }
70
+ catch (error) {
71
+ if (error instanceof IgnoreFileError) {
72
+ ignoreFile = true;
73
+ }
74
+ else {
75
+ console.error(file, error);
76
+ environment.error(`EJS error in file ${file}`, error?.toString());
77
+ process.exit(1);
78
+ }
79
+ }
80
+ }
81
+ if (ignoreFile) {
82
+ return;
83
+ }
84
+ let target = convertDotFilesAndPaths(file.replace('.ejs', ''));
85
+ let append = false;
86
+ if (target.endsWith('.append')) {
87
+ append = true;
88
+ target = target.replace('.append', '');
89
+ }
90
+ if (target.endsWith('.ts') || target.endsWith('.tsx')) {
91
+ content = await format(content, {
92
+ semi: false,
93
+ singleQuote: true,
94
+ trailingComma: 'all',
95
+ parser: 'typescript',
96
+ });
97
+ }
98
+ if (!options.typescript) {
99
+ target = target.replace(/\.tsx$/, '.jsx').replace(/\.ts$/, '.js');
100
+ }
101
+ if (append) {
102
+ await environment.appendFile(resolve(targetDir, target), content);
103
+ }
104
+ else {
105
+ await environment.writeFile(resolve(targetDir, target), content);
106
+ }
107
+ };
108
+ }
@@ -1,8 +1,4 @@
1
- import type { AddOn, CliOptions, Framework, TemplateOptions } from './types.js';
2
- export declare function getAllAddOns(framework: Framework, template: string): Promise<Array<AddOn>>;
1
+ import type { AddOn, Framework } from './types.js';
2
+ export declare function getAllAddOns(framework: Framework, template: string): Array<AddOn>;
3
3
  export declare function finalizeAddOns(framework: Framework, template: string, chosenAddOnIDs: Array<string>): Promise<Array<AddOn>>;
4
- export declare function listAddOns(options: CliOptions, { forcedMode, forcedAddOns, }: {
5
- forcedMode?: TemplateOptions;
6
- forcedAddOns?: Array<string>;
7
- }): Promise<void>;
8
4
  export declare function loadRemoteAddOn(url: string): Promise<AddOn>;
@@ -0,0 +1,4 @@
1
+ import type { Environment } from './types.js';
2
+ export declare function addToApp(addOns: Array<string>, { silent, }: {
3
+ silent?: boolean;
4
+ } | undefined, environment: Environment): Promise<void>;
@@ -1,5 +1,6 @@
1
- import type { Environment, Options } from './types';
2
- export type PersistedOptions = Exclude<Partial<Options>, 'addOns' | 'chosenAddOns'> & {
1
+ import type { Environment, Options } from './types.js';
2
+ export type PersistedOptions = Omit<Partial<Options>, 'addOns' | 'chosenAddOns' | 'framework'> & {
3
+ framework: string;
3
4
  version: number;
4
5
  existingAddOns: Array<string>;
5
6
  };
@@ -1,6 +1,3 @@
1
- import type { Framework } from './types.js';
2
1
  export declare const CODE_ROUTER = "code-router";
3
2
  export declare const FILE_ROUTER = "file-router";
4
- export declare const SUPPORTED_FRAMEWORKS: Array<Framework>;
5
- export declare const DEFAULT_FRAMEWORK: Framework;
6
3
  export declare const CONFIG_FILE = ".cta.json";
@@ -0,0 +1,5 @@
1
+ export declare function readFileHelper(path: string): string;
2
+ export declare function getBinaryFile(content: string): string | null;
3
+ export declare function relativePath(from: string, to: string): string;
4
+ export declare function isDirectory(path: string): boolean;
5
+ export declare function findFilesRecursively(path: string, files: Record<string, string>): void;
@@ -0,0 +1,5 @@
1
+ import type { Framework, FrameworkDefinition } from './types.js';
2
+ export declare function registerFramework(framework: FrameworkDefinition): void;
3
+ export declare function getFrameworkById(id: string): Framework | undefined;
4
+ export declare function getFrameworkByName(name: string): Framework | undefined;
5
+ export declare function getFrameworks(): Framework[];
@@ -1,7 +1,13 @@
1
- export { cli } from './cli.js';
2
- export { getAllAddOns } from './add-ons.js';
3
1
  export { createApp } from './create-app.js';
4
- export { createAppOptionsFromPersisted } from './custom-add-on.js';
2
+ export { addToApp } from './add-to-app.js';
3
+ export { finalizeAddOns, getAllAddOns, loadRemoteAddOn } from './add-ons.js';
5
4
  export { createMemoryEnvironment, createDefaultEnvironment, } from './environment.js';
6
- export type { AddOn, Framework, Mode } from './types.js';
5
+ export { CODE_ROUTER, CONFIG_FILE, FILE_ROUTER } from './constants.js';
6
+ export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager, getPackageManagerInstallCommand, getPackageManagerExecuteCommand, getPackageManagerScriptCommand, packageManagerInstall, packageManagerExecute, } from './package-manager.js';
7
+ export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, } from './frameworks.js';
8
+ export { formatCommand, jsSafeName, sortObject } from './utils.js';
9
+ export { writeConfigFile, readConfigFile } from './config-file.js';
10
+ export { readFileHelper, getBinaryFile, relativePath } from './file-helpers.js';
11
+ export type { AddOn, Environment, FileBundleHandler, FrameworkDefinition, Mode, Options, Starter, TemplateOptions, Variable, } from './types.js';
7
12
  export type { PersistedOptions } from './config-file.js';
13
+ export type { PackageManager } from './package-manager.js';
@@ -0,0 +1,2 @@
1
+ import type { Environment } from '../types.js';
2
+ export declare function setupGit(environment: Environment, targetDir: string): Promise<void>;
@@ -0,0 +1,2 @@
1
+ import type { Environment, Options } from '../types.js';
2
+ export declare function installShadcnComponents(environment: Environment, targetDir: string, options: Options, silent: boolean): Promise<void>;
@@ -0,0 +1,2 @@
1
+ import type { Options } from './types.js';
2
+ export declare function createPackageJSON(options: Options): any;
@@ -3,4 +3,17 @@ export declare const SUPPORTED_PACKAGE_MANAGERS: readonly ["npm", "yarn", "pnpm"
3
3
  export type PackageManager = (typeof SUPPORTED_PACKAGE_MANAGERS)[number];
4
4
  export declare const DEFAULT_PACKAGE_MANAGER: PackageManager;
5
5
  export declare function getPackageManager(): PackageManager | undefined;
6
- export declare function packageManagerExecute(environment: Environment, packagerManager: PackageManager, pkg: string, args: Array<string>, cwd: string): Promise<void>;
6
+ export declare function getPackageManagerScriptCommand(packagerManager: PackageManager, args?: Array<string>): {
7
+ command: string;
8
+ args: string[];
9
+ };
10
+ export declare function getPackageManagerExecuteCommand(packagerManager: PackageManager, pkg: string, args?: Array<string>): {
11
+ command: string;
12
+ args: string[];
13
+ };
14
+ export declare function getPackageManagerInstallCommand(packagerManager: PackageManager, pkg?: string, isDev?: boolean): {
15
+ command: "npm" | "yarn" | "pnpm" | "bun" | "deno";
16
+ args: string[];
17
+ };
18
+ export declare function packageManagerInstall(environment: Environment, cwd: string, packagerManager: PackageManager, pkg?: string): Promise<void>;
19
+ export declare function packageManagerExecute(environment: Environment, cwd: string, packagerManager: PackageManager, pkg: string, args: Array<string>): Promise<void>;
@@ -0,0 +1,2 @@
1
+ import type { Environment, Options } from './types.js';
2
+ export declare function createTemplateFile(environment: Environment, options: Options, targetDir: string): (file: string, content: string) => Promise<void>;