miolo 3.0.0-beta.21 → 3.0.0-beta.210

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 (246) hide show
  1. package/bin/build/build.mjs +53 -0
  2. package/bin/build/build_bin.mjs +17 -0
  3. package/bin/build/cli/client.mjs +52 -0
  4. package/bin/build/cli/css.mjs +22 -0
  5. package/bin/build/cli/index.mjs +40 -0
  6. package/bin/build/cli/ssr.mjs +21 -0
  7. package/bin/build/server/aliases.mjs +112 -0
  8. package/bin/build/server/babel.config.js +24 -0
  9. package/bin/build/server/banner.mjs +20 -0
  10. package/bin/build/server/bundle.mjs +111 -0
  11. package/bin/build/server/fix.mjs +15 -0
  12. package/bin/build/server/index.mjs +69 -0
  13. package/bin/build/server/options.mjs +83 -0
  14. package/bin/create/auth.mjs +23 -0
  15. package/bin/create/copy.mjs +175 -0
  16. package/bin/create/docker.mjs +25 -0
  17. package/bin/create/index.mjs +137 -0
  18. package/bin/create/pkgjson.mjs +72 -0
  19. package/bin/create/prepare-template.mjs +158 -0
  20. package/bin/create/validation.mjs +27 -0
  21. package/bin/dev/dev.mjs +32 -23
  22. package/bin/dev/dev_start.mjs +6 -5
  23. package/bin/index.mjs +94 -52
  24. package/bin/prod-bin/create-bin.mjs +42 -27
  25. package/bin/prod-bin/run.mjs +13 -9
  26. package/bin/{prod-run → run}/pid.mjs +4 -4
  27. package/bin/run/restart.mjs +13 -0
  28. package/bin/run/start.mjs +18 -0
  29. package/bin/run/stop.mjs +20 -0
  30. package/bin/util.mjs +35 -11
  31. package/package.json +59 -39
  32. package/src/config/.env +34 -12
  33. package/src/config/defaults.mjs +253 -185
  34. package/src/config/env.mjs +40 -22
  35. package/src/config/index.mjs +19 -24
  36. package/src/config/util.mjs +25 -10
  37. package/src/db-conn.mjs +34 -0
  38. package/src/engines/cron/emails.mjs +10 -5
  39. package/src/engines/cron/index.mjs +45 -51
  40. package/src/engines/cron/init.mjs +16 -17
  41. package/src/engines/cron/ipsum.mjs +65 -60
  42. package/src/engines/cron/syscheck.mjs +30 -30
  43. package/src/engines/emailer/index.mjs +1 -2
  44. package/src/engines/emailer/queue.mjs +14 -20
  45. package/src/engines/emailer/transporter.mjs +86 -74
  46. package/src/engines/geoip/index.mjs +23 -28
  47. package/src/engines/http/index.mjs +26 -15
  48. package/src/engines/logger/buildErrorEmailBody.mjs +72 -0
  49. package/src/engines/logger/index.mjs +114 -122
  50. package/src/engines/logger/injectStackTrace.mjs +59 -0
  51. package/src/engines/logger/logger_mail.mjs +47 -61
  52. package/src/engines/logger/reopenTransportOnHupSignal.mjs +12 -13
  53. package/src/engines/parser/Parser.mjs +77 -60
  54. package/src/engines/parser/index.mjs +1 -1
  55. package/src/engines/schema/diffObjs.mjs +41 -0
  56. package/src/engines/schema/index.mjs +4 -0
  57. package/src/engines/schema/input.mjs +54 -0
  58. package/src/engines/schema/output.mjs +66 -0
  59. package/src/engines/socket/index.mjs +44 -46
  60. package/src/index.mjs +15 -10
  61. package/src/middleware/auth/basic.mjs +41 -40
  62. package/src/middleware/auth/custom.mjs +10 -13
  63. package/src/middleware/auth/guest.mjs +27 -27
  64. package/src/middleware/auth/passport/index.mjs +374 -0
  65. package/src/middleware/auth/passport/session/index.mjs +43 -0
  66. package/src/middleware/auth/{credentials → passport}/session/store.mjs +35 -15
  67. package/src/middleware/auth/passport/session/store_koa_redis.mjs +3 -0
  68. package/src/middleware/context/cache/index.mjs +78 -33
  69. package/src/middleware/context/cache/options.mjs +19 -21
  70. package/src/middleware/context/db.mjs +45 -20
  71. package/src/middleware/context/index.mjs +12 -12
  72. package/src/middleware/extra.mjs +4 -5
  73. package/src/middleware/http/body.mjs +25 -25
  74. package/src/middleware/http/catcher.mjs +81 -8
  75. package/src/middleware/http/custom_blacklist.mjs +19 -16
  76. package/src/middleware/http/headers.mjs +37 -34
  77. package/src/middleware/http/ratelimit.mjs +16 -23
  78. package/src/middleware/http/request.mjs +60 -65
  79. package/src/middleware/routes/catch_js_error.mjs +30 -23
  80. package/src/middleware/routes/robots.mjs +4 -7
  81. package/src/middleware/routes/router/crud/attachCrudRoutes.mjs +108 -90
  82. package/src/middleware/routes/router/crud/getCrudConfig.mjs +31 -55
  83. package/src/middleware/routes/router/defaults.mjs +6 -19
  84. package/src/middleware/routes/router/index.mjs +17 -21
  85. package/src/middleware/routes/router/queries/attachQueriesRoutes.mjs +227 -50
  86. package/src/middleware/routes/router/queries/getQueriesConfig.mjs +45 -55
  87. package/src/middleware/routes/router/utils.mjs +41 -26
  88. package/src/middleware/ssr/context.mjs +5 -7
  89. package/src/middleware/ssr/html.mjs +66 -43
  90. package/src/middleware/ssr/loader.mjs +11 -14
  91. package/src/middleware/ssr/ssr_render.mjs +39 -22
  92. package/src/middleware/static/index.mjs +33 -14
  93. package/src/middleware/vite/devserver.mjs +38 -22
  94. package/src/middleware/vite/watcher.mjs +12 -14
  95. package/src/server-cron.mjs +13 -8
  96. package/src/server-dev.mjs +13 -16
  97. package/src/server.mjs +49 -51
  98. package/template/.agent/skills/miolo-app-arch/SKILL.md +218 -0
  99. package/template/.agent/skills/miolo-auth/SKILL.md +450 -0
  100. package/template/.agent/skills/miolo-cli-router/SKILL.md +394 -0
  101. package/template/.agent/skills/miolo-database/SKILL.md +358 -0
  102. package/template/.agent/skills/miolo-react-patterns/SKILL.md +426 -0
  103. package/template/.agent/skills/miolo-routing/SKILL.md +326 -0
  104. package/template/.agent/skills/miolo-schemas/SKILL.md +329 -0
  105. package/template/.agent/skills/miolo-session-context/SKILL.md +397 -0
  106. package/template/.agent/skills/miolo-ssr/SKILL.md +433 -0
  107. package/template/.editorconfig +18 -0
  108. package/template/.env +120 -0
  109. package/template/biome.json +63 -0
  110. package/template/components.json +21 -0
  111. package/template/db/init.sh +89 -0
  112. package/template/db/sql/00_drop.sql +2 -0
  113. package/template/db/sql/01_users.sql +31 -0
  114. package/template/db/sql/02_todos.sql +20 -0
  115. package/template/docker/Dockerfile +13 -0
  116. package/template/docker/docker-compose.yaml +79 -0
  117. package/template/gitignore +42 -0
  118. package/template/jsconfig.json +18 -0
  119. package/template/package.json +88 -0
  120. package/template/postcss.config.js +9 -0
  121. package/template/src/cli/App.jsx +25 -0
  122. package/template/src/cli/components/JsonTreeViewer.jsx +128 -0
  123. package/template/src/cli/components/shadcn-io/spinner/index.jsx +232 -0
  124. package/template/src/cli/components/stepper.jsx +408 -0
  125. package/template/src/cli/components/ui/avatar.jsx +36 -0
  126. package/template/src/cli/components/ui/badge.jsx +31 -0
  127. package/template/src/cli/components/ui/breadcrumb.jsx +97 -0
  128. package/template/src/cli/components/ui/card.jsx +73 -0
  129. package/template/src/cli/components/ui/collapsible.jsx +16 -0
  130. package/template/src/cli/components/ui/dropdown-menu.jsx +179 -0
  131. package/template/src/cli/components/ui/field.jsx +217 -0
  132. package/template/src/cli/components/ui/input.jsx +19 -0
  133. package/template/src/cli/components/ui/label.jsx +17 -0
  134. package/template/src/cli/components/ui/pagination.jsx +99 -0
  135. package/template/src/cli/components/ui/patched/alert.jsx +56 -0
  136. package/template/src/cli/components/ui/patched/button.jsx +45 -0
  137. package/template/src/cli/components/ui/patched/dialog.jsx +114 -0
  138. package/template/src/cli/components/ui/patched/sidebar.jsx +660 -0
  139. package/template/src/cli/components/ui/select.jsx +141 -0
  140. package/template/src/cli/components/ui/separator.jsx +21 -0
  141. package/template/src/cli/components/ui/sheet.jsx +115 -0
  142. package/template/src/cli/components/ui/skeleton.jsx +13 -0
  143. package/template/src/cli/components/ui/sonner.jsx +22 -0
  144. package/template/src/cli/components/ui/switch.jsx +25 -0
  145. package/template/src/cli/components/ui/table.jsx +88 -0
  146. package/template/src/cli/components/ui/textarea.jsx +16 -0
  147. package/template/src/cli/components/ui/tooltip.jsx +45 -0
  148. package/template/src/cli/config/store_keys.mjs +2 -0
  149. package/template/src/cli/context/data/DataContext.jsx +5 -0
  150. package/template/src/cli/context/data/DataProvider.jsx +44 -0
  151. package/template/src/cli/context/data/useBreads.mjs +15 -0
  152. package/template/src/cli/context/data/useDataContext.mjs +4 -0
  153. package/template/src/cli/context/session/SessionContext.mjs +4 -0
  154. package/template/src/cli/context/session/SessionProvider.jsx +31 -0
  155. package/template/src/cli/context/session/makePermissioner.mjs +34 -0
  156. package/template/src/cli/context/session/useSessionContext.mjs +6 -0
  157. package/template/src/cli/context/theme/ThemeContext.mjs +4 -0
  158. package/template/src/cli/context/theme/ThemeProvider.jsx +49 -0
  159. package/template/src/cli/context/theme/useThemeContext.mjs +6 -0
  160. package/template/src/cli/context/ui/UIContext.jsx +5 -0
  161. package/template/src/cli/context/ui/UIProvider.jsx +16 -0
  162. package/template/src/cli/context/ui/useUIContext.mjs +4 -0
  163. package/template/src/cli/context/util.mjs +17 -0
  164. package/template/src/cli/entry-cli.jsx +33 -0
  165. package/template/src/cli/hooks/useIsMobile.mjs +19 -0
  166. package/template/src/cli/hooks/useStoragedState.mjs +63 -0
  167. package/template/src/cli/index.html +29 -0
  168. package/template/src/cli/layout/app-sidebar.jsx +25 -0
  169. package/template/src/cli/layout/main-layout.jsx +63 -0
  170. package/template/src/cli/layout/nav-last-todos.jsx +72 -0
  171. package/template/src/cli/layout/nav-main.jsx +39 -0
  172. package/template/src/cli/layout/nav-user.jsx +105 -0
  173. package/template/src/cli/layout/prop-switcher.jsx +93 -0
  174. package/template/src/cli/lib/utils.mjs +10 -0
  175. package/template/src/cli/pages/Index.jsx +13 -0
  176. package/template/src/cli/pages/IndexOffline.jsx +13 -0
  177. package/template/src/cli/pages/IndexOnline.jsx +18 -0
  178. package/template/src/cli/pages/dash/Dashboard.jsx +29 -0
  179. package/template/src/cli/pages/offline/Login.jsx +43 -0
  180. package/template/src/cli/pages/offline/LoginForm.jsx +115 -0
  181. package/template/src/cli/pages/security/Security.jsx +39 -0
  182. package/template/src/cli/pages/security/SecurityForm.jsx +106 -0
  183. package/template/src/cli/pages/todos/TodoActions.jsx +99 -0
  184. package/template/src/cli/pages/todos/TodoAdd.jsx +43 -0
  185. package/template/src/cli/pages/todos/TodoList.jsx +60 -0
  186. package/template/src/cli/pages/todos/Todos.jsx +23 -0
  187. package/template/src/cli/pages/todos/context/TodosContext.jsx +5 -0
  188. package/template/src/cli/pages/todos/context/TodosProvider.jsx +191 -0
  189. package/template/src/cli/pages/todos/context/useTodosContext.mjs +4 -0
  190. package/template/src/ns/models/Todo.mjs +29 -0
  191. package/template/src/ns/models/TodoList.mjs +8 -0
  192. package/template/src/ns/models/User.mjs +40 -0
  193. package/template/src/server/bot/check_today.mjs +10 -0
  194. package/template/src/server/io/cache/base.mjs +21 -0
  195. package/template/src/server/io/db/filter.mjs +92 -0
  196. package/template/src/server/io/db/todos/delete.mjs +29 -0
  197. package/template/src/server/io/db/todos/find.mjs +13 -0
  198. package/template/src/server/io/db/todos/read.mjs +83 -0
  199. package/template/src/server/io/db/todos/toggle.mjs +37 -0
  200. package/template/src/server/io/db/todos/upsave.mjs +32 -0
  201. package/template/src/server/io/db/triggers/user.mjs +13 -0
  202. package/template/src/server/io/db/users/auth.mjs +132 -0
  203. package/template/src/server/io/db/users/pwd.mjs +38 -0
  204. package/template/src/server/io/db/users/save.mjs +17 -0
  205. package/template/src/server/miolo/auth/basic.mjs +15 -0
  206. package/template/src/server/miolo/auth/guest.mjs +3 -0
  207. package/template/src/server/miolo/auth/passport.mjs +73 -0
  208. package/template/src/server/miolo/cache.mjs +11 -0
  209. package/template/src/server/miolo/cron/foo.mjs +7 -0
  210. package/template/src/server/miolo/cron/index.mjs +28 -0
  211. package/template/src/server/miolo/cron/invalidate.mjs +21 -0
  212. package/template/src/server/miolo/db.mjs +36 -0
  213. package/template/src/server/miolo/http.mjs +14 -0
  214. package/template/src/server/miolo/index.mjs +43 -0
  215. package/template/src/server/miolo/routes/crud.mjs +16 -0
  216. package/template/src/server/miolo/routes/index.mjs +8 -0
  217. package/template/src/server/miolo/ssr/entry-server.jsx +13 -0
  218. package/template/src/server/miolo/ssr/loader.mjs +18 -0
  219. package/template/src/server/routes/index.mjs +66 -0
  220. package/template/src/server/routes/todos/mod.mjs +52 -0
  221. package/template/src/server/routes/todos/read.mjs +45 -0
  222. package/template/src/server/routes/todos/special.mjs +47 -0
  223. package/template/src/server/routes/users/user.mjs +54 -0
  224. package/template/src/server/server.mjs +10 -0
  225. package/template/src/server/utils/crypt.mjs +38 -0
  226. package/template/src/server/utils/io.mjs +15 -0
  227. package/template/src/server/utils/pwdfor.mjs +25 -0
  228. package/template/src/server/utils/schema.mjs +22 -0
  229. package/template/src/static/img/default/profile.png +0 -0
  230. package/template/src/static/img/favicon.ico +0 -0
  231. package/template/src/static/img/miolo_logo.png +0 -0
  232. package/template/src/static/img/miolo_name.png +0 -0
  233. package/template/src/static/public/manifest.json +21 -0
  234. package/template/src/static/public/sw.js +79 -0
  235. package/template/src/static/style/globals.css +156 -0
  236. package/template/src/static/style/json-tree.css +54 -0
  237. package/template/src/static/style/skeleton.css +49 -0
  238. package/bin/prod-build/build-client.mjs +0 -67
  239. package/bin/prod-build/build-server.mjs +0 -58
  240. package/bin/prod-run/restart.mjs +0 -9
  241. package/bin/prod-run/start.mjs +0 -15
  242. package/bin/prod-run/stop.mjs +0 -20
  243. package/src/engines/logger/verify.mjs +0 -22
  244. package/src/middleware/auth/credentials/index.mjs +0 -151
  245. package/src/middleware/auth/credentials/session/index.mjs +0 -24
  246. package/src/middleware/auth/credentials/session/store_koa_redis.mjs +0 -3
@@ -0,0 +1,97 @@
1
+ import { Slot } from "@radix-ui/react-slot"
2
+ import { ChevronRight, MoreHorizontal } from "lucide-react"
3
+
4
+ import { cn } from "#cli/lib/utils.mjs"
5
+
6
+ function Breadcrumb({ ...props }) {
7
+ return <nav aria-label="breadcrumb" data-slot="breadcrumb" {...props} />
8
+ }
9
+
10
+ function BreadcrumbList({ className, ...props }) {
11
+ return (
12
+ <ol
13
+ data-slot="breadcrumb-list"
14
+ className={cn(
15
+ "text-muted-foreground flex flex-wrap items-center gap-1.5 text-sm break-words sm:gap-2.5",
16
+ className
17
+ )}
18
+ {...props}
19
+ />
20
+ )
21
+ }
22
+
23
+ function BreadcrumbItem({ className, ...props }) {
24
+ return (
25
+ <li
26
+ data-slot="breadcrumb-item"
27
+ className={cn("inline-flex items-center gap-1.5", className)}
28
+ {...props}
29
+ />
30
+ )
31
+ }
32
+
33
+ function BreadcrumbLink({ asChild, className, ...props }) {
34
+ const Comp = asChild ? Slot : "a"
35
+
36
+ return (
37
+ <Comp
38
+ data-slot="breadcrumb-link"
39
+ className={cn("hover:text-foreground transition-colors", className)}
40
+ {...props}
41
+ />
42
+ )
43
+ }
44
+
45
+ function BreadcrumbPage({ className, ...props }) {
46
+ return (
47
+ // biome-ignore lint/a11y/useFocusableInteractive: biome-ignore
48
+ // biome-ignore lint/a11y/useSemanticElements: biome-ignore
49
+ <span
50
+ data-slot="breadcrumb-page"
51
+ role="link"
52
+ aria-disabled="true"
53
+ aria-current="page"
54
+ className={cn("text-foreground font-normal", className)}
55
+ {...props}
56
+ />
57
+ )
58
+ }
59
+
60
+ function BreadcrumbSeparator({ children, className, ...props }) {
61
+ return (
62
+ <li
63
+ data-slot="breadcrumb-separator"
64
+ role="presentation"
65
+ aria-hidden="true"
66
+ className={cn("[&>svg]:size-3.5", className)}
67
+ {...props}
68
+ >
69
+ {children ?? <ChevronRight />}
70
+ </li>
71
+ )
72
+ }
73
+
74
+ function BreadcrumbEllipsis({ className, ...props }) {
75
+ return (
76
+ <span
77
+ data-slot="breadcrumb-ellipsis"
78
+ role="presentation"
79
+ aria-hidden="true"
80
+ className={cn("flex size-9 items-center justify-center", className)}
81
+ {...props}
82
+ >
83
+ <MoreHorizontal className="size-4" />
84
+ <span className="sr-only">More</span>
85
+ </span>
86
+ )
87
+ }
88
+
89
+ export {
90
+ Breadcrumb,
91
+ BreadcrumbEllipsis,
92
+ BreadcrumbItem,
93
+ BreadcrumbLink,
94
+ BreadcrumbList,
95
+ BreadcrumbPage,
96
+ BreadcrumbSeparator
97
+ }
@@ -0,0 +1,73 @@
1
+ import { cn } from "#cli/lib/utils.mjs"
2
+
3
+ function Card({ className, ...props }) {
4
+ return (
5
+ <div
6
+ data-slot="card"
7
+ className={cn(
8
+ "bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6 shadow-sm",
9
+ className
10
+ )}
11
+ {...props}
12
+ />
13
+ )
14
+ }
15
+
16
+ function CardHeader({ className, ...props }) {
17
+ return (
18
+ <div
19
+ data-slot="card-header"
20
+ className={cn(
21
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-1.5 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
22
+ className
23
+ )}
24
+ {...props}
25
+ />
26
+ )
27
+ }
28
+
29
+ function CardTitle({ className, ...props }) {
30
+ return (
31
+ <div
32
+ data-slot="card-title"
33
+ className={cn("leading-none font-semibold", className)}
34
+ {...props}
35
+ />
36
+ )
37
+ }
38
+
39
+ function CardDescription({ className, ...props }) {
40
+ return (
41
+ <div
42
+ data-slot="card-description"
43
+ className={cn("text-muted-foreground text-sm", className)}
44
+ {...props}
45
+ />
46
+ )
47
+ }
48
+
49
+ function CardAction({ className, ...props }) {
50
+ return (
51
+ <div
52
+ data-slot="card-action"
53
+ className={cn("col-start-2 row-span-2 row-start-1 self-start justify-self-end", className)}
54
+ {...props}
55
+ />
56
+ )
57
+ }
58
+
59
+ function CardContent({ className, ...props }) {
60
+ return <div data-slot="card-content" className={cn("px-6", className)} {...props} />
61
+ }
62
+
63
+ function CardFooter({ className, ...props }) {
64
+ return (
65
+ <div
66
+ data-slot="card-footer"
67
+ className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
68
+ {...props}
69
+ />
70
+ )
71
+ }
72
+
73
+ export { Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }
@@ -0,0 +1,16 @@
1
+ "use client"
2
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible"
3
+
4
+ function Collapsible({ ...props }) {
5
+ return <CollapsiblePrimitive.Root data-slot="collapsible" {...props} />
6
+ }
7
+
8
+ function CollapsibleTrigger({ ...props }) {
9
+ return <CollapsiblePrimitive.CollapsibleTrigger data-slot="collapsible-trigger" {...props} />
10
+ }
11
+
12
+ function CollapsibleContent({ ...props }) {
13
+ return <CollapsiblePrimitive.CollapsibleContent data-slot="collapsible-content" {...props} />
14
+ }
15
+
16
+ export { Collapsible, CollapsibleContent, CollapsibleTrigger }
@@ -0,0 +1,179 @@
1
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"
2
+ import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react"
3
+
4
+ import { cn } from "#cli/lib/utils.mjs"
5
+
6
+ function DropdownMenu({ ...props }) {
7
+ return <DropdownMenuPrimitive.Root data-slot="dropdown-menu" {...props} />
8
+ }
9
+
10
+ function DropdownMenuPortal({ ...props }) {
11
+ return <DropdownMenuPrimitive.Portal data-slot="dropdown-menu-portal" {...props} />
12
+ }
13
+
14
+ function DropdownMenuTrigger({ ...props }) {
15
+ return <DropdownMenuPrimitive.Trigger data-slot="dropdown-menu-trigger" {...props} />
16
+ }
17
+
18
+ function DropdownMenuContent({ className, sideOffset = 4, ...props }) {
19
+ return (
20
+ <DropdownMenuPrimitive.Portal>
21
+ <DropdownMenuPrimitive.Content
22
+ data-slot="dropdown-menu-content"
23
+ sideOffset={sideOffset}
24
+ className={cn(
25
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 max-h-(--radix-dropdown-menu-content-available-height) min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border p-1 shadow-md",
26
+ className
27
+ )}
28
+ {...props}
29
+ />
30
+ </DropdownMenuPrimitive.Portal>
31
+ )
32
+ }
33
+
34
+ function DropdownMenuGroup({ ...props }) {
35
+ return <DropdownMenuPrimitive.Group data-slot="dropdown-menu-group" {...props} />
36
+ }
37
+
38
+ function DropdownMenuItem({ className, inset, variant = "default", ...props }) {
39
+ return (
40
+ <DropdownMenuPrimitive.Item
41
+ data-slot="dropdown-menu-item"
42
+ data-inset={inset}
43
+ data-variant={variant}
44
+ className={cn(
45
+ "focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:!text-destructive [&_svg:not([class*='text-'])]:text-muted-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
46
+ className
47
+ )}
48
+ {...props}
49
+ />
50
+ )
51
+ }
52
+
53
+ function DropdownMenuCheckboxItem({ className, children, checked, ...props }) {
54
+ return (
55
+ <DropdownMenuPrimitive.CheckboxItem
56
+ data-slot="dropdown-menu-checkbox-item"
57
+ className={cn(
58
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
59
+ className
60
+ )}
61
+ checked={checked}
62
+ {...props}
63
+ >
64
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
65
+ <DropdownMenuPrimitive.ItemIndicator>
66
+ <CheckIcon className="size-4" />
67
+ </DropdownMenuPrimitive.ItemIndicator>
68
+ </span>
69
+ {children}
70
+ </DropdownMenuPrimitive.CheckboxItem>
71
+ )
72
+ }
73
+
74
+ function DropdownMenuRadioGroup({ ...props }) {
75
+ return <DropdownMenuPrimitive.RadioGroup data-slot="dropdown-menu-radio-group" {...props} />
76
+ }
77
+
78
+ function DropdownMenuRadioItem({ className, children, ...props }) {
79
+ return (
80
+ <DropdownMenuPrimitive.RadioItem
81
+ data-slot="dropdown-menu-radio-item"
82
+ className={cn(
83
+ "focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-2 pl-8 text-sm outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
84
+ className
85
+ )}
86
+ {...props}
87
+ >
88
+ <span className="pointer-events-none absolute left-2 flex size-3.5 items-center justify-center">
89
+ <DropdownMenuPrimitive.ItemIndicator>
90
+ <CircleIcon className="size-2 fill-current" />
91
+ </DropdownMenuPrimitive.ItemIndicator>
92
+ </span>
93
+ {children}
94
+ </DropdownMenuPrimitive.RadioItem>
95
+ )
96
+ }
97
+
98
+ function DropdownMenuLabel({ className, inset, ...props }) {
99
+ return (
100
+ <DropdownMenuPrimitive.Label
101
+ data-slot="dropdown-menu-label"
102
+ data-inset={inset}
103
+ className={cn("px-2 py-1.5 text-sm font-medium data-[inset]:pl-8", className)}
104
+ {...props}
105
+ />
106
+ )
107
+ }
108
+
109
+ function DropdownMenuSeparator({ className, ...props }) {
110
+ return (
111
+ <DropdownMenuPrimitive.Separator
112
+ data-slot="dropdown-menu-separator"
113
+ className={cn("bg-border -mx-1 my-1 h-px", className)}
114
+ {...props}
115
+ />
116
+ )
117
+ }
118
+
119
+ function DropdownMenuShortcut({ className, ...props }) {
120
+ return (
121
+ <span
122
+ data-slot="dropdown-menu-shortcut"
123
+ className={cn("text-muted-foreground ml-auto text-xs tracking-widest", className)}
124
+ {...props}
125
+ />
126
+ )
127
+ }
128
+
129
+ function DropdownMenuSub({ ...props }) {
130
+ return <DropdownMenuPrimitive.Sub data-slot="dropdown-menu-sub" {...props} />
131
+ }
132
+
133
+ function DropdownMenuSubTrigger({ className, inset, children, ...props }) {
134
+ return (
135
+ <DropdownMenuPrimitive.SubTrigger
136
+ data-slot="dropdown-menu-sub-trigger"
137
+ data-inset={inset}
138
+ className={cn(
139
+ "focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground flex cursor-default items-center rounded-sm px-2 py-1.5 text-sm outline-hidden select-none data-[inset]:pl-8",
140
+ className
141
+ )}
142
+ {...props}
143
+ >
144
+ {children}
145
+ <ChevronRightIcon className="ml-auto size-4" />
146
+ </DropdownMenuPrimitive.SubTrigger>
147
+ )
148
+ }
149
+
150
+ function DropdownMenuSubContent({ className, ...props }) {
151
+ return (
152
+ <DropdownMenuPrimitive.SubContent
153
+ data-slot="dropdown-menu-sub-content"
154
+ className={cn(
155
+ "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 min-w-[8rem] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-md border p-1 shadow-lg",
156
+ className
157
+ )}
158
+ {...props}
159
+ />
160
+ )
161
+ }
162
+
163
+ export {
164
+ DropdownMenu,
165
+ DropdownMenuCheckboxItem,
166
+ DropdownMenuContent,
167
+ DropdownMenuGroup,
168
+ DropdownMenuItem,
169
+ DropdownMenuLabel,
170
+ DropdownMenuPortal,
171
+ DropdownMenuRadioGroup,
172
+ DropdownMenuRadioItem,
173
+ DropdownMenuSeparator,
174
+ DropdownMenuShortcut,
175
+ DropdownMenuSub,
176
+ DropdownMenuSubContent,
177
+ DropdownMenuSubTrigger,
178
+ DropdownMenuTrigger
179
+ }
@@ -0,0 +1,217 @@
1
+ import { cva } from "class-variance-authority"
2
+ import { useMemo } from "react"
3
+ import { Label } from "#cli/components/ui/label.jsx"
4
+ import { Separator } from "#cli/components/ui/separator.jsx"
5
+ import { cn } from "#cli/lib/utils.mjs"
6
+
7
+ function FieldSet({ className, ...props }) {
8
+ return (
9
+ <fieldset
10
+ data-slot="field-set"
11
+ className={cn(
12
+ "flex flex-col gap-6",
13
+ "has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
14
+ className
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ function FieldLegend({ className, variant = "legend", ...props }) {
22
+ return (
23
+ <legend
24
+ data-slot="field-legend"
25
+ data-variant={variant}
26
+ className={cn(
27
+ "mb-3 font-medium",
28
+ "data-[variant=legend]:text-base",
29
+ "data-[variant=label]:text-sm",
30
+ className
31
+ )}
32
+ {...props}
33
+ />
34
+ )
35
+ }
36
+
37
+ function FieldGroup({ className, ...props }) {
38
+ return (
39
+ <div
40
+ data-slot="field-group"
41
+ className={cn(
42
+ "group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4",
43
+ className
44
+ )}
45
+ {...props}
46
+ />
47
+ )
48
+ }
49
+
50
+ const fieldVariants = cva("group/field flex w-full gap-3 data-[invalid=true]:text-destructive", {
51
+ variants: {
52
+ orientation: {
53
+ vertical: ["flex-col [&>*]:w-full [&>.sr-only]:w-auto"],
54
+ horizontal: [
55
+ "flex-row items-center",
56
+ "[&>[data-slot=field-label]]:flex-auto",
57
+ "has-[>[data-slot=field-content]]:items-start has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px"
58
+ ],
59
+ responsive: [
60
+ "flex-col [&>*]:w-full [&>.sr-only]:w-auto @md/field-group:flex-row @md/field-group:items-center @md/field-group:[&>*]:w-auto",
61
+ "@md/field-group:[&>[data-slot=field-label]]:flex-auto",
62
+ "@md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px"
63
+ ]
64
+ }
65
+ },
66
+ defaultVariants: {
67
+ orientation: "vertical"
68
+ }
69
+ })
70
+
71
+ function Field({ className, orientation = "vertical", ...props }) {
72
+ return (
73
+ // biome-ignore lint/a11y/useSemanticElements: biome-ignore
74
+ <div
75
+ role="group"
76
+ data-slot="field"
77
+ data-orientation={orientation}
78
+ className={cn(fieldVariants({ orientation }), className)}
79
+ {...props}
80
+ />
81
+ )
82
+ }
83
+
84
+ function FieldContent({ className, ...props }) {
85
+ return (
86
+ <div
87
+ data-slot="field-content"
88
+ className={cn("group/field-content flex flex-1 flex-col gap-1.5 leading-snug", className)}
89
+ {...props}
90
+ />
91
+ )
92
+ }
93
+
94
+ function FieldLabel({ className, ...props }) {
95
+ return (
96
+ <Label
97
+ data-slot="field-label"
98
+ className={cn(
99
+ "group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50",
100
+ "has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border [&>*]:data-[slot=field]:p-4",
101
+ "has-data-[state=checked]:bg-primary/5 has-data-[state=checked]:border-primary dark:has-data-[state=checked]:bg-primary/10",
102
+ className
103
+ )}
104
+ {...props}
105
+ />
106
+ )
107
+ }
108
+
109
+ function FieldTitle({ className, ...props }) {
110
+ return (
111
+ <div
112
+ data-slot="field-label"
113
+ className={cn(
114
+ "flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50",
115
+ className
116
+ )}
117
+ {...props}
118
+ />
119
+ )
120
+ }
121
+
122
+ function FieldDescription({ className, ...props }) {
123
+ return (
124
+ <p
125
+ data-slot="field-description"
126
+ className={cn(
127
+ "text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
128
+ "last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
129
+ "[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
130
+ className
131
+ )}
132
+ {...props}
133
+ />
134
+ )
135
+ }
136
+
137
+ function FieldSeparator({ children, className, ...props }) {
138
+ return (
139
+ <div
140
+ data-slot="field-separator"
141
+ data-content={!!children}
142
+ className={cn(
143
+ "relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
144
+ className
145
+ )}
146
+ {...props}
147
+ >
148
+ <Separator className="absolute inset-0 top-1/2" />
149
+ {children && (
150
+ <span
151
+ className="bg-background text-muted-foreground relative mx-auto block w-fit px-2"
152
+ data-slot="field-separator-content"
153
+ >
154
+ {children}
155
+ </span>
156
+ )}
157
+ </div>
158
+ )
159
+ }
160
+
161
+ function FieldError({ className, children, errors, ...props }) {
162
+ const content = useMemo(() => {
163
+ if (children) {
164
+ return children
165
+ }
166
+
167
+ if (!errors?.length) {
168
+ return null
169
+ }
170
+
171
+ const uniqueErrors = [...new Map(errors.map((error) => [error?.message, error])).values()]
172
+
173
+ if (uniqueErrors?.length === 1) {
174
+ return uniqueErrors[0]?.message
175
+ }
176
+
177
+ return (
178
+ <ul className="ml-4 flex list-disc flex-col gap-1">
179
+ {uniqueErrors.map(
180
+ (error, index) =>
181
+ error?.message && (
182
+ // biome-ignore lint/suspicious/noArrayIndexKey: biome-ignore
183
+ <li key={index}>{error.message}</li>
184
+ )
185
+ )}
186
+ </ul>
187
+ )
188
+ }, [children, errors])
189
+
190
+ if (!content) {
191
+ return null
192
+ }
193
+
194
+ return (
195
+ <div
196
+ role="alert"
197
+ data-slot="field-error"
198
+ className={cn("text-destructive text-sm font-normal", className)}
199
+ {...props}
200
+ >
201
+ {content}
202
+ </div>
203
+ )
204
+ }
205
+
206
+ export {
207
+ Field,
208
+ FieldContent,
209
+ FieldDescription,
210
+ FieldError,
211
+ FieldGroup,
212
+ FieldLabel,
213
+ FieldLegend,
214
+ FieldSeparator,
215
+ FieldSet,
216
+ FieldTitle
217
+ }
@@ -0,0 +1,19 @@
1
+ import { cn } from "#cli/lib/utils.mjs"
2
+
3
+ function Input({ className, type, ...props }) {
4
+ return (
5
+ <input
6
+ type={type}
7
+ data-slot="input"
8
+ className={cn(
9
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
10
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
11
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
12
+ className
13
+ )}
14
+ {...props}
15
+ />
16
+ )
17
+ }
18
+
19
+ export { Input }
@@ -0,0 +1,17 @@
1
+ import { Label as LabelPrimitive } from "radix-ui"
2
+ import { cn } from "#cli/lib/utils.mjs"
3
+
4
+ function Label({ className, ...props }) {
5
+ return (
6
+ <LabelPrimitive.Root
7
+ data-slot="label"
8
+ className={cn(
9
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
10
+ className
11
+ )}
12
+ {...props}
13
+ />
14
+ )
15
+ }
16
+
17
+ export { Label }