Openstatus www.openstatus.dev

๐Ÿ”‘ Init clerk webhook (#7)

* ๐Ÿšง wip database schema

* ๐Ÿšง wip database schema

* ๐Ÿšง wip database schema

* ๐Ÿšง wip database schema

* ๐Ÿšง clerk and trpc

* ๐Ÿš€ clerk

* ๐ŸŸข

* ๐Ÿš€ trpc

* ๐Ÿš€ convert to localpackage

* ๐Ÿ”“ pnpm lockfile

* ๐ŸŸข fix build

authored by

Thibault Le Ouay and committed by
GitHub
96483798 d51bd559

+976 -133
+1
apps/web/.env.example
··· 1 1 # For Clerk Auth 2 2 NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY= 3 3 CLERK_SECRET_KEY= 4 + CLERK_WEBHOOK_SECRET= 4 5 5 6 NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in 6 7 NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
+1 -1
apps/web/next.config.mjs
··· 3 3 /** @type {import('next').NextConfig} */ 4 4 const nextConfig = { 5 5 reactStrictMode: true, 6 - transpilePackages: ["ui"], 6 + transpilePackages: ["ui", "@openstatus/api"], 7 7 experimental: { 8 8 serverActions: true, 9 9 },
+10 -2
apps/web/package.json
··· 9 9 "lint": "next lint" 10 10 }, 11 11 "dependencies": { 12 - "@clerk/nextjs": "^4.21.3", 12 + "@clerk/nextjs": "4.21.10", 13 + "@openstatus/api": "workspace:^", 13 14 "@openstatus/db": "workspace:^", 14 15 "@openstatus/tinybird": "workspace:*", 15 16 "@openstatus/upstash": "workspace:*", ··· 17 18 "@radix-ui/react-slot": "^1.0.2", 18 19 "@radix-ui/react-toast": "^1.1.4", 19 20 "@t3-oss/env-nextjs": "0.4.1", 20 - "@upstash/redis": "^1.21.0", 21 + "@trpc/client": "10.32.0", 22 + "@trpc/next": "10.32.0", 23 + "@trpc/react-query": "10.32.0", 24 + "@trpc/server": "10.32.0", 25 + "@upstash/redis": "1.21.0", 21 26 "class-variance-authority": "^0.6.0", 22 27 "clsx": "^1.2.1", 23 28 "cmdk": "^0.2.0", 24 29 "date-fns": "^2.30.0", 25 30 "lucide-react": "^0.244.0", 31 + "micro": "10.0.1", 26 32 "next": "13.4.6", 27 33 "next-plausible": "3.7.2", 28 34 "react": "18.2.0", 29 35 "react-dom": "18.2.0", 30 36 "resend": "^0.15.3", 37 + "superjson": "1.9.1", 38 + "svix": "1.4.12", 31 39 "tailwind-merge": "^1.13.2", 32 40 "tailwindcss-animate": "^1.0.6", 33 41 "ui": "workspace:*",
+1 -1
apps/web/src/app/_components/hero-form.tsx
··· 10 10 action={async (data) => { 11 11 try { 12 12 const number = await addToWaitlist(data); 13 - const formattedNumber = Intl.NumberFormat().format(number); 13 + const formattedNumber = Intl.NumberFormat().format(Number(number)); 14 14 toast({ 15 15 description: `Thank you, you're number ${formattedNumber} on the list.`, 16 16 });
+1 -1
apps/web/src/app/_components/input-search.tsx
··· 83 83 value={inputValue} 84 84 onValueChange={setInputValue} 85 85 onKeyDown={(e) => { 86 - if (e.key === "Escape") inputRef?.current.blur(); 86 + if (e.key === "Escape") inputRef?.current?.blur(); 87 87 }} 88 88 onBlur={() => setOpen(false)} 89 89 onFocus={() => setOpen(true)}
+5
apps/web/src/app/api/ping/route.ts
··· 1 + import { NextResponse } from "next/server"; 2 + 3 + export async function GET() { 4 + return NextResponse.json({ ping: "pong" }, { status: 200 }); 5 + }
+21
apps/web/src/app/api/trpc/edge/[trpc]/route.ts
··· 1 + import type { NextRequest } from "next/server"; 2 + import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; 3 + 4 + import { createTRPCContext } from "@openstatus/api"; 5 + import { edgeRouter } from "@openstatus/api/src/edge"; 6 + 7 + export const runtime = "edge"; 8 + 9 + const handler = (req: NextRequest) => 10 + fetchRequestHandler({ 11 + endpoint: "/api/trpc/edge", 12 + router: edgeRouter, 13 + req: req, 14 + createContext: () => createTRPCContext({ req }), 15 + onError: ({ error }) => { 16 + console.log("Error in tRPC handler (edge)"); 17 + console.error(error); 18 + }, 19 + }); 20 + 21 + export { handler as GET, handler as POST };
+22
apps/web/src/app/api/trpc/lambda/[trpc]/route.ts
··· 1 + import type { NextRequest } from "next/server"; 2 + import { fetchRequestHandler } from "@trpc/server/adapters/fetch"; 3 + 4 + import { createTRPCContext } from "@openstatus/api"; 5 + import { lambdaRouter } from "@openstatus/api/src/lambda"; 6 + 7 + // Stripe is incompatible with Edge runtimes due to using Node.js events 8 + // export const runtime = "edge"; 9 + 10 + const handler = (req: NextRequest) => 11 + fetchRequestHandler({ 12 + endpoint: "/api/trpc/lambda", 13 + router: lambdaRouter, 14 + req: req, 15 + createContext: () => createTRPCContext({ req }), 16 + onError: ({ error }) => { 17 + console.log("Error in tRPC handler (lambda)"); 18 + console.error(error); 19 + }, 20 + }); 21 + 22 + export { handler as GET, handler as POST };
+4
apps/web/src/app/api/v0/cron/route.ts
··· 34 34 const hasUrl = searchParams.has("url"); 35 35 const url = hasUrl ? searchParams.get("url") : `${DEFAULT_URL}/api/v0/ping`; 36 36 37 + if (!url) { 38 + return new Response("Error", { status: 400 }); 39 + } 40 + 37 41 const startTime = Date.now(); 38 42 const res = await fetch(url, { cache: "no-store" }); 39 43 const endTime = Date.now();
+55
apps/web/src/app/api/webhook/clerk/route.ts
··· 1 + import { env } from "@/env.mjs"; 2 + import { NextRequest, NextResponse } from "next/server"; 3 + import { Webhook } from "svix"; 4 + import { createTRPCContext } from "@openstatus/api"; 5 + import { lambdaRouter } from "@openstatus/api/src/lambda"; 6 + import { clerkEvent } from "@openstatus/api/src/router/clerk/type"; 7 + // import { clerkEvent } from "@openstatus/api/src/router/clerk"; 8 + 9 + // export const config = { 10 + // api: { 11 + // bodyParser: false, 12 + // }, 13 + // }; 14 + 15 + export async function POST(req: NextRequest) { 16 + // Get witch headers is missing 17 + // const wh = new Webhook(env.CLERK_WEBHOOK_SECRET); 18 + // const msg = wh.verify(JSON.stringify(await req.json()), req.headers as any); 19 + const json = await req.json(); 20 + const r = clerkEvent.safeParse(json); 21 + if (!r.success) { 22 + return NextResponse.json( 23 + { error: "Internal Server Error" }, 24 + { status: 500 } 25 + ); 26 + } 27 + 28 + const ctx = createTRPCContext({ req }); 29 + const caller = lambdaRouter.createCaller(ctx); 30 + 31 + const event = r.data.type; 32 + switch (event) { 33 + case "user.created": 34 + await caller.clerkRouter.webhooks.userCreated({ data: r.data }); 35 + break; 36 + case "user.updated": 37 + case "user.deleted": 38 + break; 39 + 40 + case "session.created": 41 + case "session.revoked": 42 + case "session.removed": 43 + case "session.ended": 44 + break; 45 + 46 + case "organization.created": 47 + case "organizationMembership.created": 48 + break; 49 + 50 + default: 51 + ((d: never) => console.error(`${d} not handled here`))(event); 52 + return null; 53 + } 54 + return NextResponse.json({ success: true }); 55 + }
+2
apps/web/src/env.mjs
··· 7 7 CLERK_SECRET_KEY: z.string().min(1), 8 8 TINY_BIRD_API_KEY: z.string().min(1), 9 9 RESEND_API_KEY: z.string().min(1), 10 + CLERK_WEBHOOK_SECRET: z.string().min(1), 10 11 }, 11 12 client: { 12 13 NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1), ··· 19 20 CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, 20 21 TINY_BIRD_API_KEY: process.env.TINY_BIRD_API_KEY, 21 22 RESEND_API_KEY: process.env.RESEND_API_KEY, 23 + CLERK_WEBHOOK_SECRET: process.env.CLERK_WEBHOOK_SECRET, 22 24 NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: 23 25 process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, 24 26 NEXT_PUBLIC_CLERK_SIGN_IN_URL: process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL,
+1 -1
apps/web/src/hooks/use-mouse-move.tsx
··· 5 5 export default function useMouseMove() { 6 6 React.useEffect(() => { 7 7 function mouseMoveEvent(e: MouseEvent) { 8 - const scale = window.visualViewport.scale; 8 + const scale = window.visualViewport?.scale; 9 9 // disable mouse movement on viewport zoom - causes page to slow down 10 10 if (scale === 1) { 11 11 const body = document.body;
+7 -1
apps/web/src/middleware.ts
··· 1 1 import { authMiddleware } from "@clerk/nextjs"; 2 2 3 3 export default authMiddleware({ 4 - publicRoutes: ["/", "/api/og", "/api/v0/ping", "/api/v0/cron"], // TODO: later "/api/v0/*" 4 + publicRoutes: [ 5 + "/", 6 + "/api/og", 7 + "/api/webhook/ping", 8 + "/api/v0/cron", 9 + "/api/webhook/clerk", 10 + ], 5 11 }); 6 12 7 13 export const config = {
+25
apps/web/src/trpc/client.ts
··· 1 + import { loggerLink } from "@trpc/client"; 2 + import { experimental_createTRPCNextAppDirClient } from "@trpc/next/app-dir/client"; 3 + import superjson from "superjson"; 4 + 5 + import type { AppRouter } from "@openstatus/api"; 6 + 7 + import { endingLink } from "./shared"; 8 + 9 + export const api = experimental_createTRPCNextAppDirClient<AppRouter>({ 10 + config() { 11 + return { 12 + transformer: superjson, 13 + links: [ 14 + loggerLink({ 15 + enabled: (opts) => 16 + process.env.NODE_ENV === "development" || 17 + (opts.direction === "down" && opts.result instanceof Error), 18 + }), 19 + endingLink(), 20 + ], 21 + }; 22 + }, 23 + }); 24 + 25 + export { type RouterInputs, type RouterOutputs } from "@openstatus/api";
+30
apps/web/src/trpc/server.ts
··· 1 + "use server"; 2 + 3 + import { headers } from "next/headers"; 4 + import { loggerLink } from "@trpc/client"; 5 + import { experimental_createTRPCNextAppDirServer } from "@trpc/next/app-dir/server"; 6 + import superjson from "superjson"; 7 + 8 + import type { AppRouter } from "@openstatus/api"; 9 + 10 + import { endingLink } from "./shared"; 11 + 12 + export const api = experimental_createTRPCNextAppDirServer<AppRouter>({ 13 + config() { 14 + return { 15 + transformer: superjson, 16 + links: [ 17 + loggerLink({ 18 + enabled: (opts) => 19 + process.env.NODE_ENV === "development" || 20 + (opts.direction === "down" && opts.result instanceof Error), 21 + }), 22 + endingLink({ 23 + headers: Object.fromEntries(headers().entries()), 24 + }), 25 + ], 26 + }; 27 + }, 28 + }); 29 + 30 + export { type RouterInputs, type RouterOutputs } from "@openstatus/api";
+40
apps/web/src/trpc/shared.ts
··· 1 + import type { HttpBatchLinkOptions, HTTPHeaders, TRPCLink } from "@trpc/client"; 2 + import { httpBatchLink } from "@trpc/client"; 3 + 4 + import type { AppRouter } from "@openstatus/api"; 5 + 6 + const getBaseUrl = () => { 7 + if (typeof window !== "undefined") return ""; 8 + const vc = process.env.VERCEL_URL; 9 + if (vc) return `https://${vc}`; 10 + return `http://localhost:3000`; 11 + }; 12 + 13 + const lambdas = ["clerk"]; 14 + 15 + export const endingLink = (opts?: { headers?: HTTPHeaders }) => 16 + ((runtime) => { 17 + const sharedOpts = { 18 + headers: opts?.headers, 19 + } satisfies Partial<HttpBatchLinkOptions>; 20 + 21 + const edgeLink = httpBatchLink({ 22 + ...sharedOpts, 23 + url: `${getBaseUrl()}/api/trpc/edge`, 24 + })(runtime); 25 + const lambdaLink = httpBatchLink({ 26 + ...sharedOpts, 27 + url: `${getBaseUrl()}/api/trpc/lambda`, 28 + })(runtime); 29 + 30 + return (ctx) => { 31 + const path = ctx.op.path.split(".") as [string, ...string[]]; 32 + const endpoint = lambdas.includes(path[0]) ? "lambda" : "edge"; 33 + 34 + const newCtx = { 35 + ...ctx, 36 + op: { ...ctx.op, path: path.join(".") }, 37 + }; 38 + return endpoint === "edge" ? edgeLink(newCtx) : lambdaLink(newCtx); 39 + }; 40 + }) satisfies TRPCLink<AppRouter>;
+2 -1
apps/web/tsconfig.json
··· 5 5 "paths": { 6 6 "@/*": ["./src/*"] 7 7 }, 8 - "plugins": [{ "name": "next" }] 8 + "plugins": [{ "name": "next" }], 9 + "strictNullChecks": true 9 10 }, 10 11 "include": [ 11 12 "next-env.d.ts",
+4
packages/api/.eslintrc.cjs
··· 1 + module.exports = { 2 + root: true, 3 + extends: ["custom"], 4 + };
+22
packages/api/index.ts
··· 1 + import type { inferRouterInputs, inferRouterOutputs } from "@trpc/server"; 2 + 3 + import type { AppRouter } from "./src/root"; 4 + 5 + export { createTRPCContext, createInnerTRPCContext } from "./src/trpc"; 6 + 7 + // TODO: Maybe just export `createAction` instead of the whole `trpc` object? 8 + export { t } from "./src/trpc"; 9 + 10 + export type { AppRouter } from "./src/root"; 11 + 12 + /** 13 + * Inference helpers for input types 14 + * @example type HelloInput = RouterInputs['example']['hello'] 15 + **/ 16 + export type RouterInputs = inferRouterInputs<AppRouter>; 17 + 18 + /** 19 + * Inference helpers for output types 20 + * @example type HelloOutput = RouterOutputs['example']['hello'] 21 + **/ 22 + export type RouterOutputs = inferRouterOutputs<AppRouter>;
+24
packages/api/package.json
··· 1 + { 2 + "name": "@openstatus/api", 3 + "version": "1.0.0", 4 + "description": "", 5 + "main": "index.js", 6 + "scripts": { 7 + "test": "echo \"Error: no test specified\" && exit 1" 8 + }, 9 + "dependencies": { 10 + "@clerk/nextjs": "4.21.10", 11 + "@openstatus/db": "workspace:^", 12 + "@trpc/client": "10.32.0", 13 + "@trpc/server": "10.32.0", 14 + "superjson": "1.9.1", 15 + "zod": "3.21.4" 16 + }, 17 + "devDependencies": { 18 + "tsconfig": "workspace:^", 19 + "typescript": "5.1.3" 20 + }, 21 + "keywords": [], 22 + "author": "", 23 + "license": "ISC" 24 + }
+7
packages/api/src/edge.ts
··· 1 + import { workspaceRouter } from "./router/workspace"; 2 + import { createTRPCRouter } from "./trpc"; 3 + 4 + // Deployed to /trpc/edge/** 5 + export const edgeRouter = createTRPCRouter({ 6 + workspace: workspaceRouter, 7 + });
+7
packages/api/src/lambda.ts
··· 1 + import { clerkRouter } from "./router/clerk/webhook"; 2 + import { createTRPCRouter } from "./trpc"; 3 + 4 + // Deployed to /trpc/lambda/** 5 + export const lambdaRouter = createTRPCRouter({ 6 + clerkRouter: clerkRouter, 7 + });
+6
packages/api/src/root.ts
··· 1 + import { edgeRouter } from "./edge"; 2 + import { lambdaRouter } from "./lambda"; 3 + import { mergeRouters } from "./trpc"; 4 + 5 + const appRouter = mergeRouters(edgeRouter, lambdaRouter); 6 + export type AppRouter = typeof appRouter;
+85
packages/api/src/router/clerk/type.ts
··· 1 + import { z } from "zod"; 2 + 3 + export const clerkEvent = z.discriminatedUnion("type", [ 4 + z.object({ 5 + type: z.literal("user.created"), 6 + data: z.object({ 7 + id: z.string(), 8 + // username: z.string(), 9 + created_at: z.number(), 10 + email_addresses: z.array( 11 + z.object({ 12 + email_address: z.string(), 13 + }) 14 + ), 15 + first_name: z.string(), 16 + last_name: z.string(), 17 + }), 18 + }), 19 + z.object({ 20 + type: z.literal("user.updated"), 21 + data: z.object({ 22 + id: z.string(), 23 + updated_at: z.number(), 24 + }), 25 + }), 26 + z.object({ 27 + type: z.literal("user.deleted"), 28 + data: z.object({ 29 + id: z.string(), 30 + }), 31 + }), 32 + z.object({ 33 + type: z.literal("organization.created"), 34 + data: z.object({ 35 + id: z.string(), 36 + slug: z.string(), 37 + name: z.string(), 38 + created_at: z.number(), 39 + }), 40 + }), 41 + z.object({ 42 + type: z.literal("session.created"), 43 + data: z.object({ 44 + id: z.string(), 45 + user_id: z.string(), 46 + created_at: z.number(), 47 + expire_at: z.number(), 48 + }), 49 + }), 50 + z.object({ 51 + type: z.literal("session.revoked"), 52 + data: z.object({ 53 + id: z.string(), 54 + user_id: z.string(), 55 + }), 56 + }), 57 + z.object({ 58 + type: z.literal("session.removed"), 59 + data: z.object({ 60 + id: z.string(), 61 + user_id: z.string(), 62 + }), 63 + }), 64 + z.object({ 65 + type: z.literal("session.ended"), 66 + data: z.object({ 67 + id: z.string(), 68 + user_id: z.string(), 69 + }), 70 + }), 71 + z.object({ 72 + type: z.literal("organizationMembership.created"), 73 + data: z.object({ 74 + created_at: z.number(), 75 + organization: z.object({ 76 + id: z.string(), 77 + slug: z.string(), 78 + name: z.string(), 79 + }), 80 + public_user_data: z.object({ 81 + user_id: z.string(), 82 + }), 83 + }), 84 + }), 85 + ]);
+30
packages/api/src/router/clerk/webhook.ts
··· 1 + import * as z from "zod"; 2 + 3 + import { createTRPCRouter, publicProcedure } from "../../trpc"; 4 + import { user } from "@openstatus/db/src/schema"; 5 + import { clerkEvent } from "./type"; 6 + 7 + export const webhookProcedure = publicProcedure.input( 8 + z.object({ 9 + data: clerkEvent, 10 + }) 11 + ); 12 + 13 + export const webhookRouter = createTRPCRouter({ 14 + userCreated: webhookProcedure.mutation(async (opts) => { 15 + if (opts.input.data.type === "user.created") { 16 + await opts.ctx.db.insert(user).values({ 17 + tenantId: opts.input.data.data.id, 18 + }); 19 + } 20 + }), 21 + userUpdated: webhookProcedure.mutation(async (opts) => { 22 + if (opts.input.data.type === "user.updated") { 23 + // We should do something 24 + } 25 + }), 26 + }); 27 + 28 + export const clerkRouter = createTRPCRouter({ 29 + webhooks: webhookRouter, 30 + });
+11
packages/api/src/router/workspace.ts
··· 1 + import { eq } from "@openstatus/db"; 2 + import { createTRPCRouter, protectedProcedure } from "../trpc"; 3 + import { user } from "@openstatus/db/src/schema"; 4 + 5 + export const workspaceRouter = createTRPCRouter({ 6 + getUserWorkspace: protectedProcedure.query(async (opts) => { 7 + return await opts.ctx.db.query.workspace.findMany({ 8 + with: { user: { where: eq(user.tenantId, opts.ctx.auth.userId) } }, 9 + }); 10 + }), 11 + });
+140
packages/api/src/trpc.ts
··· 1 + //@ts-expect-error FIXME: 2 + import type { NextRequest } from "next/server"; 3 + 4 + import type { 5 + SignedInAuthObject, 6 + SignedOutAuthObject, 7 + } from "@clerk/nextjs/api"; 8 + import { getAuth } from "@clerk/nextjs/server"; 9 + import { initTRPC, TRPCError } from "@trpc/server"; 10 + import superjson from "superjson"; 11 + import { ZodError } from "zod"; 12 + 13 + import { db } from "@openstatus/db"; 14 + 15 + /** 16 + * 1. CONTEXT 17 + * 18 + * This section defines the "contexts" that are available in the backend API 19 + * 20 + * These allow you to access things like the database, the session, etc, when 21 + * processing a request 22 + * 23 + */ 24 + type CreateContextOptions = { 25 + auth: SignedInAuthObject | SignedOutAuthObject | null; 26 + req?: NextRequest; 27 + }; 28 + 29 + /** 30 + * This helper generates the "internals" for a tRPC context. If you need to use 31 + * it, you can export it from here 32 + * 33 + * Examples of things you may need it for: 34 + * - testing, so we dont have to mock Next.js' req/res 35 + * - trpc's `createSSGHelpers` where we don't have req/res 36 + * @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts 37 + */ 38 + export const createInnerTRPCContext = (opts: CreateContextOptions) => { 39 + return { 40 + ...opts, 41 + db, 42 + }; 43 + }; 44 + 45 + /** 46 + * This is the actual context you'll use in your router. It will be used to 47 + * process every request that goes through your tRPC endpoint 48 + * @link https://trpc.io/docs/context 49 + */ 50 + export const createTRPCContext = (opts: { req: NextRequest }) => { 51 + const auth = getAuth(opts.req); 52 + 53 + return createInnerTRPCContext({ 54 + auth, 55 + req: opts.req, 56 + }); 57 + }; 58 + 59 + /** 60 + * 2. INITIALIZATION 61 + * 62 + * This is where the trpc api is initialized, connecting the context and 63 + * transformer 64 + */ 65 + export const t = initTRPC.context<typeof createTRPCContext>().create({ 66 + transformer: superjson, 67 + errorFormatter({ shape, error }) { 68 + return { 69 + ...shape, 70 + data: { 71 + ...shape.data, 72 + zodError: 73 + error.cause instanceof ZodError ? error.cause.flatten() : null, 74 + }, 75 + }; 76 + }, 77 + }); 78 + 79 + /** 80 + * 3. ROUTER & PROCEDURE (THE IMPORTANT BIT) 81 + * 82 + * These are the pieces you use to build your tRPC API. You should import these 83 + * a lot in the /src/server/api/routers folder 84 + */ 85 + 86 + /** 87 + * This is how you create new routers and subrouters in your tRPC API 88 + * @see https://trpc.io/docs/router 89 + */ 90 + export const createTRPCRouter = t.router; 91 + export const mergeRouters = t.mergeRouters; 92 + 93 + /** 94 + * Public (unauthed) procedure 95 + * 96 + * This is the base piece you use to build new queries and mutations on your 97 + * tRPC API. It does not guarantee that a user querying is authorized, but you 98 + * can still access user session data if they are logged in 99 + */ 100 + export const publicProcedure = t.procedure; 101 + 102 + /** 103 + * Reusable middleware that enforces users are logged in before running the 104 + * procedure 105 + */ 106 + const enforceUserIsAuthed = t.middleware(({ ctx, next }) => { 107 + if (!ctx.auth?.userId) { 108 + throw new TRPCError({ code: "UNAUTHORIZED" }); 109 + } 110 + return next({ 111 + ctx: { 112 + auth: { 113 + ...ctx.auth, 114 + userId: ctx.auth.userId, 115 + }, 116 + }, 117 + }); 118 + }); 119 + 120 + /** 121 + * Middleware to parse form data and put it in the rawInput 122 + */ 123 + export const formdataMiddleware = t.middleware(async (opts) => { 124 + const formData = await opts.ctx.req?.formData?.(); 125 + if (!formData) throw new TRPCError({ code: "BAD_REQUEST" }); 126 + 127 + return opts.next({ 128 + rawInput: formData, 129 + }); 130 + }); 131 + /** 132 + * Protected (authed) procedure 133 + * 134 + * If you want a query or mutation to ONLY be accessible to logged in users, use 135 + * this. It verifies the session is valid and guarantees ctx.session.user is not 136 + * null 137 + * 138 + * @see https://trpc.io/docs/procedures 139 + */ 140 + export const protectedProcedure = t.procedure.use(enforceUserIsAuthed);
+4
packages/api/tsconfig.json
··· 1 + { 2 + "extends": "tsconfig/nextjs.json", 3 + "include": ["src", "*.ts"] 4 + }
-1
packages/db/drizzle.config.ts
··· 4 4 import { env } from "./env.mjs"; 5 5 6 6 export default { 7 - driver: "mysql2", 8 7 schema: "./src/schema/index.ts", 9 8 out: "./drizzle", 10 9 dbCredentials: {
+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);
+1 -1
packages/db/drizzle/meta/0000_snapshot.json
··· 312 312 "tables": {}, 313 313 "columns": {} 314 314 } 315 - } 315 + }
+1 -1
packages/db/drizzle/meta/_journal.json
··· 10 10 "breakpoints": true 11 11 } 12 12 ] 13 - } 13 + }
+1 -1
packages/db/package.json
··· 2 2 "name": "@openstatus/db", 3 3 "version": "0.0.1", 4 4 "description": "", 5 - "main": "index.js", 5 + "main": "src/index.ts", 6 6 "scripts": { 7 7 "generate": "drizzle-kit generate:mysql", 8 8 "push": "drizzle-kit push:mysql"
+2 -4
packages/db/src/db.ts
··· 1 - // db.ts 2 1 import { drizzle } from "drizzle-orm/planetscale-serverless"; 3 - 2 + import * as schema from "./schema"; 4 3 import { connect } from "@planetscale/database"; 5 4 import { env } from "../env.mjs"; 6 - 7 5 const config = { 8 6 url: env.DATABASE_URL, 9 7 }; 10 8 11 9 const connection = connect(config); 12 10 13 - export const db = drizzle(connection); 11 + export const db = drizzle(connection, { schema });
+1 -1
packages/db/src/schema/incident.ts
··· 30 30 31 31 incidentId: int("incident_id").notNull(), 32 32 createdAt: timestamp("created_at").notNull().defaultNow(), 33 - updatedAt: timestamp("updated_at").notNull().onUpdateNow(), 33 + updatedAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 34 34 }); 35 35 36 36 export const incidentRelations = relations(incident, ({ one, many }) => ({
+2
packages/db/src/schema/index.ts
··· 1 + import { mysqlTable, serial, text } from "drizzle-orm/mysql-core"; 2 + 1 3 export * from "./incident"; 2 4 export * from "./page"; 3 5 export * from "./monitor";
+1 -1
packages/db/src/schema/monitor.ts
··· 26 26 pageId: int("page_id").notNull(), 27 27 28 28 createdAt: timestamp("created_at").notNull().defaultNow(), 29 - updateddAt: timestamp("updated_at").notNull().onUpdateNow(), 29 + updateddAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 30 30 }); 31 31 32 32 export const monitorRelation = relations(monitor, ({ one }) => ({
+12 -2
packages/db/src/schema/page.ts
··· 1 - import { mysqlTable, varchar, int, timestamp } from "drizzle-orm/mysql-core"; 1 + import { 2 + mysqlTable, 3 + varchar, 4 + int, 5 + timestamp, 6 + text, 7 + } from "drizzle-orm/mysql-core"; 2 8 import { relations } from "drizzle-orm"; 3 9 import { incident } from "./incident"; 10 + 4 11 import { monitor } from "./monitor"; 5 12 6 13 export const page = mysqlTable("page", { ··· 8 15 9 16 workspaceId: int("workspace_id").notNull(), 10 17 18 + title: text("title"), // title of the page 19 + icon: varchar("icon", { length: 256 }), // icon of the page 11 20 slug: varchar("slug", { length: 256 }), // which is used for https://slug.openstatus.dev 12 21 customDomain: varchar("custom_domain", { length: 256 }), 13 22 14 23 // We should store settings of the page 24 + // theme 15 25 16 26 createdAt: timestamp("created_at").notNull().defaultNow(), 17 - updatedAt: timestamp("updated_at").notNull().onUpdateNow(), 27 + updatedAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 18 28 }); 19 29 20 30 export const pageRelations = relations(page, ({ many, one }) => ({
+1 -1
packages/db/src/schema/user.ts
··· 7 7 tenantId: varchar("tenant_id", { length: 256 }), // the clerk User Id 8 8 9 9 createdAt: timestamp("created_at").notNull().defaultNow(), 10 - updatedAt: timestamp("updated_at").notNull().onUpdateNow(), 10 + updatedAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 11 11 }); 12 12 13 13 export const userRelations = relations(user, ({ many }) => ({
+1 -1
packages/db/src/schema/workspace.ts
··· 9 9 stripeId: varchar("stripe_id", { length: 256 }), 10 10 11 11 createdAt: timestamp("created_at").notNull().defaultNow(), 12 - updatedAt: timestamp("updated_at").notNull().onUpdateNow(), 12 + updatedAt: timestamp("updated_at").notNull().defaultNow().onUpdateNow(), 13 13 }); 14 14 15 15 export const workspaceRelations = relations(workspace, ({ many }) => ({
-18
packages/eslint-config-custom/.js
··· 1 - module.exports = { 2 - extends: [ 3 - "next", 4 - "turbo", 5 - "eslint:recommended", 6 - "plugin:@typescript-eslint/recommended", 7 - "prettier", 8 - ], 9 - rules: { 10 - "@next/next/no-html-link-for-pages": "off", 11 - "@typescript-eslint/no-empty-interface": "warn", 12 - }, 13 - parserOptions: { 14 - babelOptions: { 15 - presets: [require.resolve("next/babel")], 16 - }, 17 - }, 18 - };
+1 -10
packages/tinybird/package.json
··· 1 1 { 2 2 "name": "@openstatus/tinybird", 3 3 "version": "0.0.0", 4 - "main": "dist/index.mjs", 5 - "types": "dist/index.d.ts", 4 + "main": "src/index.ts", 6 5 "license": "MIT", 7 - "scripts": { 8 - "build": "tsup", 9 - "dev": "tsup --watch" 10 - }, 11 6 "dependencies": { 12 7 "@chronark/zod-bird": "^0.1.1", 13 8 "zod": "^3.21.4" 14 9 }, 15 10 "devDependencies": { 16 11 "@types/node": "20.3.1", 17 - "tsup": "^7.0.0", 18 12 "typescript": "^5.1.0", 19 13 "tsconfig": "workspace:*" 20 - }, 21 - "publishConfig": { 22 - "access": "public" 23 14 } 24 15 }
+9 -2
packages/tinybird/tsconfig.json
··· 1 1 { 2 2 "extends": "tsconfig/base.json", 3 - "exclude": ["dist"], 3 + "exclude": ["node_modules"], 4 4 "compilerOptions": { 5 - "outDir": "dist" 5 + "esModuleInterop": true, 6 + "forceConsistentCasingInFileNames": true, 7 + "isolatedModules": true, 8 + "moduleResolution": "node", 9 + "preserveWatchOutput": true, 10 + "skipLibCheck": true, 11 + "noEmit": true, 12 + "strict": true 6 13 } 7 14 }
-11
packages/tinybird/tsup.config.ts
··· 1 - import { defineConfig } from "tsup"; 2 - 3 - export default defineConfig({ 4 - entry: ["src/index.ts"], 5 - splitting: false, 6 - sourcemap: true, 7 - clean: true, 8 - dts: "src/index.ts", 9 - format: ["esm"], 10 - // watch if NODE_ENV === "development" 11 - });
+3 -1
packages/tsconfig/base.json
··· 14 14 "noUnusedParameters": false, 15 15 "preserveWatchOutput": true, 16 16 "skipLibCheck": true, 17 - "strict": true 17 + "strict": true, 18 + "strictNullChecks": true 19 + 18 20 }, 19 21 "exclude": ["node_modules"] 20 22 }
+1 -9
packages/upstash/package.json
··· 1 1 { 2 2 "name": "@openstatus/upstash", 3 3 "version": "0.0.0", 4 - "main": "dist/index.mjs", 5 - "types": "dist/index.d.ts", 6 4 "license": "MIT", 7 - "scripts": { 8 - "build": "tsup", 9 - "dev": "tsup --watch" 10 - }, 5 + "main": "./src/index.ts", 11 6 "dependencies": { 12 7 "@upstash/kafka": "^1.3.3", 13 8 "@upstash/qstash": "^0.3.6", ··· 19 14 "tsconfig": "workspace:*", 20 15 "tsup": "^7.0.0", 21 16 "typescript": "^5.1.0" 22 - }, 23 - "publishConfig": { 24 - "access": "public" 25 17 } 26 18 }
+9 -2
packages/upstash/tsconfig.json
··· 1 1 { 2 2 "extends": "tsconfig/base.json", 3 - "exclude": ["dist"], 3 + "exclude": ["node_modules"], 4 4 "compilerOptions": { 5 - "outDir": "dist" 5 + "esModuleInterop": true, 6 + "forceConsistentCasingInFileNames": true, 7 + "isolatedModules": true, 8 + "moduleResolution": "node", 9 + "preserveWatchOutput": true, 10 + "skipLibCheck": true, 11 + "noEmit": true, 12 + "strict": true 6 13 } 7 14 }
-11
packages/upstash/tsup.config.ts
··· 1 - import { defineConfig } from "tsup"; 2 - 3 - export default defineConfig({ 4 - entry: ["src/index.ts"], 5 - splitting: false, 6 - sourcemap: true, 7 - clean: true, 8 - dts: "src/index.ts", 9 - format: ["esm"], 10 - // watch if NODE_ENV === "development" 11 - });
+317 -47
pnpm-lock.yaml
··· 22 22 version: 2.8.8 23 23 turbo: 24 24 specifier: latest 25 - version: 1.10.3 25 + version: 1.10.5 26 26 typescript: 27 27 specifier: 5.1.3 28 28 version: 5.1.3 ··· 64 64 apps/web: 65 65 dependencies: 66 66 '@clerk/nextjs': 67 - specifier: ^4.21.3 68 - version: 4.21.3(next@13.4.6)(react-dom@18.2.0)(react@18.2.0) 67 + specifier: 4.21.10 68 + version: 4.21.10(next@13.4.6)(react-dom@18.2.0)(react@18.2.0) 69 + '@openstatus/api': 70 + specifier: workspace:^ 71 + version: link:../../packages/api 69 72 '@openstatus/db': 70 73 specifier: workspace:^ 71 74 version: link:../../packages/db ··· 87 90 '@t3-oss/env-nextjs': 88 91 specifier: 0.4.1 89 92 version: 0.4.1(typescript@5.1.3)(zod@3.21.4) 93 + '@trpc/client': 94 + specifier: 10.32.0 95 + version: 10.32.0(@trpc/server@10.32.0) 96 + '@trpc/next': 97 + specifier: 10.32.0 98 + version: 10.32.0(@tanstack/react-query@4.29.19)(@trpc/client@10.32.0)(@trpc/react-query@10.32.0)(@trpc/server@10.32.0)(next@13.4.6)(react-dom@18.2.0)(react@18.2.0) 99 + '@trpc/react-query': 100 + specifier: 10.32.0 101 + version: 10.32.0(@tanstack/react-query@4.29.19)(@trpc/client@10.32.0)(@trpc/server@10.32.0)(react-dom@18.2.0)(react@18.2.0) 102 + '@trpc/server': 103 + specifier: 10.32.0 104 + version: 10.32.0 90 105 '@upstash/redis': 91 - specifier: ^1.21.0 106 + specifier: 1.21.0 92 107 version: 1.21.0 93 108 class-variance-authority: 94 109 specifier: ^0.6.0 ··· 105 120 lucide-react: 106 121 specifier: ^0.244.0 107 122 version: 0.244.0(react@18.2.0) 123 + micro: 124 + specifier: 10.0.1 125 + version: 10.0.1 108 126 next: 109 127 specifier: 13.4.6 110 128 version: 13.4.6(react-dom@18.2.0)(react@18.2.0) ··· 120 138 resend: 121 139 specifier: ^0.15.3 122 140 version: 0.15.3 141 + superjson: 142 + specifier: 1.9.1 143 + version: 1.9.1 144 + svix: 145 + specifier: 1.4.12 146 + version: 1.4.12 123 147 tailwind-merge: 124 148 specifier: ^1.13.2 125 149 version: 1.13.2 ··· 161 185 specifier: 5.1.3 162 186 version: 5.1.3 163 187 188 + packages/api: 189 + dependencies: 190 + '@clerk/nextjs': 191 + specifier: 4.21.10 192 + version: 4.21.10(next@13.4.6)(react-dom@18.2.0)(react@18.2.0) 193 + '@openstatus/db': 194 + specifier: workspace:^ 195 + version: link:../db 196 + '@trpc/client': 197 + specifier: 10.32.0 198 + version: 10.32.0(@trpc/server@10.32.0) 199 + '@trpc/server': 200 + specifier: 10.32.0 201 + version: 10.32.0 202 + superjson: 203 + specifier: 1.9.1 204 + version: 1.9.1 205 + zod: 206 + specifier: 3.21.4 207 + version: 3.21.4 208 + devDependencies: 209 + tsconfig: 210 + specifier: workspace:^ 211 + version: link:../tsconfig 212 + typescript: 213 + specifier: 5.1.3 214 + version: 5.1.3 215 + 164 216 packages/db: 165 217 dependencies: 166 218 '@planetscale/database': ··· 241 293 tsconfig: 242 294 specifier: workspace:* 243 295 version: link:../tsconfig 244 - tsup: 245 - specifier: ^7.0.0 246 - version: 7.0.0(typescript@5.1.3) 247 296 typescript: 248 297 specifier: ^5.1.0 249 298 version: 5.1.3 ··· 329 378 zod: 3.21.4 330 379 dev: false 331 380 332 - /@clerk/backend@0.23.1: 333 - resolution: {integrity: sha512-2y0QRkPoGSJf/fcgRmOMY0hz7DfZpo/4kUObwaDuDz3B0OUi7NnyuN3FVDdFw2cPKikusXeJo4V4r/HcjX0teg==} 381 + /@clerk/backend@0.23.5: 382 + resolution: {integrity: sha512-x+NCRvgaVFbAQX2r5hJ6SRI1JnQWD8HAfKxZb+op0KBuKvnk1shpDX67n/23ehx+YG5rQ7FbbKHXyrO5chM5Mw==} 334 383 engines: {node: '>=14'} 335 384 dependencies: 336 - '@clerk/types': 3.42.0 385 + '@clerk/types': 3.46.0 337 386 '@peculiar/webcrypto': 1.4.1 338 387 '@types/node': 16.18.6 339 388 deepmerge: 4.2.2 ··· 342 391 tslib: 2.4.1 343 392 dev: false 344 393 345 - /@clerk/clerk-react@4.20.1(react@18.2.0): 346 - resolution: {integrity: sha512-LMuGP9zXxY9LHKwGwN37bR9jYPY/aDCj+iToJjutrqEO1Z7OPbh6IUn4TGmLXE5M4WbFjqbH0oQE+m1QfejPAA==} 394 + /@clerk/clerk-react@4.20.5(react@18.2.0): 395 + resolution: {integrity: sha512-y5edxot+7adnyUqOGNgS7bEA3eoM53FMC8jV8VmUFvKLkOOMQpgfdo3/I7PWoTrRaNwqNWmhQGy1J3uqw8gv4g==} 347 396 engines: {node: '>=14'} 348 397 peerDependencies: 349 398 react: '>=16' 350 399 dependencies: 351 400 '@clerk/shared': 0.19.1(react@18.2.0) 352 - '@clerk/types': 3.42.0 401 + '@clerk/types': 3.46.0 353 402 react: 18.2.0 354 403 swr: 1.3.0(react@18.2.0) 355 404 tslib: 2.4.1 356 405 dev: false 357 406 358 - /@clerk/clerk-sdk-node@4.10.7: 359 - resolution: {integrity: sha512-s1X+pJIJrWTrA/VxUEmjkuhQcMgl0h9AqGFl3JlHj1DYktb0jKQoGkB0sOBVoY3AV6YLLllgN0l2raXAC47zMQ==} 407 + /@clerk/clerk-sdk-node@4.10.12: 408 + resolution: {integrity: sha512-6LzLFEMZMnUE4O19XOW/6LAoAnHP7mZ2scMCib4dOvTRQxcZz1ql34ZMzewNYKrS6V5loQlslc1bnPlJ2zoX3g==} 360 409 engines: {node: '>=14'} 361 410 dependencies: 362 - '@clerk/backend': 0.23.1 363 - '@clerk/types': 3.42.0 411 + '@clerk/backend': 0.23.5 412 + '@clerk/types': 3.46.0 364 413 '@types/cookies': 0.7.7 365 414 '@types/express': 4.17.14 366 415 '@types/node-fetch': 2.6.2 ··· 370 419 tslib: 2.4.1 371 420 dev: false 372 421 373 - /@clerk/nextjs@4.21.3(next@13.4.6)(react-dom@18.2.0)(react@18.2.0): 374 - resolution: {integrity: sha512-JUlaolOZ01kBAslJtl8QOzFTvpPeUDK/bV1Eg5WKPVhUhgBPxm1YCosrsqsTuUUjdsUlvRFyHfYN0SJpaC2t6A==} 422 + /@clerk/nextjs@4.21.10(next@13.4.6)(react-dom@18.2.0)(react@18.2.0): 423 + resolution: {integrity: sha512-5G02qZOBwbYvBxbHVPKpINyhZ1a3TLZ3noBExx5JHo8+UbpEp7ENd1TyFF/oO0EWG/VTbloP1Gegjm2XG9KeKw==} 375 424 engines: {node: '>=14'} 376 425 peerDependencies: 377 426 next: '>=10' 378 427 react: ^17.0.2 || ^18.0.0-0 379 428 react-dom: ^17.0.2 || ^18.0.0-0 380 429 dependencies: 381 - '@clerk/backend': 0.23.1 382 - '@clerk/clerk-react': 4.20.1(react@18.2.0) 383 - '@clerk/clerk-sdk-node': 4.10.7 384 - '@clerk/types': 3.42.0 430 + '@clerk/backend': 0.23.5 431 + '@clerk/clerk-react': 4.20.5(react@18.2.0) 432 + '@clerk/clerk-sdk-node': 4.10.12 433 + '@clerk/types': 3.46.0 385 434 next: 13.4.6(react-dom@18.2.0)(react@18.2.0) 386 435 path-to-regexp: 6.2.1 387 436 react: 18.2.0 ··· 400 449 swr: 1.3.0(react@18.2.0) 401 450 dev: false 402 451 403 - /@clerk/types@3.42.0: 404 - resolution: {integrity: sha512-wEiBJFT3/Itzmu3jQfHK4zCMTqiE4fUheB1fpYx8JE2q498wzjTEHpglgxl88c0tudtWomUKqXIMJnBBEVVZBg==} 452 + /@clerk/types@3.46.0: 453 + resolution: {integrity: sha512-IooGZ64uARKg+GS6b38usrWqhzU0PcrDbZBaZm4JmtYd5CZbWABklBNkiXQhnnaKYdvHr5K8vhJd5spsJarNpw==} 405 454 engines: {node: '>=14'} 406 455 dependencies: 407 456 csstype: 3.1.1 ··· 1824 1873 selderee: 0.10.0 1825 1874 dev: false 1826 1875 1876 + /@stablelib/base64@1.0.1: 1877 + resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} 1878 + dev: false 1879 + 1827 1880 /@swc/helpers@0.5.1: 1828 1881 resolution: {integrity: sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==} 1829 1882 dependencies: ··· 1849 1902 '@t3-oss/env-core': 0.4.1(typescript@5.1.3)(zod@3.21.4) 1850 1903 typescript: 5.1.3 1851 1904 zod: 3.21.4 1905 + dev: false 1906 + 1907 + /@tanstack/query-core@4.29.19: 1908 + resolution: {integrity: sha512-uPe1DukeIpIHpQi6UzIgBcXsjjsDaLnc7hF+zLBKnaUlh7jFE/A+P8t4cU4VzKPMFB/C970n/9SxtpO5hmIRgw==} 1909 + dev: false 1910 + 1911 + /@tanstack/react-query@4.29.19(react-dom@18.2.0)(react@18.2.0): 1912 + resolution: {integrity: sha512-XiTIOHHQ5Cw1WUlHaD4fmVUMhoWjuNJlAeJGq7eM4BraI5z7y8WkZO+NR8PSuRnQGblpuVdjClQbDFtwxTtTUw==} 1913 + peerDependencies: 1914 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 1915 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 1916 + react-native: '*' 1917 + peerDependenciesMeta: 1918 + react-dom: 1919 + optional: true 1920 + react-native: 1921 + optional: true 1922 + dependencies: 1923 + '@tanstack/query-core': 4.29.19 1924 + react: 18.2.0 1925 + react-dom: 18.2.0(react@18.2.0) 1926 + use-sync-external-store: 1.2.0(react@18.2.0) 1927 + dev: false 1928 + 1929 + /@trpc/client@10.32.0(@trpc/server@10.32.0): 1930 + resolution: {integrity: sha512-hrj6XV84nE6DH5AmsPJ0JzIRcx3f6zU0tvS705DnZtNBOoMk7Lx+wX+KCDxj4DxLsTXC+roAxZxWwAB6/LGsXA==} 1931 + peerDependencies: 1932 + '@trpc/server': 10.32.0 1933 + dependencies: 1934 + '@trpc/server': 10.32.0 1935 + dev: false 1936 + 1937 + /@trpc/next@10.32.0(@tanstack/react-query@4.29.19)(@trpc/client@10.32.0)(@trpc/react-query@10.32.0)(@trpc/server@10.32.0)(next@13.4.6)(react-dom@18.2.0)(react@18.2.0): 1938 + resolution: {integrity: sha512-qJ3yvJDTVmiOOPW1x/FCpmOvtcMJXnP2t3EbcUFrqwgH+D1KdbU2Kk1iSa89Gwy/BBEmXUxaKkWoM3e4Id80gw==} 1939 + peerDependencies: 1940 + '@tanstack/react-query': ^4.18.0 1941 + '@trpc/client': 10.32.0 1942 + '@trpc/react-query': 10.32.0 1943 + '@trpc/server': 10.32.0 1944 + next: '*' 1945 + react: '>=16.8.0' 1946 + react-dom: '>=16.8.0' 1947 + dependencies: 1948 + '@tanstack/react-query': 4.29.19(react-dom@18.2.0)(react@18.2.0) 1949 + '@trpc/client': 10.32.0(@trpc/server@10.32.0) 1950 + '@trpc/react-query': 10.32.0(@tanstack/react-query@4.29.19)(@trpc/client@10.32.0)(@trpc/server@10.32.0)(react-dom@18.2.0)(react@18.2.0) 1951 + '@trpc/server': 10.32.0 1952 + next: 13.4.6(react-dom@18.2.0)(react@18.2.0) 1953 + react: 18.2.0 1954 + react-dom: 18.2.0(react@18.2.0) 1955 + react-ssr-prepass: 1.5.0(react@18.2.0) 1956 + dev: false 1957 + 1958 + /@trpc/react-query@10.32.0(@tanstack/react-query@4.29.19)(@trpc/client@10.32.0)(@trpc/server@10.32.0)(react-dom@18.2.0)(react@18.2.0): 1959 + resolution: {integrity: sha512-M4W1aGm3VAfQ9u4FJyK8M+pkcAV4lp32ZHxKnkRydxcsladhsqveZC9oqZqwklprEcYHtWU8v3R+jRGUjfCxpw==} 1960 + peerDependencies: 1961 + '@tanstack/react-query': ^4.18.0 1962 + '@trpc/client': 10.32.0 1963 + '@trpc/server': 10.32.0 1964 + react: '>=16.8.0' 1965 + react-dom: '>=16.8.0' 1966 + dependencies: 1967 + '@tanstack/react-query': 4.29.19(react-dom@18.2.0)(react@18.2.0) 1968 + '@trpc/client': 10.32.0(@trpc/server@10.32.0) 1969 + '@trpc/server': 10.32.0 1970 + react: 18.2.0 1971 + react-dom: 18.2.0(react@18.2.0) 1972 + dev: false 1973 + 1974 + /@trpc/server@10.32.0: 1975 + resolution: {integrity: sha512-C4HRHpaffw2pekpfNSHQtwlocq6kwAQq48mR9RIsUZGNbjXZbgvBC927vRP6QPAoG+n4oHPWyZ9G1hs3KMcPiw==} 1852 1976 dev: false 1853 1977 1854 1978 /@tsconfig/node10@1.0.9: ··· 2282 2406 normalize-path: 3.0.0 2283 2407 picomatch: 2.3.1 2284 2408 2409 + /arg@4.1.0: 2410 + resolution: {integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==} 2411 + dev: false 2412 + 2285 2413 /arg@4.1.3: 2286 2414 resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} 2287 2415 dev: true ··· 2516 2644 streamsearch: 1.1.0 2517 2645 dev: false 2518 2646 2647 + /bytes@3.1.0: 2648 + resolution: {integrity: sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==} 2649 + engines: {node: '>= 0.8'} 2650 + dev: false 2651 + 2519 2652 /cac@6.7.14: 2520 2653 resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 2521 2654 engines: {node: '>=8'} ··· 2774 2907 upper-case: 1.1.3 2775 2908 dev: true 2776 2909 2910 + /content-type@1.0.4: 2911 + resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} 2912 + engines: {node: '>= 0.6'} 2913 + dev: false 2914 + 2777 2915 /cookie@0.5.0: 2778 2916 resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} 2779 2917 engines: {node: '>= 0.6'} 2780 2918 dev: false 2781 2919 2920 + /copy-anything@3.0.5: 2921 + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} 2922 + engines: {node: '>=12.13'} 2923 + dependencies: 2924 + is-what: 4.1.15 2925 + dev: false 2926 + 2782 2927 /core-js-pure@3.31.0: 2783 2928 resolution: {integrity: sha512-/AnE9Y4OsJZicCzIe97JP5XoPKQJfTuEG43aEVLFJGOJpyqELod+pE6LEl63DfG1Mp8wX97LDaDpy1GmLEUxlg==} 2784 2929 requiresBuild: true ··· 2915 3060 /delayed-stream@1.0.0: 2916 3061 resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} 2917 3062 engines: {node: '>=0.4.0'} 3063 + dev: false 3064 + 3065 + /depd@1.1.2: 3066 + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} 3067 + engines: {node: '>= 0.6'} 2918 3068 dev: false 2919 3069 2920 3070 /dequal@2.0.3: ··· 3214 3364 es5-ext: 0.10.62 3215 3365 es6-symbol: 3.1.3 3216 3366 dev: true 3367 + 3368 + /es6-promise@4.2.8: 3369 + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} 3370 + dev: false 3217 3371 3218 3372 /es6-symbol@3.1.3: 3219 3373 resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} ··· 3728 3882 /fast-levenshtein@2.0.6: 3729 3883 resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} 3730 3884 3885 + /fast-sha256@1.3.0: 3886 + resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} 3887 + dev: false 3888 + 3731 3889 /fastq@1.15.0: 3732 3890 resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} 3733 3891 dependencies: ··· 4089 4247 entities: 4.5.0 4090 4248 dev: false 4091 4249 4250 + /http-errors@1.7.3: 4251 + resolution: {integrity: sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==} 4252 + engines: {node: '>= 0.6'} 4253 + dependencies: 4254 + depd: 1.1.2 4255 + inherits: 2.0.4 4256 + setprototypeof: 1.1.1 4257 + statuses: 1.5.0 4258 + toidentifier: 1.0.0 4259 + dev: false 4260 + 4092 4261 /human-signals@2.1.0: 4093 4262 resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} 4094 4263 engines: {node: '>=10.17.0'} ··· 4103 4272 engines: {node: '>=0.10.0'} 4104 4273 dependencies: 4105 4274 safer-buffer: 2.1.2 4106 - dev: true 4107 4275 4108 4276 /ieee754@1.2.1: 4109 4277 resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} ··· 4390 4558 call-bind: 1.0.2 4391 4559 dev: false 4392 4560 4561 + /is-what@4.1.15: 4562 + resolution: {integrity: sha512-uKua1wfy3Yt+YqsD6mTUEa2zSi3G1oPlqTflgaPJ7z63vUGN5pxFpnQfeSLMFnJDEsdvOtkp1rUWkYjB4YfhgA==} 4563 + engines: {node: '>=12.13'} 4564 + dev: false 4565 + 4393 4566 /is-whitespace@0.3.0: 4394 4567 resolution: {integrity: sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg==} 4395 4568 engines: {node: '>=0.10.0'} ··· 4641 4814 resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 4642 4815 engines: {node: '>= 8'} 4643 4816 4817 + /micro@10.0.1: 4818 + resolution: {integrity: sha512-9uwZSsUrqf6+4FLLpiPj5TRWQv5w5uJrJwsx1LR/TjqvQmKC1XnGQ9OHrFwR3cbZ46YqPqxO/XJCOpWnqMPw2Q==} 4819 + engines: {node: '>= 16.0.0'} 4820 + hasBin: true 4821 + dependencies: 4822 + arg: 4.1.0 4823 + content-type: 1.0.4 4824 + raw-body: 2.4.1 4825 + dev: false 4826 + 4644 4827 /micromatch@4.0.5: 4645 4828 resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 4646 4829 engines: {node: '>=8.6'} ··· 5221 5404 engines: {node: '>=6.0.0'} 5222 5405 dev: false 5223 5406 5407 + /querystringify@2.2.0: 5408 + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} 5409 + dev: false 5410 + 5224 5411 /queue-microtask@1.2.3: 5225 5412 resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 5226 5413 5227 5414 /quick-lru@4.0.1: 5228 5415 resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} 5229 5416 engines: {node: '>=8'} 5417 + dev: false 5418 + 5419 + /raw-body@2.4.1: 5420 + resolution: {integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==} 5421 + engines: {node: '>= 0.8'} 5422 + dependencies: 5423 + bytes: 3.1.0 5424 + http-errors: 1.7.3 5425 + iconv-lite: 0.4.24 5426 + unpipe: 1.0.0 5230 5427 dev: false 5231 5428 5232 5429 /rc@1.2.8: ··· 5307 5504 use-sidecar: 1.1.2(@types/react@18.2.12)(react@18.2.0) 5308 5505 dev: false 5309 5506 5507 + /react-ssr-prepass@1.5.0(react@18.2.0): 5508 + resolution: {integrity: sha512-yFNHrlVEReVYKsLI5lF05tZoHveA5pGzjFbFJY/3pOqqjGOmMmqx83N4hIjN2n6E1AOa+eQEUxs3CgRnPmT0RQ==} 5509 + peerDependencies: 5510 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 5511 + dependencies: 5512 + react: 18.2.0 5513 + dev: false 5514 + 5310 5515 /react-style-singleton@2.2.1(@types/react@18.2.12)(react@18.2.0): 5311 5516 resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} 5312 5517 engines: {node: '>=10'} ··· 5376 5581 rc: 1.2.8 5377 5582 dev: true 5378 5583 5584 + /requires-port@1.0.0: 5585 + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} 5586 + dev: false 5587 + 5379 5588 /resend@0.15.3: 5380 5589 resolution: {integrity: sha512-dzXHBaOjOS3ufBGjqiJjMe7LnproEn/jiAyBjg6IBtp56MCfih0O4IS4JeBcfj3y2Afm+tZITfoZAylKWLEJOg==} 5381 5590 dependencies: ··· 5484 5693 5485 5694 /safer-buffer@2.1.2: 5486 5695 resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 5487 - dev: true 5488 5696 5489 5697 /scheduler@0.23.0: 5490 5698 resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} ··· 5522 5730 upper-case-first: 1.1.2 5523 5731 dev: true 5524 5732 5733 + /setprototypeof@1.1.1: 5734 + resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} 5735 + dev: false 5736 + 5525 5737 /shebang-command@2.0.0: 5526 5738 resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 5527 5739 engines: {node: '>=8'} ··· 5612 5824 dependencies: 5613 5825 whatwg-url: 7.1.0 5614 5826 dev: true 5827 + 5828 + /statuses@1.5.0: 5829 + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} 5830 + engines: {node: '>= 0.6'} 5831 + dev: false 5615 5832 5616 5833 /streamsearch@1.1.0: 5617 5834 resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} ··· 5730 5947 pirates: 4.0.5 5731 5948 ts-interface-checker: 0.1.13 5732 5949 5950 + /superjson@1.9.1: 5951 + resolution: {integrity: sha512-oT3HA2nPKlU1+5taFgz/HDy+GEaY+CWEbLzaRJVD4gZ7zMVVC4GDNFdgvAZt6/VuIk6D2R7RtPAiCHwmdzlMmg==} 5952 + engines: {node: '>=10'} 5953 + dependencies: 5954 + copy-anything: 3.0.5 5955 + dev: false 5956 + 5733 5957 /supports-color@5.5.0: 5734 5958 resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 5735 5959 engines: {node: '>=4'} ··· 5747 5971 resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 5748 5972 engines: {node: '>= 0.4'} 5749 5973 5974 + /svix-fetch@3.0.0: 5975 + resolution: {integrity: sha512-rcADxEFhSqHbraZIsjyZNh4TF6V+koloX1OzZ+AQuObX9mZ2LIMhm1buZeuc5BIZPftZpJCMBsSiBaeszo9tRw==} 5976 + dependencies: 5977 + node-fetch: 2.6.11 5978 + whatwg-fetch: 3.6.2 5979 + transitivePeerDependencies: 5980 + - encoding 5981 + dev: false 5982 + 5983 + /svix@1.4.12: 5984 + resolution: {integrity: sha512-0OtwtbjrQ226aIhfAaRhQDKABFOSIEQpiqAEdLqEsE6AnFgu9OcI3DY1A2om+AqPWnURiEnIytsjEU11SPATwA==} 5985 + dependencies: 5986 + '@stablelib/base64': 1.0.1 5987 + es6-promise: 4.2.8 5988 + fast-sha256: 1.3.0 5989 + svix-fetch: 3.0.0 5990 + url-parse: 1.5.10 5991 + transitivePeerDependencies: 5992 + - encoding 5993 + dev: false 5994 + 5750 5995 /swap-case@1.1.2: 5751 5996 resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} 5752 5997 dependencies: ··· 5884 6129 to-no-case: 1.0.2 5885 6130 dev: false 5886 6131 6132 + /toidentifier@1.0.0: 6133 + resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} 6134 + engines: {node: '>=0.6'} 6135 + dev: false 6136 + 5887 6137 /tr46@0.0.3: 5888 6138 resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} 5889 6139 dev: false ··· 5998 6248 typescript: 5.1.3 5999 6249 dev: false 6000 6250 6001 - /turbo-darwin-64@1.10.3: 6002 - resolution: {integrity: sha512-IIB9IomJGyD3EdpSscm7Ip1xVWtYb7D0x7oH3vad3gjFcjHJzDz9xZ/iw/qItFEW+wGFcLSRPd+1BNnuLM8AsA==} 6251 + /turbo-darwin-64@1.10.5: 6252 + resolution: {integrity: sha512-fIHu+fcW7upaZEfeneoRbZjdrcsj/NxUg7IjZZmlCjgbS9Ofl8RhRid5A1L31AUK3kkqRxzagHc4WZ5x4quBgg==} 6003 6253 cpu: [x64] 6004 6254 os: [darwin] 6005 6255 requiresBuild: true 6006 6256 dev: true 6007 6257 optional: true 6008 6258 6009 - /turbo-darwin-arm64@1.10.3: 6010 - resolution: {integrity: sha512-SBNmOZU9YEB0eyNIxeeQ+Wi0Ufd+nprEVp41rgUSRXEIpXjsDjyBnKnF+sQQj3+FLb4yyi/yZQckB+55qXWEsw==} 6259 + /turbo-darwin-arm64@1.10.5: 6260 + resolution: {integrity: sha512-uv0sDWizuxVvdSjaKvWdPdX4aZ8IZeYJwTJRZwLNRxZV56/1LZD65gyQIqsSNVRHuXI199yahmB+7PMJNpZFdw==} 6011 6261 cpu: [arm64] 6012 6262 os: [darwin] 6013 6263 requiresBuild: true 6014 6264 dev: true 6015 6265 optional: true 6016 6266 6017 - /turbo-linux-64@1.10.3: 6018 - resolution: {integrity: sha512-kvAisGKE7xHJdyMxZLvg53zvHxjqPK1UVj4757PQqtx9dnjYHSc8epmivE6niPgDHon5YqImzArCjVZJYpIGHQ==} 6267 + /turbo-linux-64@1.10.5: 6268 + resolution: {integrity: sha512-hI0rErgwxNmuBCNGldhJkjSbb+mT+vjfmBVKcMI/bnBmu/KU7irCrKMe5Vas280teqBrC33GgVfXndJo2cJ1DA==} 6019 6269 cpu: [x64] 6020 6270 os: [linux] 6021 6271 requiresBuild: true 6022 6272 dev: true 6023 6273 optional: true 6024 6274 6025 - /turbo-linux-arm64@1.10.3: 6026 - resolution: {integrity: sha512-Qgaqln0IYRgyL0SowJOi+PNxejv1I2xhzXOI+D+z4YHbgSx87ox1IsALYBlK8VRVYY8VCXl+PN12r1ioV09j7A==} 6275 + /turbo-linux-arm64@1.10.5: 6276 + resolution: {integrity: sha512-JAygWZjTuD6e7w0KSGzy7UxYqeLIpGfZDne+4MGRc8I5VeWZ6i0HWTqhhIu2/A8AuklYcoj8LkOZxCnMOF3odQ==} 6027 6277 cpu: [arm64] 6028 6278 os: [linux] 6029 6279 requiresBuild: true 6030 6280 dev: true 6031 6281 optional: true 6032 6282 6033 - /turbo-windows-64@1.10.3: 6034 - resolution: {integrity: sha512-rbH9wManURNN8mBnN/ZdkpUuTvyVVEMiUwFUX4GVE5qmV15iHtZfDLUSGGCP2UFBazHcpNHG1OJzgc55GFFrUw==} 6283 + /turbo-windows-64@1.10.5: 6284 + resolution: {integrity: sha512-6w2GOKmlWEAl6QkC4c2j2ZLTwB+RK6oIDRT2KqF1m07KkY6pebEzbPZLHuP08QV+SE0t+prAn+kn7hkHYkwM+Q==} 6035 6285 cpu: [x64] 6036 6286 os: [win32] 6037 6287 requiresBuild: true 6038 6288 dev: true 6039 6289 optional: true 6040 6290 6041 - /turbo-windows-arm64@1.10.3: 6042 - resolution: {integrity: sha512-ThlkqxhcGZX39CaTjsHqJnqVe+WImjX13pmjnpChz6q5HHbeRxaJSFzgrHIOt0sUUVx90W/WrNRyoIt/aafniw==} 6291 + /turbo-windows-arm64@1.10.5: 6292 + resolution: {integrity: sha512-3eeHRJPU+5zWa/iiikoBoPlNd74Y+L9lrG6ZsDZdzUYxNRTMrZbto1Bu1UF77t10TXeT9BsZRXjquKqrA7R7tg==} 6043 6293 cpu: [arm64] 6044 6294 os: [win32] 6045 6295 requiresBuild: true 6046 6296 dev: true 6047 6297 optional: true 6048 6298 6049 - /turbo@1.10.3: 6050 - resolution: {integrity: sha512-U4gKCWcKgLcCjQd4Pl8KJdfEKumpyWbzRu75A6FCj6Ctea1PIm58W6Ltw1QXKqHrl2pF9e1raAskf/h6dlrPCA==} 6299 + /turbo@1.10.5: 6300 + resolution: {integrity: sha512-4yxHTrlugJhef4eXuyrPJtrgUZWlbcwmSb8iZL/5UzNjCmx+anOm1nfW2XFrZFKy4v0+/fUlqw8LkTgGVsOKaQ==} 6051 6301 hasBin: true 6052 6302 requiresBuild: true 6053 6303 optionalDependencies: 6054 - turbo-darwin-64: 1.10.3 6055 - turbo-darwin-arm64: 1.10.3 6056 - turbo-linux-64: 1.10.3 6057 - turbo-linux-arm64: 1.10.3 6058 - turbo-windows-64: 1.10.3 6059 - turbo-windows-arm64: 1.10.3 6304 + turbo-darwin-64: 1.10.5 6305 + turbo-darwin-arm64: 1.10.5 6306 + turbo-linux-64: 1.10.5 6307 + turbo-linux-arm64: 1.10.5 6308 + turbo-windows-64: 1.10.5 6309 + turbo-windows-arm64: 1.10.5 6060 6310 dev: true 6061 6311 6062 6312 /type-check@0.4.0: ··· 6122 6372 engines: {node: '>= 10.0.0'} 6123 6373 dev: true 6124 6374 6375 + /unpipe@1.0.0: 6376 + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} 6377 + engines: {node: '>= 0.8'} 6378 + dev: false 6379 + 6125 6380 /untildify@4.0.0: 6126 6381 resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} 6127 6382 engines: {node: '>=8'} ··· 6160 6415 dependencies: 6161 6416 punycode: 2.3.0 6162 6417 6418 + /url-parse@1.5.10: 6419 + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} 6420 + dependencies: 6421 + querystringify: 2.2.0 6422 + requires-port: 1.0.0 6423 + dev: false 6424 + 6163 6425 /use-callback-ref@1.3.0(@types/react@18.2.12)(react@18.2.0): 6164 6426 resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} 6165 6427 engines: {node: '>=10'} ··· 6189 6451 detect-node-es: 1.1.0 6190 6452 react: 18.2.0 6191 6453 tslib: 2.5.3 6454 + dev: false 6455 + 6456 + /use-sync-external-store@1.2.0(react@18.2.0): 6457 + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} 6458 + peerDependencies: 6459 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 6460 + dependencies: 6461 + react: 18.2.0 6192 6462 dev: false 6193 6463 6194 6464 /util-deprecate@1.0.2: