Openstatus www.openstatus.dev

feat: Turso experimentation (#75)

* 🚀

* fix: add missing required value

* chore: update query

* chore: add migration

* fix: pnpmlock

* fix: build

* fix: build

* fix: drizzle

* feat: turso + drizzle fix

* fix: update pr

authored by

Thibault Le Ouay and committed by
GitHub
76415ac7 aec1b7b3

+1059 -430
+9
.gitignore
··· 38 38 # packages 39 39 dist 40 40 packages/emails/.react-email 41 + packages/db/database.db 42 + packages/db/openstatus.db 43 + packages/db/database.db-wal 44 + packages/db/database.db-shm 45 + packages/db/openstatus.db-shm 46 + packages/db/openstatus.db-wal 47 + openstatus.db-wal 48 + openstatus.db 49 + openstatus.db-shm 41 50 packages/tinybird/.tinyb
+1 -3
apps/web/src/app/api/checker/cron/_cron.ts
··· 1 - import { NextResponse } from "next/server"; 2 1 import { Client } from "@upstash/qstash/cloudflare"; 3 2 import type { z } from "zod"; 4 3 5 - import { db, eq } from "@openstatus/db"; 6 - import { monitor, selectMonitorSchema } from "@openstatus/db/src/schema"; 4 + import { selectMonitorSchema } from "@openstatus/db/src/schema"; 7 5 import { availableRegions } from "@openstatus/tinybird"; 8 6 9 7 import { env } from "@/env.mjs";
+1 -1
apps/web/src/app/app/(dashboard)/[workspaceId]/monitors/page.tsx
··· 23 23 <Header title="Monitors" description="Overview of all your monitors."> 24 24 <CreateForm {...{ workspaceId }} /> 25 25 </Header> 26 - {monitors.map((monitor, index) => ( 26 + {monitors?.map((monitor, index) => ( 27 27 <Container 28 28 key={index} 29 29 title={monitor.name}
-1
apps/web/src/components/forms/montitor-form.tsx
··· 114 114 </FormDescription> 115 115 </div> 116 116 <FormControl> 117 - {/* TODO: make the monitor.active a boolean value */} 118 117 <Switch 119 118 checked={field.value === "active" ? true : false} 120 119 onCheckedChange={(value) =>
+1
apps/web/src/components/forms/status-page-form.tsx
··· 32 32 title: defaultValues?.title || "", 33 33 slug: defaultValues?.slug || "", 34 34 description: defaultValues?.description || "", 35 + workspaceId: defaultValues?.workspaceId || 0, 35 36 }, 36 37 }); 37 38
+3 -3
apps/web/src/middleware.ts
··· 73 73 auth.userId && 74 74 (req.nextUrl.pathname === "/app" || req.nextUrl.pathname === "/app/") 75 75 ) { 76 + console.log(auth.userId); 76 77 // improve on sign-up if the webhook has not been triggered yet 77 78 const userQuery = db 78 79 .select() ··· 83 84 .select() 84 85 .from(usersToWorkspaces) 85 86 .innerJoin(userQuery, eq(userQuery.id, usersToWorkspaces.userId)) 86 - .execute(); 87 - 88 - if (result.length) { 87 + .all(); 88 + if (result.length > 0) { 89 89 const orgSelection = new URL( 90 90 `/app/${result[0].users_to_workspaces.workspaceId}/dashboard`, 91 91 req.url,
+14 -10
packages/api/src/router/clerk/webhook.ts
··· 19 19 const alreadyExists = await opts.ctx.db 20 20 .select({ id: user.id }) 21 21 .from(user) 22 - .where(eq(user.tenantId, opts.input.data.data.id)); 23 - 24 - if (alreadyExists.length) return; 25 - 22 + .where(eq(user.tenantId, opts.input.data.data.id)) 23 + .get(); 24 + if (alreadyExists) return; 26 25 const userResult = await opts.ctx.db 27 26 .insert(user) 28 27 .values({ 29 28 tenantId: opts.input.data.data.id, 30 29 }) 31 - .execute(); 32 - const workspaceResult = await opts.ctx.db.insert(workspace).values({}); 33 - 30 + .returning({ id: user.id }) 31 + .get(); 32 + const workspaceResult = await opts.ctx.db 33 + .insert(workspace) 34 + .values({ name: "" }) 35 + .returning({ id: workspace.id }) 36 + .get(); 34 37 await opts.ctx.db 35 38 .insert(usersToWorkspaces) 36 39 .values({ 37 - userId: Number(userResult.insertId), 38 - workspaceId: Number(workspaceResult.insertId), 40 + userId: userResult.id, 41 + workspaceId: workspaceResult.id, 39 42 }) 40 - .execute(); 43 + .returning() 44 + .get(); 41 45 } 42 46 }), 43 47 userUpdated: webhookProcedure.mutation(async (opts) => {
+10 -5
packages/api/src/router/incident.ts
··· 15 15 createIncident: protectedProcedure 16 16 .input(insertIncidentSchema) 17 17 .mutation(async (opts) => { 18 - await opts.ctx.db.insert(incident).values(opts.input).execute(); 18 + return opts.ctx.db.insert(incident).values(opts.input).returning().get(); 19 19 }), 20 20 21 21 createIncidentUpdate: protectedProcedure 22 22 .input(insertIncidentUpdateSchema) 23 23 .mutation(async (opts) => { 24 - await opts.ctx.db.insert(incidentUpdate).values(opts.input).execute(); 24 + return opts.ctx.db 25 + .insert(incidentUpdate) 26 + .values(opts.input) 27 + .returning() 28 + .get(); 25 29 }), 26 30 27 31 updateIncident: protectedProcedure ··· 32 36 }), 33 37 ) 34 38 .mutation(async (opts) => { 35 - await opts.ctx.db 39 + return opts.ctx.db 36 40 .update(incident) 37 41 .set(opts.input.status) 38 42 .where(eq(incident.id, opts.input.incidentId)) 39 - .execute(); 43 + .returning() 44 + .get(); 40 45 }), 41 46 getIncidentByWorkspace: protectedProcedure 42 47 .input(z.object({ workspaceId: z.number() })) ··· 50 55 .select() 51 56 .from(incident) 52 57 .innerJoin(pageQuery, eq(incident.pageId, pageQuery.id)) 53 - .execute(); 58 + .all(); 54 59 }), 55 60 });
+164 -22
packages/api/src/router/monitor.ts
··· 1 1 import { z } from "zod"; 2 2 3 3 import { eq } from "@openstatus/db"; 4 - import { insertMonitorSchema, monitor } from "@openstatus/db/src/schema"; 4 + import { 5 + insertMonitorSchema, 6 + monitor, 7 + selectMonitorSchema, 8 + user, 9 + usersToWorkspaces, 10 + } from "@openstatus/db/src/schema"; 5 11 6 12 import { createTRPCRouter, protectedProcedure } from "../trpc"; 7 13 ··· 9 15 createMonitor: protectedProcedure 10 16 .input(insertMonitorSchema) 11 17 .mutation(async (opts) => { 12 - await opts.ctx.db.insert(monitor).values(opts.input).execute(); 18 + const currentUser = opts.ctx.db 19 + .select() 20 + .from(user) 21 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 22 + .as("currentUser"); 23 + const result = await opts.ctx.db 24 + .select() 25 + .from(usersToWorkspaces) 26 + .where( 27 + eq(usersToWorkspaces.workspaceId, Number(opts.input.workspaceId)), 28 + ) 29 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 30 + .get(); 31 + 32 + // the user don't have access to this workspace 33 + if (!result.users_to_workspaces) return; 34 + 35 + await opts.ctx.db.insert(monitor).values(opts.input).returning().get(); 13 36 }), 14 37 15 38 getMonitorById: protectedProcedure 16 39 .input(z.object({ id: z.number() })) 17 40 .query(async (opts) => { 18 - return await opts.ctx.db.query.monitor 19 - .findFirst({ where: eq(monitor.id, opts.input.id) }) 20 - .execute(); 41 + const mon = await opts.ctx.db.query.monitor.findFirst({ 42 + where: eq(monitor.id, opts.input.id), 43 + }); 44 + 45 + if (!mon) return; 46 + // We make sure user as access to this workspace 47 + const currentUser = opts.ctx.db 48 + .select() 49 + .from(user) 50 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 51 + .as("currentUser"); 52 + const result = await opts.ctx.db 53 + .select() 54 + .from(usersToWorkspaces) 55 + .where(eq(usersToWorkspaces.workspaceId, Number(mon.workspaceId))) 56 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 57 + .get(); 58 + 59 + if (!result.users_to_workspaces) return; 60 + 61 + return mon; 21 62 }), 22 63 23 64 updateMonitorDescription: protectedProcedure ··· 28 69 }), 29 70 ) 30 71 .mutation(async (opts) => { 31 - await opts.ctx.db 72 + // We make sure user as access to this workspace and the monitor 73 + const currentMonitor = await opts.ctx.db 74 + .select() 75 + .from(monitor) 76 + .where(eq(monitor.id, opts.input.monitorId)) 77 + .get(); 78 + 79 + const currentUser = opts.ctx.db 80 + .select() 81 + .from(user) 82 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 83 + .as("currentUser"); 84 + const result = await opts.ctx.db 85 + .select() 86 + .from(usersToWorkspaces) 87 + .where( 88 + eq(usersToWorkspaces.workspaceId, Number(currentMonitor.workspaceId)), 89 + ) 90 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 91 + .get(); 92 + 93 + if (!result.users_to_workspaces) return; 94 + 95 + opts.ctx.db 32 96 .update(monitor) 33 97 .set({ description: opts.input.description }) 34 - .where(eq(monitor.id, opts.input.monitorId)) 35 - .execute(); 98 + .where(eq(monitor.id, opts.input.monitorId)); 36 99 }), 37 100 updateMonitor: protectedProcedure 38 101 .input(insertMonitorSchema) 39 102 .mutation(async (opts) => { 40 - console.log(opts.input); 41 - const r = await opts.ctx.db 103 + const currentMonitor = await opts.ctx.db 104 + .select() 105 + .from(monitor) 106 + .where(eq(monitor.id, Number(opts.input.id))) 107 + .get(); 108 + 109 + const currentUser = opts.ctx.db 110 + .select() 111 + .from(user) 112 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 113 + .as("currentUser"); 114 + const result = await opts.ctx.db 115 + .select() 116 + .from(usersToWorkspaces) 117 + .where( 118 + eq(usersToWorkspaces.workspaceId, Number(currentMonitor.workspaceId)), 119 + ) 120 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 121 + .get(); 122 + 123 + if (!result.users_to_workspaces) return; 124 + 125 + opts.ctx.db 42 126 .update(monitor) 43 127 .set(opts.input) 44 - .where(eq(monitor.id, Number(opts.input.id))) 45 - .execute(); 46 - console.log(r); 47 - return r; 128 + .where(eq(monitor.id, Number(opts.input.id))); 48 129 }), 49 130 updateMonitorStatus: protectedProcedure 50 131 .input( ··· 54 135 }), 55 136 ) 56 137 .mutation(async (opts) => { 57 - return await opts.ctx.db 138 + const currentMonitor = await opts.ctx.db 139 + .select() 140 + .from(monitor) 141 + .where(eq(monitor.id, opts.input.id)) 142 + .get(); 143 + 144 + const currentUser = opts.ctx.db 145 + .select() 146 + .from(user) 147 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 148 + .as("currentUser"); 149 + const result = await opts.ctx.db 150 + .select() 151 + .from(usersToWorkspaces) 152 + .where( 153 + eq(usersToWorkspaces.workspaceId, Number(currentMonitor.workspaceId)), 154 + ) 155 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 156 + .get(); 157 + 158 + if (!result.users_to_workspaces) return; 159 + 160 + await opts.ctx.db 58 161 .update(monitor) 59 162 .set(opts.input.status) 60 - .where(eq(monitor.id, opts.input.id)) 61 - .execute(); 163 + .where(eq(monitor.id, opts.input.id)); 62 164 }), 63 165 64 166 deleteMonitor: protectedProcedure 65 167 .input(z.object({ monitorId: z.number() })) 66 168 .mutation(async (opts) => { 67 - await opts.ctx.db 68 - .delete(monitor) 69 - .where(eq(monitor.id, opts.input.monitorId)); 169 + const currentMonitor = await opts.ctx.db 170 + .select() 171 + .from(monitor) 172 + .where(eq(monitor.id, opts.input.monitorId)) 173 + .get(); 174 + 175 + const currentUser = opts.ctx.db 176 + .select() 177 + .from(user) 178 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 179 + .as("currentUser"); 180 + const result = await opts.ctx.db 181 + .select() 182 + .from(usersToWorkspaces) 183 + .where( 184 + eq(usersToWorkspaces.workspaceId, Number(currentMonitor.workspaceId)), 185 + ) 186 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 187 + .get(); 188 + 189 + if (!result.users_to_workspaces) return; 190 + 191 + opts.ctx.db.delete(monitor).where(eq(monitor.id, opts.input.monitorId)); 70 192 }), 71 193 getMonitorsByWorkspace: protectedProcedure 72 194 .input(z.object({ workspaceId: z.number() })) 73 195 .query(async (opts) => { 74 - return await opts.ctx.db 196 + const currentUser = opts.ctx.db 197 + .select() 198 + .from(user) 199 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 200 + .as("currentUser"); 201 + const result = await opts.ctx.db 202 + .select() 203 + .from(usersToWorkspaces) 204 + .where( 205 + eq(usersToWorkspaces.workspaceId, Number(opts.input.workspaceId)), 206 + ) 207 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 208 + .get(); 209 + 210 + // the user don't have access to this workspace 211 + if (!result.users_to_workspaces) return; 212 + 213 + const monitors = await opts.ctx.db 75 214 .select() 76 215 .from(monitor) 77 216 .where(eq(monitor.workspaceId, opts.input.workspaceId)) 78 - .execute(); 217 + .all(); 218 + const selectMonitorsArray = selectMonitorSchema.array(); 219 + 220 + return selectMonitorsArray.parse(monitors); 79 221 }), 80 222 });
+26 -16
packages/api/src/router/page.ts
··· 1 1 import { z } from "zod"; 2 2 3 3 import { eq } from "@openstatus/db"; 4 - import { insertPageSchema, page } from "@openstatus/db/src/schema"; 4 + import { 5 + insertPageSchema, 6 + page, 7 + selectIncidentSchema, 8 + selectMonitorSchema, 9 + selectPageSchema, 10 + } from "@openstatus/db/src/schema"; 5 11 6 12 import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc"; 7 13 ··· 10 16 createPage: protectedProcedure 11 17 .input(insertPageSchema) 12 18 .mutation(async (opts) => { 13 - await opts.ctx.db.insert(page).values(opts.input).execute(); 19 + return opts.ctx.db.insert(page).values(opts.input).returning().get(); 14 20 }), 15 21 16 22 getPageById: protectedProcedure 17 23 .input(z.object({ id: z.number() })) 18 24 .query(async (opts) => { 19 - return await opts.ctx.db.query.page 20 - .findFirst({ 21 - where: eq(page.id, opts.input.id), 22 - with: { monitors: true, incidents: true }, 23 - }) 24 - .execute(); 25 + return await opts.ctx.db.query.page.findFirst({ 26 + where: eq(page.id, opts.input.id), 27 + with: { monitors: true, incidents: true }, 28 + }); 25 29 }), 26 30 getPageByWorkspace: protectedProcedure 27 31 .input(z.object({ workspaceId: z.number() })) 28 32 .query(async (opts) => { 29 - return await opts.ctx.db 33 + return opts.ctx.db 30 34 .select() 31 35 .from(page) 32 - .where(eq(page.workspaceId, opts.input.workspaceId)); 36 + .where(eq(page.workspaceId, opts.input.workspaceId)) 37 + .all(); 33 38 }), 39 + 34 40 // public if we use trpc hooks to get the page from the url 35 41 getPageBySlug: publicProcedure 36 42 .input(z.object({ slug: z.string() })) 37 43 .query(async (opts) => { 38 - return await opts.ctx.db.query.page 39 - .findFirst({ 40 - where: eq(page.slug, opts.input.slug), 41 - with: { monitors: true, incidents: true }, 42 - }) 43 - .execute(); 44 + const result = opts.ctx.db.query.page.findFirst({ 45 + where: eq(page.slug, opts.input.slug), 46 + with: { monitors: true, incidents: true }, 47 + }); 48 + const selectPageSchemaWithRelation = selectPageSchema.extend({ 49 + monitors: z.array(selectMonitorSchema), 50 + incidents: z.array(selectIncidentSchema), 51 + }); 52 + 53 + return selectPageSchemaWithRelation.parse(result); 44 54 }), 45 55 });
+21 -9
packages/api/src/router/workspace.ts
··· 1 1 import { z } from "zod"; 2 2 3 3 import { eq } from "@openstatus/db"; 4 - import { 5 - page, 6 - user, 7 - usersToWorkspaces, 8 - workspace, 9 - } from "@openstatus/db/src/schema"; 4 + import { user, usersToWorkspaces, workspace } from "@openstatus/db/src/schema"; 10 5 11 6 import { createTRPCRouter, protectedProcedure } from "../trpc"; 12 7 ··· 26 21 getWorkspace: protectedProcedure 27 22 .input(z.object({ workspaceId: z.number() })) 28 23 .query(async (opts) => { 24 + const currentUser = opts.ctx.db 25 + .select() 26 + .from(user) 27 + .where(eq(user.tenantId, opts.ctx.auth.userId)) 28 + .as("currentUser"); 29 + const result = await opts.ctx.db 30 + .select() 31 + .from(usersToWorkspaces) 32 + .where( 33 + eq(usersToWorkspaces.workspaceId, Number(opts.input.workspaceId)), 34 + ) 35 + .innerJoin(currentUser, eq(usersToWorkspaces.userId, currentUser.id)) 36 + .get(); 37 + 38 + if (!result.users_to_workspaces) return; 39 + 29 40 return await opts.ctx.db.query.workspace.findMany({ 30 41 with: { 31 - page: true, 42 + pages: true, 32 43 }, 33 44 where: eq(workspace.id, opts.input.workspaceId), 34 45 }); ··· 37 48 createWorkspace: protectedProcedure 38 49 .input(z.object({ name: z.string() })) 39 50 .mutation(async (opts) => { 40 - await opts.ctx.db 51 + return opts.ctx.db 41 52 .insert(workspace) 42 53 .values({ name: opts.input.name }) 43 - .execute(); 54 + .returning() 55 + .get(); 44 56 }), 45 57 });
+4 -2
packages/db/drizzle.config.ts
··· 8 8 schema: "./src/schema/index.ts", 9 9 out: "./drizzle", 10 10 dbCredentials: { 11 - connectionString: env.DATABASE_URL, 11 + url: env.DATABASE_URL, 12 + authToken: env.DATABASE_AUTH_TOKEN, 12 13 }, 13 - driver: "mysql2", 14 + driver: "turso", 15 + strict: true, 14 16 } satisfies Config;
+71
packages/db/drizzle/0000_nebulous_shape.sql
··· 1 + CREATE TABLE `incident` ( 2 + `id` integer PRIMARY KEY NOT NULL, 3 + `status` text(2) NOT NULL, 4 + `page_id` integer NOT NULL, 5 + `updated_at` integer DEFAULT (strftime('%s', 'now')), 6 + FOREIGN KEY (`page_id`) REFERENCES `page`(`id`) ON UPDATE no action ON DELETE no action 7 + ); 8 + --> statement-breakpoint 9 + CREATE TABLE `incident_update` ( 10 + `id` integer PRIMARY KEY NOT NULL, 11 + `incident_date` integer, 12 + `title` text(256), 13 + `message` text, 14 + `incident_id` integer NOT NULL, 15 + `updated_at` integer DEFAULT (strftime('%s', 'now')), 16 + FOREIGN KEY (`incident_id`) REFERENCES `incident`(`id`) ON UPDATE no action ON DELETE no action 17 + ); 18 + --> statement-breakpoint 19 + CREATE TABLE `page` ( 20 + `id` integer PRIMARY KEY NOT NULL, 21 + `workspace_id` integer NOT NULL, 22 + `title` text NOT NULL, 23 + `description` text NOT NULL, 24 + `icon` text(256), 25 + `slug` text(256) NOT NULL, 26 + `custom_domain` text(256) DEFAULT '' NOT NULL, 27 + `updated_at` integer DEFAULT (strftime('%s', 'now')), 28 + FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE no action 29 + ); 30 + --> statement-breakpoint 31 + CREATE TABLE `monitor` ( 32 + `id` integer PRIMARY KEY NOT NULL, 33 + `job_type` text(3) DEFAULT 'other' NOT NULL, 34 + `periodicity` text(6) DEFAULT 'other' NOT NULL, 35 + `status` text(2) DEFAULT 'inactive' NOT NULL, 36 + `active` integer DEFAULT false, 37 + `url` text(512) NOT NULL, 38 + `name` text(256) DEFAULT '' NOT NULL, 39 + `description` text DEFAULT '' NOT NULL, 40 + `page_id` integer, 41 + `workspace_id` integer, 42 + `updated_at` integer DEFAULT (strftime('%s', 'now')), 43 + FOREIGN KEY (`page_id`) REFERENCES `page`(`id`) ON UPDATE no action ON DELETE no action, 44 + FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE no action 45 + ); 46 + --> statement-breakpoint 47 + CREATE TABLE `user` ( 48 + `id` integer PRIMARY KEY NOT NULL, 49 + `tenant_id` text(256), 50 + `updated_at` integer DEFAULT (strftime('%s', 'now')) 51 + ); 52 + --> statement-breakpoint 53 + CREATE TABLE `users_to_workspaces` ( 54 + `user_id` integer NOT NULL, 55 + `workspace_id` integer NOT NULL, 56 + PRIMARY KEY(`user_id`, `workspace_id`), 57 + FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON UPDATE no action ON DELETE no action, 58 + FOREIGN KEY (`workspace_id`) REFERENCES `workspace`(`id`) ON UPDATE no action ON DELETE no action 59 + ); 60 + --> statement-breakpoint 61 + CREATE TABLE `workspace` ( 62 + `id` integer PRIMARY KEY NOT NULL, 63 + `stripe_id` text(256), 64 + `name` text, 65 + `updated_at` integer DEFAULT (strftime('%s', 'now')) 66 + ); 67 + --> statement-breakpoint 68 + CREATE UNIQUE INDEX `page_slug_unique` ON `page` (`slug`);--> statement-breakpoint 69 + CREATE UNIQUE INDEX `page_custom_domain_unique` ON `page` (`custom_domain`);--> statement-breakpoint 70 + CREATE UNIQUE INDEX `user_tenant_id_unique` ON `user` (`tenant_id`);--> statement-breakpoint 71 + CREATE UNIQUE INDEX `workspace_stripe_id_unique` ON `workspace` (`stripe_id`);
-45
packages/db/drizzle/0000_overconfident_molten_man.sql
··· 1 - CREATE TABLE `incident` ( 2 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 3 - `status` enum('resolved','investigatin',''), 4 - `page_id` int, 5 - `created_at` timestamp NOT NULL DEFAULT (now()), 6 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 7 - --> statement-breakpoint 8 - CREATE TABLE `incidentUpdate` ( 9 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 10 - `incident_date` datetime, 11 - `title` varchar(256), 12 - `message` text, 13 - `incident_id` int NOT NULL, 14 - `created_at` timestamp NOT NULL DEFAULT (now()), 15 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 16 - --> statement-breakpoint 17 - CREATE TABLE `page` ( 18 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 19 - `workspace_id` int NOT NULL, 20 - `slug` varchar(256), 21 - `custom_domain` varchar(256), 22 - `created_at` timestamp NOT NULL DEFAULT (now()), 23 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 24 - --> statement-breakpoint 25 - CREATE TABLE `statusJob` ( 26 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 27 - `job_type` enum('website','cron','other') NOT NULL DEFAULT 'other', 28 - `periodicity` enum('every-5-min','every-1-min','every-1-h','other') NOT NULL DEFAULT 'other', 29 - `status` enum('active','inactive') NOT NULL DEFAULT 'inactive', 30 - `url` varchar(512), 31 - `page_id` int NOT NULL, 32 - `created_at` timestamp NOT NULL DEFAULT (now()), 33 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 34 - --> statement-breakpoint 35 - CREATE TABLE `user` ( 36 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 37 - `tenant_id` varchar(256), 38 - `created_at` timestamp NOT NULL DEFAULT (now()), 39 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 40 - --> statement-breakpoint 41 - CREATE TABLE `workspace` ( 42 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 43 - `stripe_id` varchar(256), 44 - `created_at` timestamp NOT NULL DEFAULT (now()), 45 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP);
-45
packages/db/drizzle/0000_superb_hercules.sql
··· 1 - CREATE TABLE `incident` ( 2 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 3 - `status` enum('resolved','investigatin',''), 4 - `page_id` int, 5 - `created_at` timestamp NOT NULL DEFAULT (now()), 6 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 7 - --> statement-breakpoint 8 - CREATE TABLE `incidentUpdate` ( 9 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 10 - `incident_date` datetime, 11 - `title` varchar(256), 12 - `message` text, 13 - `incident_id` int NOT NULL, 14 - `created_at` timestamp NOT NULL DEFAULT (now()), 15 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 16 - --> statement-breakpoint 17 - CREATE TABLE `page` ( 18 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 19 - `workspace_id` int NOT NULL, 20 - `slug` varchar(256), 21 - `custom_domain` varchar(256), 22 - `created_at` timestamp NOT NULL DEFAULT (now()), 23 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 24 - --> statement-breakpoint 25 - CREATE TABLE `monitor` ( 26 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 27 - `job_type` enum('website','cron','other') NOT NULL DEFAULT 'other', 28 - `periodicity` enum('1m','5m','10m','30m','1h','other') NOT NULL DEFAULT 'other', 29 - `status` enum('active','inactive') NOT NULL DEFAULT 'inactive', 30 - `url` varchar(512), 31 - `page_id` int NOT NULL, 32 - `created_at` timestamp NOT NULL DEFAULT (now()), 33 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 34 - --> statement-breakpoint 35 - CREATE TABLE `user` ( 36 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 37 - `tenant_id` varchar(256), 38 - `created_at` timestamp NOT NULL DEFAULT (now()), 39 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP); 40 - --> statement-breakpoint 41 - CREATE TABLE `workspace` ( 42 - `id` int AUTO_INCREMENT PRIMARY KEY NOT NULL, 43 - `stripe_id` varchar(256), 44 - `created_at` timestamp NOT NULL DEFAULT (now()), 45 - `updated_at` timestamp NOT NULL ON UPDATE CURRENT_TIMESTAMP);
+287 -112
packages/db/drizzle/meta/0000_snapshot.json
··· 1 1 { 2 2 "version": "5", 3 - "dialect": "mysql", 4 - "id": "b1ca2235-8b2f-4bb6-b382-484f98713c32", 3 + "dialect": "sqlite", 4 + "id": "1c9c9848-d580-4543-9104-566450666ad5", 5 5 "prevId": "00000000-0000-0000-0000-000000000000", 6 6 "tables": { 7 7 "incident": { ··· 9 9 "columns": { 10 10 "id": { 11 11 "name": "id", 12 - "type": "int", 12 + "type": "integer", 13 13 "primaryKey": true, 14 14 "notNull": true, 15 - "autoincrement": true 15 + "autoincrement": false 16 16 }, 17 17 "status": { 18 18 "name": "status", 19 - "type": "enum('resolved','investigatin','')", 19 + "type": "text(2)", 20 20 "primaryKey": false, 21 - "notNull": false, 21 + "notNull": true, 22 22 "autoincrement": false 23 23 }, 24 24 "page_id": { 25 25 "name": "page_id", 26 - "type": "int", 27 - "primaryKey": false, 28 - "notNull": false, 29 - "autoincrement": false 30 - }, 31 - "created_at": { 32 - "name": "created_at", 33 - "type": "timestamp", 26 + "type": "integer", 34 27 "primaryKey": false, 35 28 "notNull": true, 36 - "autoincrement": false, 37 - "default": "(now())" 29 + "autoincrement": false 38 30 }, 39 31 "updated_at": { 40 32 "name": "updated_at", 41 - "type": "timestamp", 33 + "type": "integer", 42 34 "primaryKey": false, 43 - "notNull": true, 35 + "notNull": false, 44 36 "autoincrement": false, 45 - "onUpdate": true 37 + "default": "(strftime('%s', 'now'))" 46 38 } 47 39 }, 48 40 "indexes": {}, 49 - "foreignKeys": {}, 50 - "compositePrimaryKeys": {} 41 + "foreignKeys": { 42 + "incident_page_id_page_id_fk": { 43 + "name": "incident_page_id_page_id_fk", 44 + "tableFrom": "incident", 45 + "tableTo": "page", 46 + "columnsFrom": [ 47 + "page_id" 48 + ], 49 + "columnsTo": [ 50 + "id" 51 + ], 52 + "onDelete": "no action", 53 + "onUpdate": "no action" 54 + } 55 + }, 56 + "compositePrimaryKeys": {}, 57 + "uniqueConstraints": {} 51 58 }, 52 - "incidentUpdate": { 53 - "name": "incidentUpdate", 59 + "incident_update": { 60 + "name": "incident_update", 54 61 "columns": { 55 62 "id": { 56 63 "name": "id", 57 - "type": "int", 64 + "type": "integer", 58 65 "primaryKey": true, 59 66 "notNull": true, 60 - "autoincrement": true 67 + "autoincrement": false 61 68 }, 62 69 "incident_date": { 63 70 "name": "incident_date", 64 - "type": "datetime", 71 + "type": "integer", 65 72 "primaryKey": false, 66 73 "notNull": false, 67 74 "autoincrement": false 68 75 }, 69 76 "title": { 70 77 "name": "title", 71 - "type": "varchar(256)", 78 + "type": "text(256)", 72 79 "primaryKey": false, 73 80 "notNull": false, 74 81 "autoincrement": false ··· 82 89 }, 83 90 "incident_id": { 84 91 "name": "incident_id", 85 - "type": "int", 92 + "type": "integer", 86 93 "primaryKey": false, 87 94 "notNull": true, 88 95 "autoincrement": false 89 96 }, 90 - "created_at": { 91 - "name": "created_at", 92 - "type": "timestamp", 93 - "primaryKey": false, 94 - "notNull": true, 95 - "autoincrement": false, 96 - "default": "(now())" 97 - }, 98 97 "updated_at": { 99 98 "name": "updated_at", 100 - "type": "timestamp", 99 + "type": "integer", 101 100 "primaryKey": false, 102 - "notNull": true, 101 + "notNull": false, 103 102 "autoincrement": false, 104 - "onUpdate": true 103 + "default": "(strftime('%s', 'now'))" 105 104 } 106 105 }, 107 106 "indexes": {}, 108 - "foreignKeys": {}, 109 - "compositePrimaryKeys": {} 107 + "foreignKeys": { 108 + "incident_update_incident_id_incident_id_fk": { 109 + "name": "incident_update_incident_id_incident_id_fk", 110 + "tableFrom": "incident_update", 111 + "tableTo": "incident", 112 + "columnsFrom": [ 113 + "incident_id" 114 + ], 115 + "columnsTo": [ 116 + "id" 117 + ], 118 + "onDelete": "no action", 119 + "onUpdate": "no action" 120 + } 121 + }, 122 + "compositePrimaryKeys": {}, 123 + "uniqueConstraints": {} 110 124 }, 111 125 "page": { 112 126 "name": "page", 113 127 "columns": { 114 128 "id": { 115 129 "name": "id", 116 - "type": "int", 130 + "type": "integer", 117 131 "primaryKey": true, 118 132 "notNull": true, 119 - "autoincrement": true 133 + "autoincrement": false 120 134 }, 121 135 "workspace_id": { 122 136 "name": "workspace_id", 123 - "type": "int", 137 + "type": "integer", 138 + "primaryKey": false, 139 + "notNull": true, 140 + "autoincrement": false 141 + }, 142 + "title": { 143 + "name": "title", 144 + "type": "text", 124 145 "primaryKey": false, 125 146 "notNull": true, 126 147 "autoincrement": false 127 148 }, 128 - "slug": { 129 - "name": "slug", 130 - "type": "varchar(256)", 149 + "description": { 150 + "name": "description", 151 + "type": "text", 131 152 "primaryKey": false, 132 - "notNull": false, 153 + "notNull": true, 133 154 "autoincrement": false 134 155 }, 135 - "custom_domain": { 136 - "name": "custom_domain", 137 - "type": "varchar(256)", 156 + "icon": { 157 + "name": "icon", 158 + "type": "text(256)", 138 159 "primaryKey": false, 139 160 "notNull": false, 140 161 "autoincrement": false 141 162 }, 142 - "created_at": { 143 - "name": "created_at", 144 - "type": "timestamp", 163 + "slug": { 164 + "name": "slug", 165 + "type": "text(256)", 166 + "primaryKey": false, 167 + "notNull": true, 168 + "autoincrement": false 169 + }, 170 + "custom_domain": { 171 + "name": "custom_domain", 172 + "type": "text(256)", 145 173 "primaryKey": false, 146 174 "notNull": true, 147 175 "autoincrement": false, 148 - "default": "(now())" 176 + "default": "''" 149 177 }, 150 178 "updated_at": { 151 179 "name": "updated_at", 152 - "type": "timestamp", 180 + "type": "integer", 153 181 "primaryKey": false, 154 - "notNull": true, 182 + "notNull": false, 155 183 "autoincrement": false, 156 - "onUpdate": true 184 + "default": "(strftime('%s', 'now'))" 157 185 } 158 186 }, 159 - "indexes": {}, 160 - "foreignKeys": {}, 161 - "compositePrimaryKeys": {} 187 + "indexes": { 188 + "page_slug_unique": { 189 + "name": "page_slug_unique", 190 + "columns": [ 191 + "slug" 192 + ], 193 + "isUnique": true 194 + }, 195 + "page_custom_domain_unique": { 196 + "name": "page_custom_domain_unique", 197 + "columns": [ 198 + "custom_domain" 199 + ], 200 + "isUnique": true 201 + } 202 + }, 203 + "foreignKeys": { 204 + "page_workspace_id_workspace_id_fk": { 205 + "name": "page_workspace_id_workspace_id_fk", 206 + "tableFrom": "page", 207 + "tableTo": "workspace", 208 + "columnsFrom": [ 209 + "workspace_id" 210 + ], 211 + "columnsTo": [ 212 + "id" 213 + ], 214 + "onDelete": "no action", 215 + "onUpdate": "no action" 216 + } 217 + }, 218 + "compositePrimaryKeys": {}, 219 + "uniqueConstraints": {} 162 220 }, 163 221 "monitor": { 164 222 "name": "monitor", 165 223 "columns": { 166 224 "id": { 167 225 "name": "id", 168 - "type": "int", 226 + "type": "integer", 169 227 "primaryKey": true, 170 228 "notNull": true, 171 - "autoincrement": true 229 + "autoincrement": false 172 230 }, 173 231 "job_type": { 174 232 "name": "job_type", 175 - "type": "enum('website','cron','other')", 233 + "type": "text(3)", 176 234 "primaryKey": false, 177 235 "notNull": true, 178 236 "autoincrement": false, ··· 180 238 }, 181 239 "periodicity": { 182 240 "name": "periodicity", 183 - "type": "enum('1m','5m','10m','30m','1h','other')", 241 + "type": "text(6)", 184 242 "primaryKey": false, 185 243 "notNull": true, 186 244 "autoincrement": false, ··· 188 246 }, 189 247 "status": { 190 248 "name": "status", 191 - "type": "enum('active','inactive')", 249 + "type": "text(2)", 192 250 "primaryKey": false, 193 251 "notNull": true, 194 252 "autoincrement": false, 195 253 "default": "'inactive'" 196 254 }, 255 + "active": { 256 + "name": "active", 257 + "type": "integer", 258 + "primaryKey": false, 259 + "notNull": false, 260 + "autoincrement": false, 261 + "default": false 262 + }, 197 263 "url": { 198 264 "name": "url", 199 - "type": "varchar(512)", 265 + "type": "text(512)", 200 266 "primaryKey": false, 201 - "notNull": false, 267 + "notNull": true, 202 268 "autoincrement": false 203 269 }, 204 - "page_id": { 205 - "name": "page_id", 206 - "type": "int", 270 + "name": { 271 + "name": "name", 272 + "type": "text(256)", 207 273 "primaryKey": false, 208 274 "notNull": true, 209 - "autoincrement": false 275 + "autoincrement": false, 276 + "default": "''" 210 277 }, 211 - "created_at": { 212 - "name": "created_at", 213 - "type": "timestamp", 278 + "description": { 279 + "name": "description", 280 + "type": "text", 214 281 "primaryKey": false, 215 282 "notNull": true, 216 283 "autoincrement": false, 217 - "default": "(now())" 284 + "default": "''" 285 + }, 286 + "page_id": { 287 + "name": "page_id", 288 + "type": "integer", 289 + "primaryKey": false, 290 + "notNull": false, 291 + "autoincrement": false 292 + }, 293 + "workspace_id": { 294 + "name": "workspace_id", 295 + "type": "integer", 296 + "primaryKey": false, 297 + "notNull": false, 298 + "autoincrement": false 218 299 }, 219 300 "updated_at": { 220 301 "name": "updated_at", 221 - "type": "timestamp", 302 + "type": "integer", 222 303 "primaryKey": false, 223 - "notNull": true, 304 + "notNull": false, 224 305 "autoincrement": false, 225 - "onUpdate": true 306 + "default": "(strftime('%s', 'now'))" 226 307 } 227 308 }, 228 309 "indexes": {}, 229 - "foreignKeys": {}, 230 - "compositePrimaryKeys": {} 310 + "foreignKeys": { 311 + "monitor_page_id_page_id_fk": { 312 + "name": "monitor_page_id_page_id_fk", 313 + "tableFrom": "monitor", 314 + "tableTo": "page", 315 + "columnsFrom": [ 316 + "page_id" 317 + ], 318 + "columnsTo": [ 319 + "id" 320 + ], 321 + "onDelete": "no action", 322 + "onUpdate": "no action" 323 + }, 324 + "monitor_workspace_id_workspace_id_fk": { 325 + "name": "monitor_workspace_id_workspace_id_fk", 326 + "tableFrom": "monitor", 327 + "tableTo": "workspace", 328 + "columnsFrom": [ 329 + "workspace_id" 330 + ], 331 + "columnsTo": [ 332 + "id" 333 + ], 334 + "onDelete": "no action", 335 + "onUpdate": "no action" 336 + } 337 + }, 338 + "compositePrimaryKeys": {}, 339 + "uniqueConstraints": {} 231 340 }, 232 341 "user": { 233 342 "name": "user", 234 343 "columns": { 235 344 "id": { 236 345 "name": "id", 237 - "type": "int", 346 + "type": "integer", 238 347 "primaryKey": true, 239 348 "notNull": true, 240 - "autoincrement": true 349 + "autoincrement": false 241 350 }, 242 351 "tenant_id": { 243 352 "name": "tenant_id", 244 - "type": "varchar(256)", 353 + "type": "text(256)", 245 354 "primaryKey": false, 246 355 "notNull": false, 247 356 "autoincrement": false 248 357 }, 249 - "created_at": { 250 - "name": "created_at", 251 - "type": "timestamp", 358 + "updated_at": { 359 + "name": "updated_at", 360 + "type": "integer", 361 + "primaryKey": false, 362 + "notNull": false, 363 + "autoincrement": false, 364 + "default": "(strftime('%s', 'now'))" 365 + } 366 + }, 367 + "indexes": { 368 + "user_tenant_id_unique": { 369 + "name": "user_tenant_id_unique", 370 + "columns": [ 371 + "tenant_id" 372 + ], 373 + "isUnique": true 374 + } 375 + }, 376 + "foreignKeys": {}, 377 + "compositePrimaryKeys": {}, 378 + "uniqueConstraints": {} 379 + }, 380 + "users_to_workspaces": { 381 + "name": "users_to_workspaces", 382 + "columns": { 383 + "user_id": { 384 + "name": "user_id", 385 + "type": "integer", 252 386 "primaryKey": false, 253 387 "notNull": true, 254 - "autoincrement": false, 255 - "default": "(now())" 388 + "autoincrement": false 256 389 }, 257 - "updated_at": { 258 - "name": "updated_at", 259 - "type": "timestamp", 390 + "workspace_id": { 391 + "name": "workspace_id", 392 + "type": "integer", 260 393 "primaryKey": false, 261 394 "notNull": true, 262 - "autoincrement": false, 263 - "onUpdate": true 395 + "autoincrement": false 264 396 } 265 397 }, 266 398 "indexes": {}, 267 - "foreignKeys": {}, 268 - "compositePrimaryKeys": {} 399 + "foreignKeys": { 400 + "users_to_workspaces_user_id_user_id_fk": { 401 + "name": "users_to_workspaces_user_id_user_id_fk", 402 + "tableFrom": "users_to_workspaces", 403 + "tableTo": "user", 404 + "columnsFrom": [ 405 + "user_id" 406 + ], 407 + "columnsTo": [ 408 + "id" 409 + ], 410 + "onDelete": "no action", 411 + "onUpdate": "no action" 412 + }, 413 + "users_to_workspaces_workspace_id_workspace_id_fk": { 414 + "name": "users_to_workspaces_workspace_id_workspace_id_fk", 415 + "tableFrom": "users_to_workspaces", 416 + "tableTo": "workspace", 417 + "columnsFrom": [ 418 + "workspace_id" 419 + ], 420 + "columnsTo": [ 421 + "id" 422 + ], 423 + "onDelete": "no action", 424 + "onUpdate": "no action" 425 + } 426 + }, 427 + "compositePrimaryKeys": { 428 + "users_to_workspaces_user_id_workspace_id_pk": { 429 + "columns": [ 430 + "user_id", 431 + "workspace_id" 432 + ] 433 + } 434 + }, 435 + "uniqueConstraints": {} 269 436 }, 270 437 "workspace": { 271 438 "name": "workspace", 272 439 "columns": { 273 440 "id": { 274 441 "name": "id", 275 - "type": "int", 442 + "type": "integer", 276 443 "primaryKey": true, 277 444 "notNull": true, 278 - "autoincrement": true 445 + "autoincrement": false 279 446 }, 280 447 "stripe_id": { 281 448 "name": "stripe_id", 282 - "type": "varchar(256)", 449 + "type": "text(256)", 283 450 "primaryKey": false, 284 451 "notNull": false, 285 452 "autoincrement": false 286 453 }, 287 - "created_at": { 288 - "name": "created_at", 289 - "type": "timestamp", 454 + "name": { 455 + "name": "name", 456 + "type": "text", 290 457 "primaryKey": false, 291 - "notNull": true, 292 - "autoincrement": false, 293 - "default": "(now())" 458 + "notNull": false, 459 + "autoincrement": false 294 460 }, 295 461 "updated_at": { 296 462 "name": "updated_at", 297 - "type": "timestamp", 463 + "type": "integer", 298 464 "primaryKey": false, 299 - "notNull": true, 465 + "notNull": false, 300 466 "autoincrement": false, 301 - "onUpdate": true 467 + "default": "(strftime('%s', 'now'))" 302 468 } 303 469 }, 304 - "indexes": {}, 470 + "indexes": { 471 + "workspace_stripe_id_unique": { 472 + "name": "workspace_stripe_id_unique", 473 + "columns": [ 474 + "stripe_id" 475 + ], 476 + "isUnique": true 477 + } 478 + }, 305 479 "foreignKeys": {}, 306 - "compositePrimaryKeys": {} 480 + "compositePrimaryKeys": {}, 481 + "uniqueConstraints": {} 307 482 } 308 483 }, 309 - "schemas": {}, 484 + "enums": {}, 310 485 "_meta": { 311 486 "schemas": {}, 312 487 "tables": {}, 313 488 "columns": {} 314 489 } 315 - } 490 + }
+4 -4
packages/db/drizzle/meta/_journal.json
··· 1 1 { 2 2 "version": "5", 3 - "dialect": "mysql", 3 + "dialect": "sqlite", 4 4 "entries": [ 5 5 { 6 6 "idx": 0, 7 7 "version": "5", 8 - "when": 1687764025255, 9 - "tag": "0000_superb_hercules", 8 + "when": 1690046393803, 9 + "tag": "0000_nebulous_shape", 10 10 "breakpoints": true 11 11 } 12 12 ] 13 - } 13 + }
+2
packages/db/env.mjs
··· 4 4 export const env = createEnv({ 5 5 server: { 6 6 DATABASE_URL: z.string().min(1), 7 + DATABASE_AUTH_TOKEN: z.string().min(1), 7 8 }, 8 9 runtimeEnv: { 9 10 DATABASE_URL: process.env.DATABASE_URL, 11 + DATABASE_AUTH_TOKEN: process.env.DATABASE_AUTH_TOKEN, 10 12 }, 11 13 });
+13 -7
packages/db/package.json
··· 4 4 "description": "", 5 5 "main": "src/index.ts", 6 6 "scripts": { 7 - "generate": "drizzle-kit generate:mysql", 8 - "push": "drizzle-kit push:mysql" 7 + "generate": "drizzle-kit generate:sqlite", 8 + "push": "drizzle-kit push:sqlite", 9 + "migrate": "ts-node --esm src/migrate.mts ", 10 + "studio": "drizzle-kit studio" 9 11 }, 10 12 "dependencies": { 11 - "@planetscale/database": "1.7.0", 12 - "@t3-oss/env-core": "0.4.1", 13 + "@libsql/client": "^0.3.1", 14 + "@t3-oss/env-core": "0.6.0", 13 15 "dotenv": "16.3.1", 14 - "drizzle-orm": "0.27.0", 16 + "drizzle-orm": "0.27.2", 15 17 "drizzle-zod": "^0.4.4", 16 18 "zod": "3.21.4" 17 19 }, 18 20 "devDependencies": { 19 21 "@types/node": "20.3.1", 20 - "drizzle-kit": "0.19.2", 22 + "drizzle-kit": "0.19.10", 21 23 "tsconfig": "workspace:^", 22 - "typescript": "5.1.3" 24 + "typescript": "5.1.3", 25 + "bufferutil": "^4.0.7", 26 + "utf-8-validate": "^6.0.3", 27 + "encoding": "0.1.13", 28 + "ts-node": "^10.9.1" 23 29 }, 24 30 "author": "" 25 31 }
+6 -7
packages/db/src/db.ts
··· 1 - import { connect } from "@planetscale/database"; 2 - import { drizzle } from "drizzle-orm/planetscale-serverless"; 1 + import { createClient } from "@libsql/client/http"; 2 + import { drizzle } from "drizzle-orm/libsql"; 3 3 4 4 import { env } from "../env.mjs"; 5 5 import * as schema from "./schema"; 6 6 7 - const config = { 7 + const client = createClient({ 8 8 url: env.DATABASE_URL, 9 - }; 10 - 11 - const connection = connect(config); 9 + authToken: env.DATABASE_AUTH_TOKEN, 10 + }); 12 11 13 - export const db = drizzle(connection, { schema }); 12 + export const db = drizzle(client, { schema });
+27
packages/db/src/migrate.mts
··· 1 + import "dotenv/config"; 2 + 3 + import { createClient } from "@libsql/client"; 4 + import { drizzle } from "drizzle-orm/libsql"; 5 + import { migrate } from "drizzle-orm/libsql/migrator"; 6 + 7 + import { env } from "../env.mjs"; 8 + 9 + async function main() { 10 + const db = drizzle( 11 + createClient({ url: env.DATABASE_URL, authToken: env.DATABASE_AUTH_TOKEN }), 12 + ); 13 + 14 + console.log("Running migrations"); 15 + 16 + await migrate(db, { migrationsFolder: "drizzle" }); 17 + 18 + console.log("Migrated successfully"); 19 + 20 + process.exit(0); 21 + } 22 + 23 + main().catch((e) => { 24 + console.error("Migration failed"); 25 + console.error(e); 26 + process.exit(1); 27 + });
+27 -23
packages/db/src/schema/incident.ts
··· 1 - import { relations } from "drizzle-orm"; 2 - import { 3 - datetime, 4 - int, 5 - mysqlEnum, 6 - mysqlTable, 7 - text, 8 - timestamp, 9 - varchar, 10 - } from "drizzle-orm/mysql-core"; 1 + import { relations, sql } from "drizzle-orm"; 2 + import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; 11 3 import { createInsertSchema, createSelectSchema } from "drizzle-zod"; 12 4 13 5 import { page } from "./page"; 14 6 15 - export const incident = mysqlTable("incident", { 16 - id: int("id").autoincrement().primaryKey(), 7 + export const incident = sqliteTable("incident", { 8 + id: integer("id").primaryKey(), 17 9 18 - status: mysqlEnum("status", ["resolved", "investigating"]).notNull(), 10 + status: text("status", ["resolved", "investigating"]).notNull(), 19 11 20 - pageId: int("page_id").notNull(), 12 + pageId: integer("page_id") 13 + .notNull() 14 + .references(() => page.id), 21 15 22 - createdAt: timestamp("created_at").notNull().defaultNow(), 23 - updatedAt: timestamp("updated_at").notNull().onUpdateNow(), 16 + createdAt: integer("updated_at", { mode: "timestamp" }).default( 17 + sql`(strftime('%s', 'now'))`, 18 + ), 19 + updatedAt: integer("updated_at", { mode: "timestamp" }).default( 20 + sql`(strftime('%s', 'now'))`, 21 + ), 24 22 }); 25 23 26 - export const incidentUpdate = mysqlTable("incidentUpdate", { 27 - id: int("id").autoincrement().primaryKey(), 24 + export const incidentUpdate = sqliteTable("incident_update", { 25 + id: integer("id").primaryKey(), 28 26 29 - date: datetime("incident_date"), 30 - title: varchar("title", { length: 256 }), // title of the incident 27 + date: integer("incident_date"), 28 + title: text("title", { length: 256 }), // title of the incident 31 29 message: text("message"), // where we can write the incident message 32 30 33 - incidentId: int("incident_id").notNull(), 34 - createdAt: timestamp("created_at").notNull().defaultNow(), 35 - updatedAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 31 + incidentId: integer("incident_id") 32 + .references(() => incident.id) 33 + .notNull(), 34 + createdAt: integer("updated_at", { mode: "timestamp" }).default( 35 + sql`(strftime('%s', 'now'))`, 36 + ), 37 + updatedAt: integer("updated_at", { mode: "timestamp" }).default( 38 + sql`(strftime('%s', 'now'))`, 39 + ), 36 40 }); 37 41 38 42 export const incidentRelations = relations(incident, ({ one, many }) => ({
+26 -35
packages/db/src/schema/monitor.ts
··· 1 - import { relations } from "drizzle-orm"; 2 - import { 3 - boolean, 4 - int, 5 - mysqlEnum, 6 - mysqlTable, 7 - text, 8 - timestamp, 9 - varchar, 10 - } from "drizzle-orm/mysql-core"; 1 + import { relations, sql } from "drizzle-orm"; 2 + import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; 11 3 import { createInsertSchema, createSelectSchema } from "drizzle-zod"; 12 4 import { z } from "zod"; 13 5 14 6 import { page } from "./page"; 15 7 import { workspace } from "./workspace"; 16 8 17 - export const monitor = mysqlTable("monitor", { 18 - id: int("id").autoincrement().primaryKey(), 19 - jobType: mysqlEnum("job_type", ["website", "cron", "other"]) 9 + export const monitor = sqliteTable("monitor", { 10 + id: integer("id").primaryKey(), 11 + jobType: text("job_type", ["website", "cron", "other"]) 20 12 .default("other") 21 13 .notNull(), 22 - periodicity: mysqlEnum("periodicity", [ 23 - "1m", 24 - "5m", 25 - "10m", 26 - "30m", 27 - "1h", 28 - "other", 29 - ]) 14 + periodicity: text("periodicity", ["1m", "5m", "10m", "30m", "1h", "other"]) 30 15 .default("other") 31 16 .notNull(), 17 + status: text("status", ["active", "inactive"]).default("inactive").notNull(), 18 + active: integer("active", { mode: "boolean" }).default(false), 32 19 33 - // TBD: if we keep or not?!? 34 - status: mysqlEnum("status", ["active", "inactive"]) 35 - .default("inactive") 36 - .notNull(), 20 + url: text("url", { length: 512 }).notNull(), 37 21 38 - active: boolean("active").default(false), 39 - 40 - url: varchar("url", { length: 512 }).notNull(), 41 - 42 - name: varchar("name", { length: 256 }).default("").notNull(), 22 + name: text("name", { length: 256 }).default("").notNull(), 43 23 description: text("description").default("").notNull(), 44 24 45 - pageId: int("page_id"), 46 - workspaceId: int("workspace_id"), 25 + pageId: integer("page_id").references(() => page.id), 26 + workspaceId: integer("workspace_id").references(() => workspace.id), 47 27 48 - createdAt: timestamp("created_at").notNull().defaultNow(), 49 - updateddAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 28 + createdAt: integer("updated_at", { mode: "timestamp" }).default( 29 + sql`(strftime('%s', 'now'))`, 30 + ), 31 + updatedAt: integer("updated_at", { mode: "timestamp" }).default( 32 + sql`(strftime('%s', 'now'))`, 33 + ), 50 34 }); 51 35 52 36 export const monitorRelation = relations(monitor, ({ one }) => ({ ··· 72 56 export const insertMonitorSchema = createInsertSchema(monitor, { 73 57 periodicity: periodicityEnum, 74 58 url: z.string().url(), 59 + status: z.enum(["active", "inactive"]).default("inactive"), 60 + active: z.boolean().default(false), 75 61 }); 76 62 77 63 // Schema for selecting a Monitor - can be used to validate API responses 78 - export const selectMonitorSchema = createSelectSchema(monitor); 64 + export const selectMonitorSchema = createSelectSchema(monitor, { 65 + periodicity: periodicityEnum, 66 + status: z.enum(["active", "inactive"]).default("inactive"), 67 + jobType: z.enum(["website", "cron", "other"]).default("other"), 68 + active: z.boolean().default(false), 69 + });
+24 -23
packages/db/src/schema/page.ts
··· 1 - import { relations } from "drizzle-orm"; 2 - import { 3 - int, 4 - mysqlTable, 5 - text, 6 - timestamp, 7 - varchar, 8 - } from "drizzle-orm/mysql-core"; 1 + import { relations, sql } from "drizzle-orm"; 2 + import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; 9 3 import { createInsertSchema, createSelectSchema } from "drizzle-zod"; 10 4 import { z } from "zod"; 11 5 12 - import { incident } from "./incident"; 13 - import { monitor } from "./monitor"; 6 + import { incident, selectIncidentSchema } from "./incident"; 7 + import { monitor, selectMonitorSchema } from "./monitor"; 8 + import { workspace } from "./workspace"; 14 9 15 - export const page = mysqlTable("page", { 16 - id: int("id").autoincrement().primaryKey(), 10 + export const page = sqliteTable("page", { 11 + id: integer("id").primaryKey(), 17 12 18 - workspaceId: int("workspace_id").notNull(), 13 + workspaceId: integer("workspace_id") 14 + .notNull() 15 + .references(() => workspace.id), 19 16 20 17 title: text("title").notNull(), // title of the page 21 18 description: text("description").notNull(), // description of the page 22 - icon: varchar("icon", { length: 256 }), // icon of the page 23 - slug: varchar("slug", { length: 256 }).notNull(), // which is used for https://slug.openstatus.dev 24 - customDomain: varchar("custom_domain", { length: 256 }).notNull().default(""), 19 + icon: text("icon", { length: 256 }), // icon of the page 20 + slug: text("slug", { length: 256 }).notNull().unique(), // which is used for https://slug.openstatus.dev 21 + customDomain: text("custom_domain", { length: 256 }) 22 + .notNull() 23 + .default("") 24 + .unique(), 25 25 26 - // We should store settings of the page 27 - // theme 28 - 29 - createdAt: timestamp("created_at").notNull().defaultNow(), 30 - updatedAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 26 + createdAt: integer("updated_at", { mode: "timestamp" }).default( 27 + sql`(strftime('%s', 'now'))`, 28 + ), 29 + updatedAt: integer("updated_at", { mode: "timestamp" }).default( 30 + sql`(strftime('%s', 'now'))`, 31 + ), 31 32 }); 32 33 33 34 export const pageRelations = relations(page, ({ many, one }) => ({ 34 35 incidents: many(incident), 35 - workspace: one(page, { 36 + workspace: one(workspace, { 36 37 fields: [page.workspaceId], 37 - references: [page.id], 38 + references: [workspace.id], 38 39 }), 39 40 monitors: many(monitor), 40 41 }));
+21 -13
packages/db/src/schema/user.ts
··· 1 - import { relations } from "drizzle-orm"; 1 + import { relations, sql } from "drizzle-orm"; 2 2 import { 3 3 int, 4 - mysqlTable, 4 + integer, 5 5 primaryKey, 6 - timestamp, 7 - varchar, 8 - } from "drizzle-orm/mysql-core"; 6 + sqliteTable, 7 + text, 8 + } from "drizzle-orm/sqlite-core"; 9 9 10 10 import { workspace } from "./workspace"; 11 11 12 - export const user = mysqlTable("user", { 13 - id: int("id").autoincrement().primaryKey(), 14 - tenantId: varchar("tenant_id", { length: 256 }), // the clerk User Id 12 + export const user = sqliteTable("user", { 13 + id: int("id").primaryKey(), 14 + tenantId: text("tenant_id", { length: 256 }).unique(), // the clerk User Id 15 15 16 - createdAt: timestamp("created_at").notNull().defaultNow(), 17 - updatedAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 16 + createdAt: integer("updated_at", { mode: "timestamp" }).default( 17 + sql`(strftime('%s', 'now'))`, 18 + ), 19 + updatedAt: integer("updated_at", { mode: "timestamp" }).default( 20 + sql`(strftime('%s', 'now'))`, 21 + ), 18 22 }); 19 23 20 24 export const userRelations = relations(user, ({ many }) => ({ 21 25 usersToWorkspaces: many(usersToWorkspaces), 22 26 })); 23 27 24 - export const usersToWorkspaces = mysqlTable( 28 + export const usersToWorkspaces = sqliteTable( 25 29 "users_to_workspaces", 26 30 { 27 - userId: int("user_id").notNull(), 28 - workspaceId: int("workspace_id").notNull(), 31 + userId: int("user_id") 32 + .notNull() 33 + .references(() => user.id), 34 + workspaceId: int("workspace_id") 35 + .notNull() 36 + .references(() => workspace.id), 29 37 }, 30 38 (t) => ({ 31 39 pk: primaryKey(t.userId, t.workspaceId),
+13 -15
packages/db/src/schema/workspace.ts
··· 1 - import { relations } from "drizzle-orm"; 2 - import { 3 - int, 4 - mysqlTable, 5 - text, 6 - timestamp, 7 - varchar, 8 - } from "drizzle-orm/mysql-core"; 1 + import { relations, sql } from "drizzle-orm"; 2 + import { integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; 9 3 10 4 import { page } from "./page"; 11 - import { user, usersToWorkspaces } from "./user"; 5 + import { usersToWorkspaces } from "./user"; 12 6 13 - export const workspace = mysqlTable("workspace", { 14 - id: int("id").autoincrement().primaryKey(), 7 + export const workspace = sqliteTable("workspace", { 8 + id: integer("id").primaryKey(), 15 9 16 - stripeId: varchar("stripe_id", { length: 256 }), 10 + stripeId: text("stripe_id", { length: 256 }).unique(), 17 11 name: text("name"), 18 12 19 - createdAt: timestamp("created_at").notNull().defaultNow(), 20 - updatedAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 13 + createdAt: integer("updated_at", { mode: "timestamp" }).default( 14 + sql`(strftime('%s', 'now'))`, 15 + ), 16 + updatedAt: integer("updated_at", { mode: "timestamp" }).default( 17 + sql`(strftime('%s', 'now'))`, 18 + ), 21 19 }); 22 20 23 21 export const workspaceRelations = relations(workspace, ({ many }) => ({ 24 - page: many(page), 25 22 usersToWorkspaces: many(usersToWorkspaces), 23 + pages: many(page), 26 24 }));
+284 -29
pnpm-lock.yaml
··· 311 311 312 312 packages/db: 313 313 dependencies: 314 - '@planetscale/database': 315 - specifier: 1.7.0 316 - version: 1.7.0 314 + '@libsql/client': 315 + specifier: ^0.3.1 316 + version: 0.3.1(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@6.0.3) 317 317 '@t3-oss/env-core': 318 - specifier: 0.4.1 319 - version: 0.4.1(typescript@5.1.3)(zod@3.21.4) 318 + specifier: 0.6.0 319 + version: 0.6.0(typescript@5.1.3)(zod@3.21.4) 320 320 dotenv: 321 321 specifier: 16.3.1 322 322 version: 16.3.1 323 323 drizzle-orm: 324 - specifier: 0.27.0 325 - version: 0.27.0(@planetscale/database@1.7.0) 324 + specifier: 0.27.2 325 + version: 0.27.2(@libsql/client@0.3.1) 326 326 drizzle-zod: 327 327 specifier: ^0.4.4 328 - version: 0.4.4(drizzle-orm@0.27.0)(zod@3.21.4) 328 + version: 0.4.4(drizzle-orm@0.27.2)(zod@3.21.4) 329 329 zod: 330 330 specifier: 3.21.4 331 331 version: 3.21.4 ··· 333 333 '@types/node': 334 334 specifier: 20.3.1 335 335 version: 20.3.1 336 + bufferutil: 337 + specifier: ^4.0.7 338 + version: 4.0.7 336 339 drizzle-kit: 337 - specifier: 0.19.2 338 - version: 0.19.2 340 + specifier: 0.19.10 341 + version: 0.19.10 342 + encoding: 343 + specifier: 0.1.13 344 + version: 0.1.13 345 + ts-node: 346 + specifier: ^10.9.1 347 + version: 10.9.1(@types/node@20.3.1)(typescript@5.1.3) 339 348 tsconfig: 340 349 specifier: workspace:^ 341 350 version: link:../tsconfig 342 351 typescript: 343 352 specifier: 5.1.3 344 353 version: 5.1.3 354 + utf-8-validate: 355 + specifier: ^6.0.3 356 + version: 6.0.3 345 357 346 358 packages/emails: 347 359 dependencies: ··· 945 957 /@deno/shim-crypto@0.3.1: 946 958 resolution: {integrity: sha512-ed4pNnfur6UbASEgF34gVxR9p7Mc3qF+Ygbmjiil8ws5IhNFhPDFy5vE5hQAUA9JmVsSxXPcVLM5Rf8LOZqQ5Q==} 947 959 dev: false 960 + 961 + /@drizzle-team/studio@0.0.5: 962 + resolution: {integrity: sha512-ps5qF0tMxWRVu+V5gvCRrQNqlY92aTnIKdq27gm9LZMSdaKYZt6AVvSK1dlUMzs6Rt0Jm80b+eWct6xShBKhIw==} 963 + dev: true 948 964 949 965 /@effect-ts/core@0.60.5: 950 966 resolution: {integrity: sha512-qi1WrtJA90XLMnj2hnUszW9Sx4dXP03ZJtCc5DiUBIOhF4Vw7plfb65/bdBySPoC9s7zy995TdUX1XBSxUkl5w==} ··· 1969 1985 dependencies: 1970 1986 jsbi: 4.3.0 1971 1987 tslib: 2.5.3 1988 + dev: false 1989 + 1990 + /@libsql/client@0.3.1(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@6.0.3): 1991 + resolution: {integrity: sha512-43/zF8fJguXd6ENwYhddpbR05bDVx3BQQUZ/BsJ0b4zLJge+WFa2smC3ILVGqvVu4ZoixbC0sfLTdVPdd2NjDA==} 1992 + dependencies: 1993 + '@libsql/hrana-client': 0.4.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@6.0.3) 1994 + better-sqlite3: 8.4.0 1995 + js-base64: 3.7.5 1996 + transitivePeerDependencies: 1997 + - bufferutil 1998 + - encoding 1999 + - utf-8-validate 2000 + dev: false 2001 + 2002 + /@libsql/hrana-client@0.4.3(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@6.0.3): 2003 + resolution: {integrity: sha512-ZlAXy3PpB8B93iu8MyDyMpzbu1b4G4oa5KOjbABHe7iBybx7yC+t3U/sK7c37QsmpRZQXi0S+vNPpGTlje3bCA==} 2004 + dependencies: 2005 + '@libsql/isomorphic-fetch': 0.1.4(encoding@0.1.13) 2006 + '@libsql/isomorphic-ws': 0.1.3(bufferutil@4.0.7)(utf-8-validate@6.0.3) 2007 + js-base64: 3.7.5 2008 + transitivePeerDependencies: 2009 + - bufferutil 2010 + - encoding 2011 + - utf-8-validate 2012 + dev: false 2013 + 2014 + /@libsql/isomorphic-fetch@0.1.4(encoding@0.1.13): 2015 + resolution: {integrity: sha512-eRgV4b1d6RVLciafGEKZghDOvrQ7fDuPgfGzelsfPz1HxFERaTQuOwL5FthZcKBtHI6Wqu5zmhUu5bREZr1mpA==} 2016 + dependencies: 2017 + '@types/node-fetch': 2.6.2 2018 + node-fetch: 2.6.11(encoding@0.1.13) 2019 + transitivePeerDependencies: 2020 + - encoding 2021 + dev: false 2022 + 2023 + /@libsql/isomorphic-ws@0.1.3(bufferutil@4.0.7)(utf-8-validate@6.0.3): 2024 + resolution: {integrity: sha512-54dZXgYwWDKsnfWv8GCVYvhn6RDlqFDGAc8EQMd941yvGMsGzo06Gn6Iyjw//nJ1iJO97FbXgoQ1apikoFD/WA==} 2025 + dependencies: 2026 + '@types/ws': 8.5.5 2027 + ws: 8.13.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) 2028 + transitivePeerDependencies: 2029 + - bufferutil 2030 + - utf-8-validate 1972 2031 dev: false 1973 2032 1974 2033 /@manypkg/find-root@2.1.0: ··· 2227 2286 '@octokit/request-error': 3.0.3 2228 2287 '@octokit/types': 9.3.2 2229 2288 is-plain-object: 5.0.0 2230 - node-fetch: 2.6.11 2289 + node-fetch: 2.6.11(encoding@0.1.13) 2231 2290 universal-user-agent: 6.0.0 2232 2291 transitivePeerDependencies: 2233 2292 - encoding ··· 2469 2528 open: 9.1.0 2470 2529 picocolors: 1.0.0 2471 2530 tslib: 2.5.3 2472 - dev: false 2473 - 2474 - /@planetscale/database@1.7.0: 2475 - resolution: {integrity: sha512-lWR6biXChUyQnxsT4RT1CIeR3ZJvwTQXiQ+158MnY3VjLwjHEGakDzdH9kwUGPk6CHvu6UeqRXp1DgUOVHJFTw==} 2476 - engines: {node: '>=16'} 2477 2531 dev: false 2478 2532 2479 2533 /@protobufjs/aspromise@1.1.2: ··· 3756 3810 zod: 3.21.4 3757 3811 dev: false 3758 3812 3813 + /@t3-oss/env-core@0.6.0(typescript@5.1.3)(zod@3.21.4): 3814 + resolution: {integrity: sha512-3FkPAba069WRZVVab/sB1m3eSGn/rZeypx5k+sWEu1d+k0OQdRDnvFS+7MtxYgqVrwaRk3b7yVnX2dgSPVmWPQ==} 3815 + peerDependencies: 3816 + typescript: '>=4.7.2' 3817 + zod: ^3.0.0 3818 + dependencies: 3819 + typescript: 5.1.3 3820 + zod: 3.21.4 3821 + dev: false 3822 + 3759 3823 /@t3-oss/env-nextjs@0.4.1(typescript@5.1.3)(zod@3.21.4): 3760 3824 resolution: {integrity: sha512-lDbewJvZwOW7bFwHzdKtAH4+YcVTvGU7UEJfHwlb1RqVe9ejPrKn6ax2OGv/nFji1JXGKecKYHz3Xkpru6TFbw==} 3761 3825 peerDependencies: ··· 4113 4177 4114 4178 /@types/unist@2.0.7: 4115 4179 resolution: {integrity: sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==} 4180 + 4181 + /@types/ws@8.5.5: 4182 + resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} 4183 + dependencies: 4184 + '@types/node': 20.3.1 4185 + dev: false 4116 4186 4117 4187 /@typescript-eslint/eslint-plugin@5.59.9(@typescript-eslint/parser@5.59.9)(eslint@8.43.0)(typescript@5.1.3): 4118 4188 resolution: {integrity: sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA==} ··· 4543 4613 resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} 4544 4614 dev: false 4545 4615 4616 + /better-sqlite3@8.4.0: 4617 + resolution: {integrity: sha512-NmsNW1CQvqMszu/CFAJ3pLct6NEFlNfuGM6vw72KHkjOD1UDnL96XNN1BMQc1hiHo8vE2GbOWQYIpZ+YM5wrZw==} 4618 + requiresBuild: true 4619 + dependencies: 4620 + bindings: 1.5.0 4621 + prebuild-install: 7.1.1 4622 + dev: false 4623 + 4546 4624 /big-integer@1.6.51: 4547 4625 resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} 4548 4626 engines: {node: '>=0.6'} ··· 4557 4635 dependencies: 4558 4636 buffers: 0.1.1 4559 4637 chainsaw: 0.1.0 4638 + dev: false 4639 + 4640 + /bindings@1.5.0: 4641 + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} 4642 + dependencies: 4643 + file-uri-to-path: 1.0.0 4560 4644 dev: false 4561 4645 4562 4646 /bl@4.1.0: ··· 4623 4707 engines: {node: '>=0.2.0'} 4624 4708 dev: false 4625 4709 4710 + /bufferutil@4.0.7: 4711 + resolution: {integrity: sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==} 4712 + engines: {node: '>=6.14.2'} 4713 + requiresBuild: true 4714 + dependencies: 4715 + node-gyp-build: 4.6.0 4716 + 4626 4717 /builtins@5.0.1: 4627 4718 resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} 4628 4719 dependencies: ··· 4798 4889 readdirp: 3.6.0 4799 4890 optionalDependencies: 4800 4891 fsevents: 2.3.2 4892 + 4893 + /chownr@1.1.4: 4894 + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} 4895 + dev: false 4801 4896 4802 4897 /class-variance-authority@0.6.0(typescript@5.1.3): 4803 4898 resolution: {integrity: sha512-qdRDgfjx3GRb9fpwpSvn+YaidnT7IUJNe4wt5/SWwM+PmUwJUhQRk/8zAyNro0PmVfmen2635UboTjIBXXxy5A==} ··· 5105 5200 dependencies: 5106 5201 character-entities: 2.0.2 5107 5202 5203 + /decompress-response@6.0.0: 5204 + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} 5205 + engines: {node: '>=10'} 5206 + dependencies: 5207 + mimic-response: 3.1.0 5208 + dev: false 5209 + 5108 5210 /deep-extend@0.6.0: 5109 5211 resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} 5110 5212 engines: {node: '>=4.0.0'} 5111 - dev: true 5112 5213 5113 5214 /deep-is@0.1.4: 5114 5215 resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} ··· 5190 5291 resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} 5191 5292 engines: {node: '>=6'} 5192 5293 5294 + /detect-libc@2.0.1: 5295 + resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} 5296 + engines: {node: '>=8'} 5297 + dev: false 5298 + 5193 5299 /detect-node-es@1.1.0: 5194 5300 resolution: {integrity: sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==} 5195 5301 dev: false ··· 5303 5409 wordwrap: 1.0.0 5304 5410 dev: true 5305 5411 5306 - /drizzle-kit@0.19.2: 5307 - resolution: {integrity: sha512-o+T/+Xc6hlLj2ocvGEo3kyWgTIAFjmsVK/HdBjU7gmbolmFZHv6T3lhaAsAD4mWfOX69uC7IggCmIqLq+zcM4Q==} 5412 + /drizzle-kit@0.19.10: 5413 + resolution: {integrity: sha512-v7bd+7YUO3NJJTY7hwt9k+DPJVw+31iejG/ztkvNS0hK8zWjJvA6NAECYZVswKQ+efCjzLgPCx+I9X105Zqt6Q==} 5308 5414 hasBin: true 5309 5415 dependencies: 5416 + '@drizzle-team/studio': 0.0.5 5310 5417 '@esbuild-kit/esm-loader': 2.5.5 5311 5418 camelcase: 7.0.1 5312 5419 chalk: 5.2.0 ··· 5322 5429 - supports-color 5323 5430 dev: true 5324 5431 5325 - /drizzle-orm@0.27.0(@planetscale/database@1.7.0): 5326 - resolution: {integrity: sha512-LGiJ0icB+wQwgbSCOvAjONY8Ec6G/EDzQQP5PmUaQYeI9OqgpVKHC2T1fFIbvk5dabWsbokJ5NOciVAxriStig==} 5432 + /drizzle-orm@0.27.2(@libsql/client@0.3.1): 5433 + resolution: {integrity: sha512-ZvBvceff+JlgP7FxHKe0zOU9CkZ4RcOtibumIrqfYzDGuOeF0YUY0F9iMqYpRM7pxnLRfC+oO7rWOUH3T5oFQA==} 5327 5434 peerDependencies: 5328 5435 '@aws-sdk/client-rds-data': '>=3' 5329 5436 '@cloudflare/workers-types': '>=3' ··· 5384 5491 sqlite3: 5385 5492 optional: true 5386 5493 dependencies: 5387 - '@planetscale/database': 1.7.0 5494 + '@libsql/client': 0.3.1(bufferutil@4.0.7)(encoding@0.1.13)(utf-8-validate@6.0.3) 5388 5495 dev: false 5389 5496 5390 - /drizzle-zod@0.4.4(drizzle-orm@0.27.0)(zod@3.21.4): 5497 + /drizzle-zod@0.4.4(drizzle-orm@0.27.2)(zod@3.21.4): 5391 5498 resolution: {integrity: sha512-XNn0mjQ306Hvg+CuyKV98wnsWBWeTqv+kgE/N79Zj0EdCvjD2kaoN5sFDGFkMVqPQuP7IB1IPs0lEcOij1RvBA==} 5392 5499 peerDependencies: 5393 5500 drizzle-orm: '>=0.23.13' 5394 5501 zod: '*' 5395 5502 dependencies: 5396 - drizzle-orm: 0.27.0(@planetscale/database@1.7.0) 5503 + drizzle-orm: 0.27.2(@libsql/client@0.3.1) 5397 5504 zod: 3.21.4 5398 5505 dev: false 5399 5506 ··· 5423 5530 resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 5424 5531 dev: false 5425 5532 5533 + /encoding@0.1.13: 5534 + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} 5535 + dependencies: 5536 + iconv-lite: 0.6.3 5537 + 5538 + /end-of-stream@1.4.4: 5539 + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} 5540 + dependencies: 5541 + once: 1.4.0 5542 + dev: false 5543 + 5426 5544 /enhanced-resolve@5.15.0: 5427 5545 resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==} 5428 5546 engines: {node: '>=10.13.0'} ··· 6088 6206 strip-final-newline: 3.0.0 6089 6207 dev: false 6090 6208 6209 + /expand-template@2.0.3: 6210 + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} 6211 + engines: {node: '>=6'} 6212 + dev: false 6213 + 6091 6214 /ext@1.7.0: 6092 6215 resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} 6093 6216 dependencies: ··· 6176 6299 dependencies: 6177 6300 flat-cache: 3.0.4 6178 6301 6302 + /file-uri-to-path@1.0.0: 6303 + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} 6304 + dev: false 6305 + 6179 6306 /fill-range@7.0.1: 6180 6307 resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 6181 6308 engines: {node: '>=8'} ··· 6257 6384 resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==} 6258 6385 dev: true 6259 6386 6387 + /fs-constants@1.0.0: 6388 + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} 6389 + dev: false 6390 + 6260 6391 /fs-extra@10.1.0: 6261 6392 resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} 6262 6393 engines: {node: '>=12'} ··· 6364 6495 resolution: {integrity: sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg==} 6365 6496 dependencies: 6366 6497 resolve-pkg-maps: 1.0.0 6498 + 6499 + /github-from-package@0.0.0: 6500 + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} 6501 + dev: false 6367 6502 6368 6503 /github-slugger@2.0.0: 6369 6504 resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} ··· 6808 6943 dependencies: 6809 6944 safer-buffer: 2.1.2 6810 6945 6946 + /iconv-lite@0.6.3: 6947 + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} 6948 + engines: {node: '>=0.10.0'} 6949 + dependencies: 6950 + safer-buffer: 2.1.2 6951 + 6811 6952 /ieee754@1.2.1: 6812 6953 resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} 6813 6954 ··· 7192 7333 /isomorphic-fetch@3.0.0: 7193 7334 resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} 7194 7335 dependencies: 7195 - node-fetch: 2.6.11 7336 + node-fetch: 2.6.11(encoding@0.1.13) 7196 7337 whatwg-fetch: 3.6.2 7197 7338 transitivePeerDependencies: 7198 7339 - encoding ··· 7210 7351 resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} 7211 7352 engines: {node: '>=10'} 7212 7353 dev: true 7354 + 7355 + /js-base64@3.7.5: 7356 + resolution: {integrity: sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA==} 7357 + dev: false 7213 7358 7214 7359 /js-beautify@1.14.8: 7215 7360 resolution: {integrity: sha512-4S7HFeI9YfRvRgKnEweohs0tgJj28InHVIj4Nl8Htf96Y6pHg3+tJrmo4ucAM9f7l4SHbFI3IvFAZ2a1eQPbyg==} ··· 8093 8238 engines: {node: '>=12'} 8094 8239 dev: false 8095 8240 8241 + /mimic-response@3.1.0: 8242 + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} 8243 + engines: {node: '>=10'} 8244 + dev: false 8245 + 8096 8246 /minimatch@3.1.2: 8097 8247 resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 8098 8248 dependencies: ··· 8121 8271 /minimist@1.2.8: 8122 8272 resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} 8123 8273 8274 + /mkdirp-classic@0.5.3: 8275 + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} 8276 + dev: false 8277 + 8124 8278 /mkdirp@0.5.6: 8125 8279 resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} 8126 8280 hasBin: true ··· 8158 8312 resolution: {integrity: sha512-7ZtY5KTCNheRGfEFxnedV5zFiORN1+Y1N6zvPTnHQd8ENUvfaDBeuJDZb2bN/oXwXxu3qkTXDzy57W5vAmDTBw==} 8159 8313 engines: {node: ^14 || ^16 || >=18} 8160 8314 hasBin: true 8315 + dev: false 8316 + 8317 + /napi-build-utils@1.0.2: 8318 + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} 8161 8319 dev: false 8162 8320 8163 8321 /natural-compare-lite@1.4.0: ··· 8265 8423 tslib: 2.5.3 8266 8424 dev: false 8267 8425 8426 + /node-abi@3.45.0: 8427 + resolution: {integrity: sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==} 8428 + engines: {node: '>=10'} 8429 + dependencies: 8430 + semver: 7.5.2 8431 + dev: false 8432 + 8268 8433 /node-domexception@1.0.0: 8269 8434 resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} 8270 8435 engines: {node: '>=10.5.0'} ··· 8274 8439 resolution: {integrity: sha512-VzW+TAk2wE4X9maiKMlT+GsPU4OMmR1U9CrHSmd3DFLn2IcZ9VJ6M6BBugGfYUnPCLSYxXdZy17M0BEJyhUTwg==} 8275 8440 dev: false 8276 8441 8277 - /node-fetch@2.6.11: 8442 + /node-fetch@2.6.11(encoding@0.1.13): 8278 8443 resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} 8279 8444 engines: {node: 4.x || >=6.0.0} 8280 8445 peerDependencies: ··· 8283 8448 encoding: 8284 8449 optional: true 8285 8450 dependencies: 8451 + encoding: 0.1.13 8286 8452 whatwg-url: 5.0.0 8287 8453 dev: false 8288 8454 ··· 8294 8460 fetch-blob: 3.2.0 8295 8461 formdata-polyfill: 4.0.10 8296 8462 dev: false 8463 + 8464 + /node-gyp-build@4.6.0: 8465 + resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} 8466 + hasBin: true 8297 8467 8298 8468 /node-plop@0.26.3: 8299 8469 resolution: {integrity: sha512-Cov028YhBZ5aB7MdMWJEmwyBig43aGL5WT4vdoB28Oitau1zZAcHUn8Sgfk9HM33TqhtLJ9PlM/O0Mv+QpV/4Q==} ··· 8795 8965 picocolors: 1.0.0 8796 8966 source-map-js: 1.0.2 8797 8967 8968 + /prebuild-install@7.1.1: 8969 + resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} 8970 + engines: {node: '>=10'} 8971 + hasBin: true 8972 + dependencies: 8973 + detect-libc: 2.0.1 8974 + expand-template: 2.0.3 8975 + github-from-package: 0.0.0 8976 + minimist: 1.2.8 8977 + mkdirp-classic: 0.5.3 8978 + napi-build-utils: 1.0.2 8979 + node-abi: 3.45.0 8980 + pump: 3.0.0 8981 + rc: 1.2.8 8982 + simple-get: 4.0.1 8983 + tar-fs: 2.1.1 8984 + tunnel-agent: 0.6.0 8985 + dev: false 8986 + 8798 8987 /prelude-ls@1.2.1: 8799 8988 resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} 8800 8989 engines: {node: '>= 0.8.0'} ··· 8922 9111 resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} 8923 9112 dev: false 8924 9113 9114 + /pump@3.0.0: 9115 + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} 9116 + dependencies: 9117 + end-of-stream: 1.4.4 9118 + once: 1.4.0 9119 + dev: false 9120 + 8925 9121 /punycode@2.3.0: 8926 9122 resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} 8927 9123 engines: {node: '>=6'} ··· 8972 9168 ini: 1.3.8 8973 9169 minimist: 1.2.8 8974 9170 strip-json-comments: 2.0.1 8975 - dev: true 8976 9171 8977 9172 /react-day-picker@8.8.0(date-fns@2.30.0)(react@18.2.0): 8978 9173 resolution: {integrity: sha512-QIC3uOuyGGbtypbd5QEggsCSqVaPNu8kzUWquZ7JjW9fuWB9yv7WyixKmnaFelTLXFdq7h7zU6n/aBleBqe/dA==} ··· 9544 9739 /signal-exit@3.0.7: 9545 9740 resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 9546 9741 9742 + /simple-concat@1.0.1: 9743 + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} 9744 + dev: false 9745 + 9746 + /simple-get@4.0.1: 9747 + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} 9748 + dependencies: 9749 + decompress-response: 6.0.0 9750 + once: 1.4.0 9751 + simple-concat: 1.0.1 9752 + dev: false 9753 + 9547 9754 /sisteransi@1.0.5: 9548 9755 resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} 9549 9756 dev: true ··· 9752 9959 /strip-json-comments@2.0.1: 9753 9960 resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} 9754 9961 engines: {node: '>=0.10.0'} 9755 - dev: true 9756 9962 9757 9963 /strip-json-comments@3.1.1: 9758 9964 resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} ··· 9827 10033 /svix-fetch@3.0.0: 9828 10034 resolution: {integrity: sha512-rcADxEFhSqHbraZIsjyZNh4TF6V+koloX1OzZ+AQuObX9mZ2LIMhm1buZeuc5BIZPftZpJCMBsSiBaeszo9tRw==} 9829 10035 dependencies: 9830 - node-fetch: 2.6.11 10036 + node-fetch: 2.6.11(encoding@0.1.13) 9831 10037 whatwg-fetch: 3.6.2 9832 10038 transitivePeerDependencies: 9833 10039 - encoding ··· 9950 10156 engines: {node: '>=6'} 9951 10157 dev: false 9952 10158 10159 + /tar-fs@2.1.1: 10160 + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} 10161 + dependencies: 10162 + chownr: 1.1.4 10163 + mkdirp-classic: 0.5.3 10164 + pump: 3.0.0 10165 + tar-stream: 2.2.0 10166 + dev: false 10167 + 10168 + /tar-stream@2.2.0: 10169 + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} 10170 + engines: {node: '>=6'} 10171 + dependencies: 10172 + bl: 4.1.0 10173 + end-of-stream: 1.4.4 10174 + fs-constants: 1.0.0 10175 + inherits: 2.0.4 10176 + readable-stream: 3.6.2 10177 + dev: false 10178 + 9953 10179 /text-table@0.2.0: 9954 10180 resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} 9955 10181 ··· 10165 10391 dependencies: 10166 10392 tslib: 1.14.1 10167 10393 typescript: 5.1.3 10394 + dev: false 10395 + 10396 + /tunnel-agent@0.6.0: 10397 + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} 10398 + dependencies: 10399 + safe-buffer: 5.2.1 10168 10400 dev: false 10169 10401 10170 10402 /turbo-darwin-64@1.10.6: ··· 10489 10721 react: 18.2.0 10490 10722 dev: false 10491 10723 10724 + /utf-8-validate@6.0.3: 10725 + resolution: {integrity: sha512-uIuGf9TWQ/y+0Lp+KGZCMuJWc3N9BHA+l/UmHd/oUHwJJDeysyTRxNQVkbzsIWfGFbRe3OcgML/i0mvVRPOyDA==} 10726 + engines: {node: '>=6.14.2'} 10727 + requiresBuild: true 10728 + dependencies: 10729 + node-gyp-build: 4.6.0 10730 + 10492 10731 /util-deprecate@1.0.2: 10493 10732 resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} 10494 10733 ··· 10660 10899 10661 10900 /wrappy@1.0.2: 10662 10901 resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 10902 + 10903 + /ws@8.13.0(bufferutil@4.0.7)(utf-8-validate@6.0.3): 10904 + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} 10905 + engines: {node: '>=10.0.0'} 10906 + peerDependencies: 10907 + bufferutil: ^4.0.1 10908 + utf-8-validate: '>=5.0.2' 10909 + peerDependenciesMeta: 10910 + bufferutil: 10911 + optional: true 10912 + utf-8-validate: 10913 + optional: true 10914 + dependencies: 10915 + bufferutil: 4.0.7 10916 + utf-8-validate: 6.0.3 10917 + dev: false 10663 10918 10664 10919 /xtend@4.0.2: 10665 10920 resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}