@reliverse/dler 1.7.152 → 2.0.0

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 (822) hide show
  1. package/cli.js +1316 -0
  2. package/package.json +21 -144
  3. package/LICENSE +0 -21
  4. package/LICENSES +0 -22
  5. package/README.md +0 -36
  6. package/bin/impl/add/add-global/install-impl.d.ts +0 -38
  7. package/bin/impl/add/add-global/install-impl.js +0 -254
  8. package/bin/impl/add/add-global/install-mod.d.ts +0 -0
  9. package/bin/impl/add/add-global/install-mod.js +0 -0
  10. package/bin/impl/add/add-local/api/orpc.d.ts +0 -1
  11. package/bin/impl/add/add-local/api/orpc.js +0 -4
  12. package/bin/impl/add/add-local/api/trpc.d.ts +0 -1
  13. package/bin/impl/add/add-local/api/trpc.js +0 -4
  14. package/bin/impl/add/add-local/auth/better-auth.d.ts +0 -1
  15. package/bin/impl/add/add-local/auth/better-auth.js +0 -4
  16. package/bin/impl/add/add-local/auth/clerk-auth.d.ts +0 -1
  17. package/bin/impl/add/add-local/auth/clerk-auth.js +0 -4
  18. package/bin/impl/add/add-local/auth/next-auth.d.ts +0 -1
  19. package/bin/impl/add/add-local/auth/next-auth.js +0 -4
  20. package/bin/impl/add/add-local/core/deps.d.ts +0 -8
  21. package/bin/impl/add/add-local/core/deps.js +0 -19
  22. package/bin/impl/add/add-local/core/prompts.d.ts +0 -4
  23. package/bin/impl/add/add-local/core/prompts.js +0 -12
  24. package/bin/impl/add/add-local/core/templates.d.ts +0 -29
  25. package/bin/impl/add/add-local/core/templates.js +0 -85
  26. package/bin/impl/add/add-local/core/types.d.ts +0 -6
  27. package/bin/impl/add/add-local/core/types.js +0 -0
  28. package/bin/impl/add/add-local/db/drizzle.d.ts +0 -1
  29. package/bin/impl/add/add-local/db/drizzle.js +0 -4
  30. package/bin/impl/add/add-local/db/prisma.d.ts +0 -1
  31. package/bin/impl/add/add-local/db/prisma.js +0 -4
  32. package/bin/impl/add/add-local/files/uploadthing.d.ts +0 -1
  33. package/bin/impl/add/add-local/files/uploadthing.js +0 -4
  34. package/bin/impl/add/add-local/form/react-hook-form.d.ts +0 -1
  35. package/bin/impl/add/add-local/form/react-hook-form.js +0 -4
  36. package/bin/impl/add/add-local/form/tanstack-form.d.ts +0 -1
  37. package/bin/impl/add/add-local/form/tanstack-form.js +0 -4
  38. package/bin/impl/add/add-local/fws/browser/plasmo.d.ts +0 -1
  39. package/bin/impl/add/add-local/fws/browser/plasmo.js +0 -4
  40. package/bin/impl/add/add-local/fws/browser/wxt.d.ts +0 -1
  41. package/bin/impl/add/add-local/fws/browser/wxt.js +0 -4
  42. package/bin/impl/add/add-local/fws/configs/eslint-config.d.ts +0 -1
  43. package/bin/impl/add/add-local/fws/configs/eslint-config.js +0 -4
  44. package/bin/impl/add/add-local/fws/native/lynx.d.ts +0 -1
  45. package/bin/impl/add/add-local/fws/native/lynx.js +0 -4
  46. package/bin/impl/add/add-local/fws/native/react.d.ts +0 -1
  47. package/bin/impl/add/add-local/fws/native/react.js +0 -4
  48. package/bin/impl/add/add-local/fws/plugins/eslint-plugin.d.ts +0 -1
  49. package/bin/impl/add/add-local/fws/plugins/eslint-plugin.js +0 -4
  50. package/bin/impl/add/add-local/fws/vscode/vscode-ext.d.ts +0 -1
  51. package/bin/impl/add/add-local/fws/vscode/vscode-ext.js +0 -4
  52. package/bin/impl/add/add-local/fws/web/astro.d.ts +0 -1
  53. package/bin/impl/add/add-local/fws/web/astro.js +0 -4
  54. package/bin/impl/add/add-local/fws/web/jstack.d.ts +0 -1
  55. package/bin/impl/add/add-local/fws/web/jstack.js +0 -4
  56. package/bin/impl/add/add-local/fws/web/next.d.ts +0 -1
  57. package/bin/impl/add/add-local/fws/web/next.js +0 -4
  58. package/bin/impl/add/add-local/fws/web/start.d.ts +0 -1
  59. package/bin/impl/add/add-local/fws/web/start.js +0 -4
  60. package/bin/impl/add/add-local/fws/web/vite.d.ts +0 -1
  61. package/bin/impl/add/add-local/fws/web/vite.js +0 -4
  62. package/bin/impl/add/add-local/i18n/gt-libs.d.ts +0 -1
  63. package/bin/impl/add/add-local/i18n/gt-libs.js +0 -4
  64. package/bin/impl/add/add-local/i18n/languine.d.ts +0 -1
  65. package/bin/impl/add/add-local/i18n/languine.js +0 -19
  66. package/bin/impl/add/add-local/i18n/next-intl.d.ts +0 -1
  67. package/bin/impl/add/add-local/i18n/next-intl.js +0 -4
  68. package/bin/impl/add/add-local/llm/vercel.d.ts +0 -1
  69. package/bin/impl/add/add-local/llm/vercel.js +0 -4
  70. package/bin/impl/add/add-local/mail/resend.d.ts +0 -1
  71. package/bin/impl/add/add-local/mail/resend.js +0 -4
  72. package/bin/impl/add/add-local/pay/polar.d.ts +0 -1
  73. package/bin/impl/add/add-local/pay/polar.js +0 -4
  74. package/bin/impl/add/add-local/pay/stripe.d.ts +0 -1
  75. package/bin/impl/add/add-local/pay/stripe.js +0 -4
  76. package/bin/impl/add/add-local/tool/biome.d.ts +0 -1
  77. package/bin/impl/add/add-local/tool/biome.js +0 -4
  78. package/bin/impl/add/add-local/tool/eslint.d.ts +0 -1
  79. package/bin/impl/add/add-local/tool/eslint.js +0 -4
  80. package/bin/impl/add/add-local/tool/oxlint.d.ts +0 -4
  81. package/bin/impl/add/add-local/tool/oxlint.js +0 -4
  82. package/bin/impl/add/add-local/ui/21st.d.ts +0 -4
  83. package/bin/impl/add/add-local/ui/21st.js +0 -4
  84. package/bin/impl/add/add-local/ui/shadcn.d.ts +0 -1
  85. package/bin/impl/add/add-local/ui/shadcn.js +0 -4
  86. package/bin/impl/add/add-local/ui/tailwind.d.ts +0 -1
  87. package/bin/impl/add/add-local/ui/tailwind.js +0 -4
  88. package/bin/impl/add/add-rule/add-rule-const.d.ts +0 -11
  89. package/bin/impl/add/add-rule/add-rule-const.js +0 -32
  90. package/bin/impl/add/add-rule/add-rule-impl.d.ts +0 -21
  91. package/bin/impl/add/add-rule/add-rule-impl.js +0 -300
  92. package/bin/impl/add/add-rule/add-rule-types.d.ts +0 -18
  93. package/bin/impl/add/add-rule/add-rule-types.js +0 -0
  94. package/bin/impl/add/add-rule/add-rule-utils.d.ts +0 -61
  95. package/bin/impl/add/add-rule/add-rule-utils.js +0 -324
  96. package/bin/impl/ai/ai-impl/ai-auth.d.ts +0 -10
  97. package/bin/impl/ai/ai-impl/ai-auth.js +0 -59
  98. package/bin/impl/ai/ai-impl/ai-chat.d.ts +0 -5
  99. package/bin/impl/ai/ai-impl/ai-chat.js +0 -93
  100. package/bin/impl/ai/ai-impl/ai-const.d.ts +0 -7
  101. package/bin/impl/ai/ai-impl/ai-const.js +0 -14
  102. package/bin/impl/ai/ai-impl/ai-tools.d.ts +0 -5
  103. package/bin/impl/ai/ai-impl/ai-tools.js +0 -32
  104. package/bin/impl/ai/ai-impl/ai-types.d.ts +0 -12
  105. package/bin/impl/ai/ai-impl/ai-types.js +0 -0
  106. package/bin/impl/ai/ai-impl/code/code-mod.d.ts +0 -6
  107. package/bin/impl/ai/ai-impl/code/code-mod.js +0 -164
  108. package/bin/impl/ai/ai-impl/mcp/mcp-mod.d.ts +0 -5
  109. package/bin/impl/ai/ai-impl/mcp/mcp-mod.js +0 -125
  110. package/bin/impl/ai/ai-impl/relinter/relinter.d.ts +0 -27
  111. package/bin/impl/ai/ai-impl/relinter/relinter.js +0 -309
  112. package/bin/impl/ai/ai-menu.d.ts +0 -3
  113. package/bin/impl/ai/ai-menu.js +0 -40
  114. package/bin/impl/auth/consts.d.ts +0 -2
  115. package/bin/impl/auth/consts.js +0 -2
  116. package/bin/impl/auth/generators/auth-config.d.ts +0 -32
  117. package/bin/impl/auth/generators/auth-config.js +0 -533
  118. package/bin/impl/auth/generators/drizzle.d.ts +0 -3
  119. package/bin/impl/auth/generators/drizzle.js +0 -137
  120. package/bin/impl/auth/generators/index.d.ts +0 -16
  121. package/bin/impl/auth/generators/index.js +0 -18
  122. package/bin/impl/auth/generators/kysely.d.ts +0 -2
  123. package/bin/impl/auth/generators/kysely.js +0 -9
  124. package/bin/impl/auth/generators/prisma.d.ts +0 -2
  125. package/bin/impl/auth/generators/prisma.js +0 -154
  126. package/bin/impl/auth/generators/types.d.ts +0 -11
  127. package/bin/impl/auth/generators/types.js +0 -0
  128. package/bin/impl/auth/impl/init.d.ts +0 -183
  129. package/bin/impl/auth/impl/init.js +0 -367
  130. package/bin/impl/auth/impl/migrate.d.ts +0 -6
  131. package/bin/impl/auth/impl/migrate.js +0 -90
  132. package/bin/impl/auth/impl/types.d.ts +0 -12
  133. package/bin/impl/auth/impl/types.js +0 -0
  134. package/bin/impl/auth/utils/add-svelte-kit-env-modules.d.ts +0 -3
  135. package/bin/impl/auth/utils/add-svelte-kit-env-modules.js +0 -91
  136. package/bin/impl/auth/utils/check-package-managers.d.ts +0 -4
  137. package/bin/impl/auth/utils/check-package-managers.js +0 -20
  138. package/bin/impl/auth/utils/format-ms.d.ts +0 -4
  139. package/bin/impl/auth/utils/format-ms.js +0 -11
  140. package/bin/impl/auth/utils/generate-secret.d.ts +0 -1
  141. package/bin/impl/auth/utils/generate-secret.js +0 -2
  142. package/bin/impl/auth/utils/get-config.d.ts +0 -8
  143. package/bin/impl/auth/utils/get-config.js +0 -169
  144. package/bin/impl/auth/utils/get-package-info.d.ts +0 -1
  145. package/bin/impl/auth/utils/get-package-info.js +0 -6
  146. package/bin/impl/auth/utils/get-tsconfig-info.d.ts +0 -2
  147. package/bin/impl/auth/utils/get-tsconfig-info.js +0 -15
  148. package/bin/impl/auth/utils/install-dependencies.d.ts +0 -5
  149. package/bin/impl/auth/utils/install-dependencies.js +0 -34
  150. package/bin/impl/build/binary-flow.d.ts +0 -6
  151. package/bin/impl/build/binary-flow.js +0 -173
  152. package/bin/impl/build/build-library.d.ts +0 -42
  153. package/bin/impl/build/build-library.js +0 -626
  154. package/bin/impl/build/build-regular.d.ts +0 -20
  155. package/bin/impl/build/build-regular.js +0 -398
  156. package/bin/impl/build/impl.d.ts +0 -19
  157. package/bin/impl/build/impl.js +0 -104
  158. package/bin/impl/build/library-flow.d.ts +0 -26
  159. package/bin/impl/build/library-flow.js +0 -252
  160. package/bin/impl/build/postbuild.d.ts +0 -3
  161. package/bin/impl/build/postbuild.js +0 -173
  162. package/bin/impl/build/ppb-utils.d.ts +0 -16
  163. package/bin/impl/build/ppb-utils.js +0 -99
  164. package/bin/impl/build/prebuild.d.ts +0 -2
  165. package/bin/impl/build/prebuild.js +0 -108
  166. package/bin/impl/build/providers/auto.d.ts +0 -3
  167. package/bin/impl/build/providers/auto.js +0 -105
  168. package/bin/impl/build/providers/build.d.ts +0 -8
  169. package/bin/impl/build/providers/build.js +0 -351
  170. package/bin/impl/build/providers/bun/bun-build.d.ts +0 -0
  171. package/bin/impl/build/providers/bun/bun-build.js +0 -0
  172. package/bin/impl/build/providers/bun/single-file.d.ts +0 -25
  173. package/bin/impl/build/providers/bun/single-file.js +0 -146
  174. package/bin/impl/build/providers/copy/copy-mod.d.ts +0 -2
  175. package/bin/impl/build/providers/copy/copy-mod.js +0 -49
  176. package/bin/impl/build/providers/mkdist/mkdist-impl/loader.d.ts +0 -4
  177. package/bin/impl/build/providers/mkdist/mkdist-impl/loader.js +0 -26
  178. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/js.d.ts +0 -2
  179. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/js.js +0 -50
  180. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/loaders-mod.d.ts +0 -12
  181. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/loaders-mod.js +0 -30
  182. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/postcss.d.ts +0 -3
  183. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/postcss.js +0 -28
  184. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/sass.d.ts +0 -2
  185. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/sass.js +0 -31
  186. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/vue.d.ts +0 -17
  187. package/bin/impl/build/providers/mkdist/mkdist-impl/loaders/vue.js +0 -145
  188. package/bin/impl/build/providers/mkdist/mkdist-impl/make.d.ts +0 -11
  189. package/bin/impl/build/providers/mkdist/mkdist-impl/make.js +0 -192
  190. package/bin/impl/build/providers/mkdist/mkdist-impl/utils/dts.d.ts +0 -11
  191. package/bin/impl/build/providers/mkdist/mkdist-impl/utils/dts.js +0 -94
  192. package/bin/impl/build/providers/mkdist/mkdist-impl/utils/fs.d.ts +0 -1
  193. package/bin/impl/build/providers/mkdist/mkdist-impl/utils/fs.js +0 -15
  194. package/bin/impl/build/providers/mkdist/mkdist-impl/utils/vue-dts.d.ts +0 -3
  195. package/bin/impl/build/providers/mkdist/mkdist-impl/utils/vue-dts.js +0 -175
  196. package/bin/impl/build/providers/mkdist/mkdist-mod.d.ts +0 -2
  197. package/bin/impl/build/providers/mkdist/mkdist-mod.js +0 -92
  198. package/bin/impl/build/providers/rollup/build.d.ts +0 -2
  199. package/bin/impl/build/providers/rollup/build.js +0 -100
  200. package/bin/impl/build/providers/rollup/config.d.ts +0 -2
  201. package/bin/impl/build/providers/rollup/config.js +0 -112
  202. package/bin/impl/build/providers/rollup/plugins/cjs.d.ts +0 -4
  203. package/bin/impl/build/providers/rollup/plugins/cjs.js +0 -47
  204. package/bin/impl/build/providers/rollup/plugins/esbuild.d.ts +0 -3
  205. package/bin/impl/build/providers/rollup/plugins/esbuild.js +0 -91
  206. package/bin/impl/build/providers/rollup/plugins/json.d.ts +0 -3
  207. package/bin/impl/build/providers/rollup/plugins/json.js +0 -17
  208. package/bin/impl/build/providers/rollup/plugins/raw.d.ts +0 -8
  209. package/bin/impl/build/providers/rollup/plugins/raw.js +0 -20
  210. package/bin/impl/build/providers/rollup/plugins/shebang.d.ts +0 -5
  211. package/bin/impl/build/providers/rollup/plugins/shebang.js +0 -42
  212. package/bin/impl/build/providers/rollup/stub.d.ts +0 -2
  213. package/bin/impl/build/providers/rollup/stub.js +0 -125
  214. package/bin/impl/build/providers/rollup/utils.d.ts +0 -5
  215. package/bin/impl/build/providers/rollup/utils.js +0 -38
  216. package/bin/impl/build/providers/rollup/watch.d.ts +0 -2
  217. package/bin/impl/build/providers/rollup/watch.js +0 -30
  218. package/bin/impl/build/providers/untyped/untyped-mod.d.ts +0 -2
  219. package/bin/impl/build/providers/untyped/untyped-mod.js +0 -111
  220. package/bin/impl/build/providers/utils.d.ts +0 -19
  221. package/bin/impl/build/providers/utils.js +0 -148
  222. package/bin/impl/build/providers/validate.d.ts +0 -4
  223. package/bin/impl/build/providers/validate.js +0 -52
  224. package/bin/impl/build/regular-flow.d.ts +0 -10
  225. package/bin/impl/build/regular-flow.js +0 -246
  226. package/bin/impl/clone/firecrawl/firecrawl-mod.d.ts +0 -1
  227. package/bin/impl/clone/firecrawl/firecrawl-mod.js +0 -11
  228. package/bin/impl/cmod/cmod-impl.d.ts +0 -9
  229. package/bin/impl/cmod/cmod-impl.js +0 -21
  230. package/bin/impl/config/biome.d.ts +0 -2
  231. package/bin/impl/config/biome.js +0 -34
  232. package/bin/impl/config/comments.d.ts +0 -1
  233. package/bin/impl/config/comments.js +0 -57
  234. package/bin/impl/config/constants.d.ts +0 -45
  235. package/bin/impl/config/constants.js +0 -60
  236. package/bin/impl/config/content.d.ts +0 -14
  237. package/bin/impl/config/content.js +0 -15
  238. package/bin/impl/config/core.d.ts +0 -14
  239. package/bin/impl/config/core.js +0 -79
  240. package/bin/impl/config/create.d.ts +0 -35
  241. package/bin/impl/config/create.js +0 -274
  242. package/bin/impl/config/def-utils.d.ts +0 -6
  243. package/bin/impl/config/def-utils.js +0 -227
  244. package/bin/impl/config/detect.d.ts +0 -24
  245. package/bin/impl/config/detect.js +0 -371
  246. package/bin/impl/config/gen-cfg.d.ts +0 -3
  247. package/bin/impl/config/gen-cfg.js +0 -180
  248. package/bin/impl/config/load.d.ts +0 -15
  249. package/bin/impl/config/load.js +0 -87
  250. package/bin/impl/config/migrate.d.ts +0 -5
  251. package/bin/impl/config/migrate.js +0 -60
  252. package/bin/impl/config/path.d.ts +0 -11
  253. package/bin/impl/config/path.js +0 -28
  254. package/bin/impl/config/prepare.d.ts +0 -3
  255. package/bin/impl/config/prepare.js +0 -832
  256. package/bin/impl/config/prompts.d.ts +0 -5
  257. package/bin/impl/config/prompts.js +0 -12
  258. package/bin/impl/config/read.d.ts +0 -11
  259. package/bin/impl/config/read.js +0 -62
  260. package/bin/impl/config/repair.d.ts +0 -15
  261. package/bin/impl/config/repair.js +0 -101
  262. package/bin/impl/config/unstable.d.ts +0 -11
  263. package/bin/impl/config/unstable.js +0 -29
  264. package/bin/impl/config/update.d.ts +0 -10
  265. package/bin/impl/config/update.js +0 -145
  266. package/bin/impl/config/utils.d.ts +0 -17
  267. package/bin/impl/config/utils.js +0 -85
  268. package/bin/impl/conv/mod.d.ts +0 -26
  269. package/bin/impl/conv/mod.js +0 -193
  270. package/bin/impl/db/client.d.ts +0 -4
  271. package/bin/impl/db/client.js +0 -32
  272. package/bin/impl/db/config.d.ts +0 -2
  273. package/bin/impl/db/config.js +0 -59
  274. package/bin/impl/db/messages.d.ts +0 -13
  275. package/bin/impl/db/messages.js +0 -81
  276. package/bin/impl/db/schema.d.ts +0 -90
  277. package/bin/impl/db/schema.js +0 -9
  278. package/bin/impl/env/env-impl.d.ts +0 -1
  279. package/bin/impl/env/env-impl.js +0 -28
  280. package/bin/impl/get/get-core.d.ts +0 -3
  281. package/bin/impl/get/get-core.js +0 -453
  282. package/bin/impl/init/init-utils/init-impl.d.ts +0 -6
  283. package/bin/impl/init/init-utils/init-impl.js +0 -31
  284. package/bin/impl/init/init-utils/init-utils.d.ts +0 -35
  285. package/bin/impl/init/init-utils/init-utils.js +0 -255
  286. package/bin/impl/init/init-utils/mm-deprecated/editor-menu.d.ts +0 -4
  287. package/bin/impl/init/init-utils/mm-deprecated/editor-menu.js +0 -400
  288. package/bin/impl/init/mm-deprecated/drizzle/manageDrizzleConstants.d.ts +0 -2
  289. package/bin/impl/init/mm-deprecated/drizzle/manageDrizzleConstants.js +0 -36
  290. package/bin/impl/init/mm-deprecated/drizzle/manageDrizzleSchema.d.ts +0 -1
  291. package/bin/impl/init/mm-deprecated/drizzle/manageDrizzleSchema.js +0 -81
  292. package/bin/impl/init/mm-deprecated/drizzle/manageDrizzleSchemaUtils.d.ts +0 -16
  293. package/bin/impl/init/mm-deprecated/drizzle/manageDrizzleSchemaUtils.js +0 -474
  294. package/bin/impl/init/mm-deprecated/editor-impl.d.ts +0 -1
  295. package/bin/impl/init/mm-deprecated/editor-impl.js +0 -153
  296. package/bin/impl/init/mm-deprecated/editor-mod.d.ts +0 -18
  297. package/bin/impl/init/mm-deprecated/editor-mod.js +0 -184
  298. package/bin/impl/init/mm-deprecated/feature-add.d.ts +0 -2
  299. package/bin/impl/init/mm-deprecated/feature-add.js +0 -591
  300. package/bin/impl/init/mm-deprecated/feature-rm.d.ts +0 -2
  301. package/bin/impl/init/mm-deprecated/feature-rm.js +0 -98
  302. package/bin/impl/init/mm-deprecated/shadcn/shadcn-mod.d.ts +0 -1
  303. package/bin/impl/init/mm-deprecated/shadcn/shadcn-mod.js +0 -87
  304. package/bin/impl/init/use-template/cp-impl.d.ts +0 -39
  305. package/bin/impl/init/use-template/cp-impl.js +0 -286
  306. package/bin/impl/init/use-template/cp-mod.d.ts +0 -31
  307. package/bin/impl/init/use-template/cp-mod.js +0 -233
  308. package/bin/impl/init/use-template/cp-modules/cli-main-modules/cli-menu-items/showCloneProjectMenu.d.ts +0 -11
  309. package/bin/impl/init/use-template/cp-modules/cli-main-modules/cli-menu-items/showCloneProjectMenu.js +0 -206
  310. package/bin/impl/init/use-template/cp-modules/cli-main-modules/modules/showAnykeyPrompt.d.ts +0 -1
  311. package/bin/impl/init/use-template/cp-modules/cli-main-modules/modules/showAnykeyPrompt.js +0 -9
  312. package/bin/impl/init/use-template/cp-modules/compose-env-file/cef-impl.d.ts +0 -16
  313. package/bin/impl/init/use-template/cp-modules/compose-env-file/cef-impl.js +0 -400
  314. package/bin/impl/init/use-template/cp-modules/compose-env-file/cef-keys.d.ts +0 -17
  315. package/bin/impl/init/use-template/cp-modules/compose-env-file/cef-keys.js +0 -142
  316. package/bin/impl/init/use-template/cp-modules/compose-env-file/cef-mod.d.ts +0 -2
  317. package/bin/impl/init/use-template/cp-modules/compose-env-file/cef-mod.js +0 -167
  318. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/deploy.d.ts +0 -12
  319. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/deploy.js +0 -91
  320. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/gdp-mod.d.ts +0 -55
  321. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/gdp-mod.js +0 -449
  322. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/git.d.ts +0 -51
  323. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/git.js +0 -311
  324. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/github.d.ts +0 -8
  325. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/github.js +0 -113
  326. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/helpers/domainHelpers.d.ts +0 -1
  327. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/helpers/domainHelpers.js +0 -25
  328. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/helpers/handlePkgJsonScripts.d.ts +0 -1
  329. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/helpers/handlePkgJsonScripts.js +0 -52
  330. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/helpers/promptForDomain.d.ts +0 -4
  331. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/helpers/promptForDomain.js +0 -39
  332. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/utils-git-github.d.ts +0 -8
  333. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/utils-git-github.js +0 -75
  334. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/utils-private-repo.d.ts +0 -12
  335. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/utils-private-repo.js +0 -168
  336. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/utils-repo-exists.d.ts +0 -10
  337. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/utils-repo-exists.js +0 -62
  338. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-api.d.ts +0 -10
  339. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-api.js +0 -36
  340. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-check.d.ts +0 -14
  341. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-check.js +0 -29
  342. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-config.d.ts +0 -27
  343. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-config.js +0 -104
  344. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-create.d.ts +0 -17
  345. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-create.js +0 -129
  346. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-deploy.d.ts +0 -20
  347. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-deploy.js +0 -151
  348. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-domain.d.ts +0 -5
  349. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-domain.js +0 -44
  350. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-env.d.ts +0 -3
  351. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-env.js +0 -58
  352. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-team.d.ts +0 -15
  353. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-team.js +0 -74
  354. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-types.d.ts +0 -28
  355. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-types.js +0 -0
  356. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-utils.d.ts +0 -26
  357. package/bin/impl/init/use-template/cp-modules/git-deploy-prompts/vercel/vercel-utils.js +0 -134
  358. package/bin/impl/inject/inject-impl-mod.d.ts +0 -112
  359. package/bin/impl/inject/inject-impl-mod.js +0 -716
  360. package/bin/impl/invoke/mod.d.ts +0 -59
  361. package/bin/impl/invoke/mod.js +0 -353
  362. package/bin/impl/login/login-impl.d.ts +0 -6
  363. package/bin/impl/login/login-impl.js +0 -179
  364. package/bin/impl/logout/logout-impl.d.ts +0 -1
  365. package/bin/impl/logout/logout-impl.js +0 -20
  366. package/bin/impl/magic/magic-apply.d.ts +0 -88
  367. package/bin/impl/magic/magic-apply.js +0 -669
  368. package/bin/impl/magic/magic-spells.d.ts +0 -46
  369. package/bin/impl/magic/magic-spells.js +0 -144
  370. package/bin/impl/merge/mod.d.ts +0 -8
  371. package/bin/impl/merge/mod.js +0 -160
  372. package/bin/impl/migrate/codemods/anything-bun.d.ts +0 -5
  373. package/bin/impl/migrate/codemods/anything-bun.js +0 -577
  374. package/bin/impl/migrate/codemods/commander-rempts.d.ts +0 -4
  375. package/bin/impl/migrate/codemods/commander-rempts.js +0 -250
  376. package/bin/impl/migrate/codemods/console-relinka.d.ts +0 -3
  377. package/bin/impl/migrate/codemods/console-relinka.js +0 -142
  378. package/bin/impl/migrate/codemods/fs-relifso.d.ts +0 -8
  379. package/bin/impl/migrate/codemods/fs-relifso.js +0 -156
  380. package/bin/impl/migrate/codemods/monorepo-catalog.d.ts +0 -96
  381. package/bin/impl/migrate/codemods/monorepo-catalog.js +0 -517
  382. package/bin/impl/migrate/codemods/nodenext-bundler.d.ts +0 -10
  383. package/bin/impl/migrate/codemods/nodenext-bundler.js +0 -222
  384. package/bin/impl/migrate/codemods/path-pathkit.d.ts +0 -8
  385. package/bin/impl/migrate/codemods/path-pathkit.js +0 -143
  386. package/bin/impl/migrate/codemods/readdir-glob.d.ts +0 -8
  387. package/bin/impl/migrate/codemods/readdir-glob.js +0 -133
  388. package/bin/impl/monorepo/cache-mod.d.ts +0 -29
  389. package/bin/impl/monorepo/cache-mod.js +0 -61
  390. package/bin/impl/monorepo/commands-mod.d.ts +0 -24
  391. package/bin/impl/monorepo/commands-mod.js +0 -159
  392. package/bin/impl/monorepo/graph-mod.d.ts +0 -29
  393. package/bin/impl/monorepo/graph-mod.js +0 -106
  394. package/bin/impl/monorepo/mod.d.ts +0 -5
  395. package/bin/impl/monorepo/mod.js +0 -5
  396. package/bin/impl/monorepo/monorepo-mod.d.ts +0 -26
  397. package/bin/impl/monorepo/monorepo-mod.js +0 -152
  398. package/bin/impl/mrse/mrse-impl.d.ts +0 -53
  399. package/bin/impl/mrse/mrse-impl.js +0 -132
  400. package/bin/impl/pack/mod.d.ts +0 -43
  401. package/bin/impl/pack/mod.js +0 -200
  402. package/bin/impl/providers/better-t-stack/better-t-stack-mod.d.ts +0 -14
  403. package/bin/impl/providers/better-t-stack/better-t-stack-mod.js +0 -35
  404. package/bin/impl/providers/better-t-stack/better-t-stack-types.d.ts +0 -21
  405. package/bin/impl/providers/better-t-stack/better-t-stack-types.js +0 -0
  406. package/bin/impl/providers/better-t-stack/constants.d.ts +0 -61
  407. package/bin/impl/providers/better-t-stack/constants.js +0 -81
  408. package/bin/impl/providers/better-t-stack/helpers/database-providers/mongodb-atlas-setup.d.ts +0 -2
  409. package/bin/impl/providers/better-t-stack/helpers/database-providers/mongodb-atlas-setup.js +0 -133
  410. package/bin/impl/providers/better-t-stack/helpers/database-providers/neon-setup.d.ts +0 -2
  411. package/bin/impl/providers/better-t-stack/helpers/database-providers/neon-setup.js +0 -168
  412. package/bin/impl/providers/better-t-stack/helpers/database-providers/prisma-postgres-setup.d.ts +0 -2
  413. package/bin/impl/providers/better-t-stack/helpers/database-providers/prisma-postgres-setup.js +0 -161
  414. package/bin/impl/providers/better-t-stack/helpers/database-providers/supabase-setup.d.ts +0 -2
  415. package/bin/impl/providers/better-t-stack/helpers/database-providers/supabase-setup.js +0 -162
  416. package/bin/impl/providers/better-t-stack/helpers/database-providers/turso-setup.d.ts +0 -2
  417. package/bin/impl/providers/better-t-stack/helpers/database-providers/turso-setup.js +0 -250
  418. package/bin/impl/providers/better-t-stack/helpers/project-generation/create-project.d.ts +0 -2
  419. package/bin/impl/providers/better-t-stack/helpers/project-generation/create-project.js +0 -82
  420. package/bin/impl/providers/better-t-stack/helpers/project-generation/create-readme.d.ts +0 -2
  421. package/bin/impl/providers/better-t-stack/helpers/project-generation/create-readme.js +0 -245
  422. package/bin/impl/providers/better-t-stack/helpers/project-generation/env-setup.d.ts +0 -8
  423. package/bin/impl/providers/better-t-stack/helpers/project-generation/env-setup.js +0 -193
  424. package/bin/impl/providers/better-t-stack/helpers/project-generation/install-dependencies.d.ts +0 -6
  425. package/bin/impl/providers/better-t-stack/helpers/project-generation/install-dependencies.js +0 -25
  426. package/bin/impl/providers/better-t-stack/helpers/project-generation/post-installation.d.ts +0 -4
  427. package/bin/impl/providers/better-t-stack/helpers/project-generation/post-installation.js +0 -228
  428. package/bin/impl/providers/better-t-stack/helpers/project-generation/project-config.d.ts +0 -3
  429. package/bin/impl/providers/better-t-stack/helpers/project-generation/project-config.js +0 -224
  430. package/bin/impl/providers/better-t-stack/helpers/project-generation/template-manager.d.ts +0 -9
  431. package/bin/impl/providers/better-t-stack/helpers/project-generation/template-manager.js +0 -484
  432. package/bin/impl/providers/better-t-stack/helpers/setup/addons-setup.d.ts +0 -2
  433. package/bin/impl/providers/better-t-stack/helpers/setup/addons-setup.js +0 -99
  434. package/bin/impl/providers/better-t-stack/helpers/setup/api-setup.d.ts +0 -2
  435. package/bin/impl/providers/better-t-stack/helpers/setup/api-setup.js +0 -236
  436. package/bin/impl/providers/better-t-stack/helpers/setup/auth-setup.d.ts +0 -3
  437. package/bin/impl/providers/better-t-stack/helpers/setup/auth-setup.js +0 -67
  438. package/bin/impl/providers/better-t-stack/helpers/setup/backend-setup.d.ts +0 -2
  439. package/bin/impl/providers/better-t-stack/helpers/setup/backend-setup.js +0 -52
  440. package/bin/impl/providers/better-t-stack/helpers/setup/db-setup.d.ts +0 -2
  441. package/bin/impl/providers/better-t-stack/helpers/setup/db-setup.js +0 -84
  442. package/bin/impl/providers/better-t-stack/helpers/setup/examples-setup.d.ts +0 -2
  443. package/bin/impl/providers/better-t-stack/helpers/setup/examples-setup.js +0 -38
  444. package/bin/impl/providers/better-t-stack/helpers/setup/runtime-setup.d.ts +0 -2
  445. package/bin/impl/providers/better-t-stack/helpers/setup/runtime-setup.js +0 -79
  446. package/bin/impl/providers/better-t-stack/helpers/setup/starlight-setup.d.ts +0 -2
  447. package/bin/impl/providers/better-t-stack/helpers/setup/starlight-setup.js +0 -41
  448. package/bin/impl/providers/better-t-stack/helpers/setup/tauri-setup.d.ts +0 -2
  449. package/bin/impl/providers/better-t-stack/helpers/setup/tauri-setup.js +0 -67
  450. package/bin/impl/providers/better-t-stack/packed/addons.d.ts +0 -2
  451. package/bin/impl/providers/better-t-stack/packed/addons.js +0 -263
  452. package/bin/impl/providers/better-t-stack/packed/api.d.ts +0 -2
  453. package/bin/impl/providers/better-t-stack/packed/api.js +0 -678
  454. package/bin/impl/providers/better-t-stack/packed/auth.d.ts +0 -2
  455. package/bin/impl/providers/better-t-stack/packed/auth.js +0 -4277
  456. package/bin/impl/providers/better-t-stack/packed/backend.d.ts +0 -2
  457. package/bin/impl/providers/better-t-stack/packed/backend.js +0 -996
  458. package/bin/impl/providers/better-t-stack/packed/base.d.ts +0 -2
  459. package/bin/impl/providers/better-t-stack/packed/base.js +0 -32
  460. package/bin/impl/providers/better-t-stack/packed/binaries/01dad80fc2.png +0 -0
  461. package/bin/impl/providers/better-t-stack/packed/binaries/0ba5eb8b0a.png +0 -0
  462. package/bin/impl/providers/better-t-stack/packed/binaries/19b53640a9.png +0 -0
  463. package/bin/impl/providers/better-t-stack/packed/binaries/206a875d5d.png +0 -0
  464. package/bin/impl/providers/better-t-stack/packed/binaries/2dc8b34485.png +0 -0
  465. package/bin/impl/providers/better-t-stack/packed/binaries/3f71f5a845.png +0 -0
  466. package/bin/impl/providers/better-t-stack/packed/binaries/6eda863d14.ico +0 -0
  467. package/bin/impl/providers/better-t-stack/packed/binaries/70aadde45a.png +0 -0
  468. package/bin/impl/providers/better-t-stack/packed/binaries/9ecfcc8f0e.ico +0 -0
  469. package/bin/impl/providers/better-t-stack/packed/binaries/9fc7a0c84f.ico +0 -0
  470. package/bin/impl/providers/better-t-stack/packed/binaries/b72f6b7339.png +0 -0
  471. package/bin/impl/providers/better-t-stack/packed/binaries/cb25ca74dd.png +0 -0
  472. package/bin/impl/providers/better-t-stack/packed/binaries/dee83fc2fb.png +0 -0
  473. package/bin/impl/providers/better-t-stack/packed/binaries/eda53e30fe.svg +0 -6
  474. package/bin/impl/providers/better-t-stack/packed/db.d.ts +0 -2
  475. package/bin/impl/providers/better-t-stack/packed/db.js +0 -329
  476. package/bin/impl/providers/better-t-stack/packed/examples.d.ts +0 -2
  477. package/bin/impl/providers/better-t-stack/packed/examples.js +0 -3470
  478. package/bin/impl/providers/better-t-stack/packed/extras.d.ts +0 -2
  479. package/bin/impl/providers/better-t-stack/packed/extras.js +0 -33
  480. package/bin/impl/providers/better-t-stack/packed/frontend.d.ts +0 -2
  481. package/bin/impl/providers/better-t-stack/packed/frontend.js +0 -6116
  482. package/bin/impl/providers/better-t-stack/packed/runtime.d.ts +0 -2
  483. package/bin/impl/providers/better-t-stack/packed/runtime.js +0 -35
  484. package/bin/impl/providers/better-t-stack/prompts/addons.d.ts +0 -2
  485. package/bin/impl/providers/better-t-stack/prompts/addons.js +0 -62
  486. package/bin/impl/providers/better-t-stack/prompts/api.d.ts +0 -2
  487. package/bin/impl/providers/better-t-stack/prompts/api.js +0 -52
  488. package/bin/impl/providers/better-t-stack/prompts/auth.d.ts +0 -2
  489. package/bin/impl/providers/better-t-stack/prompts/auth.js +0 -19
  490. package/bin/impl/providers/better-t-stack/prompts/backend.d.ts +0 -2
  491. package/bin/impl/providers/better-t-stack/prompts/backend.js +0 -60
  492. package/bin/impl/providers/better-t-stack/prompts/config-prompts.d.ts +0 -2
  493. package/bin/impl/providers/better-t-stack/prompts/config-prompts.js +0 -88
  494. package/bin/impl/providers/better-t-stack/prompts/database-setup.d.ts +0 -2
  495. package/bin/impl/providers/better-t-stack/prompts/database-setup.js +0 -67
  496. package/bin/impl/providers/better-t-stack/prompts/database.d.ts +0 -2
  497. package/bin/impl/providers/better-t-stack/prompts/database.js +0 -48
  498. package/bin/impl/providers/better-t-stack/prompts/examples.d.ts +0 -2
  499. package/bin/impl/providers/better-t-stack/prompts/examples.js +0 -44
  500. package/bin/impl/providers/better-t-stack/prompts/frontend.d.ts +0 -2
  501. package/bin/impl/providers/better-t-stack/prompts/frontend.js +0 -107
  502. package/bin/impl/providers/better-t-stack/prompts/git.d.ts +0 -1
  503. package/bin/impl/providers/better-t-stack/prompts/git.js +0 -15
  504. package/bin/impl/providers/better-t-stack/prompts/install.d.ts +0 -1
  505. package/bin/impl/providers/better-t-stack/prompts/install.js +0 -15
  506. package/bin/impl/providers/better-t-stack/prompts/orm.d.ts +0 -2
  507. package/bin/impl/providers/better-t-stack/prompts/orm.js +0 -43
  508. package/bin/impl/providers/better-t-stack/prompts/package-manager.d.ts +0 -2
  509. package/bin/impl/providers/better-t-stack/prompts/package-manager.js +0 -29
  510. package/bin/impl/providers/better-t-stack/prompts/project-name.d.ts +0 -1
  511. package/bin/impl/providers/better-t-stack/prompts/project-name.js +0 -62
  512. package/bin/impl/providers/better-t-stack/prompts/runtime.d.ts +0 -2
  513. package/bin/impl/providers/better-t-stack/prompts/runtime.js +0 -41
  514. package/bin/impl/providers/better-t-stack/types.d.ts +0 -124
  515. package/bin/impl/providers/better-t-stack/types.js +0 -29
  516. package/bin/impl/providers/better-t-stack/utils/add-package-deps.d.ts +0 -6
  517. package/bin/impl/providers/better-t-stack/utils/add-package-deps.js +0 -31
  518. package/bin/impl/providers/better-t-stack/utils/analytics.d.ts +0 -2
  519. package/bin/impl/providers/better-t-stack/utils/analytics.js +0 -32
  520. package/bin/impl/providers/better-t-stack/utils/command-exists.d.ts +0 -1
  521. package/bin/impl/providers/better-t-stack/utils/command-exists.js +0 -14
  522. package/bin/impl/providers/better-t-stack/utils/display-config.d.ts +0 -2
  523. package/bin/impl/providers/better-t-stack/utils/display-config.js +0 -59
  524. package/bin/impl/providers/better-t-stack/utils/generate-reproducible-command.d.ts +0 -2
  525. package/bin/impl/providers/better-t-stack/utils/generate-reproducible-command.js +0 -39
  526. package/bin/impl/providers/better-t-stack/utils/get-latest-cli-version.d.ts +0 -1
  527. package/bin/impl/providers/better-t-stack/utils/get-latest-cli-version.js +0 -8
  528. package/bin/impl/providers/better-t-stack/utils/get-package-execution-command.d.ts +0 -10
  529. package/bin/impl/providers/better-t-stack/utils/get-package-execution-command.js +0 -10
  530. package/bin/impl/providers/better-t-stack/utils/get-package-manager.d.ts +0 -2
  531. package/bin/impl/providers/better-t-stack/utils/get-package-manager.js +0 -10
  532. package/bin/impl/providers/better-t-stack/utils/open-url.d.ts +0 -1
  533. package/bin/impl/providers/better-t-stack/utils/open-url.js +0 -22
  534. package/bin/impl/providers/better-t-stack/utils/render-title.d.ts +0 -2
  535. package/bin/impl/providers/better-t-stack/utils/render-title.js +0 -43
  536. package/bin/impl/providers/better-t-stack/utils/sponsors.d.ts +0 -16
  537. package/bin/impl/providers/better-t-stack/utils/sponsors.js +0 -37
  538. package/bin/impl/providers/better-t-stack/utils/template-processor.d.ts +0 -8
  539. package/bin/impl/providers/better-t-stack/utils/template-processor.js +0 -23
  540. package/bin/impl/providers/better-t-stack/validation.d.ts +0 -4
  541. package/bin/impl/providers/better-t-stack/validation.js +0 -436
  542. package/bin/impl/providers/package.json +0 -3
  543. package/bin/impl/providers/reliverse-stack/reliverse-stack-mod.d.ts +0 -6
  544. package/bin/impl/providers/reliverse-stack/reliverse-stack-mod.js +0 -146
  545. package/bin/impl/providers/reliverse-stack/rs-impl.d.ts +0 -37
  546. package/bin/impl/providers/reliverse-stack/rs-impl.js +0 -367
  547. package/bin/impl/pub/impl.d.ts +0 -8
  548. package/bin/impl/pub/impl.js +0 -87
  549. package/bin/impl/pub/pub-library.d.ts +0 -5
  550. package/bin/impl/pub/pub-library.js +0 -149
  551. package/bin/impl/pub/pub-regular.d.ts +0 -9
  552. package/bin/impl/pub/pub-regular.js +0 -87
  553. package/bin/impl/remdn/mod.d.ts +0 -45
  554. package/bin/impl/remdn/mod.js +0 -648
  555. package/bin/impl/rempts/cmd.d.ts +0 -18
  556. package/bin/impl/rempts/cmd.js +0 -260
  557. package/bin/impl/rules/reliverse/dler-config-health/dler-config-health.d.ts +0 -2
  558. package/bin/impl/rules/reliverse/dler-config-health/dler-config-health.js +0 -37
  559. package/bin/impl/rules/reliverse/file-extensions/file-extensions.d.ts +0 -2
  560. package/bin/impl/rules/reliverse/file-extensions/file-extensions.js +0 -62
  561. package/bin/impl/rules/reliverse/missing-deps/analyzer.d.ts +0 -2
  562. package/bin/impl/rules/reliverse/missing-deps/analyzer.js +0 -49
  563. package/bin/impl/rules/reliverse/missing-deps/deps-mod.d.ts +0 -2
  564. package/bin/impl/rules/reliverse/missing-deps/deps-mod.js +0 -57
  565. package/bin/impl/rules/reliverse/missing-deps/deps-types.d.ts +0 -28
  566. package/bin/impl/rules/reliverse/missing-deps/deps-types.js +0 -0
  567. package/bin/impl/rules/reliverse/missing-deps/filesystem.d.ts +0 -4
  568. package/bin/impl/rules/reliverse/missing-deps/filesystem.js +0 -39
  569. package/bin/impl/rules/reliverse/missing-deps/formatter.d.ts +0 -2
  570. package/bin/impl/rules/reliverse/missing-deps/formatter.js +0 -101
  571. package/bin/impl/rules/reliverse/missing-deps/parser.d.ts +0 -5
  572. package/bin/impl/rules/reliverse/missing-deps/parser.js +0 -57
  573. package/bin/impl/rules/reliverse/no-dynamic-imports/no-dynamic-imports.d.ts +0 -7
  574. package/bin/impl/rules/reliverse/no-dynamic-imports/no-dynamic-imports.js +0 -89
  575. package/bin/impl/rules/reliverse/no-index-files/no-index-files.d.ts +0 -2
  576. package/bin/impl/rules/reliverse/no-index-files/no-index-files.js +0 -31
  577. package/bin/impl/rules/reliverse/package-json-health/package-json-health.d.ts +0 -2
  578. package/bin/impl/rules/reliverse/package-json-health/package-json-health.js +0 -61
  579. package/bin/impl/rules/reliverse/path-extensions/path-extensions.d.ts +0 -2
  580. package/bin/impl/rules/reliverse/path-extensions/path-extensions.js +0 -87
  581. package/bin/impl/rules/reliverse/self-include/self-include.d.ts +0 -2
  582. package/bin/impl/rules/reliverse/self-include/self-include.js +0 -93
  583. package/bin/impl/rules/reliverse/tsconfig-health/tsconfig-health.d.ts +0 -2
  584. package/bin/impl/rules/reliverse/tsconfig-health/tsconfig-health.js +0 -35
  585. package/bin/impl/rules/rules-consts.d.ts +0 -29
  586. package/bin/impl/rules/rules-consts.js +0 -48
  587. package/bin/impl/rules/rules-mod.d.ts +0 -2
  588. package/bin/impl/rules/rules-mod.js +0 -87
  589. package/bin/impl/rules/rules-utils.d.ts +0 -4
  590. package/bin/impl/rules/rules-utils.js +0 -49
  591. package/bin/impl/schema/gen.d.ts +0 -3
  592. package/bin/impl/schema/gen.js +0 -1493
  593. package/bin/impl/schema/mod.d.ts +0 -1329
  594. package/bin/impl/schema/mod.js +0 -344
  595. package/bin/impl/schema/utils.d.ts +0 -17
  596. package/bin/impl/schema/utils.js +0 -86
  597. package/bin/impl/split/impl.d.ts +0 -18
  598. package/bin/impl/split/impl.js +0 -89
  599. package/bin/impl/toolbox/toolbox-impl.d.ts +0 -5
  600. package/bin/impl/toolbox/toolbox-impl.js +0 -78
  601. package/bin/impl/toolbox/toolbox-vercel.d.ts +0 -6
  602. package/bin/impl/toolbox/toolbox-vercel.js +0 -97
  603. package/bin/impl/transform/transform-impl-mod.d.ts +0 -117
  604. package/bin/impl/transform/transform-impl-mod.js +0 -172
  605. package/bin/impl/types/mod.d.ts +0 -634
  606. package/bin/impl/types/mod.js +0 -0
  607. package/bin/impl/update/impl.d.ts +0 -21
  608. package/bin/impl/update/impl.js +0 -142
  609. package/bin/impl/update/utils.d.ts +0 -87
  610. package/bin/impl/update/utils.js +0 -448
  611. package/bin/impl/upload/providers/providers-mod.d.ts +0 -20
  612. package/bin/impl/upload/providers/providers-mod.js +0 -40
  613. package/bin/impl/upload/providers/uploadcare.d.ts +0 -13
  614. package/bin/impl/upload/providers/uploadcare.js +0 -26
  615. package/bin/impl/upload/providers/uploadthing.d.ts +0 -11
  616. package/bin/impl/upload/providers/uploadthing.js +0 -31
  617. package/bin/impl/upload/upload-utils.d.ts +0 -1
  618. package/bin/impl/upload/upload-utils.js +0 -7
  619. package/bin/impl/utils/agg/agg-1.d.ts +0 -1
  620. package/bin/impl/utils/agg/agg-1.js +0 -196
  621. package/bin/impl/utils/agg/agg-2.d.ts +0 -35
  622. package/bin/impl/utils/agg/agg-2.js +0 -148
  623. package/bin/impl/utils/agg/agg-3.d.ts +0 -41
  624. package/bin/impl/utils/agg/agg-3.js +0 -197
  625. package/bin/impl/utils/agg/agg-4.d.ts +0 -8
  626. package/bin/impl/utils/agg/agg-4.js +0 -26
  627. package/bin/impl/utils/agg/agg-5.d.ts +0 -4
  628. package/bin/impl/utils/agg/agg-5.js +0 -10
  629. package/bin/impl/utils/b-exts.d.ts +0 -5
  630. package/bin/impl/utils/b-exts.js +0 -406
  631. package/bin/impl/utils/badgeNotifiers.d.ts +0 -2
  632. package/bin/impl/utils/badgeNotifiers.js +0 -3
  633. package/bin/impl/utils/binary.d.ts +0 -4
  634. package/bin/impl/utils/binary.js +0 -11
  635. package/bin/impl/utils/codemods/convertCjsToEsm.d.ts +0 -1
  636. package/bin/impl/utils/codemods/convertCjsToEsm.js +0 -27
  637. package/bin/impl/utils/codemods/convertDatabase.d.ts +0 -2
  638. package/bin/impl/utils/codemods/convertDatabase.js +0 -229
  639. package/bin/impl/utils/codemods/convertDefinitions.d.ts +0 -1
  640. package/bin/impl/utils/codemods/convertDefinitions.js +0 -42
  641. package/bin/impl/utils/codemods/convertImportStyle.d.ts +0 -1
  642. package/bin/impl/utils/codemods/convertImportStyle.js +0 -30
  643. package/bin/impl/utils/codemods/convertJsToTs.d.ts +0 -1
  644. package/bin/impl/utils/codemods/convertJsToTs.js +0 -99
  645. package/bin/impl/utils/codemods/convertQuoteStyle.d.ts +0 -1
  646. package/bin/impl/utils/codemods/convertQuoteStyle.js +0 -31
  647. package/bin/impl/utils/codemods/convertRuntime.d.ts +0 -1
  648. package/bin/impl/utils/codemods/convertRuntime.js +0 -116
  649. package/bin/impl/utils/codemods/convertToMonorepo.d.ts +0 -2
  650. package/bin/impl/utils/codemods/convertToMonorepo.js +0 -137
  651. package/bin/impl/utils/codemods/removeComments.d.ts +0 -1
  652. package/bin/impl/utils/codemods/removeComments.js +0 -13
  653. package/bin/impl/utils/codemods/removeUnusedDeps.d.ts +0 -1
  654. package/bin/impl/utils/codemods/removeUnusedDeps.js +0 -29
  655. package/bin/impl/utils/codemods/replaceImportSymbol.d.ts +0 -1
  656. package/bin/impl/utils/codemods/replaceImportSymbol.js +0 -57
  657. package/bin/impl/utils/codemods/replaceWithModern.d.ts +0 -1
  658. package/bin/impl/utils/codemods/replaceWithModern.js +0 -122
  659. package/bin/impl/utils/comments.d.ts +0 -6
  660. package/bin/impl/utils/comments.js +0 -41
  661. package/bin/impl/utils/common.d.ts +0 -9
  662. package/bin/impl/utils/common.js +0 -37
  663. package/bin/impl/utils/createPackageJSON.d.ts +0 -6
  664. package/bin/impl/utils/createPackageJSON.js +0 -20
  665. package/bin/impl/utils/decideHelper.d.ts +0 -12
  666. package/bin/impl/utils/decideHelper.js +0 -32
  667. package/bin/impl/utils/dependencies/getUserPkgManager.d.ts +0 -13
  668. package/bin/impl/utils/dependencies/getUserPkgManager.js +0 -178
  669. package/bin/impl/utils/downloading/downloadI18nFiles.d.ts +0 -1
  670. package/bin/impl/utils/downloading/downloadI18nFiles.js +0 -98
  671. package/bin/impl/utils/downloading/downloadRepo.d.ts +0 -41
  672. package/bin/impl/utils/downloading/downloadRepo.js +0 -412
  673. package/bin/impl/utils/downloading/handleDownload.d.ts +0 -17
  674. package/bin/impl/utils/downloading/handleDownload.js +0 -160
  675. package/bin/impl/utils/exec/exec-enoent.d.ts +0 -15
  676. package/bin/impl/utils/exec/exec-enoent.js +0 -38
  677. package/bin/impl/utils/exec/exec-env.d.ts +0 -6
  678. package/bin/impl/utils/exec/exec-env.js +0 -34
  679. package/bin/impl/utils/exec/exec-error.d.ts +0 -7
  680. package/bin/impl/utils/exec/exec-error.js +0 -15
  681. package/bin/impl/utils/exec/exec-escape.d.ts +0 -2
  682. package/bin/impl/utils/exec/exec-escape.js +0 -15
  683. package/bin/impl/utils/exec/exec-mod.d.ts +0 -58
  684. package/bin/impl/utils/exec/exec-mod.js +0 -224
  685. package/bin/impl/utils/exec/exec-parse.d.ts +0 -2
  686. package/bin/impl/utils/exec/exec-parse.js +0 -71
  687. package/bin/impl/utils/exec/exec-resolve.d.ts +0 -2
  688. package/bin/impl/utils/exec/exec-resolve.js +0 -39
  689. package/bin/impl/utils/exec/exec-shebang.d.ts +0 -1
  690. package/bin/impl/utils/exec/exec-shebang.js +0 -14
  691. package/bin/impl/utils/exec/exec-spawn.d.ts +0 -3
  692. package/bin/impl/utils/exec/exec-spawn.js +0 -18
  693. package/bin/impl/utils/exec/exec-stream.d.ts +0 -4
  694. package/bin/impl/utils/exec/exec-stream.js +0 -18
  695. package/bin/impl/utils/exec/exec-types.d.ts +0 -13
  696. package/bin/impl/utils/exec/exec-types.js +0 -9
  697. package/bin/impl/utils/file-type.d.ts +0 -21
  698. package/bin/impl/utils/file-type.js +0 -78
  699. package/bin/impl/utils/finalize.d.ts +0 -10
  700. package/bin/impl/utils/finalize.js +0 -33
  701. package/bin/impl/utils/finish-text.d.ts +0 -6
  702. package/bin/impl/utils/finish-text.js +0 -41
  703. package/bin/impl/utils/fs-rename.d.ts +0 -2
  704. package/bin/impl/utils/fs-rename.js +0 -108
  705. package/bin/impl/utils/getEffectiveDir.d.ts +0 -5
  706. package/bin/impl/utils/getEffectiveDir.js +0 -4
  707. package/bin/impl/utils/getPackageManager.d.ts +0 -3
  708. package/bin/impl/utils/getPackageManager.js +0 -14
  709. package/bin/impl/utils/handlers/dependencies.d.ts +0 -1
  710. package/bin/impl/utils/handlers/dependencies.js +0 -19
  711. package/bin/impl/utils/handlers/handleCleanup.d.ts +0 -1
  712. package/bin/impl/utils/handlers/handleCleanup.js +0 -84
  713. package/bin/impl/utils/handlers/handleCodemods.d.ts +0 -2
  714. package/bin/impl/utils/handlers/handleCodemods.js +0 -203
  715. package/bin/impl/utils/handlers/isAppInstalled.d.ts +0 -1
  716. package/bin/impl/utils/handlers/isAppInstalled.js +0 -17
  717. package/bin/impl/utils/handlers/promptPackageJsonScripts.d.ts +0 -8
  718. package/bin/impl/utils/handlers/promptPackageJsonScripts.js +0 -130
  719. package/bin/impl/utils/handlers/shadcn.d.ts +0 -19
  720. package/bin/impl/utils/handlers/shadcn.js +0 -299
  721. package/bin/impl/utils/hasOnlyReliverseConfig.d.ts +0 -6
  722. package/bin/impl/utils/hasOnlyReliverseConfig.js +0 -15
  723. package/bin/impl/utils/init/init-const.d.ts +0 -34
  724. package/bin/impl/utils/init/init-const.js +0 -17
  725. package/bin/impl/utils/init/init-impl.d.ts +0 -22
  726. package/bin/impl/utils/init/init-impl.js +0 -229
  727. package/bin/impl/utils/init/init-tmpl.d.ts +0 -3
  728. package/bin/impl/utils/init/init-tmpl.js +0 -68
  729. package/bin/impl/utils/init/init-types.d.ts +0 -41
  730. package/bin/impl/utils/init/init-types.js +0 -0
  731. package/bin/impl/utils/instanceGithub.d.ts +0 -28
  732. package/bin/impl/utils/instanceGithub.js +0 -50
  733. package/bin/impl/utils/instanceVercel.d.ts +0 -16
  734. package/bin/impl/utils/instanceVercel.js +0 -39
  735. package/bin/impl/utils/microHelpers.d.ts +0 -11
  736. package/bin/impl/utils/microHelpers.js +0 -8
  737. package/bin/impl/utils/mrseHelpers.d.ts +0 -6
  738. package/bin/impl/utils/mrseHelpers.js +0 -21
  739. package/bin/impl/utils/pkgJsonHelpers.d.ts +0 -7
  740. package/bin/impl/utils/pkgJsonHelpers.js +0 -15
  741. package/bin/impl/utils/pm/pm-api.d.ts +0 -87
  742. package/bin/impl/utils/pm/pm-api.js +0 -170
  743. package/bin/impl/utils/pm/pm-catalog.d.ts +0 -36
  744. package/bin/impl/utils/pm/pm-catalog.js +0 -237
  745. package/bin/impl/utils/pm/pm-detect.d.ts +0 -12
  746. package/bin/impl/utils/pm/pm-detect.js +0 -99
  747. package/bin/impl/utils/pm/pm-meta.d.ts +0 -27
  748. package/bin/impl/utils/pm/pm-meta.js +0 -86
  749. package/bin/impl/utils/pm/pm-parse.d.ts +0 -8
  750. package/bin/impl/utils/pm/pm-parse.js +0 -29
  751. package/bin/impl/utils/pm/pm-types.d.ts +0 -46
  752. package/bin/impl/utils/pm/pm-types.js +0 -0
  753. package/bin/impl/utils/pm/pm-utils.d.ts +0 -12
  754. package/bin/impl/utils/pm/pm-utils.js +0 -115
  755. package/bin/impl/utils/projectRepository.d.ts +0 -58
  756. package/bin/impl/utils/projectRepository.js +0 -228
  757. package/bin/impl/utils/prompts/askAppOrLib.d.ts +0 -1
  758. package/bin/impl/utils/prompts/askAppOrLib.js +0 -30
  759. package/bin/impl/utils/prompts/askInstallDeps.d.ts +0 -7
  760. package/bin/impl/utils/prompts/askInstallDeps.js +0 -40
  761. package/bin/impl/utils/prompts/askOpenInIDE.d.ts +0 -5
  762. package/bin/impl/utils/prompts/askOpenInIDE.js +0 -43
  763. package/bin/impl/utils/prompts/askProjectName.d.ts +0 -3
  764. package/bin/impl/utils/prompts/askProjectName.js +0 -21
  765. package/bin/impl/utils/prompts/askUsernameFrontend.d.ts +0 -2
  766. package/bin/impl/utils/prompts/askUsernameFrontend.js +0 -28
  767. package/bin/impl/utils/prompts/askUsernameGithub.d.ts +0 -2
  768. package/bin/impl/utils/prompts/askUsernameGithub.js +0 -29
  769. package/bin/impl/utils/prompts/shouldInitGit.d.ts +0 -1
  770. package/bin/impl/utils/prompts/shouldInitGit.js +0 -8
  771. package/bin/impl/utils/reliverseMemory.d.ts +0 -3
  772. package/bin/impl/utils/reliverseMemory.js +0 -122
  773. package/bin/impl/utils/replacements/reps-impl.d.ts +0 -35
  774. package/bin/impl/utils/replacements/reps-impl.js +0 -220
  775. package/bin/impl/utils/replacements/reps-keys.d.ts +0 -16
  776. package/bin/impl/utils/replacements/reps-keys.js +0 -14
  777. package/bin/impl/utils/replacements/reps-mod.d.ts +0 -5
  778. package/bin/impl/utils/replacements/reps-mod.js +0 -211
  779. package/bin/impl/utils/replacements.d.ts +0 -0
  780. package/bin/impl/utils/replacements.js +0 -0
  781. package/bin/impl/utils/resolve-cross-libs.d.ts +0 -1
  782. package/bin/impl/utils/resolve-cross-libs.js +0 -641
  783. package/bin/impl/utils/schemaMemory.d.ts +0 -17
  784. package/bin/impl/utils/schemaMemory.js +0 -0
  785. package/bin/impl/utils/schemaTemplate.d.ts +0 -27
  786. package/bin/impl/utils/schemaTemplate.js +0 -98
  787. package/bin/impl/utils/startEndPrompts.d.ts +0 -8
  788. package/bin/impl/utils/startEndPrompts.js +0 -53
  789. package/bin/impl/utils/terminalHelpers.d.ts +0 -19
  790. package/bin/impl/utils/terminalHelpers.js +0 -43
  791. package/bin/impl/utils/testsRuntime.d.ts +0 -5
  792. package/bin/impl/utils/testsRuntime.js +0 -11
  793. package/bin/impl/utils/tsconfigHelpers.d.ts +0 -5
  794. package/bin/impl/utils/tsconfigHelpers.js +0 -14
  795. package/bin/impl/utils/utils-build.d.ts +0 -33
  796. package/bin/impl/utils/utils-build.js +0 -97
  797. package/bin/impl/utils/utils-clean.d.ts +0 -11
  798. package/bin/impl/utils/utils-clean.js +0 -70
  799. package/bin/impl/utils/utils-deps.d.ts +0 -5
  800. package/bin/impl/utils/utils-deps.js +0 -126
  801. package/bin/impl/utils/utils-determine.d.ts +0 -12
  802. package/bin/impl/utils/utils-determine.js +0 -25
  803. package/bin/impl/utils/utils-error-cwd.d.ts +0 -19
  804. package/bin/impl/utils/utils-error-cwd.js +0 -49
  805. package/bin/impl/utils/utils-fs.d.ts +0 -25
  806. package/bin/impl/utils/utils-fs.js +0 -183
  807. package/bin/impl/utils/utils-jsr-json.d.ts +0 -9
  808. package/bin/impl/utils/utils-jsr-json.js +0 -75
  809. package/bin/impl/utils/utils-misc.d.ts +0 -7
  810. package/bin/impl/utils/utils-misc.js +0 -7
  811. package/bin/impl/utils/utils-package-json-libraries.d.ts +0 -10
  812. package/bin/impl/utils/utils-package-json-libraries.js +0 -316
  813. package/bin/impl/utils/utils-package-json-regular.d.ts +0 -8
  814. package/bin/impl/utils/utils-package-json-regular.js +0 -165
  815. package/bin/impl/utils/utils-perf.d.ts +0 -5
  816. package/bin/impl/utils/utils-perf.js +0 -22
  817. package/bin/impl/utils/utils-security.d.ts +0 -12
  818. package/bin/impl/utils/utils-security.js +0 -95
  819. package/bin/impl/utils/utils-tsconfig.d.ts +0 -10
  820. package/bin/impl/utils/utils-tsconfig.js +0 -81
  821. package/bin/mod.d.ts +0 -437
  822. package/bin/mod.js +0 -1039
@@ -1,3470 +0,0 @@
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/impl/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/impl/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/impl/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
- };