kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: :sparkles: adding crud for workspaces

Andrej faad3a49 b8250e68

+835 -61
+44
apps/api/src/workspace/controllers/delete-workspace.ts
··· 1 + import { and, eq } from "drizzle-orm"; 2 + import workspace from ".."; 3 + import db from "../../database"; 4 + import { workspaceTable } from "../../database/schema"; 5 + import type { DeleteWorkspacePayload } from "../db/queries"; 6 + 7 + async function deleteWorkspace({ 8 + userId, 9 + workspaceId, 10 + }: DeleteWorkspacePayload) { 11 + const workspace = await db 12 + .select({ 13 + id: workspaceTable.id, 14 + ownerId: workspaceTable.ownerId, 15 + }) 16 + .from(workspaceTable) 17 + .where( 18 + and( 19 + eq(workspaceTable.id, workspaceId), 20 + eq(workspaceTable.ownerId, userId), 21 + ), 22 + ) 23 + .limit(1); 24 + 25 + const isWorkspaceExisting = Boolean(workspace.at(0)); 26 + 27 + if (!isWorkspaceExisting) { 28 + throw new Error("Workspace not found or access denied"); 29 + } 30 + 31 + const deletedWorkspace = await db 32 + .delete(workspaceTable) 33 + .where(eq(workspaceTable.id, workspaceId)) 34 + .returning({ 35 + id: workspaceTable.id, 36 + name: workspaceTable.name, 37 + ownerId: workspaceTable.ownerId, 38 + createdAt: workspaceTable.createdAt, 39 + }); 40 + 41 + return deletedWorkspace.at(0); 42 + } 43 + 44 + export default deleteWorkspace;
+36
apps/api/src/workspace/controllers/get-workspace.ts
··· 1 + import { and, eq, or } from "drizzle-orm"; 2 + import db from "../../database"; 3 + import { workspaceTable, workspaceUserTable } from "../../database/schema"; 4 + 5 + // TODO: Unify this type 6 + async function getWorkspace({ 7 + userId, 8 + workspaceId, 9 + }: { userId: string; workspaceId: string }) { 10 + const workspace = await db 11 + .select({ 12 + id: workspaceTable.id, 13 + name: workspaceTable.name, 14 + ownerId: workspaceTable.ownerId, 15 + createdAt: workspaceTable.createdAt, 16 + }) 17 + .from(workspaceTable) 18 + .leftJoin( 19 + workspaceUserTable, 20 + eq(workspaceTable.id, workspaceUserTable.workspaceId), 21 + ) 22 + .where( 23 + and( 24 + eq(workspaceTable.id, workspaceId), 25 + or( 26 + eq(workspaceTable.ownerId, userId), 27 + eq(workspaceUserTable.userId, userId), 28 + ), 29 + ), 30 + ) 31 + .limit(1); 32 + 33 + return workspace.at(0); 34 + } 35 + 36 + export default getWorkspace;
+21 -3
apps/api/src/workspace/controllers/get-workspaces.ts
··· 1 + import { eq, or } from "drizzle-orm"; 1 2 import db from "../../database"; 2 - import { workspaceTable } from "../../database/schema"; 3 + import { workspaceTable, workspaceUserTable } from "../../database/schema"; 3 4 4 - async function getWorkspaces() { 5 - return db.select().from(workspaceTable); 5 + // TODO: Unify this type 6 + async function getWorkspaces({ userId }: { userId: string }) { 7 + return await db 8 + .select({ 9 + id: workspaceTable.id, 10 + name: workspaceTable.name, 11 + ownerId: workspaceTable.ownerId, 12 + }) 13 + .from(workspaceTable) 14 + .leftJoin( 15 + workspaceUserTable, 16 + eq(workspaceTable.id, workspaceUserTable.workspaceId), 17 + ) 18 + .where( 19 + or( 20 + eq(workspaceTable.ownerId, userId), 21 + eq(workspaceUserTable.userId, userId), 22 + ), 23 + ); 6 24 } 7 25 8 26 export default getWorkspaces;
+47
apps/api/src/workspace/controllers/update-workspace.ts
··· 1 + import { and, eq, or } from "drizzle-orm"; 2 + import db from "../../database"; 3 + import { workspaceTable } from "../../database/schema"; 4 + import type { UpdateWorkspacePayload } from "../db/queries"; 5 + 6 + async function updateWorkspace({ 7 + userId, 8 + workspaceId, 9 + body, 10 + }: { userId: string; workspaceId: string; body: UpdateWorkspacePayload }) { 11 + const workspace = await db 12 + .select({ 13 + id: workspaceTable.id, 14 + ownerId: workspaceTable.ownerId, 15 + }) 16 + .from(workspaceTable) 17 + .where( 18 + and( 19 + eq(workspaceTable.id, workspaceId), 20 + eq(workspaceTable.ownerId, userId), 21 + ), 22 + ) 23 + .limit(1); 24 + 25 + const isWorkspaceExisting = Boolean(workspace.at(0)); 26 + 27 + if (!isWorkspaceExisting) { 28 + throw new Error("TODO"); 29 + } 30 + 31 + const updatedWorkspace = await db 32 + .update(workspaceTable) 33 + .set({ 34 + ...body, 35 + }) 36 + .where(eq(workspaceTable.id, workspaceId)) 37 + .returning({ 38 + id: workspaceTable.id, 39 + name: workspaceTable.name, 40 + ownerId: workspaceTable.ownerId, 41 + createdAt: workspaceTable.createdAt, 42 + }); 43 + 44 + return updatedWorkspace.at(0); 45 + } 46 + 47 + export default updateWorkspace;
+14 -1
apps/api/src/workspace/db/queries.ts
··· 1 1 import { createInsertSchema } from "drizzle-typebox"; 2 - import { t } from "elysia"; 2 + import { type Static, t } from "elysia"; 3 3 import { workspaceTable } from "../../database/schema"; 4 4 5 5 export const createWorkspaceSchema = createInsertSchema(workspaceTable, { 6 6 name: t.String(), 7 7 }); 8 + 9 + export const updateWorkspaceSchema = t.Object({ 10 + name: t.Optional(t.String()), 11 + description: t.Optional(t.String()), 12 + }); 13 + 14 + export const deleteWorkspaceSchema = t.Object({ 15 + userId: t.String(), 16 + workspaceId: t.String(), 17 + }); 18 + 19 + export type UpdateWorkspacePayload = Static<typeof updateWorkspaceSchema>; 20 + export type DeleteWorkspacePayload = Static<typeof deleteWorkspaceSchema>;
+51 -25
apps/api/src/workspace/index.ts
··· 1 - import { eq, or } from "drizzle-orm"; 2 - import Elysia from "elysia"; 3 - import db from "../database"; 4 - import { workspaceTable, workspaceUserTable } from "../database/schema"; 1 + import Elysia, { t } from "elysia"; 5 2 import createWorkspace from "./controllers/create-workspace"; 6 - import { createWorkspaceSchema } from "./db/queries"; 3 + import deleteWorkspace from "./controllers/delete-workspace"; 4 + import getWorkspace from "./controllers/get-workspace"; 5 + import getWorkspaces from "./controllers/get-workspaces"; 6 + import updateWorkspace from "./controllers/update-workspace"; 7 + import { updateWorkspaceSchema } from "./db/queries"; 7 8 8 9 const workspace = new Elysia({ prefix: "/workspace" }) 9 10 .state("userId", "") 10 11 .post( 11 - "/", 12 - async ({ body }) => { 13 - const createdWorkspace = await createWorkspace(body); 12 + "/create", 13 + async ({ body, store }) => { 14 + const userId = store.userId; 15 + 16 + const createdWorkspace = await createWorkspace({ 17 + ...body, 18 + ownerId: userId, 19 + }); 14 20 15 21 return createdWorkspace; 16 22 }, 17 23 { 18 - body: createWorkspaceSchema, 24 + body: t.Object({ 25 + name: t.String(), 26 + }), 19 27 }, 20 28 ) 21 - .get("/workspaces", async ({ store }) => { 29 + .get("/list", async ({ store }) => { 22 30 const userId = store.userId; 23 31 24 - const workspaces = await db 25 - .select() 26 - .from(workspaceTable) 27 - .leftJoin( 28 - workspaceUserTable, 29 - eq(workspaceTable.id, workspaceUserTable.workspaceId), 30 - ) 31 - .where( 32 - or( 33 - eq(workspaceTable.ownerId, userId), 34 - eq(workspaceUserTable.userId, userId), 35 - ), 36 - ); 32 + const workspaces = await getWorkspaces({ userId }); 37 33 38 34 return workspaces; 39 35 }) 40 - .put("/:id", () => {}) 41 - .delete("/:id", () => {}); 36 + .get("/:id", async ({ store, params }) => { 37 + const userId = store.userId; 38 + const workspaceId = params.id; 39 + 40 + const workspace = await getWorkspace({ userId, workspaceId }); 41 + 42 + return workspace; 43 + }) 44 + .put( 45 + "/:id", 46 + async ({ store, params, body }) => { 47 + const userId = store.userId; 48 + const workspaceId = params.id; 49 + 50 + const updatedWorkspace = await updateWorkspace({ 51 + userId, 52 + workspaceId, 53 + body, 54 + }); 55 + 56 + return updatedWorkspace; 57 + }, 58 + { body: updateWorkspaceSchema }, 59 + ) 60 + .delete("/:id", async ({ store, params }) => { 61 + const userId = store.userId; 62 + const workspaceId = params.id; 63 + 64 + const deletedWorkspace = await deleteWorkspace({ userId, workspaceId }); 65 + 66 + return deletedWorkspace; 67 + }); 42 68 43 69 export default workspace;
+1
apps/web/package.json
··· 11 11 "dependencies": { 12 12 "@hookform/resolvers": "^3.9.1", 13 13 "@radix-ui/react-avatar": "^1.1.2", 14 + "@radix-ui/react-dialog": "^1.1.4", 14 15 "@radix-ui/react-label": "^2.1.1", 15 16 "@radix-ui/react-slot": "^1.1.1", 16 17 "@tanstack/react-query": "^5.62.12",
+88
apps/web/src/components/common/sidebar/sections/workspaces/add-workspace-modal.tsx
··· 1 + import { Button } from "@/components/ui/button"; 2 + import { Input } from "@/components/ui/input"; 3 + import useCreateWorkspace from "@/hooks/queries/workspace/use-create-workspace"; 4 + import * as Dialog from "@radix-ui/react-dialog"; 5 + import { useQueryClient } from "@tanstack/react-query"; 6 + import { X } from "lucide-react"; 7 + import { useState } from "react"; 8 + 9 + interface CreateWorkspaceModalProps { 10 + open: boolean; 11 + onClose: () => void; 12 + } 13 + 14 + export function CreateWorkspaceModal({ 15 + open, 16 + onClose, 17 + }: CreateWorkspaceModalProps) { 18 + const [name, setName] = useState(""); 19 + const queryClient = useQueryClient(); 20 + const { mutateAsync } = useCreateWorkspace({ name }); 21 + 22 + const handleSubmit = async (e: React.FormEvent) => { 23 + e.preventDefault(); 24 + if (!name.trim()) return; 25 + 26 + await mutateAsync(); 27 + await queryClient.invalidateQueries({ queryKey: ["workspaces"] }); 28 + 29 + setName(""); 30 + onClose(); 31 + }; 32 + 33 + return ( 34 + <Dialog.Root open={open} onOpenChange={onClose}> 35 + <Dialog.Portal> 36 + <Dialog.Overlay className="fixed inset-0 bg-black/40 backdrop-blur-sm" /> 37 + <Dialog.Content className="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md"> 38 + <div className="bg-white dark:bg-zinc-900 rounded-lg shadow-xl"> 39 + <div className="flex items-center justify-between p-4 border-b border-zinc-200 dark:border-zinc-800"> 40 + <Dialog.Title className="text-lg font-semibold text-zinc-900 dark:text-zinc-100"> 41 + New Workspace 42 + </Dialog.Title> 43 + <Dialog.Close className="text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-300"> 44 + <X size={20} /> 45 + </Dialog.Close> 46 + </div> 47 + 48 + <form onSubmit={handleSubmit} className="p-4"> 49 + <div className="mb-4"> 50 + <label 51 + htmlFor="workspaceName" 52 + aria-label="Workspace name" 53 + className="block text-sm font-medium text-zinc-900 dark:text-zinc-300 mb-1" 54 + > 55 + Workspace Name 56 + </label> 57 + <Input 58 + value={name} 59 + onChange={(e) => setName(e.target.value)} 60 + placeholder="My Workspace" 61 + className="bg-white dark:bg-zinc-800/50" 62 + required 63 + /> 64 + </div> 65 + 66 + <div className="flex justify-end gap-2"> 67 + <Dialog.Close asChild> 68 + <Button 69 + type="button" 70 + className="bg-zinc-100 text-zinc-900 hover:bg-zinc-200 dark:bg-zinc-800 dark:text-zinc-100 dark:hover:bg-zinc-700" 71 + > 72 + Cancel 73 + </Button> 74 + </Dialog.Close> 75 + <Button 76 + type="submit" 77 + className="bg-indigo-600 text-white hover:bg-indigo-500 dark:bg-indigo-500 dark:hover:bg-indigo-400" 78 + > 79 + Create Workspace 80 + </Button> 81 + </div> 82 + </form> 83 + </div> 84 + </Dialog.Content> 85 + </Dialog.Portal> 86 + </Dialog.Root> 87 + ); 88 + }
+18 -7
apps/web/src/components/common/sidebar/sections/workspaces/add-workspace.tsx
··· 1 1 import { Plus } from "lucide-react"; 2 + import { useState } from "react"; 3 + import { CreateWorkspaceModal } from "./add-workspace-modal"; 2 4 3 5 function AddWorkspace() { 6 + const [isDialogOpen, setIsDialogOpen] = useState<boolean>(false); 7 + 4 8 return ( 5 - <button 6 - type="button" 7 - className="w-full text-left px-3 py-2 text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800 rounded-lg flex items-center transition-colors" 8 - > 9 - <Plus className="w-4 h-4 mr-2 text-zinc-500 dark:text-zinc-400" /> 10 - Add Workspace 11 - </button> 9 + <> 10 + <button 11 + type="button" 12 + onClick={() => setIsDialogOpen(true)} 13 + className="w-full text-left px-3 py-2 text-zinc-700 hover:bg-zinc-100 dark:text-zinc-300 dark:hover:bg-zinc-800 rounded-lg flex items-center transition-colors" 14 + > 15 + <Plus className="w-4 h-4 mr-2 text-zinc-500 dark:text-zinc-400" /> 16 + Add Workspace 17 + </button> 18 + <CreateWorkspaceModal 19 + open={isDialogOpen} 20 + onClose={() => setIsDialogOpen(false)} 21 + /> 22 + </> 12 23 ); 13 24 } 14 25
+10 -14
apps/web/src/components/common/sidebar/sections/workspaces/index.tsx
··· 1 + import useGetWorkspaces from "@/hooks/queries/workspace/use-get-workspace"; 1 2 import AddWorkspace from "./add-workspace"; 2 3 import WorkspaceItemButton from "./workspace-item-button"; 3 4 4 - const workspaces = [ 5 - { 6 - id: "1", 7 - name: "Personal Workspace", 8 - }, 9 - { 10 - id: "2", 11 - name: "Uni Workspace", 12 - }, 13 - ]; 5 + const selectedWorkspace = { 6 + id: "1", 7 + }; 14 8 15 9 function Workspaces() { 16 - const selectedWorkspace = { 17 - id: "1", 18 - name: "Personal Workspace", 19 - }; 10 + const { data } = useGetWorkspaces(); 11 + const workspaces = data?.data; 12 + 13 + if (!workspaces || !workspaces?.length) { 14 + return <div>You don't have any workspaces</div>; 15 + } 20 16 21 17 return ( 22 18 <div>
+120
apps/web/src/components/ui/dialog.tsx
··· 1 + import * as DialogPrimitive from "@radix-ui/react-dialog"; 2 + import { X } from "lucide-react"; 3 + import * as React from "react"; 4 + 5 + import { cn } from "@/lib/utils"; 6 + 7 + const Dialog = DialogPrimitive.Root; 8 + 9 + const DialogTrigger = DialogPrimitive.Trigger; 10 + 11 + const DialogPortal = DialogPrimitive.Portal; 12 + 13 + const DialogClose = DialogPrimitive.Close; 14 + 15 + const DialogOverlay = React.forwardRef< 16 + React.ElementRef<typeof DialogPrimitive.Overlay>, 17 + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay> 18 + >(({ className, ...props }, ref) => ( 19 + <DialogPrimitive.Overlay 20 + ref={ref} 21 + className={cn( 22 + "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0", 23 + className, 24 + )} 25 + {...props} 26 + /> 27 + )); 28 + DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; 29 + 30 + const DialogContent = React.forwardRef< 31 + React.ElementRef<typeof DialogPrimitive.Content>, 32 + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> 33 + >(({ className, children, ...props }, ref) => ( 34 + <DialogPortal> 35 + <DialogOverlay /> 36 + <DialogPrimitive.Content 37 + ref={ref} 38 + className={cn( 39 + "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 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-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg", 40 + className, 41 + )} 42 + {...props} 43 + > 44 + {children} 45 + <DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground"> 46 + <X className="h-4 w-4" /> 47 + <span className="sr-only">Close</span> 48 + </DialogPrimitive.Close> 49 + </DialogPrimitive.Content> 50 + </DialogPortal> 51 + )); 52 + DialogContent.displayName = DialogPrimitive.Content.displayName; 53 + 54 + const DialogHeader = ({ 55 + className, 56 + ...props 57 + }: React.HTMLAttributes<HTMLDivElement>) => ( 58 + <div 59 + className={cn( 60 + "flex flex-col space-y-1.5 text-center sm:text-left", 61 + className, 62 + )} 63 + {...props} 64 + /> 65 + ); 66 + DialogHeader.displayName = "DialogHeader"; 67 + 68 + const DialogFooter = ({ 69 + className, 70 + ...props 71 + }: React.HTMLAttributes<HTMLDivElement>) => ( 72 + <div 73 + className={cn( 74 + "flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", 75 + className, 76 + )} 77 + {...props} 78 + /> 79 + ); 80 + DialogFooter.displayName = "DialogFooter"; 81 + 82 + const DialogTitle = React.forwardRef< 83 + React.ElementRef<typeof DialogPrimitive.Title>, 84 + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title> 85 + >(({ className, ...props }, ref) => ( 86 + <DialogPrimitive.Title 87 + ref={ref} 88 + className={cn( 89 + "text-lg font-semibold leading-none tracking-tight", 90 + className, 91 + )} 92 + {...props} 93 + /> 94 + )); 95 + DialogTitle.displayName = DialogPrimitive.Title.displayName; 96 + 97 + const DialogDescription = React.forwardRef< 98 + React.ElementRef<typeof DialogPrimitive.Description>, 99 + React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description> 100 + >(({ className, ...props }, ref) => ( 101 + <DialogPrimitive.Description 102 + ref={ref} 103 + className={cn("text-sm text-muted-foreground", className)} 104 + {...props} 105 + /> 106 + )); 107 + DialogDescription.displayName = DialogPrimitive.Description.displayName; 108 + 109 + export { 110 + Dialog, 111 + DialogPortal, 112 + DialogOverlay, 113 + DialogTrigger, 114 + DialogClose, 115 + DialogContent, 116 + DialogHeader, 117 + DialogFooter, 118 + DialogTitle, 119 + DialogDescription, 120 + };
+13
apps/web/src/fetchers/workspace/create-workspace.ts
··· 1 + import { api } from "@kaneo/libs"; 2 + 3 + const createWorkspace = async ({ name }: { name: string }) => { 4 + const response = await api.workspace.create.post({ name }); 5 + 6 + if (response.error) { 7 + throw new Error(response.error.value.message); 8 + } 9 + 10 + return response; 11 + }; 12 + 13 + export default createWorkspace;
+9
apps/web/src/fetchers/workspace/get-workspaces.ts
··· 1 + import { api } from "@kaneo/libs"; 2 + 3 + const getWorkspaces = async () => { 4 + const response = await api.workspace.list.get(); 5 + 6 + return response; 7 + }; 8 + 9 + export default getWorkspaces;
+10
apps/web/src/hooks/queries/workspace/use-create-workspace.ts
··· 1 + import createWorkspace from "@/fetchers/workspace/create-workspace"; 2 + import { useMutation } from "@tanstack/react-query"; 3 + 4 + function useCreateWorkspace({ name }: { name: string }) { 5 + return useMutation({ 6 + mutationFn: () => createWorkspace({ name }), 7 + }); 8 + } 9 + 10 + export default useCreateWorkspace;
+11
apps/web/src/hooks/queries/workspace/use-get-workspace.ts
··· 1 + import getWorkspaces from "@/fetchers/workspace/get-workspaces"; 2 + import { useQuery } from "@tanstack/react-query"; 3 + 4 + function useGetWorkspaces() { 5 + return useQuery({ 6 + queryFn: () => getWorkspaces(), 7 + queryKey: ["workspaces"], 8 + }); 9 + } 10 + 11 + export default useGetWorkspaces;
+12
apps/web/src/index.css
··· 49 49 } 50 50 } 51 51 52 + @layer base { 53 + body { 54 + @apply text-zinc-900 55 + } 56 + 57 + .dark { 58 + body { 59 + @apply text-zinc-300 60 + } 61 + } 62 + } 63 + 52 64 /* Custom scrollbar styles */ 53 65 @layer utilities { 54 66 .scrollbar-thin {
+7 -1
biome.json
··· 7 7 }, 8 8 "files": { 9 9 "ignoreUnknown": false, 10 - "ignore": ["**/tsconfig*.json", "routeTree.gen.ts", "dist", "cache"] 10 + "ignore": [ 11 + "**/tsconfig*.json", 12 + "routeTree.gen.ts", 13 + "dist", 14 + "cache", 15 + "*.css" 16 + ] 11 17 }, 12 18 "formatter": { 13 19 "enabled": true,
+323 -10
pnpm-lock.yaml
··· 71 71 version: 0.30.1 72 72 drizzle-orm: 73 73 specifier: ^0.38.3 74 - version: 0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.42)(react@18.3.1) 74 + version: 0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.43)(react@18.3.1) 75 75 drizzle-typebox: 76 76 specifier: ^0.2.1 77 - version: 0.2.1(@sinclair/typebox@0.34.13)(drizzle-orm@0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.42)(react@18.3.1)) 77 + version: 0.2.1(@sinclair/typebox@0.34.13)(drizzle-orm@0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.43)(react@18.3.1)) 78 78 elysia: 79 79 specifier: 1.2.9 80 80 version: 1.2.9(@sinclair/typebox@0.34.13)(typescript@5.6.3) 81 81 devDependencies: 82 82 bun-types: 83 83 specifier: latest 84 - version: 1.1.42 84 + version: 1.1.43 85 85 86 86 apps/web: 87 87 dependencies: ··· 91 91 '@radix-ui/react-avatar': 92 92 specifier: ^1.1.2 93 93 version: 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 94 + '@radix-ui/react-dialog': 95 + specifier: ^1.1.4 96 + version: 1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 94 97 '@radix-ui/react-label': 95 98 specifier: ^2.1.1 96 99 version: 2.1.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ··· 1075 1078 resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 1076 1079 engines: {node: '>=14'} 1077 1080 1081 + '@radix-ui/primitive@1.1.1': 1082 + resolution: {integrity: sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA==} 1083 + 1078 1084 '@radix-ui/react-avatar@1.1.2': 1079 1085 resolution: {integrity: sha512-GaC7bXQZ5VgZvVvsJ5mu/AEbjYLnhhkoidOboC50Z6FFlLA03wG2ianUoH+zgDQ31/9gCF59bE4+2bBgTyMiig==} 1080 1086 peerDependencies: ··· 1106 1112 '@types/react': 1107 1113 optional: true 1108 1114 1115 + '@radix-ui/react-dialog@1.1.4': 1116 + resolution: {integrity: sha512-Ur7EV1IwQGCyaAuyDRiOLA5JIUZxELJljF+MbM/2NC0BYwfuRrbpS30BiQBJrVruscgUkieKkqXYDOoByaxIoA==} 1117 + peerDependencies: 1118 + '@types/react': '*' 1119 + '@types/react-dom': '*' 1120 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1121 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1122 + peerDependenciesMeta: 1123 + '@types/react': 1124 + optional: true 1125 + '@types/react-dom': 1126 + optional: true 1127 + 1128 + '@radix-ui/react-dismissable-layer@1.1.3': 1129 + resolution: {integrity: sha512-onrWn/72lQoEucDmJnr8uczSNTujT0vJnA/X5+3AkChVPowr8n1yvIKIabhWyMQeMvvmdpsvcyDqx3X1LEXCPg==} 1130 + peerDependencies: 1131 + '@types/react': '*' 1132 + '@types/react-dom': '*' 1133 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1134 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1135 + peerDependenciesMeta: 1136 + '@types/react': 1137 + optional: true 1138 + '@types/react-dom': 1139 + optional: true 1140 + 1141 + '@radix-ui/react-focus-guards@1.1.1': 1142 + resolution: {integrity: sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg==} 1143 + peerDependencies: 1144 + '@types/react': '*' 1145 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1146 + peerDependenciesMeta: 1147 + '@types/react': 1148 + optional: true 1149 + 1150 + '@radix-ui/react-focus-scope@1.1.1': 1151 + resolution: {integrity: sha512-01omzJAYRxXdG2/he/+xy+c8a8gCydoQ1yOxnWNcRhrrBW5W+RQJ22EK1SaO8tb3WoUsuEw7mJjBozPzihDFjA==} 1152 + peerDependencies: 1153 + '@types/react': '*' 1154 + '@types/react-dom': '*' 1155 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1156 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1157 + peerDependenciesMeta: 1158 + '@types/react': 1159 + optional: true 1160 + '@types/react-dom': 1161 + optional: true 1162 + 1163 + '@radix-ui/react-id@1.1.0': 1164 + resolution: {integrity: sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==} 1165 + peerDependencies: 1166 + '@types/react': '*' 1167 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1168 + peerDependenciesMeta: 1169 + '@types/react': 1170 + optional: true 1171 + 1109 1172 '@radix-ui/react-label@2.1.1': 1110 1173 resolution: {integrity: sha512-UUw5E4e/2+4kFMH7+YxORXGWggtY6sM8WIwh5RZchhLuUg2H1hc98Py+pr8HMz6rdaYrK2t296ZEjYLOCO5uUw==} 1111 1174 peerDependencies: ··· 1119 1182 '@types/react-dom': 1120 1183 optional: true 1121 1184 1185 + '@radix-ui/react-portal@1.1.3': 1186 + resolution: {integrity: sha512-NciRqhXnGojhT93RPyDaMPfLH3ZSl4jjIFbZQ1b/vxvZEdHsBZ49wP9w8L3HzUQwep01LcWtkUvm0OVB5JAHTw==} 1187 + peerDependencies: 1188 + '@types/react': '*' 1189 + '@types/react-dom': '*' 1190 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1191 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1192 + peerDependenciesMeta: 1193 + '@types/react': 1194 + optional: true 1195 + '@types/react-dom': 1196 + optional: true 1197 + 1198 + '@radix-ui/react-presence@1.1.2': 1199 + resolution: {integrity: sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg==} 1200 + peerDependencies: 1201 + '@types/react': '*' 1202 + '@types/react-dom': '*' 1203 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1204 + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1205 + peerDependenciesMeta: 1206 + '@types/react': 1207 + optional: true 1208 + '@types/react-dom': 1209 + optional: true 1210 + 1122 1211 '@radix-ui/react-primitive@2.0.1': 1123 1212 resolution: {integrity: sha512-sHCWTtxwNn3L3fH8qAfnF3WbUZycW93SM1j3NFDzXBiz8D6F5UTTy8G1+WFEaiCdvCVRJWj6N2R4Xq6HdiHmDg==} 1124 1213 peerDependencies: ··· 1150 1239 '@types/react': 1151 1240 optional: true 1152 1241 1242 + '@radix-ui/react-use-controllable-state@1.1.0': 1243 + resolution: {integrity: sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==} 1244 + peerDependencies: 1245 + '@types/react': '*' 1246 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1247 + peerDependenciesMeta: 1248 + '@types/react': 1249 + optional: true 1250 + 1251 + '@radix-ui/react-use-escape-keydown@1.1.0': 1252 + resolution: {integrity: sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==} 1253 + peerDependencies: 1254 + '@types/react': '*' 1255 + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc 1256 + peerDependenciesMeta: 1257 + '@types/react': 1258 + optional: true 1259 + 1153 1260 '@radix-ui/react-use-layout-effect@1.1.0': 1154 1261 resolution: {integrity: sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==} 1155 1262 peerDependencies: ··· 1492 1599 argparse@2.0.1: 1493 1600 resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} 1494 1601 1602 + aria-hidden@1.2.4: 1603 + resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==} 1604 + engines: {node: '>=10'} 1605 + 1495 1606 array-ify@1.0.0: 1496 1607 resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} 1497 1608 ··· 1545 1656 bun-types@1.1.37: 1546 1657 resolution: {integrity: sha512-C65lv6eBr3LPJWFZ2gswyrGZ82ljnH8flVE03xeXxKhi2ZGtFiO4isRKTKnitbSqtRAcaqYSR6djt1whI66AbA==} 1547 1658 1548 - bun-types@1.1.42: 1549 - resolution: {integrity: sha512-beMbnFqWbbBQHll/bn3phSwmoOQmnX2nt8NI9iOQKFbgR5Z6rlH3YuaMdlid8vp5XGct3/W4QVQBmhoOEoe4nw==} 1659 + bun-types@1.1.43: 1660 + resolution: {integrity: sha512-W0wCtVH+bwFp7p3Zgs03CqxEDmXxEvmmUM/FBKgWIv9T8gyeotvIjIbHzuDScc2DphhRNtr7hJLCR5PspYL5qw==} 1550 1661 1551 1662 callsites@3.1.0: 1552 1663 resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} ··· 1668 1779 detect-libc@2.0.3: 1669 1780 resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} 1670 1781 engines: {node: '>=8'} 1782 + 1783 + detect-node-es@1.1.0: 1784 + resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} 1671 1785 1672 1786 didyoumean@1.2.2: 1673 1787 resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} ··· 1915 2029 resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 1916 2030 engines: {node: 6.* || 8.* || >= 10.*} 1917 2031 2032 + get-nonce@1.0.1: 2033 + resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} 2034 + engines: {node: '>=6'} 2035 + 1918 2036 get-tsconfig@4.8.1: 1919 2037 resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} 1920 2038 ··· 2324 2442 peerDependencies: 2325 2443 react: ^16.8.0 || ^17 || ^18 || ^19 2326 2444 2445 + react-remove-scroll-bar@2.3.8: 2446 + resolution: {integrity: sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==} 2447 + engines: {node: '>=10'} 2448 + peerDependencies: 2449 + '@types/react': '*' 2450 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 2451 + peerDependenciesMeta: 2452 + '@types/react': 2453 + optional: true 2454 + 2455 + react-remove-scroll@2.6.2: 2456 + resolution: {integrity: sha512-KmONPx5fnlXYJQqC62Q+lwIeAk64ws/cUw6omIumRzMRPqgnYqhSSti99nbj0Ry13bv7dF+BKn7NB+OqkdZGTw==} 2457 + engines: {node: '>=10'} 2458 + peerDependencies: 2459 + '@types/react': '*' 2460 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc 2461 + peerDependenciesMeta: 2462 + '@types/react': 2463 + optional: true 2464 + 2465 + react-style-singleton@2.2.3: 2466 + resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==} 2467 + engines: {node: '>=10'} 2468 + peerDependencies: 2469 + '@types/react': '*' 2470 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc 2471 + peerDependenciesMeta: 2472 + '@types/react': 2473 + optional: true 2474 + 2327 2475 react@18.3.1: 2328 2476 resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} 2329 2477 engines: {node: '>=0.10.0'} ··· 2580 2728 peerDependencies: 2581 2729 browserslist: '>= 4.21.0' 2582 2730 2731 + use-callback-ref@1.3.3: 2732 + resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} 2733 + engines: {node: '>=10'} 2734 + peerDependencies: 2735 + '@types/react': '*' 2736 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc 2737 + peerDependenciesMeta: 2738 + '@types/react': 2739 + optional: true 2740 + 2741 + use-sidecar@1.1.3: 2742 + resolution: {integrity: sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==} 2743 + engines: {node: '>=10'} 2744 + peerDependencies: 2745 + '@types/react': '*' 2746 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc 2747 + peerDependenciesMeta: 2748 + '@types/react': 2749 + optional: true 2750 + 2583 2751 use-sync-external-store@1.4.0: 2584 2752 resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} 2585 2753 peerDependencies: ··· 3333 3501 '@pkgjs/parseargs@0.11.0': 3334 3502 optional: true 3335 3503 3504 + '@radix-ui/primitive@1.1.1': {} 3505 + 3336 3506 '@radix-ui/react-avatar@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 3337 3507 dependencies: 3338 3508 '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) ··· 3357 3527 optionalDependencies: 3358 3528 '@types/react': 18.3.18 3359 3529 3530 + '@radix-ui/react-dialog@1.1.4(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 3531 + dependencies: 3532 + '@radix-ui/primitive': 1.1.1 3533 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) 3534 + '@radix-ui/react-context': 1.1.1(@types/react@18.3.18)(react@18.3.1) 3535 + '@radix-ui/react-dismissable-layer': 1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 3536 + '@radix-ui/react-focus-guards': 1.1.1(@types/react@18.3.18)(react@18.3.1) 3537 + '@radix-ui/react-focus-scope': 1.1.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 3538 + '@radix-ui/react-id': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3539 + '@radix-ui/react-portal': 1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 3540 + '@radix-ui/react-presence': 1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 3541 + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 3542 + '@radix-ui/react-slot': 1.1.1(@types/react@18.3.18)(react@18.3.1) 3543 + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3544 + aria-hidden: 1.2.4 3545 + react: 18.3.1 3546 + react-dom: 18.3.1(react@18.3.1) 3547 + react-remove-scroll: 2.6.2(@types/react@18.3.18)(react@18.3.1) 3548 + optionalDependencies: 3549 + '@types/react': 18.3.18 3550 + '@types/react-dom': 18.3.5(@types/react@18.3.18) 3551 + 3552 + '@radix-ui/react-dismissable-layer@1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 3553 + dependencies: 3554 + '@radix-ui/primitive': 1.1.1 3555 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) 3556 + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 3557 + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3558 + '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3559 + react: 18.3.1 3560 + react-dom: 18.3.1(react@18.3.1) 3561 + optionalDependencies: 3562 + '@types/react': 18.3.18 3563 + '@types/react-dom': 18.3.5(@types/react@18.3.18) 3564 + 3565 + '@radix-ui/react-focus-guards@1.1.1(@types/react@18.3.18)(react@18.3.1)': 3566 + dependencies: 3567 + react: 18.3.1 3568 + optionalDependencies: 3569 + '@types/react': 18.3.18 3570 + 3571 + '@radix-ui/react-focus-scope@1.1.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 3572 + dependencies: 3573 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) 3574 + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 3575 + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3576 + react: 18.3.1 3577 + react-dom: 18.3.1(react@18.3.1) 3578 + optionalDependencies: 3579 + '@types/react': 18.3.18 3580 + '@types/react-dom': 18.3.5(@types/react@18.3.18) 3581 + 3582 + '@radix-ui/react-id@1.1.0(@types/react@18.3.18)(react@18.3.1)': 3583 + dependencies: 3584 + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3585 + react: 18.3.1 3586 + optionalDependencies: 3587 + '@types/react': 18.3.18 3588 + 3360 3589 '@radix-ui/react-label@2.1.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 3361 3590 dependencies: 3362 3591 '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ··· 3366 3595 '@types/react': 18.3.18 3367 3596 '@types/react-dom': 18.3.5(@types/react@18.3.18) 3368 3597 3598 + '@radix-ui/react-portal@1.1.3(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 3599 + dependencies: 3600 + '@radix-ui/react-primitive': 2.0.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) 3601 + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3602 + react: 18.3.1 3603 + react-dom: 18.3.1(react@18.3.1) 3604 + optionalDependencies: 3605 + '@types/react': 18.3.18 3606 + '@types/react-dom': 18.3.5(@types/react@18.3.18) 3607 + 3608 + '@radix-ui/react-presence@1.1.2(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 3609 + dependencies: 3610 + '@radix-ui/react-compose-refs': 1.1.1(@types/react@18.3.18)(react@18.3.1) 3611 + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3612 + react: 18.3.1 3613 + react-dom: 18.3.1(react@18.3.1) 3614 + optionalDependencies: 3615 + '@types/react': 18.3.18 3616 + '@types/react-dom': 18.3.5(@types/react@18.3.18) 3617 + 3369 3618 '@radix-ui/react-primitive@2.0.1(@types/react-dom@18.3.5(@types/react@18.3.18))(@types/react@18.3.18)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': 3370 3619 dependencies: 3371 3620 '@radix-ui/react-slot': 1.1.1(@types/react@18.3.18)(react@18.3.1) ··· 3388 3637 optionalDependencies: 3389 3638 '@types/react': 18.3.18 3390 3639 3640 + '@radix-ui/react-use-controllable-state@1.1.0(@types/react@18.3.18)(react@18.3.1)': 3641 + dependencies: 3642 + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3643 + react: 18.3.1 3644 + optionalDependencies: 3645 + '@types/react': 18.3.18 3646 + 3647 + '@radix-ui/react-use-escape-keydown@1.1.0(@types/react@18.3.18)(react@18.3.1)': 3648 + dependencies: 3649 + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.3.18)(react@18.3.1) 3650 + react: 18.3.1 3651 + optionalDependencies: 3652 + '@types/react': 18.3.18 3653 + 3391 3654 '@radix-ui/react-use-layout-effect@1.1.0(@types/react@18.3.18)(react@18.3.1)': 3392 3655 dependencies: 3393 3656 react: 18.3.1 ··· 3684 3947 3685 3948 argparse@2.0.1: {} 3686 3949 3950 + aria-hidden@1.2.4: 3951 + dependencies: 3952 + tslib: 2.8.1 3953 + 3687 3954 array-ify@1.0.0: {} 3688 3955 3689 3956 autoprefixer@10.4.20(postcss@8.4.49): ··· 3753 4020 '@types/node': 20.12.14 3754 4021 '@types/ws': 8.5.13 3755 4022 3756 - bun-types@1.1.42: 4023 + bun-types@1.1.43: 3757 4024 dependencies: 3758 4025 '@types/node': 20.12.14 3759 4026 '@types/ws': 8.5.13 ··· 3864 4131 3865 4132 detect-libc@2.0.3: {} 3866 4133 4134 + detect-node-es@1.1.0: {} 4135 + 3867 4136 didyoumean@1.2.2: {} 3868 4137 3869 4138 dlv@1.1.3: {} ··· 3881 4150 transitivePeerDependencies: 3882 4151 - supports-color 3883 4152 3884 - drizzle-orm@0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.42)(react@18.3.1): 4153 + drizzle-orm@0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.43)(react@18.3.1): 3885 4154 optionalDependencies: 3886 4155 '@types/react': 18.3.18 3887 4156 better-sqlite3: 11.7.0 3888 - bun-types: 1.1.42 4157 + bun-types: 1.1.43 3889 4158 react: 18.3.1 3890 4159 3891 - drizzle-typebox@0.2.1(@sinclair/typebox@0.34.13)(drizzle-orm@0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.42)(react@18.3.1)): 4160 + drizzle-typebox@0.2.1(@sinclair/typebox@0.34.13)(drizzle-orm@0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.43)(react@18.3.1)): 3892 4161 dependencies: 3893 4162 '@sinclair/typebox': 0.34.13 3894 - drizzle-orm: 0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.42)(react@18.3.1) 4163 + drizzle-orm: 0.38.3(@types/react@18.3.18)(better-sqlite3@11.7.0)(bun-types@1.1.43)(react@18.3.1) 3895 4164 3896 4165 eastasianwidth@0.2.0: {} 3897 4166 ··· 4093 4362 gensync@1.0.0-beta.2: {} 4094 4363 4095 4364 get-caller-file@2.0.5: {} 4365 + 4366 + get-nonce@1.0.1: {} 4096 4367 4097 4368 get-tsconfig@4.8.1: 4098 4369 dependencies: ··· 4431 4702 dependencies: 4432 4703 react: 18.3.1 4433 4704 4705 + react-remove-scroll-bar@2.3.8(@types/react@18.3.18)(react@18.3.1): 4706 + dependencies: 4707 + react: 18.3.1 4708 + react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) 4709 + tslib: 2.8.1 4710 + optionalDependencies: 4711 + '@types/react': 18.3.18 4712 + 4713 + react-remove-scroll@2.6.2(@types/react@18.3.18)(react@18.3.1): 4714 + dependencies: 4715 + react: 18.3.1 4716 + react-remove-scroll-bar: 2.3.8(@types/react@18.3.18)(react@18.3.1) 4717 + react-style-singleton: 2.2.3(@types/react@18.3.18)(react@18.3.1) 4718 + tslib: 2.8.1 4719 + use-callback-ref: 1.3.3(@types/react@18.3.18)(react@18.3.1) 4720 + use-sidecar: 1.1.3(@types/react@18.3.18)(react@18.3.1) 4721 + optionalDependencies: 4722 + '@types/react': 18.3.18 4723 + 4724 + react-style-singleton@2.2.3(@types/react@18.3.18)(react@18.3.1): 4725 + dependencies: 4726 + get-nonce: 1.0.1 4727 + react: 18.3.1 4728 + tslib: 2.8.1 4729 + optionalDependencies: 4730 + '@types/react': 18.3.18 4731 + 4434 4732 react@18.3.1: 4435 4733 dependencies: 4436 4734 loose-envify: 1.4.0 ··· 4703 5001 browserslist: 4.24.3 4704 5002 escalade: 3.2.0 4705 5003 picocolors: 1.1.1 5004 + 5005 + use-callback-ref@1.3.3(@types/react@18.3.18)(react@18.3.1): 5006 + dependencies: 5007 + react: 18.3.1 5008 + tslib: 2.8.1 5009 + optionalDependencies: 5010 + '@types/react': 18.3.18 5011 + 5012 + use-sidecar@1.1.3(@types/react@18.3.18)(react@18.3.1): 5013 + dependencies: 5014 + detect-node-es: 1.1.0 5015 + react: 18.3.1 5016 + tslib: 2.8.1 5017 + optionalDependencies: 5018 + '@types/react': 18.3.18 4706 5019 4707 5020 use-sync-external-store@1.4.0(react@18.3.1): 4708 5021 dependencies: