create-mantiq 0.4.0 → 1.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 (346) hide show
  1. package/package.json +2 -1
  2. package/src/index.ts +44 -18
  3. package/src/templates.ts +14 -326
  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": "1.0.0",
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
@@ -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)
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.460.0', 'radix-ui': '^1.4.0' }
720
+ : kit === 'vue'
721
+ ? { 'clsx': '^2.1.0', 'tailwind-merge': '^2.6.0', 'class-variance-authority': '^0.7.1', 'lucide-vue-next': '^0.460.0', 'radix-vue': '^1.9.0' }
722
+ : { 'clsx': '^2.1.0', 'tailwind-merge': '^2.6.0', 'tailwind-variants': '^3.2.0', 'lucide-svelte': '^0.460.0', 'bits-ui': '^1.0.0' }
722
723
 
723
724
  templates['package.json'] = JSON.stringify({
724
725
  name: ctx.name,
@@ -729,8 +730,9 @@ 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',
@@ -745,9 +747,10 @@ function applyKitOverrides(templates: Record<string, string>, ctx: TemplateConte
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/mail': '^0.2.0',
751
+ '@mantiq/notify': '^0.1.0',
750
752
  '@mantiq/vite': '^0.1.2',
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
  }