diff --git a/apps/dashboard/app/(app)/settings/billing/stripe/success/page.tsx b/apps/dashboard/app/(app)/settings/billing/stripe/success/page.tsx index 7618ed7fe..c36fa7b35 100644 --- a/apps/dashboard/app/(app)/settings/billing/stripe/success/page.tsx +++ b/apps/dashboard/app/(app)/settings/billing/stripe/success/page.tsx @@ -5,7 +5,6 @@ import { getTenantId } from "@/lib/auth"; import { db, eq, schema } from "@/lib/db"; import { stripeEnv } from "@/lib/env"; import { PostHogClient } from "@/lib/posthog"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { currentUser } from "@clerk/nextjs"; import { defaultProSubscriptions } from "@unkey/billing"; import { headers } from "next/headers"; @@ -114,22 +113,6 @@ export default async function StripeSuccess(props: Props) { userAgent: h.get("user-agent") ?? undefined, }, }); - await ingestAuditLogsTinybird({ - workspaceId: ws.id, - actor: { type: "user", id: user.id }, - event: "workspace.update", - description: "Changed plan to 'pro'", - resources: [ - { - type: "workspace", - id: ws.id, - }, - ], - context: { - location: h.get("x-forwarded-for") ?? process.env.VERCEL_REGION ?? "unknown", - userAgent: h.get("user-agent") ?? undefined, - }, - }); } }); diff --git a/apps/dashboard/app/new/page.tsx b/apps/dashboard/app/new/page.tsx index 68aaaf0ea..d67692f0e 100644 --- a/apps/dashboard/app/new/page.tsx +++ b/apps/dashboard/app/new/page.tsx @@ -3,7 +3,6 @@ import { Button } from "@/components/ui/button"; import { Separator } from "@/components/ui/separator"; import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { auth } from "@clerk/nextjs"; import { newId } from "@unkey/id"; import { ArrowRight, DatabaseZap, GlobeLock, KeySquare } from "lucide-react"; @@ -251,26 +250,6 @@ export default async function (props: Props) { }, }); }); - await ingestAuditLogsTinybird({ - workspaceId: workspaceId, - event: "workspace.create", - actor: { - type: "user", - id: userId, - }, - description: `Created ${workspaceId}`, - resources: [ - { - type: "workspace", - id: workspaceId, - }, - ], - - context: { - userAgent: headers().get("user-agent") ?? undefined, - location: headers().get("x-forwarded-for") ?? process.env.VERCEL_REGION ?? "unknown", - }, - }); return redirect(`/new?workspaceId=${workspaceId}`); } diff --git a/apps/dashboard/lib/tinybird.ts b/apps/dashboard/lib/tinybird.ts index 9240e2302..37c561a47 100644 --- a/apps/dashboard/lib/tinybird.ts +++ b/apps/dashboard/lib/tinybird.ts @@ -1,10 +1,7 @@ -import { time } from "node:console"; import { env } from "@/lib/env"; import { NoopTinybird, Tinybird } from "@chronark/zod-bird"; -import { newId } from "@unkey/id"; -import { auditLogSchemaV1, unkeyAuditLogEvents } from "@unkey/schema/src/auditlog"; +import type { unkeyAuditLogEvents } from "@unkey/schema/src/auditlog"; import { z } from "zod"; -import type { MaybeArray } from "./types"; const token = env().TINYBIRD_TOKEN; const tb = token ? new Tinybird({ token }) : new NoopTinybird(); @@ -504,32 +501,6 @@ export type UnkeyAuditLog = { }; }; -export function ingestAuditLogsTinybird(logs: MaybeArray) { - if (Array.isArray(logs) && logs.length === 0) { - return Promise.resolve(); - } - return tb.buildIngestEndpoint({ - datasource: "audit_logs__v2", - event: auditLogSchemaV1 - .merge( - z.object({ - event: unkeyAuditLogEvents, - auditLogId: z.string().default(newId("auditLog")), - bucket: z.string().default("unkey_mutations"), - time: z.number().default(Date.now()), - }), - ) - .transform((l) => ({ - ...l, - actor: { - ...l.actor, - meta: l.actor.meta ? JSON.stringify(l.actor.meta) : undefined, - }, - resources: JSON.stringify(l.resources), - })), - })(logs); -} - export const getRatelimitsHourly = tb.buildPipe({ pipe: "get_ratelimits_hourly__v1", parameters: z.object({ diff --git a/apps/dashboard/lib/trpc/routers/api/create.ts b/apps/dashboard/lib/trpc/routers/api/create.ts index 043fde9a6..434b618b8 100644 --- a/apps/dashboard/lib/trpc/routers/api/create.ts +++ b/apps/dashboard/lib/trpc/routers/api/create.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { newId } from "@unkey/id"; @@ -90,25 +89,6 @@ export const createApi = rateLimitedProcedure(ratelimit.create) userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: ws.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "api.create", - description: `Created ${apiId}`, - resources: [ - { - type: "api", - id: apiId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); return { diff --git a/apps/dashboard/lib/trpc/routers/api/delete.ts b/apps/dashboard/lib/trpc/routers/api/delete.ts index 965f0cd3d..087e3531d 100644 --- a/apps/dashboard/lib/trpc/routers/api/delete.ts +++ b/apps/dashboard/lib/trpc/routers/api/delete.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const deleteApi = rateLimitedProcedure(ratelimit.delete) @@ -66,25 +65,6 @@ export const deleteApi = rateLimitedProcedure(ratelimit.delete) userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: api.workspaceId, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "api.delete", - description: `Deleted ${api.id}`, - resources: [ - { - type: "api", - id: api.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); const keyIds = await tx.query.keys.findMany({ where: eq(schema.keys.keyAuthId, api.keyAuthId!), @@ -122,34 +102,6 @@ export const deleteApi = rateLimitedProcedure(ratelimit.delete) }, })), ); - await ingestAuditLogsTinybird( - keyIds.map(({ id }) => ({ - workspaceId: api.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.delete", - description: `Deleted ${id} as part of the ${api.id} deletion`, - resources: [ - { - type: "api", - id: api.id, - }, - { - type: "key", - id: id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - })), - ).catch((err) => { - tx.rollback(); - throw err; - }); } }); } catch (_err) { diff --git a/apps/dashboard/lib/trpc/routers/api/updateDeleteProtection.ts b/apps/dashboard/lib/trpc/routers/api/updateDeleteProtection.ts index 6780e7194..2306ca17b 100644 --- a/apps/dashboard/lib/trpc/routers/api/updateDeleteProtection.ts +++ b/apps/dashboard/lib/trpc/routers/api/updateDeleteProtection.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const updateAPIDeleteProtection = rateLimitedProcedure(ratelimit.update) @@ -76,28 +75,4 @@ export const updateAPIDeleteProtection = rateLimitedProcedure(ratelimit.update) }, }); }); - await ingestAuditLogsTinybird({ - workspaceId: api.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "api.update", - description: `API ${api.name} delete protection is now ${ - input.enabled ? "enabled" : "disabled" - }.}`, - resources: [ - { - type: "api", - id: api.id, - meta: { - deleteProtection: input.enabled, - }, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/api/updateIpWhitelist.ts b/apps/dashboard/lib/trpc/routers/api/updateIpWhitelist.ts index 27b26d86f..b7dc45041 100644 --- a/apps/dashboard/lib/trpc/routers/api/updateIpWhitelist.ts +++ b/apps/dashboard/lib/trpc/routers/api/updateIpWhitelist.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const updateApiIpWhitelist = rateLimitedProcedure(ratelimit.update) @@ -88,23 +87,4 @@ export const updateApiIpWhitelist = rateLimitedProcedure(ratelimit.update) }, }); }); - await ingestAuditLogsTinybird({ - workspaceId: api.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "api.update", - description: `Changed ${api.id} IP whitelist from ${api.ipWhitelist} to ${newIpWhitelist}`, - resources: [ - { - type: "api", - id: api.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/api/updateName.ts b/apps/dashboard/lib/trpc/routers/api/updateName.ts index f493de233..a054eefd4 100644 --- a/apps/dashboard/lib/trpc/routers/api/updateName.ts +++ b/apps/dashboard/lib/trpc/routers/api/updateName.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const updateApiName = rateLimitedProcedure(ratelimit.update) @@ -71,23 +70,4 @@ export const updateApiName = rateLimitedProcedure(ratelimit.update) }, }); }); - await ingestAuditLogsTinybird({ - workspaceId: api.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "api.update", - description: `Changed ${api.id} name from ${api.name} to ${input.name}`, - resources: [ - { - type: "api", - id: api.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/key/create.ts b/apps/dashboard/lib/trpc/routers/key/create.ts index 445188ef6..0c7f9f5a2 100644 --- a/apps/dashboard/lib/trpc/routers/key/create.ts +++ b/apps/dashboard/lib/trpc/routers/key/create.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; @@ -134,22 +133,5 @@ export const createKey = rateLimitedProcedure(ratelimit.create) }); }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "key.create", - description: `Created ${keyId}`, - resources: [ - { - type: "key", - id: keyId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); - return { keyId, key }; }); diff --git a/apps/dashboard/lib/trpc/routers/key/createRootKey.ts b/apps/dashboard/lib/trpc/routers/key/createRootKey.ts index bc845eb2e..6761ca577 100644 --- a/apps/dashboard/lib/trpc/routers/key/createRootKey.ts +++ b/apps/dashboard/lib/trpc/routers/key/createRootKey.ts @@ -1,6 +1,6 @@ import { db, eq, schema } from "@/lib/db"; import { env } from "@/lib/env"; -import { type UnkeyAuditLog, ingestAuditLogsTinybird } from "@/lib/tinybird"; +import type { UnkeyAuditLog } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; @@ -197,7 +197,5 @@ export const createRootKey = rateLimitedProcedure(ratelimit.create) }); } - await ingestAuditLogsTinybird(auditLogs); - return { key, keyId }; }); diff --git a/apps/dashboard/lib/trpc/routers/key/delete.ts b/apps/dashboard/lib/trpc/routers/key/delete.ts index 0d7dbb56c..9b207328f 100644 --- a/apps/dashboard/lib/trpc/routers/key/delete.ts +++ b/apps/dashboard/lib/trpc/routers/key/delete.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { and, db, eq, inArray, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -82,23 +81,4 @@ export const deleteKeys = rateLimitedProcedure(ratelimit.delete) "We are unable to delete the key. Please contact support using support@unkey.dev", }); }); - - await ingestAuditLogsTinybird( - workspace.keys.map((key) => ({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "key.delete", - description: `Deleted ${key.id}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - })), - ); }); diff --git a/apps/dashboard/lib/trpc/routers/key/deleteRootKey.ts b/apps/dashboard/lib/trpc/routers/key/deleteRootKey.ts index 7c5758013..8e7d81a75 100644 --- a/apps/dashboard/lib/trpc/routers/key/deleteRootKey.ts +++ b/apps/dashboard/lib/trpc/routers/key/deleteRootKey.ts @@ -1,7 +1,6 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, inArray, schema } from "@/lib/db"; import { env } from "@/lib/env"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -84,23 +83,4 @@ export const deleteRootKeys = rateLimitedProcedure(ratelimit.delete) "We are unable to delete the root key. Please contact support using support@unkey.dev", }); }); - - await ingestAuditLogsTinybird( - rootKeys.map((key) => ({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "key.delete", - description: `Deleted ${key.id}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - })), - ); }); diff --git a/apps/dashboard/lib/trpc/routers/key/updateEnabled.ts b/apps/dashboard/lib/trpc/routers/key/updateEnabled.ts index 5389ca2cc..92a5ced6a 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateEnabled.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateEnabled.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -70,23 +69,4 @@ export const updateKeyEnabled = rateLimitedProcedure(ratelimit.update) }, }); }); - await ingestAuditLogsTinybird({ - workspaceId: key.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: `${input.enabled ? "Enabled" : "Disabled"} ${key.id}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/key/updateExpiration.ts b/apps/dashboard/lib/trpc/routers/key/updateExpiration.ts index d99250e33..c49f677fd 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateExpiration.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateExpiration.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -95,28 +94,5 @@ export const updateKeyExpiration = rateLimitedProcedure(ratelimit.update) }); }); - await ingestAuditLogsTinybird({ - workspaceId: key.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: `${ - input.expiration - ? `Changed expiration of ${key.id} to ${input.expiration.toUTCString()}` - : `Disabled expiration for ${key.id}` - }`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); return true; }); diff --git a/apps/dashboard/lib/trpc/routers/key/updateMetadata.ts b/apps/dashboard/lib/trpc/routers/key/updateMetadata.ts index d8ae50db0..949f02acd 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateMetadata.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateMetadata.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -84,24 +83,5 @@ export const updateKeyMetadata = rateLimitedProcedure(ratelimit.update) }); }); - await ingestAuditLogsTinybird({ - workspaceId: key.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: `Updated metadata of ${key.id}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); return true; }); diff --git a/apps/dashboard/lib/trpc/routers/key/updateName.ts b/apps/dashboard/lib/trpc/routers/key/updateName.ts index bcf372b9e..23ab0d1a9 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateName.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateName.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -72,24 +71,5 @@ export const updateKeyName = rateLimitedProcedure(ratelimit.update) }); }); - await ingestAuditLogsTinybird({ - workspaceId: key.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: `Changed name of ${key.id} to ${input.name}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); return true; }); diff --git a/apps/dashboard/lib/trpc/routers/key/updateOwnerId.ts b/apps/dashboard/lib/trpc/routers/key/updateOwnerId.ts index 41c557477..7fb8a5b80 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateOwnerId.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateOwnerId.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -72,25 +71,5 @@ export const updateKeyOwnerId = rateLimitedProcedure(ratelimit.update) }); }); - await ingestAuditLogsTinybird({ - workspaceId: key.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: `Changed ownerId of ${key.id} to ${input.ownerId}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); - return true; }); diff --git a/apps/dashboard/lib/trpc/routers/key/updateRatelimit.ts b/apps/dashboard/lib/trpc/routers/key/updateRatelimit.ts index 9c74a9f0b..24583f4ed 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateRatelimit.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateRatelimit.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -86,38 +85,6 @@ export const updateKeyRatelimit = rateLimitedProcedure(ratelimit.update) }, }); }); - - await ingestAuditLogsTinybird({ - workspaceId: key.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: `Changed ratelimit of ${key.id}`, - resources: [ - { - type: "key", - id: key.id, - meta: { - "ratelimit.async": ratelimitAsync, - "ratelimit.limit": ratelimitLimit, - "ratelimit.duration": ratelimitDuration, - }, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }).catch((err) => { - console.error(err); - throw new TRPCError({ - code: "INTERNAL_SERVER_ERROR", - message: - "We were unable to update ratelimit on this key. Please contact support using support@unkey.dev", - }); - }); } else { await db .transaction(async (tx) => { @@ -158,25 +125,5 @@ export const updateKeyRatelimit = rateLimitedProcedure(ratelimit.update) "We were unable to update ratelimit on this key. Please contact support using support@unkey.dev", }); }); - - await ingestAuditLogsTinybird({ - workspaceId: key.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: `Disabled ratelimit of ${key.id}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); } }); diff --git a/apps/dashboard/lib/trpc/routers/key/updateRemaining.ts b/apps/dashboard/lib/trpc/routers/key/updateRemaining.ts index 6dde718bf..fdfdd249f 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateRemaining.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateRemaining.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -87,29 +86,6 @@ export const updateKeyRemaining = rateLimitedProcedure(ratelimit.update) userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: key.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: input.limitEnabled - ? `Changed remaining for ${key.id} to remaining=${input.remaining}, refill=${ - input.refill ? `${input.refill.amount}@${input.refill.interval}` : "none" - }` - : `Disabled limit for ${key.id}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }) .catch((err) => { console.error(err); diff --git a/apps/dashboard/lib/trpc/routers/key/updateRootKeyName.ts b/apps/dashboard/lib/trpc/routers/key/updateRootKeyName.ts index 36f4b4c3f..79c4978e0 100644 --- a/apps/dashboard/lib/trpc/routers/key/updateRootKeyName.ts +++ b/apps/dashboard/lib/trpc/routers/key/updateRootKeyName.ts @@ -1,7 +1,6 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; import { env } from "@/lib/env"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; import { auth, t } from "../../trpc"; @@ -83,24 +82,4 @@ export const updateRootKeyName = t.procedure }, }); }); - - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "key.update", - description: `Changed name of ${key.id} to ${input.name}`, - resources: [ - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/llmGateway/create.ts b/apps/dashboard/lib/trpc/routers/llmGateway/create.ts index 53366df2a..01511d64e 100644 --- a/apps/dashboard/lib/trpc/routers/llmGateway/create.ts +++ b/apps/dashboard/lib/trpc/routers/llmGateway/create.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { DatabaseError } from "@planetscale/database"; import { TRPCError } from "@trpc/server"; @@ -78,26 +77,6 @@ export const createLlmGateway = rateLimitedProcedure(ratelimit.create) }); }); - await ingestAuditLogsTinybird({ - workspaceId: ws.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "llmGateway.create", - description: `Created ${llmGatewayId}`, - resources: [ - { - type: "gateway", - id: llmGatewayId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); - return { id: llmGatewayId, }; diff --git a/apps/dashboard/lib/trpc/routers/llmGateway/delete.ts b/apps/dashboard/lib/trpc/routers/llmGateway/delete.ts index 991eba0cd..6b9467eb0 100644 --- a/apps/dashboard/lib/trpc/routers/llmGateway/delete.ts +++ b/apps/dashboard/lib/trpc/routers/llmGateway/delete.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const deleteLlmGateway = rateLimitedProcedure(ratelimit.delete) @@ -67,25 +66,6 @@ export const deleteLlmGateway = rateLimitedProcedure(ratelimit.delete) }, }); }); - await ingestAuditLogsTinybird({ - workspaceId: llmGateway.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "llmGateway.delete", - description: `Deleted ${llmGateway.id}`, - resources: [ - { - type: "gateway", - id: llmGateway.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); return { id: llmGateway.id, diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts b/apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts index 0489b3b45..d626aba58 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/createNamespace.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { DatabaseError } from "@planetscale/database"; import { newId } from "@unkey/id"; @@ -79,26 +78,6 @@ export const createNamespace = rateLimitedProcedure(ratelimit.create) }); }); - await ingestAuditLogsTinybird({ - workspaceId: ws.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "ratelimitNamespace.create", - description: `Created ${namespaceId}`, - resources: [ - { - type: "ratelimitNamespace", - id: namespaceId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); - return { id: namespaceId, }; diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts b/apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts index 23d1855ed..021361c84 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/createOverride.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { and, db, eq, isNull, schema, sql } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { newId } from "@unkey/id"; @@ -113,30 +112,6 @@ export const createOverride = rateLimitedProcedure(ratelimit.create) }); }); - await ingestAuditLogsTinybird({ - workspaceId: namespace.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "ratelimitOverride.create", - description: `Created ${input.identifier}`, - resources: [ - { - type: "ratelimitNamespace", - id: input.namespaceId, - }, - { - type: "ratelimitOverride", - id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); - return { id, }; diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/deleteNamespace.ts b/apps/dashboard/lib/trpc/routers/ratelimit/deleteNamespace.ts index f15b66c6b..dcdbed62b 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/deleteNamespace.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/deleteNamespace.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const deleteNamespace = rateLimitedProcedure(ratelimit.delete) @@ -67,25 +66,6 @@ export const deleteNamespace = rateLimitedProcedure(ratelimit.delete) userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: namespace.workspaceId, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "ratelimitNamespace.delete", - description: `Deleted ${namespace.id}`, - resources: [ - { - type: "ratelimitNamespace", - id: namespace.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); const overrides = await tx.query.ratelimitOverrides.findMany({ where: (table, { eq }) => eq(table.namespaceId, namespace.id), @@ -130,34 +110,6 @@ export const deleteNamespace = rateLimitedProcedure(ratelimit.delete) }, })), ); - await ingestAuditLogsTinybird( - overrides.map(({ id }) => ({ - workspaceId: namespace.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "ratelimitOverride.delete", - description: `Deleted ${id} as part of the ${namespace.id} deletion`, - resources: [ - { - type: "ratelimitNamespace", - id: namespace.id, - }, - { - type: "ratelimitOverride", - id: id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - })), - ).catch((err) => { - tx.rollback(); - throw err; - }); } }); }); diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/deleteOverride.ts b/apps/dashboard/lib/trpc/routers/ratelimit/deleteOverride.ts index d5e432fe6..795dac6a4 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/deleteOverride.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/deleteOverride.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const deleteOverride = rateLimitedProcedure(ratelimit.create) @@ -84,28 +83,4 @@ export const deleteOverride = rateLimitedProcedure(ratelimit.create) }, }); }); - - await ingestAuditLogsTinybird({ - workspaceId: override.namespace.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "ratelimitOverride.delete", - description: `Deleted ${override.id}`, - resources: [ - { - type: "ratelimitNamespace", - id: override.namespace.id, - }, - { - type: "ratelimitOverride", - id: override.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/updateNamespaceName.ts b/apps/dashboard/lib/trpc/routers/ratelimit/updateNamespaceName.ts index 3dc1d50d0..8a147a9f9 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/updateNamespaceName.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/updateNamespaceName.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const updateNamespaceName = rateLimitedProcedure(ratelimit.update) @@ -84,23 +83,4 @@ export const updateNamespaceName = rateLimitedProcedure(ratelimit.update) }, }); }); - await ingestAuditLogsTinybird({ - workspaceId: ws.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "ratelimitNamespace.update", - description: `Changed ${namespace.id} name from ${namespace.name} to ${input.name}`, - resources: [ - { - type: "ratelimitNamespace", - id: namespace.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/ratelimit/updateOverride.ts b/apps/dashboard/lib/trpc/routers/ratelimit/updateOverride.ts index 1685fac9c..a2ce58f00 100644 --- a/apps/dashboard/lib/trpc/routers/ratelimit/updateOverride.ts +++ b/apps/dashboard/lib/trpc/routers/ratelimit/updateOverride.ts @@ -3,7 +3,6 @@ import { z } from "zod"; import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; export const updateOverride = rateLimitedProcedure(ratelimit.update) @@ -92,28 +91,4 @@ export const updateOverride = rateLimitedProcedure(ratelimit.update) }, }); }); - - await ingestAuditLogsTinybird({ - workspaceId: override.namespace.workspace.id, - actor: { - type: "user", - id: ctx.user.id, - }, - event: "ratelimitOverride.update", - description: `Changed ${override.id} limits from ${override.limit}/${override.duration} to ${input.limit}/${input.duration}`, - resources: [ - { - type: "ratelimitNamespace", - id: override.namespace.id, - }, - { - type: "ratelimitOverride", - id: override.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac.ts b/apps/dashboard/lib/trpc/routers/rbac.ts index dc0e3cc0d..0fef9a8a5 100644 --- a/apps/dashboard/lib/trpc/routers/rbac.ts +++ b/apps/dashboard/lib/trpc/routers/rbac.ts @@ -1,7 +1,7 @@ import { type Permission, and, db, eq, schema } from "@/lib/db"; import { insertAuditLogs } from "@/lib/audit"; -import { type UnkeyAuditLog, ingestAuditLogsTinybird } from "@/lib/tinybird"; +import type { UnkeyAuditLog } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; @@ -79,7 +79,6 @@ export const rbacRouter = t.router({ .onDuplicateKeyUpdate({ set: { permissionId: permissions[0].id } }); await insertAuditLogs(tx, auditLogs); }); - await ingestAuditLogsTinybird(auditLogs); }), removePermissionFromRootKey: rateLimitedProcedure(ratelimit.update) .input( @@ -436,26 +435,6 @@ export const rbacRouter = t.router({ location: ctx.audit.location, }, }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - event: "role.create", - actor: { - type: "user", - id: ctx.user.id, - }, - description: `Created ${roleId}`, - resources: [ - { - type: "role", - id: roleId, - }, - ], - - context: { - userAgent: ctx.audit.userAgent, - location: ctx.audit.location, - }, - }); if (input.permissionIds && input.permissionIds.length > 0) { await tx.insert(schema.rolesPermissions).values( @@ -489,29 +468,6 @@ export const rbacRouter = t.router({ }, })), ); - await ingestAuditLogsTinybird( - input.permissionIds.map((permissionId) => ({ - workspaceId: workspace.id, - event: "authorization.connect_role_and_permission", - actor: { - type: "user", - id: ctx.user.id, - }, - description: `Connected ${roleId} and ${permissionId}`, - resources: [ - { type: "role", id: roleId }, - { - type: "permission", - id: permissionId, - }, - ], - - context: { - userAgent: ctx.audit.userAgent, - location: ctx.audit.location, - }, - })), - ); } }); return { roleId }; @@ -666,26 +622,6 @@ export const rbacRouter = t.router({ }, }); }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - event: "permission.create", - actor: { - type: "user", - id: ctx.user.id, - }, - description: `Created ${permissionId}`, - resources: [ - { - type: "permission", - id: permissionId, - }, - ], - - context: { - userAgent: ctx.audit.userAgent, - location: ctx.audit.location, - }, - }); return { permissionId }; }), diff --git a/apps/dashboard/lib/trpc/routers/rbac/addPermissionToRootKey.ts b/apps/dashboard/lib/trpc/routers/rbac/addPermissionToRootKey.ts index cd7e19565..3ed8fa5ed 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/addPermissionToRootKey.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/addPermissionToRootKey.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { unkeyPermissionValidation } from "@unkey/rbac"; @@ -106,27 +105,4 @@ export const addPermissionToRootKey = rateLimitedProcedure(ratelimit.create) }, ]); }); - await ingestAuditLogsTinybird([ - ...auditLogs, - { - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "authorization.connect_permission_and_key", - description: `Attached ${p.id} to ${rootKey.id}`, - resources: [ - { - type: "key", - id: rootKey.id, - }, - { - type: "permission", - id: p.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }, - ]); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/connectRoleToKey.ts b/apps/dashboard/lib/trpc/routers/rbac/connectRoleToKey.ts index 631ad8e7f..280966704 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/connectRoleToKey.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/connectRoleToKey.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -97,25 +96,4 @@ export const connectRoleToKey = rateLimitedProcedure(ratelimit.update) }, }); }); - - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "authorization.connect_role_and_key", - description: `Connect role ${role.id} to ${key.id}`, - resources: [ - { - type: "role", - id: role.id, - }, - { - type: "key", - id: key.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/createPermission.ts b/apps/dashboard/lib/trpc/routers/rbac/createPermission.ts index 5bf352c8e..af87eb79c 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/createPermission.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/createPermission.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; @@ -79,26 +78,6 @@ export const createPermission = rateLimitedProcedure(ratelimit.create) "We are unable to create a permission. Please contact support using support@unkey.dev.", }); }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - event: "permission.create", - actor: { - type: "user", - id: ctx.user.id, - }, - description: `Created ${permissionId}`, - resources: [ - { - type: "permission", - id: permissionId, - }, - ], - - context: { - userAgent: ctx.audit.userAgent, - location: ctx.audit.location, - }, - }); return { permissionId }; }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/createRole.ts b/apps/dashboard/lib/trpc/routers/rbac/createRole.ts index 6714ec0a2..ba6a50543 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/createRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/createRole.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; @@ -79,26 +78,6 @@ export const createRole = rateLimitedProcedure(ratelimit.create) location: ctx.audit.location, }, }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - event: "role.create", - actor: { - type: "user", - id: ctx.user.id, - }, - description: `Created ${roleId}`, - resources: [ - { - type: "role", - id: roleId, - }, - ], - - context: { - userAgent: ctx.audit.userAgent, - location: ctx.audit.location, - }, - }); if (input.permissionIds && input.permissionIds.length > 0) { await tx.insert(schema.rolesPermissions).values( @@ -132,29 +111,6 @@ export const createRole = rateLimitedProcedure(ratelimit.create) }, })), ); - await ingestAuditLogsTinybird( - input.permissionIds.map((permissionId) => ({ - workspaceId: workspace.id, - event: "authorization.connect_role_and_permission", - actor: { - type: "user", - id: ctx.user.id, - }, - description: `Connected ${roleId} and ${permissionId}`, - resources: [ - { type: "role", id: roleId }, - { - type: "permission", - id: permissionId, - }, - ], - - context: { - userAgent: ctx.audit.userAgent, - location: ctx.audit.location, - }, - })), - ); } }); return { roleId }; diff --git a/apps/dashboard/lib/trpc/routers/rbac/deletePermission.ts b/apps/dashboard/lib/trpc/routers/rbac/deletePermission.ts index de290538c..a7fa53ebf 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/deletePermission.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/deletePermission.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { and, db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -79,21 +78,4 @@ export const deletePermission = rateLimitedProcedure(ratelimit.delete) "We are unable to delete the permission. Please contact support using support@unkey.dev", }); }); - - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "permission.delete", - description: `Deleted permission ${input.permissionId}`, - resources: [ - { - type: "permission", - id: input.permissionId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/deleteRole.ts b/apps/dashboard/lib/trpc/routers/rbac/deleteRole.ts index 845e93f9e..8fff0110a 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/deleteRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/deleteRole.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { and, db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -71,21 +70,4 @@ export const deleteRole = rateLimitedProcedure(ratelimit.delete) }, }); }); - - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "role.delete", - description: `Deleted role ${input.roleId}`, - resources: [ - { - type: "role", - id: input.roleId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/disconnectPermissionFromRole.ts b/apps/dashboard/lib/trpc/routers/rbac/disconnectPermissionFromRole.ts index d483bf778..1b130b8e0 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/disconnectPermissionFromRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/disconnectPermissionFromRole.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { and, db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -72,25 +71,4 @@ export const disconnectPermissionFromRole = rateLimitedProcedure(ratelimit.updat "We are unable to disconnect the permission from the role. Please contact support using support@unkey.dev", }); }); - - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "authorization.disconnect_role_and_permissions", - description: `Disconnect role ${input.roleId} from permission ${input.permissionId}`, - resources: [ - { - type: "role", - id: input.roleId, - }, - { - type: "permission", - id: input.permissionId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/disconnectRoleFromKey.ts b/apps/dashboard/lib/trpc/routers/rbac/disconnectRoleFromKey.ts index 6f8e3c1a4..48caddfb4 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/disconnectRoleFromKey.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/disconnectRoleFromKey.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { and, db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -72,25 +71,4 @@ export const disconnectRoleFromKey = rateLimitedProcedure(ratelimit.update) "We are unable to disconnect the role from the key. Please contact support using support@unkey.dev", }); }); - - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "authorization.disconnect_role_and_key", - description: `Disconnect role ${input.roleId} from ${input.keyId}`, - resources: [ - { - type: "role", - id: input.roleId, - }, - { - type: "key", - id: input.keyId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/removePermissionFromRootKey.ts b/apps/dashboard/lib/trpc/routers/rbac/removePermissionFromRootKey.ts index 5e055cbd4..511717e1c 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/removePermissionFromRootKey.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/removePermissionFromRootKey.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { and, db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -107,25 +106,4 @@ export const removePermissionFromRootKey = rateLimitedProcedure(ratelimit.update "We are unable to remove permission from the root key. Please contact support using support@unkey.dev", }); }); - - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "authorization.disconnect_permission_and_key", - description: `Disconnect ${input.permissionName} from ${input.rootKeyId}`, - resources: [ - { - type: "permission", - id: input.permissionName, - }, - { - type: "key", - id: input.rootKeyId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts b/apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts index 480e6ad3f..a0b84d315 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/updatePermission.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -91,20 +90,4 @@ export const updatePermission = rateLimitedProcedure(ratelimit.update) "We are unable to update the permission. Please contact support using support@unkey.dev.", }); }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "permission.update", - description: `Update permission ${input.id}`, - resources: [ - { - type: "permission", - id: input.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/updateRole.ts b/apps/dashboard/lib/trpc/routers/rbac/updateRole.ts index 455166eef..d09d9a306 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/updateRole.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/updateRole.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -83,21 +82,4 @@ export const updateRole = rateLimitedProcedure(ratelimit.update) "We are unable to update the role. Please contact support using support@unkey.dev.", }); }); - - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "role.update", - description: `Updated role ${input.id}`, - resources: [ - { - type: "role", - id: input.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/lib/trpc/routers/rbac/upsertPermission.ts b/apps/dashboard/lib/trpc/routers/rbac/upsertPermission.ts index 028bb33ab..b903ba151 100644 --- a/apps/dashboard/lib/trpc/routers/rbac/upsertPermission.ts +++ b/apps/dashboard/lib/trpc/routers/rbac/upsertPermission.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { type Permission, db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import type { Context } from "../../context"; @@ -62,22 +61,7 @@ export async function upsertPermission( userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId, - actor: { type: "user", id: ctx.user!.id }, - event: "permission.create", - description: `Created ${permission.id}`, - resources: [ - { - type: "permission", - id: permission.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); + return permission; }); } diff --git a/apps/dashboard/lib/trpc/routers/vercel.ts b/apps/dashboard/lib/trpc/routers/vercel.ts index 625ccafda..ce5d7ffee 100644 --- a/apps/dashboard/lib/trpc/routers/vercel.ts +++ b/apps/dashboard/lib/trpc/routers/vercel.ts @@ -1,14 +1,12 @@ import { insertAuditLogs } from "@/lib/audit"; import { type VercelBinding, and, db, eq, schema } from "@/lib/db"; import { env } from "@/lib/env"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { TRPCError } from "@trpc/server"; import { newId } from "@unkey/id"; import { newKey } from "@unkey/keys"; import { Vercel } from "@unkey/vercel"; import { z } from "zod"; import { auth, t } from "../trpc"; - export const vercelRouter = t.router({ setupProject: t.procedure .use(auth) @@ -95,26 +93,6 @@ export const vercelRouter = t.router({ userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: integration.workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "key.create", - description: `Created ${keyId}`, - resources: [ - { - type: "key", - id: keyId, - }, - { - type: "vercelIntegration", - id: integration.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); const setRootKeyRes = await vercel.upsertEnvironmentVariable( @@ -165,26 +143,6 @@ export const vercelRouter = t.router({ userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: integration.workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "vercelBinding.create", - description: `Created ${vercelBindingId} for ${keyId}`, - resources: [ - { - type: "vercelBinding", - id: vercelBindingId, - }, - { - type: "key", - id: keyId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); // Api Id stuff @@ -216,7 +174,7 @@ export const vercelRouter = t.router({ workspaceId: integration.workspace.id, integrationId: integration.id, }); - await ingestAuditLogsTinybird({ + await insertAuditLogs(tx, { workspaceId: integration.workspace.id, actor: { type: "user", id: ctx.user.id }, event: "vercelBinding.create", @@ -319,29 +277,6 @@ export const vercelRouter = t.router({ userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: integration.workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "vercelBinding.update", - description: `Updated ${existingBinding.id}`, - resources: [ - { - type: "vercelBinding", - id: existingBinding.id, - meta: { - vercelEnvironment: res.val.created.id, - }, - }, - { - type: "api", - id: input.apiId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); } else { await db.transaction(async (tx) => { @@ -359,7 +294,7 @@ export const vercelRouter = t.router({ workspaceId: integration.workspace.id, integrationId: integration.id, }); - await ingestAuditLogsTinybird({ + await insertAuditLogs(tx, { workspaceId: integration.workspace.id, actor: { type: "user", id: ctx.user.id }, event: "vercelBinding.create", @@ -455,22 +390,6 @@ export const vercelRouter = t.router({ userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: integration.workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "key.create", - description: `Created ${keyId}`, - resources: [ - { - type: "key", - id: keyId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); const res = await vercel.upsertEnvironmentVariable( @@ -523,29 +442,6 @@ export const vercelRouter = t.router({ userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: integration.workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "vercelBinding.update", - description: `Updated ${existingBinding.id}`, - resources: [ - { - type: "vercelBinding", - id: existingBinding.id, - meta: { - vercelEnvironment: res.val.created.id, - }, - }, - { - type: "key", - id: keyId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); } else { await db.transaction(async (tx) => { @@ -592,34 +488,6 @@ export const vercelRouter = t.router({ userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: integration.workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "vercelBinding.create", - description: `Created ${vercelBindingId} for ${keyId}`, - resources: [ - { - type: "vercelIntegration", - id: integration.id, - }, - { - type: "vercelBinding", - id: vercelBindingId, - meta: { - environment: input.environment, - projectId: input.projectId, - }, - }, - { - type: "key", - id: keyId, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); } }), @@ -675,22 +543,6 @@ export const vercelRouter = t.router({ userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: binding.vercelIntegrations.workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "vercelBinding.delete", - description: `Deleted ${binding.id}`, - resources: [ - { - type: "vercelBinding", - id: binding.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); }), disconnectProject: t.procedure @@ -753,27 +605,6 @@ export const vercelRouter = t.router({ userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: integration.workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "vercelBinding.delete", - description: `Deleted ${binding.id}`, - resources: [ - { - type: "vercelBinding", - id: binding.id, - meta: { - vercelProjectId: binding.projectId, - vercelEnvironment: binding.environment, - vercelEnvironmentVariableId: binding.vercelEnvId, - }, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); } }), diff --git a/apps/dashboard/lib/trpc/routers/workspace/changeName.ts b/apps/dashboard/lib/trpc/routers/workspace/changeName.ts index a980db260..d42972fa6 100644 --- a/apps/dashboard/lib/trpc/routers/workspace/changeName.ts +++ b/apps/dashboard/lib/trpc/routers/workspace/changeName.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { clerkClient } from "@clerk/nextjs"; import { TRPCError } from "@trpc/server"; @@ -59,22 +58,7 @@ export const changeWorkspaceName = rateLimitedProcedure(ratelimit.update) userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: ws.id, - actor: { type: "user", id: ctx.user.id }, - event: "workspace.update", - description: `Changed name from ${ws.name} to ${input.name}`, - resources: [ - { - type: "workspace", - id: ws.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); + if (ctx.tenant.id.startsWith("org_")) { await clerkClient.organizations.updateOrganization(ctx.tenant.id, { name: input.name, diff --git a/apps/dashboard/lib/trpc/routers/workspace/changePlan.ts b/apps/dashboard/lib/trpc/routers/workspace/changePlan.ts index 55f3f2698..56ec6ccfd 100644 --- a/apps/dashboard/lib/trpc/routers/workspace/changePlan.ts +++ b/apps/dashboard/lib/trpc/routers/workspace/changePlan.ts @@ -1,7 +1,6 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; import { stripeEnv } from "@/lib/env"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { defaultProSubscriptions } from "@unkey/billing"; @@ -94,22 +93,6 @@ export const changeWorkspacePlan = rateLimitedProcedure(ratelimit.update) userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "workspace.update", - description: "Removed downgrade request", - resources: [ - { - type: "workspace", - id: workspace.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }) .catch((err) => { console.error(err); @@ -154,22 +137,6 @@ export const changeWorkspacePlan = rateLimitedProcedure(ratelimit.update) userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "workspace.update", - description: "Requested downgrade to 'free'", - resources: [ - { - type: "workspace", - id: workspace.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); return { title: "Your plan is scheduled to downgrade on the first of next month.", @@ -219,22 +186,6 @@ export const changeWorkspacePlan = rateLimitedProcedure(ratelimit.update) userAgent: ctx.audit.userAgent, }, }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "workspace.update", - description: "Changed plan to 'pro'", - resources: [ - { - type: "workspace", - id: workspace.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); return { title: "Your workspace has been upgraded" }; } diff --git a/apps/dashboard/lib/trpc/routers/workspace/create.ts b/apps/dashboard/lib/trpc/routers/workspace/create.ts index d90b2908e..94b2fd495 100644 --- a/apps/dashboard/lib/trpc/routers/workspace/create.ts +++ b/apps/dashboard/lib/trpc/routers/workspace/create.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { type Workspace, db, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { clerkClient } from "@clerk/nextjs"; import { TRPCError } from "@trpc/server"; @@ -103,22 +102,6 @@ export const createWorkspace = rateLimitedProcedure(ratelimit.create) "We are unable to create the workspace. Please contact support using support@unkey.dev", }); }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "workspace.create", - description: `Created ${workspace.id}`, - resources: [ - { - type: "workspace", - id: workspace.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); return { workspace, diff --git a/apps/dashboard/lib/trpc/routers/workspace/optIntoBeta.ts b/apps/dashboard/lib/trpc/routers/workspace/optIntoBeta.ts index 6c7982881..e0d93cb5e 100644 --- a/apps/dashboard/lib/trpc/routers/workspace/optIntoBeta.ts +++ b/apps/dashboard/lib/trpc/routers/workspace/optIntoBeta.ts @@ -1,6 +1,5 @@ import { insertAuditLogs } from "@/lib/audit"; import { db, eq, schema } from "@/lib/db"; -import { ingestAuditLogsTinybird } from "@/lib/tinybird"; import { rateLimitedProcedure, ratelimit } from "@/lib/trpc/ratelimitProcedure"; import { TRPCError } from "@trpc/server"; import { z } from "zod"; @@ -78,20 +77,4 @@ export const optWorkspaceIntoBeta = rateLimitedProcedure(ratelimit.update) message: "Failed to update workspace, please contact support using support@unkey.dev.", }); }); - await ingestAuditLogsTinybird({ - workspaceId: workspace.id, - actor: { type: "user", id: ctx.user.id }, - event: "workspace.opt_in", - description: `Opted ${workspace.id} into beta: ${input.feature}`, - resources: [ - { - type: "workspace", - id: workspace.id, - }, - ], - context: { - location: ctx.audit.location, - userAgent: ctx.audit.userAgent, - }, - }); }); diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 3cdcaa97c..80bc5ffca 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -124,7 +124,7 @@ "@types/ms": "^0.7.34", "@types/node": "^20.14.9", "@types/react": "18.2.79", - "@types/react-dom": "18.3.0", + "@types/react-dom": "18.2.25", "autoprefixer": "^10.4.19", "postcss": "^8.4.38", "tailwindcss": "^3.4.3", diff --git a/apps/workflows/jobs/create-invoice.ts b/apps/workflows/jobs/create-invoice.ts deleted file mode 100644 index 820a28ea7..000000000 --- a/apps/workflows/jobs/create-invoice.ts +++ /dev/null @@ -1,276 +0,0 @@ -import { Tinybird } from "@/lib/tinybird"; -import { - type FixedSubscription, - type TieredSubscription, - calculateTieredPrices, -} from "@unkey/billing"; -import { z } from "zod"; - -import { env } from "@/lib/env"; -import { client } from "@/trigger"; - -import { connectDatabase } from "@/lib/db"; -import { type IO, eventTrigger } from "@trigger.dev/sdk"; - -import Stripe from "stripe"; - -export const createInvoiceJob = client.defineJob({ - id: "billing.invoicing.createInvoice", - name: "Collect usage and create invoice", - version: "0.0.2", - trigger: eventTrigger({ - name: "billing.invoicing.createInvoice", - schema: z.object({ - workspaceId: z.string(), - year: z.number(), - month: z.number(), - }), - }), - - run: async (payload, io, _ctx) => { - const { workspaceId, year, month } = payload; - - const db = connectDatabase(); - const stripe = new Stripe(env().STRIPE_SECRET_KEY, { - apiVersion: "2023-10-16", - typescript: true, - }); - const tinybird = new Tinybird(env().TINYBIRD_TOKEN); - - const workspace = await io.runTask(`get workspace ${workspaceId}`, async () => - db.query.workspaces.findFirst({ - where: (table, { and, eq, isNull }) => - and(eq(table.id, workspaceId), isNull(table.deletedAt)), - }), - ); - - if (!workspace) { - throw new Error(`workspace ${workspaceId} not found`); - } - - if (!workspace.stripeCustomerId) { - throw new Error(`workspace ${workspaceId} has no stripe customer id`); - } - - const paymentMethodId = await io.runTask(`get payment method for ${workspace.id}`, async () => { - const paymentMethods = await stripe.paymentMethods.list({ - customer: workspace.stripeCustomerId!, - limit: 1, - }); - - return paymentMethods.data.at(0)?.id; - }); - - const invoiceId = await io.runTask(`create invoice for ${workspace.id}`, async () => - stripe.invoices - .create({ - customer: workspace.stripeCustomerId!, - default_payment_method: paymentMethodId, - auto_advance: false, - custom_fields: [ - { - name: "Workspace", - value: workspace.name, - }, - { - name: "Billing Period", - value: new Date(year, month - 1, 1).toLocaleString("en-US", { - month: "long", - year: "numeric", - }), - }, - ], - }) - .then((invoice) => invoice.id), - ); - - let prorate: number | undefined = undefined; - if ( - workspace.planChanged && - new Date(workspace.planChanged).getUTCFullYear() === year && - new Date(workspace.planChanged).getUTCMonth() + 1 === month - ) { - const start = new Date(year, month - 1, 1); - const end = new Date(year, month, 1); - prorate = - (end.getTime() - new Date(workspace.planChanged).getTime()) / - (end.getTime() - start.getTime()); - io.logger.info("prorating", { start, end, prorate }); - } else if ( - workspace.createdAt && - new Date(workspace.createdAt).getUTCFullYear() === year && - new Date(workspace.createdAt).getUTCMonth() + 1 === month - ) { - const start = new Date(year, month - 1, 1); - const end = new Date(year, month, 1); - prorate = - (end.getTime() - new Date(workspace.createdAt).getTime()) / - (end.getTime() - start.getTime()); - io.logger.info("prorating", { start, end, prorate }); - } - - if (workspace.subscriptions?.plan) { - await createFixedCostInvoiceItem({ - stripe, - invoiceId, - stripeCustomerId: workspace.stripeCustomerId!, - io, - name: "Pro plan", - sub: workspace.subscriptions.plan, - prorate, - }); - } - - /** - * Verifications - */ - if (workspace.subscriptions?.verifications) { - const verifications = await io.runTask(`get verifications for ${workspace.id}`, async () => - tinybird - .verifications({ - workspaceId: workspace.id, - year, - month, - }) - .then((res) => res.data.at(0)?.success ?? 0), - ); - - await createTieredInvoiceItem({ - stripe, - invoiceId, - stripeCustomerId: workspace.stripeCustomerId!, - io, - name: "Verifications", - sub: workspace.subscriptions.verifications, - usage: verifications, - }); - } - - /** - * Ratelimits - */ - if (workspace.subscriptions?.ratelimits) { - const ratelimits = await io.runTask(`get ratelimits for ${workspace.id}`, async () => - tinybird - .ratelimits({ - workspaceId: workspace.id, - year, - month, - }) - .then((res) => res.data.at(0)?.success ?? 0), - ); - - await createTieredInvoiceItem({ - stripe, - invoiceId, - stripeCustomerId: workspace.stripeCustomerId!, - io, - name: "Ratelimits", - sub: workspace.subscriptions.ratelimits, - usage: ratelimits, - }); - } - - /** - * Support - */ - if (workspace.subscriptions?.support) { - await createFixedCostInvoiceItem({ - stripe, - invoiceId, - stripeCustomerId: workspace.stripeCustomerId!, - io, - name: "Professional Support", - sub: workspace.subscriptions.support, - prorate, - }); - } - - return { - invoiceId, - }; - }, -}); - -async function createFixedCostInvoiceItem({ - stripe, - invoiceId, - io, - stripeCustomerId, - name, - sub, - prorate, -}: { - stripe: Stripe; - invoiceId: string; - io: IO; - stripeCustomerId: string; - name: string; - sub: FixedSubscription; - /** - * number between 0 and 1 to indicate how much to charge - * if they have had a fixed cost item for 15/30 days, this should be 0.5 - */ - prorate?: number; -}): Promise { - await io.runTask(name, async () => { - await stripe.invoiceItems.create({ - customer: stripeCustomerId, - invoice: invoiceId, - quantity: 1, - price_data: { - currency: "usd", - product: sub.productId, - unit_amount_decimal: - typeof prorate === "number" - ? (Number.parseInt(sub.cents) * prorate).toFixed(2) - : sub.cents, - }, - currency: "usd", - description: typeof prorate === "number" ? `${name} (Prorated)` : name, - }); - }); -} - -async function createTieredInvoiceItem({ - stripe, - invoiceId, - io, - stripeCustomerId, - name, - sub, - usage, -}: { - stripe: Stripe; - invoiceId: string; - io: IO; - stripeCustomerId: string; - name: string; - sub: TieredSubscription; - usage: number; -}): Promise { - const cost = calculateTieredPrices(sub.tiers, usage); - if (cost.err) { - throw new Error(cost.err.message); - } - - for (const tier of cost.val.tiers) { - if (tier.quantity > 0 && tier.centsPerUnit) { - const description = `${name} ${tier.firstUnit}${tier.lastUnit ? `-${tier.lastUnit}` : "+"}`; - await io.runTask(description, async () => { - await stripe.invoiceItems.create({ - customer: stripeCustomerId, - invoice: invoiceId, - quantity: tier.quantity, - price_data: { - currency: "usd", - product: sub.productId, - unit_amount_decimal: tier.centsPerUnit!, - }, - currency: "usd", - description, - }); - }); - } - } -} diff --git a/apps/workflows/jobs/downgrade-requests.ts b/apps/workflows/jobs/downgrade-requests.ts deleted file mode 100644 index b8c19864d..000000000 --- a/apps/workflows/jobs/downgrade-requests.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { client } from "@/trigger"; - -import { connectDatabase, eq, schema } from "@/lib/db"; -import { env } from "@/lib/env"; -import { Tinybird } from "@/lib/tinybird"; -import { eventTrigger } from "@trigger.dev/sdk"; - -client.defineJob({ - id: "billing.downgrade", - name: "Downgrade workspaces when requested", - version: "0.0.2", - trigger: eventTrigger({ - name: "billing.downgrade", - }), - - run: async (_payload, io, _ctx) => { - const db = connectDatabase(); - const tb = new Tinybird(env().TINYBIRD_TOKEN); - - const workspaces = await io.runTask("get workspace with downgrade request", async () => - db.query.workspaces.findMany({ - where: (table, { and, isNotNull }) => and(isNotNull(table.planDowngradeRequest)), - }), - ); - - for (const ws of workspaces) { - await io.runTask(`downgrade workspace ${ws.id}`, async () => { - await db - .update(schema.workspaces) - .set({ - plan: ws.planDowngradeRequest, - planChanged: null, - planDowngradeRequest: null, - subscriptions: ws.planDowngradeRequest === "free" ? null : undefined, - }) - .where(eq(schema.workspaces.id, ws.id)); - }); - await io.runTask(`create audit log for downgrading ${ws.id}`, async () => { - await tb.ingestAuditLogs({ - workspaceId: ws.id, - event: "workspace.update", - actor: { - type: "system", - id: "trigger", - }, - description: `Downgraded ${ws.id} to ${ws.planDowngradeRequest}`, - resources: [ - { - type: "workspace", - id: ws.id, - }, - ], - context: { - location: "trigger", - }, - }); - }); - } - }, -}); diff --git a/apps/workflows/jobs/end-trials.ts b/apps/workflows/jobs/end-trials.ts deleted file mode 100644 index 80fa13fb0..000000000 --- a/apps/workflows/jobs/end-trials.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { connectDatabase, eq, schema } from "@/lib/db"; -import { env } from "@/lib/env"; -import { Tinybird } from "@/lib/tinybird"; -import { client } from "@/trigger"; -import { clerkClient } from "@clerk/nextjs"; -import { cronTrigger } from "@trigger.dev/sdk"; -import { Slack } from "@trigger.dev/slack"; -import { Resend } from "@unkey/resend"; - -const slack = new Slack({ - id: "unkey", -}); - -client.defineJob({ - id: "billing.trials.end", - name: "End trials", - version: "0.0.1", - trigger: cronTrigger({ - cron: "0 * * * *", - }), - integrations: { - slack, - }, - run: async (_payload, io, _ctx) => { - const db = connectDatabase(); - const resend = new Resend({ apiKey: env().RESEND_API_KEY }); - const tb = new Tinybird(env().TINYBIRD_TOKEN); - - const workspaces = await io.runTask("list workspaces", () => - db.query.workspaces.findMany({ - where: (table, { isNotNull, isNull, lte, and }) => - and( - isNotNull(table.trialEnds), - lte(table.trialEnds, new Date()), - isNull(table.deletedAt), - ), - }), - ); - io.logger.info(`found ${workspaces.length} workspaces with an expired trial`); - - for (const ws of workspaces) { - await io.runTask(`end trial for worksapce ${ws.id}`, async () => { - await db - .update(schema.workspaces) - .set({ - trialEnds: null, - plan: "free", - subscriptions: null, - }) - .where(eq(schema.workspaces.id, ws.id)); - }); - await io.runTask(`create audit log for trial ending ${ws.id}`, async () => { - await tb.ingestAuditLogs({ - workspaceId: ws.id, - event: "workspace.update", - actor: { - type: "system", - id: "trigger", - }, - description: `Ended trial for ${ws.id}`, - resources: [ - { - type: "workspace", - id: ws.id, - }, - ], - context: { - location: "trigger", - }, - }); - }); - - const users = await io.runTask(`get users for workspace ${ws.id}`, () => - getUsers(ws.tenantId), - ); - - for await (const user of users) { - io.logger.info(`sending trial ended email to ${user.email}`); - await resend.sendTrialEnded({ - email: user.email, - name: user.name, - workspace: ws.name, - }); - } - await io.slack.postMessage(`notify slack channel about workspace ${ws.id}`, { - channel: "C04GWUTDC3W", - text: `Trial ended for workspace ${ws.name} (${ws.id})`, - }); - } - - return {}; - }, -}); - -async function getUsers(tenantId: string): Promise<{ id: string; email: string; name: string }[]> { - const userIds: string[] = []; - if (tenantId.startsWith("org_")) { - const members = await clerkClient.organizations.getOrganizationMembershipList({ - organizationId: tenantId, - }); - for (const m of members) { - userIds.push(m.publicUserData!.userId); - } - } else { - userIds.push(tenantId); - } - - return await Promise.all( - userIds.map(async (userId) => { - const user = await clerkClient.users.getUser(userId); - const email = user.emailAddresses.at(0)?.emailAddress; - if (!email) { - throw new Error(`user ${user.id} does not have an email`); - } - return { - id: user.id, - name: user.firstName ?? user.username ?? "there", - email, - }; - }), - ); -} diff --git a/apps/workflows/jobs/index.ts b/apps/workflows/jobs/index.ts index d09538aa3..249e51f0f 100644 --- a/apps/workflows/jobs/index.ts +++ b/apps/workflows/jobs/index.ts @@ -1,8 +1,4 @@ // export all your job files here -export * from "./end-trials"; -export * from "./create-invoice"; -// export * from "./invoicing"; export * from "./refill-daily"; export * from "./refill-monthly"; -export * from "./downgrade-requests"; diff --git a/apps/workflows/jobs/invoicing.ts.disabled b/apps/workflows/jobs/invoicing.ts.disabled deleted file mode 100644 index ec54fc16b..000000000 --- a/apps/workflows/jobs/invoicing.ts.disabled +++ /dev/null @@ -1,63 +0,0 @@ -import { connectDatabase } from "@/lib/db"; -import { client } from "@/trigger"; -import { cronTrigger } from "@trigger.dev/sdk"; -import { createInvoiceJob } from "."; - -client.defineJob({ - id: "billing.invoicing", - name: "Monthly invoicing", - version: "0.0.1", - - trigger: cronTrigger({ - cron: "0 12 1 * *", // every 1st of the month at noon UTC - }), - run: async (_payload, io, _ctx) => { - const db = connectDatabase(); - - let workspaces = await io.runTask("list workspaces", async () => - db.query.workspaces.findMany({ - where: (table, { isNotNull, isNull, not, eq, and }) => - and( - isNotNull(table.stripeCustomerId), - isNotNull(table.subscriptions), - not(eq(table.plan, "free")), - isNull(table.deletedAt), - ), - }), - ); - // hack to filter out workspaces with `{}` as subscriptions - workspaces = workspaces.filter( - (ws) => ws.subscriptions && Object.keys(ws.subscriptions).length > 0, - ); - - io.logger.info(`found ${workspaces.length} workspaces`, workspaces); - - /** - * Dates gymnastics to get the previous month's number, ie: if it's December now, it returns -> 11 - */ - const t = new Date(); - t.setUTCMonth(t.getUTCMonth() - 1); - const year = t.getUTCFullYear(); - const month = t.getUTCMonth() + 1; // months are 0 indexed - - await createInvoiceJob.batchInvokeAndWaitForCompletion( - "invoice workspaces", - workspaces.map((ws) => ({ - payload: { - workspaceId: ws.id, - year, - month, - }, - })), - ); - - await io.sendEvent("downgrade", { - name: "billing.downgrade", - payload: {}, - }); - - return { - workspaceIds: workspaces.map((w) => w.id), - }; - }, -}); diff --git a/apps/workflows/jobs/refill-daily.ts b/apps/workflows/jobs/refill-daily.ts index 21b319abd..edbcb9f53 100644 --- a/apps/workflows/jobs/refill-daily.ts +++ b/apps/workflows/jobs/refill-daily.ts @@ -1,8 +1,7 @@ import { connectDatabase, eq, lte, schema } from "@/lib/db"; -import { env } from "@/lib/env"; -import { Tinybird } from "@/lib/tinybird"; import { client } from "@/trigger"; import { cronTrigger } from "@trigger.dev/sdk"; +import { newId } from "@unkey/id"; client.defineJob({ id: "refill.daily", @@ -14,7 +13,6 @@ client.defineJob({ run: async (_payload, io, _ctx) => { const db = connectDatabase(); - const tb = new Tinybird(env().TINYBIRD_TOKEN); const t = new Date(); t.setUTCHours(t.getUTCHours() - 24); @@ -35,40 +33,58 @@ client.defineJob({ }), ); io.logger.info(`found ${keys.length} keys with daily refill set`); - // const keysWithRefill = keys.length; + for (const key of keys) { - await io.runTask(`refill for ${key.id}`, async () => { - await db - .update(schema.keys) - .set({ - remaining: key.refillAmount, - lastRefillAt: new Date(), - }) - .where(eq(schema.keys.id, key.id)); + const bucket = await io.runTask(`get bucket for ${key.workspaceId}`, async () => { + return await db.query.auditLogBucket.findFirst({ + where: (table, { eq, and }) => + and(eq(table.workspaceId, key.workspaceId), eq(table.name, "unkey_mutations")), + }); }); + if (!bucket) { + io.logger.error(`bucket for ${key.workspaceId} does not exist`); + continue; + } + + await io.runTask(`refill for ${key.id}`, async () => { + await db.transaction(async (tx) => { + await tx + .update(schema.keys) + .set({ + remaining: key.refillAmount, + lastRefillAt: new Date(), + }) + .where(eq(schema.keys.id, key.id)); - await io.runTask(`create audit log refilling ${key.id}`, async () => { - await tb.ingestAuditLogs({ - workspaceId: key.workspaceId, - event: "key.update", - actor: { - type: "system", - id: "trigger", - }, - description: `Refilled ${key.id} to ${key.refillAmount}`, - resources: [ + const auditLogId = newId("auditLog"); + await tx.insert(schema.auditLog).values({ + id: auditLogId, + workspaceId: key.workspaceId, + bucketId: bucket.id, + time: Date.now(), + event: "key.update", + actorId: "trigger", + actorType: "system", + display: `Refilled ${key.id} to ${key.refillAmount}`, + }); + await tx.insert(schema.auditLogTarget).values([ { type: "workspace", id: key.workspaceId, + workspaceId: key.workspaceId, + bucketId: bucket.id, + auditLogId, + displayName: `workspace ${key.workspaceId}`, }, { type: "key", id: key.id, + workspaceId: key.workspaceId, + bucketId: bucket.id, + auditLogId, + displayName: `key ${key.id}`, }, - ], - context: { - location: "trigger", - }, + ]); }); }); } diff --git a/apps/workflows/jobs/refill-monthly.ts b/apps/workflows/jobs/refill-monthly.ts index 8b1e95eb2..452752ae2 100644 --- a/apps/workflows/jobs/refill-monthly.ts +++ b/apps/workflows/jobs/refill-monthly.ts @@ -1,9 +1,7 @@ import { connectDatabase, eq, gt, lte, schema } from "@/lib/db"; -import { env } from "@/lib/env"; -import { Tinybird } from "@/lib/tinybird"; import { client } from "@/trigger"; import { cronTrigger } from "@trigger.dev/sdk"; - +import { newId } from "@unkey/id"; client.defineJob({ id: "refill.monthly", name: "Monthly refill", @@ -14,7 +12,6 @@ client.defineJob({ run: async (_payload, io, _ctx) => { const db = connectDatabase(); - const tb = new Tinybird(env().TINYBIRD_TOKEN); const t = new Date(); t.setUTCMonth(t.getUTCMonth() - 1); @@ -35,39 +32,57 @@ client.defineJob({ }), ); io.logger.info(`found ${keys.length} keys with monthly refill set`); - // const keysWithRefill = keys.length; for (const key of keys) { - await io.runTask(`refill for ${key.id}`, async () => { - await db - .update(schema.keys) - .set({ - remaining: key.refillAmount, - lastRefillAt: new Date(), - }) - .where(eq(schema.keys.id, key.id)); + const bucket = await io.runTask(`get bucket for ${key.workspaceId}`, async () => { + return await db.query.auditLogBucket.findFirst({ + where: (table, { eq, and }) => + and(eq(table.workspaceId, key.workspaceId), eq(table.name, "unkey_mutations")), + }); }); - await io.runTask(`create audit log refilling ${key.id}`, async () => { - await tb.ingestAuditLogs({ - workspaceId: key.workspaceId, - event: "key.update", - actor: { - type: "system", - id: "trigger", - }, - description: `Refilled ${key.id} to ${key.refillAmount}`, - resources: [ + if (!bucket) { + io.logger.error(`bucket for ${key.workspaceId} does not exist`); + continue; + } + + await io.runTask(`refill for ${key.id}`, async () => { + await db.transaction(async (tx) => { + await tx + .update(schema.keys) + .set({ + remaining: key.refillAmount, + lastRefillAt: new Date(), + }) + .where(eq(schema.keys.id, key.id)); + + const auditLogId = newId("auditLog"); + await tx.insert(schema.auditLog).values({ + id: auditLogId, + workspaceId: key.workspaceId, + bucketId: bucket.id, + time: Date.now(), + event: "key.update", + actorId: "trigger", + actorType: "system", + display: `Refilled ${key.id} to ${key.refillAmount}`, + }); + await tx.insert(schema.auditLogTarget).values([ { type: "workspace", id: key.workspaceId, + workspaceId: key.workspaceId, + bucketId: bucket.id, + auditLogId, + displayName: `workspace ${key.workspaceId}`, }, { type: "key", id: key.id, + workspaceId: key.workspaceId, + bucketId: bucket.id, + auditLogId, + displayName: `key ${key.id}`, }, - ], - context: { - location: "trigger", - }, + ]); }); }); } diff --git a/apps/workflows/lib/tinybird.ts b/apps/workflows/lib/tinybird.ts index dcc3bf16e..4eaf645b8 100644 --- a/apps/workflows/lib/tinybird.ts +++ b/apps/workflows/lib/tinybird.ts @@ -1,10 +1,6 @@ import { Tinybird as Client } from "@chronark/zod-bird"; -import { newId } from "@unkey/id"; -import { auditLogSchemaV1, unkeyAuditLogEvents } from "@unkey/schema/src/auditlog"; import { z } from "zod"; -type MaybeArray = T | T[]; - export class Tinybird { private readonly tb: Client; @@ -65,55 +61,4 @@ export class Tinybird { }, }); } - - public ingestAuditLogs( - logs: MaybeArray<{ - workspaceId: string; - event: z.infer; - description: string; - actor: { - type: "user" | "key" | "system"; - name?: string; - id: string; - }; - resources: Array<{ - type: - | "key" - | "api" - | "workspace" - | "role" - | "permission" - | "keyAuth" - | "vercelBinding" - | "vercelIntegration"; - id: string; - meta?: Record; - }>; - context: { - userAgent?: string; - location: string; - }; - }>, - ) { - return this.tb.buildIngestEndpoint({ - datasource: "audit_logs__v2", - event: auditLogSchemaV1 - .merge( - z.object({ - event: unkeyAuditLogEvents, - auditLogId: z.string().default(newId("auditLog")), - bucket: z.string().default("unkey_mutations"), - time: z.number().default(Date.now()), - }), - ) - .transform((l) => ({ - ...l, - actor: { - ...l.actor, - meta: l.actor.meta ? JSON.stringify(l.actor.meta) : undefined, - }, - resources: JSON.stringify(l.resources), - })), - })(logs); - } } diff --git a/packages/api/src/openapi.d.ts b/packages/api/src/openapi.d.ts index 8d534161f..ac451fca0 100644 --- a/packages/api/src/openapi.d.ts +++ b/packages/api/src/openapi.d.ts @@ -4188,7 +4188,7 @@ export interface operations { */ valid: boolean; /** - * @description The name of the key, give keys a name to easily identifiy their purpose + * @description The name of the key, give keys a name to easily identify their purpose * @example Customer X */ name?: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0b87271f3..9561c9d54 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -257,55 +257,55 @@ importers: version: 1.18.0 '@radix-ui/react-accordion': specifier: ^1.2.0 - version: 1.2.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.2.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-alert-dialog': specifier: ^1.0.5 - version: 1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-avatar': specifier: ^1.0.4 - version: 1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-checkbox': specifier: ^1.0.4 - version: 1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-collapsible': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-dialog': specifier: ^1.0.5 - version: 1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-dropdown-menu': specifier: ^2.1.1 - version: 2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 2.1.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-label': specifier: ^2.0.2 - version: 2.0.2(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 2.0.2(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-popover': specifier: ^1.0.7 - version: 1.0.7(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.7(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-progress': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-scroll-area': specifier: ^1.0.5 - version: 1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-select': specifier: ^2.0.0 - version: 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-separator': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-slot': specifier: ^1.1.0 version: 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-switch': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-tabs': specifier: ^1.1.0 - version: 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-tooltip': specifier: ^1.0.7 - version: 1.0.7(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + version: 1.0.7(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@tailwindcss/container-queries': specifier: ^0.1.1 version: 0.1.1(tailwindcss@3.4.3) @@ -575,8 +575,8 @@ importers: specifier: 18.2.79 version: 18.2.79 '@types/react-dom': - specifier: 18.3.0 - version: 18.3.0 + specifier: 18.2.25 + version: 18.2.25 apps/docs: dependencies: @@ -1188,7 +1188,7 @@ importers: devDependencies: checkly: specifier: latest - version: 4.9.0(@types/node@20.14.9)(typescript@5.5.3) + version: 4.8.1(@types/node@20.14.9)(typescript@5.5.3) ts-node: specifier: 10.9.1 version: 10.9.1(@types/node@20.14.9)(typescript@5.5.3) @@ -7302,6 +7302,34 @@ packages: /@radix-ui/primitive@1.1.0: resolution: {integrity: sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==} + /@radix-ui/react-accordion@1.2.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-HJOzSX8dQqtsp/3jVxCU3CXEONF7/2jlGAB28oX8TTw1Dz8JYbEI1UcL8355PuLBE41/IRRMvCw7VkiK/jcUOQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collapsible': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-accordion@1.2.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-HJOzSX8dQqtsp/3jVxCU3CXEONF7/2jlGAB28oX8TTw1Dz8JYbEI1UcL8355PuLBE41/IRRMvCw7VkiK/jcUOQ==} peerDependencies: @@ -7386,7 +7414,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-alert-dialog@1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-alert-dialog@1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-OrVIOcZL0tl6xibeuGt5/+UxoT2N27KCFOPjFyfXMnchxSHZ/OW7cCX2nGlIYJrbHK/fczPcFzAwvNBB6XBNMA==} peerDependencies: '@types/react': '*' @@ -7403,11 +7431,32 @@ packages: '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-slot': 1.0.2(@types/react@18.2.79)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-arrow@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -7454,7 +7503,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-arrow@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-arrow@1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==} peerDependencies: '@types/react': '*' @@ -7467,9 +7516,9 @@ packages: '@types/react-dom': optional: true dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -7512,6 +7561,30 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: true + /@radix-ui/react-avatar@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-avatar@1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==} peerDependencies: @@ -7536,6 +7609,34 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-checkbox@1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-CBuGQa52aAYnADZVt/KBQzXrwx6TqnlwtcIPGtVt5JkkzQwMOLJjPukimhfKEr4GQNd43C+djUh5Ikopj8pSLg==} peerDependencies: @@ -7564,7 +7665,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==} peerDependencies: '@types/react': '*' @@ -7582,12 +7683,12 @@ packages: '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-id': 1.0.1(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -7620,6 +7721,33 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-collapsible@1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-collapsible@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-zQY7Epa8sTL0mq4ajSJpjgn2YmCgyrG7RsQgLp3C0LQVkG7+Tf6Pv1CeNWZLyqMjhdPkBa5Lx7wYBeSu7uCSTA==} peerDependencies: @@ -7701,6 +7829,30 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-collection@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==} peerDependencies: @@ -7749,6 +7901,29 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-collection@1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-collection@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==} peerDependencies: @@ -8047,6 +8222,40 @@ packages: - '@types/react' dev: true + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.5(@types/react@18.2.79)(react@18.3.1) + dev: false + /@radix-ui/react-dialog@1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==} peerDependencies: @@ -8286,6 +8495,31 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==} peerDependencies: @@ -8336,7 +8570,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-dismissable-layer@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-dismissable-layer@1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==} peerDependencies: '@types/react': '*' @@ -8351,11 +8585,11 @@ packages: dependencies: '@radix-ui/primitive': 1.1.0 '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-escape-keydown': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -8454,7 +8688,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-dropdown-menu@2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-dropdown-menu@2.1.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-y8E+x9fBq9qvteD2Zwa4397pUVhYsh9iq44b5RD5qu1GMJWBCBuVg1hMyItbc6+zH00TxGRqd9Iot4wzf3OoBQ==} peerDependencies: '@types/react': '*' @@ -8471,11 +8705,11 @@ packages: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-menu': 2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-menu': 2.1.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -8567,6 +8801,29 @@ packages: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==} peerDependencies: @@ -8613,7 +8870,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-focus-scope@1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-200UD8zylvEyL8Bx+z76RJnASR2gRMuxlgFCPAe/Q/679a/r0eK3MBVYMb7vZODZcffZBdob1EGnky78xmVvcA==} peerDependencies: '@types/react': '*' @@ -8627,10 +8884,10 @@ packages: optional: true dependencies: '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -8779,7 +9036,7 @@ packages: react: 18.3.1 dev: true - /@radix-ui/react-label@2.0.2(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-label@2.0.2(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} peerDependencies: '@types/react': '*' @@ -8793,14 +9050,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-label@2.0.2(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-label@2.0.2(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} peerDependencies: '@types/react': '*' @@ -8814,14 +9071,35 @@ packages: optional: true dependencies: '@babel/runtime': 7.25.6 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1) - '@types/react': 18.3.2 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.2.79 '@types/react-dom': 18.3.0 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-menu@2.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-label@2.0.2(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-N5ehvlM7qoTLx7nWPodsPYPgMzA5WM8zZChQg8nyFJKnDO5WHdba1vv5/H6IO5LtJMfD2Q3wh1qHFGNtK0w3bQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.3.2)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.3.2 + '@types/react-dom': 18.3.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-menu@2.1.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-oa3mXRRVjHi6DZu/ghuzdylyjaMXLymx83irM7hTxutQbD+7IhPKdMdRHD26Rm+kHRrWcrUkkRPv5pd47a2xFQ==} peerDependencies: '@types/react': '*' @@ -8835,29 +9113,64 @@ packages: optional: true dependencies: '@radix-ui/primitive': 1.1.0 - '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-direction': 1.1.0(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-focus-guards': 1.1.0(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-popper': 1.2.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.1.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-slot': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-remove-scroll: 2.5.7(@types/react@18.2.79)(react@18.3.1) dev: false + /@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + aria-hidden: 1.2.4 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-remove-scroll: 2.5.5(@types/react@18.2.79)(react@18.3.1) + dev: false + /@radix-ui/react-popover@1.0.7(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==} peerDependencies: @@ -8992,6 +9305,36 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-arrow': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/rect': 1.0.1 + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-popper@1.1.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==} peerDependencies: @@ -9052,7 +9395,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-popper@1.2.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-popper@1.2.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==} peerDependencies: '@types/react': '*' @@ -9066,17 +9409,17 @@ packages: optional: true dependencies: '@floating-ui/react-dom': 2.1.2(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-arrow': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-rect': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-size': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@radix-ui/rect': 1.1.0 '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -9169,6 +9512,27 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-portal@1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==} peerDependencies: @@ -9211,7 +9575,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-portal@1.1.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-portal@1.1.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==} peerDependencies: '@types/react': '*' @@ -9224,10 +9588,10 @@ packages: '@types/react-dom': optional: true dependencies: - '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -9326,6 +9690,28 @@ packages: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-presence@1.0.1(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==} peerDependencies: @@ -9370,6 +9756,27 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-presence@1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-presence@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==} peerDependencies: @@ -9484,6 +9891,27 @@ packages: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-primitive@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==} peerDependencies: @@ -9547,6 +9975,26 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-primitive@2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/react-slot': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-primitive@2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==} peerDependencies: @@ -9625,7 +10073,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: true - /@radix-ui/react-progress@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-progress@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-5G6Om/tYSxjSeEdrb1VfKkfZfn/1IlPWd731h2RfPuSbIfNUgfqAwbKfJCg/PP6nuUCTrYzalwHSpSinoWoCag==} peerDependencies: '@types/react': '*' @@ -9640,9 +10088,9 @@ packages: dependencies: '@babel/runtime': 7.25.6 '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -9676,6 +10124,34 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-collection': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-compose-refs': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-roving-focus@1.1.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==} peerDependencies: @@ -9760,6 +10236,35 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-scroll-area@1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-b6PAgH4GQf9QEn8zbT2XUHpW5z8BzqEc7Kl11TwDrvuTrxlkcjTD5qa/bxgKr+nmuXKu4L/W5UZ4mlP/VG/5Gw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/number': 1.0.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-scroll-area@1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-b6PAgH4GQf9QEn8zbT2XUHpW5z8BzqEc7Kl11TwDrvuTrxlkcjTD5qa/bxgKr+nmuXKu4L/W5UZ4mlP/VG/5Gw==} peerDependencies: @@ -9817,7 +10322,7 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false - /@radix-ui/react-select@2.0.0(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-select@2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==} peerDependencies: '@types/react': '*' @@ -9833,31 +10338,52 @@ packages: '@babel/runtime': 7.25.6 '@radix-ui/number': 1.0.1 '@radix-ui/primitive': 1.0.1 - '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-direction': 1.0.1(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-id': 1.0.1(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-slot': 1.0.2(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 aria-hidden: 1.2.4 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) react-remove-scroll: 2.5.5(@types/react@18.2.79)(react@18.3.1) dev: false + /@radix-ui/react-separator@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-separator@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-itYmTy/kokS21aiV5+Z56MZB54KrhPgn6eHDKkFeOLR34HMN2s8PaN47qZZAGnvupcjxHaFZnW4pQEh0BvvVuw==} peerDependencies: @@ -10019,7 +10545,7 @@ packages: react: 18.3.1 dev: true - /@radix-ui/react-switch@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + /@radix-ui/react-switch@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==} peerDependencies: '@types/react': '*' @@ -10036,12 +10562,39 @@ packages: '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.79)(react@18.3.1) '@types/react': 18.2.79 - '@types/react-dom': 18.3.0 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + + /@radix-ui/react-tabs@1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-bZgOKB/LtZIij75FSuPzyEti/XBhJH52ExgtdVqjCIh+Nx/FW+LhnbXtbCzIi34ccyMsyOja8T0thCzoHFXNKA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@radix-ui/primitive': 1.1.0 + '@radix-ui/react-context': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-direction': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-id': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-presence': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 2.0.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-roving-focus': 1.1.0(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.1.0(@types/react@18.2.79)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) dev: false @@ -10240,6 +10793,38 @@ packages: react-dom: 18.3.1(react@18.3.1) dev: false + /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-popper': 1.1.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@radix-ui/react-slot': 1.0.2(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.79)(react@18.3.1) + '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-tooltip@1.0.7(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==} peerDependencies: @@ -10779,6 +11364,27 @@ packages: react: 18.3.1 dev: true + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.25.6 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.25)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1) + '@types/react': 18.2.79 + '@types/react-dom': 18.2.25 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + dev: false + /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.3.0)(@types/react@18.2.79)(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==} peerDependencies: @@ -12605,7 +13211,6 @@ packages: resolution: {integrity: sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA==} dependencies: '@types/react': 18.3.8 - dev: true /@types/react-dom@18.3.0: resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} @@ -14175,8 +14780,8 @@ packages: get-func-name: 2.0.2 dev: true - /checkly@4.9.0(@types/node@20.14.9)(typescript@5.5.3): - resolution: {integrity: sha512-LqohEntErF7dJaJPsEpjvr/O9wUfzBRac6DOXgFDMEw+dNi19oBAcspdOqVGjPjMoCZ9/s5b5tSJI1pusY4mJQ==} + /checkly@4.8.1(@types/node@20.14.9)(typescript@5.5.3): + resolution: {integrity: sha512-LyVxHVOqjZ6k/QXGZQhZgnG7stL5mYfzu+Vl5hkdh2ZKDm/MLk4Q+gRKAyMLOjMN66jrJN1ZM1K3zlLt2/EJcg==} engines: {node: '>=16.0.0'} hasBin: true dependencies: