create-mantiq 0.4.0 → 0.5.1

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 (346) hide show
  1. package/package.json +2 -1
  2. package/src/index.ts +44 -18
  3. package/src/templates.ts +23 -335
  4. package/src/ui/shadcn.ts +450 -192
  5. package/stubs/manifest.json +1415 -0
  6. package/stubs/react/components.json.stub +19 -0
  7. package/stubs/react/src/App.tsx.stub +64 -0
  8. package/stubs/react/src/components/data-table.tsx.stub +548 -0
  9. package/stubs/react/src/components/layout/app-sidebar.tsx.stub +74 -0
  10. package/stubs/react/src/components/layout/authenticated-layout.tsx.stub +42 -0
  11. package/stubs/react/src/components/layout/header.tsx.stub +88 -0
  12. package/stubs/react/src/components/layout/index.ts.stub +10 -0
  13. package/stubs/react/src/components/layout/main.tsx.stub +22 -0
  14. package/stubs/react/src/components/layout/nav-group.tsx.stub +193 -0
  15. package/stubs/react/src/components/layout/nav-user.tsx.stub +111 -0
  16. package/stubs/react/src/components/layout/search-dialog.tsx.stub +121 -0
  17. package/stubs/react/src/components/layout/sidebar-data.ts.stub +57 -0
  18. package/stubs/react/src/components/layout/theme-toggle.tsx.stub +43 -0
  19. package/stubs/react/src/components/layout/top-nav.tsx.stub +94 -0
  20. package/stubs/react/src/components/ui/avatar.tsx.stub +107 -0
  21. package/stubs/react/src/components/ui/badge.tsx.stub +48 -0
  22. package/stubs/react/src/components/ui/button.tsx.stub +64 -0
  23. package/stubs/react/src/components/ui/card.tsx.stub +92 -0
  24. package/stubs/react/src/components/ui/dialog.tsx.stub +156 -0
  25. package/stubs/react/src/components/ui/dropdown-menu.tsx.stub +255 -0
  26. package/stubs/react/src/components/ui/input.tsx.stub +21 -0
  27. package/stubs/react/src/components/ui/label.tsx.stub +22 -0
  28. package/stubs/react/src/components/ui/separator.tsx.stub +28 -0
  29. package/stubs/react/src/components/ui/sheet.tsx.stub +143 -0
  30. package/stubs/react/src/components/ui/sidebar.tsx.stub +726 -0
  31. package/stubs/react/src/components/ui/skeleton.tsx.stub +13 -0
  32. package/stubs/react/src/components/ui/table.tsx.stub +116 -0
  33. package/stubs/react/src/components/ui/tabs.tsx.stub +69 -0
  34. package/stubs/react/src/components/ui/tooltip.tsx.stub +55 -0
  35. package/stubs/react/src/hooks/use-mobile.ts.stub +19 -0
  36. package/stubs/react/src/lib/api.ts.stub +17 -0
  37. package/stubs/react/src/lib/utils.ts.stub +6 -0
  38. package/stubs/react/src/main.tsx.stub +10 -0
  39. package/stubs/react/src/pages/Dashboard.tsx.stub +283 -0
  40. package/stubs/react/src/pages/Login.tsx.stub +119 -0
  41. package/stubs/react/src/pages/Register.tsx.stub +133 -0
  42. package/stubs/react/src/pages/Users.tsx.stub +411 -0
  43. package/stubs/react/src/pages/account/layout.tsx.stub +59 -0
  44. package/stubs/react/src/pages/account/preferences.tsx.stub +80 -0
  45. package/stubs/react/src/pages/account/profile.tsx.stub +65 -0
  46. package/stubs/react/src/pages/account/security.tsx.stub +105 -0
  47. package/stubs/react/src/pages/users/dialogs.tsx.stub +309 -0
  48. package/stubs/react/src/pages.ts.stub +17 -0
  49. package/stubs/react/src/ssr.tsx.stub +7 -0
  50. package/stubs/react/src/style.css.stub +138 -0
  51. package/stubs/react/tsconfig.json.stub +36 -0
  52. package/stubs/react/vite.config.ts.stub +22 -0
  53. package/stubs/shared/app/Http/Controllers/AuthController.ts.stub +67 -0
  54. package/stubs/shared/app/Http/Controllers/HomeController.ts.stub +62 -0
  55. package/stubs/shared/app/Http/Controllers/PageController.ts.stub +66 -0
  56. package/stubs/shared/database/factories/UserFactory.ts.stub +16 -0
  57. package/stubs/shared/database/seeders/DatabaseSeeder.ts.stub +42 -0
  58. package/stubs/shared/routes/api.ts.stub +106 -0
  59. package/stubs/shared/routes/web.ts.stub +23 -0
  60. package/stubs/svelte/components.json.stub +15 -0
  61. package/stubs/svelte/src/App.svelte.stub +77 -0
  62. package/stubs/svelte/src/lib/api.ts.stub +17 -0
  63. package/stubs/svelte/src/lib/components/DataTable.svelte.stub +399 -0
  64. package/stubs/svelte/src/lib/components/layout/AppSidebar.svelte.stub +62 -0
  65. package/stubs/svelte/src/lib/components/layout/AuthenticatedLayout.svelte.stub +40 -0
  66. package/stubs/svelte/src/lib/components/layout/Header.svelte.stub +98 -0
  67. package/stubs/svelte/src/lib/components/layout/Main.svelte.stub +26 -0
  68. package/stubs/svelte/src/lib/components/layout/NavGroup.svelte.stub +142 -0
  69. package/stubs/svelte/src/lib/components/layout/NavUser.svelte.stub +100 -0
  70. package/stubs/svelte/src/lib/components/layout/SearchDialog.svelte.stub +124 -0
  71. package/stubs/svelte/src/lib/components/layout/ThemeToggle.svelte.stub +30 -0
  72. package/stubs/svelte/src/lib/components/layout/TopNav.svelte.stub +81 -0
  73. package/stubs/svelte/src/lib/components/layout/sidebar-data.ts.stub +57 -0
  74. package/stubs/svelte/src/lib/components/ui/avatar/avatar-badge.svelte.stub +26 -0
  75. package/stubs/svelte/src/lib/components/ui/avatar/avatar-fallback.svelte.stub +20 -0
  76. package/stubs/svelte/src/lib/components/ui/avatar/avatar-group-count.svelte.stub +23 -0
  77. package/stubs/svelte/src/lib/components/ui/avatar/avatar-group.svelte.stub +23 -0
  78. package/stubs/svelte/src/lib/components/ui/avatar/avatar-image.svelte.stub +17 -0
  79. package/stubs/svelte/src/lib/components/ui/avatar/avatar.svelte.stub +26 -0
  80. package/stubs/svelte/src/lib/components/ui/avatar/index.ts.stub +22 -0
  81. package/stubs/svelte/src/lib/components/ui/badge/badge.svelte.stub +49 -0
  82. package/stubs/svelte/src/lib/components/ui/badge/index.ts.stub +2 -0
  83. package/stubs/svelte/src/lib/components/ui/button/button.svelte.stub +82 -0
  84. package/stubs/svelte/src/lib/components/ui/button/index.ts.stub +17 -0
  85. package/stubs/svelte/src/lib/components/ui/card/card-action.svelte.stub +23 -0
  86. package/stubs/svelte/src/lib/components/ui/card/card-content.svelte.stub +20 -0
  87. package/stubs/svelte/src/lib/components/ui/card/card-description.svelte.stub +20 -0
  88. package/stubs/svelte/src/lib/components/ui/card/card-footer.svelte.stub +20 -0
  89. package/stubs/svelte/src/lib/components/ui/card/card-header.svelte.stub +23 -0
  90. package/stubs/svelte/src/lib/components/ui/card/card-title.svelte.stub +15 -0
  91. package/stubs/svelte/src/lib/components/ui/card/card.svelte.stub +22 -0
  92. package/stubs/svelte/src/lib/components/ui/card/index.ts.stub +25 -0
  93. package/stubs/svelte/src/lib/components/ui/dialog/dialog-close.svelte.stub +11 -0
  94. package/stubs/svelte/src/lib/components/ui/dialog/dialog-content.svelte.stub +48 -0
  95. package/stubs/svelte/src/lib/components/ui/dialog/dialog-description.svelte.stub +17 -0
  96. package/stubs/svelte/src/lib/components/ui/dialog/dialog-footer.svelte.stub +32 -0
  97. package/stubs/svelte/src/lib/components/ui/dialog/dialog-header.svelte.stub +20 -0
  98. package/stubs/svelte/src/lib/components/ui/dialog/dialog-overlay.svelte.stub +17 -0
  99. package/stubs/svelte/src/lib/components/ui/dialog/dialog-portal.svelte.stub +7 -0
  100. package/stubs/svelte/src/lib/components/ui/dialog/dialog-title.svelte.stub +17 -0
  101. package/stubs/svelte/src/lib/components/ui/dialog/dialog-trigger.svelte.stub +11 -0
  102. package/stubs/svelte/src/lib/components/ui/dialog/dialog.svelte.stub +7 -0
  103. package/stubs/svelte/src/lib/components/ui/dialog/index.ts.stub +34 -0
  104. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-group.svelte.stub +16 -0
  105. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.stub +44 -0
  106. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-content.svelte.stub +31 -0
  107. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte.stub +22 -0
  108. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-group.svelte.stub +7 -0
  109. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-item.svelte.stub +27 -0
  110. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-label.svelte.stub +24 -0
  111. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-portal.svelte.stub +7 -0
  112. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.stub +16 -0
  113. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte.stub +34 -0
  114. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-separator.svelte.stub +17 -0
  115. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte.stub +20 -0
  116. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte.stub +17 -0
  117. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte.stub +29 -0
  118. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-sub.svelte.stub +7 -0
  119. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.stub +7 -0
  120. package/stubs/svelte/src/lib/components/ui/dropdown-menu/dropdown-menu.svelte.stub +7 -0
  121. package/stubs/svelte/src/lib/components/ui/dropdown-menu/index.ts.stub +54 -0
  122. package/stubs/svelte/src/lib/components/ui/input/index.ts.stub +7 -0
  123. package/stubs/svelte/src/lib/components/ui/input/input.svelte.stub +48 -0
  124. package/stubs/svelte/src/lib/components/ui/label/index.ts.stub +7 -0
  125. package/stubs/svelte/src/lib/components/ui/label/label.svelte.stub +20 -0
  126. package/stubs/svelte/src/lib/components/ui/separator/index.ts.stub +7 -0
  127. package/stubs/svelte/src/lib/components/ui/separator/separator.svelte.stub +23 -0
  128. package/stubs/svelte/src/lib/components/ui/sheet/index.ts.stub +34 -0
  129. package/stubs/svelte/src/lib/components/ui/sheet/sheet-close.svelte.stub +7 -0
  130. package/stubs/svelte/src/lib/components/ui/sheet/sheet-content.svelte.stub +55 -0
  131. package/stubs/svelte/src/lib/components/ui/sheet/sheet-description.svelte.stub +17 -0
  132. package/stubs/svelte/src/lib/components/ui/sheet/sheet-footer.svelte.stub +20 -0
  133. package/stubs/svelte/src/lib/components/ui/sheet/sheet-header.svelte.stub +20 -0
  134. package/stubs/svelte/src/lib/components/ui/sheet/sheet-overlay.svelte.stub +17 -0
  135. package/stubs/svelte/src/lib/components/ui/sheet/sheet-portal.svelte.stub +7 -0
  136. package/stubs/svelte/src/lib/components/ui/sheet/sheet-title.svelte.stub +17 -0
  137. package/stubs/svelte/src/lib/components/ui/sheet/sheet-trigger.svelte.stub +7 -0
  138. package/stubs/svelte/src/lib/components/ui/sheet/sheet.svelte.stub +7 -0
  139. package/stubs/svelte/src/lib/components/ui/sidebar/constants.ts.stub +6 -0
  140. package/stubs/svelte/src/lib/components/ui/sidebar/context.svelte.ts.stub +81 -0
  141. package/stubs/svelte/src/lib/components/ui/sidebar/index.ts.stub +75 -0
  142. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-content.svelte.stub +24 -0
  143. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-footer.svelte.stub +21 -0
  144. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-group-action.svelte.stub +33 -0
  145. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-group-content.svelte.stub +21 -0
  146. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-group-label.svelte.stub +33 -0
  147. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-group.svelte.stub +21 -0
  148. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-header.svelte.stub +21 -0
  149. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-input.svelte.stub +21 -0
  150. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-inset.svelte.stub +20 -0
  151. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu-action.svelte.stub +37 -0
  152. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu-badge.svelte.stub +24 -0
  153. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu-button.svelte.stub +102 -0
  154. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu-item.svelte.stub +21 -0
  155. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu-skeleton.svelte.stub +36 -0
  156. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-button.svelte.stub +39 -0
  157. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu-sub-item.svelte.stub +21 -0
  158. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu-sub.svelte.stub +21 -0
  159. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-menu.svelte.stub +21 -0
  160. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-provider.svelte.stub +53 -0
  161. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-rail.svelte.stub +36 -0
  162. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-separator.svelte.stub +19 -0
  163. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar-trigger.svelte.stub +36 -0
  164. package/stubs/svelte/src/lib/components/ui/sidebar/sidebar.svelte.stub +108 -0
  165. package/stubs/svelte/src/lib/components/ui/skeleton/index.ts.stub +7 -0
  166. package/stubs/svelte/src/lib/components/ui/skeleton/skeleton.svelte.stub +17 -0
  167. package/stubs/svelte/src/lib/components/ui/table/index.ts.stub +28 -0
  168. package/stubs/svelte/src/lib/components/ui/table/table-body.svelte.stub +15 -0
  169. package/stubs/svelte/src/lib/components/ui/table/table-caption.svelte.stub +20 -0
  170. package/stubs/svelte/src/lib/components/ui/table/table-cell.svelte.stub +15 -0
  171. package/stubs/svelte/src/lib/components/ui/table/table-footer.svelte.stub +20 -0
  172. package/stubs/svelte/src/lib/components/ui/table/table-head.svelte.stub +15 -0
  173. package/stubs/svelte/src/lib/components/ui/table/table-header.svelte.stub +20 -0
  174. package/stubs/svelte/src/lib/components/ui/table/table-row.svelte.stub +15 -0
  175. package/stubs/svelte/src/lib/components/ui/table/table.svelte.stub +17 -0
  176. package/stubs/svelte/src/lib/components/ui/tabs/index.ts.stub +18 -0
  177. package/stubs/svelte/src/lib/components/ui/tabs/tabs-content.svelte.stub +17 -0
  178. package/stubs/svelte/src/lib/components/ui/tabs/tabs-list.svelte.stub +40 -0
  179. package/stubs/svelte/src/lib/components/ui/tabs/tabs-trigger.svelte.stub +23 -0
  180. package/stubs/svelte/src/lib/components/ui/tabs/tabs.svelte.stub +19 -0
  181. package/stubs/svelte/src/lib/components/ui/tooltip/index.ts.stub +19 -0
  182. package/stubs/svelte/src/lib/components/ui/tooltip/tooltip-content.svelte.stub +52 -0
  183. package/stubs/svelte/src/lib/components/ui/tooltip/tooltip-portal.svelte.stub +7 -0
  184. package/stubs/svelte/src/lib/components/ui/tooltip/tooltip-provider.svelte.stub +7 -0
  185. package/stubs/svelte/src/lib/components/ui/tooltip/tooltip-trigger.svelte.stub +7 -0
  186. package/stubs/svelte/src/lib/components/ui/tooltip/tooltip.svelte.stub +10 -0
  187. package/stubs/svelte/src/lib/hooks/is-mobile.svelte.ts.stub +9 -0
  188. package/stubs/svelte/src/lib/utils.ts.stub +6 -0
  189. package/stubs/svelte/src/main.ts.stub +12 -0
  190. package/stubs/svelte/src/pages/Dashboard.svelte.stub +201 -0
  191. package/stubs/svelte/src/pages/Login.svelte.stub +117 -0
  192. package/stubs/svelte/src/pages/Register.svelte.stub +130 -0
  193. package/stubs/svelte/src/pages/Users.svelte.stub +347 -0
  194. package/stubs/svelte/src/pages/account/layout.svelte.stub +62 -0
  195. package/stubs/svelte/src/pages/account/preferences.svelte.stub +79 -0
  196. package/stubs/svelte/src/pages/account/profile.svelte.stub +66 -0
  197. package/stubs/svelte/src/pages/account/security.svelte.stub +110 -0
  198. package/stubs/svelte/src/pages/users/AddUserDialog.svelte.stub +103 -0
  199. package/stubs/svelte/src/pages/users/DeleteUserDialog.svelte.stub +78 -0
  200. package/stubs/svelte/src/pages/users/EditUserDialog.svelte.stub +104 -0
  201. package/stubs/svelte/src/pages.ts.stub +17 -0
  202. package/stubs/svelte/src/ssr.ts.stub +10 -0
  203. package/stubs/svelte/src/style.css.stub +127 -0
  204. package/stubs/svelte/svelte.config.js.stub +5 -0
  205. package/stubs/svelte/tsconfig.json.stub +25 -0
  206. package/stubs/svelte/vite.config.ts.stub +23 -0
  207. package/stubs/vue/components.json.stub +21 -0
  208. package/stubs/vue/src/App.vue.stub +73 -0
  209. package/stubs/vue/src/components/DataTable.vue.stub +68 -0
  210. package/stubs/vue/src/components/layout/AppSidebar.vue.stub +68 -0
  211. package/stubs/vue/src/components/layout/AuthenticatedLayout.vue.stub +36 -0
  212. package/stubs/vue/src/components/layout/Header.vue.stub +89 -0
  213. package/stubs/vue/src/components/layout/Main.vue.stub +22 -0
  214. package/stubs/vue/src/components/layout/NavGroup.vue.stub +152 -0
  215. package/stubs/vue/src/components/layout/NavUser.vue.stub +113 -0
  216. package/stubs/vue/src/components/layout/SearchDialog.vue.stub +121 -0
  217. package/stubs/vue/src/components/layout/ThemeToggle.vue.stub +40 -0
  218. package/stubs/vue/src/components/layout/TopNav.vue.stub +77 -0
  219. package/stubs/vue/src/components/layout/index.ts.stub +9 -0
  220. package/stubs/vue/src/components/layout/sidebar-data.ts.stub +57 -0
  221. package/stubs/vue/src/components/ui/avatar/Avatar.vue.stub +18 -0
  222. package/stubs/vue/src/components/ui/avatar/AvatarFallback.vue.stub +21 -0
  223. package/stubs/vue/src/components/ui/avatar/AvatarImage.vue.stub +16 -0
  224. package/stubs/vue/src/components/ui/avatar/index.ts.stub +3 -0
  225. package/stubs/vue/src/components/ui/badge/Badge.vue.stub +26 -0
  226. package/stubs/vue/src/components/ui/badge/index.ts.stub +26 -0
  227. package/stubs/vue/src/components/ui/button/Button.vue.stub +31 -0
  228. package/stubs/vue/src/components/ui/button/index.ts.stub +38 -0
  229. package/stubs/vue/src/components/ui/card/Card.vue.stub +22 -0
  230. package/stubs/vue/src/components/ui/card/CardAction.vue.stub +17 -0
  231. package/stubs/vue/src/components/ui/card/CardContent.vue.stub +17 -0
  232. package/stubs/vue/src/components/ui/card/CardDescription.vue.stub +17 -0
  233. package/stubs/vue/src/components/ui/card/CardFooter.vue.stub +17 -0
  234. package/stubs/vue/src/components/ui/card/CardHeader.vue.stub +17 -0
  235. package/stubs/vue/src/components/ui/card/CardTitle.vue.stub +17 -0
  236. package/stubs/vue/src/components/ui/card/index.ts.stub +7 -0
  237. package/stubs/vue/src/components/ui/dialog/Dialog.vue.stub +19 -0
  238. package/stubs/vue/src/components/ui/dialog/DialogClose.vue.stub +15 -0
  239. package/stubs/vue/src/components/ui/dialog/DialogContent.vue.stub +53 -0
  240. package/stubs/vue/src/components/ui/dialog/DialogDescription.vue.stub +23 -0
  241. package/stubs/vue/src/components/ui/dialog/DialogFooter.vue.stub +27 -0
  242. package/stubs/vue/src/components/ui/dialog/DialogHeader.vue.stub +17 -0
  243. package/stubs/vue/src/components/ui/dialog/DialogOverlay.vue.stub +21 -0
  244. package/stubs/vue/src/components/ui/dialog/DialogScrollContent.vue.stub +59 -0
  245. package/stubs/vue/src/components/ui/dialog/DialogTitle.vue.stub +23 -0
  246. package/stubs/vue/src/components/ui/dialog/DialogTrigger.vue.stub +15 -0
  247. package/stubs/vue/src/components/ui/dialog/index.ts.stub +10 -0
  248. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenu.vue.stub +19 -0
  249. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuCheckboxItem.vue.stub +39 -0
  250. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuContent.vue.stub +39 -0
  251. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuGroup.vue.stub +15 -0
  252. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuItem.vue.stub +31 -0
  253. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuLabel.vue.stub +23 -0
  254. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuRadioGroup.vue.stub +21 -0
  255. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuRadioItem.vue.stub +40 -0
  256. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuSeparator.vue.stub +23 -0
  257. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuShortcut.vue.stub +17 -0
  258. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuSub.vue.stub +18 -0
  259. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuSubContent.vue.stub +27 -0
  260. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuSubTrigger.vue.stub +31 -0
  261. package/stubs/vue/src/components/ui/dropdown-menu/DropdownMenuTrigger.vue.stub +17 -0
  262. package/stubs/vue/src/components/ui/dropdown-menu/index.ts.stub +16 -0
  263. package/stubs/vue/src/components/ui/input/Input.vue.stub +33 -0
  264. package/stubs/vue/src/components/ui/input/index.ts.stub +1 -0
  265. package/stubs/vue/src/components/ui/label/Label.vue.stub +26 -0
  266. package/stubs/vue/src/components/ui/label/index.ts.stub +1 -0
  267. package/stubs/vue/src/components/ui/separator/Separator.vue.stub +29 -0
  268. package/stubs/vue/src/components/ui/separator/index.ts.stub +1 -0
  269. package/stubs/vue/src/components/ui/sheet/Sheet.vue.stub +19 -0
  270. package/stubs/vue/src/components/ui/sheet/SheetClose.vue.stub +15 -0
  271. package/stubs/vue/src/components/ui/sheet/SheetContent.vue.stub +62 -0
  272. package/stubs/vue/src/components/ui/sheet/SheetDescription.vue.stub +21 -0
  273. package/stubs/vue/src/components/ui/sheet/SheetFooter.vue.stub +16 -0
  274. package/stubs/vue/src/components/ui/sheet/SheetHeader.vue.stub +15 -0
  275. package/stubs/vue/src/components/ui/sheet/SheetOverlay.vue.stub +21 -0
  276. package/stubs/vue/src/components/ui/sheet/SheetTitle.vue.stub +21 -0
  277. package/stubs/vue/src/components/ui/sheet/SheetTrigger.vue.stub +15 -0
  278. package/stubs/vue/src/components/ui/sheet/index.ts.stub +8 -0
  279. package/stubs/vue/src/components/ui/sidebar/Sidebar.vue.stub +96 -0
  280. package/stubs/vue/src/components/ui/sidebar/SidebarContent.vue.stub +18 -0
  281. package/stubs/vue/src/components/ui/sidebar/SidebarFooter.vue.stub +18 -0
  282. package/stubs/vue/src/components/ui/sidebar/SidebarGroup.vue.stub +18 -0
  283. package/stubs/vue/src/components/ui/sidebar/SidebarGroupAction.vue.stub +27 -0
  284. package/stubs/vue/src/components/ui/sidebar/SidebarGroupContent.vue.stub +18 -0
  285. package/stubs/vue/src/components/ui/sidebar/SidebarGroupLabel.vue.stub +25 -0
  286. package/stubs/vue/src/components/ui/sidebar/SidebarHeader.vue.stub +18 -0
  287. package/stubs/vue/src/components/ui/sidebar/SidebarInput.vue.stub +22 -0
  288. package/stubs/vue/src/components/ui/sidebar/SidebarInset.vue.stub +21 -0
  289. package/stubs/vue/src/components/ui/sidebar/SidebarMenu.vue.stub +18 -0
  290. package/stubs/vue/src/components/ui/sidebar/SidebarMenuAction.vue.stub +35 -0
  291. package/stubs/vue/src/components/ui/sidebar/SidebarMenuBadge.vue.stub +26 -0
  292. package/stubs/vue/src/components/ui/sidebar/SidebarMenuButton.vue.stub +48 -0
  293. package/stubs/vue/src/components/ui/sidebar/SidebarMenuButtonChild.vue.stub +36 -0
  294. package/stubs/vue/src/components/ui/sidebar/SidebarMenuItem.vue.stub +18 -0
  295. package/stubs/vue/src/components/ui/sidebar/SidebarMenuSkeleton.vue.stub +35 -0
  296. package/stubs/vue/src/components/ui/sidebar/SidebarMenuSub.vue.stub +22 -0
  297. package/stubs/vue/src/components/ui/sidebar/SidebarMenuSubButton.vue.stub +36 -0
  298. package/stubs/vue/src/components/ui/sidebar/SidebarMenuSubItem.vue.stub +18 -0
  299. package/stubs/vue/src/components/ui/sidebar/SidebarProvider.vue.stub +82 -0
  300. package/stubs/vue/src/components/ui/sidebar/SidebarRail.vue.stub +33 -0
  301. package/stubs/vue/src/components/ui/sidebar/SidebarSeparator.vue.stub +19 -0
  302. package/stubs/vue/src/components/ui/sidebar/SidebarTrigger.vue.stub +27 -0
  303. package/stubs/vue/src/components/ui/sidebar/index.ts.stub +60 -0
  304. package/stubs/vue/src/components/ui/sidebar/utils.ts.stub +19 -0
  305. package/stubs/vue/src/components/ui/skeleton/Skeleton.vue.stub +17 -0
  306. package/stubs/vue/src/components/ui/skeleton/index.ts.stub +1 -0
  307. package/stubs/vue/src/components/ui/table/Table.vue.stub +16 -0
  308. package/stubs/vue/src/components/ui/table/TableBody.vue.stub +17 -0
  309. package/stubs/vue/src/components/ui/table/TableCaption.vue.stub +17 -0
  310. package/stubs/vue/src/components/ui/table/TableCell.vue.stub +22 -0
  311. package/stubs/vue/src/components/ui/table/TableEmpty.vue.stub +34 -0
  312. package/stubs/vue/src/components/ui/table/TableFooter.vue.stub +17 -0
  313. package/stubs/vue/src/components/ui/table/TableHead.vue.stub +17 -0
  314. package/stubs/vue/src/components/ui/table/TableHeader.vue.stub +17 -0
  315. package/stubs/vue/src/components/ui/table/TableRow.vue.stub +17 -0
  316. package/stubs/vue/src/components/ui/table/index.ts.stub +9 -0
  317. package/stubs/vue/src/components/ui/table/utils.ts.stub +10 -0
  318. package/stubs/vue/src/components/ui/tabs/Tabs.vue.stub +24 -0
  319. package/stubs/vue/src/components/ui/tabs/TabsContent.vue.stub +21 -0
  320. package/stubs/vue/src/components/ui/tabs/TabsList.vue.stub +24 -0
  321. package/stubs/vue/src/components/ui/tabs/TabsTrigger.vue.stub +26 -0
  322. package/stubs/vue/src/components/ui/tabs/index.ts.stub +4 -0
  323. package/stubs/vue/src/components/ui/tooltip/Tooltip.vue.stub +19 -0
  324. package/stubs/vue/src/components/ui/tooltip/TooltipContent.vue.stub +34 -0
  325. package/stubs/vue/src/components/ui/tooltip/TooltipProvider.vue.stub +14 -0
  326. package/stubs/vue/src/components/ui/tooltip/TooltipTrigger.vue.stub +15 -0
  327. package/stubs/vue/src/components/ui/tooltip/index.ts.stub +4 -0
  328. package/stubs/vue/src/lib/api.ts.stub +17 -0
  329. package/stubs/vue/src/lib/utils.ts.stub +7 -0
  330. package/stubs/vue/src/main.ts.stub +13 -0
  331. package/stubs/vue/src/pages/Dashboard.vue.stub +211 -0
  332. package/stubs/vue/src/pages/Login.vue.stub +118 -0
  333. package/stubs/vue/src/pages/Register.vue.stub +133 -0
  334. package/stubs/vue/src/pages/Users.vue.stub +209 -0
  335. package/stubs/vue/src/pages/account/layout.vue.stub +57 -0
  336. package/stubs/vue/src/pages/account/preferences.vue.stub +88 -0
  337. package/stubs/vue/src/pages/account/profile.vue.stub +78 -0
  338. package/stubs/vue/src/pages/account/security.vue.stub +93 -0
  339. package/stubs/vue/src/pages/users/dialogs/AddUserDialog.vue.stub +86 -0
  340. package/stubs/vue/src/pages/users/dialogs/DeleteUserDialog.vue.stub +62 -0
  341. package/stubs/vue/src/pages/users/dialogs/EditUserDialog.vue.stub +94 -0
  342. package/stubs/vue/src/pages.ts.stub +17 -0
  343. package/stubs/vue/src/ssr.ts.stub +9 -0
  344. package/stubs/vue/src/style.css.stub +27 -0
  345. package/stubs/vue/tsconfig.json.stub +23 -0
  346. package/stubs/vue/vite.config.ts.stub +22 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-mantiq",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "Scaffold a new MantiqJS application",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -34,6 +34,7 @@
34
34
  },
35
35
  "files": [
36
36
  "src/",
37
+ "stubs/",
37
38
  "package.json",
38
39
  "README.md"
39
40
  ],
package/src/index.ts CHANGED
@@ -86,24 +86,12 @@ if (!isCI && !kit) {
86
86
 
87
87
  kit = framework === 'none' ? undefined : framework as Kit
88
88
 
89
- // UI kit selection (React only)
90
- if (kit === 'react' && !flags['ui']) {
91
- const uiChoice = await term.select('Which UI kit?', [
92
- { value: 'none', label: 'Plain Tailwind' },
93
- { value: 'shadcn', label: 'shadcn/ui', hint: 'Radix + Tailwind' },
94
- ])
95
- ui = uiChoice as 'shadcn' | 'none'
96
- }
97
89
  } else {
98
90
  // Validate flags
99
91
  if (kit && !validKits.includes(kit as Kit)) {
100
92
  console.error(`\n ${red('ERROR')} Invalid kit "${kit}". Valid options: ${validKits.join(', ')}\n`)
101
93
  process.exit(1)
102
94
  }
103
- if (ui === 'shadcn' && kit !== 'react') {
104
- console.error(`\n ${red('ERROR')} shadcn/ui is only available with --kit=react\n`)
105
- process.exit(1)
106
- }
107
95
  term.header()
108
96
  }
109
97
 
@@ -113,14 +101,52 @@ term.step('Scaffolding project')
113
101
  const appKey = `base64:${randomBytes(32).toString('base64')}`
114
102
  const templates = getTemplates({ name: projectName, appKey, kit, ui })
115
103
 
116
- // Write all files
117
- const files = Object.keys(templates).sort()
118
- for (const relativePath of files) {
104
+ // Write base skeleton (dynamic templates)
105
+ const templateFiles = Object.keys(templates).sort()
106
+ for (const relativePath of templateFiles) {
119
107
  const fullPath = `${projectDir}/${relativePath}`
120
108
  mkdirSync(dirname(fullPath), { recursive: true })
121
109
  await Bun.write(fullPath, templates[relativePath]!)
122
110
  }
123
- console.log(` ${dim(`${files.length} files created`)}`)
111
+
112
+ // Copy starter kit stubs (static files)
113
+ let stubCount = 0
114
+ if (kit) {
115
+ const stubsDir = resolve(import.meta.dir, '..', 'stubs')
116
+ const manifestPath = resolve(stubsDir, 'manifest.json')
117
+
118
+ if (existsSync(manifestPath)) {
119
+ const manifest = JSON.parse(await Bun.file(manifestPath).text())
120
+ const kitManifest = manifest[kit]
121
+ const sharedManifest = manifest.shared
122
+
123
+ // Copy kit-specific stubs (src/, vite.config.ts, tsconfig.json, etc.)
124
+ if (kitManifest?.files) {
125
+ for (const { stub, target } of kitManifest.files) {
126
+ const src = resolve(stubsDir, kit, stub)
127
+ const dest = resolve(projectDir, target)
128
+ mkdirSync(dirname(dest), { recursive: true })
129
+ await Bun.write(dest, Bun.file(src))
130
+ stubCount++
131
+ }
132
+ }
133
+
134
+ // Copy shared stubs (routes, controllers, seeder) with placeholder replacement
135
+ if (sharedManifest?.files) {
136
+ const mainEntry = kitManifest?.mainEntry ?? 'src/main.ts'
137
+ for (const { stub, target } of sharedManifest.files) {
138
+ const src = resolve(stubsDir, 'shared', stub)
139
+ const dest = resolve(projectDir, target)
140
+ mkdirSync(dirname(dest), { recursive: true })
141
+ let content = await Bun.file(src).text()
142
+ content = content.replace(/\{\{MAIN_ENTRY\}\}/g, mainEntry)
143
+ await Bun.write(dest, content)
144
+ stubCount++
145
+ }
146
+ }
147
+ }
148
+ }
149
+ console.log(` ${dim(`${templateFiles.length + stubCount} files created`)}`)
124
150
 
125
151
  // ── Install dependencies ─────────────────────────────────────────────────────
126
152
  const spin = term.spinner('Installing dependencies')
@@ -133,8 +159,8 @@ const install = Bun.spawn(['bun', 'install'], {
133
159
  await install.exited
134
160
  spin.stop('Dependencies installed')
135
161
 
136
- // ── Install shadcn components (if selected) ─────────────────────────────────
137
- if (ui === 'shadcn' && kit === 'react') {
162
+ // ── Install shadcn components (React always uses shadcn) ─────────────────────
163
+ if (kit === 'react') {
138
164
  const shadcnSpin = term.spinner('Installing shadcn/ui components')
139
165
 
140
166
  const run = async (args: string[]) => {
package/src/templates.ts CHANGED
@@ -1,8 +1,3 @@
1
- import { getReactTemplates } from './kits/react.ts'
2
- import { getVueTemplates } from './kits/vue.ts'
3
- import { getSvelteTemplates } from './kits/svelte.ts'
4
- import { getShadcnTemplates } from './ui/shadcn.ts'
5
-
6
1
  export interface TemplateContext {
7
2
  name: string
8
3
  appKey: string
@@ -26,12 +21,12 @@ export function getTemplates(ctx: TemplateContext): Record<string, string> {
26
21
  },
27
22
  dependencies: {
28
23
  '@mantiq/auth': '^0.1.2',
29
- '@mantiq/cli': '^0.1.2',
30
- '@mantiq/core': '^0.1.2',
31
- '@mantiq/database': '^0.1.2',
24
+ '@mantiq/cli': '^0.1.6',
25
+ '@mantiq/core': '^0.1.4',
26
+ '@mantiq/database': '^0.1.4',
32
27
  '@mantiq/events': '^0.1.2',
33
28
  '@mantiq/filesystem': '^0.1.2',
34
- '@mantiq/heartbeat': '^0.1.2',
29
+ '@mantiq/heartbeat': '^0.3.0',
35
30
  '@mantiq/helpers': '^0.1.2',
36
31
  '@mantiq/logging': '^0.1.2',
37
32
  '@mantiq/queue': '^0.1.2',
@@ -711,14 +706,20 @@ export default class DatabaseSeeder extends Seeder {
711
706
 
712
707
  function applyKitOverrides(templates: Record<string, string>, ctx: TemplateContext): void {
713
708
  const kit = ctx.kit!
714
- const mainEntry = kit === 'react' ? 'src/main.tsx' : 'src/main.ts'
715
709
 
716
710
  // ── package.json ────────────────────────────────────────────────────────
717
711
  const frameworkDevDeps: Record<string, string> = kit === 'react'
718
712
  ? { 'react': '^19.0.0', 'react-dom': '^19.0.0', '@vitejs/plugin-react': '^4.0.0', '@types/react': '^19.0.0', '@types/react-dom': '^19.0.0' }
719
713
  : kit === 'vue'
720
714
  ? { 'vue': '^3.5.0', '@vitejs/plugin-vue': '^5.0.0' }
721
- : { 'svelte': '^4.0.0', '@sveltejs/vite-plugin-svelte': '^3.0.0' }
715
+ : { 'svelte': '^5.0.0', '@sveltejs/vite-plugin-svelte': '^5.0.0' }
716
+
717
+ // UI library deps (shadcn + icons) — must match what the stubs actually import
718
+ const uiDeps: Record<string, string> = kit === 'react'
719
+ ? { 'clsx': '^2.1.0', 'tailwind-merge': '^2.6.0', 'class-variance-authority': '^0.7.1', 'lucide-react': '^0.577.0', 'radix-ui': '^1.4.0' }
720
+ : kit === 'vue'
721
+ ? { 'clsx': '^2.1.0', 'tailwind-merge': '^3.5.0', 'class-variance-authority': '^0.7.1', 'lucide-vue-next': '^0.577.0', 'reka-ui': '^2.9.0', 'tw-animate-css': '^1.4.0', '@tanstack/vue-table': '^8.0.0' }
722
+ : { 'clsx': '^2.1.0', 'tailwind-merge': '^2.6.0', 'tailwind-variants': '^3.2.0', 'lucide-svelte': '^0.577.0', '@lucide/svelte': '^0.577.0', 'bits-ui': '^2.16.0' }
722
723
 
723
724
  templates['package.json'] = JSON.stringify({
724
725
  name: ctx.name,
@@ -729,25 +730,27 @@ function applyKitOverrides(templates: Record<string, string>, ctx: TemplateConte
729
730
  dev: 'bun run --watch index.ts',
730
731
  start: 'bun run index.ts',
731
732
  mantiq: 'bun run mantiq.ts',
732
- 'dev:frontend': 'vite',
733
- 'build:frontend': `vite build && vite build --ssr ${kit === 'react' ? 'src/ssr.tsx' : 'src/ssr.ts'} --outDir bootstrap/ssr`,
733
+ build: `vite build && vite build --ssr ${kit === 'react' ? 'src/ssr.tsx' : 'src/ssr.ts'} --outDir bootstrap/ssr`,
734
+ setup: 'bun install && bun mantiq migrate && bun mantiq seed && bun run build',
735
+ postinstall: 'rm -rf node_modules/@mantiq/*/node_modules/@mantiq 2>/dev/null; true',
734
736
  },
735
737
  dependencies: {
736
738
  '@mantiq/auth': '^0.1.2',
737
- '@mantiq/cli': '^0.1.2',
738
- '@mantiq/core': '^0.1.2',
739
- '@mantiq/database': '^0.1.2',
739
+ '@mantiq/cli': '^0.1.6',
740
+ '@mantiq/core': '^0.1.4',
741
+ '@mantiq/database': '^0.1.4',
740
742
  '@mantiq/events': '^0.1.2',
741
743
  '@mantiq/filesystem': '^0.1.2',
742
- '@mantiq/heartbeat': '^0.1.2',
744
+ '@mantiq/heartbeat': '^0.3.0',
743
745
  '@mantiq/helpers': '^0.1.2',
744
746
  '@mantiq/logging': '^0.1.2',
745
747
  '@mantiq/queue': '^0.1.2',
746
748
  '@mantiq/realtime': '^0.1.2',
747
749
  '@mantiq/validation': '^0.1.2',
748
- '@mantiq/mail': '^0.2.0',
749
- '@mantiq/notify': '^0.1.0',
750
- '@mantiq/vite': '^0.1.2',
750
+ '@mantiq/mail': '^0.2.0',
751
+ '@mantiq/notify': '^0.1.0',
752
+ '@mantiq/vite': '^0.1.3',
753
+ ...uiDeps,
751
754
  },
752
755
  devDependencies: {
753
756
  'bun-types': 'latest',
@@ -759,30 +762,6 @@ function applyKitOverrides(templates: Record<string, string>, ctx: TemplateConte
759
762
  },
760
763
  }, null, 2) + '\n'
761
764
 
762
- // ── tsconfig.json (React needs JSX + DOM) ───────────────────────────────
763
- if (kit === 'react') {
764
- templates['tsconfig.json'] = JSON.stringify({
765
- compilerOptions: {
766
- target: 'ESNext',
767
- module: 'ESNext',
768
- moduleResolution: 'bundler',
769
- lib: ['ESNext', 'DOM', 'DOM.Iterable'],
770
- types: ['bun-types'],
771
- jsx: 'react-jsx',
772
- strict: true,
773
- noImplicitAny: true,
774
- strictNullChecks: true,
775
- noUncheckedIndexedAccess: true,
776
- noImplicitOverride: true,
777
- allowImportingTsExtensions: true,
778
- noEmit: true,
779
- skipLibCheck: true,
780
- },
781
- include: ['./**/*'],
782
- exclude: ['node_modules'],
783
- }, null, 2) + '\n'
784
- }
785
-
786
765
  // ── .env ────────────────────────────────────────────────────────────────
787
766
  templates['.env'] = `APP_NAME=${ctx.name}
788
767
  APP_ENV=local
@@ -926,295 +905,4 @@ if (import.meta.main) {
926
905
  await kernel.start()
927
906
  }
928
907
  `
929
-
930
- // ── config/vite.ts ──────────────────────────────────────────────────────
931
- const ssrEntry = kit === 'react' ? 'src/ssr.tsx' : 'src/ssr.ts'
932
- templates['config/vite.ts'] = `import { env } from '@mantiq/core'
933
-
934
- export default {
935
- devServerUrl: env('VITE_DEV_SERVER_URL', 'http://localhost:5173'),
936
- buildDir: 'build',
937
- publicDir: import.meta.dir + '/../public',
938
- manifest: '.vite/manifest.json',
939
- reactRefresh: ${kit === 'react' ? 'true' : 'false'},
940
- rootElement: 'app',
941
- ssr: {
942
- entry: '${kit === 'react' ? 'src/ssr.tsx' : 'src/ssr.ts'}',
943
- bundle: 'bootstrap/ssr/ssr.js',
944
- },
945
- }
946
- `
947
-
948
- // ── routes/web.ts ───────────────────────────────────────────────────────
949
- templates['routes/web.ts'] = `import type { Router } from '@mantiq/core'
950
- import { HomeController } from '../app/Http/Controllers/HomeController.ts'
951
- import { PageController } from '../app/Http/Controllers/PageController.ts'
952
- import { AuthController } from '../app/Http/Controllers/AuthController.ts'
953
-
954
- export default function (router: Router) {
955
- // Welcome page — shows auth-aware buttons
956
- router.get('/', [HomeController, 'index'])
957
-
958
- // Page routes — each returns HTML (first load) or JSON (client navigation)
959
- router.get('/dashboard', [PageController, 'dashboard']).middleware('auth')
960
- router.get('/login', [PageController, 'login']).middleware('guest')
961
- router.get('/register', [PageController, 'register']).middleware('guest')
962
-
963
- // Auth actions
964
- router.post('/login', [AuthController, 'login'])
965
- router.post('/register', [AuthController, 'register'])
966
- router.post('/logout', [AuthController, 'logout']).middleware('auth')
967
- }
968
- `
969
-
970
- // ── routes/api.ts ───────────────────────────────────────────────────────
971
- templates['routes/api.ts'] = `import type { Router } from '@mantiq/core'
972
- import { MantiqResponse } from '@mantiq/core'
973
- import { User } from '../app/Models/User.ts'
974
-
975
- export default function (router: Router) {
976
- router.get('/api/ping', () => {
977
- return MantiqResponse.json({ status: 'ok', timestamp: new Date().toISOString() })
978
- })
979
-
980
- router.get('/api/users', async () => {
981
- const users = await User.all()
982
- return MantiqResponse.json({ data: users.map((u: any) => u.toObject()) })
983
- }).middleware('auth')
984
- }
985
- `
986
-
987
- // ── HomeController (welcome page, auth-aware) ─────────────────────────
988
- // Build as a function body string to avoid nested template literal escaping issues
989
- const welcomeCSS = `*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;background:#0a0a0b;color:#fafafa;min-height:100vh;display:flex;align-items:center;justify-content:center;-webkit-font-smoothing:antialiased}.c{width:100%;max-width:460px;padding:32px;animation:up .5s ease}@keyframes up{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}.w{font-size:28px;font-weight:600;letter-spacing:-0.04em;color:#fafafa}.w .d{color:#10b981}.v{font-family:'SF Mono',ui-monospace,monospace;font-size:12px;color:#52525b;margin-top:6px}hr{border:none;border-top:1px solid #1e1e1e;margin:24px 0}.g{display:grid;grid-template-columns:1fr 1fr;gap:8px}.l{background:#111113;border:1px solid #1e1e1e;border-radius:8px;padding:14px 16px;text-decoration:none;color:#a1a1aa;font-size:13px;display:flex;align-items:center;justify-content:space-between;transition:border-color .15s,color .15s}.l:hover{border-color:#27272a;color:#34d399}.l-accent{border-color:#10b981;color:#fafafa}.l-accent:hover{background:#10b981;color:#0a0a0b}.l .a{color:#52525b;font-size:11px;transition:color .15s}.l:hover .a{color:#34d399}.l-accent .a{color:#10b981}.l-accent:hover .a{color:#0a0a0b}.e{margin-top:24px;font-family:'SF Mono',ui-monospace,monospace;font-size:11px;color:#3f3f46;line-height:2}.e span{color:#52525b}.g2{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px}`
990
-
991
- templates['app/Http/Controllers/HomeController.ts'] = [
992
- "import type { MantiqRequest } from '@mantiq/core'",
993
- "import { config } from '@mantiq/core'",
994
- "import { auth } from '@mantiq/auth'",
995
- "",
996
- "const CSS = " + JSON.stringify(welcomeCSS),
997
- "",
998
- "export class HomeController {",
999
- " async index(request: MantiqRequest): Promise<Response> {",
1000
- " const appName = config('app.name') ?? 'MantiqJS'",
1001
- " const appEnv = config('app.env') ?? 'production'",
1002
- " const debug = config('app.debug') ? 'Enabled' : 'Disabled'",
1003
- " const bunVersion = typeof Bun !== 'undefined' ? Bun.version : 'unknown'",
1004
- "",
1005
- " let mantiqVersion = '0.0.0'",
1006
- " try {",
1007
- " const pkg = await Bun.file(require.resolve('@mantiq/core/package.json')).json()",
1008
- " mantiqVersion = pkg.version",
1009
- " } catch { /* fallback */ }",
1010
- "",
1011
- " let isLoggedIn = false",
1012
- " try {",
1013
- " const manager = auth()",
1014
- " manager.setRequest(request)",
1015
- " const user = await manager.user()",
1016
- " if (user) isLoggedIn = true",
1017
- " } catch { /* not authenticated */ }",
1018
- "",
1019
- " let migrated = false",
1020
- " try {",
1021
- " const { User } = await import('../../Models/User.ts')",
1022
- " await User.count()",
1023
- " migrated = true",
1024
- " } catch { /* table missing */ }",
1025
- "",
1026
- " const authButtons = isLoggedIn",
1027
- " ? '<a class=\"l l-accent\" href=\"/dashboard\">Dashboard<span class=\"a\">&rarr;</span></a>' +",
1028
- " '<a class=\"l\" href=\"/_heartbeat\">Heartbeat<span class=\"a\">&rarr;</span></a>'",
1029
- " : migrated",
1030
- " ? '<a class=\"l l-accent\" href=\"/login\">Sign in<span class=\"a\">&rarr;</span></a>' +",
1031
- " '<a class=\"l\" href=\"/register\">Register<span class=\"a\">&rarr;</span></a>'",
1032
- " : '<a class=\"l\" href=\"/_heartbeat\">Heartbeat<span class=\"a\">&rarr;</span></a>' +",
1033
- " '<a class=\"l\" href=\"/api/ping\">API Ping<span class=\"a\">&rarr;</span></a>'",
1034
- "",
1035
- " const html = [",
1036
- " '<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">',",
1037
- " '<title>' + appName + '</title><style>' + CSS + '</style></head><body><div class=\"c\">',",
1038
- " '<div class=\"w\"><span class=\"d\">.</span>mantiq</div>',",
1039
- " '<div class=\"v\">v' + mantiqVersion + ' \\u2014 ' + appName + '</div><hr>',",
1040
- " '<div class=\"g\">' + authButtons + '</div>',",
1041
- " '<div class=\"g2\">',",
1042
- " '<a class=\"l\" href=\"https://github.com/mantiqjs/mantiq\" target=\"_blank\" rel=\"noopener\">GitHub<span class=\"a\">&nearr;</span></a>',",
1043
- " '<a class=\"l\" href=\"https://www.npmjs.com/org/mantiq\" target=\"_blank\" rel=\"noopener\">npm<span class=\"a\">&nearr;</span></a>',",
1044
- " '</div>',",
1045
- " '<div class=\"e\"><span>Runtime</span> Bun ' + bunVersion + '<br><span>Environment</span> ' + appEnv + '<br><span>Debug</span> ' + debug + '</div>',",
1046
- " '</div></body></html>',",
1047
- " ].join('')",
1048
- "",
1049
- " return new Response(html, {",
1050
- " headers: { 'Content-Type': 'text/html; charset=utf-8' },",
1051
- " })",
1052
- " }",
1053
- "}",
1054
- ].join('\n') + '\n'
1055
-
1056
- // ── PageController (SSR + universal routing) ────────────────────────────
1057
- templates['app/Http/Controllers/PageController.ts'] = `import type { MantiqRequest } from '@mantiq/core'
1058
- import { config } from '@mantiq/core'
1059
- import { vite } from '@mantiq/vite'
1060
- import { auth } from '@mantiq/auth'
1061
- import { User } from '../../Models/User.ts'
1062
-
1063
- export class PageController {
1064
- async dashboard(request: MantiqRequest): Promise<Response> {
1065
- const manager = auth()
1066
- manager.setRequest(request)
1067
- const user = await manager.user()
1068
-
1069
- const currentUser = user ? {
1070
- id: (user as any).getAttribute?.('id') ?? user.getAuthIdentifier(),
1071
- name: (user as any).getAttribute?.('name') ?? '',
1072
- email: (user as any).getAttribute?.('email') ?? '',
1073
- } : null
1074
-
1075
- const users = await User.all()
1076
-
1077
- return vite().render(request, {
1078
- page: 'Dashboard',
1079
- entry: ['src/style.css', '${mainEntry}'],
1080
- title: config('app.name') + ' — Dashboard',
1081
- data: {
1082
- appName: config('app.name'),
1083
- currentUser,
1084
- users: users.map((u: any) => u.toObject()),
1085
- },
1086
- })
1087
- }
1088
-
1089
- async login(request: MantiqRequest): Promise<Response> {
1090
- return vite().render(request, {
1091
- page: 'Login',
1092
- entry: ['src/style.css', '${mainEntry}'],
1093
- title: config('app.name') + ' — Sign In',
1094
- data: { appName: config('app.name') },
1095
- })
1096
- }
1097
-
1098
- async register(request: MantiqRequest): Promise<Response> {
1099
- return vite().render(request, {
1100
- page: 'Register',
1101
- entry: ['src/style.css', '${mainEntry}'],
1102
- title: config('app.name') + ' — Register',
1103
- data: { appName: config('app.name') },
1104
- })
1105
- }
1106
- }
1107
- `
1108
-
1109
- // ── AuthController ──────────────────────────────────────────────────────
1110
- templates['app/Http/Controllers/AuthController.ts'] = `import type { MantiqRequest } from '@mantiq/core'
1111
- import { MantiqResponse, HashManager } from '@mantiq/core'
1112
- import { auth } from '@mantiq/auth'
1113
- import { User } from '../../Models/User.ts'
1114
-
1115
- export class AuthController {
1116
- async register(request: MantiqRequest): Promise<Response> {
1117
- const body = await request.input() as { name?: string; email?: string; password?: string }
1118
-
1119
- if (!body.name || !body.email || !body.password) {
1120
- return MantiqResponse.json({ error: 'Name, email and password are required.' }, 422)
1121
- }
1122
- if (body.password.length < 6) {
1123
- return MantiqResponse.json({ error: 'Password must be at least 6 characters.' }, 422)
1124
- }
1125
-
1126
- const existing = await User.where('email', body.email).first()
1127
- if (existing) {
1128
- return MantiqResponse.json({ error: 'A user with this email already exists.' }, 422)
1129
- }
1130
-
1131
- const hasher = new HashManager({ bcrypt: { rounds: 10 } })
1132
- const hashed = await hasher.make(body.password)
1133
-
1134
- const user = await User.create({
1135
- name: body.name,
1136
- email: body.email,
1137
- password: hashed,
1138
- })
1139
-
1140
- const manager = auth()
1141
- manager.setRequest(request)
1142
- await manager.login(user as any)
1143
-
1144
- return MantiqResponse.json({ message: 'Registered.', user: user.toObject() }, 201)
1145
- }
1146
-
1147
- async login(request: MantiqRequest): Promise<Response> {
1148
- const body = await request.input() as { email?: string; password?: string; remember?: boolean }
1149
-
1150
- if (!body.email || !body.password) {
1151
- return MantiqResponse.json({ error: 'Email and password are required.' }, 422)
1152
- }
1153
-
1154
- const manager = auth()
1155
- manager.setRequest(request)
1156
-
1157
- const success = await manager.attempt(
1158
- { email: body.email, password: body.password },
1159
- body.remember ?? false,
1160
- )
1161
-
1162
- if (!success) {
1163
- return MantiqResponse.json({ error: 'Invalid credentials.' }, 401)
1164
- }
1165
-
1166
- const user = await manager.user()
1167
- return MantiqResponse.json({ message: 'Logged in.', user })
1168
- }
1169
-
1170
- async logout(request: MantiqRequest): Promise<Response> {
1171
- const manager = auth()
1172
- manager.setRequest(request)
1173
- await manager.logout()
1174
- return MantiqResponse.json({ message: 'Logged out.' })
1175
- }
1176
- }
1177
- `
1178
-
1179
- // ── UserSeeder ──────────────────────────────────────────────────────────
1180
- templates['database/seeders/UserSeeder.ts'] = `import { Seeder } from '@mantiq/database'
1181
- import { HashManager } from '@mantiq/core'
1182
- import { User } from '../../app/Models/User.ts'
1183
-
1184
- export default class UserSeeder extends Seeder {
1185
- override async run() {
1186
- const existing = await User.where('email', 'admin@example.com').first()
1187
- if (existing) return
1188
-
1189
- const hasher = new HashManager({ bcrypt: { rounds: 10 } })
1190
- await User.create({
1191
- name: 'Admin',
1192
- email: 'admin@example.com',
1193
- password: await hasher.make('password'),
1194
- })
1195
- }
1196
- }
1197
- `
1198
-
1199
- // ── Merge framework-specific files (vite.config.ts, src/*, etc.) ────────
1200
- const kitTemplates = kit === 'react'
1201
- ? getReactTemplates(ctx)
1202
- : kit === 'vue'
1203
- ? getVueTemplates(ctx)
1204
- : getSvelteTemplates(ctx)
1205
-
1206
- Object.assign(templates, kitTemplates)
1207
-
1208
- // ── Apply shadcn/ui overlay (React only) ──────────────────────────────
1209
- if (ctx.ui === 'shadcn' && kit === 'react') {
1210
- const shadcn = getShadcnTemplates(ctx)
1211
-
1212
- // Merge shadcn deps into package.json
1213
- const pkg = JSON.parse(templates['package.json']!)
1214
- Object.assign(pkg.dependencies, shadcn.dependencies)
1215
- templates['package.json'] = JSON.stringify(pkg, null, 2) + '\n'
1216
-
1217
- // Merge shadcn files (overrides pages + adds components)
1218
- Object.assign(templates, shadcn.files)
1219
- }
1220
908
  }