@tanstack/cta-engine 0.10.0-alpha.21 → 0.10.0-alpha.25

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 (340) hide show
  1. package/dist/add-ons.js +91 -5
  2. package/dist/add.js +125 -0
  3. package/dist/cli.js +132 -0
  4. package/dist/config-file.js +9 -14
  5. package/dist/constants.js +2 -0
  6. package/dist/create-app.js +451 -142
  7. package/dist/custom-add-on.js +254 -0
  8. package/dist/environment.js +32 -64
  9. package/dist/file-helper.js +18 -0
  10. package/dist/index.js +1 -17
  11. package/dist/mcp.js +229 -0
  12. package/dist/options.js +333 -9
  13. package/dist/package-manager.js +6 -51
  14. package/dist/templates.js +6 -0
  15. package/dist/toolchain.js +6 -0
  16. package/dist/types/add-ons.d.ts +8 -3
  17. package/dist/types/add.d.ts +3 -0
  18. package/dist/types/cli.d.ts +7 -0
  19. package/dist/types/config-file.d.ts +4 -6
  20. package/dist/types/constants.d.ts +3 -0
  21. package/dist/types/create-app.d.ts +7 -1
  22. package/dist/types/custom-add-on.d.ts +3 -0
  23. package/dist/types/environment.d.ts +1 -2
  24. package/dist/types/file-helper.d.ts +2 -0
  25. package/dist/types/index.d.ts +1 -20
  26. package/dist/types/mcp.d.ts +7 -0
  27. package/dist/types/options.d.ts +6 -2
  28. package/dist/types/package-manager.d.ts +1 -18
  29. package/dist/types/templates.d.ts +1 -0
  30. package/dist/types/toolchain.d.ts +3 -0
  31. package/dist/types/types.d.ts +85 -788
  32. package/dist/types/utils.d.ts +0 -5
  33. package/dist/types.js +1 -65
  34. package/dist/utils.js +0 -9
  35. package/package.json +12 -9
  36. package/src/add-ons.ts +123 -7
  37. package/src/add.ts +186 -0
  38. package/src/cli.ts +210 -0
  39. package/src/config-file.ts +17 -26
  40. package/src/constants.ts +5 -0
  41. package/src/create-app.ts +730 -180
  42. package/src/custom-add-on.ts +325 -0
  43. package/src/environment.ts +33 -77
  44. package/src/file-helper.ts +20 -0
  45. package/src/index.ts +1 -77
  46. package/src/mcp.ts +302 -0
  47. package/src/options.ts +409 -8
  48. package/src/package-manager.ts +9 -80
  49. package/src/templates.ts +7 -0
  50. package/src/toolchain.ts +7 -0
  51. package/src/types.ts +87 -175
  52. package/src/utils.ts +0 -17
  53. package/templates/react/add-on/clerk/README.md +3 -0
  54. package/templates/react/add-on/clerk/assets/_dot_env.local.append +2 -0
  55. package/templates/react/add-on/clerk/assets/src/integrations/clerk/header-user.tsx +19 -0
  56. package/templates/react/add-on/clerk/assets/src/integrations/clerk/provider.tsx +18 -0
  57. package/templates/react/add-on/clerk/assets/src/routes/demo.clerk.tsx +20 -0
  58. package/templates/react/add-on/clerk/info.json +13 -0
  59. package/templates/react/add-on/clerk/package.json +5 -0
  60. package/templates/react/add-on/convex/README.md +4 -0
  61. package/templates/react/add-on/convex/assets/_dot_cursorrules.append +93 -0
  62. package/templates/react/add-on/convex/assets/_dot_env.local.append +3 -0
  63. package/templates/react/add-on/convex/assets/convex/products.ts +8 -0
  64. package/templates/react/add-on/convex/assets/convex/schema.ts +10 -0
  65. package/templates/react/add-on/convex/assets/src/integrations/convex/provider.tsx +20 -0
  66. package/templates/react/add-on/convex/assets/src/routes/demo.convex.tsx +33 -0
  67. package/templates/react/add-on/convex/info.json +13 -0
  68. package/templates/react/add-on/convex/package.json +6 -0
  69. package/templates/react/add-on/form/assets/src/components/demo.FormComponents.tsx.ejs +300 -0
  70. package/templates/react/add-on/form/assets/src/hooks/demo.form-context.ts +4 -0
  71. package/templates/react/add-on/form/assets/src/hooks/demo.form.ts +22 -0
  72. package/templates/react/add-on/form/assets/src/routes/demo.form.address.tsx.ejs +213 -0
  73. package/templates/react/add-on/form/assets/src/routes/demo.form.simple.tsx.ejs +77 -0
  74. package/templates/react/add-on/form/info.json +26 -0
  75. package/templates/react/add-on/form/package.json +6 -0
  76. package/templates/react/add-on/module-federation/assets/module-federation.config.js.ejs +31 -0
  77. package/templates/react/add-on/module-federation/assets/src/demo-mf-component.tsx +3 -0
  78. package/templates/react/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +11 -0
  79. package/templates/react/add-on/module-federation/info.json +7 -0
  80. package/templates/react/add-on/module-federation/package.json +5 -0
  81. package/templates/react/add-on/netlify/README.md +11 -0
  82. package/templates/react/add-on/netlify/info.json +7 -0
  83. package/templates/react/add-on/sentry/assets/_dot_cursorrules.append +22 -0
  84. package/templates/react/add-on/sentry/assets/_dot_env.local.append +11 -0
  85. package/templates/react/add-on/sentry/assets/src/app/global-middleware.ts +11 -0
  86. package/templates/react/add-on/sentry/assets/src/routes/demo.sentry.testing.tsx +489 -0
  87. package/templates/react/add-on/sentry/info.json +14 -0
  88. package/templates/react/add-on/sentry/package.json +5 -0
  89. package/templates/react/add-on/shadcn/README.md +7 -0
  90. package/templates/react/add-on/shadcn/assets/_dot_cursorrules.append +7 -0
  91. package/templates/react/add-on/shadcn/assets/components.json +21 -0
  92. package/templates/react/add-on/shadcn/assets/src/lib/utils.ts +6 -0
  93. package/templates/react/add-on/shadcn/assets/src/styles.css +138 -0
  94. package/templates/react/add-on/shadcn/info.json +7 -0
  95. package/templates/react/add-on/shadcn/package.json +9 -0
  96. package/templates/react/add-on/start/assets/_dot_gitignore.append +2 -0
  97. package/templates/react/add-on/start/assets/app.config.ts.ejs +32 -0
  98. package/templates/react/add-on/start/assets/src/api.ts +6 -0
  99. package/templates/react/add-on/start/assets/src/client.tsx.ejs +33 -0
  100. package/templates/react/add-on/start/assets/src/router.tsx.ejs +48 -0
  101. package/templates/react/add-on/start/assets/src/routes/api.demo-names.ts +11 -0
  102. package/templates/react/add-on/start/assets/src/routes/demo.start.api-request.tsx.ejs +33 -0
  103. package/templates/react/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +50 -0
  104. package/templates/react/add-on/start/assets/src/ssr.tsx.ejs +30 -0
  105. package/templates/react/add-on/start/info.json +18 -0
  106. package/templates/react/add-on/start/package.json +13 -0
  107. package/templates/react/add-on/store/assets/src/lib/demo-store.ts +13 -0
  108. package/templates/react/add-on/store/assets/src/routes/demo.store.tsx.ejs +75 -0
  109. package/templates/react/add-on/store/info.json +13 -0
  110. package/templates/react/add-on/store/package.json +6 -0
  111. package/templates/react/add-on/t3env/README.md +16 -0
  112. package/templates/react/add-on/t3env/assets/src/env.ts +39 -0
  113. package/templates/react/add-on/t3env/info.json +10 -0
  114. package/templates/react/add-on/t3env/package.json +6 -0
  115. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/init.ts +9 -0
  116. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/react.ts +4 -0
  117. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/router.ts +18 -0
  118. package/templates/react/add-on/tRPC/assets/src/routes/api.trpc.$.tsx +16 -0
  119. package/templates/react/add-on/tRPC/info.json +9 -0
  120. package/templates/react/add-on/tRPC/package.json +9 -0
  121. package/templates/react/add-on/table/assets/src/data/demo-table-data.ts +50 -0
  122. package/templates/react/add-on/table/assets/src/routes/demo.table.tsx.ejs +373 -0
  123. package/templates/react/add-on/table/info.json +13 -0
  124. package/templates/react/add-on/table/package.json +7 -0
  125. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/layout.tsx +5 -0
  126. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/root-provider.tsx.ejs +70 -0
  127. package/templates/react/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx.ejs +53 -0
  128. package/templates/react/add-on/tanstack-query/info.json +13 -0
  129. package/templates/react/add-on/tanstack-query/package.json +6 -0
  130. package/templates/react/base/README.md.ejs +558 -0
  131. package/templates/react/base/_dot_gitignore +5 -0
  132. package/templates/react/base/_dot_vscode/settings.biome.json +35 -0
  133. package/templates/react/base/_dot_vscode/settings.json +11 -0
  134. package/templates/react/base/index.html.ejs +20 -0
  135. package/templates/react/base/package.biome.json +10 -0
  136. package/templates/react/base/package.eslintprettier.json +11 -0
  137. package/templates/react/base/package.json +30 -0
  138. package/templates/react/base/package.ts.json +7 -0
  139. package/templates/react/base/package.tw.json +6 -0
  140. package/templates/react/base/public/favicon.ico +0 -0
  141. package/templates/react/base/public/logo192.png +0 -0
  142. package/templates/react/base/public/logo512.png +0 -0
  143. package/templates/react/base/public/manifest.json +25 -0
  144. package/templates/react/base/public/robots.txt +3 -0
  145. package/templates/react/base/src/App.css +38 -0
  146. package/templates/react/base/src/App.test.tsx.ejs +10 -0
  147. package/templates/react/base/src/App.tsx.ejs +74 -0
  148. package/templates/react/base/src/components/Header.tsx.ejs +27 -0
  149. package/templates/react/base/src/logo.svg +44 -0
  150. package/templates/react/base/src/reportWebVitals.ts.ejs +28 -0
  151. package/templates/react/base/src/styles.css.ejs +15 -0
  152. package/templates/react/base/toolchain/.prettierignore +3 -0
  153. package/templates/react/base/toolchain/biome.json +31 -0
  154. package/templates/react/base/toolchain/eslint.config.js +5 -0
  155. package/templates/react/base/toolchain/prettier.config.js +10 -0
  156. package/templates/react/base/tsconfig.json.ejs +29 -0
  157. package/templates/react/base/vite.config.js.ejs +23 -0
  158. package/templates/react/code-router/src/main.tsx.ejs +92 -0
  159. package/templates/react/example/tanchat/README.md +37 -0
  160. package/templates/react/example/tanchat/assets/_dot_env.local.append +2 -0
  161. package/templates/react/example/tanchat/assets/public/example-guitar-flowers.jpg +0 -0
  162. package/templates/react/example/tanchat/assets/public/example-guitar-motherboard.jpg +0 -0
  163. package/templates/react/example/tanchat/assets/public/example-guitar-racing.jpg +0 -0
  164. package/templates/react/example/tanchat/assets/public/example-guitar-steamer-trunk.jpg +0 -0
  165. package/templates/react/example/tanchat/assets/public/example-guitar-superhero.jpg +0 -0
  166. package/templates/react/example/tanchat/assets/public/example-guitar-traveling.jpg +0 -0
  167. package/templates/react/example/tanchat/assets/public/example-guitar-video-games.jpg +0 -0
  168. package/templates/react/example/tanchat/assets/src/components/example-AIAssistant.tsx +173 -0
  169. package/templates/react/example/tanchat/assets/src/components/example-GuitarRecommendation.tsx +47 -0
  170. package/templates/react/example/tanchat/assets/src/data/example-guitars.ts +83 -0
  171. package/templates/react/example/tanchat/assets/src/demo.index.css +220 -0
  172. package/templates/react/example/tanchat/assets/src/integrations/tanchat/header-user.tsx +5 -0
  173. package/templates/react/example/tanchat/assets/src/routes/api.messages.ts +24 -0
  174. package/templates/react/example/tanchat/assets/src/routes/api.sse.ts +23 -0
  175. package/templates/react/example/tanchat/assets/src/routes/example.chat.tsx +159 -0
  176. package/templates/react/example/tanchat/assets/src/routes/example.guitars/$guitarId.tsx +50 -0
  177. package/templates/react/example/tanchat/assets/src/routes/example.guitars/index.tsx +54 -0
  178. package/templates/react/example/tanchat/assets/src/store/example-assistant.ts +3 -0
  179. package/templates/react/example/tanchat/assets/src/utils/demo.ai.ts +62 -0
  180. package/templates/react/example/tanchat/assets/src/utils/demo.sse.ts +31 -0
  181. package/templates/react/example/tanchat/assets/src/utils/demo.tools.ts +47 -0
  182. package/templates/react/example/tanchat/info.json +19 -0
  183. package/templates/react/example/tanchat/package.json +16 -0
  184. package/templates/react/file-router/package.fr.json +5 -0
  185. package/templates/react/file-router/src/main.tsx.ejs +55 -0
  186. package/templates/react/file-router/src/routes/__root.tsx.ejs +82 -0
  187. package/templates/solid/add-on/form/assets/src/routes/demo.form.tsx.ejs +352 -0
  188. package/templates/solid/add-on/form/info.json +13 -0
  189. package/templates/solid/add-on/form/package.json +5 -0
  190. package/templates/solid/add-on/module-federation/assets/module-federation.config.js.ejs +27 -0
  191. package/templates/solid/add-on/module-federation/assets/src/demo-mf-component.tsx +3 -0
  192. package/templates/solid/add-on/module-federation/assets/src/demo-mf-self-contained.tsx +9 -0
  193. package/templates/solid/add-on/module-federation/info.json +7 -0
  194. package/templates/solid/add-on/module-federation/package.json +5 -0
  195. package/templates/solid/add-on/sentry/assets/_dot_cursorrules.append +22 -0
  196. package/templates/solid/add-on/sentry/assets/_dot_env.local.append +2 -0
  197. package/templates/solid/add-on/sentry/assets/src/routes/demo.sentry.bad-event-handler.tsx +20 -0
  198. package/templates/solid/add-on/sentry/info.json +13 -0
  199. package/templates/solid/add-on/sentry/package.json +5 -0
  200. package/templates/solid/add-on/solid-ui/README.md +9 -0
  201. package/templates/solid/add-on/solid-ui/assets/src/lib/utils.ts +6 -0
  202. package/templates/solid/add-on/solid-ui/assets/src/styles.css +138 -0
  203. package/templates/solid/add-on/solid-ui/assets/ui.config.json +13 -0
  204. package/templates/solid/add-on/solid-ui/info.json +11 -0
  205. package/templates/solid/add-on/solid-ui/package.json +9 -0
  206. package/templates/solid/add-on/start/assets/app.config.ts +16 -0
  207. package/templates/solid/add-on/start/assets/src/api.ts +6 -0
  208. package/templates/solid/add-on/start/assets/src/client.tsx +7 -0
  209. package/templates/solid/add-on/start/assets/src/router.tsx.ejs +24 -0
  210. package/templates/solid/add-on/start/assets/src/routes/demo.start.server-funcs.tsx +49 -0
  211. package/templates/solid/add-on/start/assets/src/ssr.tsx +12 -0
  212. package/templates/solid/add-on/start/info.json +14 -0
  213. package/templates/solid/add-on/start/package.json +12 -0
  214. package/templates/solid/add-on/store/assets/src/lib/demo-store.ts +13 -0
  215. package/templates/solid/add-on/store/assets/src/routes/demo.store.tsx.ejs +77 -0
  216. package/templates/solid/add-on/store/info.json +13 -0
  217. package/templates/solid/add-on/store/package.json +6 -0
  218. package/templates/solid/add-on/t3env/README.md +16 -0
  219. package/templates/solid/add-on/t3env/assets/src/env.ts +39 -0
  220. package/templates/solid/add-on/t3env/info.json +10 -0
  221. package/templates/solid/add-on/t3env/package.json +6 -0
  222. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/header-user.tsx +5 -0
  223. package/templates/solid/add-on/tanstack-query/assets/src/integrations/tanstack-query/provider.tsx +15 -0
  224. package/templates/solid/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx +30 -0
  225. package/templates/solid/add-on/tanstack-query/info.json +13 -0
  226. package/templates/solid/add-on/tanstack-query/package.json +6 -0
  227. package/templates/solid/base/README.md.ejs +215 -0
  228. package/templates/solid/base/_dot_cursorrules.append +35 -0
  229. package/templates/solid/base/_dot_gitignore +5 -0
  230. package/templates/solid/base/_dot_vscode/settings.biome.json +35 -0
  231. package/templates/solid/base/_dot_vscode/settings.json +11 -0
  232. package/templates/solid/base/index.html.ejs +20 -0
  233. package/templates/solid/base/package.biome.json +10 -0
  234. package/templates/solid/base/package.eslintprettier.json +11 -0
  235. package/templates/solid/base/package.json +23 -0
  236. package/templates/solid/base/package.ts.json +5 -0
  237. package/templates/solid/base/package.tw.json +6 -0
  238. package/templates/solid/base/public/favicon.ico +0 -0
  239. package/templates/solid/base/public/logo192.png +0 -0
  240. package/templates/solid/base/public/logo512.png +0 -0
  241. package/templates/solid/base/public/manifest.json +25 -0
  242. package/templates/solid/base/public/robots.txt +3 -0
  243. package/templates/solid/base/src/App.css +0 -0
  244. package/templates/solid/base/src/App.tsx.ejs +47 -0
  245. package/templates/solid/base/src/components/Header.tsx.ejs +26 -0
  246. package/templates/solid/base/src/logo.svg +120 -0
  247. package/templates/solid/base/src/styles.css.ejs +15 -0
  248. package/templates/solid/base/toolchain/.prettierignore +3 -0
  249. package/templates/solid/base/toolchain/biome.json +31 -0
  250. package/templates/solid/base/toolchain/eslint.config.js +5 -0
  251. package/templates/solid/base/toolchain/prettier.config.js +10 -0
  252. package/templates/solid/base/tsconfig.json.ejs +31 -0
  253. package/templates/solid/base/vite.config.js.ejs +22 -0
  254. package/templates/solid/code-router/src/main.tsx.ejs +71 -0
  255. package/templates/solid/example/tanchat/README.md +52 -0
  256. package/templates/solid/example/tanchat/assets/ai-streaming-server/README.md +110 -0
  257. package/templates/solid/example/tanchat/assets/ai-streaming-server/_dot_env.example +1 -0
  258. package/templates/solid/example/tanchat/assets/ai-streaming-server/package.json +26 -0
  259. package/templates/solid/example/tanchat/assets/ai-streaming-server/src/index.ts +102 -0
  260. package/templates/solid/example/tanchat/assets/ai-streaming-server/tsconfig.json +15 -0
  261. package/templates/solid/example/tanchat/assets/src/components/demo.SettingsDialog.tsx +149 -0
  262. package/templates/solid/example/tanchat/assets/src/demo.index.css +227 -0
  263. package/templates/solid/example/tanchat/assets/src/lib/demo-store.ts +13 -0
  264. package/templates/solid/example/tanchat/assets/src/routes/example.chat.tsx +435 -0
  265. package/templates/solid/example/tanchat/assets/src/store/demo.hooks.ts +17 -0
  266. package/templates/solid/example/tanchat/assets/src/store/demo.store.ts +133 -0
  267. package/templates/solid/example/tanchat/info.json +14 -0
  268. package/templates/solid/example/tanchat/package.json +7 -0
  269. package/templates/solid/file-router/package.fr.json +5 -0
  270. package/templates/solid/file-router/src/main.tsx.ejs +47 -0
  271. package/templates/solid/file-router/src/routes/__root.tsx.ejs +41 -0
  272. package/templates/solid/file-router/src/routes/index.tsx +43 -0
  273. package/tests/cra.test.ts +293 -0
  274. package/tests/snapshots/cra/cr-js-npm.json +33 -0
  275. package/tests/snapshots/cra/cr-ts-npm.json +34 -0
  276. package/tests/snapshots/cra/cr-ts-start-npm.json +38 -0
  277. package/tests/snapshots/cra/fr-ts-npm.json +34 -0
  278. package/tests/snapshots/cra/fr-ts-tw-npm.json +33 -0
  279. package/tests/snapshots/cra/solid-cr-js-npm.json +31 -0
  280. package/tests/snapshots/cra/solid-cr-ts-npm.json +32 -0
  281. package/tests/snapshots/cra/solid-cr-ts-start-npm.json +36 -0
  282. package/tests/snapshots/cra/solid-fr-ts-npm.json +33 -0
  283. package/tests/snapshots/cra/solid-fr-ts-tw-npm.json +32 -0
  284. package/tests/test-utilities.ts +87 -0
  285. package/dist/add-to-app.js +0 -169
  286. package/dist/custom-add-ons/add-on.js +0 -175
  287. package/dist/custom-add-ons/shared.js +0 -117
  288. package/dist/custom-add-ons/starter.js +0 -84
  289. package/dist/file-helpers.js +0 -165
  290. package/dist/frameworks.js +0 -92
  291. package/dist/integrations/git.js +0 -4
  292. package/dist/integrations/shadcn.js +0 -33
  293. package/dist/package-json.js +0 -48
  294. package/dist/special-steps/index.js +0 -24
  295. package/dist/special-steps/rimraf-node-modules.js +0 -16
  296. package/dist/template-file.js +0 -112
  297. package/dist/types/add-to-app.d.ts +0 -17
  298. package/dist/types/custom-add-ons/add-on.d.ts +0 -69
  299. package/dist/types/custom-add-ons/shared.d.ts +0 -15
  300. package/dist/types/custom-add-ons/starter.d.ts +0 -7
  301. package/dist/types/file-helpers.d.ts +0 -15
  302. package/dist/types/frameworks.d.ts +0 -7
  303. package/dist/types/integrations/git.d.ts +0 -2
  304. package/dist/types/integrations/shadcn.d.ts +0 -2
  305. package/dist/types/package-json.d.ts +0 -7
  306. package/dist/types/special-steps/index.d.ts +0 -2
  307. package/dist/types/special-steps/rimraf-node-modules.d.ts +0 -2
  308. package/dist/types/template-file.d.ts +0 -2
  309. package/src/add-to-app.ts +0 -274
  310. package/src/custom-add-ons/add-on.ts +0 -261
  311. package/src/custom-add-ons/shared.ts +0 -161
  312. package/src/custom-add-ons/starter.ts +0 -126
  313. package/src/file-helpers.ts +0 -235
  314. package/src/frameworks.ts +0 -134
  315. package/src/integrations/git.ts +0 -7
  316. package/src/integrations/shadcn.ts +0 -54
  317. package/src/package-json.ts +0 -69
  318. package/src/special-steps/index.ts +0 -36
  319. package/src/special-steps/rimraf-node-modules.ts +0 -25
  320. package/src/template-file.ts +0 -150
  321. package/tests/add-ons.test.ts +0 -67
  322. package/tests/add-to-app.test.ts +0 -358
  323. package/tests/config-file.test.ts +0 -68
  324. package/tests/create-app.test.ts +0 -120
  325. package/tests/custom-add-ons/add-on.test.ts +0 -12
  326. package/tests/custom-add-ons/shared.test.ts +0 -257
  327. package/tests/custom-add-ons/starter.test.ts +0 -58
  328. package/tests/environment.test.ts +0 -115
  329. package/tests/file-helper.test.ts +0 -90
  330. package/tests/frameworks.test.ts +0 -95
  331. package/tests/index.test.ts +0 -9
  332. package/tests/integrations/git.test.ts +0 -20
  333. package/tests/integrations/shadcn.test.ts +0 -91
  334. package/tests/options.test.ts +0 -42
  335. package/tests/package-json.test.ts +0 -63
  336. package/tests/package-manager.test.ts +0 -154
  337. package/tests/setupVitest.ts +0 -6
  338. package/tests/template-file.test.ts +0 -178
  339. package/tests/utils.test.ts +0 -23
  340. package/vitest.config.ts +0 -21
@@ -1,182 +1,491 @@
1
- import { basename, resolve } from 'node:path';
2
- import { isBase64 } from './file-helpers.js';
3
- import { formatCommand } from './utils.js';
4
- import { writeConfigFileToEnvironment } from './config-file.js';
5
- import { getPackageManagerScriptCommand, packageManagerInstall, } from './package-manager.js';
6
- import { createPackageJSON } from './package-json.js';
7
- import { createTemplateFile } from './template-file.js';
8
- import { installShadcnComponents } from './integrations/shadcn.js';
9
- import { setupGit } from './integrations/git.js';
10
- import { runSpecialSteps } from './special-steps/index.js';
11
- async function writeFiles(environment, options) {
12
- const templateFileFromContent = createTemplateFile(environment, options);
13
- async function writeFileBundle(bundle) {
14
- const files = await bundle.getFiles();
1
+ import { basename, dirname, resolve } from 'node:path';
2
+ import { log, outro, spinner } from '@clack/prompts';
3
+ import { render } from 'ejs';
4
+ import { format } from 'prettier';
5
+ import chalk from 'chalk';
6
+ import { getTemplatesRoot } from './templates.js';
7
+ import { CODE_ROUTER, FILE_ROUTER } from './constants.js';
8
+ import { sortObject } from './utils.js';
9
+ import { writeConfigFile } from './config-file.js';
10
+ import { packageManagerExecute } from './package-manager.js';
11
+ import { getBinaryFile } from './file-helper.js';
12
+ function createCopyFiles(environment, targetDir) {
13
+ return async function copyFiles(templateDir, files,
14
+ // optionally copy files from a folder to the root
15
+ toRoot) {
15
16
  for (const file of files) {
16
- const contents = await bundle.getFileContents(file);
17
- const isBinaryFile = isBase64(contents);
18
- if (isBinaryFile) {
19
- await environment.writeFileBase64(resolve(options.targetDir, file), contents);
17
+ let targetFileName = file.replace('.tw', '');
18
+ if (toRoot) {
19
+ const fileNoPath = targetFileName.split('/').pop();
20
+ targetFileName = fileNoPath ? `./${fileNoPath}` : targetFileName;
20
21
  }
21
- else {
22
- await templateFileFromContent(file, contents);
22
+ await environment.copyFile(resolve(templateDir, file), resolve(targetDir, targetFileName));
23
+ }
24
+ };
25
+ }
26
+ function jsSafeName(name) {
27
+ return name
28
+ .split(/[^a-zA-Z0-9]/)
29
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
30
+ .join('');
31
+ }
32
+ function createTemplateFile(environment, projectName, options, targetDir) {
33
+ return async function templateFile(file, content, targetFileName, extraTemplateValues) {
34
+ function getPackageManagerAddScript(packageName, isDev = false) {
35
+ let command;
36
+ switch (options.packageManager) {
37
+ case 'yarn':
38
+ case 'pnpm':
39
+ command = isDev
40
+ ? `${options.packageManager} add ${packageName} --dev`
41
+ : `${options.packageManager} add ${packageName}`;
42
+ break;
43
+ default:
44
+ command = isDev
45
+ ? `${options.packageManager} install ${packageName} -D`
46
+ : `${options.packageManager} install ${packageName}`;
47
+ break;
48
+ }
49
+ return command;
50
+ }
51
+ function getPackageManagerRunScript(scriptName) {
52
+ let command;
53
+ switch (options.packageManager) {
54
+ case 'yarn':
55
+ case 'pnpm':
56
+ command = `${options.packageManager} ${scriptName}`;
57
+ break;
58
+ case 'deno':
59
+ command = `${options.packageManager} task ${scriptName}`;
60
+ break;
61
+ default:
62
+ command = `${options.packageManager} run ${scriptName}`;
63
+ break;
64
+ }
65
+ return command;
66
+ }
67
+ const templateValues = {
68
+ packageManager: options.packageManager,
69
+ projectName: projectName,
70
+ typescript: options.typescript,
71
+ tailwind: options.tailwind,
72
+ toolchain: options.toolchain,
73
+ js: options.typescript ? 'ts' : 'js',
74
+ jsx: options.typescript ? 'tsx' : 'jsx',
75
+ fileRouter: options.mode === FILE_ROUTER,
76
+ codeRouter: options.mode === CODE_ROUTER,
77
+ addOnEnabled: options.chosenAddOns.reduce((acc, addOn) => {
78
+ acc[addOn.id] = true;
79
+ return acc;
80
+ }, {}),
81
+ addOns: options.chosenAddOns,
82
+ ...extraTemplateValues,
83
+ getPackageManagerAddScript,
84
+ getPackageManagerRunScript,
85
+ };
86
+ try {
87
+ content = render(content, templateValues);
88
+ }
89
+ catch (error) {
90
+ console.error(chalk.red(`EJS error in file ${file}`));
91
+ console.error(error);
92
+ process.exit(1);
93
+ }
94
+ const target = targetFileName ?? file.replace('.ejs', '');
95
+ if (target.endsWith('.ts') || target.endsWith('.tsx')) {
96
+ content = await format(content, {
97
+ semi: false,
98
+ singleQuote: true,
99
+ trailingComma: 'all',
100
+ parser: 'typescript',
101
+ });
102
+ }
103
+ await environment.writeFile(resolve(targetDir, target), content);
104
+ };
105
+ }
106
+ async function createPackageJSON(environment, projectName, options, templateDir, routerDir, targetDir, addOns) {
107
+ let packageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.json'), 'utf8'));
108
+ packageJSON.name = projectName;
109
+ if (options.typescript) {
110
+ const tsPackageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.ts.json'), 'utf8'));
111
+ packageJSON = {
112
+ ...packageJSON,
113
+ devDependencies: {
114
+ ...packageJSON.devDependencies,
115
+ ...tsPackageJSON.devDependencies,
116
+ },
117
+ };
118
+ }
119
+ if (options.tailwind) {
120
+ const twPackageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.tw.json'), 'utf8'));
121
+ packageJSON = {
122
+ ...packageJSON,
123
+ dependencies: {
124
+ ...packageJSON.dependencies,
125
+ ...twPackageJSON.dependencies,
126
+ },
127
+ };
128
+ }
129
+ if (options.toolchain === 'biome') {
130
+ const biomePackageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.biome.json'), 'utf8'));
131
+ packageJSON = {
132
+ ...packageJSON,
133
+ scripts: {
134
+ ...packageJSON.scripts,
135
+ ...biomePackageJSON.scripts,
136
+ },
137
+ devDependencies: {
138
+ ...packageJSON.devDependencies,
139
+ ...biomePackageJSON.devDependencies,
140
+ },
141
+ };
142
+ }
143
+ if (options.toolchain === 'eslint+prettier') {
144
+ const eslintPrettierPackageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.eslintprettier.json'), 'utf-8'));
145
+ packageJSON = {
146
+ ...packageJSON,
147
+ scripts: {
148
+ ...packageJSON.scripts,
149
+ ...eslintPrettierPackageJSON.scripts,
150
+ },
151
+ devDependencies: {
152
+ ...packageJSON.devDependencies,
153
+ ...eslintPrettierPackageJSON.devDependencies,
154
+ },
155
+ };
156
+ }
157
+ if (options.mode === FILE_ROUTER) {
158
+ const frPackageJSON = JSON.parse(await environment.readFile(resolve(routerDir, 'package.fr.json'), 'utf8'));
159
+ packageJSON = {
160
+ ...packageJSON,
161
+ dependencies: {
162
+ ...packageJSON.dependencies,
163
+ ...frPackageJSON.dependencies,
164
+ },
165
+ };
166
+ }
167
+ for (const addOn of addOns) {
168
+ packageJSON = {
169
+ ...packageJSON,
170
+ dependencies: {
171
+ ...packageJSON.dependencies,
172
+ ...addOn.dependencies,
173
+ },
174
+ devDependencies: {
175
+ ...packageJSON.devDependencies,
176
+ ...addOn.devDependencies,
177
+ },
178
+ scripts: {
179
+ ...packageJSON.scripts,
180
+ ...addOn.scripts,
181
+ },
182
+ };
183
+ }
184
+ packageJSON.dependencies = sortObject(packageJSON.dependencies);
185
+ packageJSON.devDependencies = sortObject(packageJSON.devDependencies);
186
+ await environment.writeFile(resolve(targetDir, 'package.json'), JSON.stringify(packageJSON, null, 2));
187
+ }
188
+ async function copyAddOnFile(environment, content, target, targetPath, templateFile) {
189
+ let targetFile = basename(target).replace(/^_dot_/, '.');
190
+ let isTemplate = false;
191
+ if (targetFile.endsWith('.ejs')) {
192
+ targetFile = targetFile.replace('.ejs', '');
193
+ isTemplate = true;
194
+ }
195
+ let isAppend = false;
196
+ if (targetFile.endsWith('.append')) {
197
+ targetFile = targetFile.replace('.append', '');
198
+ isAppend = true;
199
+ }
200
+ const finalTargetPath = resolve(dirname(targetPath), targetFile);
201
+ const binaryContent = getBinaryFile(content);
202
+ if (binaryContent) {
203
+ await environment.writeFile(finalTargetPath, binaryContent);
204
+ return;
205
+ }
206
+ if (isTemplate) {
207
+ await templateFile(content, finalTargetPath);
208
+ }
209
+ else {
210
+ if (isAppend) {
211
+ await environment.appendFile(finalTargetPath, content);
212
+ }
213
+ else {
214
+ await environment.writeFile(finalTargetPath, content);
215
+ }
216
+ }
217
+ }
218
+ export async function createApp(options, { silent = false, environment, cwd, appName = 'TanStack', }) {
219
+ environment.startRun();
220
+ const templateDirBase = resolve(getTemplatesRoot(), options.framework, 'base');
221
+ const templateDirRouter = resolve(getTemplatesRoot(), options.framework, options.mode);
222
+ let targetDir = cwd || '';
223
+ if (!targetDir.length) {
224
+ targetDir = resolve(process.cwd(), options.projectName);
225
+ }
226
+ const copyFiles = createCopyFiles(environment, targetDir);
227
+ const templateFileFromContent = createTemplateFile(environment, options.projectName, options, targetDir);
228
+ async function templateFile(templateBase, file, targetFileName, extraTemplateValues) {
229
+ const content = await environment.readFile(resolve(templateBase, file), 'utf-8');
230
+ return templateFileFromContent(file, content.toString(), targetFileName, extraTemplateValues);
231
+ }
232
+ const isAddOnEnabled = (id) => options.chosenAddOns.find((a) => a.id === id);
233
+ async function runAddOn(addOn) {
234
+ if (addOn.files) {
235
+ for (const file of Object.keys(addOn.files)) {
236
+ await copyAddOnFile(environment, addOn.files[file], file, resolve(targetDir, file), (content, targetFileName) => templateFileFromContent(targetFileName, content));
23
237
  }
24
238
  }
25
- const deletedFiles = await bundle.getDeletedFiles();
26
- for (const file of deletedFiles) {
27
- await environment.deleteFile(resolve(options.targetDir, file));
239
+ if (addOn.deletedFiles) {
240
+ for (const file of addOn.deletedFiles) {
241
+ await environment.deleteFile(resolve(targetDir, file));
242
+ }
243
+ }
244
+ if (addOn.command && addOn.command.command) {
245
+ await environment.execute(addOn.command.command, addOn.command.args || [], resolve(targetDir));
246
+ }
247
+ }
248
+ // Setup the .vscode directory
249
+ switch (options.toolchain) {
250
+ case 'biome':
251
+ await environment.copyFile(resolve(templateDirBase, '_dot_vscode/settings.biome.json'), resolve(targetDir, '.vscode/settings.json'));
252
+ break;
253
+ case 'none':
254
+ default:
255
+ await environment.copyFile(resolve(templateDirBase, '_dot_vscode/settings.json'), resolve(targetDir, '.vscode/settings.json'));
256
+ }
257
+ // Fill the public directory
258
+ copyFiles(templateDirBase, [
259
+ './public/robots.txt',
260
+ './public/favicon.ico',
261
+ './public/manifest.json',
262
+ './public/logo192.png',
263
+ './public/logo512.png',
264
+ ]);
265
+ // Check for a .cursorrules file
266
+ if (environment.exists(resolve(templateDirBase, '.cursorrules'))) {
267
+ await environment.copyFile(resolve(templateDirBase, '.cursorrules'), resolve(targetDir, '.cursorrules'));
268
+ }
269
+ // Copy in Vite and Tailwind config and CSS
270
+ if (!options.tailwind) {
271
+ await copyFiles(templateDirBase, ['./src/App.css']);
272
+ }
273
+ // Don't create a vite.config.js file if we are building a Start app
274
+ if (!isAddOnEnabled('start')) {
275
+ await templateFile(templateDirBase, './vite.config.js.ejs');
276
+ }
277
+ await templateFile(templateDirBase, './src/styles.css.ejs');
278
+ copyFiles(templateDirBase, ['./src/logo.svg']);
279
+ if (options.toolchain === 'biome') {
280
+ copyFiles(templateDirBase, ['./toolchain/biome.json'], true);
281
+ }
282
+ if (options.toolchain === 'eslint+prettier') {
283
+ copyFiles(templateDirBase, [
284
+ './toolchain/eslint.config.js',
285
+ './toolchain/prettier.config.js',
286
+ './toolchain/.prettierignore',
287
+ ], true);
288
+ }
289
+ // Setup reportWebVitals
290
+ if (!isAddOnEnabled('start') && options.framework === 'react') {
291
+ if (options.typescript) {
292
+ await templateFile(templateDirBase, './src/reportWebVitals.ts.ejs');
293
+ }
294
+ else {
295
+ await templateFile(templateDirBase, './src/reportWebVitals.ts.ejs', './src/reportWebVitals.js');
28
296
  }
29
297
  }
30
- environment.startStep({
31
- id: 'write-framework-files',
32
- type: 'file',
33
- message: 'Writing framework files...',
34
- });
35
- await writeFileBundle(options.framework);
36
- environment.finishStep('write-framework-files', 'Framework files written');
37
- let wroteAddonFiles = false;
38
- for (const type of ['add-on', 'example', 'toolchain']) {
298
+ if (!isAddOnEnabled('start')) {
299
+ await templateFile(templateDirBase, './index.html.ejs');
300
+ }
301
+ // Add .gitignore
302
+ await environment.copyFile(resolve(templateDirBase, '_dot_gitignore'), resolve(targetDir, '.gitignore'));
303
+ // Setup tsconfig
304
+ if (options.typescript) {
305
+ await templateFile(templateDirBase, './tsconfig.json.ejs', './tsconfig.json');
306
+ }
307
+ // Setup the package.json file, optionally with typescript, tailwind and formatter/linter
308
+ await createPackageJSON(environment, options.projectName, options, templateDirBase, templateDirRouter, targetDir, options.chosenAddOns.map((addOn) => addOn.packageAdditions));
309
+ // Copy all the asset files from the addons
310
+ const s = silent ? null : spinner();
311
+ for (const type of ['add-on', 'example']) {
39
312
  for (const phase of ['setup', 'add-on', 'example']) {
40
313
  for (const addOn of options.chosenAddOns.filter((addOn) => addOn.phase === phase && addOn.type === type)) {
41
- environment.startStep({
42
- id: 'write-addon-files',
43
- type: 'file',
44
- message: `Writing ${addOn.name} files...`,
45
- });
46
- await writeFileBundle(addOn);
47
- wroteAddonFiles = true;
314
+ s?.start(`Setting up ${addOn.name}...`);
315
+ await runAddOn(addOn);
316
+ s?.stop(`${addOn.name} setup complete`);
48
317
  }
49
318
  }
50
319
  }
51
- if (wroteAddonFiles) {
52
- environment.finishStep('write-addon-files', 'Add-on files written');
53
- }
54
- if (options.starter) {
55
- environment.startStep({
56
- id: 'write-starter-files',
57
- type: 'file',
58
- message: 'Writing starter files...',
59
- });
60
- await writeFileBundle(options.starter);
61
- environment.finishStep('write-starter-files', 'Starter files written');
62
- }
63
- environment.startStep({
64
- id: 'write-package-json',
65
- type: 'file',
66
- message: 'Writing package.json...',
67
- });
68
- await environment.writeFile(resolve(options.targetDir, './package.json'), JSON.stringify(createPackageJSON(options), null, 2));
69
- environment.finishStep('write-package-json', 'Package.json written');
70
- environment.startStep({
71
- id: 'write-config-file',
72
- type: 'file',
73
- message: 'Writing config file...',
74
- });
75
- await writeConfigFileToEnvironment(environment, options);
76
- environment.finishStep('write-config-file', 'Config file written');
77
- }
78
- async function runCommandsAndInstallDependencies(environment, options) {
79
- const s = environment.spinner();
80
- // Setup git
81
- if (options.git) {
82
- s.start(`Initializing git repository...`);
83
- environment.startStep({
84
- id: 'initialize-git-repository',
85
- type: 'command',
86
- message: 'Initializing git repository...',
87
- });
88
- await setupGit(environment, options.targetDir);
89
- environment.finishStep('initialize-git-repository', 'Initialized git repository');
90
- s.stop(`Initialized git repository`);
320
+ if (isAddOnEnabled('shadcn')) {
321
+ const shadcnComponents = new Set();
322
+ for (const addOn of options.chosenAddOns) {
323
+ if (addOn.shadcnComponents) {
324
+ for (const component of addOn.shadcnComponents) {
325
+ shadcnComponents.add(component);
326
+ }
327
+ }
328
+ }
329
+ if (options.overlay) {
330
+ if (options.overlay.shadcnComponents) {
331
+ for (const component of options.overlay.shadcnComponents) {
332
+ shadcnComponents.add(component);
333
+ }
334
+ }
335
+ }
336
+ if (shadcnComponents.size > 0) {
337
+ s?.start(`Installing shadcn components (${Array.from(shadcnComponents).join(', ')})...`);
338
+ await packageManagerExecute(environment, options.packageManager, 'shadcn@latest', ['add', '--silent', '--yes', ...shadcnComponents], resolve(targetDir));
339
+ s?.stop(`Installed additional shadcn components`);
340
+ }
91
341
  }
92
- // Run any special steps for the new add-ons
93
- const specialSteps = new Set([]);
94
- for (const addOn of options.chosenAddOns) {
95
- for (const step of addOn.createSpecialSteps || []) {
96
- specialSteps.add(step);
342
+ const integrations = [];
343
+ if (environment.exists(resolve(targetDir, 'src/integrations'))) {
344
+ for (const integration of environment.readdir(resolve(targetDir, 'src/integrations'))) {
345
+ const integrationName = jsSafeName(integration);
346
+ if (environment.exists(resolve(targetDir, 'src/integrations', integration, 'layout.tsx'))) {
347
+ integrations.push({
348
+ type: 'layout',
349
+ name: `${integrationName}Layout`,
350
+ path: `integrations/${integration}/layout`,
351
+ });
352
+ }
353
+ if (environment.exists(resolve(targetDir, 'src/integrations', integration, 'provider.tsx'))) {
354
+ integrations.push({
355
+ type: 'provider',
356
+ name: `${integrationName}Provider`,
357
+ path: `integrations/${integration}/provider`,
358
+ });
359
+ }
360
+ if (environment.exists(resolve(targetDir, 'src/integrations', integration, 'root-provider.tsx'))) {
361
+ integrations.push({
362
+ type: 'root-provider',
363
+ name: integrationName,
364
+ path: `integrations/${integration}/root-provider`,
365
+ });
366
+ }
367
+ if (environment.exists(resolve(targetDir, 'src/integrations', integration, 'header-user.tsx'))) {
368
+ integrations.push({
369
+ type: 'header-user',
370
+ name: `${integrationName}Header`,
371
+ path: `integrations/${integration}/header-user`,
372
+ });
373
+ }
97
374
  }
98
375
  }
99
- if (specialSteps.size) {
100
- await runSpecialSteps(environment, options, Array.from(specialSteps));
376
+ const routes = [];
377
+ if (environment.exists(resolve(targetDir, 'src/routes'))) {
378
+ for (const file of environment.readdir(resolve(targetDir, 'src/routes'))) {
379
+ const name = file.replace(/\.tsx?|\.jsx?/, '');
380
+ const safeRouteName = jsSafeName(name);
381
+ routes.push({
382
+ path: `./routes/${name}`,
383
+ name: safeRouteName,
384
+ });
385
+ }
101
386
  }
102
- // Install dependencies
103
- s.start(`Installing dependencies via ${options.packageManager}...`);
104
- environment.startStep({
105
- id: 'install-dependencies',
106
- type: 'package-manager',
107
- message: `Installing dependencies via ${options.packageManager}...`,
108
- });
109
- await packageManagerInstall(environment, options.targetDir, options.packageManager);
110
- environment.finishStep('install-dependencies', 'Installed dependencies');
111
- s.stop(`Installed dependencies`);
112
- for (const phase of ['setup', 'add-on', 'example']) {
113
- for (const addOn of options.chosenAddOns.filter((addOn) => addOn.phase === phase && addOn.command && addOn.command.command)) {
114
- s.start(`Running commands for ${addOn.name}...`);
115
- const cmd = formatCommand({
116
- command: addOn.command.command,
117
- args: addOn.command.args || [],
387
+ // Create the main entry point
388
+ if (!isAddOnEnabled('start')) {
389
+ if (options.typescript) {
390
+ await templateFile(templateDirRouter, './src/main.tsx.ejs', './src/main.tsx', {
391
+ routes,
392
+ integrations,
118
393
  });
119
- environment.startStep({
120
- id: 'run-commands',
121
- type: 'command',
122
- message: cmd,
394
+ }
395
+ else {
396
+ await templateFile(templateDirRouter, './src/main.tsx.ejs', './src/main.jsx', {
397
+ routes,
398
+ integrations,
123
399
  });
124
- await environment.execute(addOn.command.command, addOn.command.args || [], options.targetDir);
125
- environment.finishStep('run-commands', 'Setup commands complete');
126
- s.stop(`${addOn.name} commands complete`);
127
- }
128
- }
129
- // Adding starter
130
- if (options.starter &&
131
- options.starter.command &&
132
- options.starter.command.command) {
133
- s.start(`Setting up starter ${options.starter.name}...`);
134
- const cmd = formatCommand({
135
- command: options.starter.command.command,
136
- args: options.starter.command.args || [],
400
+ }
401
+ }
402
+ // Setup the app component. There are four variations, typescript/javascript and tailwind/non-tailwind.
403
+ if (options.mode === FILE_ROUTER) {
404
+ await templateFile(templateDirRouter, './src/routes/__root.tsx.ejs', './src/routes/__root.tsx', {
405
+ integrations,
137
406
  });
138
- environment.startStep({
139
- id: 'run-starter-command',
140
- type: 'command',
141
- message: cmd,
407
+ await templateFile(templateDirBase, './src/App.tsx.ejs', './src/routes/index.tsx');
408
+ }
409
+ else {
410
+ await templateFile(templateDirBase, './src/App.tsx.ejs', options.typescript ? undefined : './src/App.jsx');
411
+ if (options.framework === 'react') {
412
+ await templateFile(templateDirBase, './src/App.test.tsx.ejs', options.typescript ? undefined : './src/App.test.jsx');
413
+ }
414
+ }
415
+ if (routes.length > 0 ||
416
+ options.chosenAddOns.length > 0 ||
417
+ integrations.length > 0) {
418
+ await templateFile(templateDirBase, './src/components/Header.tsx.ejs', './src/components/Header.tsx', {
419
+ integrations,
142
420
  });
143
- await environment.execute(options.starter.command.command, options.starter.command.args || [], options.targetDir);
144
- environment.finishStep('run-starter-command', 'Starter command complete');
145
- s.stop(`${options.starter.name} commands complete`);
146
421
  }
147
- await installShadcnComponents(environment, options.targetDir, options);
148
- }
149
- function report(environment, options) {
150
422
  const warnings = [];
151
423
  for (const addOn of options.chosenAddOns) {
152
424
  if (addOn.warning) {
153
425
  warnings.push(addOn.warning);
154
426
  }
155
427
  }
428
+ // Create the README.md
429
+ await templateFile(templateDirBase, 'README.md.ejs');
430
+ // Adding overlay
431
+ if (options.overlay) {
432
+ s?.start(`Setting up overlay ${options.overlay.name}...`);
433
+ await runAddOn(options.overlay);
434
+ s?.stop(`Overlay ${options.overlay.name} setup complete`);
435
+ }
436
+ // Install dependencies
437
+ s?.start(`Installing dependencies via ${options.packageManager}...`);
438
+ await environment.execute(options.packageManager, ['install'], resolve(targetDir));
439
+ s?.stop(`Installed dependencies`);
156
440
  if (warnings.length > 0) {
157
- environment.warn('Warnings', warnings.join('\n'));
441
+ if (!silent) {
442
+ log.warn(chalk.red(warnings.join('\n')));
443
+ }
158
444
  }
159
- // Format errors
445
+ if (options.toolchain === 'biome') {
446
+ s?.start(`Applying toolchain ${options.toolchain}...`);
447
+ switch (options.packageManager) {
448
+ case 'pnpm':
449
+ // pnpm automatically forwards extra arguments
450
+ await environment.execute(options.packageManager, ['run', 'check', '--fix'], resolve(targetDir));
451
+ break;
452
+ default:
453
+ await environment.execute(options.packageManager, ['run', 'check', '--', '--fix'], resolve(targetDir));
454
+ break;
455
+ }
456
+ s?.stop(`Applied toolchain ${options.toolchain}...`);
457
+ }
458
+ if (options.toolchain === 'eslint+prettier') {
459
+ s?.start(`Applying toolchain ${options.toolchain}...`);
460
+ await environment.execute(options.packageManager, ['run', 'check'], targetDir);
461
+ s?.stop(`Applied toolchain ${options.toolchain}...`);
462
+ }
463
+ if (options.git) {
464
+ s?.start(`Initializing git repository...`);
465
+ await environment.execute('git', ['init'], resolve(targetDir));
466
+ s?.stop(`Initialized git repository`);
467
+ }
468
+ await writeConfigFile(environment, targetDir, options);
469
+ environment.finishRun();
160
470
  let errorStatement = '';
161
471
  if (environment.getErrors().length) {
162
472
  errorStatement = `
163
473
 
164
- Errors were encountered during the creation of your app:
474
+ ${chalk.red('Errors were encountered during this process:')}
165
475
 
166
476
  ${environment.getErrors().join('\n')}`;
167
477
  }
168
- environment.outro(`Your ${environment.appName} app is ready in '${basename(options.targetDir)}'.
478
+ if (!silent) {
479
+ let startCommand = `${options.packageManager} ${isAddOnEnabled('start') ? 'dev' : 'start'}`;
480
+ if (options.packageManager === 'deno') {
481
+ startCommand = `deno ${isAddOnEnabled('start') ? 'task dev' : 'start'}`;
482
+ }
483
+ outro(`Your ${appName} app is ready in '${basename(targetDir)}'.
169
484
 
170
485
  Use the following commands to start your app:
171
486
  % cd ${options.projectName}
172
- % ${formatCommand(getPackageManagerScriptCommand(options.packageManager, ['dev']))}
487
+ % ${startCommand}
173
488
 
174
- Please check the README.md for more information on testing, styling, adding routes, etc.${errorStatement}`);
175
- }
176
- export async function createApp(environment, options) {
177
- environment.startRun();
178
- await writeFiles(environment, options);
179
- await runCommandsAndInstallDependencies(environment, options);
180
- environment.finishRun();
181
- report(environment, options);
489
+ Please check the README.md for more information on testing, styling, adding routes, react-query, etc.${errorStatement}`);
490
+ }
182
491
  }