@reliverse/dler 1.7.92 → 1.7.93

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 (1019) hide show
  1. package/LICENSES +4 -1
  2. package/README.md +25 -1213
  3. package/bin/app/add/add-global/install-impl.d.ts +9 -0
  4. package/bin/app/add/add-global/install-impl.js +138 -0
  5. package/bin/app/add/add-local/api/orpc.d.ts +1 -0
  6. package/bin/app/add/add-local/api/orpc.js +4 -0
  7. package/bin/app/add/add-local/api/trpc.d.ts +1 -0
  8. package/bin/app/add/add-local/api/trpc.js +4 -0
  9. package/bin/app/add/add-local/auth/better-auth.d.ts +1 -0
  10. package/bin/app/add/add-local/auth/better-auth.js +4 -0
  11. package/bin/app/add/add-local/auth/clerk-auth.d.ts +1 -0
  12. package/bin/app/add/add-local/auth/clerk-auth.js +4 -0
  13. package/bin/app/add/add-local/auth/next-auth.d.ts +1 -0
  14. package/bin/app/add/add-local/auth/next-auth.js +4 -0
  15. package/bin/app/add/add-local/core/deps.d.ts +8 -0
  16. package/bin/app/add/add-local/core/deps.js +19 -0
  17. package/bin/app/add/add-local/core/prompts.d.ts +4 -0
  18. package/bin/app/add/add-local/core/prompts.js +12 -0
  19. package/bin/app/add/add-local/core/templates.d.ts +29 -0
  20. package/bin/app/add/add-local/core/templates.js +85 -0
  21. package/bin/app/add/add-local/core/types.d.ts +6 -0
  22. package/bin/app/add/add-local/db/drizzle.d.ts +1 -0
  23. package/bin/app/add/add-local/db/drizzle.js +4 -0
  24. package/bin/app/add/add-local/db/prisma.d.ts +1 -0
  25. package/bin/app/add/add-local/db/prisma.js +4 -0
  26. package/bin/app/add/add-local/files/uploadthing.d.ts +1 -0
  27. package/bin/app/add/add-local/files/uploadthing.js +4 -0
  28. package/bin/app/add/add-local/form/react-hook-form.d.ts +1 -0
  29. package/bin/app/add/add-local/form/react-hook-form.js +4 -0
  30. package/bin/app/add/add-local/form/tanstack-form.d.ts +1 -0
  31. package/bin/app/add/add-local/form/tanstack-form.js +4 -0
  32. package/bin/app/add/add-local/fws/browser/plasmo.d.ts +1 -0
  33. package/bin/app/add/add-local/fws/browser/plasmo.js +4 -0
  34. package/bin/app/add/add-local/fws/browser/wxt.d.ts +1 -0
  35. package/bin/app/add/add-local/fws/browser/wxt.js +4 -0
  36. package/bin/app/add/add-local/fws/configs/eslint-config.d.ts +1 -0
  37. package/bin/app/add/add-local/fws/configs/eslint-config.js +4 -0
  38. package/bin/app/add/add-local/fws/native/lynx.d.ts +1 -0
  39. package/bin/app/add/add-local/fws/native/lynx.js +4 -0
  40. package/bin/app/add/add-local/fws/native/react.d.ts +1 -0
  41. package/bin/app/add/add-local/fws/native/react.js +4 -0
  42. package/bin/app/add/add-local/fws/plugins/eslint-plugin.d.ts +1 -0
  43. package/bin/app/add/add-local/fws/plugins/eslint-plugin.js +4 -0
  44. package/bin/app/add/add-local/fws/vscode/vscode-ext.d.ts +1 -0
  45. package/bin/app/add/add-local/fws/vscode/vscode-ext.js +4 -0
  46. package/bin/app/add/add-local/fws/web/astro.d.ts +1 -0
  47. package/bin/app/add/add-local/fws/web/astro.js +4 -0
  48. package/bin/app/add/add-local/fws/web/jstack.d.ts +1 -0
  49. package/bin/app/add/add-local/fws/web/jstack.js +4 -0
  50. package/bin/app/add/add-local/fws/web/next.d.ts +1 -0
  51. package/bin/app/add/add-local/fws/web/next.js +4 -0
  52. package/bin/app/add/add-local/fws/web/start.d.ts +1 -0
  53. package/bin/app/add/add-local/fws/web/start.js +4 -0
  54. package/bin/app/add/add-local/fws/web/vite.d.ts +1 -0
  55. package/bin/app/add/add-local/fws/web/vite.js +4 -0
  56. package/bin/app/add/add-local/i18n/gt-libs.d.ts +1 -0
  57. package/bin/app/add/add-local/i18n/gt-libs.js +4 -0
  58. package/bin/app/add/add-local/i18n/languine.d.ts +1 -0
  59. package/bin/app/add/add-local/i18n/languine.js +19 -0
  60. package/bin/app/add/add-local/i18n/next-intl.d.ts +1 -0
  61. package/bin/app/add/add-local/i18n/next-intl.js +4 -0
  62. package/bin/app/add/add-local/llm/vercel.d.ts +1 -0
  63. package/bin/app/add/add-local/llm/vercel.js +4 -0
  64. package/bin/app/add/add-local/mail/resend.d.ts +1 -0
  65. package/bin/app/add/add-local/mail/resend.js +4 -0
  66. package/bin/app/add/add-local/pay/polar.d.ts +1 -0
  67. package/bin/app/add/add-local/pay/polar.js +4 -0
  68. package/bin/app/add/add-local/pay/stripe.d.ts +1 -0
  69. package/bin/app/add/add-local/pay/stripe.js +4 -0
  70. package/bin/app/add/add-local/tool/biome.d.ts +1 -0
  71. package/bin/app/add/add-local/tool/biome.js +4 -0
  72. package/bin/app/add/add-local/tool/eslint.d.ts +1 -0
  73. package/bin/app/add/add-local/tool/eslint.js +4 -0
  74. package/bin/app/add/add-local/tool/oxlint.d.ts +4 -0
  75. package/bin/app/add/add-local/tool/oxlint.js +4 -0
  76. package/bin/app/add/add-local/ui/21st.d.ts +4 -0
  77. package/bin/app/add/add-local/ui/21st.js +4 -0
  78. package/bin/app/add/add-local/ui/shadcn.d.ts +1 -0
  79. package/bin/app/add/add-local/ui/shadcn.js +4 -0
  80. package/bin/app/add/add-local/ui/tailwind.d.ts +1 -0
  81. package/bin/app/add/add-local/ui/tailwind.js +4 -0
  82. package/bin/app/add/add-rule/add-rule-const.d.ts +11 -0
  83. package/bin/app/add/add-rule/add-rule-const.js +32 -0
  84. package/bin/app/add/add-rule/add-rule-impl.d.ts +21 -0
  85. package/bin/app/add/add-rule/add-rule-impl.js +300 -0
  86. package/bin/app/add/add-rule/add-rule-mod.d.ts +19 -0
  87. package/bin/app/add/add-rule/add-rule-mod.js +55 -0
  88. package/bin/app/add/add-rule/add-rule-types.d.ts +18 -0
  89. package/bin/app/add/add-rule/add-rule-utils.d.ts +61 -0
  90. package/bin/app/add/add-rule/add-rule-utils.js +324 -0
  91. package/bin/app/add/cmd.d.ts +19 -0
  92. package/bin/app/add/cmd.js +55 -0
  93. package/bin/app/agg/cmd.js +2 -2
  94. package/bin/app/ai/ai-impl/ai-auth.d.ts +10 -0
  95. package/bin/app/ai/ai-impl/ai-auth.js +61 -0
  96. package/bin/app/ai/ai-impl/ai-chat.d.ts +5 -0
  97. package/bin/app/ai/ai-impl/ai-chat.js +93 -0
  98. package/bin/app/ai/ai-impl/ai-const.d.ts +7 -0
  99. package/bin/app/ai/ai-impl/ai-const.js +14 -0
  100. package/bin/app/ai/ai-impl/ai-tools.d.ts +5 -0
  101. package/bin/app/ai/ai-impl/ai-tools.js +32 -0
  102. package/bin/app/ai/ai-impl/ai-types.d.ts +12 -0
  103. package/bin/app/ai/ai-impl/code/code-mod.d.ts +6 -0
  104. package/bin/app/ai/ai-impl/code/code-mod.js +164 -0
  105. package/bin/app/ai/ai-impl/gen/image.d.ts +29 -0
  106. package/bin/app/ai/ai-impl/gen/image.js +77 -0
  107. package/bin/app/ai/ai-impl/mcp/mcp-mod.d.ts +5 -0
  108. package/bin/app/ai/ai-impl/mcp/mcp-mod.js +127 -0
  109. package/bin/app/ai/ai-impl/relinter/relinter.d.ts +27 -0
  110. package/bin/app/ai/ai-impl/relinter/relinter.js +310 -0
  111. package/bin/app/ai/ai-menu.d.ts +3 -0
  112. package/bin/app/ai/ai-menu.js +40 -0
  113. package/bin/app/ai/cmd.d.ts +19 -0
  114. package/bin/app/ai/cmd.js +63 -0
  115. package/bin/app/better/auth/(generators)/auth-config.d.ts +44 -0
  116. package/bin/app/better/auth/(generators)/auth-config.js +537 -0
  117. package/bin/app/better/auth/(generators)/drizzle.d.ts +3 -0
  118. package/bin/app/better/auth/(generators)/drizzle.js +137 -0
  119. package/bin/app/better/auth/(generators)/index.d.ts +16 -0
  120. package/bin/app/better/auth/(generators)/index.js +18 -0
  121. package/bin/app/better/auth/(generators)/kysely.d.ts +2 -0
  122. package/bin/app/better/auth/(generators)/kysely.js +9 -0
  123. package/bin/app/better/auth/(generators)/prisma.d.ts +2 -0
  124. package/bin/app/better/auth/(generators)/prisma.js +154 -0
  125. package/bin/app/better/auth/(generators)/types.d.ts +11 -0
  126. package/bin/app/better/auth/(utils)/add-svelte-kit-env-modules.d.ts +3 -0
  127. package/bin/app/better/auth/(utils)/add-svelte-kit-env-modules.js +91 -0
  128. package/bin/app/better/auth/(utils)/check-package-managers.d.ts +4 -0
  129. package/bin/app/better/auth/(utils)/check-package-managers.js +20 -0
  130. package/bin/app/better/auth/(utils)/format-ms.d.ts +4 -0
  131. package/bin/app/better/auth/(utils)/format-ms.js +11 -0
  132. package/bin/app/better/auth/(utils)/generate-secret.d.ts +1 -0
  133. package/bin/app/better/auth/(utils)/generate-secret.js +4 -0
  134. package/bin/app/better/auth/(utils)/get-config.d.ts +8 -0
  135. package/bin/app/better/auth/(utils)/get-config.js +168 -0
  136. package/bin/app/better/auth/(utils)/get-package-info.d.ts +1 -0
  137. package/bin/app/better/auth/(utils)/get-package-info.js +6 -0
  138. package/bin/app/better/auth/(utils)/get-tsconfig-info.d.ts +2 -0
  139. package/bin/app/better/auth/(utils)/get-tsconfig-info.js +15 -0
  140. package/bin/app/better/auth/(utils)/install-dependencies.d.ts +5 -0
  141. package/bin/app/better/auth/(utils)/install-dependencies.js +34 -0
  142. package/bin/app/better/auth/cmd.d.ts +13 -0
  143. package/bin/app/better/auth/cmd.js +72 -0
  144. package/bin/app/better/auth/consts.d.ts +2 -0
  145. package/bin/app/better/auth/consts.js +2 -0
  146. package/bin/app/better/auth/generate/cmd.d.ts +23 -0
  147. package/bin/app/better/auth/generate/cmd.js +127 -0
  148. package/bin/app/better/auth/generateSecret/cmd.d.ts +2 -0
  149. package/bin/app/better/auth/generateSecret/cmd.js +21 -0
  150. package/bin/app/better/auth/init/cmd.d.ts +160 -0
  151. package/bin/app/better/auth/init/cmd.js +979 -0
  152. package/bin/app/better/auth/migrate/cmd.d.ts +24 -0
  153. package/bin/app/better/auth/migrate/cmd.js +115 -0
  154. package/bin/app/build/binary/cmd.d.ts +12 -5
  155. package/bin/app/build/binary/cmd.js +34 -9
  156. package/bin/app/build/build-library.d.ts +42 -0
  157. package/bin/app/build/build-library.js +632 -0
  158. package/bin/app/build/build-regular.d.ts +19 -0
  159. package/bin/app/build/build-regular.js +400 -0
  160. package/bin/app/build/cmd.js +2 -2
  161. package/bin/app/build/impl.d.ts +1 -1
  162. package/bin/app/build/impl.js +8 -8
  163. package/bin/app/build/library-flow.d.ts +25 -0
  164. package/bin/app/build/library-flow.js +203 -0
  165. package/bin/app/build/postbuild.d.ts +1 -1
  166. package/bin/app/build/postbuild.js +5 -5
  167. package/bin/app/build/prebuild.d.ts +1 -1
  168. package/bin/app/build/prebuild.js +2 -2
  169. package/bin/app/build/providers/auto.d.ts +3 -0
  170. package/bin/app/build/providers/auto.js +105 -0
  171. package/bin/app/build/providers/build.d.ts +8 -0
  172. package/bin/app/build/providers/build.js +351 -0
  173. package/bin/app/build/providers/bun/single-file.js +146 -0
  174. package/bin/app/build/providers/copy/copy-mod.d.ts +2 -0
  175. package/bin/app/build/providers/copy/copy-mod.js +49 -0
  176. package/bin/app/build/providers/mkdist/mkdist-impl/loader.d.ts +4 -0
  177. package/bin/app/build/providers/mkdist/mkdist-impl/loaders/js.d.ts +2 -0
  178. package/bin/app/build/providers/mkdist/mkdist-impl/loaders/loaders-mod.d.ts +12 -0
  179. package/bin/app/build/providers/mkdist/mkdist-impl/loaders/postcss.d.ts +3 -0
  180. package/bin/app/build/providers/mkdist/mkdist-impl/loaders/sass.d.ts +2 -0
  181. package/bin/app/build/providers/mkdist/mkdist-impl/loaders/sass.js +31 -0
  182. package/bin/app/build/providers/mkdist/mkdist-impl/loaders/vue.d.ts +17 -0
  183. package/bin/app/build/providers/mkdist/mkdist-impl/loaders/vue.js +145 -0
  184. package/bin/app/build/providers/mkdist/mkdist-impl/make.d.ts +11 -0
  185. package/bin/app/build/providers/mkdist/mkdist-impl/make.js +192 -0
  186. package/bin/app/build/providers/mkdist/mkdist-impl/utils/dts.d.ts +11 -0
  187. package/bin/app/build/providers/mkdist/mkdist-impl/utils/dts.js +94 -0
  188. package/bin/app/build/providers/mkdist/mkdist-impl/utils/vue-dts.d.ts +3 -0
  189. package/bin/app/build/providers/mkdist/mkdist-impl/utils/vue-dts.js +175 -0
  190. package/bin/app/build/providers/mkdist/mkdist-mod.d.ts +2 -0
  191. package/bin/app/build/providers/mkdist/mkdist-mod.js +92 -0
  192. package/bin/app/build/providers/rollup/build.d.ts +2 -0
  193. package/bin/app/build/providers/rollup/config.d.ts +2 -0
  194. package/bin/app/build/providers/rollup/config.js +112 -0
  195. package/bin/app/build/providers/rollup/plugins/cjs.d.ts +4 -0
  196. package/bin/app/build/providers/rollup/plugins/esbuild.d.ts +3 -0
  197. package/bin/app/build/providers/rollup/plugins/shebang.js +42 -0
  198. package/bin/app/build/providers/rollup/stub.d.ts +2 -0
  199. package/bin/app/build/providers/rollup/stub.js +125 -0
  200. package/bin/app/build/providers/rollup/utils.d.ts +5 -0
  201. package/bin/app/build/providers/rollup/watch.d.ts +2 -0
  202. package/bin/app/build/providers/untyped/untyped-mod.d.ts +2 -0
  203. package/bin/app/build/providers/untyped/untyped-mod.js +111 -0
  204. package/bin/app/build/providers/utils.d.ts +19 -0
  205. package/bin/app/build/providers/utils.js +148 -0
  206. package/bin/app/build/providers/validate.d.ts +4 -0
  207. package/bin/app/build/providers/validate.js +52 -0
  208. package/bin/app/build/regular-flow.d.ts +9 -0
  209. package/bin/app/build/regular-flow.js +173 -0
  210. package/bin/app/catalog/cmd.js +2 -2
  211. package/bin/app/check/cmd.js +14 -14
  212. package/bin/app/cli/cmd.d.ts +12 -0
  213. package/bin/app/cli/cmd.js +56 -0
  214. package/bin/app/cli/impl.d.ts +5 -0
  215. package/bin/app/cli/impl.js +88 -0
  216. package/bin/app/clone/cmd.d.ts +43 -0
  217. package/bin/app/clone/cmd.js +112 -0
  218. package/bin/app/clone/firecrawl/firecrawl-mod.d.ts +1 -0
  219. package/bin/app/clone/firecrawl/firecrawl-mod.js +14 -0
  220. package/bin/app/cmds/inject/inject-impl-mod.js +724 -0
  221. package/bin/app/cmds/transform/transform-impl-mod.js +178 -0
  222. package/bin/app/cmds.d.ts +3 -0
  223. package/bin/app/cmds.js +4 -1
  224. package/bin/app/cmod/cmd.d.ts +31 -0
  225. package/bin/app/cmod/cmd.js +66 -0
  226. package/bin/app/cmod/cmod-impl.d.ts +9 -0
  227. package/bin/app/cmod/cmod-impl.js +21 -0
  228. package/bin/app/config/cfg-biome.d.ts +2 -0
  229. package/bin/app/config/cfg-biome.js +34 -0
  230. package/bin/app/config/cfg-comments.d.ts +1 -0
  231. package/bin/app/config/cfg-comments.js +57 -0
  232. package/bin/app/config/cfg-content.d.ts +14 -0
  233. package/bin/app/config/cfg-content.js +15 -0
  234. package/bin/app/config/cfg-core.d.ts +14 -0
  235. package/bin/app/config/cfg-core.js +63 -0
  236. package/bin/app/config/cfg-create.d.ts +35 -0
  237. package/bin/app/config/cfg-create.js +281 -0
  238. package/bin/app/config/cfg-def-utils.d.ts +6 -0
  239. package/bin/app/config/cfg-def-utils.js +229 -0
  240. package/bin/app/config/cfg-default.d.ts +3 -0
  241. package/bin/app/config/cfg-default.js +155 -0
  242. package/bin/app/config/cfg-detect.d.ts +22 -0
  243. package/bin/app/config/cfg-detect.js +347 -0
  244. package/bin/app/config/cfg-gen-cfg.d.ts +3 -0
  245. package/bin/app/config/cfg-gen-cfg.js +185 -0
  246. package/bin/app/config/cfg-migrate.d.ts +5 -0
  247. package/bin/app/config/cfg-migrate.js +56 -0
  248. package/bin/app/config/cfg-path.d.ts +11 -0
  249. package/bin/app/config/cfg-path.js +33 -0
  250. package/bin/app/config/cfg-prepare.d.ts +2 -0
  251. package/bin/app/config/cfg-prepare.js +302 -0
  252. package/bin/app/config/cfg-prompts.d.ts +5 -0
  253. package/bin/app/config/cfg-prompts.js +12 -0
  254. package/bin/app/config/cfg-read.d.ts +11 -0
  255. package/bin/app/config/cfg-read.js +84 -0
  256. package/bin/app/config/cfg-repair.d.ts +16 -0
  257. package/bin/app/config/cfg-repair.js +137 -0
  258. package/bin/app/config/cfg-schema.d.ts +130 -0
  259. package/bin/app/config/cfg-schema.js +443 -0
  260. package/bin/app/config/cfg-unstable.d.ts +11 -0
  261. package/bin/app/config/cfg-unstable.js +41 -0
  262. package/bin/app/config/cfg-update.d.ts +10 -0
  263. package/bin/app/config/cfg-update.js +152 -0
  264. package/bin/app/config/cfg-utils.d.ts +17 -0
  265. package/bin/app/config/cfg-utils.js +85 -0
  266. package/bin/app/config/cmd.js +1 -1
  267. package/bin/app/config/constants.d.ts +44 -0
  268. package/bin/app/config/constants.js +59 -0
  269. package/bin/app/config/core.js +231 -0
  270. package/bin/app/config/default.d.ts +6 -0
  271. package/bin/app/config/default.js +159 -0
  272. package/bin/app/config/load.d.ts +15 -0
  273. package/bin/app/config/load.js +87 -0
  274. package/bin/app/config/prepare.js +338 -0
  275. package/bin/app/conv/cmd.js +1 -1
  276. package/bin/app/create/cmd.js +4 -4
  277. package/bin/app/cross/mod.js +27 -0
  278. package/bin/app/db/client.d.ts +4 -0
  279. package/bin/app/db/client.js +32 -0
  280. package/bin/app/db/config.d.ts +2 -0
  281. package/bin/app/db/config.js +59 -0
  282. package/bin/app/db/messages.d.ts +13 -0
  283. package/bin/app/db/messages.js +83 -0
  284. package/bin/app/db/schema.d.ts +90 -0
  285. package/bin/app/db/schema.js +9 -0
  286. package/bin/app/env/cmd.d.ts +7 -0
  287. package/bin/app/env/cmd.js +19 -0
  288. package/bin/app/env/env-impl.d.ts +1 -0
  289. package/bin/app/env/env-impl.js +28 -0
  290. package/bin/app/fs/cmd.js +3 -3
  291. package/bin/app/get/cmd.d.ts +1 -1
  292. package/bin/app/get/cmd.js +1 -1
  293. package/bin/app/get/get-impl/get-core.js +453 -0
  294. package/bin/app/get/get-mod.js +68 -0
  295. package/bin/app/help/cmd.d.ts +7 -0
  296. package/bin/app/help/cmd.js +23 -0
  297. package/bin/app/help/help-impl.d.ts +7 -0
  298. package/bin/app/help/help-impl.js +23 -0
  299. package/bin/app/init/cmd-2.d.ts +13 -0
  300. package/bin/app/init/cmd-2.js +68 -0
  301. package/bin/app/init/init-utils/init-impl.d.ts +6 -0
  302. package/bin/app/init/init-utils/init-impl.js +31 -0
  303. package/bin/app/init/init-utils/init-utils.d.ts +35 -0
  304. package/bin/app/init/init-utils/init-utils.js +255 -0
  305. package/bin/app/init/init-utils/mm-deprecated/editor-menu.d.ts +3 -0
  306. package/bin/app/init/init-utils/mm-deprecated/editor-menu.js +404 -0
  307. package/bin/app/init/mm-deprecated/drizzle/manageDrizzleConstants.d.ts +2 -0
  308. package/bin/app/init/mm-deprecated/drizzle/manageDrizzleConstants.js +36 -0
  309. package/bin/app/init/mm-deprecated/drizzle/manageDrizzleSchema.d.ts +1 -0
  310. package/bin/app/init/mm-deprecated/drizzle/manageDrizzleSchema.js +81 -0
  311. package/bin/app/init/mm-deprecated/drizzle/manageDrizzleSchemaUtils.d.ts +16 -0
  312. package/bin/app/init/mm-deprecated/drizzle/manageDrizzleSchemaUtils.js +474 -0
  313. package/bin/app/init/mm-deprecated/editor-impl.d.ts +1 -0
  314. package/bin/app/init/mm-deprecated/editor-impl.js +153 -0
  315. package/bin/app/init/mm-deprecated/editor-mod.d.ts +18 -0
  316. package/bin/app/init/mm-deprecated/editor-mod.js +184 -0
  317. package/bin/app/init/mm-deprecated/feature-add.d.ts +2 -0
  318. package/bin/app/init/mm-deprecated/feature-add.js +591 -0
  319. package/bin/app/init/mm-deprecated/feature-rm.d.ts +2 -0
  320. package/bin/app/init/mm-deprecated/feature-rm.js +98 -0
  321. package/bin/app/init/mm-deprecated/shadcn/shadcn-mod.d.ts +1 -0
  322. package/bin/app/init/mm-deprecated/shadcn/shadcn-mod.js +87 -0
  323. package/bin/app/init/use-template/cp-impl.d.ts +38 -0
  324. package/bin/app/init/use-template/cp-impl.js +286 -0
  325. package/bin/app/init/use-template/cp-mod.d.ts +31 -0
  326. package/bin/app/init/use-template/cp-mod.js +233 -0
  327. package/bin/app/init/use-template/cp-modules/cli-main-modules/cli-menu-items/getMainMenuOptions.d.ts +12 -0
  328. package/bin/app/init/use-template/cp-modules/cli-main-modules/cli-menu-items/getMainMenuOptions.js +69 -0
  329. package/bin/app/init/use-template/cp-modules/cli-main-modules/cli-menu-items/showCloneProjectMenu.d.ts +11 -0
  330. package/bin/app/init/use-template/cp-modules/cli-main-modules/cli-menu-items/showCloneProjectMenu.js +206 -0
  331. package/bin/app/init/use-template/cp-modules/cli-main-modules/modules/showAnykeyPrompt.d.ts +1 -0
  332. package/bin/app/init/use-template/cp-modules/cli-main-modules/modules/showAnykeyPrompt.js +9 -0
  333. package/bin/app/init/use-template/cp-modules/cli-main-modules/modules/showStartEndPrompt.d.ts +2 -0
  334. package/bin/app/init/use-template/cp-modules/cli-main-modules/modules/showStartEndPrompt.js +26 -0
  335. package/bin/app/init/use-template/cp-modules/compose-env-file/cef-impl.d.ts +16 -0
  336. package/bin/app/init/use-template/cp-modules/compose-env-file/cef-impl.js +400 -0
  337. package/bin/app/init/use-template/cp-modules/compose-env-file/cef-keys.d.ts +26 -0
  338. package/bin/app/init/use-template/cp-modules/compose-env-file/cef-keys.js +202 -0
  339. package/bin/app/init/use-template/cp-modules/compose-env-file/cef-mod.d.ts +2 -0
  340. package/bin/app/init/use-template/cp-modules/compose-env-file/cef-mod.js +167 -0
  341. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/deploy.d.ts +11 -0
  342. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/deploy.js +91 -0
  343. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/gdp-mod.d.ts +54 -0
  344. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/gdp-mod.js +449 -0
  345. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/git.d.ts +50 -0
  346. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/git.js +313 -0
  347. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/github.d.ts +8 -0
  348. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/github.js +113 -0
  349. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/helpers/domainHelpers.d.ts +1 -0
  350. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/helpers/domainHelpers.js +25 -0
  351. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/helpers/handlePkgJsonScripts.d.ts +1 -0
  352. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/helpers/handlePkgJsonScripts.js +52 -0
  353. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/helpers/promptForDomain.d.ts +4 -0
  354. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/helpers/promptForDomain.js +39 -0
  355. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/utils-git-github.d.ts +8 -0
  356. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/utils-git-github.js +75 -0
  357. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/utils-private-repo.d.ts +12 -0
  358. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/utils-private-repo.js +165 -0
  359. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/utils-repo-exists.d.ts +9 -0
  360. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/utils-repo-exists.js +62 -0
  361. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-api.d.ts +10 -0
  362. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-api.js +36 -0
  363. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-check.d.ts +14 -0
  364. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-check.js +29 -0
  365. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-config.d.ts +27 -0
  366. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-config.js +104 -0
  367. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-create.d.ts +17 -0
  368. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-create.js +129 -0
  369. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-deploy.d.ts +20 -0
  370. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-deploy.js +151 -0
  371. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-domain.d.ts +5 -0
  372. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-domain.js +44 -0
  373. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-env.d.ts +3 -0
  374. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-env.js +58 -0
  375. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-team.d.ts +15 -0
  376. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-team.js +74 -0
  377. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-types.d.ts +28 -0
  378. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-utils.d.ts +26 -0
  379. package/bin/app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-utils.js +134 -0
  380. package/bin/app/install/cmd.js +3 -7
  381. package/bin/app/invoke/cmd.d.ts +59 -0
  382. package/bin/app/invoke/cmd.js +353 -0
  383. package/bin/app/libs/cmd.js +2 -2
  384. package/bin/app/login/cmd.d.ts +7 -0
  385. package/bin/app/login/cmd.js +41 -0
  386. package/bin/app/login/login-impl.d.ts +7 -0
  387. package/bin/app/login/login-impl.js +182 -0
  388. package/bin/app/logout/cmd.d.ts +7 -0
  389. package/bin/app/logout/cmd.js +47 -0
  390. package/bin/app/logout/logout-impl.d.ts +1 -0
  391. package/bin/app/logout/logout-impl.js +20 -0
  392. package/bin/app/magic/cmd.js +2 -2
  393. package/bin/app/magic/magic-apply.js +669 -0
  394. package/bin/app/memory/cmd.d.ts +2 -0
  395. package/bin/app/memory/cmd.js +26 -0
  396. package/bin/app/memory/memory-impl.d.ts +2 -0
  397. package/bin/app/memory/memory-impl.js +26 -0
  398. package/bin/app/merge/cmd.js +17 -18
  399. package/bin/app/migrate/codemods/anything-bun.js +2 -2
  400. package/bin/app/migrate/codemods/commander-rempts.js +3 -3
  401. package/bin/app/migrate/codemods/console-relinka.js +1 -1
  402. package/bin/app/migrate/codemods/fs-relifso.js +2 -2
  403. package/bin/app/migrate/codemods/nodenext-bundler.js +2 -3
  404. package/bin/app/migrate/codemods/path-pathkit.js +2 -2
  405. package/bin/app/migrate/codemods/readdir-glob.js +2 -2
  406. package/bin/app/mkdist/cmd.js +2 -2
  407. package/bin/app/mrse/cmd.d.ts +41 -0
  408. package/bin/app/mrse/cmd.js +395 -0
  409. package/bin/app/mrse/mrse-impl.d.ts +53 -0
  410. package/bin/app/mrse/mrse-impl.js +132 -0
  411. package/bin/app/pack/cmd.js +4 -4
  412. package/bin/app/providers/better-t-stack/better-t-stack-mod.d.ts +14 -0
  413. package/bin/app/providers/better-t-stack/better-t-stack-mod.js +35 -0
  414. package/bin/app/providers/better-t-stack/better-t-stack-types.d.ts +21 -0
  415. package/bin/app/providers/better-t-stack/better-t-stack-types.js +0 -0
  416. package/bin/app/providers/better-t-stack/constants.d.ts +61 -0
  417. package/bin/app/providers/better-t-stack/constants.js +81 -0
  418. package/bin/app/providers/better-t-stack/helpers/database-providers/mongodb-atlas-setup.d.ts +2 -0
  419. package/bin/app/providers/better-t-stack/helpers/database-providers/mongodb-atlas-setup.js +132 -0
  420. package/bin/app/providers/better-t-stack/helpers/database-providers/neon-setup.d.ts +2 -0
  421. package/bin/app/providers/better-t-stack/helpers/database-providers/neon-setup.js +167 -0
  422. package/bin/app/providers/better-t-stack/helpers/database-providers/prisma-postgres-setup.d.ts +2 -0
  423. package/bin/app/providers/better-t-stack/helpers/database-providers/prisma-postgres-setup.js +161 -0
  424. package/bin/app/providers/better-t-stack/helpers/database-providers/supabase-setup.d.ts +2 -0
  425. package/bin/app/providers/better-t-stack/helpers/database-providers/supabase-setup.js +162 -0
  426. package/bin/app/providers/better-t-stack/helpers/database-providers/turso-setup.d.ts +2 -0
  427. package/bin/app/providers/better-t-stack/helpers/database-providers/turso-setup.js +250 -0
  428. package/bin/app/providers/better-t-stack/helpers/project-generation/create-project.d.ts +2 -0
  429. package/bin/app/providers/better-t-stack/helpers/project-generation/create-project.js +82 -0
  430. package/bin/app/providers/better-t-stack/helpers/project-generation/create-readme.d.ts +2 -0
  431. package/bin/app/providers/better-t-stack/helpers/project-generation/create-readme.js +245 -0
  432. package/bin/app/providers/better-t-stack/helpers/project-generation/env-setup.d.ts +8 -0
  433. package/bin/app/providers/better-t-stack/helpers/project-generation/env-setup.js +193 -0
  434. package/bin/app/providers/better-t-stack/helpers/project-generation/install-dependencies.d.ts +6 -0
  435. package/bin/app/providers/better-t-stack/helpers/project-generation/install-dependencies.js +25 -0
  436. package/bin/app/providers/better-t-stack/helpers/project-generation/post-installation.d.ts +4 -0
  437. package/bin/app/providers/better-t-stack/helpers/project-generation/post-installation.js +228 -0
  438. package/bin/app/providers/better-t-stack/helpers/project-generation/project-config.d.ts +3 -0
  439. package/bin/app/providers/better-t-stack/helpers/project-generation/project-config.js +224 -0
  440. package/bin/app/providers/better-t-stack/helpers/project-generation/template-manager.d.ts +9 -0
  441. package/bin/app/providers/better-t-stack/helpers/project-generation/template-manager.js +484 -0
  442. package/bin/app/providers/better-t-stack/helpers/setup/addons-setup.d.ts +2 -0
  443. package/bin/app/providers/better-t-stack/helpers/setup/addons-setup.js +99 -0
  444. package/bin/app/providers/better-t-stack/helpers/setup/api-setup.d.ts +2 -0
  445. package/bin/app/providers/better-t-stack/helpers/setup/api-setup.js +236 -0
  446. package/bin/app/providers/better-t-stack/helpers/setup/auth-setup.d.ts +3 -0
  447. package/bin/app/providers/better-t-stack/helpers/setup/auth-setup.js +67 -0
  448. package/bin/app/providers/better-t-stack/helpers/setup/backend-setup.d.ts +2 -0
  449. package/bin/app/providers/better-t-stack/helpers/setup/backend-setup.js +52 -0
  450. package/bin/app/providers/better-t-stack/helpers/setup/db-setup.d.ts +2 -0
  451. package/bin/app/providers/better-t-stack/helpers/setup/db-setup.js +84 -0
  452. package/bin/app/providers/better-t-stack/helpers/setup/examples-setup.d.ts +2 -0
  453. package/bin/app/providers/better-t-stack/helpers/setup/examples-setup.js +38 -0
  454. package/bin/app/providers/better-t-stack/helpers/setup/runtime-setup.d.ts +2 -0
  455. package/bin/app/providers/better-t-stack/helpers/setup/runtime-setup.js +79 -0
  456. package/bin/app/providers/better-t-stack/helpers/setup/starlight-setup.d.ts +2 -0
  457. package/bin/app/providers/better-t-stack/helpers/setup/starlight-setup.js +41 -0
  458. package/bin/app/providers/better-t-stack/helpers/setup/tauri-setup.d.ts +2 -0
  459. package/bin/app/providers/better-t-stack/helpers/setup/tauri-setup.js +67 -0
  460. package/bin/app/providers/better-t-stack/index.d.ts +2 -0
  461. package/bin/app/providers/better-t-stack/index.js +282 -0
  462. package/bin/app/providers/better-t-stack/packed/addons.d.ts +2 -0
  463. package/bin/app/providers/better-t-stack/packed/addons.js +263 -0
  464. package/bin/app/providers/better-t-stack/packed/api.d.ts +2 -0
  465. package/bin/app/providers/better-t-stack/packed/api.js +678 -0
  466. package/bin/app/providers/better-t-stack/packed/auth.d.ts +2 -0
  467. package/bin/app/providers/better-t-stack/packed/auth.js +4277 -0
  468. package/bin/app/providers/better-t-stack/packed/backend.d.ts +2 -0
  469. package/bin/app/providers/better-t-stack/packed/backend.js +996 -0
  470. package/bin/app/providers/better-t-stack/packed/base.d.ts +2 -0
  471. package/bin/app/providers/better-t-stack/packed/base.js +32 -0
  472. package/bin/app/providers/better-t-stack/packed/binaries/01dad80fc2.png +0 -0
  473. package/bin/app/providers/better-t-stack/packed/binaries/0ba5eb8b0a.png +0 -0
  474. package/bin/app/providers/better-t-stack/packed/binaries/19b53640a9.png +0 -0
  475. package/bin/app/providers/better-t-stack/packed/binaries/206a875d5d.png +0 -0
  476. package/bin/app/providers/better-t-stack/packed/binaries/2dc8b34485.png +0 -0
  477. package/bin/app/providers/better-t-stack/packed/binaries/3f71f5a845.png +0 -0
  478. package/bin/app/providers/better-t-stack/packed/binaries/6eda863d14.ico +0 -0
  479. package/bin/app/providers/better-t-stack/packed/binaries/70aadde45a.png +0 -0
  480. package/bin/app/providers/better-t-stack/packed/binaries/9ecfcc8f0e.ico +0 -0
  481. package/bin/app/providers/better-t-stack/packed/binaries/9fc7a0c84f.ico +0 -0
  482. package/bin/app/providers/better-t-stack/packed/binaries/b72f6b7339.png +0 -0
  483. package/bin/app/providers/better-t-stack/packed/binaries/cb25ca74dd.png +0 -0
  484. package/bin/app/providers/better-t-stack/packed/binaries/dee83fc2fb.png +0 -0
  485. package/bin/app/providers/better-t-stack/packed/binaries/eda53e30fe.svg +6 -0
  486. package/bin/app/providers/better-t-stack/packed/db.d.ts +2 -0
  487. package/bin/app/providers/better-t-stack/packed/db.js +329 -0
  488. package/bin/app/providers/better-t-stack/packed/examples.d.ts +2 -0
  489. package/bin/app/providers/better-t-stack/packed/examples.js +3470 -0
  490. package/bin/app/providers/better-t-stack/packed/extras.d.ts +2 -0
  491. package/bin/app/providers/better-t-stack/packed/extras.js +33 -0
  492. package/bin/app/providers/better-t-stack/packed/frontend.d.ts +2 -0
  493. package/bin/app/providers/better-t-stack/packed/frontend.js +6116 -0
  494. package/bin/app/providers/better-t-stack/packed/runtime.d.ts +2 -0
  495. package/bin/app/providers/better-t-stack/packed/runtime.js +35 -0
  496. package/bin/app/providers/better-t-stack/prompts/addons.d.ts +2 -0
  497. package/bin/app/providers/better-t-stack/prompts/addons.js +62 -0
  498. package/bin/app/providers/better-t-stack/prompts/api.d.ts +2 -0
  499. package/bin/app/providers/better-t-stack/prompts/api.js +52 -0
  500. package/bin/app/providers/better-t-stack/prompts/auth.d.ts +2 -0
  501. package/bin/app/providers/better-t-stack/prompts/auth.js +19 -0
  502. package/bin/app/providers/better-t-stack/prompts/backend.d.ts +2 -0
  503. package/bin/app/providers/better-t-stack/prompts/backend.js +60 -0
  504. package/bin/app/providers/better-t-stack/prompts/config-prompts.d.ts +2 -0
  505. package/bin/app/providers/better-t-stack/prompts/config-prompts.js +88 -0
  506. package/bin/app/providers/better-t-stack/prompts/database-setup.d.ts +2 -0
  507. package/bin/app/providers/better-t-stack/prompts/database-setup.js +67 -0
  508. package/bin/app/providers/better-t-stack/prompts/database.d.ts +2 -0
  509. package/bin/app/providers/better-t-stack/prompts/database.js +48 -0
  510. package/bin/app/providers/better-t-stack/prompts/examples.d.ts +2 -0
  511. package/bin/app/providers/better-t-stack/prompts/examples.js +44 -0
  512. package/bin/app/providers/better-t-stack/prompts/frontend.d.ts +2 -0
  513. package/bin/app/providers/better-t-stack/prompts/frontend.js +107 -0
  514. package/bin/app/providers/better-t-stack/prompts/git.d.ts +1 -0
  515. package/bin/app/providers/better-t-stack/prompts/git.js +15 -0
  516. package/bin/app/providers/better-t-stack/prompts/install.d.ts +1 -0
  517. package/bin/app/providers/better-t-stack/prompts/install.js +15 -0
  518. package/bin/app/providers/better-t-stack/prompts/orm.d.ts +2 -0
  519. package/bin/app/providers/better-t-stack/prompts/orm.js +43 -0
  520. package/bin/app/providers/better-t-stack/prompts/package-manager.d.ts +2 -0
  521. package/bin/app/providers/better-t-stack/prompts/package-manager.js +29 -0
  522. package/bin/app/providers/better-t-stack/prompts/project-name.d.ts +1 -0
  523. package/bin/app/providers/better-t-stack/prompts/project-name.js +62 -0
  524. package/bin/app/providers/better-t-stack/prompts/runtime.d.ts +2 -0
  525. package/bin/app/providers/better-t-stack/prompts/runtime.js +41 -0
  526. package/bin/app/providers/better-t-stack/types.d.ts +124 -0
  527. package/bin/app/providers/better-t-stack/types.js +29 -0
  528. package/bin/app/providers/better-t-stack/utils/add-package-deps.d.ts +6 -0
  529. package/bin/app/providers/better-t-stack/utils/add-package-deps.js +31 -0
  530. package/bin/app/providers/better-t-stack/utils/analytics.d.ts +2 -0
  531. package/bin/app/providers/better-t-stack/utils/analytics.js +32 -0
  532. package/bin/app/providers/better-t-stack/utils/command-exists.d.ts +1 -0
  533. package/bin/app/providers/better-t-stack/utils/command-exists.js +14 -0
  534. package/bin/app/providers/better-t-stack/utils/display-config.d.ts +2 -0
  535. package/bin/app/providers/better-t-stack/utils/display-config.js +59 -0
  536. package/bin/app/providers/better-t-stack/utils/generate-reproducible-command.d.ts +2 -0
  537. package/bin/app/providers/better-t-stack/utils/generate-reproducible-command.js +39 -0
  538. package/bin/app/providers/better-t-stack/utils/get-latest-cli-version.d.ts +1 -0
  539. package/bin/app/providers/better-t-stack/utils/get-latest-cli-version.js +8 -0
  540. package/bin/app/providers/better-t-stack/utils/get-package-execution-command.d.ts +10 -0
  541. package/bin/app/providers/better-t-stack/utils/get-package-execution-command.js +10 -0
  542. package/bin/app/providers/better-t-stack/utils/get-package-manager.d.ts +2 -0
  543. package/bin/app/providers/better-t-stack/utils/get-package-manager.js +10 -0
  544. package/bin/app/providers/better-t-stack/utils/open-url.d.ts +1 -0
  545. package/bin/app/providers/better-t-stack/utils/open-url.js +22 -0
  546. package/bin/app/providers/better-t-stack/utils/render-title.d.ts +2 -0
  547. package/bin/app/providers/better-t-stack/utils/render-title.js +43 -0
  548. package/bin/app/providers/better-t-stack/utils/sponsors.d.ts +16 -0
  549. package/bin/app/providers/better-t-stack/utils/sponsors.js +37 -0
  550. package/bin/app/providers/better-t-stack/utils/template-processor.d.ts +8 -0
  551. package/bin/app/providers/better-t-stack/utils/template-processor.js +23 -0
  552. package/bin/app/providers/better-t-stack/validation.d.ts +4 -0
  553. package/bin/app/providers/better-t-stack/validation.js +436 -0
  554. package/bin/app/providers/reliverse-stack/reliverse-stack-mod.d.ts +6 -0
  555. package/bin/app/providers/reliverse-stack/reliverse-stack-mod.js +146 -0
  556. package/bin/app/providers/reliverse-stack/rs-impl.d.ts +37 -0
  557. package/bin/app/providers/reliverse-stack/rs-impl.js +367 -0
  558. package/bin/app/pub/cmd.js +2 -2
  559. package/bin/app/pub/impl.d.ts +1 -1
  560. package/bin/app/pub/impl.js +7 -7
  561. package/bin/app/pub/pub-library.d.ts +5 -0
  562. package/bin/app/pub/pub-library.js +122 -0
  563. package/bin/app/pub/pub-regular.d.ts +9 -0
  564. package/bin/app/pub/pub-regular.js +78 -0
  565. package/bin/app/remdn/cmd.js +4 -6
  566. package/bin/app/remove/cmd.js +4 -4
  567. package/bin/app/rempts/cmd.js +1 -1
  568. package/bin/app/rules/reliverse/dler-config-health/dler-config-health.d.ts +2 -0
  569. package/bin/app/rules/reliverse/dler-config-health/dler-config-health.js +37 -0
  570. package/bin/app/rules/reliverse/file-extensions/file-extensions.d.ts +2 -0
  571. package/bin/app/rules/reliverse/file-extensions/file-extensions.js +62 -0
  572. package/bin/app/rules/reliverse/missing-deps/analyzer.js +49 -0
  573. package/bin/app/rules/reliverse/missing-deps/deps-mod.d.ts +2 -0
  574. package/bin/app/rules/reliverse/missing-deps/deps-mod.js +57 -0
  575. package/bin/app/rules/reliverse/missing-deps/deps-types.js +0 -0
  576. package/bin/app/rules/reliverse/missing-deps/formatter.js +101 -0
  577. package/bin/app/rules/reliverse/no-dynamic-imports/no-dynamic-imports.d.ts +7 -0
  578. package/bin/app/rules/reliverse/no-dynamic-imports/no-dynamic-imports.js +89 -0
  579. package/bin/app/rules/reliverse/no-index-files/no-index-files.d.ts +2 -0
  580. package/bin/app/rules/reliverse/package-json-health/package-json-health.d.ts +2 -0
  581. package/bin/app/rules/reliverse/path-extensions/path-extensions.d.ts +2 -0
  582. package/bin/app/rules/reliverse/path-extensions/path-extensions.js +87 -0
  583. package/bin/app/rules/reliverse/self-include/self-include.d.ts +2 -0
  584. package/bin/app/rules/reliverse/self-include/self-include.js +93 -0
  585. package/bin/app/rules/reliverse/tsconfig-health/tsconfig-health.d.ts +2 -0
  586. package/bin/app/rules/rules-mod.d.ts +2 -0
  587. package/bin/app/rules/rules-utils.js +49 -0
  588. package/bin/app/schema/cmd.d.ts +2 -0
  589. package/bin/app/schema/cmd.js +24 -0
  590. package/bin/app/schema/schema-impl.d.ts +2 -0
  591. package/bin/app/schema/schema-impl.js +24 -0
  592. package/bin/app/studio/cmd.d.ts +2 -0
  593. package/bin/app/studio/cmd.js +20 -0
  594. package/bin/app/studio/studio-impl.d.ts +2 -0
  595. package/bin/app/studio/studio-impl.js +20 -0
  596. package/bin/app/toolbox/cmd.d.ts +7 -0
  597. package/bin/app/toolbox/cmd.js +37 -0
  598. package/bin/app/toolbox/toolbox-impl.d.ts +6 -0
  599. package/bin/app/toolbox/toolbox-impl.js +127 -0
  600. package/bin/app/toolbox/toolbox-vercel.d.ts +6 -0
  601. package/bin/app/toolbox/toolbox-vercel.js +105 -0
  602. package/bin/app/types/mod.d.ts +2165 -0
  603. package/bin/app/types/mod.js +162 -0
  604. package/bin/app/update/cmd-2.d.ts +2 -0
  605. package/bin/app/update/cmd-2.js +50 -0
  606. package/bin/app/update/cmd.js +14 -10
  607. package/bin/app/update/migrate/cmd.js +6 -5
  608. package/bin/app/update/update-impl.d.ts +2 -0
  609. package/bin/app/update/update-impl.js +50 -0
  610. package/bin/app/upgrade/cmd.js +2 -2
  611. package/bin/app/upload/cmd.d.ts +17 -0
  612. package/bin/app/upload/cmd.js +67 -0
  613. package/bin/app/upload/providers/providers-mod.d.ts +20 -0
  614. package/bin/app/upload/providers/providers-mod.js +40 -0
  615. package/bin/app/upload/providers/uploadcare.d.ts +13 -0
  616. package/bin/app/upload/providers/uploadcare.js +26 -0
  617. package/bin/app/upload/providers/uploadthing.d.ts +11 -0
  618. package/bin/app/upload/providers/uploadthing.js +31 -0
  619. package/bin/app/upload/upload-utils.d.ts +1 -0
  620. package/bin/app/upload/upload-utils.js +7 -0
  621. package/bin/app/utils/agg/agg-1.js +196 -0
  622. package/bin/app/utils/agg/agg-3.js +197 -0
  623. package/bin/app/utils/agg/agg-5.js +10 -0
  624. package/bin/app/utils/badgeNotifiers.d.ts +2 -0
  625. package/bin/app/utils/badgeNotifiers.js +3 -0
  626. package/bin/app/utils/codemods/convertCjsToEsm.d.ts +1 -0
  627. package/bin/app/utils/codemods/convertCjsToEsm.js +27 -0
  628. package/bin/app/utils/codemods/convertDatabase.d.ts +2 -0
  629. package/bin/app/utils/codemods/convertDatabase.js +229 -0
  630. package/bin/app/utils/codemods/convertDefinitions.d.ts +1 -0
  631. package/bin/app/utils/codemods/convertDefinitions.js +42 -0
  632. package/bin/app/utils/codemods/convertImportStyle.d.ts +1 -0
  633. package/bin/app/utils/codemods/convertImportStyle.js +30 -0
  634. package/bin/app/utils/codemods/convertJsToTs.d.ts +1 -0
  635. package/bin/app/utils/codemods/convertJsToTs.js +99 -0
  636. package/bin/app/utils/codemods/convertQuoteStyle.d.ts +1 -0
  637. package/bin/app/utils/codemods/convertQuoteStyle.js +31 -0
  638. package/bin/app/utils/codemods/convertRuntime.d.ts +1 -0
  639. package/bin/app/utils/codemods/convertRuntime.js +116 -0
  640. package/bin/app/utils/codemods/convertToMonorepo.d.ts +2 -0
  641. package/bin/app/utils/codemods/convertToMonorepo.js +137 -0
  642. package/bin/app/utils/codemods/removeComments.d.ts +1 -0
  643. package/bin/app/utils/codemods/removeComments.js +13 -0
  644. package/bin/app/utils/codemods/removeUnusedDeps.d.ts +1 -0
  645. package/bin/app/utils/codemods/removeUnusedDeps.js +29 -0
  646. package/bin/app/utils/codemods/replaceImportSymbol.d.ts +1 -0
  647. package/bin/app/utils/codemods/replaceImportSymbol.js +57 -0
  648. package/bin/app/utils/codemods/replaceWithModern.d.ts +1 -0
  649. package/bin/app/utils/codemods/replaceWithModern.js +122 -0
  650. package/bin/app/utils/createPackageJSON.d.ts +6 -0
  651. package/bin/app/utils/createPackageJSON.js +20 -0
  652. package/bin/app/utils/decideHelper.d.ts +12 -0
  653. package/bin/app/utils/decideHelper.js +32 -0
  654. package/bin/app/utils/dependencies/getUserPkgManager.d.ts +13 -0
  655. package/bin/app/utils/dependencies/getUserPkgManager.js +178 -0
  656. package/bin/app/utils/downloading/downloadI18nFiles.d.ts +1 -0
  657. package/bin/app/utils/downloading/downloadI18nFiles.js +98 -0
  658. package/bin/app/utils/downloading/downloadRepo.d.ts +41 -0
  659. package/bin/app/utils/downloading/downloadRepo.js +362 -0
  660. package/bin/app/utils/downloading/handleDownload.d.ts +17 -0
  661. package/bin/app/utils/downloading/handleDownload.js +160 -0
  662. package/bin/app/utils/exec/exec-env.js +34 -0
  663. package/bin/app/utils/exec/exec-error.d.ts +7 -0
  664. package/bin/app/utils/exec/exec-error.js +15 -0
  665. package/bin/app/utils/exec/exec-mod.d.ts +58 -0
  666. package/bin/app/utils/exec/exec-mod.js +224 -0
  667. package/bin/app/utils/exec/exec-parse.js +71 -0
  668. package/bin/app/utils/exec/exec-resolve.js +39 -0
  669. package/bin/app/utils/file-type.js +78 -0
  670. package/bin/app/utils/finalize.d.ts +9 -0
  671. package/bin/app/utils/finalize.js +34 -0
  672. package/bin/app/utils/fs-rename.js +108 -0
  673. package/bin/app/utils/getEffectiveDir.d.ts +5 -0
  674. package/bin/app/utils/getEffectiveDir.js +4 -0
  675. package/bin/app/utils/getPackageManager.d.ts +3 -0
  676. package/bin/app/utils/getPackageManager.js +14 -0
  677. package/bin/app/utils/handlers/dependencies.d.ts +1 -0
  678. package/bin/app/utils/handlers/dependencies.js +19 -0
  679. package/bin/app/utils/handlers/handleCleanup.d.ts +1 -0
  680. package/bin/app/utils/handlers/handleCleanup.js +84 -0
  681. package/bin/app/utils/handlers/handleCodemods.d.ts +2 -0
  682. package/bin/app/utils/handlers/handleCodemods.js +203 -0
  683. package/bin/app/utils/handlers/isAppInstalled.d.ts +1 -0
  684. package/bin/app/utils/handlers/isAppInstalled.js +17 -0
  685. package/bin/app/utils/handlers/promptPackageJsonScripts.d.ts +8 -0
  686. package/bin/app/utils/handlers/promptPackageJsonScripts.js +128 -0
  687. package/bin/app/utils/handlers/shadcn.d.ts +19 -0
  688. package/bin/app/utils/handlers/shadcn.js +299 -0
  689. package/bin/app/utils/hasOnlyRseConfig.d.ts +6 -0
  690. package/bin/app/utils/hasOnlyRseConfig.js +15 -0
  691. package/bin/app/utils/init/init-const.d.ts +34 -0
  692. package/bin/app/utils/init/init-const.js +17 -0
  693. package/bin/app/utils/init/init-types.js +0 -0
  694. package/bin/app/utils/instanceGithub.d.ts +29 -0
  695. package/bin/app/utils/instanceGithub.js +50 -0
  696. package/bin/app/utils/instanceVercel.d.ts +16 -0
  697. package/bin/app/utils/instanceVercel.js +39 -0
  698. package/bin/app/utils/microHelpers.d.ts +11 -0
  699. package/bin/app/utils/microHelpers.js +8 -0
  700. package/bin/app/utils/mrseHelpers.d.ts +6 -0
  701. package/bin/app/utils/mrseHelpers.js +21 -0
  702. package/bin/app/utils/native-cli/nc-impl.d.ts +15 -0
  703. package/bin/app/utils/native-cli/nc-impl.js +154 -0
  704. package/bin/app/utils/native-cli/nc-mod.d.ts +3 -0
  705. package/bin/app/utils/native-cli/nc-mod.js +44 -0
  706. package/bin/app/utils/pkgJsonHelpers.d.ts +7 -0
  707. package/bin/app/utils/pkgJsonHelpers.js +15 -0
  708. package/bin/app/utils/pm/pm-api.js +170 -0
  709. package/bin/app/utils/pm/pm-meta.js +86 -0
  710. package/bin/app/utils/pm/pm-types.js +0 -0
  711. package/bin/app/utils/pm/pm-utils.js +115 -0
  712. package/bin/app/utils/projectRepository.d.ts +59 -0
  713. package/bin/app/utils/projectRepository.js +229 -0
  714. package/bin/app/utils/prompts/askAppOrLib.d.ts +1 -0
  715. package/bin/app/utils/prompts/askAppOrLib.js +30 -0
  716. package/bin/app/utils/prompts/askInstallDeps.d.ts +7 -0
  717. package/bin/app/utils/prompts/askInstallDeps.js +40 -0
  718. package/bin/app/utils/prompts/askOpenInIDE.d.ts +5 -0
  719. package/bin/app/utils/prompts/askOpenInIDE.js +43 -0
  720. package/bin/app/utils/prompts/askProjectName.d.ts +3 -0
  721. package/bin/app/utils/prompts/askProjectName.js +21 -0
  722. package/bin/app/utils/prompts/askUsernameFrontend.d.ts +2 -0
  723. package/bin/app/utils/prompts/askUsernameFrontend.js +29 -0
  724. package/bin/app/utils/prompts/askUsernameGithub.d.ts +2 -0
  725. package/bin/app/utils/prompts/askUsernameGithub.js +29 -0
  726. package/bin/app/utils/prompts/shouldInitGit.d.ts +1 -0
  727. package/bin/app/utils/prompts/shouldInitGit.js +8 -0
  728. package/bin/app/utils/reliverseMemory.d.ts +3 -0
  729. package/bin/app/utils/reliverseMemory.js +122 -0
  730. package/bin/app/utils/replacements/reps-impl.d.ts +35 -0
  731. package/bin/app/utils/replacements/reps-impl.js +216 -0
  732. package/bin/app/utils/replacements/reps-keys.d.ts +19 -0
  733. package/bin/app/utils/replacements/reps-keys.js +31 -0
  734. package/bin/app/utils/replacements/reps-mod.d.ts +5 -0
  735. package/bin/app/utils/replacements/reps-mod.js +211 -0
  736. package/bin/app/utils/replacements.d.ts +0 -0
  737. package/bin/app/utils/replacements.js +0 -0
  738. package/bin/app/utils/resolve-cross-libs.js +641 -0
  739. package/bin/app/utils/schemaMemory.d.ts +31 -0
  740. package/bin/app/utils/schemaMemory.js +16 -0
  741. package/bin/app/utils/schemaTemplate.d.ts +52 -0
  742. package/bin/app/utils/schemaTemplate.js +117 -0
  743. package/bin/app/utils/spinner.d.ts +17 -0
  744. package/bin/app/utils/spinner.js +54 -0
  745. package/bin/app/utils/startEndPrompts.d.ts +2 -0
  746. package/bin/app/utils/startEndPrompts.js +14 -0
  747. package/bin/app/utils/terminalHelpers.d.ts +19 -0
  748. package/bin/app/utils/terminalHelpers.js +43 -0
  749. package/bin/app/utils/testsRuntime.d.ts +5 -0
  750. package/bin/app/utils/testsRuntime.js +11 -0
  751. package/bin/app/utils/tsconfigHelpers.d.ts +5 -0
  752. package/bin/app/utils/tsconfigHelpers.js +14 -0
  753. package/bin/app/utils/utils-build.d.ts +33 -0
  754. package/bin/app/utils/utils-clean.d.ts +11 -0
  755. package/bin/app/utils/utils-clean.js +70 -0
  756. package/bin/app/utils/utils-deps.d.ts +5 -0
  757. package/bin/app/utils/utils-determine.d.ts +12 -0
  758. package/bin/app/utils/utils-fs.js +183 -0
  759. package/bin/app/utils/utils-jsr-json.d.ts +9 -0
  760. package/bin/app/utils/utils-jsr-json.js +75 -0
  761. package/bin/app/utils/utils-package-json-libraries.d.ts +10 -0
  762. package/bin/app/utils/utils-package-json-regular.d.ts +8 -0
  763. package/bin/app/utils/utils-package-json-regular.js +165 -0
  764. package/bin/app/utils/utils-perf.d.ts +5 -0
  765. package/bin/app/utils/utils-security.d.ts +12 -0
  766. package/bin/app/utils/utils-security.js +95 -0
  767. package/bin/app/utils/utils-tsconfig.d.ts +10 -0
  768. package/bin/app/utils/utils-tsconfig.js +81 -0
  769. package/bin/app/web/README.md +149 -0
  770. package/bin/app/web/cmd.d.ts +2 -0
  771. package/bin/app/web/cmd.js +11 -0
  772. package/bin/app/x/cmd.js +3 -3
  773. package/bin/dler-go +4 -0
  774. package/bin/dler-rust +4 -0
  775. package/bin/dler.d.ts +1 -0
  776. package/bin/dler.js +98 -0
  777. package/bin/mod.d.ts +294 -1
  778. package/bin/mod.js +734 -4
  779. package/package.json +65 -7
  780. package/bin/cli.js +0 -89
  781. package/bin/libs/cfg/cfg-impl/cfg-dler.d.ts +0 -812
  782. package/bin/libs/cfg/cfg-impl/cfg-dler.js +0 -161
  783. package/bin/libs/cfg/cfg-mod.d.ts +0 -2
  784. package/bin/libs/cfg/cfg-mod.js +0 -1
  785. package/bin/libs/get/get-impl/get-core.js +0 -453
  786. package/bin/libs/get/get-mod.js +0 -88
  787. package/bin/libs/sdk/sdk-impl/build/build-library.d.ts +0 -43
  788. package/bin/libs/sdk/sdk-impl/build/build-library.js +0 -639
  789. package/bin/libs/sdk/sdk-impl/build/build-regular.d.ts +0 -20
  790. package/bin/libs/sdk/sdk-impl/build/build-regular.js +0 -407
  791. package/bin/libs/sdk/sdk-impl/build/providers/auto.d.ts +0 -3
  792. package/bin/libs/sdk/sdk-impl/build/providers/auto.js +0 -105
  793. package/bin/libs/sdk/sdk-impl/build/providers/build.d.ts +0 -8
  794. package/bin/libs/sdk/sdk-impl/build/providers/build.js +0 -351
  795. package/bin/libs/sdk/sdk-impl/build/providers/bun/single-file.js +0 -133
  796. package/bin/libs/sdk/sdk-impl/build/providers/copy/copy-mod.d.ts +0 -2
  797. package/bin/libs/sdk/sdk-impl/build/providers/copy/copy-mod.js +0 -49
  798. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/loader.d.ts +0 -4
  799. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/loaders/js.d.ts +0 -2
  800. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/loaders/loaders-mod.d.ts +0 -12
  801. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/loaders/postcss.d.ts +0 -3
  802. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/loaders/sass.d.ts +0 -2
  803. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/loaders/sass.js +0 -31
  804. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/loaders/vue.d.ts +0 -17
  805. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/loaders/vue.js +0 -145
  806. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/make.d.ts +0 -11
  807. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/make.js +0 -192
  808. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/utils/dts.d.ts +0 -11
  809. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/utils/dts.js +0 -94
  810. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/utils/vue-dts.d.ts +0 -3
  811. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-impl/utils/vue-dts.js +0 -174
  812. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-mod.d.ts +0 -2
  813. package/bin/libs/sdk/sdk-impl/build/providers/mkdist/mkdist-mod.js +0 -92
  814. package/bin/libs/sdk/sdk-impl/build/providers/rollup/build.d.ts +0 -2
  815. package/bin/libs/sdk/sdk-impl/build/providers/rollup/config.d.ts +0 -2
  816. package/bin/libs/sdk/sdk-impl/build/providers/rollup/config.js +0 -113
  817. package/bin/libs/sdk/sdk-impl/build/providers/rollup/plugins/cjs.d.ts +0 -4
  818. package/bin/libs/sdk/sdk-impl/build/providers/rollup/plugins/esbuild.d.ts +0 -3
  819. package/bin/libs/sdk/sdk-impl/build/providers/rollup/plugins/shebang.js +0 -42
  820. package/bin/libs/sdk/sdk-impl/build/providers/rollup/stub.d.ts +0 -2
  821. package/bin/libs/sdk/sdk-impl/build/providers/rollup/stub.js +0 -125
  822. package/bin/libs/sdk/sdk-impl/build/providers/rollup/utils.d.ts +0 -5
  823. package/bin/libs/sdk/sdk-impl/build/providers/rollup/watch.d.ts +0 -2
  824. package/bin/libs/sdk/sdk-impl/build/providers/untyped/untyped-mod.d.ts +0 -2
  825. package/bin/libs/sdk/sdk-impl/build/providers/untyped/untyped-mod.js +0 -111
  826. package/bin/libs/sdk/sdk-impl/build/providers/utils.d.ts +0 -19
  827. package/bin/libs/sdk/sdk-impl/build/providers/utils.js +0 -148
  828. package/bin/libs/sdk/sdk-impl/build/providers/validate.d.ts +0 -4
  829. package/bin/libs/sdk/sdk-impl/build/providers/validate.js +0 -52
  830. package/bin/libs/sdk/sdk-impl/cmds/inject/inject-impl-mod.js +0 -724
  831. package/bin/libs/sdk/sdk-impl/cmds/transform/transform-impl-mod.js +0 -178
  832. package/bin/libs/sdk/sdk-impl/config/core.js +0 -231
  833. package/bin/libs/sdk/sdk-impl/config/default.d.ts +0 -6
  834. package/bin/libs/sdk/sdk-impl/config/default.js +0 -159
  835. package/bin/libs/sdk/sdk-impl/config/info.d.ts +0 -2
  836. package/bin/libs/sdk/sdk-impl/config/info.js +0 -20
  837. package/bin/libs/sdk/sdk-impl/config/load.d.ts +0 -15
  838. package/bin/libs/sdk/sdk-impl/config/load.js +0 -87
  839. package/bin/libs/sdk/sdk-impl/config/prepare.js +0 -338
  840. package/bin/libs/sdk/sdk-impl/config/types.d.ts +0 -734
  841. package/bin/libs/sdk/sdk-impl/constants.d.ts +0 -1
  842. package/bin/libs/sdk/sdk-impl/constants.js +0 -13
  843. package/bin/libs/sdk/sdk-impl/library-flow.d.ts +0 -26
  844. package/bin/libs/sdk/sdk-impl/library-flow.js +0 -203
  845. package/bin/libs/sdk/sdk-impl/magic/magic-apply.js +0 -669
  846. package/bin/libs/sdk/sdk-impl/pub/pub-library.d.ts +0 -5
  847. package/bin/libs/sdk/sdk-impl/pub/pub-library.js +0 -122
  848. package/bin/libs/sdk/sdk-impl/pub/pub-regular.d.ts +0 -9
  849. package/bin/libs/sdk/sdk-impl/pub/pub-regular.js +0 -78
  850. package/bin/libs/sdk/sdk-impl/regular-flow.d.ts +0 -10
  851. package/bin/libs/sdk/sdk-impl/regular-flow.js +0 -173
  852. package/bin/libs/sdk/sdk-impl/rules/reliverse/dler-config-health/dler-config-health.d.ts +0 -2
  853. package/bin/libs/sdk/sdk-impl/rules/reliverse/dler-config-health/dler-config-health.js +0 -37
  854. package/bin/libs/sdk/sdk-impl/rules/reliverse/file-extensions/file-extensions.d.ts +0 -2
  855. package/bin/libs/sdk/sdk-impl/rules/reliverse/file-extensions/file-extensions.js +0 -65
  856. package/bin/libs/sdk/sdk-impl/rules/reliverse/missing-deps/analyzer.js +0 -49
  857. package/bin/libs/sdk/sdk-impl/rules/reliverse/missing-deps/deps-mod.d.ts +0 -2
  858. package/bin/libs/sdk/sdk-impl/rules/reliverse/missing-deps/deps-mod.js +0 -57
  859. package/bin/libs/sdk/sdk-impl/rules/reliverse/missing-deps/formatter.js +0 -101
  860. package/bin/libs/sdk/sdk-impl/rules/reliverse/no-dynamic-imports/no-dynamic-imports.d.ts +0 -8
  861. package/bin/libs/sdk/sdk-impl/rules/reliverse/no-dynamic-imports/no-dynamic-imports.js +0 -89
  862. package/bin/libs/sdk/sdk-impl/rules/reliverse/no-index-files/no-index-files.d.ts +0 -2
  863. package/bin/libs/sdk/sdk-impl/rules/reliverse/package-json-health/package-json-health.d.ts +0 -2
  864. package/bin/libs/sdk/sdk-impl/rules/reliverse/path-extensions/path-extensions.d.ts +0 -2
  865. package/bin/libs/sdk/sdk-impl/rules/reliverse/path-extensions/path-extensions.js +0 -90
  866. package/bin/libs/sdk/sdk-impl/rules/reliverse/self-include/self-include.d.ts +0 -2
  867. package/bin/libs/sdk/sdk-impl/rules/reliverse/self-include/self-include.js +0 -93
  868. package/bin/libs/sdk/sdk-impl/rules/reliverse/tsconfig-health/tsconfig-health.d.ts +0 -2
  869. package/bin/libs/sdk/sdk-impl/rules/rules-mod.d.ts +0 -2
  870. package/bin/libs/sdk/sdk-impl/rules/rules-utils.js +0 -49
  871. package/bin/libs/sdk/sdk-impl/sdk-types.d.ts +0 -415
  872. package/bin/libs/sdk/sdk-impl/utils/agg/agg-1.js +0 -196
  873. package/bin/libs/sdk/sdk-impl/utils/agg/agg-3.js +0 -197
  874. package/bin/libs/sdk/sdk-impl/utils/agg/agg-5.js +0 -17
  875. package/bin/libs/sdk/sdk-impl/utils/exec/exec-env.js +0 -34
  876. package/bin/libs/sdk/sdk-impl/utils/exec/exec-error.d.ts +0 -7
  877. package/bin/libs/sdk/sdk-impl/utils/exec/exec-error.js +0 -15
  878. package/bin/libs/sdk/sdk-impl/utils/exec/exec-mod.d.ts +0 -58
  879. package/bin/libs/sdk/sdk-impl/utils/exec/exec-mod.js +0 -224
  880. package/bin/libs/sdk/sdk-impl/utils/exec/exec-parse.js +0 -71
  881. package/bin/libs/sdk/sdk-impl/utils/exec/exec-resolve.js +0 -39
  882. package/bin/libs/sdk/sdk-impl/utils/file-type.js +0 -78
  883. package/bin/libs/sdk/sdk-impl/utils/finalize.d.ts +0 -10
  884. package/bin/libs/sdk/sdk-impl/utils/finalize.js +0 -34
  885. package/bin/libs/sdk/sdk-impl/utils/fs-rename.js +0 -108
  886. package/bin/libs/sdk/sdk-impl/utils/init/init-const.d.ts +0 -34
  887. package/bin/libs/sdk/sdk-impl/utils/init/init-const.js +0 -17
  888. package/bin/libs/sdk/sdk-impl/utils/pm/pm-api.js +0 -170
  889. package/bin/libs/sdk/sdk-impl/utils/pm/pm-meta.js +0 -86
  890. package/bin/libs/sdk/sdk-impl/utils/pm/pm-utils.js +0 -115
  891. package/bin/libs/sdk/sdk-impl/utils/resolve-cross-libs.js +0 -641
  892. package/bin/libs/sdk/sdk-impl/utils/spinner.d.ts +0 -17
  893. package/bin/libs/sdk/sdk-impl/utils/spinner.js +0 -53
  894. package/bin/libs/sdk/sdk-impl/utils/utils-build.d.ts +0 -33
  895. package/bin/libs/sdk/sdk-impl/utils/utils-clean.d.ts +0 -11
  896. package/bin/libs/sdk/sdk-impl/utils/utils-clean.js +0 -70
  897. package/bin/libs/sdk/sdk-impl/utils/utils-consts.d.ts +0 -9
  898. package/bin/libs/sdk/sdk-impl/utils/utils-consts.js +0 -10
  899. package/bin/libs/sdk/sdk-impl/utils/utils-deps.d.ts +0 -5
  900. package/bin/libs/sdk/sdk-impl/utils/utils-determine.d.ts +0 -12
  901. package/bin/libs/sdk/sdk-impl/utils/utils-fs.js +0 -183
  902. package/bin/libs/sdk/sdk-impl/utils/utils-jsr-json.d.ts +0 -9
  903. package/bin/libs/sdk/sdk-impl/utils/utils-jsr-json.js +0 -75
  904. package/bin/libs/sdk/sdk-impl/utils/utils-package-json-libraries.d.ts +0 -10
  905. package/bin/libs/sdk/sdk-impl/utils/utils-package-json-regular.d.ts +0 -8
  906. package/bin/libs/sdk/sdk-impl/utils/utils-package-json-regular.js +0 -165
  907. package/bin/libs/sdk/sdk-impl/utils/utils-perf.d.ts +0 -5
  908. package/bin/libs/sdk/sdk-impl/utils/utils-security.d.ts +0 -12
  909. package/bin/libs/sdk/sdk-impl/utils/utils-security.js +0 -95
  910. package/bin/libs/sdk/sdk-impl/utils/utils-tsconfig.d.ts +0 -4
  911. package/bin/libs/sdk/sdk-impl/utils/utils-tsconfig.js +0 -44
  912. package/bin/libs/sdk/sdk-mod.d.ts +0 -125
  913. package/bin/libs/sdk/sdk-mod.js +0 -303
  914. /package/bin/{libs/sdk/sdk-impl/build/providers/bun/bun-build.d.ts → app/add/add-global/install-mod.d.ts} +0 -0
  915. /package/bin/{libs/sdk/sdk-impl/build/providers/bun/bun-build.js → app/add/add-global/install-mod.js} +0 -0
  916. /package/bin/{libs/sdk/sdk-impl/config → app/add/add-local/core}/types.js +0 -0
  917. /package/bin/{libs/sdk/sdk-impl/rules/reliverse/missing-deps/deps-types.js → app/add/add-rule/add-rule-types.js} +0 -0
  918. /package/bin/{libs/sdk/sdk-impl/sdk-types.js → app/ai/ai-impl/ai-types.js} +0 -0
  919. /package/bin/{libs/sdk/sdk-impl/utils/init/init-types.js → app/better/auth/(generators)/types.js} +0 -0
  920. /package/bin/{libs/sdk/sdk-impl/utils/pm/pm-types.js → app/build/providers/bun/bun-build.d.ts} +0 -0
  921. /package/bin/{libs/sdk/sdk-impl/utils/replacements.d.ts → app/build/providers/bun/bun-build.js} +0 -0
  922. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/bun/single-file.d.ts +0 -0
  923. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/mkdist/mkdist-impl/loader.js +0 -0
  924. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/mkdist/mkdist-impl/loaders/js.js +0 -0
  925. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/mkdist/mkdist-impl/loaders/loaders-mod.js +0 -0
  926. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/mkdist/mkdist-impl/loaders/postcss.js +0 -0
  927. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/mkdist/mkdist-impl/utils/fs.d.ts +0 -0
  928. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/mkdist/mkdist-impl/utils/fs.js +0 -0
  929. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/build.js +0 -0
  930. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/plugins/cjs.js +0 -0
  931. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/plugins/esbuild.js +0 -0
  932. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/plugins/json.d.ts +0 -0
  933. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/plugins/json.js +0 -0
  934. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/plugins/raw.d.ts +0 -0
  935. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/plugins/raw.js +0 -0
  936. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/plugins/shebang.d.ts +0 -0
  937. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/utils.js +0 -0
  938. /package/bin/{libs/sdk/sdk-impl → app}/build/providers/rollup/watch.js +0 -0
  939. /package/bin/{libs/sdk/sdk-impl → app}/cmds/inject/inject-impl-mod.d.ts +0 -0
  940. /package/bin/{libs/sdk/sdk-impl → app}/cmds/transform/transform-impl-mod.d.ts +0 -0
  941. /package/bin/{libs/sdk/sdk-impl → app}/config/core.d.ts +0 -0
  942. /package/bin/{libs/sdk/sdk-impl → app}/config/prepare.d.ts +0 -0
  943. /package/bin/{cli.d.ts → app/cross/mod.d.ts} +0 -0
  944. /package/bin/{libs → app}/get/get-impl/get-core.d.ts +0 -0
  945. /package/bin/{libs → app}/get/get-mod.d.ts +0 -0
  946. /package/bin/{libs/sdk/sdk-impl/utils/replacements.js → app/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-types.js} +0 -0
  947. /package/bin/{libs/sdk/sdk-impl → app}/magic/magic-apply.d.ts +0 -0
  948. /package/bin/{libs/sdk/sdk-impl → app}/magic/magic-spells.d.ts +0 -0
  949. /package/bin/{libs/sdk/sdk-impl → app}/magic/magic-spells.js +0 -0
  950. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/missing-deps/analyzer.d.ts +0 -0
  951. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/missing-deps/deps-types.d.ts +0 -0
  952. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/missing-deps/filesystem.d.ts +0 -0
  953. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/missing-deps/filesystem.js +0 -0
  954. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/missing-deps/formatter.d.ts +0 -0
  955. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/missing-deps/parser.d.ts +0 -0
  956. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/missing-deps/parser.js +0 -0
  957. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/no-index-files/no-index-files.js +0 -0
  958. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/package-json-health/package-json-health.js +0 -0
  959. /package/bin/{libs/sdk/sdk-impl → app}/rules/reliverse/tsconfig-health/tsconfig-health.js +0 -0
  960. /package/bin/{libs/sdk/sdk-impl → app}/rules/rules-consts.d.ts +0 -0
  961. /package/bin/{libs/sdk/sdk-impl → app}/rules/rules-consts.js +0 -0
  962. /package/bin/{libs/sdk/sdk-impl → app}/rules/rules-mod.js +0 -0
  963. /package/bin/{libs/sdk/sdk-impl → app}/rules/rules-utils.d.ts +0 -0
  964. /package/bin/{libs/sdk/sdk-impl → app}/utils/agg/agg-1.d.ts +0 -0
  965. /package/bin/{libs/sdk/sdk-impl → app}/utils/agg/agg-2.d.ts +0 -0
  966. /package/bin/{libs/sdk/sdk-impl → app}/utils/agg/agg-2.js +0 -0
  967. /package/bin/{libs/sdk/sdk-impl → app}/utils/agg/agg-3.d.ts +0 -0
  968. /package/bin/{libs/sdk/sdk-impl → app}/utils/agg/agg-4.d.ts +0 -0
  969. /package/bin/{libs/sdk/sdk-impl → app}/utils/agg/agg-4.js +0 -0
  970. /package/bin/{libs/sdk/sdk-impl → app}/utils/agg/agg-5.d.ts +0 -0
  971. /package/bin/{libs/sdk/sdk-impl → app}/utils/b-exts.d.ts +0 -0
  972. /package/bin/{libs/sdk/sdk-impl → app}/utils/b-exts.js +0 -0
  973. /package/bin/{libs/sdk/sdk-impl → app}/utils/binary.d.ts +0 -0
  974. /package/bin/{libs/sdk/sdk-impl → app}/utils/binary.js +0 -0
  975. /package/bin/{libs/sdk/sdk-impl → app}/utils/comments.d.ts +0 -0
  976. /package/bin/{libs/sdk/sdk-impl → app}/utils/comments.js +0 -0
  977. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-enoent.d.ts +0 -0
  978. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-enoent.js +0 -0
  979. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-env.d.ts +0 -0
  980. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-escape.d.ts +0 -0
  981. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-escape.js +0 -0
  982. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-parse.d.ts +0 -0
  983. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-resolve.d.ts +0 -0
  984. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-shebang.d.ts +0 -0
  985. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-shebang.js +0 -0
  986. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-spawn.d.ts +0 -0
  987. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-spawn.js +0 -0
  988. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-stream.d.ts +0 -0
  989. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-stream.js +0 -0
  990. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-types.d.ts +0 -0
  991. /package/bin/{libs/sdk/sdk-impl → app}/utils/exec/exec-types.js +0 -0
  992. /package/bin/{libs/sdk/sdk-impl → app}/utils/file-type.d.ts +0 -0
  993. /package/bin/{libs/sdk/sdk-impl → app}/utils/fs-rename.d.ts +0 -0
  994. /package/bin/{libs/sdk/sdk-impl → app}/utils/init/init-impl.d.ts +0 -0
  995. /package/bin/{libs/sdk/sdk-impl → app}/utils/init/init-impl.js +0 -0
  996. /package/bin/{libs/sdk/sdk-impl → app}/utils/init/init-tmpl.d.ts +0 -0
  997. /package/bin/{libs/sdk/sdk-impl → app}/utils/init/init-tmpl.js +0 -0
  998. /package/bin/{libs/sdk/sdk-impl → app}/utils/init/init-types.d.ts +0 -0
  999. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-api.d.ts +0 -0
  1000. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-catalog.d.ts +0 -0
  1001. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-catalog.js +0 -0
  1002. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-detect.d.ts +0 -0
  1003. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-detect.js +0 -0
  1004. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-meta.d.ts +0 -0
  1005. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-parse.d.ts +0 -0
  1006. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-parse.js +0 -0
  1007. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-types.d.ts +0 -0
  1008. /package/bin/{libs/sdk/sdk-impl → app}/utils/pm/pm-utils.d.ts +0 -0
  1009. /package/bin/{libs/sdk/sdk-impl → app}/utils/resolve-cross-libs.d.ts +0 -0
  1010. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-build.js +0 -0
  1011. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-deps.js +0 -0
  1012. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-determine.js +0 -0
  1013. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-error-cwd.d.ts +0 -0
  1014. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-error-cwd.js +0 -0
  1015. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-fs.d.ts +0 -0
  1016. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-misc.d.ts +0 -0
  1017. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-misc.js +0 -0
  1018. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-package-json-libraries.js +0 -0
  1019. /package/bin/{libs/sdk/sdk-impl → app}/utils/utils-perf.js +0 -0
@@ -0,0 +1,3470 @@
1
+ export const DLER_TPL_EXAMPLES = {
2
+ name: "examples",
3
+ description: "Template generated from 31 files",
4
+ updatedAt: "2025-06-17T20:33:59.686Z",
5
+ config: {
6
+ files: {
7
+ "examples/ai/native/nativewind/app/(drawer)/ai.tsx.hbs": {
8
+ metadata: {
9
+ updatedAt: "2025-06-17T06:06:35.000Z",
10
+ updatedHash: "cc30ba62a9"
11
+ },
12
+ content: `import { useRef, useEffect } from "react";
13
+ import {
14
+ View,
15
+ Text,
16
+ TextInput,
17
+ TouchableOpacity,
18
+ ScrollView,
19
+ KeyboardAvoidingView,
20
+ Platform,
21
+ } from "react-native";
22
+ import { useChat } from "@ai-sdk/react";
23
+ import { fetch as expoFetch } from "expo/fetch";
24
+ import { Ionicons } from "@expo/vector-icons";
25
+ import { Container } from "@/components/container";
26
+ // Utility function to generate API URLs
27
+ const generateAPIUrl = (relativePath: string) => {
28
+ const serverUrl = process.env.EXPO_PUBLIC_SERVER_URL;
29
+ if (!serverUrl) {
30
+ throw new Error("EXPO_PUBLIC_SERVER_URL environment variable is not defined");
31
+ }
32
+ const path = relativePath.startsWith('/') ? relativePath : \`/\${relativePath}\`;
33
+ return serverUrl.concat(path);
34
+ };
35
+ export default function AIScreen() {
36
+ const { messages, input, handleInputChange, handleSubmit, error } = useChat({
37
+ fetch: expoFetch as unknown as typeof globalThis.fetch,
38
+ api: generateAPIUrl('/ai'),
39
+ onError: error => console.error(error, 'AI Chat Error'),
40
+ maxSteps: 5,
41
+ });
42
+ const scrollViewRef = useRef<ScrollView>(null);
43
+ useEffect(() => {
44
+ scrollViewRef.current?.scrollToEnd({ animated: true });
45
+ }, [messages]);
46
+ const onSubmit = () => {
47
+ if (input.trim()) {
48
+ handleSubmit();
49
+ }
50
+ };
51
+ if (error) {
52
+ return (
53
+ <Container>
54
+ <View className="flex-1 justify-center items-center px-4">
55
+ <Text className="text-destructive text-center text-lg mb-4">
56
+ Error: {error.message}
57
+ </Text>
58
+ <Text className="text-muted-foreground text-center">
59
+ Please check your connection and try again.
60
+ </Text>
61
+ </View>
62
+ </Container>
63
+ );
64
+ }
65
+ return (
66
+ <Container>
67
+ <KeyboardAvoidingView
68
+ className="flex-1"
69
+ behavior={Platform.OS === "ios" ? "padding" : "height"}
70
+ >
71
+ <View className="flex-1 px-4 py-6">
72
+ <View className="mb-6">
73
+ <Text className="text-foreground text-2xl font-bold mb-2">
74
+ AI Chat
75
+ </Text>
76
+ <Text className="text-muted-foreground">
77
+ Chat with our AI assistant
78
+ </Text>
79
+ </View>
80
+ <ScrollView
81
+ ref={scrollViewRef}
82
+ className="flex-1 mb-4"
83
+ showsVerticalScrollIndicator={false}
84
+ >
85
+ {messages.length === 0 ? (
86
+ <View className="flex-1 justify-center items-center">
87
+ <Text className="text-center text-muted-foreground text-lg">
88
+ Ask me anything to get started!
89
+ </Text>
90
+ </View>
91
+ ) : (
92
+ <View className="space-y-4">
93
+ {messages.map((message) => (
94
+ <View
95
+ key={message.id}
96
+ className={\`p-3 rounded-lg \${
97
+ message.role === "user"
98
+ ? "bg-primary/10 ml-8"
99
+ : "bg-card mr-8 border border-border"
100
+ }\`}
101
+ >
102
+ <Text className="text-sm font-semibold mb-1 text-foreground">
103
+ {message.role === "user" ? "You" : "AI Assistant"}
104
+ </Text>
105
+ <Text className="text-foreground leading-relaxed">
106
+ {message.content}
107
+ </Text>
108
+ </View>
109
+ ))}
110
+ </View>
111
+ )}
112
+ </ScrollView>
113
+ <View className="border-t border-border pt-4">
114
+ <View className="flex-row items-end space-x-2">
115
+ <TextInput
116
+ value={input}
117
+ onChange={(e) =>
118
+ handleInputChange({
119
+ ...e,
120
+ target: {
121
+ ...e.target,
122
+ value: e.nativeEvent.text,
123
+ },
124
+ } as unknown as React.ChangeEvent<HTMLInputElement>)
125
+ }
126
+ placeholder="Type your message..."
127
+ placeholderTextColor="#6b7280"
128
+ className="flex-1 border border-border rounded-md px-3 py-2 text-foreground bg-background min-h-[40px] max-h-[120px]"
129
+ onSubmitEditing={(e) => {
130
+ handleSubmit(e);
131
+ e.preventDefault();
132
+ }}
133
+ autoFocus={true}
134
+ />
135
+ <TouchableOpacity
136
+ onPress={onSubmit}
137
+ disabled={!input.trim()}
138
+ className={\`p-2 rounded-md \${
139
+ input.trim()
140
+ ? "bg-primary"
141
+ : "bg-muted"
142
+ }\`}
143
+ >
144
+ <Ionicons
145
+ name="send"
146
+ size={20}
147
+ color={input.trim() ? "#ffffff" : "#6b7280"}
148
+ />
149
+ </TouchableOpacity>
150
+ </View>
151
+ </View>
152
+ </View>
153
+ </KeyboardAvoidingView>
154
+ </Container>
155
+ );
156
+ } `,
157
+ type: "text"
158
+ },
159
+ "examples/ai/native/nativewind/polyfills.js": {
160
+ metadata: {
161
+ updatedAt: "2025-06-17T06:06:35.000Z",
162
+ updatedHash: "9866d77e7e"
163
+ },
164
+ content: `import structuredClone from "@ungap/structured-clone";
165
+ import { Platform } from "react-native";
166
+ if (Platform.OS !== "web") {
167
+ const setupPolyfills = async () => {
168
+ const { polyfillGlobal } = await import(
169
+ "react-native/Libraries/Utilities/PolyfillFunctions"
170
+ );
171
+ const { TextEncoderStream, TextDecoderStream } = await import(
172
+ "@stardazed/streams-text-encoding"
173
+ );
174
+ if (!("structuredClone" in global)) {
175
+ polyfillGlobal("structuredClone", () => structuredClone);
176
+ }
177
+ polyfillGlobal("TextEncoderStream", () => TextEncoderStream);
178
+ polyfillGlobal("TextDecoderStream", () => TextDecoderStream);
179
+ };
180
+ setupPolyfills();
181
+ }
182
+ export {};
183
+ `,
184
+ type: "text"
185
+ },
186
+ "examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs": {
187
+ metadata: {
188
+ updatedAt: "2025-06-17T06:06:35.000Z",
189
+ updatedHash: "3eab7496a4"
190
+ },
191
+ content: `import { useRef, useEffect } from "react";
192
+ import {
193
+ View,
194
+ Text,
195
+ TextInput,
196
+ TouchableOpacity,
197
+ ScrollView,
198
+ KeyboardAvoidingView,
199
+ Platform,
200
+ } from "react-native";
201
+ import { useChat } from "@ai-sdk/react";
202
+ import { fetch as expoFetch } from "expo/fetch";
203
+ import { Ionicons } from "@expo/vector-icons";
204
+ import { StyleSheet, useUnistyles } from "react-native-unistyles";
205
+ import { Container } from "@/components/container";
206
+ const generateAPIUrl = (relativePath: string) => {
207
+ const serverUrl = process.env.EXPO_PUBLIC_SERVER_URL;
208
+ if (!serverUrl) {
209
+ throw new Error(
210
+ "EXPO_PUBLIC_SERVER_URL environment variable is not defined",
211
+ );
212
+ }
213
+ const path = relativePath.startsWith("/") ? relativePath : \`/\${relativePath}\`;
214
+ return serverUrl.concat(path);
215
+ };
216
+ export default function AIScreen() {
217
+ const { theme } = useUnistyles();
218
+ const { messages, input, handleInputChange, handleSubmit, error } = useChat({
219
+ fetch: expoFetch as unknown as typeof globalThis.fetch,
220
+ api: generateAPIUrl("/ai"),
221
+ onError: (error) => console.error(error, "AI Chat Error"),
222
+ maxSteps: 5,
223
+ });
224
+ const scrollViewRef = useRef<ScrollView>(null);
225
+ useEffect(() => {
226
+ scrollViewRef.current?.scrollToEnd({ animated: true });
227
+ }, [messages]);
228
+ const onSubmit = () => {
229
+ if (input.trim()) {
230
+ handleSubmit();
231
+ }
232
+ };
233
+ if (error) {
234
+ return (
235
+ <Container>
236
+ <View style={styles.errorContainer}>
237
+ <Text style={styles.errorText}>Error: {error.message}</Text>
238
+ <Text style={styles.errorSubtext}>
239
+ Please check your connection and try again.
240
+ </Text>
241
+ </View>
242
+ </Container>
243
+ );
244
+ }
245
+ return (
246
+ <Container>
247
+ <KeyboardAvoidingView
248
+ style={styles.container}
249
+ behavior={Platform.OS === "ios" ? "padding" : "height"}
250
+ >
251
+ <View style={styles.content}>
252
+ <View style={styles.header}>
253
+ <Text style={styles.headerTitle}>AI Chat</Text>
254
+ <Text style={styles.headerSubtitle}>
255
+ Chat with our AI assistant
256
+ </Text>
257
+ </View>
258
+ <ScrollView
259
+ ref={scrollViewRef}
260
+ style={styles.messagesContainer}
261
+ showsVerticalScrollIndicator={false}
262
+ >
263
+ {messages.length === 0 ? (
264
+ <View style={styles.emptyContainer}>
265
+ <Text style={styles.emptyText}>
266
+ Ask me anything to get started!
267
+ </Text>
268
+ </View>
269
+ ) : (
270
+ <View style={styles.messagesWrapper}>
271
+ {messages.map((message) => (
272
+ <View
273
+ key={message.id}
274
+ style={[
275
+ styles.messageContainer,
276
+ message.role === "user"
277
+ ? styles.userMessage
278
+ : styles.assistantMessage,
279
+ ]}
280
+ >
281
+ <Text style={styles.messageRole}>
282
+ {message.role === "user" ? "You" : "AI Assistant"}
283
+ </Text>
284
+ <Text style={styles.messageContent}>{message.content}</Text>
285
+ </View>
286
+ ))}
287
+ </View>
288
+ )}
289
+ </ScrollView>
290
+ <View style={styles.inputSection}>
291
+ <View style={styles.inputContainer}>
292
+ <TextInput
293
+ value={input}
294
+ onChange={(e) =>
295
+ handleInputChange({
296
+ ...e,
297
+ target: {
298
+ ...e.target,
299
+ value: e.nativeEvent.text,
300
+ },
301
+ } as unknown as React.ChangeEvent<HTMLInputElement>)
302
+ }
303
+ placeholder="Type your message..."
304
+ placeholderTextColor={theme.colors.border}
305
+ style={styles.textInput}
306
+ onSubmitEditing={(e) => {
307
+ handleSubmit(e);
308
+ e.preventDefault();
309
+ }}
310
+ autoFocus={true}
311
+ />
312
+ <TouchableOpacity
313
+ onPress={onSubmit}
314
+ disabled={!input.trim()}
315
+ style={[
316
+ styles.sendButton,
317
+ !input.trim() && styles.sendButtonDisabled,
318
+ ]}
319
+ >
320
+ <Ionicons
321
+ name="send"
322
+ size={20}
323
+ color={
324
+ input.trim() ? theme.colors.background : theme.colors.border
325
+ }
326
+ />
327
+ </TouchableOpacity>
328
+ </View>
329
+ </View>
330
+ </View>
331
+ </KeyboardAvoidingView>
332
+ </Container>
333
+ );
334
+ }
335
+ const styles = StyleSheet.create((theme) => ({
336
+ container: {
337
+ flex: 1,
338
+ },
339
+ content: {
340
+ flex: 1,
341
+ paddingHorizontal: theme.spacing.md,
342
+ paddingVertical: theme.spacing.lg,
343
+ },
344
+ errorContainer: {
345
+ flex: 1,
346
+ justifyContent: "center",
347
+ alignItems: "center",
348
+ paddingHorizontal: theme.spacing.md,
349
+ },
350
+ errorText: {
351
+ color: theme.colors.destructive,
352
+ textAlign: "center",
353
+ fontSize: 18,
354
+ marginBottom: theme.spacing.md,
355
+ },
356
+ errorSubtext: {
357
+ color: theme.colors.typography,
358
+ textAlign: "center",
359
+ fontSize: 16,
360
+ },
361
+ header: {
362
+ marginBottom: theme.spacing.lg,
363
+ },
364
+ headerTitle: {
365
+ fontSize: 28,
366
+ fontWeight: "bold",
367
+ color: theme.colors.typography,
368
+ marginBottom: theme.spacing.sm,
369
+ },
370
+ headerSubtitle: {
371
+ fontSize: 16,
372
+ color: theme.colors.typography,
373
+ },
374
+ messagesContainer: {
375
+ flex: 1,
376
+ marginBottom: theme.spacing.md,
377
+ },
378
+ emptyContainer: {
379
+ flex: 1,
380
+ justifyContent: "center",
381
+ alignItems: "center",
382
+ },
383
+ emptyText: {
384
+ textAlign: "center",
385
+ color: theme.colors.typography,
386
+ fontSize: 18,
387
+ },
388
+ messagesWrapper: {
389
+ gap: theme.spacing.md,
390
+ },
391
+ messageContainer: {
392
+ padding: theme.spacing.md,
393
+ borderRadius: 8,
394
+ },
395
+ userMessage: {
396
+ backgroundColor: theme.colors.primary + "20",
397
+ marginLeft: theme.spacing.xl,
398
+ alignSelf: "flex-end",
399
+ },
400
+ assistantMessage: {
401
+ backgroundColor: theme.colors.background,
402
+ marginRight: theme.spacing.xl,
403
+ borderWidth: 1,
404
+ borderColor: theme.colors.border,
405
+ },
406
+ messageRole: {
407
+ fontSize: 14,
408
+ fontWeight: "600",
409
+ marginBottom: theme.spacing.sm,
410
+ color: theme.colors.typography,
411
+ },
412
+ messageContent: {
413
+ color: theme.colors.typography,
414
+ lineHeight: 20,
415
+ },
416
+ toolInvocations: {
417
+ fontSize: 12,
418
+ color: theme.colors.typography,
419
+ fontFamily: "monospace",
420
+ backgroundColor: theme.colors.border + "40",
421
+ padding: theme.spacing.sm,
422
+ borderRadius: 4,
423
+ marginTop: theme.spacing.sm,
424
+ },
425
+ inputSection: {
426
+ borderTopWidth: 1,
427
+ borderTopColor: theme.colors.border,
428
+ paddingTop: theme.spacing.md,
429
+ },
430
+ inputContainer: {
431
+ flexDirection: "row",
432
+ alignItems: "flex-end",
433
+ gap: theme.spacing.sm,
434
+ },
435
+ textInput: {
436
+ flex: 1,
437
+ borderWidth: 1,
438
+ borderColor: theme.colors.border,
439
+ borderRadius: 8,
440
+ paddingHorizontal: theme.spacing.md,
441
+ paddingVertical: theme.spacing.sm,
442
+ color: theme.colors.typography,
443
+ backgroundColor: theme.colors.background,
444
+ fontSize: 16,
445
+ minHeight: 40,
446
+ maxHeight: 120,
447
+ },
448
+ sendButton: {
449
+ backgroundColor: theme.colors.primary,
450
+ padding: theme.spacing.sm,
451
+ borderRadius: 8,
452
+ justifyContent: "center",
453
+ alignItems: "center",
454
+ },
455
+ sendButtonDisabled: {
456
+ backgroundColor: theme.colors.border,
457
+ },
458
+ }));
459
+ `,
460
+ type: "text"
461
+ },
462
+ "examples/ai/native/unistyles/polyfills.js": {
463
+ metadata: {
464
+ updatedAt: "2025-06-17T06:06:35.000Z",
465
+ updatedHash: "9866d77e7e"
466
+ },
467
+ content: `import structuredClone from "@ungap/structured-clone";
468
+ import { Platform } from "react-native";
469
+ if (Platform.OS !== "web") {
470
+ const setupPolyfills = async () => {
471
+ const { polyfillGlobal } = await import(
472
+ "react-native/Libraries/Utilities/PolyfillFunctions"
473
+ );
474
+ const { TextEncoderStream, TextDecoderStream } = await import(
475
+ "@stardazed/streams-text-encoding"
476
+ );
477
+ if (!("structuredClone" in global)) {
478
+ polyfillGlobal("structuredClone", () => structuredClone);
479
+ }
480
+ polyfillGlobal("TextEncoderStream", () => TextEncoderStream);
481
+ polyfillGlobal("TextDecoderStream", () => TextDecoderStream);
482
+ };
483
+ setupPolyfills();
484
+ }
485
+ export {};
486
+ `,
487
+ type: "text"
488
+ },
489
+ "examples/ai/server/next/src/app/ai/route.ts": {
490
+ metadata: {
491
+ updatedAt: "2025-06-17T06:06:35.000Z",
492
+ updatedHash: "eee0d6a73d"
493
+ },
494
+ content: `import { google } from '@ai-sdk/google';
495
+ import { streamText } from 'ai';
496
+ export const maxDuration = 30;
497
+ export async function POST(req: Request) {
498
+ const { messages } = await req.json();
499
+ const result = streamText({
500
+ model: google('gemini-2.0-flash'),
501
+ messages,
502
+ });
503
+ return result.toDataStreamResponse();
504
+ }
505
+ `,
506
+ type: "text"
507
+ },
508
+ "examples/ai/web/nuxt/app/pages/ai.vue": {
509
+ metadata: {
510
+ updatedAt: "2025-06-17T06:06:35.000Z",
511
+ updatedHash: "7dd81ef739"
512
+ },
513
+ content: `<script setup lang="ts">
514
+ import { useChat } from '@ai-sdk/vue'
515
+ import { nextTick, ref, watch } from 'vue'
516
+ const config = useRuntimeConfig()
517
+ const serverUrl = config.public.serverURL
518
+ const { messages, input, handleSubmit } = useChat({
519
+ api: \`\${serverUrl}/ai\`,
520
+ })
521
+ const messagesEndRef = ref<null | HTMLDivElement>(null)
522
+ watch(messages, async () => {
523
+ await nextTick()
524
+ messagesEndRef.value?.scrollIntoView({ behavior: 'smooth' })
525
+ })
526
+ function getMessageText(message: any) {
527
+ return message.parts
528
+ .filter((part: any) => part.type === 'text')
529
+ .map((part: any) => part.text)
530
+ .join('')
531
+ }
532
+ <\/script>
533
+ <template>
534
+ <div class="grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4">
535
+ <div class="overflow-y-auto space-y-4 pb-4">
536
+ <div v-if="messages.length === 0" class="text-center text-muted-foreground mt-8">
537
+ Ask me anything to get started!
538
+ </div>
539
+ <div
540
+ v-for="message in messages"
541
+ :key="message.id"
542
+ :class="[
543
+ 'p-3 rounded-lg',
544
+ message.role === 'user' ? 'bg-primary/10 ml-8' : 'bg-secondary/20 mr-8'
545
+ ]"
546
+ >
547
+ <p class="text-sm font-semibold mb-1">
548
+ {{ message.role === 'user' ? 'You' : 'AI Assistant' }}
549
+ </p>
550
+ <div class="whitespace-pre-wrap">{{ getMessageText(message) }}</div>
551
+ </div>
552
+ <div ref="messagesEndRef" />
553
+ </div>
554
+ <form @submit.prevent="handleSubmit" class="w-full flex items-center space-x-2 pt-2 border-t">
555
+ <UInput
556
+ name="prompt"
557
+ v-model="input"
558
+ placeholder="Type your message..."
559
+ class="flex-1"
560
+ autocomplete="off"
561
+ autofocus
562
+ />
563
+ <UButton type="submit" color="primary" size="md" square>
564
+ <UIcon name="i-lucide-send" class="w-5 h-5" />
565
+ </UButton>
566
+ </form>
567
+ </div>
568
+ </template>
569
+ `,
570
+ type: "text"
571
+ },
572
+ "examples/ai/web/react/next/src/app/ai/page.tsx": {
573
+ metadata: {
574
+ updatedAt: "2025-06-17T06:06:35.000Z",
575
+ updatedHash: "0c366c76eb"
576
+ },
577
+ content: `"use client"
578
+ import { useChat } from "@ai-sdk/react";
579
+ import { Input } from "@/components/ui/input";
580
+ import { Button } from "@/components/ui/button";
581
+ import { Send } from "lucide-react";
582
+ import { useRef, useEffect } from "react";
583
+ export default function AIPage() {
584
+ const { messages, input, handleInputChange, handleSubmit } = useChat({
585
+ api: \`\${process.env.NEXT_PUBLIC_SERVER_URL}/ai\`,
586
+ });
587
+ const messagesEndRef = useRef<HTMLDivElement>(null);
588
+ useEffect(() => {
589
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
590
+ }, [messages]);
591
+ return (
592
+ <div className="grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4">
593
+ <div className="overflow-y-auto space-y-4 pb-4">
594
+ {messages.length === 0 ? (
595
+ <div className="text-center text-muted-foreground mt-8">
596
+ Ask me anything to get started!
597
+ </div>
598
+ ) : (
599
+ messages.map((message) => (
600
+ <div
601
+ key={message.id}
602
+ className={\`p-3 rounded-lg \${
603
+ message.role === "user"
604
+ ? "bg-primary/10 ml-8"
605
+ : "bg-secondary/20 mr-8"
606
+ }\`}
607
+ >
608
+ <p className="text-sm font-semibold mb-1">
609
+ {message.role === "user" ? "You" : "AI Assistant"}
610
+ </p>
611
+ <div className="whitespace-pre-wrap">{message.content}</div>
612
+ </div>
613
+ ))
614
+ )}
615
+ <div ref={messagesEndRef} />
616
+ </div>
617
+ <form
618
+ onSubmit={handleSubmit}
619
+ className="w-full flex items-center space-x-2 pt-2 border-t"
620
+ >
621
+ <Input
622
+ name="prompt"
623
+ value={input}
624
+ onChange={handleInputChange}
625
+ placeholder="Type your message..."
626
+ className="flex-1"
627
+ autoComplete="off"
628
+ autoFocus
629
+ />
630
+ <Button type="submit" size="icon">
631
+ <Send size={18} />
632
+ </Button>
633
+ </form>
634
+ </div>
635
+ );
636
+ }
637
+ `,
638
+ type: "text"
639
+ },
640
+ "examples/ai/web/react/react-router/src/routes/ai.tsx": {
641
+ metadata: {
642
+ updatedAt: "2025-06-17T06:06:35.000Z",
643
+ updatedHash: "47e1850967"
644
+ },
645
+ content: `import { useChat } from "@ai-sdk/react";
646
+ import { Input } from "@/components/ui/input";
647
+ import { Button } from "@/components/ui/button";
648
+ import { Send } from "lucide-react";
649
+ import { useRef, useEffect } from "react";
650
+ export default function AI() {
651
+ const { messages, input, handleInputChange, handleSubmit } = useChat({
652
+ api: \`\${import.meta.env.VITE_SERVER_URL}/ai\`,
653
+ });
654
+ const messagesEndRef = useRef<HTMLDivElement>(null);
655
+ useEffect(() => {
656
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
657
+ }, [messages]);
658
+ return (
659
+ <div className="grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4">
660
+ <div className="overflow-y-auto space-y-4 pb-4">
661
+ {messages.length === 0 ? (
662
+ <div className="text-center text-muted-foreground mt-8">
663
+ Ask me anything to get started!
664
+ </div>
665
+ ) : (
666
+ messages.map((message) => (
667
+ <div
668
+ key={message.id}
669
+ className={\`p-3 rounded-lg \${
670
+ message.role === "user"
671
+ ? "bg-primary/10 ml-8"
672
+ : "bg-secondary/20 mr-8"
673
+ }\`}
674
+ >
675
+ <p className="text-sm font-semibold mb-1">
676
+ {message.role === "user" ? "You" : "AI Assistant"}
677
+ </p>
678
+ <div className="whitespace-pre-wrap">{message.content}</div>
679
+ </div>
680
+ ))
681
+ )}
682
+ <div ref={messagesEndRef} />
683
+ </div>
684
+ <form
685
+ onSubmit={handleSubmit}
686
+ className="w-full flex items-center space-x-2 pt-2 border-t"
687
+ >
688
+ <Input
689
+ name="prompt"
690
+ value={input}
691
+ onChange={handleInputChange}
692
+ placeholder="Type your message..."
693
+ className="flex-1"
694
+ autoComplete="off"
695
+ autoFocus
696
+ />
697
+ <Button type="submit" size="icon">
698
+ <Send size={18} />
699
+ </Button>
700
+ </form>
701
+ </div>
702
+ );
703
+ }
704
+ `,
705
+ type: "text"
706
+ },
707
+ "examples/ai/web/react/tanstack-router/src/routes/ai.tsx": {
708
+ metadata: {
709
+ updatedAt: "2025-06-17T06:06:35.000Z",
710
+ updatedHash: "64b5db59bb"
711
+ },
712
+ content: `import { createFileRoute } from "@tanstack/react-router";
713
+ import { useChat } from "@ai-sdk/react";
714
+ import { Input } from "@/components/ui/input";
715
+ import { Button } from "@/components/ui/button";
716
+ import { Send } from "lucide-react";
717
+ import { useRef, useEffect } from "react";
718
+ export const Route = createFileRoute("/ai")({
719
+ component: RouteComponent,
720
+ });
721
+ function RouteComponent() {
722
+ const { messages, input, handleInputChange, handleSubmit } = useChat({
723
+ api: \`\${import.meta.env.VITE_SERVER_URL}/ai\`,
724
+ });
725
+ const messagesEndRef = useRef<HTMLDivElement>(null);
726
+ useEffect(() => {
727
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
728
+ }, [messages]);
729
+ return (
730
+ <div className="grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4">
731
+ <div className="overflow-y-auto space-y-4 pb-4">
732
+ {messages.length === 0 ? (
733
+ <div className="text-center text-muted-foreground mt-8">
734
+ Ask me anything to get started!
735
+ </div>
736
+ ) : (
737
+ messages.map((message) => (
738
+ <div
739
+ key={message.id}
740
+ className={\`p-3 rounded-lg \${
741
+ message.role === "user"
742
+ ? "bg-primary/10 ml-8"
743
+ : "bg-secondary/20 mr-8"
744
+ }\`}
745
+ >
746
+ <p className="text-sm font-semibold mb-1">
747
+ {message.role === "user" ? "You" : "AI Assistant"}
748
+ </p>
749
+ <div className="whitespace-pre-wrap">{message.content}</div>
750
+ </div>
751
+ ))
752
+ )}
753
+ <div ref={messagesEndRef} />
754
+ </div>
755
+ <form
756
+ onSubmit={handleSubmit}
757
+ className="w-full flex items-center space-x-2 pt-2 border-t"
758
+ >
759
+ <Input
760
+ name="prompt"
761
+ value={input}
762
+ onChange={handleInputChange}
763
+ placeholder="Type your message..."
764
+ className="flex-1"
765
+ autoComplete="off"
766
+ autoFocus
767
+ />
768
+ <Button type="submit" size="icon">
769
+ <Send size={18} />
770
+ </Button>
771
+ </form>
772
+ </div>
773
+ );
774
+ }
775
+ `,
776
+ type: "text"
777
+ },
778
+ "examples/ai/web/react/tanstack-start/src/routes/ai.tsx": {
779
+ metadata: {
780
+ updatedAt: "2025-06-17T06:06:35.000Z",
781
+ updatedHash: "64b5db59bb"
782
+ },
783
+ content: `import { createFileRoute } from "@tanstack/react-router";
784
+ import { useChat } from "@ai-sdk/react";
785
+ import { Input } from "@/components/ui/input";
786
+ import { Button } from "@/components/ui/button";
787
+ import { Send } from "lucide-react";
788
+ import { useRef, useEffect } from "react";
789
+ export const Route = createFileRoute("/ai")({
790
+ component: RouteComponent,
791
+ });
792
+ function RouteComponent() {
793
+ const { messages, input, handleInputChange, handleSubmit } = useChat({
794
+ api: \`\${import.meta.env.VITE_SERVER_URL}/ai\`,
795
+ });
796
+ const messagesEndRef = useRef<HTMLDivElement>(null);
797
+ useEffect(() => {
798
+ messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
799
+ }, [messages]);
800
+ return (
801
+ <div className="grid grid-rows-[1fr_auto] overflow-hidden w-full mx-auto p-4">
802
+ <div className="overflow-y-auto space-y-4 pb-4">
803
+ {messages.length === 0 ? (
804
+ <div className="text-center text-muted-foreground mt-8">
805
+ Ask me anything to get started!
806
+ </div>
807
+ ) : (
808
+ messages.map((message) => (
809
+ <div
810
+ key={message.id}
811
+ className={\`p-3 rounded-lg \${
812
+ message.role === "user"
813
+ ? "bg-primary/10 ml-8"
814
+ : "bg-secondary/20 mr-8"
815
+ }\`}
816
+ >
817
+ <p className="text-sm font-semibold mb-1">
818
+ {message.role === "user" ? "You" : "AI Assistant"}
819
+ </p>
820
+ <div className="whitespace-pre-wrap">{message.content}</div>
821
+ </div>
822
+ ))
823
+ )}
824
+ <div ref={messagesEndRef} />
825
+ </div>
826
+ <form
827
+ onSubmit={handleSubmit}
828
+ className="w-full flex items-center space-x-2 pt-2 border-t"
829
+ >
830
+ <Input
831
+ name="prompt"
832
+ value={input}
833
+ onChange={handleInputChange}
834
+ placeholder="Type your message..."
835
+ className="flex-1"
836
+ autoComplete="off"
837
+ autoFocus
838
+ />
839
+ <Button type="submit" size="icon">
840
+ <Send size={18} />
841
+ </Button>
842
+ </form>
843
+ </div>
844
+ );
845
+ }
846
+ `,
847
+ type: "text"
848
+ },
849
+ "examples/ai/web/svelte/src/routes/ai/+page.svelte": {
850
+ metadata: {
851
+ updatedAt: "2025-06-17T06:06:35.000Z",
852
+ updatedHash: "a6b5e9020b"
853
+ },
854
+ content: `<script lang="ts">
855
+ import { PUBLIC_SERVER_URL } from '$env/static/public';
856
+ import { Chat } from '@ai-sdk/svelte';
857
+ const chat = new Chat({
858
+ api: \`\${PUBLIC_SERVER_URL}/ai\`,
859
+ });
860
+ let messagesEndElement: HTMLDivElement | null = null;
861
+ $effect(() => {
862
+ const messageCount = chat.messages.length;
863
+ if (messageCount > 0) {
864
+ setTimeout(() => {
865
+ messagesEndElement?.scrollIntoView({ behavior: 'smooth' });
866
+ }, 0);
867
+ }
868
+ });
869
+ <\/script>
870
+ <div class="mx-auto grid h-full w-full max-w-2xl grid-rows-[1fr_auto] overflow-hidden p-4">
871
+ <div class="mb-4 space-y-4 overflow-y-auto pb-4">
872
+ {#if chat.messages.length === 0}
873
+ <div class="mt-8 text-center text-neutral-500">Ask the AI anything to get started!</div>
874
+ {/if}
875
+ {#each chat.messages as message (message.id)}
876
+ <div
877
+ class="w-fit max-w-[85%] rounded-lg p-3 text-sm md:text-base"
878
+ class:ml-auto={message.role === 'user'}
879
+ class:bg-indigo-600={message.role === 'user'}
880
+ class:text-white={message.role === 'user'}
881
+ class:bg-neutral-700={message.role === 'assistant'}
882
+ class:text-neutral-100={message.role === 'assistant'}
883
+ >
884
+ <p
885
+ class="mb-1 text-xs font-semibold uppercase tracking-wide"
886
+ class:text-indigo-200={message.role === 'user'}
887
+ class:text-neutral-400={message.role === 'assistant'}
888
+ >
889
+ {message.role === 'user' ? 'You' : 'AI Assistant'}
890
+ </p>
891
+ <div class="whitespace-pre-wrap break-words">
892
+ {#each message.parts as part, partIndex (partIndex)}
893
+ {#if part.type === 'text'}
894
+ {part.text}
895
+ {:else if part.type === 'tool-invocation'}
896
+ <pre class="mt-2 rounded bg-neutral-800 p-2 text-xs text-neutral-300"
897
+ >{JSON.stringify(part.toolInvocation, null, 2)}</pre
898
+ >
899
+ {/if}
900
+ {/each}
901
+ </div>
902
+ </div>
903
+ {/each}
904
+ <div bind:this={messagesEndElement}></div>
905
+ </div>
906
+ <form
907
+ onsubmit={chat.handleSubmit}
908
+ class="flex w-full items-center space-x-2 border-t border-neutral-700 pt-4"
909
+ >
910
+ <input
911
+ name="prompt"
912
+ bind:value={chat.input}
913
+ placeholder="Type your message..."
914
+ class="flex-1 rounded border border-neutral-600 bg-neutral-800 px-3 py-2 text-neutral-100 placeholder-neutral-500 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500 disabled:opacity-50"
915
+ autocomplete="off"
916
+ onkeydown={(e) => {
917
+ if (e.key === 'Enter' && !e.shiftKey) {
918
+ e.preventDefault();
919
+ chat.handleSubmit(e);
920
+ }
921
+ }}
922
+ />
923
+ <button
924
+ type="submit"
925
+ disabled={!chat.input.trim()}
926
+ class="inline-flex h-10 w-10 items-center justify-center rounded bg-indigo-600 text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:ring-offset-neutral-900 disabled:cursor-not-allowed disabled:opacity-50"
927
+ aria-label="Send message"
928
+ >
929
+ <svg
930
+ xmlns="http://www.w3.org/2000/svg"
931
+ width="18"
932
+ height="18"
933
+ viewBox="0 0 24 24"
934
+ fill="none"
935
+ stroke="currentColor"
936
+ stroke-width="2"
937
+ stroke-linecap="round"
938
+ stroke-linejoin="round"
939
+ >
940
+ <path d="m22 2-7 20-4-9-9-4Z" /><path d="M22 2 11 13" />
941
+ </svg>
942
+ </button>
943
+ </form>
944
+ </div>
945
+ `,
946
+ type: "text"
947
+ },
948
+ "examples/todo/native/nativewind/app/(drawer)/todos.tsx.hbs": {
949
+ metadata: {
950
+ updatedAt: "2025-06-17T06:06:35.000Z",
951
+ updatedHash: "2bb32caaba"
952
+ },
953
+ content: `import { useState } from "react";
954
+ import {
955
+ View,
956
+ Text,
957
+ TextInput,
958
+ TouchableOpacity,
959
+ ScrollView,
960
+ ActivityIndicator,
961
+ Alert,
962
+ } from "react-native";
963
+ import { Ionicons } from "@expo/vector-icons";
964
+ {{#if (eq backend "convex")}}
965
+ import { useMutation, useQuery } from "convex/react";
966
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
967
+ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
968
+ {{else}}
969
+ import { useMutation, useQuery } from "@tanstack/react-query";
970
+ {{/if}}
971
+ import { Container } from "@/components/container";
972
+ {{#unless (eq backend "convex")}}
973
+ {{#if (eq api "orpc")}}
974
+ import { orpc } from "@/utils/orpc";
975
+ {{/if}}
976
+ {{#if (eq api "trpc")}}
977
+ import { trpc } from "@/utils/trpc";
978
+ {{/if}}
979
+ {{/unless}}
980
+ export default function TodosScreen() {
981
+ const [newTodoText, setNewTodoText] = useState("");
982
+ {{#if (eq backend "convex")}}
983
+ const todos = useQuery(api.todos.getAll);
984
+ const createTodoMutation = useMutation(api.todos.create);
985
+ const toggleTodoMutation = useMutation(api.todos.toggle);
986
+ const deleteTodoMutation = useMutation(api.todos.deleteTodo);
987
+ const handleAddTodo = async () => {
988
+ const text = newTodoText.trim();
989
+ if (!text) return;
990
+ await createTodoMutation({ text });
991
+ setNewTodoText("");
992
+ };
993
+ const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => {
994
+ toggleTodoMutation({ id, completed: !currentCompleted });
995
+ };
996
+ const handleDeleteTodo = (id: Id<"todos">) => {
997
+ Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
998
+ { text: "Cancel", style: "cancel" },
999
+ {
1000
+ text: "Delete",
1001
+ style: "destructive",
1002
+ onPress: () => deleteTodoMutation({ id }),
1003
+ },
1004
+ ]);
1005
+ };
1006
+ {{else}}
1007
+ {{#if (eq api "orpc")}}
1008
+ const todos = useQuery(orpc.todo.getAll.queryOptions());
1009
+ const createMutation = useMutation(
1010
+ orpc.todo.create.mutationOptions({
1011
+ onSuccess: () => {
1012
+ todos.refetch();
1013
+ setNewTodoText("");
1014
+ },
1015
+ }),
1016
+ );
1017
+ const toggleMutation = useMutation(
1018
+ orpc.todo.toggle.mutationOptions({
1019
+ onSuccess: () => { todos.refetch() },
1020
+ }),
1021
+ );
1022
+ const deleteMutation = useMutation(
1023
+ orpc.todo.delete.mutationOptions({
1024
+ onSuccess: () => { todos.refetch() },
1025
+ }),
1026
+ );
1027
+ {{/if}}
1028
+ {{#if (eq api "trpc")}}
1029
+ const todos = useQuery(trpc.todo.getAll.queryOptions());
1030
+ const createMutation = useMutation(
1031
+ trpc.todo.create.mutationOptions({
1032
+ onSuccess: () => {
1033
+ todos.refetch();
1034
+ setNewTodoText("");
1035
+ },
1036
+ }),
1037
+ );
1038
+ const toggleMutation = useMutation(
1039
+ trpc.todo.toggle.mutationOptions({
1040
+ onSuccess: () => { todos.refetch() },
1041
+ }),
1042
+ );
1043
+ const deleteMutation = useMutation(
1044
+ trpc.todo.delete.mutationOptions({
1045
+ onSuccess: () => { todos.refetch() },
1046
+ }),
1047
+ );
1048
+ {{/if}}
1049
+ const handleAddTodo = () => {
1050
+ if (newTodoText.trim()) {
1051
+ createMutation.mutate({ text: newTodoText });
1052
+ }
1053
+ };
1054
+ const handleToggleTodo = (id: number, completed: boolean) => {
1055
+ toggleMutation.mutate({ id, completed: !completed });
1056
+ };
1057
+ const handleDeleteTodo = (id: number) => {
1058
+ Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
1059
+ { text: "Cancel", style: "cancel" },
1060
+ {
1061
+ text: "Delete",
1062
+ style: "destructive",
1063
+ onPress: () => deleteMutation.mutate({ id }),
1064
+ },
1065
+ ]);
1066
+ };
1067
+ {{/if}}
1068
+ return (
1069
+ <Container>
1070
+ <ScrollView className="flex-1">
1071
+ <View className="px-4 py-6">
1072
+ <View className="mb-6 rounded-lg border border-border p-4 bg-card">
1073
+ <Text className="text-foreground text-2xl font-bold mb-2">
1074
+ Todo List
1075
+ </Text>
1076
+ <Text className="text-muted-foreground mb-4">
1077
+ Manage your tasks efficiently
1078
+ </Text>
1079
+ <View className="mb-6">
1080
+ <View className="flex-row items-center space-x-2 mb-2">
1081
+ <TextInput
1082
+ value={newTodoText}
1083
+ onChangeText={setNewTodoText}
1084
+ placeholder="Add a new task..."
1085
+ placeholderTextColor="#6b7280"
1086
+ {{#if (eq backend "convex")}}
1087
+ {{else}}
1088
+ editable={!createMutation.isPending}
1089
+ {{/if}}
1090
+ className="flex-1 border border-border rounded-md px-3 py-2 text-foreground bg-background"
1091
+ onSubmitEditing={handleAddTodo}
1092
+ returnKeyType="done"
1093
+ />
1094
+ <TouchableOpacity
1095
+ onPress={handleAddTodo}
1096
+ {{#if (eq backend "convex")}}
1097
+ disabled={!newTodoText.trim()}
1098
+ {{else}}
1099
+ disabled={createMutation.isPending || !newTodoText.trim()}
1100
+ {{/if}}
1101
+ className={\`px-4 py-2 rounded-md \${
1102
+ {{#if (eq backend "convex")}}
1103
+ !newTodoText.trim()
1104
+ {{else}}
1105
+ createMutation.isPending || !newTodoText.trim()
1106
+ {{/if}}
1107
+ ? "bg-muted"
1108
+ : "bg-primary"
1109
+ }\`}
1110
+ >
1111
+ {{#if (eq backend "convex")}}
1112
+ <Text className="text-white font-medium">Add</Text>
1113
+ {{else}}
1114
+ {createMutation.isPending ? (
1115
+ <ActivityIndicator size="small" color="white" />
1116
+ ) : (
1117
+ <Text className="text-white font-medium">Add</Text>
1118
+ )}
1119
+ {{/if}}
1120
+ </TouchableOpacity>
1121
+ </View>
1122
+ </View>
1123
+ {{#if (eq backend "convex")}}
1124
+ {todos === undefined ? (
1125
+ <View className="flex justify-center py-8">
1126
+ <ActivityIndicator size="large" color="#3b82f6" />
1127
+ </View>
1128
+ ) : todos.length === 0 ? (
1129
+ <Text className="py-8 text-center text-muted-foreground">
1130
+ No todos yet. Add one above!
1131
+ </Text>
1132
+ ) : (
1133
+ <View className="space-y-2">
1134
+ {todos.map((todo) => (
1135
+ <View
1136
+ key={todo._id}
1137
+ className="flex-row items-center justify-between rounded-md border border-border p-3 bg-background"
1138
+ >
1139
+ <View className="flex-row items-center flex-1">
1140
+ <TouchableOpacity
1141
+ onPress={() =>
1142
+ handleToggleTodo(todo._id, todo.completed)
1143
+ }
1144
+ className="mr-3"
1145
+ >
1146
+ <Ionicons
1147
+ name={todo.completed ? "checkbox" : "square-outline"}
1148
+ size={24}
1149
+ color={todo.completed ? "#22c55e" : "#6b7280"}
1150
+ />
1151
+ </TouchableOpacity>
1152
+ <Text
1153
+ className={\`flex-1 \${
1154
+ todo.completed
1155
+ ? "line-through text-muted-foreground"
1156
+ : "text-foreground"
1157
+ }\`}
1158
+ >
1159
+ {todo.text}
1160
+ </Text>
1161
+ </View>
1162
+ <TouchableOpacity
1163
+ onPress={() => handleDeleteTodo(todo._id)}
1164
+ className="ml-2 p-1"
1165
+ >
1166
+ <Ionicons
1167
+ name="trash-outline"
1168
+ size={20}
1169
+ color="#ef4444"
1170
+ />
1171
+ </TouchableOpacity>
1172
+ </View>
1173
+ ))}
1174
+ </View>
1175
+ )}
1176
+ {{else}}
1177
+ {todos.isLoading ? (
1178
+ <View className="flex justify-center py-8">
1179
+ <ActivityIndicator size="large" color="#3b82f6" />
1180
+ </View>
1181
+ ) : todos.data?.length === 0 ? (
1182
+ <Text className="py-8 text-center text-muted-foreground">
1183
+ No todos yet. Add one above!
1184
+ </Text>
1185
+ ) : (
1186
+ <View className="space-y-2">
1187
+ {todos.data?.map((todo) => (
1188
+ <View
1189
+ key={todo.id}
1190
+ className="flex-row items-center justify-between rounded-md border border-border p-3 bg-background"
1191
+ >
1192
+ <View className="flex-row items-center flex-1">
1193
+ <TouchableOpacity
1194
+ onPress={() =>
1195
+ handleToggleTodo(todo.id, todo.completed)
1196
+ }
1197
+ className="mr-3"
1198
+ >
1199
+ <Ionicons
1200
+ name={todo.completed ? "checkbox" : "square-outline"}
1201
+ size={24}
1202
+ color={todo.completed ? "#22c55e" : "#6b7280"}
1203
+ />
1204
+ </TouchableOpacity>
1205
+ <Text
1206
+ className={\`flex-1 \${
1207
+ todo.completed
1208
+ ? "line-through text-muted-foreground"
1209
+ : "text-foreground"
1210
+ }\`}
1211
+ >
1212
+ {todo.text}
1213
+ </Text>
1214
+ </View>
1215
+ <TouchableOpacity
1216
+ onPress={() => handleDeleteTodo(todo.id)}
1217
+ className="ml-2 p-1"
1218
+ >
1219
+ <Ionicons
1220
+ name="trash-outline"
1221
+ size={20}
1222
+ color="#ef4444"
1223
+ />
1224
+ </TouchableOpacity>
1225
+ </View>
1226
+ ))}
1227
+ </View>
1228
+ )}
1229
+ {{/if}}
1230
+ </View>
1231
+ </View>
1232
+ </ScrollView>
1233
+ </Container>
1234
+ );
1235
+ }
1236
+ `,
1237
+ type: "text"
1238
+ },
1239
+ "examples/todo/native/unistyles/app/(drawer)/todos.tsx.hbs": {
1240
+ metadata: {
1241
+ updatedAt: "2025-06-17T06:06:35.000Z",
1242
+ updatedHash: "26a877bbb6"
1243
+ },
1244
+ content: `import { useState } from "react";
1245
+ import {
1246
+ View,
1247
+ Text,
1248
+ TextInput,
1249
+ TouchableOpacity,
1250
+ ScrollView,
1251
+ ActivityIndicator,
1252
+ Alert,
1253
+ } from "react-native";
1254
+ import { Ionicons } from "@expo/vector-icons";
1255
+ import { StyleSheet, useUnistyles } from "react-native-unistyles";
1256
+ {{#if (eq backend "convex")}}
1257
+ import { useMutation, useQuery } from "convex/react";
1258
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
1259
+ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
1260
+ {{else}}
1261
+ import { useMutation, useQuery } from "@tanstack/react-query";
1262
+ {{/if}}
1263
+ import { Container } from "@/components/container";
1264
+ {{#unless (eq backend "convex")}}
1265
+ {{#if (eq api "orpc")}}
1266
+ import { orpc } from "@/utils/orpc";
1267
+ {{/if}}
1268
+ {{#if (eq api "trpc")}}
1269
+ import { trpc } from "@/utils/trpc";
1270
+ {{/if}}
1271
+ {{/unless}}
1272
+ export default function TodosScreen() {
1273
+ const [newTodoText, setNewTodoText] = useState("");
1274
+ const { theme } = useUnistyles();
1275
+ {{#if (eq backend "convex")}}
1276
+ const todos = useQuery(api.todos.getAll);
1277
+ const createTodoMutation = useMutation(api.todos.create);
1278
+ const toggleTodoMutation = useMutation(api.todos.toggle);
1279
+ const deleteTodoMutation = useMutation(api.todos.deleteTodo);
1280
+ const handleAddTodo = async () => {
1281
+ const text = newTodoText.trim();
1282
+ if (!text) return;
1283
+ await createTodoMutation({ text });
1284
+ setNewTodoText("");
1285
+ };
1286
+ const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => {
1287
+ toggleTodoMutation({ id, completed: !currentCompleted });
1288
+ };
1289
+ const handleDeleteTodo = (id: Id<"todos">) => {
1290
+ Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
1291
+ { text: "Cancel", style: "cancel" },
1292
+ {
1293
+ text: "Delete",
1294
+ style: "destructive",
1295
+ onPress: () => deleteTodoMutation({ id }),
1296
+ },
1297
+ ]);
1298
+ };
1299
+ {{else}}
1300
+ {{#if (eq api "orpc")}}
1301
+ const todos = useQuery(orpc.todo.getAll.queryOptions());
1302
+ const createMutation = useMutation(
1303
+ orpc.todo.create.mutationOptions({
1304
+ onSuccess: () => {
1305
+ todos.refetch();
1306
+ setNewTodoText("");
1307
+ },
1308
+ })
1309
+ );
1310
+ const toggleMutation = useMutation(
1311
+ orpc.todo.toggle.mutationOptions({
1312
+ onSuccess: () => { todos.refetch() },
1313
+ })
1314
+ );
1315
+ const deleteMutation = useMutation(
1316
+ orpc.todo.delete.mutationOptions({
1317
+ onSuccess: () => { todos.refetch() },
1318
+ })
1319
+ );
1320
+ {{/if}}
1321
+ {{#if (eq api "trpc")}}
1322
+ const todos = useQuery(trpc.todo.getAll.queryOptions());
1323
+ const createMutation = useMutation(
1324
+ trpc.todo.create.mutationOptions({
1325
+ onSuccess: () => {
1326
+ todos.refetch();
1327
+ setNewTodoText("");
1328
+ },
1329
+ })
1330
+ );
1331
+ const toggleMutation = useMutation(
1332
+ trpc.todo.toggle.mutationOptions({
1333
+ onSuccess: () => { todos.refetch() },
1334
+ })
1335
+ );
1336
+ const deleteMutation = useMutation(
1337
+ trpc.todo.delete.mutationOptions({
1338
+ onSuccess: () => { todos.refetch() },
1339
+ })
1340
+ );
1341
+ {{/if}}
1342
+ const handleAddTodo = () => {
1343
+ if (newTodoText.trim()) {
1344
+ createMutation.mutate({ text: newTodoText });
1345
+ }
1346
+ };
1347
+ const handleToggleTodo = (id: number, completed: boolean) => {
1348
+ toggleMutation.mutate({ id, completed: !completed });
1349
+ };
1350
+ const handleDeleteTodo = (id: number) => {
1351
+ Alert.alert("Delete Todo", "Are you sure you want to delete this todo?", [
1352
+ { text: "Cancel", style: "cancel" },
1353
+ {
1354
+ text: "Delete",
1355
+ style: "destructive",
1356
+ onPress: () => deleteMutation.mutate({ id }),
1357
+ },
1358
+ ]);
1359
+ };
1360
+ {{/if}}
1361
+ const isLoading = {{#if (eq backend "convex")}}!todos{{else}}todos.isLoading{{/if}};
1362
+ const isCreating = {{#if (eq backend "convex")}}false{{else}}createMutation.isPending{{/if}};
1363
+ const primaryButtonTextColor = theme.colors.background;
1364
+ return (
1365
+ <Container>
1366
+ <ScrollView style={styles.scrollView}>
1367
+ <View style={styles.headerContainer}>
1368
+ <Text style={styles.headerTitle}>Todo List</Text>
1369
+ <Text style={styles.headerSubtitle}>
1370
+ Manage your tasks efficiently
1371
+ </Text>
1372
+ <View style={styles.inputContainer}>
1373
+ <TextInput
1374
+ value={newTodoText}
1375
+ onChangeText={setNewTodoText}
1376
+ placeholder="Add a new task..."
1377
+ placeholderTextColor={theme.colors.border}
1378
+ editable={!isCreating}
1379
+ style={styles.textInput}
1380
+ onSubmitEditing={handleAddTodo}
1381
+ returnKeyType="done"
1382
+ />
1383
+ <TouchableOpacity
1384
+ onPress={handleAddTodo}
1385
+ disabled={isCreating || !newTodoText.trim()}
1386
+ style={[
1387
+ styles.addButton,
1388
+ (isCreating || !newTodoText.trim()) && styles.addButtonDisabled,
1389
+ ]}
1390
+ >
1391
+ {isCreating ? (
1392
+ <ActivityIndicator size="small" color={primaryButtonTextColor} />
1393
+ ) : (
1394
+ <Ionicons
1395
+ name="add"
1396
+ size={24}
1397
+ color={primaryButtonTextColor}
1398
+ />
1399
+ )}
1400
+ </TouchableOpacity>
1401
+ </View>
1402
+ </View>
1403
+ {isLoading && (
1404
+ <View style={styles.loadingContainer}>
1405
+ <ActivityIndicator size="large" color={theme.colors.primary} />
1406
+ <Text style={styles.loadingText}>Loading todos...</Text>
1407
+ </View>
1408
+ )}
1409
+ {{#if (eq backend "convex")}}
1410
+ {todos && todos.length === 0 && !isLoading && (
1411
+ <Text style={styles.emptyText}>No todos yet. Add one!</Text>
1412
+ )}
1413
+ {todos?.map((todo) => (
1414
+ <View key={todo._id} style={styles.todoItem}>
1415
+ <TouchableOpacity
1416
+ onPress={() => handleToggleTodo(todo._id, todo.completed)}
1417
+ style={styles.todoContent}
1418
+ >
1419
+ <Ionicons
1420
+ name={todo.completed ? "checkbox" : "square-outline"}
1421
+ size={24}
1422
+ color={todo.completed ? theme.colors.primary : theme.colors.typography}
1423
+ style={styles.checkbox}
1424
+ />
1425
+ <Text
1426
+ style={[
1427
+ styles.todoText,
1428
+ todo.completed && styles.todoTextCompleted,
1429
+ ]}
1430
+ >
1431
+ {todo.text}
1432
+ </Text>
1433
+ </TouchableOpacity>
1434
+ <TouchableOpacity onPress={() => handleDeleteTodo(todo._id)}>
1435
+ <Ionicons name="trash-outline" size={24} color={theme.colors.destructive} />
1436
+ </TouchableOpacity>
1437
+ </View>
1438
+ ))}
1439
+ {{else}}
1440
+ {todos.data && todos.data.length === 0 && !isLoading && (
1441
+ <Text style={styles.emptyText}>No todos yet. Add one!</Text>
1442
+ )}
1443
+ {todos.data?.map((todo: { id: number; text: string; completed: boolean }) => (
1444
+ <View key={todo.id} style={styles.todoItem}>
1445
+ <TouchableOpacity
1446
+ onPress={() => handleToggleTodo(todo.id, todo.completed)}
1447
+ style={styles.todoContent}
1448
+ >
1449
+ <Ionicons
1450
+ name={todo.completed ? "checkbox" : "square-outline"}
1451
+ size={24}
1452
+ color={todo.completed ? theme.colors.primary : theme.colors.typography}
1453
+ style={styles.checkbox}
1454
+ />
1455
+ <Text
1456
+ style={[
1457
+ styles.todoText,
1458
+ todo.completed && styles.todoTextCompleted,
1459
+ ]}
1460
+ >
1461
+ {todo.text}
1462
+ </Text>
1463
+ </TouchableOpacity>
1464
+ <TouchableOpacity onPress={() => handleDeleteTodo(todo.id)}>
1465
+ <Ionicons name="trash-outline" size={24} color={theme.colors.destructive} />
1466
+ </TouchableOpacity>
1467
+ </View>
1468
+ ))}
1469
+ {{/if}}
1470
+ </ScrollView>
1471
+ </Container>
1472
+ );
1473
+ }
1474
+ const styles = StyleSheet.create((theme) => ({
1475
+ scrollView: {
1476
+ flex: 1,
1477
+ },
1478
+ headerContainer: {
1479
+ paddingHorizontal: theme.spacing.md,
1480
+ paddingVertical: theme.spacing.lg,
1481
+ borderBottomWidth: 1,
1482
+ borderBottomColor: theme.colors.border,
1483
+ backgroundColor: theme.colors.background,
1484
+ },
1485
+ headerTitle: {
1486
+ fontSize: 28,
1487
+ fontWeight: "bold",
1488
+ color: theme.colors.typography,
1489
+ marginBottom: theme.spacing.sm,
1490
+ },
1491
+ headerSubtitle: {
1492
+ fontSize: 16,
1493
+ color: theme.colors.typography,
1494
+ marginBottom: theme.spacing.md,
1495
+ },
1496
+ inputContainer: {
1497
+ flexDirection: "row",
1498
+ alignItems: "center",
1499
+ marginBottom: theme.spacing.md,
1500
+ },
1501
+ textInput: {
1502
+ flex: 1,
1503
+ borderWidth: 1,
1504
+ borderColor: theme.colors.border,
1505
+ borderRadius: 8,
1506
+ paddingHorizontal: theme.spacing.md,
1507
+ paddingVertical: theme.spacing.sm,
1508
+ color: theme.colors.typography,
1509
+ backgroundColor: theme.colors.background,
1510
+ marginRight: theme.spacing.sm,
1511
+ fontSize: 16,
1512
+ },
1513
+ addButton: {
1514
+ backgroundColor: theme.colors.primary,
1515
+ padding: theme.spacing.sm,
1516
+ borderRadius: 8,
1517
+ justifyContent: "center",
1518
+ alignItems: "center",
1519
+ },
1520
+ addButtonDisabled: {
1521
+ backgroundColor: theme.colors.border,
1522
+ },
1523
+ loadingContainer: {
1524
+ flex: 1,
1525
+ justifyContent: "center",
1526
+ alignItems: "center",
1527
+ padding: theme.spacing.lg,
1528
+ },
1529
+ loadingText: {
1530
+ marginTop: theme.spacing.sm,
1531
+ fontSize: 16,
1532
+ color: theme.colors.typography,
1533
+ },
1534
+ emptyText: {
1535
+ textAlign: "center",
1536
+ marginTop: theme.spacing.xl,
1537
+ fontSize: 16,
1538
+ color: theme.colors.typography,
1539
+ },
1540
+ todoItem: {
1541
+ flexDirection: "row",
1542
+ justifyContent: "space-between",
1543
+ alignItems: "center",
1544
+ paddingVertical: theme.spacing.md,
1545
+ paddingHorizontal: theme.spacing.md,
1546
+ borderBottomWidth: 1,
1547
+ borderBottomColor: theme.colors.border,
1548
+ backgroundColor: theme.colors.background,
1549
+ },
1550
+ todoContent: {
1551
+ flexDirection: "row",
1552
+ alignItems: "center",
1553
+ flex: 1,
1554
+ },
1555
+ checkbox: {
1556
+ marginRight: theme.spacing.md,
1557
+ },
1558
+ todoText: {
1559
+ fontSize: 16,
1560
+ color: theme.colors.typography,
1561
+ flex: 1,
1562
+ },
1563
+ todoTextCompleted: {
1564
+ textDecorationLine: "line-through",
1565
+ color: theme.colors.border,
1566
+ },
1567
+ }));
1568
+ `,
1569
+ type: "text"
1570
+ },
1571
+ "examples/todo/server/drizzle/base/src/routers/todo.ts.hbs": {
1572
+ metadata: {
1573
+ updatedAt: "2025-06-17T06:06:35.000Z",
1574
+ updatedHash: "9410e1685b"
1575
+ },
1576
+ content: `{{#if (eq api "orpc")}}
1577
+ import { eq } from "drizzle-orm";
1578
+ import z from "zod/v4";
1579
+ import { db } from "../db";
1580
+ import { todo } from "../db/schema/todo";
1581
+ import { publicProcedure } from "../lib/orpc";
1582
+ export const todoRouter = {
1583
+ getAll: publicProcedure.handler(async () => {
1584
+ return await db.select().from(todo);
1585
+ }),
1586
+ create: publicProcedure
1587
+ .input(z.object({ text: z.string().min(1) }))
1588
+ .handler(async ({ input }) => {
1589
+ const result = await db
1590
+ .insert(todo)
1591
+ .values({
1592
+ text: input.text,
1593
+ })
1594
+ .returning();
1595
+ return result[0];
1596
+ }),
1597
+ toggle: publicProcedure
1598
+ .input(z.object({ id: z.number(), completed: z.boolean() }))
1599
+ .handler(async ({ input }) => {
1600
+ await db
1601
+ .update(todo)
1602
+ .set({ completed: input.completed })
1603
+ .where(eq(todo.id, input.id));
1604
+ return { success: true };
1605
+ }),
1606
+ delete: publicProcedure
1607
+ .input(z.object({ id: z.number() }))
1608
+ .handler(async ({ input }) => {
1609
+ await db.delete(todo).where(eq(todo.id, input.id));
1610
+ return { success: true };
1611
+ }),
1612
+ };
1613
+ {{/if}}
1614
+ {{#if (eq api "trpc")}}
1615
+ import z from "zod/v4";
1616
+ import { router, publicProcedure } from "../lib/trpc";
1617
+ import { todo } from "../db/schema/todo";
1618
+ import { eq } from "drizzle-orm";
1619
+ import { db } from "../db";
1620
+ export const todoRouter = router({
1621
+ getAll: publicProcedure.query(async () => {
1622
+ return await db.select().from(todo);
1623
+ }),
1624
+ create: publicProcedure
1625
+ .input(z.object({ text: z.string().min(1) }))
1626
+ .mutation(async ({ input }) => {
1627
+ return await db.insert(todo).values({
1628
+ text: input.text,
1629
+ });
1630
+ }),
1631
+ toggle: publicProcedure
1632
+ .input(z.object({ id: z.number(), completed: z.boolean() }))
1633
+ .mutation(async ({ input }) => {
1634
+ return await db
1635
+ .update(todo)
1636
+ .set({ completed: input.completed })
1637
+ .where(eq(todo.id, input.id));
1638
+ }),
1639
+ delete: publicProcedure
1640
+ .input(z.object({ id: z.number() }))
1641
+ .mutation(async ({ input }) => {
1642
+ return await db.delete(todo).where(eq(todo.id, input.id));
1643
+ }),
1644
+ });
1645
+ {{/if}}
1646
+ `,
1647
+ type: "text"
1648
+ },
1649
+ "examples/todo/server/drizzle/mysql/src/db/schema/todo.ts": {
1650
+ metadata: {
1651
+ updatedAt: "2025-06-17T06:06:35.000Z",
1652
+ updatedHash: "81aa9be62e"
1653
+ },
1654
+ content: `import { mysqlTable, varchar, int, boolean } from "drizzle-orm/mysql-core";
1655
+ export const todo = mysqlTable("todo", {
1656
+ id: int("id").primaryKey().autoincrement(),
1657
+ text: varchar("text", { length: 255 }).notNull(),
1658
+ completed: boolean("completed").default(false).notNull(),
1659
+ });
1660
+ `,
1661
+ type: "text"
1662
+ },
1663
+ "examples/todo/server/drizzle/postgres/src/db/schema/todo.ts": {
1664
+ metadata: {
1665
+ updatedAt: "2025-06-17T06:06:35.000Z",
1666
+ updatedHash: "9a25bd9121"
1667
+ },
1668
+ content: `import { pgTable, text, boolean, serial } from "drizzle-orm/pg-core";
1669
+ export const todo = pgTable("todo", {
1670
+ id: serial("id").primaryKey(),
1671
+ text: text("text").notNull(),
1672
+ completed: boolean("completed").default(false).notNull()
1673
+ });
1674
+ `,
1675
+ type: "text"
1676
+ },
1677
+ "examples/todo/server/drizzle/sqlite/src/db/schema/todo.ts": {
1678
+ metadata: {
1679
+ updatedAt: "2025-06-17T06:06:35.000Z",
1680
+ updatedHash: "5b49068b07"
1681
+ },
1682
+ content: `import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core";
1683
+ export const todo = sqliteTable("todo", {
1684
+ id: integer("id").primaryKey({ autoIncrement: true }),
1685
+ text: text("text").notNull(),
1686
+ completed: integer("completed", { mode: "boolean" }).default(false).notNull(),
1687
+ });
1688
+ `,
1689
+ type: "text"
1690
+ },
1691
+ "examples/todo/server/mongoose/base/src/routers/todo.ts.hbs": {
1692
+ metadata: {
1693
+ updatedAt: "2025-06-17T06:06:35.000Z",
1694
+ updatedHash: "3b24eb8d8b"
1695
+ },
1696
+ content: `{{#if (eq api "orpc")}}
1697
+ import z from "zod/v4";
1698
+ import { publicProcedure } from "../lib/orpc";
1699
+ import { Todo } from "../db/models/todo.model";
1700
+ export const todoRouter = {
1701
+ getAll: publicProcedure.handler(async () => {
1702
+ return await Todo.find().lean();
1703
+ }),
1704
+ create: publicProcedure
1705
+ .input(z.object({ text: z.string().min(1) }))
1706
+ .handler(async ({ input }) => {
1707
+ const newTodo = await Todo.create({ text: input.text });
1708
+ return newTodo.toObject();
1709
+ }),
1710
+ toggle: publicProcedure
1711
+ .input(z.object({ id: z.string(), completed: z.boolean() }))
1712
+ .handler(async ({ input }) => {
1713
+ await Todo.updateOne({ id: input.id }, { completed: input.completed });
1714
+ return { success: true };
1715
+ }),
1716
+ delete: publicProcedure
1717
+ .input(z.object({ id: z.string() }))
1718
+ .handler(async ({ input }) => {
1719
+ await Todo.deleteOne({ id: input.id });
1720
+ return { success: true };
1721
+ }),
1722
+ };
1723
+ {{/if}}
1724
+ {{#if (eq api "trpc")}}
1725
+ import z from "zod/v4";
1726
+ import { router, publicProcedure } from "../lib/trpc";
1727
+ import { Todo } from "../db/models/todo.model";
1728
+ export const todoRouter = router({
1729
+ getAll: publicProcedure.query(async () => {
1730
+ return await Todo.find().lean();
1731
+ }),
1732
+ create: publicProcedure
1733
+ .input(z.object({ text: z.string().min(1) }))
1734
+ .mutation(async ({ input }) => {
1735
+ const newTodo = await Todo.create({ text: input.text });
1736
+ return newTodo.toObject();
1737
+ }),
1738
+ toggle: publicProcedure
1739
+ .input(z.object({ id: z.string(), completed: z.boolean() }))
1740
+ .mutation(async ({ input }) => {
1741
+ await Todo.updateOne({ id: input.id }, { completed: input.completed });
1742
+ return { success: true };
1743
+ }),
1744
+ delete: publicProcedure
1745
+ .input(z.object({ id: z.string() }))
1746
+ .mutation(async ({ input }) => {
1747
+ await Todo.deleteOne({ id: input.id });
1748
+ return { success: true };
1749
+ }),
1750
+ });
1751
+ {{/if}}
1752
+ `,
1753
+ type: "text"
1754
+ },
1755
+ "examples/todo/server/mongoose/mongodb/src/db/models/todo.model.ts": {
1756
+ metadata: {
1757
+ updatedAt: "2025-06-17T06:06:35.000Z",
1758
+ updatedHash: "cde8d8384d"
1759
+ },
1760
+ content: `import mongoose from 'mongoose';
1761
+ const { Schema, model } = mongoose;
1762
+ const todoSchema = new Schema({
1763
+ id: {
1764
+ type: mongoose.Schema.Types.ObjectId,
1765
+ auto: true,
1766
+ },
1767
+ text: {
1768
+ type: String,
1769
+ required: true,
1770
+ },
1771
+ completed: {
1772
+ type: Boolean,
1773
+ default: false,
1774
+ },
1775
+ }, {
1776
+ collection: 'todo'
1777
+ });
1778
+ const Todo = model('Todo', todoSchema);
1779
+ export { Todo };
1780
+ `,
1781
+ type: "text"
1782
+ },
1783
+ "examples/todo/server/prisma/base/src/routers/todo.ts.hbs": {
1784
+ metadata: {
1785
+ updatedAt: "2025-06-17T06:06:35.000Z",
1786
+ updatedHash: "547defb0a3"
1787
+ },
1788
+ content: `{{#if (eq api "orpc")}}
1789
+ import z from "zod/v4";
1790
+ import prisma from "../../prisma";
1791
+ import { publicProcedure } from "../lib/orpc";
1792
+ export const todoRouter = {
1793
+ getAll: publicProcedure.handler(async () => {
1794
+ return await prisma.todo.findMany({
1795
+ orderBy: {
1796
+ id: "asc",
1797
+ },
1798
+ });
1799
+ }),
1800
+ create: publicProcedure
1801
+ .input(z.object({ text: z.string().min(1) }))
1802
+ .handler(async ({ input }) => {
1803
+ return await prisma.todo.create({
1804
+ data: {
1805
+ text: input.text,
1806
+ },
1807
+ });
1808
+ }),
1809
+ toggle: publicProcedure
1810
+ {{#if (eq database "mongodb")}}
1811
+ .input(z.object({ id: z.string(), completed: z.boolean() }))
1812
+ {{else}}
1813
+ .input(z.object({ id: z.number(), completed: z.boolean() }))
1814
+ {{/if}}
1815
+ .handler(async ({ input }) => {
1816
+ await prisma.todo.update({
1817
+ where: { id: input.id },
1818
+ data: { completed: input.completed },
1819
+ });
1820
+ return { success: true };
1821
+ }),
1822
+ delete: publicProcedure
1823
+ {{#if (eq database "mongodb")}}
1824
+ .input(z.object({ id: z.string() }))
1825
+ {{else}}
1826
+ .input(z.object({ id: z.number() }))
1827
+ {{/if}}
1828
+ .handler(async ({ input }) => {
1829
+ await prisma.todo.delete({
1830
+ where: { id: input.id },
1831
+ });
1832
+ return { success: true };
1833
+ }),
1834
+ };
1835
+ {{/if}}
1836
+ {{#if (eq api "trpc")}}
1837
+ import { TRPCError } from "@trpc/server";
1838
+ import z from "zod/v4";
1839
+ import prisma from "../../prisma";
1840
+ import { publicProcedure, router } from "../lib/trpc";
1841
+ export const todoRouter = router({
1842
+ getAll: publicProcedure.query(async () => {
1843
+ return await prisma.todo.findMany({
1844
+ orderBy: {
1845
+ id: "asc"
1846
+ }
1847
+ });
1848
+ }),
1849
+ create: publicProcedure
1850
+ .input(z.object({ text: z.string().min(1) }))
1851
+ .mutation(async ({ input }) => {
1852
+ return await prisma.todo.create({
1853
+ data: {
1854
+ text: input.text,
1855
+ },
1856
+ });
1857
+ }),
1858
+ toggle: publicProcedure
1859
+ {{#if (eq database "mongodb")}}
1860
+ .input(z.object({ id: z.string(), completed: z.boolean() }))
1861
+ {{else}}
1862
+ .input(z.object({ id: z.number(), completed: z.boolean() }))
1863
+ {{/if}}
1864
+ .mutation(async ({ input }) => {
1865
+ try {
1866
+ return await prisma.todo.update({
1867
+ where: { id: input.id },
1868
+ data: { completed: input.completed },
1869
+ });
1870
+ } catch (error) {
1871
+ throw new TRPCError({
1872
+ code: "NOT_FOUND",
1873
+ message: "Todo not found",
1874
+ });
1875
+ }
1876
+ }),
1877
+ delete: publicProcedure
1878
+ {{#if (eq database "mongodb")}}
1879
+ .input(z.object({ id: z.string() }))
1880
+ {{else}}
1881
+ .input(z.object({ id: z.number() }))
1882
+ {{/if}}
1883
+ .mutation(async ({ input }) => {
1884
+ try {
1885
+ return await prisma.todo.delete({
1886
+ where: { id: input.id },
1887
+ });
1888
+ } catch (error) {
1889
+ throw new TRPCError({
1890
+ code: "NOT_FOUND",
1891
+ message: "Todo not found",
1892
+ });
1893
+ }
1894
+ }),
1895
+ });
1896
+ {{/if}}
1897
+ `,
1898
+ type: "text"
1899
+ },
1900
+ "examples/todo/server/prisma/mongodb/prisma/schema/todo.prisma": {
1901
+ metadata: {
1902
+ updatedAt: "2025-06-17T06:06:35.000Z",
1903
+ updatedHash: "509c80584c"
1904
+ },
1905
+ content: `model Todo {
1906
+ id String @id @default(auto()) @map("_id") @db.ObjectId
1907
+ text String
1908
+ completed Boolean @default(false)
1909
+ @@map("todo")
1910
+ }
1911
+ `,
1912
+ type: "text"
1913
+ },
1914
+ "examples/todo/server/prisma/mysql/prisma/schema/todo.prisma": {
1915
+ metadata: {
1916
+ updatedAt: "2025-06-17T06:06:35.000Z",
1917
+ updatedHash: "07d1175c34"
1918
+ },
1919
+ content: `model Todo {
1920
+ id Int @id @default(autoincrement())
1921
+ text String
1922
+ completed Boolean @default(false)
1923
+ @@map("todo")
1924
+ }
1925
+ `,
1926
+ type: "text"
1927
+ },
1928
+ "examples/todo/server/prisma/postgres/prisma/schema/todo.prisma": {
1929
+ metadata: {
1930
+ updatedAt: "2025-06-17T06:06:35.000Z",
1931
+ updatedHash: "07d1175c34"
1932
+ },
1933
+ content: `model Todo {
1934
+ id Int @id @default(autoincrement())
1935
+ text String
1936
+ completed Boolean @default(false)
1937
+ @@map("todo")
1938
+ }
1939
+ `,
1940
+ type: "text"
1941
+ },
1942
+ "examples/todo/server/prisma/sqlite/prisma/schema/todo.prisma": {
1943
+ metadata: {
1944
+ updatedAt: "2025-06-17T06:06:35.000Z",
1945
+ updatedHash: "07d1175c34"
1946
+ },
1947
+ content: `model Todo {
1948
+ id Int @id @default(autoincrement())
1949
+ text String
1950
+ completed Boolean @default(false)
1951
+ @@map("todo")
1952
+ }
1953
+ `,
1954
+ type: "text"
1955
+ },
1956
+ "examples/todo/web/nuxt/app/pages/todos.vue": {
1957
+ metadata: {
1958
+ updatedAt: "2025-06-17T06:06:35.000Z",
1959
+ updatedHash: "5770b2133c"
1960
+ },
1961
+ content: `<script setup lang="ts">
1962
+ import { ref } from 'vue'
1963
+ import { useQuery, useMutation, useQueryClient } from '@tanstack/vue-query'
1964
+ const { $orpc } = useNuxtApp()
1965
+ const newTodoText = ref('')
1966
+ const queryClient = useQueryClient()
1967
+ const todos = useQuery($orpc.todo.getAll.queryOptions())
1968
+ const createMutation = useMutation($orpc.todo.create.mutationOptions({
1969
+ onSuccess: () => {
1970
+ queryClient.invalidateQueries()
1971
+ newTodoText.value = ''
1972
+ }
1973
+ }))
1974
+ const toggleMutation = useMutation($orpc.todo.toggle.mutationOptions({
1975
+ onSuccess: () => queryClient.invalidateQueries()
1976
+ }))
1977
+ const deleteMutation = useMutation($orpc.todo.delete.mutationOptions({
1978
+ onSuccess: () => queryClient.invalidateQueries()
1979
+ }))
1980
+ function handleAddTodo() {
1981
+ if (newTodoText.value.trim()) {
1982
+ createMutation.mutate({ text: newTodoText.value })
1983
+ }
1984
+ }
1985
+ function handleToggleTodo(id: number, completed: boolean) {
1986
+ toggleMutation.mutate({ id, completed: !completed })
1987
+ }
1988
+ function handleDeleteTodo(id: number) {
1989
+ deleteMutation.mutate({ id })
1990
+ }
1991
+ <\/script>
1992
+ <template>
1993
+ <div class="mx-auto w-full max-w-md py-10">
1994
+ <UCard>
1995
+ <template #header>
1996
+ <div>
1997
+ <div class="text-xl font-bold">Todo List</div>
1998
+ <div class="text-muted text-sm">Manage your tasks efficiently</div>
1999
+ </div>
2000
+ </template>
2001
+ <form @submit.prevent="handleAddTodo" class="mb-6 flex items-center gap-2">
2002
+ <UInput
2003
+ v-model="newTodoText"
2004
+ placeholder="Add a new task..."
2005
+ autocomplete="off"
2006
+ class="w-full"
2007
+ />
2008
+ <UButton
2009
+ type="submit"
2010
+ icon="i-lucide-plus"
2011
+ >
2012
+ Add
2013
+ </UButton>
2014
+ </form>
2015
+ <div v-if="todos.status.value === 'pending'" class="flex justify-center py-4">
2016
+ <UIcon name="i-lucide-loader-2" class="animate-spin w-6 h-6" />
2017
+ </div>
2018
+ <p v-else-if="todos.status.value === 'error'" class="py-4 text-center text-red-500">
2019
+ Error: {{ todos.error.value?.message || 'Failed to load todos' }}
2020
+ </p>
2021
+ <p v-else-if="todos.data.value?.length === 0" class="py-4 text-center">
2022
+ No todos yet. Add one above!
2023
+ </p>
2024
+ <ul v-else class="space-y-2">
2025
+ <li
2026
+ v-for="todo in todos.data.value"
2027
+ :key="todo.id"
2028
+ class="flex items-center justify-between rounded-md border p-2"
2029
+ >
2030
+ <div class="flex items-center gap-2">
2031
+ <UCheckbox
2032
+ :model-value="todo.completed"
2033
+ @update:model-value="() => handleToggleTodo(todo.id, todo.completed)"
2034
+ :id="\`todo-\${todo.id}\`"
2035
+ />
2036
+ <label
2037
+ :for="\`todo-\${todo.id}\`"
2038
+ :class="{ 'line-through text-muted': todo.completed }"
2039
+ class="cursor-pointer"
2040
+ >
2041
+ {{ todo.text }}
2042
+ </label>
2043
+ </div>
2044
+ <UButton
2045
+ color="neutral"
2046
+ variant="ghost"
2047
+ size="sm"
2048
+ square
2049
+ @click="handleDeleteTodo(todo.id)"
2050
+ aria-label="Delete todo"
2051
+ icon="i-lucide-trash-2"
2052
+ />
2053
+ </li>
2054
+ </ul>
2055
+ </UCard>
2056
+ </div>
2057
+ </template>
2058
+ `,
2059
+ type: "text"
2060
+ },
2061
+ "examples/todo/web/react/next/src/app/todos/page.tsx.hbs": {
2062
+ metadata: {
2063
+ updatedAt: "2025-06-17T06:06:35.000Z",
2064
+ updatedHash: "dbf393c2f2"
2065
+ },
2066
+ content: `"use client"
2067
+ import { Button } from "@/components/ui/button";
2068
+ import {
2069
+ Card,
2070
+ CardContent,
2071
+ CardDescription,
2072
+ CardHeader,
2073
+ CardTitle,
2074
+ } from "@/components/ui/card";
2075
+ import { Checkbox } from "@/components/ui/checkbox";
2076
+ import { Input } from "@/components/ui/input";
2077
+ import { Loader2, Trash2 } from "lucide-react";
2078
+ import { useState } from "react";
2079
+ {{#if (eq backend "convex")}}
2080
+ import { useMutation, useQuery } from "convex/react";
2081
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
2082
+ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
2083
+ {{else}}
2084
+ import { useMutation, useQuery } from "@tanstack/react-query";
2085
+ {{#if (eq api "orpc")}}
2086
+ import { orpc } from "@/utils/orpc";
2087
+ {{/if}}
2088
+ {{#if (eq api "trpc")}}
2089
+ import { trpc } from "@/utils/trpc";
2090
+ {{/if}}
2091
+ {{/if}}
2092
+ export default function TodosPage() {
2093
+ const [newTodoText, setNewTodoText] = useState("");
2094
+ {{#if (eq backend "convex")}}
2095
+ const todos = useQuery(api.todos.getAll);
2096
+ const createTodoMutation = useMutation(api.todos.create);
2097
+ const toggleTodoMutation = useMutation(api.todos.toggle);
2098
+ const deleteTodoMutation = useMutation(api.todos.deleteTodo);
2099
+ const handleAddTodo = async (e: React.FormEvent) => {
2100
+ e.preventDefault();
2101
+ const text = newTodoText.trim();
2102
+ if (!text) return;
2103
+ await createTodoMutation({ text });
2104
+ setNewTodoText("");
2105
+ };
2106
+ const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => {
2107
+ toggleTodoMutation({ id, completed: !currentCompleted });
2108
+ };
2109
+ const handleDeleteTodo = (id: Id<"todos">) => {
2110
+ deleteTodoMutation({ id });
2111
+ };
2112
+ {{else}}
2113
+ {{#if (eq api "orpc")}}
2114
+ const todos = useQuery(orpc.todo.getAll.queryOptions());
2115
+ const createMutation = useMutation(
2116
+ orpc.todo.create.mutationOptions({
2117
+ onSuccess: () => {
2118
+ todos.refetch();
2119
+ setNewTodoText("");
2120
+ },
2121
+ }),
2122
+ );
2123
+ const toggleMutation = useMutation(
2124
+ orpc.todo.toggle.mutationOptions({
2125
+ onSuccess: () => { todos.refetch() },
2126
+ }),
2127
+ );
2128
+ const deleteMutation = useMutation(
2129
+ orpc.todo.delete.mutationOptions({
2130
+ onSuccess: () => { todos.refetch() },
2131
+ }),
2132
+ );
2133
+ {{/if}}
2134
+ {{#if (eq api "trpc")}}
2135
+ const todos = useQuery(trpc.todo.getAll.queryOptions());
2136
+ const createMutation = useMutation(
2137
+ trpc.todo.create.mutationOptions({
2138
+ onSuccess: () => {
2139
+ todos.refetch();
2140
+ setNewTodoText("");
2141
+ },
2142
+ }),
2143
+ );
2144
+ const toggleMutation = useMutation(
2145
+ trpc.todo.toggle.mutationOptions({
2146
+ onSuccess: () => { todos.refetch() },
2147
+ }),
2148
+ );
2149
+ const deleteMutation = useMutation(
2150
+ trpc.todo.delete.mutationOptions({
2151
+ onSuccess: () => { todos.refetch() },
2152
+ }),
2153
+ );
2154
+ {{/if}}
2155
+ const handleAddTodo = (e: React.FormEvent) => {
2156
+ e.preventDefault();
2157
+ if (newTodoText.trim()) {
2158
+ createMutation.mutate({ text: newTodoText });
2159
+ }
2160
+ };
2161
+ const handleToggleTodo = (id: number, completed: boolean) => {
2162
+ toggleMutation.mutate({ id, completed: !completed });
2163
+ };
2164
+ const handleDeleteTodo = (id: number) => {
2165
+ deleteMutation.mutate({ id });
2166
+ };
2167
+ {{/if}}
2168
+ return (
2169
+ <div className="mx-auto w-full max-w-md py-10">
2170
+ <Card>
2171
+ <CardHeader>
2172
+ <CardTitle>Todo List</CardTitle>
2173
+ <CardDescription>Manage your tasks efficiently</CardDescription>
2174
+ </CardHeader>
2175
+ <CardContent>
2176
+ <form
2177
+ onSubmit={handleAddTodo}
2178
+ className="mb-6 flex items-center space-x-2"
2179
+ >
2180
+ <Input
2181
+ value={newTodoText}
2182
+ onChange={(e) => setNewTodoText(e.target.value)}
2183
+ placeholder="Add a new task..."
2184
+ {{#if (eq backend "convex")}}
2185
+ {{else}}
2186
+ disabled={createMutation.isPending}
2187
+ {{/if}}
2188
+ />
2189
+ <Button
2190
+ type="submit"
2191
+ {{#if (eq backend "convex")}}
2192
+ disabled={!newTodoText.trim()}
2193
+ {{else}}
2194
+ disabled={createMutation.isPending || !newTodoText.trim()}
2195
+ {{/if}}
2196
+ >
2197
+ {{#if (eq backend "convex")}}
2198
+ Add
2199
+ {{else}}
2200
+ {createMutation.isPending ? (
2201
+ <Loader2 className="h-4 w-4 animate-spin" />
2202
+ ) : (
2203
+ "Add"
2204
+ )}
2205
+ {{/if}}
2206
+ </Button>
2207
+ </form>
2208
+ {{#if (eq backend "convex")}}
2209
+ {todos === undefined ? (
2210
+ <div className="flex justify-center py-4">
2211
+ <Loader2 className="h-6 w-6 animate-spin" />
2212
+ </div>
2213
+ ) : todos.length === 0 ? (
2214
+ <p className="py-4 text-center">No todos yet. Add one above!</p>
2215
+ ) : (
2216
+ <ul className="space-y-2">
2217
+ {todos.map((todo) => (
2218
+ <li
2219
+ key={todo._id}
2220
+ className="flex items-center justify-between rounded-md border p-2"
2221
+ >
2222
+ <div className="flex items-center space-x-2">
2223
+ <Checkbox
2224
+ checked={todo.completed}
2225
+ onCheckedChange={() =>
2226
+ handleToggleTodo(todo._id, todo.completed)
2227
+ }
2228
+ id={\`todo-\${todo._id}\`}
2229
+ />
2230
+ <label
2231
+ htmlFor={\`todo-\${todo._id}\`}
2232
+ className={\`\${todo.completed ? "line-through text-muted-foreground" : ""}\`}
2233
+ >
2234
+ {todo.text}
2235
+ </label>
2236
+ </div>
2237
+ <Button
2238
+ variant="ghost"
2239
+ size="icon"
2240
+ onClick={() => handleDeleteTodo(todo._id)}
2241
+ aria-label="Delete todo"
2242
+ >
2243
+ <Trash2 className="h-4 w-4" />
2244
+ </Button>
2245
+ </li>
2246
+ ))}
2247
+ </ul>
2248
+ )}
2249
+ {{else}}
2250
+ {todos.isLoading ? (
2251
+ <div className="flex justify-center py-4">
2252
+ <Loader2 className="h-6 w-6 animate-spin" />
2253
+ </div>
2254
+ ) : todos.data?.length === 0 ? (
2255
+ <p className="py-4 text-center">
2256
+ No todos yet. Add one above!
2257
+ </p>
2258
+ ) : (
2259
+ <ul className="space-y-2">
2260
+ {todos.data?.map((todo) => (
2261
+ <li
2262
+ key={todo.id}
2263
+ className="flex items-center justify-between rounded-md border p-2"
2264
+ >
2265
+ <div className="flex items-center space-x-2">
2266
+ <Checkbox
2267
+ checked={todo.completed}
2268
+ onCheckedChange={() =>
2269
+ handleToggleTodo(todo.id, todo.completed)
2270
+ }
2271
+ id={\`todo-\${todo.id}\`}
2272
+ />
2273
+ <label
2274
+ htmlFor={\`todo-\${todo.id}\`}
2275
+ className={\`\${todo.completed ? "line-through text-muted-foreground" : ""}\`}
2276
+ >
2277
+ {todo.text}
2278
+ </label>
2279
+ </div>
2280
+ <Button
2281
+ variant="ghost"
2282
+ size="icon"
2283
+ onClick={() => handleDeleteTodo(todo.id)}
2284
+ aria-label="Delete todo"
2285
+ >
2286
+ <Trash2 className="h-4 w-4" />
2287
+ </Button>
2288
+ </li>
2289
+ ))}
2290
+ </ul>
2291
+ )}
2292
+ {{/if}}
2293
+ </CardContent>
2294
+ </Card>
2295
+ </div>
2296
+ );
2297
+ }
2298
+ `,
2299
+ type: "text"
2300
+ },
2301
+ "examples/todo/web/react/react-router/src/routes/todos.tsx.hbs": {
2302
+ metadata: {
2303
+ updatedAt: "2025-06-17T06:06:35.000Z",
2304
+ updatedHash: "d356a03356"
2305
+ },
2306
+ content: `import { Button } from "@/components/ui/button";
2307
+ import {
2308
+ Card,
2309
+ CardContent,
2310
+ CardDescription,
2311
+ CardHeader,
2312
+ CardTitle,
2313
+ } from "@/components/ui/card";
2314
+ import { Checkbox } from "@/components/ui/checkbox";
2315
+ import { Input } from "@/components/ui/input";
2316
+ import { Loader2, Trash2 } from "lucide-react";
2317
+ import { useState } from "react";
2318
+ {{#if (eq backend "convex")}}
2319
+ import { useMutation, useQuery } from "convex/react";
2320
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
2321
+ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
2322
+ {{else}}
2323
+ {{#if (eq api "orpc")}}
2324
+ import { orpc } from "@/utils/orpc";
2325
+ {{/if}}
2326
+ {{#if (eq api "trpc")}}
2327
+ import { trpc } from "@/utils/trpc";
2328
+ {{/if}}
2329
+ import { useMutation, useQuery } from "@tanstack/react-query";
2330
+ {{/if}}
2331
+ export default function Todos() {
2332
+ const [newTodoText, setNewTodoText] = useState("");
2333
+ {{#if (eq backend "convex")}}
2334
+ const todos = useQuery(api.todos.getAll);
2335
+ const createTodo = useMutation(api.todos.create);
2336
+ const toggleTodo = useMutation(api.todos.toggle);
2337
+ const deleteTodo = useMutation(api.todos.deleteTodo);
2338
+ const handleAddTodo = async (e: React.FormEvent) => {
2339
+ e.preventDefault();
2340
+ const text = newTodoText.trim();
2341
+ if (!text) return;
2342
+ await createTodo({ text });
2343
+ setNewTodoText("");
2344
+ };
2345
+ const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => {
2346
+ toggleTodo({ id, completed: !currentCompleted });
2347
+ };
2348
+ const handleDeleteTodo = (id: Id<"todos">) => {
2349
+ deleteTodo({ id });
2350
+ };
2351
+ {{else}}
2352
+ {{#if (eq api "orpc")}}
2353
+ const todos = useQuery(orpc.todo.getAll.queryOptions());
2354
+ const createMutation = useMutation(
2355
+ orpc.todo.create.mutationOptions({
2356
+ onSuccess: () => {
2357
+ todos.refetch();
2358
+ setNewTodoText("");
2359
+ },
2360
+ })
2361
+ );
2362
+ const toggleMutation = useMutation(
2363
+ orpc.todo.toggle.mutationOptions({
2364
+ onSuccess: () => { todos.refetch() },
2365
+ })
2366
+ );
2367
+ const deleteMutation = useMutation(
2368
+ orpc.todo.delete.mutationOptions({
2369
+ onSuccess: () => { todos.refetch() },
2370
+ })
2371
+ );
2372
+ {{/if}}
2373
+ {{#if (eq api "trpc")}}
2374
+ const todos = useQuery(trpc.todo.getAll.queryOptions());
2375
+ const createMutation = useMutation(
2376
+ trpc.todo.create.mutationOptions({
2377
+ onSuccess: () => {
2378
+ todos.refetch();
2379
+ setNewTodoText("");
2380
+ },
2381
+ })
2382
+ );
2383
+ const toggleMutation = useMutation(
2384
+ trpc.todo.toggle.mutationOptions({
2385
+ onSuccess: () => { todos.refetch() },
2386
+ })
2387
+ );
2388
+ const deleteMutation = useMutation(
2389
+ trpc.todo.delete.mutationOptions({
2390
+ onSuccess: () => { todos.refetch() },
2391
+ })
2392
+ );
2393
+ {{/if}}
2394
+ const handleAddTodo = (e: React.FormEvent) => {
2395
+ e.preventDefault();
2396
+ if (newTodoText.trim()) {
2397
+ createMutation.mutate({ text: newTodoText });
2398
+ }
2399
+ };
2400
+ const handleToggleTodo = (id: number, completed: boolean) => {
2401
+ toggleMutation.mutate({ id, completed: !completed });
2402
+ };
2403
+ const handleDeleteTodo = (id: number) => {
2404
+ deleteMutation.mutate({ id });
2405
+ };
2406
+ {{/if}}
2407
+ return (
2408
+ <div className="w-full mx-auto max-w-md py-10">
2409
+ <Card>
2410
+ <CardHeader>
2411
+ <CardTitle>Todo List</CardTitle>
2412
+ <CardDescription>Manage your tasks efficiently</CardDescription>
2413
+ </CardHeader>
2414
+ <CardContent>
2415
+ <form
2416
+ onSubmit={handleAddTodo}
2417
+ className="mb-6 flex items-center space-x-2"
2418
+ >
2419
+ <Input
2420
+ value={newTodoText}
2421
+ onChange={(e) => setNewTodoText(e.target.value)}
2422
+ placeholder="Add a new task..."
2423
+ {{#if (eq backend "convex")}}
2424
+ {{else}}
2425
+ disabled={createMutation.isPending}
2426
+ {{/if}}
2427
+ />
2428
+ <Button
2429
+ type="submit"
2430
+ {{#if (eq backend "convex")}}
2431
+ disabled={!newTodoText.trim()}
2432
+ {{else}}
2433
+ disabled={createMutation.isPending || !newTodoText.trim()}
2434
+ {{/if}}
2435
+ >
2436
+ {{#if (eq backend "convex")}}
2437
+ Add
2438
+ {{else}}
2439
+ {createMutation.isPending ? (
2440
+ <Loader2 className="h-4 w-4 animate-spin" />
2441
+ ) : (
2442
+ "Add"
2443
+ )}
2444
+ {{/if}}
2445
+ </Button>
2446
+ </form>
2447
+ {{#if (eq backend "convex")}}
2448
+ {todos === undefined ? (
2449
+ <div className="flex justify-center py-4">
2450
+ <Loader2 className="h-6 w-6 animate-spin" />
2451
+ </div>
2452
+ ) : todos.length === 0 ? (
2453
+ <p className="py-4 text-center">No todos yet. Add one above!</p>
2454
+ ) : (
2455
+ <ul className="space-y-2">
2456
+ {todos.map((todo) => (
2457
+ <li
2458
+ key={todo._id}
2459
+ className="flex items-center justify-between rounded-md border p-2"
2460
+ >
2461
+ <div className="flex items-center space-x-2">
2462
+ <Checkbox
2463
+ checked={todo.completed}
2464
+ onCheckedChange={() =>
2465
+ handleToggleTodo(todo._id, todo.completed)
2466
+ }
2467
+ id={\`todo-\${todo._id}\`}
2468
+ />
2469
+ <label
2470
+ htmlFor={\`todo-\${todo._id}\`}
2471
+ className={\`\${todo.completed ? "line-through text-muted-foreground" : ""}\`}
2472
+ >
2473
+ {todo.text}
2474
+ </label>
2475
+ </div>
2476
+ <Button
2477
+ variant="ghost"
2478
+ size="icon"
2479
+ onClick={() => handleDeleteTodo(todo._id)}
2480
+ aria-label="Delete todo"
2481
+ >
2482
+ <Trash2 className="h-4 w-4" />
2483
+ </Button>
2484
+ </li>
2485
+ ))}
2486
+ </ul>
2487
+ )}
2488
+ {{else}}
2489
+ {todos.isLoading ? (
2490
+ <div className="flex justify-center py-4">
2491
+ <Loader2 className="h-6 w-6 animate-spin" />
2492
+ </div>
2493
+ ) : todos.data?.length === 0 ? (
2494
+ <p className="py-4 text-center">
2495
+ No todos yet. Add one above!
2496
+ </p>
2497
+ ) : (
2498
+ <ul className="space-y-2">
2499
+ {todos.data?.map((todo) => (
2500
+ <li
2501
+ key={todo.id}
2502
+ className="flex items-center justify-between rounded-md border p-2"
2503
+ >
2504
+ <div className="flex items-center space-x-2">
2505
+ <Checkbox
2506
+ checked={todo.completed}
2507
+ onCheckedChange={() =>
2508
+ handleToggleTodo(todo.id, todo.completed)
2509
+ }
2510
+ id={\`todo-\${todo.id}\`}
2511
+ />
2512
+ <label
2513
+ htmlFor={\`todo-\${todo.id}\`}
2514
+ className={\`\${todo.completed ? "line-through" : ""}\`}
2515
+ >
2516
+ {todo.text}
2517
+ </label>
2518
+ </div>
2519
+ <Button
2520
+ variant="ghost"
2521
+ size="icon"
2522
+ onClick={() => handleDeleteTodo(todo.id)}
2523
+ aria-label="Delete todo"
2524
+ >
2525
+ <Trash2 className="h-4 w-4" />
2526
+ </Button>
2527
+ </li>
2528
+ ))}
2529
+ </ul>
2530
+ )}
2531
+ {{/if}}
2532
+ </CardContent>
2533
+ </Card>
2534
+ </div>
2535
+ );
2536
+ }
2537
+ `,
2538
+ type: "text"
2539
+ },
2540
+ "examples/todo/web/react/tanstack-router/src/routes/todos.tsx.hbs": {
2541
+ metadata: {
2542
+ updatedAt: "2025-06-17T06:06:35.000Z",
2543
+ updatedHash: "0e20c217d0"
2544
+ },
2545
+ content: `import { Button } from "@/components/ui/button";
2546
+ import {
2547
+ Card,
2548
+ CardContent,
2549
+ CardDescription,
2550
+ CardHeader,
2551
+ CardTitle,
2552
+ } from "@/components/ui/card";
2553
+ import { Checkbox } from "@/components/ui/checkbox";
2554
+ import { Input } from "@/components/ui/input";
2555
+ import { createFileRoute } from "@tanstack/react-router";
2556
+ import { Loader2, Trash2 } from "lucide-react";
2557
+ import { useState } from "react";
2558
+ {{#if (eq backend "convex")}}
2559
+ import { useMutation, useQuery } from "convex/react";
2560
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
2561
+ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
2562
+ {{else}}
2563
+ {{#if (eq api "orpc")}}
2564
+ import { orpc } from "@/utils/orpc";
2565
+ {{/if}}
2566
+ {{#if (eq api "trpc")}}
2567
+ import { trpc } from "@/utils/trpc";
2568
+ {{/if}}
2569
+ import { useMutation, useQuery } from "@tanstack/react-query";
2570
+ {{/if}}
2571
+ export const Route = createFileRoute("/todos")({
2572
+ component: TodosRoute,
2573
+ });
2574
+ function TodosRoute() {
2575
+ const [newTodoText, setNewTodoText] = useState("");
2576
+ {{#if (eq backend "convex")}}
2577
+ const todos = useQuery(api.todos.getAll);
2578
+ const createTodo = useMutation(api.todos.create);
2579
+ const toggleTodo = useMutation(api.todos.toggle);
2580
+ const deleteTodo = useMutation(api.todos.deleteTodo);
2581
+ const handleAddTodo = async (e: React.FormEvent) => {
2582
+ e.preventDefault();
2583
+ const text = newTodoText.trim();
2584
+ if (!text) return;
2585
+ await createTodo({ text });
2586
+ setNewTodoText("");
2587
+ };
2588
+ const handleToggleTodo = (id: Id<"todos">, currentCompleted: boolean) => {
2589
+ toggleTodo({ id, completed: !currentCompleted });
2590
+ };
2591
+ const handleDeleteTodo = (id: Id<"todos">) => {
2592
+ deleteTodo({ id });
2593
+ };
2594
+ {{else}}
2595
+ {{#if (eq api "orpc")}}
2596
+ const todos = useQuery(orpc.todo.getAll.queryOptions());
2597
+ const createMutation = useMutation(
2598
+ orpc.todo.create.mutationOptions({
2599
+ onSuccess: () => {
2600
+ todos.refetch();
2601
+ setNewTodoText("");
2602
+ },
2603
+ }),
2604
+ );
2605
+ const toggleMutation = useMutation(
2606
+ orpc.todo.toggle.mutationOptions({
2607
+ onSuccess: () => { todos.refetch() },
2608
+ }),
2609
+ );
2610
+ const deleteMutation = useMutation(
2611
+ orpc.todo.delete.mutationOptions({
2612
+ onSuccess: () => { todos.refetch() },
2613
+ }),
2614
+ );
2615
+ {{/if}}
2616
+ {{#if (eq api "trpc")}}
2617
+ const todos = useQuery(trpc.todo.getAll.queryOptions());
2618
+ const createMutation = useMutation(
2619
+ trpc.todo.create.mutationOptions({
2620
+ onSuccess: () => {
2621
+ todos.refetch();
2622
+ setNewTodoText("");
2623
+ },
2624
+ }),
2625
+ );
2626
+ const toggleMutation = useMutation(
2627
+ trpc.todo.toggle.mutationOptions({
2628
+ onSuccess: () => { todos.refetch() },
2629
+ }),
2630
+ );
2631
+ const deleteMutation = useMutation(
2632
+ trpc.todo.delete.mutationOptions({
2633
+ onSuccess: () => { todos.refetch() },
2634
+ }),
2635
+ );
2636
+ {{/if}}
2637
+ const handleAddTodo = (e: React.FormEvent) => {
2638
+ e.preventDefault();
2639
+ if (newTodoText.trim()) {
2640
+ createMutation.mutate({ text: newTodoText });
2641
+ }
2642
+ };
2643
+ const handleToggleTodo = (id: number, completed: boolean) => {
2644
+ toggleMutation.mutate({ id, completed: !completed });
2645
+ };
2646
+ const handleDeleteTodo = (id: number) => {
2647
+ deleteMutation.mutate({ id });
2648
+ };
2649
+ {{/if}}
2650
+ return (
2651
+ <div className="mx-auto w-full max-w-md py-10">
2652
+ <Card>
2653
+ <CardHeader>
2654
+ <CardTitle>Todo List</CardTitle>
2655
+ <CardDescription>Manage your tasks efficiently</CardDescription>
2656
+ </CardHeader>
2657
+ <CardContent>
2658
+ <form
2659
+ onSubmit={handleAddTodo}
2660
+ className="mb-6 flex items-center space-x-2"
2661
+ >
2662
+ <Input
2663
+ value={newTodoText}
2664
+ onChange={(e) => setNewTodoText(e.target.value)}
2665
+ placeholder="Add a new task..."
2666
+ {{#if (eq backend "convex")}}
2667
+ {{else}}
2668
+ disabled={createMutation.isPending}
2669
+ {{/if}}
2670
+ />
2671
+ <Button
2672
+ type="submit"
2673
+ {{#if (eq backend "convex")}}
2674
+ disabled={!newTodoText.trim()}
2675
+ {{else}}
2676
+ disabled={createMutation.isPending || !newTodoText.trim()}
2677
+ {{/if}}
2678
+ >
2679
+ {{#if (eq backend "convex")}}
2680
+ Add
2681
+ {{else}}
2682
+ {createMutation.isPending ? (
2683
+ <Loader2 className="h-4 w-4 animate-spin" />
2684
+ ) : (
2685
+ "Add"
2686
+ )}
2687
+ {{/if}}
2688
+ </Button>
2689
+ </form>
2690
+ {{#if (eq backend "convex")}}
2691
+ {todos === undefined ? (
2692
+ <div className="flex justify-center py-4">
2693
+ <Loader2 className="h-6 w-6 animate-spin" />
2694
+ </div>
2695
+ ) : todos.length === 0 ? (
2696
+ <p className="py-4 text-center">No todos yet. Add one above!</p>
2697
+ ) : (
2698
+ <ul className="space-y-2">
2699
+ {todos.map((todo) => (
2700
+ <li
2701
+ key={todo._id}
2702
+ className="flex items-center justify-between rounded-md border p-2"
2703
+ >
2704
+ <div className="flex items-center space-x-2">
2705
+ <Checkbox
2706
+ checked={todo.completed}
2707
+ onCheckedChange={() =>
2708
+ handleToggleTodo(todo._id, todo.completed)
2709
+ }
2710
+ id={\`todo-\${todo._id}\`}
2711
+ />
2712
+ <label
2713
+ htmlFor={\`todo-\${todo._id}\`}
2714
+ className={\`\${todo.completed ? "line-through text-muted-foreground" : ""}\`}
2715
+ >
2716
+ {todo.text}
2717
+ </label>
2718
+ </div>
2719
+ <Button
2720
+ variant="ghost"
2721
+ size="icon"
2722
+ onClick={() => handleDeleteTodo(todo._id)}
2723
+ aria-label="Delete todo"
2724
+ >
2725
+ <Trash2 className="h-4 w-4" />
2726
+ </Button>
2727
+ </li>
2728
+ ))}
2729
+ </ul>
2730
+ )}
2731
+ {{else}}
2732
+ {todos.isLoading ? (
2733
+ <div className="flex justify-center py-4">
2734
+ <Loader2 className="h-6 w-6 animate-spin" />
2735
+ </div>
2736
+ ) : todos.data?.length === 0 ? (
2737
+ <p className="py-4 text-center">
2738
+ No todos yet. Add one above!
2739
+ </p>
2740
+ ) : (
2741
+ <ul className="space-y-2">
2742
+ {todos.data?.map((todo) => (
2743
+ <li
2744
+ key={todo.id}
2745
+ className="flex items-center justify-between rounded-md border p-2"
2746
+ >
2747
+ <div className="flex items-center space-x-2">
2748
+ <Checkbox
2749
+ checked={todo.completed}
2750
+ onCheckedChange={() =>
2751
+ handleToggleTodo(todo.id, todo.completed)
2752
+ }
2753
+ id={\`todo-\${todo.id}\`}
2754
+ />
2755
+ <label
2756
+ htmlFor={\`todo-\${todo.id}\`}
2757
+ className={\`\${todo.completed ? "line-through" : ""}\`}
2758
+ >
2759
+ {todo.text}
2760
+ </label>
2761
+ </div>
2762
+ <Button
2763
+ variant="ghost"
2764
+ size="icon"
2765
+ onClick={() => handleDeleteTodo(todo.id)}
2766
+ aria-label="Delete todo"
2767
+ >
2768
+ <Trash2 className="h-4 w-4" />
2769
+ </Button>
2770
+ </li>
2771
+ ))}
2772
+ </ul>
2773
+ )}
2774
+ {{/if}}
2775
+ </CardContent>
2776
+ </Card>
2777
+ </div>
2778
+ );
2779
+ }
2780
+ `,
2781
+ type: "text"
2782
+ },
2783
+ "examples/todo/web/react/tanstack-start/src/routes/todos.tsx.hbs": {
2784
+ metadata: {
2785
+ updatedAt: "2025-06-17T06:06:35.000Z",
2786
+ updatedHash: "7283124458"
2787
+ },
2788
+ content: `import { Button } from "@/components/ui/button";
2789
+ import {
2790
+ Card,
2791
+ CardContent,
2792
+ CardDescription,
2793
+ CardHeader,
2794
+ CardTitle,
2795
+ } from "@/components/ui/card";
2796
+ import { Checkbox } from "@/components/ui/checkbox";
2797
+ import { Input } from "@/components/ui/input";
2798
+ import { createFileRoute } from "@tanstack/react-router";
2799
+ import { Loader2, Trash2 } from "lucide-react";
2800
+ import { useState } from "react";
2801
+ {{#if (eq backend "convex")}}
2802
+ import { useSuspenseQuery } from "@tanstack/react-query";
2803
+ import { convexQuery } from "@convex-dev/react-query";
2804
+ import { useMutation } from "convex/react";
2805
+ import { api } from "@{{projectName}}/backend/convex/_generated/api";
2806
+ import type { Id } from "@{{projectName}}/backend/convex/_generated/dataModel";
2807
+ {{else}}
2808
+ {{#if (eq api "trpc")}}
2809
+ import { useTRPC } from "@/utils/trpc";
2810
+ {{/if}}
2811
+ {{#if (eq api "orpc")}}
2812
+ import { orpc } from "@/utils/orpc";
2813
+ {{/if}}
2814
+ import { useMutation, useQuery } from "@tanstack/react-query";
2815
+ {{/if}}
2816
+ export const Route = createFileRoute("/todos")({
2817
+ component: TodosRoute,
2818
+ });
2819
+ function TodosRoute() {
2820
+ const [newTodoText, setNewTodoText] = useState("");
2821
+ {{#if (eq backend "convex")}}
2822
+ const todosQuery = useSuspenseQuery(convexQuery(api.todos.getAll, {}));
2823
+ const todos = todosQuery.data;
2824
+ const createTodo = useMutation(api.todos.create);
2825
+ const toggleTodo = useMutation(api.todos.toggle);
2826
+ const removeTodo = useMutation(api.todos.deleteTodo);
2827
+ const handleAddTodo = async (e: React.FormEvent) => {
2828
+ e.preventDefault();
2829
+ const text = newTodoText.trim();
2830
+ if (text) {
2831
+ setNewTodoText("");
2832
+ try {
2833
+ await createTodo({ text });
2834
+ } catch (error) {
2835
+ console.error("Failed to add todo:", error);
2836
+ setNewTodoText(text);
2837
+ }
2838
+ }
2839
+ };
2840
+ const handleToggleTodo = async (id: Id<"todos">, completed: boolean) => {
2841
+ try {
2842
+ await toggleTodo({ id, completed: !completed });
2843
+ } catch (error) {
2844
+ console.error("Failed to toggle todo:", error);
2845
+ }
2846
+ };
2847
+ const handleDeleteTodo = async (id: Id<"todos">) => {
2848
+ try {
2849
+ await removeTodo({ id });
2850
+ } catch (error) {
2851
+ console.error("Failed to delete todo:", error);
2852
+ }
2853
+ };
2854
+ {{else}}
2855
+ {{#if (eq api "trpc")}}
2856
+ const trpc = useTRPC();
2857
+ {{/if}}
2858
+ {{#if (eq api "orpc")}}
2859
+ {{/if}}
2860
+ {{#if (eq api "trpc")}}
2861
+ const todos = useQuery(trpc.todo.getAll.queryOptions());
2862
+ const createMutation = useMutation(
2863
+ trpc.todo.create.mutationOptions({
2864
+ onSuccess: () => {
2865
+ todos.refetch();
2866
+ setNewTodoText("");
2867
+ },
2868
+ }),
2869
+ );
2870
+ const toggleMutation = useMutation(
2871
+ trpc.todo.toggle.mutationOptions({
2872
+ onSuccess: () => { todos.refetch() },
2873
+ }),
2874
+ );
2875
+ const deleteMutation = useMutation(
2876
+ trpc.todo.delete.mutationOptions({
2877
+ onSuccess: () => { todos.refetch() },
2878
+ }),
2879
+ );
2880
+ {{/if}}
2881
+ {{#if (eq api "orpc")}}
2882
+ const todos = useQuery(orpc.todo.getAll.queryOptions());
2883
+ const createMutation = useMutation(
2884
+ orpc.todo.create.mutationOptions({
2885
+ onSuccess: () => {
2886
+ todos.refetch();
2887
+ setNewTodoText("");
2888
+ },
2889
+ }),
2890
+ );
2891
+ const toggleMutation = useMutation(
2892
+ orpc.todo.toggle.mutationOptions({
2893
+ onSuccess: () => { todos.refetch() },
2894
+ }),
2895
+ );
2896
+ const deleteMutation = useMutation(
2897
+ orpc.todo.delete.mutationOptions({
2898
+ onSuccess: () => { todos.refetch() },
2899
+ }),
2900
+ );
2901
+ {{/if}}
2902
+ const handleAddTodo = (e: React.FormEvent) => {
2903
+ e.preventDefault();
2904
+ if (newTodoText.trim()) {
2905
+ createMutation.mutate({ text: newTodoText });
2906
+ }
2907
+ };
2908
+ const handleToggleTodo = (id: number, completed: boolean) => {
2909
+ toggleMutation.mutate({ id, completed: !completed });
2910
+ };
2911
+ const handleDeleteTodo = (id: number) => {
2912
+ deleteMutation.mutate({ id });
2913
+ };
2914
+ {{/if}}
2915
+ return (
2916
+ <div className="mx-auto w-full max-w-md py-10">
2917
+ <Card>
2918
+ <CardHeader>
2919
+ <CardTitle>Todo List{{#if (eq backend "convex")}} (Convex){{/if}}</CardTitle>
2920
+ <CardDescription>Manage your tasks efficiently</CardDescription>
2921
+ </CardHeader>
2922
+ <CardContent>
2923
+ <form
2924
+ onSubmit={handleAddTodo}
2925
+ className="mb-6 flex items-center space-x-2"
2926
+ >
2927
+ <Input
2928
+ value={newTodoText}
2929
+ onChange={(e) => setNewTodoText(e.target.value)}
2930
+ placeholder="Add a new task..."
2931
+ {{#unless (eq backend "convex")}}
2932
+ disabled={createMutation.isPending}
2933
+ {{/unless}}
2934
+ />
2935
+ <Button
2936
+ type="submit"
2937
+ {{#unless (eq backend "convex")}}
2938
+ disabled={createMutation.isPending || !newTodoText.trim()}
2939
+ {{else}}
2940
+ disabled={!newTodoText.trim()}
2941
+ {{/unless}}
2942
+ >
2943
+ {{#unless (eq backend "convex")}}
2944
+ {createMutation.isPending ? (
2945
+ <Loader2 className="h-4 w-4 animate-spin" />
2946
+ ) : (
2947
+ "Add"
2948
+ )}
2949
+ {{else}}
2950
+ Add
2951
+ {{/unless}}
2952
+ </Button>
2953
+ </form>
2954
+ {{#if (eq backend "convex")}}
2955
+ {todos?.length === 0 ? (
2956
+ <p className="py-4 text-center">No todos yet. Add one above!</p>
2957
+ ) : (
2958
+ <ul className="space-y-2">
2959
+ {todos?.map((todo) => (
2960
+ <li
2961
+ key={todo._id}
2962
+ className="flex items-center justify-between rounded-md border p-2"
2963
+ >
2964
+ <div className="flex items-center space-x-2">
2965
+ <Checkbox
2966
+ checked={todo.completed}
2967
+ onCheckedChange={() =>
2968
+ handleToggleTodo(todo._id, todo.completed)
2969
+ }
2970
+ id={\`todo-\${todo._id}\`}
2971
+ />
2972
+ <label
2973
+ htmlFor={\`todo-\${todo._id}\`}
2974
+ className={\`\${
2975
+ todo.completed
2976
+ ? "text-muted-foreground line-through"
2977
+ : ""
2978
+ }\`}
2979
+ >
2980
+ {todo.text}
2981
+ </label>
2982
+ </div>
2983
+ <Button
2984
+ variant="ghost"
2985
+ size="icon"
2986
+ onClick={() => handleDeleteTodo(todo._id)}
2987
+ aria-label="Delete todo"
2988
+ >
2989
+ <Trash2 className="h-4 w-4" />
2990
+ </Button>
2991
+ </li>
2992
+ ))}
2993
+ </ul>
2994
+ )}
2995
+ {{else}}
2996
+ {todos.isLoading ? (
2997
+ <div className="flex justify-center py-4">
2998
+ <Loader2 className="h-6 w-6 animate-spin" />
2999
+ </div>
3000
+ ) : todos.data?.length === 0 ? (
3001
+ <p className="py-4 text-center">No todos yet. Add one above!</p>
3002
+ ) : (
3003
+ <ul className="space-y-2">
3004
+ {todos.data?.map((todo) => (
3005
+ <li
3006
+ key={todo.id}
3007
+ className="flex items-center justify-between rounded-md border p-2"
3008
+ >
3009
+ <div className="flex items-center space-x-2">
3010
+ <Checkbox
3011
+ checked={todo.completed}
3012
+ onCheckedChange={() =>
3013
+ handleToggleTodo(todo.id, todo.completed)
3014
+ }
3015
+ id={\`todo-\${todo.id}\`}
3016
+ />
3017
+ <label
3018
+ htmlFor={\`todo-\${todo.id}\`}
3019
+ className={\`\${todo.completed ? "line-through" : ""}\`}
3020
+ >
3021
+ {todo.text}
3022
+ </label>
3023
+ </div>
3024
+ <Button
3025
+ variant="ghost"
3026
+ size="icon"
3027
+ onClick={() => handleDeleteTodo(todo.id)}
3028
+ aria-label="Delete todo"
3029
+ >
3030
+ <Trash2 className="h-4 w-4" />
3031
+ </Button>
3032
+ </li>
3033
+ ))}
3034
+ </ul>
3035
+ )}
3036
+ {{/if}}
3037
+ </CardContent>
3038
+ </Card>
3039
+ </div>
3040
+ );
3041
+ }
3042
+ `,
3043
+ type: "text"
3044
+ },
3045
+ "examples/todo/web/solid/src/routes/todos.tsx.hbs": {
3046
+ metadata: {
3047
+ updatedAt: "2025-06-17T06:06:35.000Z",
3048
+ updatedHash: "fdf2b26d48"
3049
+ },
3050
+ content: `import { createFileRoute } from "@tanstack/solid-router";
3051
+ import { Loader2, Trash2 } from "lucide-solid";
3052
+ import { createSignal, For, Show } from "solid-js";
3053
+ import { orpc } from "@/utils/orpc";
3054
+ import { useQuery, useMutation } from "@tanstack/solid-query";
3055
+ export const Route = createFileRoute("/todos")({
3056
+ component: TodosRoute,
3057
+ });
3058
+ function TodosRoute() {
3059
+ const [newTodoText, setNewTodoText] = createSignal("");
3060
+ const todos = useQuery(() => orpc.todo.getAll.queryOptions());
3061
+ const createMutation = useMutation(() =>
3062
+ orpc.todo.create.mutationOptions({
3063
+ onSuccess: () => {
3064
+ todos.refetch();
3065
+ setNewTodoText("");
3066
+ },
3067
+ }),
3068
+ );
3069
+ const toggleMutation = useMutation(() =>
3070
+ orpc.todo.toggle.mutationOptions({
3071
+ onSuccess: () => { todos.refetch() },
3072
+ }),
3073
+ );
3074
+ const deleteMutation = useMutation(() =>
3075
+ orpc.todo.delete.mutationOptions({
3076
+ onSuccess: () => { todos.refetch() },
3077
+ }),
3078
+ );
3079
+ const handleAddTodo = (e: Event) => {
3080
+ e.preventDefault();
3081
+ if (newTodoText().trim()) {
3082
+ createMutation.mutate({ text: newTodoText() });
3083
+ }
3084
+ };
3085
+ const handleToggleTodo = (id: number, completed: boolean) => {
3086
+ toggleMutation.mutate({ id, completed: !completed });
3087
+ };
3088
+ const handleDeleteTodo = (id: number) => {
3089
+ deleteMutation.mutate({ id });
3090
+ };
3091
+ return (
3092
+ <div class="mx-auto w-full max-w-md py-10">
3093
+ <div class="rounded-lg border p-6 shadow-sm">
3094
+ <div class="mb-4">
3095
+ <h2 class="text-xl font-semibold">Todo List</h2>
3096
+ <p class="text-sm">Manage your tasks efficiently</p>
3097
+ </div>
3098
+ <div>
3099
+ <form
3100
+ onSubmit={handleAddTodo}
3101
+ class="mb-6 flex items-center space-x-2"
3102
+ >
3103
+ <input
3104
+ type="text"
3105
+ value={newTodoText()}
3106
+ onInput={(e) => setNewTodoText(e.currentTarget.value)}
3107
+ placeholder="Add a new task..."
3108
+ disabled={createMutation.isPending}
3109
+ class="w-full rounded-md border p-2 text-sm"
3110
+ />
3111
+ <button
3112
+ type="submit"
3113
+ disabled={createMutation.isPending || !newTodoText().trim()}
3114
+ class="rounded-md bg-blue-600 px-4 py-2 text-sm text-white disabled:opacity-50"
3115
+ >
3116
+ <Show when={createMutation.isPending} fallback="Add">
3117
+ <Loader2 class="h-4 w-4 animate-spin" />
3118
+ </Show>
3119
+ </button>
3120
+ </form>
3121
+ <Show when={todos.isLoading}>
3122
+ <div class="flex justify-center py-4">
3123
+ <Loader2 class="h-6 w-6 animate-spin" />
3124
+ </div>
3125
+ </Show>
3126
+ <Show when={!todos.isLoading && todos.data?.length === 0}>
3127
+ <p class="py-4 text-center">No todos yet. Add one above!</p>
3128
+ </Show>
3129
+ <Show when={!todos.isLoading}>
3130
+ <ul class="space-y-2">
3131
+ <For each={todos.data}>
3132
+ {(todo) => (
3133
+ <li class="flex items-center justify-between rounded-md border p-2">
3134
+ <div class="flex items-center space-x-2">
3135
+ <input
3136
+ type="checkbox"
3137
+ checked={todo.completed}
3138
+ onChange={() =>
3139
+ handleToggleTodo(todo.id, todo.completed)
3140
+ }
3141
+ id={\`todo-\${todo.id}\`}
3142
+ class="h-4 w-4"
3143
+ />
3144
+ <label
3145
+ for={\`todo-\${todo.id}\`}
3146
+ class={todo.completed ? "line-through" : ""}
3147
+ >
3148
+ {todo.text}
3149
+ </label>
3150
+ </div>
3151
+ <button
3152
+ type="button"
3153
+ onClick={() => handleDeleteTodo(todo.id)}
3154
+ aria-label="Delete todo"
3155
+ class="ml-2 rounded-md p-1"
3156
+ >
3157
+ <Trash2 class="h-4 w-4" />
3158
+ </button>
3159
+ </li>
3160
+ )}
3161
+ </For>
3162
+ </ul>
3163
+ </Show>
3164
+ </div>
3165
+ </div>
3166
+ </div>
3167
+ );
3168
+ }
3169
+ `,
3170
+ type: "text"
3171
+ },
3172
+ "examples/todo/web/svelte/src/routes/todos/+page.svelte.hbs": {
3173
+ metadata: {
3174
+ updatedAt: "2025-06-17T06:06:35.000Z",
3175
+ updatedHash: "782c16fd68"
3176
+ },
3177
+ content: `{{#if (eq backend "convex")}}
3178
+ <script lang="ts">
3179
+ import { useQuery, useConvexClient } from 'convex-svelte';
3180
+ import { api } from '@{{projectName}}/backend/convex/_generated/api';
3181
+ import type { Id } from '@{{projectName}}/backend/convex/_generated/dataModel';
3182
+ let newTodoText = $state('');
3183
+ let isAdding = $state(false);
3184
+ let addError = $state<Error | null>(null);
3185
+ let togglingId = $state<Id<'todos'> | null>(null);
3186
+ let toggleError = $state<Error | null>(null);
3187
+ let deletingId = $state<Id<'todos'> | null>(null);
3188
+ let deleteError = $state<Error | null>(null);
3189
+ const client = useConvexClient();
3190
+ const todosQuery = useQuery(api.todos.getAll, {});
3191
+ async function handleAddTodo(event: SubmitEvent) {
3192
+ event.preventDefault();
3193
+ const text = newTodoText.trim();
3194
+ if (!text || isAdding) return;
3195
+ isAdding = true;
3196
+ addError = null;
3197
+ try {
3198
+ await client.mutation(api.todos.create, { text });
3199
+ newTodoText = '';
3200
+ } catch (err) {
3201
+ console.error('Failed to add todo:', err);
3202
+ addError = err instanceof Error ? err : new Error(String(err));
3203
+ } finally {
3204
+ isAdding = false;
3205
+ }
3206
+ }
3207
+ async function handleToggleTodo(id: Id<'todos'>, completed: boolean) {
3208
+ if (togglingId === id || deletingId === id) return;
3209
+ togglingId = id;
3210
+ toggleError = null;
3211
+ try {
3212
+ await client.mutation(api.todos.toggle, { id, completed: !completed });
3213
+ } catch (err) {
3214
+ console.error('Failed to toggle todo:', err);
3215
+ toggleError = err instanceof Error ? err : new Error(String(err));
3216
+ } finally {
3217
+ if (togglingId === id) {
3218
+ togglingId = null;
3219
+ }
3220
+ }
3221
+ }
3222
+ async function handleDeleteTodo(id: Id<'todos'>) {
3223
+ if (togglingId === id || deletingId === id) return;
3224
+ deletingId = id;
3225
+ deleteError = null;
3226
+ try {
3227
+ await client.mutation(api.todos.deleteTodo, { id });
3228
+ } catch (err) {
3229
+ console.error('Failed to delete todo:', err);
3230
+ deleteError = err instanceof Error ? err : new Error(String(err));
3231
+ } finally {
3232
+ if (deletingId === id) {
3233
+ deletingId = null;
3234
+ }
3235
+ }
3236
+ }
3237
+ const canAdd = $derived(!isAdding && newTodoText.trim().length > 0);
3238
+ const isLoadingTodos = $derived(todosQuery.isLoading);
3239
+ const todos = $derived(todosQuery.data ?? []);
3240
+ const hasTodos = $derived(todos.length > 0);
3241
+ <\/script>
3242
+ <div class="p-4">
3243
+ <h1 class="text-xl mb-4">Todos (Convex)</h1>
3244
+ <form onsubmit={handleAddTodo} class="flex gap-2 mb-4">
3245
+ <input
3246
+ type="text"
3247
+ bind:value={newTodoText}
3248
+ placeholder="New task..."
3249
+ disabled={isAdding}
3250
+ class="p-1 flex-grow"
3251
+ />
3252
+ <button
3253
+ type="submit"
3254
+ disabled={!canAdd}
3255
+ class="bg-blue-500 text-white px-3 py-1 rounded disabled:opacity-50"
3256
+ >
3257
+ {#if isAdding}Adding...{:else}Add{/if}
3258
+ </button>
3259
+ </form>
3260
+ {#if isLoadingTodos}
3261
+ <p>Loading...</p>
3262
+ {:else if !hasTodos}
3263
+ <p>No todos yet.</p>
3264
+ {:else}
3265
+ <ul class="space-y-1">
3266
+ {#each todos as todo (todo._id)}
3267
+ {@const isTogglingThis = togglingId === todo._id}
3268
+ {@const isDeletingThis = deletingId === todo._id}
3269
+ {@const isDisabled = isTogglingThis || isDeletingThis}
3270
+ <li
3271
+ class="flex items-center justify-between p-2"
3272
+ class:opacity-50={isDisabled}
3273
+ >
3274
+ <div class="flex items-center gap-2">
3275
+ <input
3276
+ type="checkbox"
3277
+ id={\`todo-\${todo._id}\`}
3278
+ checked={todo.completed}
3279
+ onchange={() => handleToggleTodo(todo._id, todo.completed)}
3280
+ disabled={isDisabled}
3281
+ />
3282
+ <label
3283
+ for={\`todo-\${todo._id}\`}
3284
+ class:line-through={todo.completed}
3285
+ >
3286
+ {todo.text}
3287
+ </label>
3288
+ </div>
3289
+ <button
3290
+ type="button"
3291
+ onclick={() => handleDeleteTodo(todo._id)}
3292
+ disabled={isDisabled}
3293
+ aria-label="Delete todo"
3294
+ class="text-red-500 px-1 disabled:opacity-50"
3295
+ >
3296
+ {#if isDeletingThis}Deleting...{:else}X{/if}
3297
+ </button>
3298
+ </li>
3299
+ {/each}
3300
+ </ul>
3301
+ {/if}
3302
+ {#if todosQuery.error}
3303
+ <p class="mt-4 text-red-500">
3304
+ Error loading: {todosQuery.error?.message ?? 'Unknown error'}
3305
+ </p>
3306
+ {/if}
3307
+ {#if addError}
3308
+ <p class="mt-4 text-red-500">
3309
+ Error adding: {addError.message ?? 'Unknown error'}
3310
+ </p>
3311
+ {/if}
3312
+ {#if toggleError}
3313
+ <p class="mt-4 text-red-500">
3314
+ Error updating: {toggleError.message ?? 'Unknown error'}
3315
+ </p>
3316
+ {/if}
3317
+ {#if deleteError}
3318
+ <p class="mt-4 text-red-500">
3319
+ Error deleting: {deleteError.message ?? 'Unknown error'}
3320
+ </p>
3321
+ {/if}
3322
+ </div>
3323
+ {{else}}
3324
+ <script lang="ts">
3325
+ {{#if (eq api "orpc")}}
3326
+ import { orpc } from '$lib/orpc';
3327
+ {{/if}}
3328
+ import { createQuery, createMutation } from '@tanstack/svelte-query';
3329
+ let newTodoText = $state('');
3330
+ {{#if (eq api "orpc")}}
3331
+ const todosQuery = createQuery(orpc.todo.getAll.queryOptions());
3332
+ const addMutation = createMutation(
3333
+ orpc.todo.create.mutationOptions({
3334
+ onSuccess: () => {
3335
+ $todosQuery.refetch();
3336
+ newTodoText = '';
3337
+ },
3338
+ onError: (error) => {
3339
+ console.error('Failed to create todo:', error?.message ?? error);
3340
+ },
3341
+ })
3342
+ );
3343
+ const toggleMutation = createMutation(
3344
+ orpc.todo.toggle.mutationOptions({
3345
+ onSuccess: () => {
3346
+ $todosQuery.refetch();
3347
+ },
3348
+ onError: (error) => {
3349
+ console.error('Failed to toggle todo:', error?.message ?? error);
3350
+ },
3351
+ })
3352
+ );
3353
+ const deleteMutation = createMutation(
3354
+ orpc.todo.delete.mutationOptions({
3355
+ onSuccess: () => {
3356
+ $todosQuery.refetch();
3357
+ },
3358
+ onError: (error) => {
3359
+ console.error('Failed to delete todo:', error?.message ?? error);
3360
+ },
3361
+ })
3362
+ );
3363
+ {{/if}}
3364
+ function handleAddTodo(event: SubmitEvent) {
3365
+ event.preventDefault();
3366
+ const text = newTodoText.trim();
3367
+ if (text) {
3368
+ $addMutation.mutate({ text });
3369
+ }
3370
+ }
3371
+ function handleToggleTodo(id: number, completed: boolean) {
3372
+ $toggleMutation.mutate({ id, completed: !completed });
3373
+ }
3374
+ function handleDeleteTodo(id: number) {
3375
+ $deleteMutation.mutate({ id });
3376
+ }
3377
+ const isAdding = $derived($addMutation.isPending);
3378
+ const canAdd = $derived(!isAdding && newTodoText.trim().length > 0);
3379
+ const isLoadingTodos = $derived($todosQuery.isLoading);
3380
+ const todos = $derived($todosQuery.data ?? []);
3381
+ const hasTodos = $derived(todos.length > 0);
3382
+ <\/script>
3383
+ <div class="p-4">
3384
+ <h1 class="text-xl mb-4">Todos{{#if (eq api "orpc")}} (oRPC){{/if}}</h1>
3385
+ <form onsubmit={handleAddTodo} class="flex gap-2 mb-4">
3386
+ <input
3387
+ type="text"
3388
+ bind:value={newTodoText}
3389
+ placeholder="New task..."
3390
+ disabled={isAdding}
3391
+ class=" p-1 flex-grow"
3392
+ />
3393
+ <button
3394
+ type="submit"
3395
+ disabled={!canAdd}
3396
+ class="bg-blue-500 text-white px-3 py-1 rounded disabled:opacity-50"
3397
+ >
3398
+ {#if isAdding}Adding...{:else}Add{/if}
3399
+ </button>
3400
+ </form>
3401
+ {#if isLoadingTodos}
3402
+ <p>Loading...</p>
3403
+ {:else if !hasTodos}
3404
+ <p>No todos yet.</p>
3405
+ {:else}
3406
+ <ul class="space-y-1">
3407
+ {#each todos as todo (todo.id)}
3408
+ {@const isToggling = $toggleMutation.isPending && $toggleMutation.variables?.id === todo.id}
3409
+ {@const isDeleting = $deleteMutation.isPending && $deleteMutation.variables?.id === todo.id}
3410
+ {@const isDisabled = isToggling || isDeleting}
3411
+ <li
3412
+ class="flex items-center justify-between p-2 "
3413
+ class:opacity-50={isDisabled}
3414
+ >
3415
+ <div class="flex items-center gap-2">
3416
+ <input
3417
+ type="checkbox"
3418
+ id={\`todo-\${todo.id}\`}
3419
+ checked={todo.completed}
3420
+ onchange={() => handleToggleTodo(todo.id, todo.completed)}
3421
+ disabled={isDisabled}
3422
+ />
3423
+ <label
3424
+ for={\`todo-\${todo.id}\`}
3425
+ class:line-through={todo.completed}
3426
+ >
3427
+ {todo.text}
3428
+ </label>
3429
+ </div>
3430
+ <button
3431
+ type="button"
3432
+ onclick={() => handleDeleteTodo(todo.id)}
3433
+ disabled={isDisabled}
3434
+ aria-label="Delete todo"
3435
+ class="text-red-500 px-1 disabled:opacity-50"
3436
+ >
3437
+ {#if isDeleting}Deleting...{:else}X{/if}
3438
+ </button>
3439
+ </li>
3440
+ {/each}
3441
+ </ul>
3442
+ {/if}
3443
+ {#if $todosQuery.isError}
3444
+ <p class="mt-4 text-red-500">
3445
+ Error loading: {$todosQuery.error?.message ?? 'Unknown error'}
3446
+ </p>
3447
+ {/if}
3448
+ {#if $addMutation.isError}
3449
+ <p class="mt-4 text-red-500">
3450
+ Error adding: {$addMutation.error?.message ?? 'Unknown error'}
3451
+ </p>
3452
+ {/if}
3453
+ {#if $toggleMutation.isError}
3454
+ <p class="mt-4 text-red-500">
3455
+ Error updating: {$toggleMutation.error?.message ?? 'Unknown error'}
3456
+ </p>
3457
+ {/if}
3458
+ {#if $deleteMutation.isError}
3459
+ <p class="mt-4 text-red-500">
3460
+ Error deleting: {$deleteMutation.error?.message ?? 'Unknown error'}
3461
+ </p>
3462
+ {/if}
3463
+ </div>
3464
+ {{/if}}
3465
+ `,
3466
+ type: "text"
3467
+ }
3468
+ }
3469
+ }
3470
+ };