diff --git a/.env.example b/.env.example index caecbe6..982b485 100644 --- a/.env.example +++ b/.env.example @@ -8,9 +8,9 @@ UPSTASH_REDIS_EXPIRY_SECONDS="" UPSTASH_RATELIMIT_REQUESTS="" UPSTASH_RATELIMIT_SECONDS="" -#Next Auth Core -NEXTAUTH_SECRET="" -NEXTAUTH_URL="" +#Auth +NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="" +CLERK_SECRET_KEY="" # Next Auth Github Provider GITHUB_CLIENT_ID="" diff --git a/drizzle.config.ts b/drizzle.config.ts new file mode 100644 index 0000000..3d04386 --- /dev/null +++ b/drizzle.config.ts @@ -0,0 +1,12 @@ +import type { Config } from "drizzle-kit"; +import "dotenv/config"; + +export default { + schema: "./src/server/schema.ts", + out: "./drizzle/generated", + driver: "mysql2", + breakpoints: true, + dbCredentials: { + connectionString: process.env.DATABASE_URL!, + }, +} satisfies Config; diff --git a/next.config.mjs b/next.config.mjs index ea8dac8..87738f0 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -10,7 +10,11 @@ const config = { defaultLocale: "en", }, images: { - domains: ["avatars.githubusercontent.com", "lh3.googleusercontent.com"], + domains: [ + "avatars.githubusercontent.com", + "lh3.googleusercontent.com", + "img.clerk.com", + ], }, }; diff --git a/package.json b/package.json index 35779b9..c2dda6a 100644 --- a/package.json +++ b/package.json @@ -1,34 +1,35 @@ { "name": "sprintpadawan", - "version": "1.2.7", + "version": "2.0.0", "description": "Plan. Sprint. Repeat.", "private": true, "scripts": { "build": "next build", - "serv": "NEXTAUTH_URL=http://localhost:3000 && next dev", + "serv": "next dev", "dev": "pnpm serv", - "postinstall": "prisma generate", "lint": "next lint", "start": "next start" }, "dependencies": { "@ably-labs/react-hooks": "^2.1.1", - "@auth/prisma-adapter": "^1.0.1", - "@prisma/client": "5.1.1", + "@clerk/nextjs": "^4.23.2", + "@paralleldrive/cuid2": "^2.2.2", + "@planetscale/database": "^1.10.0", "@react-email/components": "^0.0.7", "@tanstack/react-query": "^4.32.6", "@trpc/client": "10.37.1", "@trpc/next": "10.37.1", "@trpc/react-query": "10.37.1", "@trpc/server": "10.37.1", - "@unkey/api": "^0.5.0", + "@unkey/api": "^0.6.9", "@upstash/ratelimit": "^0.4.3", "@upstash/redis": "^1.22.0", - "ably": "^1.2.42", + "ably": "^1.2.43", "autoprefixer": "^10.4.14", + "dotenv": "^16.3.1", + "drizzle-orm": "^0.28.2", "json2csv": "6.0.0-alpha.2", "next": "^13.4.13", - "next-auth": "^4.22.5", "nextjs-cors": "^2.1.2", "postcss": "^8.4.27", "react": "18.2.0", @@ -44,14 +45,14 @@ "devDependencies": { "@types/eslint": "^8.44.2", "@types/json2csv": "^5.0.3", - "@types/node": "^20.4.9", - "@types/react": "^18.2.19", + "@types/node": "^20.4.10", + "@types/react": "^18.2.20", "@typescript-eslint/eslint-plugin": "^6.3.0", "@typescript-eslint/parser": "^6.3.0", "daisyui": "^3.5.1", - "eslint": "^8.46.0", + "drizzle-kit": "^0.19.12", + "eslint": "^8.47.0", "eslint-config-next": "^13.4.13", - "prisma": "5.1.1", "tailwindcss": "^3.3.3", "typescript": "^5.1.6" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 86e28d7..e612815 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,15 @@ dependencies: '@ably-labs/react-hooks': specifier: ^2.1.1 version: 2.1.1(react-dom@18.2.0)(react@18.2.0) - '@auth/prisma-adapter': - specifier: ^1.0.1 - version: 1.0.1(@prisma/client@5.1.1) - '@prisma/client': - specifier: 5.1.1 - version: 5.1.1(prisma@5.1.1) + '@clerk/nextjs': + specifier: ^4.23.2 + version: 4.23.2(next@13.4.13)(react-dom@18.2.0)(react@18.2.0) + '@paralleldrive/cuid2': + specifier: ^2.2.2 + version: 2.2.2 + '@planetscale/database': + specifier: ^1.10.0 + version: 1.10.0 '@react-email/components': specifier: ^0.0.7 version: 0.0.7 @@ -33,8 +36,8 @@ dependencies: specifier: 10.37.1 version: 10.37.1 '@unkey/api': - specifier: ^0.5.0 - version: 0.5.0 + specifier: ^0.6.9 + version: 0.6.9 '@upstash/ratelimit': specifier: ^0.4.3 version: 0.4.3 @@ -42,20 +45,23 @@ dependencies: specifier: ^1.22.0 version: 1.22.0 ably: - specifier: ^1.2.42 - version: 1.2.42 + specifier: ^1.2.43 + version: 1.2.43 autoprefixer: specifier: ^10.4.14 version: 10.4.14(postcss@8.4.27) + dotenv: + specifier: ^16.3.1 + version: 16.3.1 + drizzle-orm: + specifier: ^0.28.2 + version: 0.28.2(@planetscale/database@1.10.0) json2csv: specifier: 6.0.0-alpha.2 version: 6.0.0-alpha.2 next: specifier: ^13.4.13 version: 13.4.13(react-dom@18.2.0)(react@18.2.0) - next-auth: - specifier: ^4.22.5 - version: 4.22.5(next@13.4.13)(react-dom@18.2.0)(react@18.2.0) nextjs-cors: specifier: ^2.1.2 version: 2.1.2(next@13.4.13) @@ -98,29 +104,29 @@ devDependencies: specifier: ^5.0.3 version: 5.0.3 '@types/node': - specifier: ^20.4.9 - version: 20.4.9 + specifier: ^20.4.10 + version: 20.4.10 '@types/react': - specifier: ^18.2.19 - version: 18.2.19 + specifier: ^18.2.20 + version: 18.2.20 '@typescript-eslint/eslint-plugin': specifier: ^6.3.0 - version: 6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0)(typescript@5.1.6) + version: 6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0)(typescript@5.1.6) '@typescript-eslint/parser': specifier: ^6.3.0 - version: 6.3.0(eslint@8.46.0)(typescript@5.1.6) + version: 6.3.0(eslint@8.47.0)(typescript@5.1.6) daisyui: specifier: ^3.5.1 version: 3.5.1 + drizzle-kit: + specifier: ^0.19.12 + version: 0.19.12 eslint: - specifier: ^8.46.0 - version: 8.46.0 + specifier: ^8.47.0 + version: 8.47.0 eslint-config-next: specifier: ^13.4.13 - version: 13.4.13(eslint@8.46.0)(typescript@5.1.6) - prisma: - specifier: 5.1.1 - version: 5.1.1 + version: 13.4.13(eslint@8.47.0)(typescript@5.1.6) tailwindcss: specifier: ^3.3.3 version: 3.3.3 @@ -141,7 +147,7 @@ packages: react: '>=18.1.0' react-dom: '>=18.1.0' dependencies: - ably: 1.2.42 + ably: 1.2.43 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -160,33 +166,6 @@ packages: engines: {node: '>=10'} dev: true - /@auth/core@0.9.0: - resolution: {integrity: sha512-W2WO0WCBg1T3P8+yjQPzurTQhPv6ecBYfJ2oE3uvXPAX5ZLWAMSjKFAIa9oLZy5pwrB+YehJZPnlIxVilhrVcg==} - peerDependencies: - nodemailer: ^6.8.0 - peerDependenciesMeta: - nodemailer: - optional: true - dependencies: - '@panva/hkdf': 1.1.1 - cookie: 0.5.0 - jose: 4.14.4 - oauth4webapi: 2.3.0 - preact: 10.11.3 - preact-render-to-string: 5.2.3(preact@10.11.3) - dev: false - - /@auth/prisma-adapter@1.0.1(@prisma/client@5.1.1): - resolution: {integrity: sha512-sBp9l/jVr7l9y7rp2Pv6eoP7i8X2CgRNE3jDWJ0B/u+HnKRofXflD1cldPqRSAkJhqH3UxhVtMTEijT9FoofmQ==} - peerDependencies: - '@prisma/client': '>=2.26.0 || >=3 || >=4' - dependencies: - '@auth/core': 0.9.0 - '@prisma/client': 5.1.1(prisma@5.1.1) - transitivePeerDependencies: - - nodemailer - dev: false - /@babel/code-frame@7.22.10: resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} engines: {node: '>=6.9.0'} @@ -215,6 +194,83 @@ packages: dependencies: regenerator-runtime: 0.14.0 + /@clerk/backend@0.27.0: + resolution: {integrity: sha512-Sj541JrpqAn1A/UwdyDBxFV3stq2A/Pe/8HdPTG3Cct6briPyavfi46O5s1+L3BSvUcKUY+UbM0+8VsoCNFi4w==} + engines: {node: '>=14'} + dependencies: + '@clerk/types': 3.49.0 + '@peculiar/webcrypto': 1.4.1 + '@types/node': 16.18.6 + cookie: 0.5.0 + deepmerge: 4.2.2 + node-fetch-native: 1.0.1 + snakecase-keys: 5.4.4 + tslib: 2.4.1 + dev: false + + /@clerk/clerk-react@4.23.2(react@18.2.0): + resolution: {integrity: sha512-6MJa8ecr22qHhTfdkMMIJGctMBqj01fLJ4vmfZvr22tIkwkPXoeYJd5XcFKuSoO2dXc1eHD/F9i/HdCqGm68gw==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16' + dependencies: + '@clerk/shared': 0.21.0(react@18.2.0) + '@clerk/types': 3.49.0 + react: 18.2.0 + tslib: 2.4.1 + dev: false + + /@clerk/clerk-sdk-node@4.12.2: + resolution: {integrity: sha512-7xYPsLSeGO5XoP0No/9m2dsCMezwtmiYGKOwWzt41ZzJNFlU0rfqYF3VOZEsbtQlc3ZXeU+67ItjoJYrf3kT6A==} + engines: {node: '>=14'} + dependencies: + '@clerk/backend': 0.27.0 + '@clerk/types': 3.49.0 + '@types/cookies': 0.7.7 + '@types/express': 4.17.14 + '@types/node-fetch': 2.6.2 + camelcase-keys: 6.2.2 + snakecase-keys: 3.2.1 + tslib: 2.4.1 + dev: false + + /@clerk/nextjs@4.23.2(next@13.4.13)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-99bSVu9r1E9MxybO/6mmPAufSKq4KU7SFeMVkylX7UF8sy5t/LE9cLHyc+9jitcCGgZNai9Om4sj1WIgkNOP8w==} + engines: {node: '>=14'} + peerDependencies: + next: '>=10' + react: ^17.0.2 || ^18.0.0-0 + react-dom: ^17.0.2 || ^18.0.0-0 + dependencies: + '@clerk/backend': 0.27.0 + '@clerk/clerk-react': 4.23.2(react@18.2.0) + '@clerk/clerk-sdk-node': 4.12.2 + '@clerk/types': 3.49.0 + next: 13.4.13(react-dom@18.2.0)(react@18.2.0) + path-to-regexp: 6.2.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + tslib: 2.4.1 + dev: false + + /@clerk/shared@0.21.0(react@18.2.0): + resolution: {integrity: sha512-tkV2OAddFMPBHDjcMbtNNrV3NQD+hGKf2hn3TKv1mRJNZ2oR5Bfk8r0bkaqwoqxX8ndkbHLCa9gwR8SWO7GGow==} + peerDependencies: + react: '>=16' + dependencies: + glob-to-regexp: 0.4.1 + js-cookie: 3.0.1 + react: 18.2.0 + swr: 1.3.0(react@18.2.0) + dev: false + + /@clerk/types@3.49.0: + resolution: {integrity: sha512-vAx5R/iYfsgIaIDMiDr6ZKQnAneAmRrUVYz6KCtPG6/hnEAnRYhwXpEUi89e5G0BFmuUfSxe/N/Anfc1PNteXQ==} + engines: {node: '>=14'} + dependencies: + csstype: 3.1.1 + dev: false + /@commander-js/extra-typings@9.4.1(commander@9.4.1): resolution: {integrity: sha512-v0BqORYamk1koxDon6femDGLWSL7P78vYTyOU5nFaALnmNALL+ktgdHvWbxzzBBJIKS7kv3XvM/DqNwiLcgFTA==} peerDependencies: @@ -223,6 +279,24 @@ packages: commander: 9.4.1 dev: false + /@drizzle-team/studio@0.0.5: + resolution: {integrity: sha512-ps5qF0tMxWRVu+V5gvCRrQNqlY92aTnIKdq27gm9LZMSdaKYZt6AVvSK1dlUMzs6Rt0Jm80b+eWct6xShBKhIw==} + dev: true + + /@esbuild-kit/core-utils@3.1.0: + resolution: {integrity: sha512-Uuk8RpCg/7fdHSceR1M6XbSZFSuMrxcePFuGgyvsBn+u339dk5OeL4jv2EojwTN2st/unJGsVm4qHWjWNmJ/tw==} + dependencies: + esbuild: 0.17.19 + source-map-support: 0.5.21 + dev: true + + /@esbuild-kit/esm-loader@2.5.5: + resolution: {integrity: sha512-Qwfvj/qoPbClxCRNuac1Du01r9gvNOT+pMYtJDapfB1eoGN1YlJ1BixLyL9WVENRx5RXgNLdfYdx/CuswlGhMw==} + dependencies: + '@esbuild-kit/core-utils': 3.1.0 + get-tsconfig: 4.7.0 + dev: true + /@esbuild/android-arm64@0.16.4: resolution: {integrity: sha512-VPuTzXFm/m2fcGfN6CiwZTlLzxrKsWbPkG7ArRFpuxyaHUm/XFHQPD4xNwZT6uUmpIHhnSjcaCmcla8COzmZ5Q==} engines: {node: '>=12'} @@ -232,6 +306,24 @@ packages: dev: false optional: true + /@esbuild/android-arm64@0.17.19: + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.18.20: + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm@0.16.4: resolution: {integrity: sha512-rZzb7r22m20S1S7ufIc6DC6W659yxoOrl7sKP1nCYhuvUlnCFHVSbATG4keGUtV8rDz11sRRDbWkvQZpzPaHiw==} engines: {node: '>=12'} @@ -241,6 +333,24 @@ packages: dev: false optional: true + /@esbuild/android-arm@0.17.19: + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.18.20: + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-x64@0.16.4: resolution: {integrity: sha512-MW+B2O++BkcOfMWmuHXB15/l1i7wXhJFqbJhp82IBOais8RBEQv2vQz/jHrDEHaY2X0QY7Wfw86SBL2PbVOr0g==} engines: {node: '>=12'} @@ -250,6 +360,24 @@ packages: dev: false optional: true + /@esbuild/android-x64@0.17.19: + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.18.20: + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-arm64@0.16.4: resolution: {integrity: sha512-a28X1O//aOfxwJVZVs7ZfM8Tyih2Za4nKJrBwW5Wm4yKsnwBy9aiS/xwpxiiTRttw3EaTg4Srerhcm6z0bu9Wg==} engines: {node: '>=12'} @@ -259,6 +387,24 @@ packages: dev: false optional: true + /@esbuild/darwin-arm64@0.17.19: + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.18.20: + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/darwin-x64@0.16.4: resolution: {integrity: sha512-e3doCr6Ecfwd7VzlaQqEPrnbvvPjE9uoTpxG5pyLzr2rI2NMjDHmvY1E5EO81O/e9TUOLLkXA5m6T8lfjK9yAA==} engines: {node: '>=12'} @@ -268,6 +414,24 @@ packages: dev: false optional: true + /@esbuild/darwin-x64@0.17.19: + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.18.20: + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-arm64@0.16.4: resolution: {integrity: sha512-Oup3G/QxBgvvqnXWrBed7xxkFNwAwJVHZcklWyQt7YCAL5bfUkaa6FVWnR78rNQiM8MqqLiT6ZTZSdUFuVIg1w==} engines: {node: '>=12'} @@ -277,6 +441,24 @@ packages: dev: false optional: true + /@esbuild/freebsd-arm64@0.17.19: + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.18.20: + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/freebsd-x64@0.16.4: resolution: {integrity: sha512-vAP+eYOxlN/Bpo/TZmzEQapNS8W1njECrqkTpNgvXskkkJC2AwOXwZWai/Kc2vEFZUXQttx6UJbj9grqjD/+9Q==} engines: {node: '>=12'} @@ -286,6 +468,24 @@ packages: dev: false optional: true + /@esbuild/freebsd-x64@0.17.19: + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.18.20: + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm64@0.16.4: resolution: {integrity: sha512-2zXoBhv4r5pZiyjBKrOdFP4CXOChxXiYD50LRUU+65DkdS5niPFHbboKZd/c81l0ezpw7AQnHeoCy5hFrzzs4g==} engines: {node: '>=12'} @@ -295,6 +495,24 @@ packages: dev: false optional: true + /@esbuild/linux-arm64@0.17.19: + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.18.20: + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-arm@0.16.4: resolution: {integrity: sha512-A47ZmtpIPyERxkSvIv+zLd6kNIOtJH03XA0Hy7jaceRDdQaQVGSDt4mZqpWqJYgDk9rg96aglbF6kCRvPGDSUA==} engines: {node: '>=12'} @@ -304,6 +522,24 @@ packages: dev: false optional: true + /@esbuild/linux-arm@0.17.19: + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.18.20: + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ia32@0.16.4: resolution: {integrity: sha512-uxdSrpe9wFhz4yBwt2kl2TxS/NWEINYBUFIxQtaEVtglm1eECvsj1vEKI0KX2k2wCe17zDdQ3v+jVxfwVfvvjw==} engines: {node: '>=12'} @@ -313,6 +549,24 @@ packages: dev: false optional: true + /@esbuild/linux-ia32@0.17.19: + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.18.20: + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64@0.16.4: resolution: {integrity: sha512-peDrrUuxbZ9Jw+DwLCh/9xmZAk0p0K1iY5d2IcwmnN+B87xw7kujOkig6ZRcZqgrXgeRGurRHn0ENMAjjD5DEg==} engines: {node: '>=12'} @@ -322,6 +576,24 @@ packages: dev: false optional: true + /@esbuild/linux-loong64@0.17.19: + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.18.20: + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-mips64el@0.16.4: resolution: {integrity: sha512-sD9EEUoGtVhFjjsauWjflZklTNr57KdQ6xfloO4yH1u7vNQlOfAlhEzbyBKfgbJlW7rwXYBdl5/NcZ+Mg2XhQA==} engines: {node: '>=12'} @@ -331,6 +603,24 @@ packages: dev: false optional: true + /@esbuild/linux-mips64el@0.17.19: + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.18.20: + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-ppc64@0.16.4: resolution: {integrity: sha512-X1HSqHUX9D+d0l6/nIh4ZZJ94eQky8d8z6yxAptpZE3FxCWYWvTDd9X9ST84MGZEJx04VYUD/AGgciddwO0b8g==} engines: {node: '>=12'} @@ -340,6 +630,24 @@ packages: dev: false optional: true + /@esbuild/linux-ppc64@0.17.19: + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.18.20: + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-riscv64@0.16.4: resolution: {integrity: sha512-97ANpzyNp0GTXCt6SRdIx1ngwncpkV/z453ZuxbnBROCJ5p/55UjhbaG23UdHj88fGWLKPFtMoU4CBacz4j9FA==} engines: {node: '>=12'} @@ -349,6 +657,24 @@ packages: dev: false optional: true + /@esbuild/linux-riscv64@0.17.19: + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.18.20: + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-s390x@0.16.4: resolution: {integrity: sha512-pUvPQLPmbEeJRPjP0DYTC1vjHyhrnCklQmCGYbipkep+oyfTn7GTBJXoPodR7ZS5upmEyc8lzAkn2o29wD786A==} engines: {node: '>=12'} @@ -358,6 +684,24 @@ packages: dev: false optional: true + /@esbuild/linux-s390x@0.17.19: + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.18.20: + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-x64@0.16.4: resolution: {integrity: sha512-N55Q0mJs3Sl8+utPRPBrL6NLYZKBCLLx0bme/+RbjvMforTGGzFvsRl4xLTZMUBFC1poDzBEPTEu5nxizQ9Nlw==} engines: {node: '>=12'} @@ -367,6 +711,24 @@ packages: dev: false optional: true + /@esbuild/linux-x64@0.17.19: + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.18.20: + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/netbsd-x64@0.16.4: resolution: {integrity: sha512-LHSJLit8jCObEQNYkgsDYBh2JrJT53oJO2HVdkSYLa6+zuLJh0lAr06brXIkljrlI+N7NNW1IAXGn/6IZPi3YQ==} engines: {node: '>=12'} @@ -376,6 +738,24 @@ packages: dev: false optional: true + /@esbuild/netbsd-x64@0.17.19: + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.18.20: + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/openbsd-x64@0.16.4: resolution: {integrity: sha512-nLgdc6tWEhcCFg/WVFaUxHcPK3AP/bh+KEwKtl69Ay5IBqUwKDaq/6Xk0E+fh/FGjnLwqFSsarsbPHeKM8t8Sw==} engines: {node: '>=12'} @@ -385,6 +765,24 @@ packages: dev: false optional: true + /@esbuild/openbsd-x64@0.17.19: + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.18.20: + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /@esbuild/sunos-x64@0.16.4: resolution: {integrity: sha512-08SluG24GjPO3tXKk95/85n9kpyZtXCVwURR2i4myhrOfi3jspClV0xQQ0W0PYWHioJj+LejFMt41q+PG3mlAQ==} engines: {node: '>=12'} @@ -394,6 +792,24 @@ packages: dev: false optional: true + /@esbuild/sunos-x64@0.17.19: + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.18.20: + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-arm64@0.16.4: resolution: {integrity: sha512-yYiRDQcqLYQSvNQcBKN7XogbrSvBE45FEQdH8fuXPl7cngzkCvpsG2H9Uey39IjQ6gqqc+Q4VXYHsQcKW0OMjQ==} engines: {node: '>=12'} @@ -403,6 +819,24 @@ packages: dev: false optional: true + /@esbuild/win32-arm64@0.17.19: + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.18.20: + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-ia32@0.16.4: resolution: {integrity: sha512-5rabnGIqexekYkh9zXG5waotq8mrdlRoBqAktjx2W3kb0zsI83mdCwrcAeKYirnUaTGztR5TxXcXmQrEzny83w==} engines: {node: '>=12'} @@ -412,6 +846,24 @@ packages: dev: false optional: true + /@esbuild/win32-ia32@0.17.19: + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.18.20: + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@esbuild/win32-x64@0.16.4: resolution: {integrity: sha512-sN/I8FMPtmtT2Yw+Dly8Ur5vQ5a/RmC8hW7jO9PtPSQUPkowxWpcUZnqOggU7VwyT3Xkj6vcXWd3V/qTXwultQ==} engines: {node: '>=12'} @@ -421,14 +873,32 @@ packages: dev: false optional: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.46.0): + /@esbuild/win32-x64@0.17.19: + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.18.20: + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.47.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.46.0 - eslint-visitor-keys: 3.4.2 + eslint: 8.47.0 + eslint-visitor-keys: 3.4.3 dev: true /@eslint-community/regexpp@4.6.2: @@ -436,14 +906,14 @@ packages: engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc@2.1.1: - resolution: {integrity: sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==} + /@eslint/eslintrc@2.1.2: + resolution: {integrity: sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4 espree: 9.6.1 - globals: 13.20.0 + globals: 13.21.0 ignore: 5.2.4 import-fresh: 3.3.0 js-yaml: 4.1.0 @@ -453,8 +923,8 @@ packages: - supports-color dev: true - /@eslint/js@8.46.0: - resolution: {integrity: sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==} + /@eslint/js@8.47.0: + resolution: {integrity: sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true @@ -619,6 +1089,11 @@ packages: dev: false optional: true + /@noble/hashes@1.3.1: + resolution: {integrity: sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==} + engines: {node: '>= 16'} + dev: false + /@nodelib/fs.scandir@2.1.5: resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -765,43 +1240,42 @@ packages: resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} dev: false - /@panva/hkdf@1.1.1: - resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==} - dev: false - - /@pkgr/utils@2.4.2: - resolution: {integrity: sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + /@paralleldrive/cuid2@2.2.2: + resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==} dependencies: - cross-spawn: 7.0.3 - fast-glob: 3.3.1 - is-glob: 4.0.3 - open: 9.1.0 - picocolors: 1.0.0 - tslib: 2.6.1 - dev: true + '@noble/hashes': 1.3.1 + dev: false - /@prisma/client@5.1.1(prisma@5.1.1): - resolution: {integrity: sha512-fxcCeK5pMQGcgCqCrWsi+I2rpIbk0rAhdrN+ke7f34tIrgPwA68ensrpin+9+fZvuV2OtzHmuipwduSY6HswdA==} - engines: {node: '>=16.13'} - requiresBuild: true - peerDependencies: - prisma: '*' - peerDependenciesMeta: - prisma: - optional: true + /@peculiar/asn1-schema@2.3.6: + resolution: {integrity: sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA==} dependencies: - '@prisma/engines-version': 5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e - prisma: 5.1.1 + asn1js: 3.0.5 + pvtsutils: 1.3.3 + tslib: 2.4.1 dev: false - /@prisma/engines-version@5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e: - resolution: {integrity: sha512-owZqbY/wucbr65bXJ/ljrHPgQU5xXTSkmcE/JcbqE1kusuAXV/TLN3/exmz21SZ5rJ7WDkyk70J2G/n68iogbQ==} + /@peculiar/json-schema@1.1.12: + resolution: {integrity: sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==} + engines: {node: '>=8.0.0'} + dependencies: + tslib: 2.4.1 dev: false - /@prisma/engines@5.1.1: - resolution: {integrity: sha512-NV/4nVNWFZSJCCIA3HIFJbbDKO/NARc9ej0tX5S9k2EVbkrFJC4Xt9b0u4rNZWL4V+F5LAjvta8vzEUw0rw+HA==} - requiresBuild: true + /@peculiar/webcrypto@1.4.1: + resolution: {integrity: sha512-eK4C6WTNYxoI7JOabMoZICiyqRRtJB220bh0Mbj5RwRycleZf9BPyZoxsTvpP0FpmVS2aS13NKOuh5/tN3sIRw==} + engines: {node: '>=10.12.0'} + dependencies: + '@peculiar/asn1-schema': 2.3.6 + '@peculiar/json-schema': 1.1.12 + pvtsutils: 1.3.3 + tslib: 2.4.1 + webcrypto-core: 1.7.7 + dev: false + + /@planetscale/database@1.10.0: + resolution: {integrity: sha512-XMfNRjIPgGTga6g1YpGr7E21CcnHZcHZdyhRUIiZ/AlpD+ts65UF2B3wKjcu7MKMynmmcOGs6R9kAT6D1OTlZQ==} + engines: {node: '>=16'} + dev: false /@radix-ui/react-compose-refs@1.0.0(react@18.2.0): resolution: {integrity: sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==} @@ -1084,15 +1558,37 @@ packages: resolution: {integrity: sha512-r3VeA319/braYMBIzj+XLgLKQ9lJSVglvPvP9HUv4kr5w6Y5grQMxMcExhTiZWltE9bnSJHKtBBzHafOo7KC8A==} dev: false + /@types/body-parser@1.19.2: + resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + dependencies: + '@types/connect': 3.4.35 + '@types/node': 20.4.10 + dev: false + /@types/cacheable-request@6.0.3: resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} dependencies: '@types/http-cache-semantics': 4.0.1 '@types/keyv': 3.1.4 - '@types/node': 20.4.9 + '@types/node': 20.4.10 '@types/responselike': 1.0.0 dev: false + /@types/connect@3.4.35: + resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + dependencies: + '@types/node': 20.4.10 + dev: false + + /@types/cookies@0.7.7: + resolution: {integrity: sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==} + dependencies: + '@types/connect': 3.4.35 + '@types/express': 4.17.14 + '@types/keygrip': 1.0.2 + '@types/node': 20.4.10 + dev: false + /@types/eslint@8.44.2: resolution: {integrity: sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==} dependencies: @@ -1104,10 +1600,32 @@ packages: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: true + /@types/express-serve-static-core@4.17.35: + resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} + dependencies: + '@types/node': 20.4.10 + '@types/qs': 6.9.7 + '@types/range-parser': 1.2.4 + '@types/send': 0.17.1 + dev: false + + /@types/express@4.17.14: + resolution: {integrity: sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==} + dependencies: + '@types/body-parser': 1.19.2 + '@types/express-serve-static-core': 4.17.35 + '@types/qs': 6.9.7 + '@types/serve-static': 1.15.2 + dev: false + /@types/http-cache-semantics@4.0.1: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: false + /@types/http-errors@2.0.1: + resolution: {integrity: sha512-/K3ds8TRAfBvi5vfjuz8y6+GiAYBZ0x4tXv1Av6CWBWn0IlADc+ZX9pMq7oU0fNQPnBwIZl3rmeLp6SBApbxSQ==} + dev: false + /@types/json-schema@7.0.12: resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} dev: true @@ -1115,25 +1633,48 @@ packages: /@types/json2csv@5.0.3: resolution: {integrity: sha512-ZJEv6SzhPhgpBpxZU4n/TZekbZqI4EcyXXRwms1lAITG2kIAtj85PfNYafUOY1zy8bWs5ujaub0GU4copaA0sw==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.4.10 dev: true /@types/json5@0.0.29: resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} dev: true + /@types/keygrip@1.0.2: + resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==} + dev: false + /@types/keyv@3.1.4: resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.4.10 + dev: false + + /@types/mime@1.3.2: + resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + dev: false + + /@types/mime@3.0.1: + resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + dev: false + + /@types/node-fetch@2.6.2: + resolution: {integrity: sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==} + dependencies: + '@types/node': 20.4.10 + form-data: 3.0.1 dev: false /@types/node@12.20.55: resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} dev: false - /@types/node@20.4.9: - resolution: {integrity: sha512-8e2HYcg7ohnTUbHk8focoklEQYvemQmu9M/f43DZVx43kHn0tE3BY/6gSDxS7k0SprtS0NHvj+L80cGLnoOUcQ==} + /@types/node@16.18.6: + resolution: {integrity: sha512-vmYJF0REqDyyU0gviezF/KHq/fYaUbFhkcNbQCuPGFQj6VTbXuHZoxs/Y7mutWe73C8AC6l9fFu8mSYiBAqkGA==} + dev: false + + /@types/node@20.4.10: + resolution: {integrity: sha512-vwzFiiy8Rn6E0MtA13/Cxxgpan/N6UeNYR9oUu6kuJWxu6zCk98trcDp8CBhbtaeuq9SykCmXkFr2lWLoPcvLg==} /@types/normalize-package-data@2.4.1: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} @@ -1143,8 +1684,16 @@ packages: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} dev: true - /@types/react@18.2.19: - resolution: {integrity: sha512-e2S8wmY1ePfM517PqCG80CcE48Xs5k0pwJzuDZsfE8IZRRBfOMCF+XqnFxu6mWtyivum1MQm4aco+WIt6Coimw==} + /@types/qs@6.9.7: + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + dev: false + + /@types/range-parser@1.2.4: + resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + dev: false + + /@types/react@18.2.20: + resolution: {integrity: sha512-WKNtmsLWJM/3D5mG4U84cysVY31ivmyw85dE84fOCk5Hx78wezB/XEjVPWl2JTZ5FkEeaTJf+VgUAUn3PE7Isw==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.3 @@ -1154,7 +1703,7 @@ packages: /@types/responselike@1.0.0: resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} dependencies: - '@types/node': 20.4.9 + '@types/node': 20.4.10 dev: false /@types/scheduler@0.16.3: @@ -1165,7 +1714,22 @@ packages: resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} dev: true - /@typescript-eslint/eslint-plugin@6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.46.0)(typescript@5.1.6): + /@types/send@0.17.1: + resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} + dependencies: + '@types/mime': 1.3.2 + '@types/node': 20.4.10 + dev: false + + /@types/serve-static@1.15.2: + resolution: {integrity: sha512-J2LqtvFYCzaj8pVYKw8klQXrLLk7TBZmQ4ShlcdkELFKGwGMfevMLneMMRkMgZxotOD9wg497LpC7O8PcvAmfw==} + dependencies: + '@types/http-errors': 2.0.1 + '@types/mime': 3.0.1 + '@types/node': 20.4.10 + dev: false + + /@typescript-eslint/eslint-plugin@6.3.0(@typescript-eslint/parser@6.3.0)(eslint@8.47.0)(typescript@5.1.6): resolution: {integrity: sha512-IZYjYZ0ifGSLZbwMqIip/nOamFiWJ9AH+T/GYNZBWkVcyNQOFGtSMoWV7RvY4poYCMZ/4lHzNl796WOSNxmk8A==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1177,13 +1741,13 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + '@typescript-eslint/parser': 6.3.0(eslint@8.47.0)(typescript@5.1.6) '@typescript-eslint/scope-manager': 6.3.0 - '@typescript-eslint/type-utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - '@typescript-eslint/utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + '@typescript-eslint/type-utils': 6.3.0(eslint@8.47.0)(typescript@5.1.6) + '@typescript-eslint/utils': 6.3.0(eslint@8.47.0)(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.3.0 debug: 4.3.4 - eslint: 8.46.0 + eslint: 8.47.0 graphemer: 1.4.0 ignore: 5.2.4 natural-compare: 1.4.0 @@ -1195,7 +1759,7 @@ packages: - supports-color dev: true - /@typescript-eslint/parser@6.3.0(eslint@8.46.0)(typescript@5.1.6): + /@typescript-eslint/parser@6.3.0(eslint@8.47.0)(typescript@5.1.6): resolution: {integrity: sha512-ibP+y2Gr6p0qsUkhs7InMdXrwldjxZw66wpcQq9/PzAroM45wdwyu81T+7RibNCh8oc0AgrsyCwJByncY0Ongg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1210,7 +1774,7 @@ packages: '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.3.0 debug: 4.3.4 - eslint: 8.46.0 + eslint: 8.47.0 typescript: 5.1.6 transitivePeerDependencies: - supports-color @@ -1224,7 +1788,7 @@ packages: '@typescript-eslint/visitor-keys': 6.3.0 dev: true - /@typescript-eslint/type-utils@6.3.0(eslint@8.46.0)(typescript@5.1.6): + /@typescript-eslint/type-utils@6.3.0(eslint@8.47.0)(typescript@5.1.6): resolution: {integrity: sha512-7Oj+1ox1T2Yc8PKpBvOKWhoI/4rWFd1j7FA/rPE0lbBPXTKjdbtC+7Ev0SeBjEKkIhKWVeZSP+mR7y1Db1CdfQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1235,9 +1799,9 @@ packages: optional: true dependencies: '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) - '@typescript-eslint/utils': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + '@typescript-eslint/utils': 6.3.0(eslint@8.47.0)(typescript@5.1.6) debug: 4.3.4 - eslint: 8.46.0 + eslint: 8.47.0 ts-api-utils: 1.0.1(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: @@ -1270,19 +1834,19 @@ packages: - supports-color dev: true - /@typescript-eslint/utils@6.3.0(eslint@8.46.0)(typescript@5.1.6): + /@typescript-eslint/utils@6.3.0(eslint@8.47.0)(typescript@5.1.6): resolution: {integrity: sha512-hLLg3BZE07XHnpzglNBG8P/IXq/ZVXraEbgY7FM0Cnc1ehM8RMdn9mat3LubJ3KBeYXXPxV1nugWbQPjGeJk6Q==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0) '@types/json-schema': 7.0.12 '@types/semver': 7.5.0 '@typescript-eslint/scope-manager': 6.3.0 '@typescript-eslint/types': 6.3.0 '@typescript-eslint/typescript-estree': 6.3.0(typescript@5.1.6) - eslint: 8.46.0 + eslint: 8.47.0 semver: 7.5.4 transitivePeerDependencies: - supports-color @@ -1294,11 +1858,11 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dependencies: '@typescript-eslint/types': 6.3.0 - eslint-visitor-keys: 3.4.2 + eslint-visitor-keys: 3.4.3 dev: true - /@unkey/api@0.5.0: - resolution: {integrity: sha512-C3q2ITvBR5jpK68KNAhhqcR+BzRhXW9ppubdrbaXawEnwxE+F+I2qMU+KqkCM1MbP+ZUv4/E1gX8cobH4X0sWg==} + /@unkey/api@0.6.9: + resolution: {integrity: sha512-MdTvj89tL9o0qXdtv8Vs9LcoEhh0dEWfOHoGHelLKu1N1Dt1rPaiRMR5vat9LYJUZuFjeYAXHYATxFvmU+fJBQ==} dev: false /@upstash/core-analytics@0.0.6: @@ -1330,8 +1894,8 @@ packages: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} dev: false - /ably@1.2.42: - resolution: {integrity: sha512-dUnza7cERLWaDa/2pLVXtU2PJoU5k/t6g9sQZI1dgWC5Vok39nE6tf/xH2Rat7PJs7pXl9hLpkg1AhS4Xwd2/w==} + /ably@1.2.43: + resolution: {integrity: sha512-HZ99Nd98KzYToNUD4+ysHp4+vMp1NmYTi59yqGpejHo/VffTgg0pereoib0nRRAHYUhGUGys5HGwR5yHYESWDA==} engines: {node: '>=5.10.x'} dependencies: '@ably/msgpack-js': 0.4.0 @@ -1514,6 +2078,15 @@ packages: is-shared-array-buffer: 1.0.2 dev: true + /asn1js@3.0.5: + resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} + engines: {node: '>=12.0.0'} + dependencies: + pvtsutils: 1.3.3 + pvutils: 1.1.3 + tslib: 2.4.1 + dev: false + /ast-types-flow@0.0.7: resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} dev: true @@ -1534,7 +2107,7 @@ packages: postcss: ^8.1.0 dependencies: browserslist: 4.21.10 - caniuse-lite: 1.0.30001519 + caniuse-lite: 1.0.30001520 fraction.js: 4.2.0 normalize-range: 0.1.2 picocolors: 1.0.0 @@ -1591,6 +2164,7 @@ packages: /big-integer@1.6.51: resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} engines: {node: '>=0.6'} + dev: false /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} @@ -1622,13 +2196,6 @@ packages: to-utf8: 0.0.1 dev: false - /bplist-parser@0.2.0: - resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} - engines: {node: '>= 5.10.0'} - dependencies: - big-integer: 1.6.51 - dev: true - /brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} dependencies: @@ -1639,7 +2206,6 @@ packages: resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} dependencies: balanced-match: 1.0.2 - dev: false /braces@3.0.2: resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} @@ -1652,12 +2218,16 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001519 - electron-to-chromium: 1.4.488 + caniuse-lite: 1.0.30001520 + electron-to-chromium: 1.4.490 node-releases: 2.0.13 update-browserslist-db: 1.0.11(browserslist@4.21.10) dev: false + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + /buffer-indexof-polyfill@1.0.2: resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} engines: {node: '>=0.10'} @@ -1675,13 +2245,6 @@ packages: engines: {node: '>=0.2.0'} dev: false - /bundle-name@3.0.0: - resolution: {integrity: sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==} - engines: {node: '>=12'} - dependencies: - run-applescript: 5.0.0 - dev: true - /busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -1727,8 +2290,27 @@ packages: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} - /caniuse-lite@1.0.30001519: - resolution: {integrity: sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==} + /camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + dev: false + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: false + + /camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + dev: true + + /caniuse-lite@1.0.30001520: + resolution: {integrity: sha512-tahF5O9EiiTzwTUqAeFjIZbn4Dnqxzz7ktrgGlMYNLH43Ul26IgTMH/zvL3DG0lZxBYnlT04axvInszUsZULdA==} dev: false /chainsaw@0.1.0: @@ -1753,6 +2335,11 @@ packages: ansi-styles: 4.3.0 supports-color: 7.2.0 + /chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + /chokidar@3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -1771,6 +2358,17 @@ packages: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} dev: false + /cli-color@2.0.3: + resolution: {integrity: sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ==} + engines: {node: '>=0.10'} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-iterator: 2.0.3 + memoizee: 0.4.15 + timers-ext: 0.1.7 + dev: true + /cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -1877,6 +2475,11 @@ packages: engines: {node: ^12.20.0 || >=14} dev: false + /commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + dev: true + /concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1951,10 +2554,21 @@ packages: engines: {node: '>=4'} hasBin: true + /csstype@3.1.1: + resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + dev: false + /csstype@3.1.2: resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} dev: true + /d@1.0.1: + resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} + dependencies: + es5-ext: 0.10.62 + type: 1.2.0 + dev: true + /daisyui@3.5.1: resolution: {integrity: sha512-7GG+9QXnr2qQMCqnyFU8TxpaOYJigXiEtmzoivmiiZZHvxqIwYdaMAkgivqTVxEgy3Hot3m1suzZjmt1zUrvmA==} engines: {node: '>=16.9.0'} @@ -2011,29 +2625,16 @@ packages: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} dev: true + /deepmerge@4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: false + /deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} dev: false - /default-browser-id@3.0.0: - resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} - engines: {node: '>=12'} - dependencies: - bplist-parser: 0.2.0 - untildify: 4.0.0 - dev: true - - /default-browser@4.0.0: - resolution: {integrity: sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==} - engines: {node: '>=14.16'} - dependencies: - bundle-name: 3.0.0 - default-browser-id: 3.0.0 - execa: 7.2.0 - titleize: 3.0.0 - dev: true - /defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} dependencies: @@ -2045,11 +2646,6 @@ packages: engines: {node: '>=10'} dev: false - /define-lazy-prop@3.0.0: - resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} - engines: {node: '>=12'} - dev: true - /define-properties@1.2.0: resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} engines: {node: '>= 0.4'} @@ -2119,6 +2715,12 @@ packages: /didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + /difflib@0.2.4: + resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} + dependencies: + heap: 0.2.7 + dev: true + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -2169,6 +2771,110 @@ packages: domhandler: 5.0.3 dev: false + /dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.4.1 + dev: false + + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: false + + /dreamopt@0.8.0: + resolution: {integrity: sha512-vyJTp8+mC+G+5dfgsY+r3ckxlz+QMX40VjPQsZc5gxVAxLmi64TBoVkP54A/pRAXMXsbu2GMMBrZPxNv23waMg==} + engines: {node: '>=0.4.0'} + dependencies: + wordwrap: 1.0.0 + dev: true + + /drizzle-kit@0.19.12: + resolution: {integrity: sha512-rcsmh5gUIkvuD0WrbEc+aLpqY2q2J8ltynRcJiJo2l01hhsYvPnX0sgxWlFXlfAIa5ZXNw2nJZhYlslI6tG3MA==} + hasBin: true + dependencies: + '@drizzle-team/studio': 0.0.5 + '@esbuild-kit/esm-loader': 2.5.5 + camelcase: 7.0.1 + chalk: 5.3.0 + commander: 9.5.0 + esbuild: 0.18.20 + esbuild-register: 3.4.2(esbuild@0.18.20) + glob: 8.1.0 + hanji: 0.0.5 + json-diff: 0.9.0 + minimatch: 7.4.6 + zod: 3.21.4 + transitivePeerDependencies: + - supports-color + dev: true + + /drizzle-orm@0.28.2(@planetscale/database@1.10.0): + resolution: {integrity: sha512-QRyuzvpJr7GE6LpvZ/sg2nAKNg2if1uGGkgFTiXn4auuYId//vVJe6HBsDTktfKfcaDGzIYos+/f+PS5EkBmrg==} + peerDependencies: + '@aws-sdk/client-rds-data': '>=3' + '@cloudflare/workers-types': '>=3' + '@libsql/client': '*' + '@neondatabase/serverless': '>=0.1' + '@opentelemetry/api': ^1.4.1 + '@planetscale/database': '>=1' + '@types/better-sqlite3': '*' + '@types/pg': '*' + '@types/sql.js': '*' + '@vercel/postgres': '*' + better-sqlite3: '>=7' + bun-types: '*' + knex: '*' + kysely: '*' + mysql2: '>=2' + pg: '>=8' + postgres: '>=3' + sql.js: '>=1' + sqlite3: '>=5' + peerDependenciesMeta: + '@aws-sdk/client-rds-data': + optional: true + '@cloudflare/workers-types': + optional: true + '@libsql/client': + optional: true + '@neondatabase/serverless': + optional: true + '@opentelemetry/api': + optional: true + '@planetscale/database': + optional: true + '@types/better-sqlite3': + optional: true + '@types/pg': + optional: true + '@types/sql.js': + optional: true + '@vercel/postgres': + optional: true + better-sqlite3: + optional: true + bun-types: + optional: true + knex: + optional: true + kysely: + optional: true + mysql2: + optional: true + pg: + optional: true + postgres: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + dependencies: + '@planetscale/database': 1.10.0 + dev: false + /duplexer2@0.1.4: resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} dependencies: @@ -2186,8 +2892,8 @@ packages: semver: 7.5.4 dev: false - /electron-to-chromium@1.4.488: - resolution: {integrity: sha512-Dv4sTjiW7t/UWGL+H8ZkgIjtUAVZDgb/PwGWvMsCT7jipzUV/u5skbLXPFKb6iV0tiddVi/bcS2/kUrczeWgIQ==} + /electron-to-chromium@1.4.490: + resolution: {integrity: sha512-6s7NVJz+sATdYnIwhdshx/N/9O6rvMxmhVoDSDFdj6iA45gHR8EQje70+RYsF4GeB+k0IeNSBnP7yG9ZXJFr7A==} dev: false /emoji-regex@9.2.2: @@ -2288,6 +2994,51 @@ packages: is-symbol: 1.0.4 dev: true + /es5-ext@0.10.62: + resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} + engines: {node: '>=0.10'} + requiresBuild: true + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.3 + next-tick: 1.1.0 + dev: true + + /es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-symbol: 3.1.3 + dev: true + + /es6-symbol@3.1.3: + resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} + dependencies: + d: 1.0.1 + ext: 1.7.0 + dev: true + + /es6-weak-map@2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-iterator: 2.0.3 + es6-symbol: 3.1.3 + dev: true + + /esbuild-register@3.4.2(esbuild@0.18.20): + resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.3.4 + esbuild: 0.18.20 + transitivePeerDependencies: + - supports-color + dev: true + /esbuild@0.16.4: resolution: {integrity: sha512-qQrPMQpPTWf8jHugLWHoGqZjApyx3OEm76dlTXobHwh/EBbavbRdjXdYi/GWr43GyN0sfpap14GPkb05NH3ROA==} engines: {node: '>=12'} @@ -2318,6 +3069,66 @@ packages: '@esbuild/win32-x64': 0.16.4 dev: false + /esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + dev: true + + /esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + dev: true + /escalade@3.1.1: resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} engines: {node: '>=6'} @@ -2333,7 +3144,7 @@ packages: engines: {node: '>=10'} dev: true - /eslint-config-next@13.4.13(eslint@8.46.0)(typescript@5.1.6): + /eslint-config-next@13.4.13(eslint@8.47.0)(typescript@5.1.6): resolution: {integrity: sha512-EXAh5h1yG/YTNa5YdskzaSZncBjKjvFe2zclMCi2KXyTsXha22wB6MPs/U7idB6a2qjpBdbZcruQY1TWjfNMZw==} peerDependencies: eslint: ^7.23.0 || ^8.0.0 @@ -2344,14 +3155,14 @@ packages: dependencies: '@next/eslint-plugin-next': 13.4.13 '@rushstack/eslint-patch': 1.3.3 - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) - eslint: 8.46.0 + '@typescript-eslint/parser': 6.3.0(eslint@8.47.0)(typescript@5.1.6) + eslint: 8.47.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.0)(eslint@8.46.0) - eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.46.0) - eslint-plugin-jsx-a11y: 6.7.1(eslint@8.46.0) - eslint-plugin-react: 7.33.1(eslint@8.46.0) - eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.46.0) + eslint-import-resolver-typescript: 3.6.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.0)(eslint@8.47.0) + eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-typescript@3.6.0)(eslint@8.47.0) + eslint-plugin-jsx-a11y: 6.7.1(eslint@8.47.0) + eslint-plugin-react: 7.33.1(eslint@8.47.0) + eslint-plugin-react-hooks: 5.0.0-canary-7118f5dd7-20230705(eslint@8.47.0) typescript: 5.1.6 transitivePeerDependencies: - eslint-import-resolver-webpack @@ -2368,8 +3179,8 @@ packages: - supports-color dev: true - /eslint-import-resolver-typescript@3.5.5(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.0)(eslint@8.46.0): - resolution: {integrity: sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw==} + /eslint-import-resolver-typescript@3.6.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.0)(eslint@8.47.0): + resolution: {integrity: sha512-QTHR9ddNnn35RTxlaEnx2gCxqFlF2SEN0SE2d17SqwyM7YOSI2GHWRYp5BiRkObTUNYPupC/3Fq2a0PpT+EKpg==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -2377,14 +3188,13 @@ packages: dependencies: debug: 4.3.4 enhanced-resolve: 5.15.0 - eslint: 8.46.0 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.46.0) - eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.46.0) - get-tsconfig: 4.6.2 - globby: 13.2.2 + eslint: 8.47.0 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.0)(eslint@8.47.0) + eslint-plugin-import: 2.28.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-typescript@3.6.0)(eslint@8.47.0) + fast-glob: 3.3.1 + get-tsconfig: 4.7.0 is-core-module: 2.13.0 is-glob: 4.0.3 - synckit: 0.8.5 transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node @@ -2392,7 +3202,7 @@ packages: - supports-color dev: true - /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.46.0): + /eslint-module-utils@2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.0)(eslint@8.47.0): resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} engines: {node: '>=4'} peerDependencies: @@ -2413,16 +3223,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + '@typescript-eslint/parser': 6.3.0(eslint@8.47.0)(typescript@5.1.6) debug: 3.2.7 - eslint: 8.46.0 + eslint: 8.47.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.5.5(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.0)(eslint@8.46.0) + eslint-import-resolver-typescript: 3.6.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.28.0)(eslint@8.47.0) transitivePeerDependencies: - supports-color dev: true - /eslint-plugin-import@2.28.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-typescript@3.5.5)(eslint@8.46.0): + /eslint-plugin-import@2.28.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-typescript@3.6.0)(eslint@8.47.0): resolution: {integrity: sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==} engines: {node: '>=4'} peerDependencies: @@ -2432,16 +3242,16 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.3.0(eslint@8.46.0)(typescript@5.1.6) + '@typescript-eslint/parser': 6.3.0(eslint@8.47.0)(typescript@5.1.6) array-includes: 3.1.6 array.prototype.findlastindex: 1.2.2 array.prototype.flat: 1.3.1 array.prototype.flatmap: 1.3.1 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.46.0 + eslint: 8.47.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.5.5)(eslint@8.46.0) + eslint-module-utils: 2.8.0(@typescript-eslint/parser@6.3.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.0)(eslint@8.47.0) has: 1.0.3 is-core-module: 2.13.0 is-glob: 4.0.3 @@ -2458,7 +3268,7 @@ packages: - supports-color dev: true - /eslint-plugin-jsx-a11y@6.7.1(eslint@8.46.0): + /eslint-plugin-jsx-a11y@6.7.1(eslint@8.47.0): resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} engines: {node: '>=4.0'} peerDependencies: @@ -2473,7 +3283,7 @@ packages: axobject-query: 3.2.1 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 8.46.0 + eslint: 8.47.0 has: 1.0.3 jsx-ast-utils: 3.3.5 language-tags: 1.0.5 @@ -2483,16 +3293,16 @@ packages: semver: 6.3.1 dev: true - /eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705(eslint@8.46.0): + /eslint-plugin-react-hooks@5.0.0-canary-7118f5dd7-20230705(eslint@8.47.0): resolution: {integrity: sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.46.0 + eslint: 8.47.0 dev: true - /eslint-plugin-react@7.33.1(eslint@8.46.0): + /eslint-plugin-react@7.33.1(eslint@8.47.0): resolution: {integrity: sha512-L093k0WAMvr6VhNwReB8VgOq5s2LesZmrpPdKz/kZElQDzqS7G7+DnKoqT+w4JwuiGeAhAvHO0fvy0Eyk4ejDA==} engines: {node: '>=4'} peerDependencies: @@ -2502,7 +3312,7 @@ packages: array.prototype.flatmap: 1.3.1 array.prototype.tosorted: 1.1.1 doctrine: 2.1.0 - eslint: 8.46.0 + eslint: 8.47.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.5 minimatch: 3.1.2 @@ -2524,20 +3334,20 @@ packages: estraverse: 5.3.0 dev: true - /eslint-visitor-keys@3.4.2: - resolution: {integrity: sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==} + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint@8.46.0: - resolution: {integrity: sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==} + /eslint@8.47.0: + resolution: {integrity: sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.46.0) + '@eslint-community/eslint-utils': 4.4.0(eslint@8.47.0) '@eslint-community/regexpp': 4.6.2 - '@eslint/eslintrc': 2.1.1 - '@eslint/js': 8.46.0 + '@eslint/eslintrc': 2.1.2 + '@eslint/js': 8.47.0 '@humanwhocodes/config-array': 0.11.10 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -2548,7 +3358,7 @@ packages: doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.2 + eslint-visitor-keys: 3.4.3 espree: 9.6.1 esquery: 1.5.0 esutils: 2.0.3 @@ -2556,7 +3366,7 @@ packages: file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.20.0 + globals: 13.21.0 graphemer: 1.4.0 ignore: 5.2.4 imurmurhash: 0.1.4 @@ -2581,7 +3391,7 @@ packages: dependencies: acorn: 8.10.0 acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.4.2 + eslint-visitor-keys: 3.4.3 dev: true /esprima@4.0.1: @@ -2614,6 +3424,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + dev: true + /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -2627,27 +3444,19 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 strip-final-newline: 2.0.0 - - /execa@7.2.0: - resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} - engines: {node: ^14.18.0 || ^16.14.0 || >=18.0.0} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 4.3.1 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.1.0 - onetime: 6.0.0 - signal-exit: 3.0.7 - strip-final-newline: 3.0.0 - dev: true + dev: false /expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} dev: false + /ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + dependencies: + type: 2.7.2 + dev: true + /extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -2759,6 +3568,15 @@ packages: is-callable: 1.2.7 dev: true + /form-data@3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -2854,6 +3672,7 @@ packages: /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} + dev: false /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} @@ -2863,8 +3682,8 @@ packages: get-intrinsic: 1.2.1 dev: true - /get-tsconfig@4.6.2: - resolution: {integrity: sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==} + /get-tsconfig@4.7.0: + resolution: {integrity: sha512-pmjiZ7xtB8URYm74PlGJozDNyhvsVLUcpBa8DZBG3bWHwaHa9bPiRpiSfovw+fjhwONSCWKRyk+JQHEGZmMrzw==} dependencies: resolve-pkg-maps: 1.0.0 dev: true @@ -2941,10 +3760,9 @@ packages: inherits: 2.0.4 minimatch: 5.1.6 once: 1.4.0 - dev: false - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + /globals@13.21.0: + resolution: {integrity: sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 @@ -2968,17 +3786,6 @@ packages: merge2: 1.4.1 slash: 3.0.0 - /globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.1 - ignore: 5.2.4 - merge2: 1.4.1 - slash: 4.0.0 - dev: true - /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: @@ -3021,6 +3828,13 @@ packages: uncrypto: 0.1.3 dev: false + /hanji@0.0.5: + resolution: {integrity: sha512-Abxw1Lq+TnYiL4BueXqMau222fPSPMFtya8HdpWsz/xVAhifXou71mPh/kY2+08RgFcVccjG3uZHs6K5HAe3zw==} + dependencies: + lodash.throttle: 4.1.1 + sisteransi: 1.0.5 + dev: true + /has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} dev: true @@ -3061,6 +3875,10 @@ packages: dependencies: function-bind: 1.1.1 + /heap@0.2.7: + resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + dev: true + /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} dev: false @@ -3139,11 +3957,7 @@ packages: /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - - /human-signals@4.3.1: - resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} - engines: {node: '>=14.18.0'} - dev: true + dev: false /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} @@ -3270,18 +4084,6 @@ packages: has-tostringtag: 1.0.0 dev: true - /is-docker@2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - dev: true - - /is-docker@3.0.0: - resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - hasBin: true - dev: true - /is-extendable@0.1.1: resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} engines: {node: '>=0.10.0'} @@ -3297,14 +4099,6 @@ packages: dependencies: is-extglob: 2.1.1 - /is-inside-container@1.0.0: - resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} - engines: {node: '>=14.16'} - hasBin: true - dependencies: - is-docker: 3.0.0 - dev: true - /is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -3336,6 +4130,10 @@ packages: engines: {node: '>=0.10.0'} dev: false + /is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: true + /is-regex@1.1.4: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} @@ -3353,11 +4151,7 @@ packages: /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - - /is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true + dev: false /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} @@ -3401,13 +4195,6 @@ packages: engines: {node: '>=0.10.0'} dev: false - /is-wsl@2.2.0: - resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} - engines: {node: '>=8'} - dependencies: - is-docker: 2.2.1 - dev: true - /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} dev: false @@ -3437,10 +4224,6 @@ packages: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} dev: false - /jose@4.14.4: - resolution: {integrity: sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==} - dev: false - /js-beautify@1.14.9: resolution: {integrity: sha512-coM7xq1syLcMyuVGyToxcj2AlzhkDjmfklL8r0JgJ7A76wyGMpJ1oA35mr4APdYNO/o/4YY8H54NQIJzhMbhBg==} engines: {node: '>=12'} @@ -3452,6 +4235,11 @@ packages: nopt: 6.0.0 dev: false + /js-cookie@3.0.1: + resolution: {integrity: sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==} + engines: {node: '>=12'} + dev: false + /js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -3474,6 +4262,15 @@ packages: resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} dev: false + /json-diff@0.9.0: + resolution: {integrity: sha512-cVnggDrVkAAA3OvFfHpFEhOnmcsUpleEKq4d4O8sQWWSH40MBrWstKigVB1kGrgLWzuom+7rRdaCsnBD6VyObQ==} + hasBin: true + dependencies: + cli-color: 2.0.3 + difflib: 0.2.4 + dreamopt: 0.8.0 + dev: true + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: false @@ -3599,6 +4396,10 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} dev: true + /lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + dev: true + /log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} @@ -3613,6 +4414,12 @@ packages: dependencies: js-tokens: 4.0.0 + /lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.4.1 + dev: false + /lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} @@ -3624,17 +4431,42 @@ packages: dependencies: yallist: 4.0.0 + /lru-queue@0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + dependencies: + es5-ext: 0.10.62 + dev: true + + /map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + dev: false + /media-typer@0.3.0: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} dev: false + /memoizee@0.4.15: + resolution: {integrity: sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-weak-map: 2.0.3 + event-emitter: 0.3.5 + is-promise: 2.2.2 + lru-queue: 0.1.0 + next-tick: 1.1.0 + timers-ext: 0.1.7 + dev: true + /merge-descriptors@1.0.1: resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} dev: false /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: false /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} @@ -3673,11 +4505,7 @@ packages: /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - - /mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - dev: true + dev: false /mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} @@ -3699,7 +4527,13 @@ packages: engines: {node: '>=10'} dependencies: brace-expansion: 2.0.1 - dev: false + + /minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true /minimatch@9.0.1: resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} @@ -3760,30 +4594,9 @@ packages: engines: {node: '>= 0.6'} dev: false - /next-auth@4.22.5(next@13.4.13)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-zPVEpqDp4cx1y0HbonCSrz2sA4qw0grTMd/S0PezUKXvDzmVemtsJnfNK/xo5pO2sz5ilM541+EVCTp9QoRLbA==} - peerDependencies: - next: ^12.2.5 || ^13 - nodemailer: ^6.6.5 - react: ^17.0.2 || ^18 - react-dom: ^17.0.2 || ^18 - peerDependenciesMeta: - nodemailer: - optional: true - dependencies: - '@babel/runtime': 7.22.10 - '@panva/hkdf': 1.1.1 - cookie: 0.5.0 - jose: 4.14.4 - next: 13.4.13(react-dom@18.2.0)(react@18.2.0) - oauth: 0.9.15 - openid-client: 5.4.3 - preact: 10.16.0 - preact-render-to-string: 5.2.6(preact@10.16.0) - react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) - uuid: 8.3.2 - dev: false + /next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + dev: true /next@13.4.13(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-A3YVbVDNeXLhWsZ8Nf6IkxmNlmTNz0yVg186NJ97tGZqPDdPzTrHotJ+A1cuJm2XfuWPrKOUZILl5iBQkIf8Jw==} @@ -3803,7 +4616,7 @@ packages: '@next/env': 13.4.13 '@swc/helpers': 0.5.1 busboy: 1.6.0 - caniuse-lite: 1.0.30001519 + caniuse-lite: 1.0.30001520 postcss: 8.4.14 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) @@ -3834,6 +4647,13 @@ packages: next: 13.4.13(react-dom@18.2.0)(react@18.2.0) dev: false + /no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.4.1 + dev: false + /node-abi@3.45.0: resolution: {integrity: sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==} engines: {node: '>=10'} @@ -3845,6 +4665,10 @@ packages: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} dev: false + /node-fetch-native@1.0.1: + resolution: {integrity: sha512-VzW+TAk2wE4X9maiKMlT+GsPU4OMmR1U9CrHSmd3DFLn2IcZ9VJ6M6BBugGfYUnPCLSYxXdZy17M0BEJyhUTwg==} + dev: false + /node-fetch@2.6.12: resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} engines: {node: 4.x || >=6.0.0} @@ -3913,31 +4737,12 @@ packages: engines: {node: '>=8'} dependencies: path-key: 3.1.1 - - /npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dependencies: - path-key: 4.0.0 - dev: true - - /oauth4webapi@2.3.0: - resolution: {integrity: sha512-JGkb5doGrwzVDuHwgrR4nHJayzN4h59VCed6EW8Tql6iHDfZIabCJvg6wtbn5q6pyB2hZruI3b77Nudvq7NmvA==} - dev: false - - /oauth@0.9.15: - resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} dev: false /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - /object-hash@2.2.0: - resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} - engines: {node: '>= 6'} - dev: false - /object-hash@3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} @@ -4003,11 +4808,6 @@ packages: es-abstract: 1.22.1 dev: true - /oidc-token-hash@5.0.3: - resolution: {integrity: sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==} - engines: {node: ^10.13.0 || >=12.0.0} - dev: false - /once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: @@ -4018,37 +4818,12 @@ packages: engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 - - /onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} - dependencies: - mimic-fn: 4.0.0 - dev: true - - /open@9.1.0: - resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} - engines: {node: '>=14.16'} - dependencies: - default-browser: 4.0.0 - define-lazy-prop: 3.0.0 - is-inside-container: 1.0.0 - is-wsl: 2.2.0 - dev: true + dev: false /openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} dev: false - /openid-client@5.4.3: - resolution: {integrity: sha512-sVQOvjsT/sbSfYsQI/9liWQGVZH/Pp3rrtlGEwgk/bbHfrUDZ24DN57lAagIwFtuEu+FM9Ev7r85s8S/yPjimQ==} - dependencies: - jose: 4.14.4 - lru-cache: 6.0.0 - object-hash: 2.2.0 - oidc-token-hash: 5.0.3 - dev: false - /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -4155,14 +4930,13 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - /path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - dev: true - /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + /path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + dev: false + /path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -4337,32 +5111,6 @@ packages: picocolors: 1.0.0 source-map-js: 1.0.2 - /preact-render-to-string@5.2.3(preact@10.11.3): - resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==} - peerDependencies: - preact: '>=10' - dependencies: - preact: 10.11.3 - pretty-format: 3.8.0 - dev: false - - /preact-render-to-string@5.2.6(preact@10.16.0): - resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} - peerDependencies: - preact: '>=10' - dependencies: - preact: 10.16.0 - pretty-format: 3.8.0 - dev: false - - /preact@10.11.3: - resolution: {integrity: sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==} - dev: false - - /preact@10.16.0: - resolution: {integrity: sha512-XTSj3dJ4roKIC93pald6rWuB2qQJO9gO2iLLyTe87MrjQN+HklueLsmskbywEWqCHlclgz3/M4YLL2iBr9UmMA==} - dev: false - /prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} engines: {node: '>=10'} @@ -4392,10 +5140,6 @@ packages: engines: {node: '>=6'} dev: false - /pretty-format@3.8.0: - resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==} - dev: false - /pretty@2.0.0: resolution: {integrity: sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==} engines: {node: '>=0.10.0'} @@ -4405,14 +5149,6 @@ packages: js-beautify: 1.14.9 dev: false - /prisma@5.1.1: - resolution: {integrity: sha512-WJFG/U7sMmcc6TjJTTifTfpI6Wjoh55xl4AzopVwAdyK68L9/ogNo8QQ2cxuUjJf/Wa82z/uhyh3wMzvRIBphg==} - engines: {node: '>=16.13'} - hasBin: true - requiresBuild: true - dependencies: - '@prisma/engines': 5.1.1 - /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: false @@ -4445,6 +5181,17 @@ packages: engines: {node: '>=6'} dev: true + /pvtsutils@1.3.3: + resolution: {integrity: sha512-6sAOMlXyrJ+8tRN5IAaYfuYZRp1C2uJ0SyDynEFxL+VY8kCRib9Lpj/+KPaNFpaQWr/iRik5nrzz6iaNlxgEGA==} + dependencies: + tslib: 2.6.1 + dev: false + + /pvutils@1.1.3: + resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} + engines: {node: '>=6.0.0'} + dev: false + /qs@6.11.2: resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} engines: {node: '>=0.6'} @@ -4459,6 +5206,11 @@ packages: resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==} dev: false + /quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + dev: false + /quick-lru@5.1.1: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} @@ -4702,13 +5454,6 @@ packages: glob: 7.2.3 dev: true - /run-applescript@5.0.0: - resolution: {integrity: sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==} - engines: {node: '>=12'} - dependencies: - execa: 5.1.1 - dev: true - /run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} dependencies: @@ -4825,6 +5570,7 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: false /simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} @@ -4844,19 +5590,54 @@ packages: is-arrayish: 0.3.2 dev: false + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - /slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + /snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.4.1 + dev: false + + /snakecase-keys@3.2.1: + resolution: {integrity: sha512-CjU5pyRfwOtaOITYv5C8DzpZ8XA/ieRsDpr93HI2r6e3YInC6moZpSQbmUtg8cTk58tq2x3jcG2gv+p1IZGmMA==} + engines: {node: '>=8'} + dependencies: + map-obj: 4.3.0 + to-snake-case: 1.0.0 + dev: false + + /snakecase-keys@5.4.4: + resolution: {integrity: sha512-YTywJG93yxwHLgrYLZjlC75moVEX04LZM4FHfihjHe1FCXm+QaLOFfSf535aXOAd0ArVQMWUAe8ZPm4VtWyXaA==} engines: {node: '>=12'} - dev: true + dependencies: + map-obj: 4.3.0 + snake-case: 3.0.4 + type-fest: 2.19.0 + dev: false /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + /spdx-correct@3.2.0: resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} dependencies: @@ -4963,11 +5744,7 @@ packages: /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} - - /strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - dev: true + dev: false /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} @@ -5046,13 +5823,13 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - /synckit@0.8.5: - resolution: {integrity: sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q==} - engines: {node: ^14.18.0 || >=16.0.0} + /swr@1.3.0(react@18.2.0): + resolution: {integrity: sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 dependencies: - '@pkgr/utils': 2.4.2 - tslib: 2.6.1 - dev: true + react: 18.2.0 + dev: false /tailwindcss@3.2.7(postcss@8.4.21): resolution: {integrity: sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ==} @@ -5177,17 +5954,35 @@ packages: any-promise: 1.3.0 dev: true - /titleize@3.0.0: - resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==} - engines: {node: '>=12'} + /timers-ext@0.1.7: + resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==} + dependencies: + es5-ext: 0.10.62 + next-tick: 1.1.0 dev: true + /to-no-case@1.0.2: + resolution: {integrity: sha512-Z3g735FxuZY8rodxV4gH7LxClE4H0hTIyHNIHdk+vpQxjLm0cwnKXq/OFVZ76SOQmto7txVcwSCwkU5kqp+FKg==} + dev: false + /to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 + /to-snake-case@1.0.0: + resolution: {integrity: sha512-joRpzBAk1Bhi2eGEYBjukEWHOe/IvclOkiJl3DtA91jV6NwQ3MwXA4FHYeqk8BNp/D8bmi9tcNbRu/SozP0jbQ==} + dependencies: + to-space-case: 1.0.0 + dev: false + + /to-space-case@1.0.0: + resolution: {integrity: sha512-rLdvwXZ39VOn1IxGL3V6ZstoTbwLRckQmn/U8ZDLuWwIXNpuZDhQ3AiRUlhTbOXFVE9C+dR51wM0CBDhk31VcA==} + dependencies: + to-no-case: 1.0.2 + dev: false + /to-utf8@0.0.1: resolution: {integrity: sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==} dev: false @@ -5252,8 +6047,13 @@ packages: strip-bom: 3.0.0 dev: true + /tslib@2.4.1: + resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} + dev: false + /tslib@2.6.1: resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} + dev: false /tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -5289,6 +6089,11 @@ packages: engines: {node: '>=8'} dev: false + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: false + /type-fest@3.13.0: resolution: {integrity: sha512-Gur3yQGM9qiLNs0KPP7LPgeRbio2QTt4xXouobMCarR0/wyW3F+F/+OWwshg3NG0Adon7uQfSZBpB46NfhoF1A==} engines: {node: '>=14.16'} @@ -5302,6 +6107,14 @@ packages: mime-types: 2.1.35 dev: false + /type@1.2.0: + resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} + dev: true + + /type@2.7.2: + resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} + dev: true + /typed-array-buffer@1.0.0: resolution: {integrity: sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==} engines: {node: '>= 0.4'} @@ -5382,11 +6195,6 @@ packages: engines: {node: '>= 0.8'} dev: false - /untildify@4.0.0: - resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} - engines: {node: '>=8'} - dev: true - /unzipper@0.10.14: resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} dependencies: @@ -5430,11 +6238,6 @@ packages: /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false - /validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} dependencies: @@ -5461,6 +6264,16 @@ packages: defaults: 1.0.4 dev: false + /webcrypto-core@1.7.7: + resolution: {integrity: sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==} + dependencies: + '@peculiar/asn1-schema': 2.3.6 + '@peculiar/json-schema': 1.1.12 + asn1js: 3.0.5 + pvtsutils: 1.3.3 + tslib: 2.4.1 + dev: false + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} dev: false @@ -5504,6 +6317,10 @@ packages: dependencies: isexe: 2.0.0 + /wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + dev: true + /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} @@ -5554,4 +6371,3 @@ packages: /zod@3.21.4: resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} - dev: false diff --git a/prisma/schema.prisma b/prisma/schema.prisma deleted file mode 100644 index edcd219..0000000 --- a/prisma/schema.prisma +++ /dev/null @@ -1,109 +0,0 @@ -generator client { - provider = "prisma-client-js" -} - -datasource db { - provider = "mysql" - url = env("DATABASE_URL") - relationMode = "prisma" -} - -model Account { - id String @id @default(cuid()) - createdAt DateTime @default(now()) - userId String - type String - provider String - providerAccountId String - refresh_token String? @db.Text - access_token String? @db.Text - expires_at Int? - token_type String? - scope String? - id_token String? @db.Text - session_state String? - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@unique([provider, providerAccountId]) - @@index([userId]) -} - -model Session { - id String @id @default(cuid()) - createdAt DateTime @default(now()) - sessionToken String @unique - userId String - expires DateTime - user User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@index([userId]) -} - -model User { - id String @id @default(cuid()) - createdAt DateTime @default(now()) - name String? - email String? @unique - emailVerified DateTime? - image String? - accounts Account[] - sessions Session[] - rooms Room[] - votes Vote[] - logs Log[] - isAdmin Boolean @default(false) - isVIP Boolean @default(false) - -} - -model VerificationToken { - identifier String - token String @unique - expires DateTime - - @@unique([identifier, token]) -} - -model Room { - id String @id @unique @default(cuid()) - createdAt DateTime @default(now()) - userId String - roomName String - storyName String - visible Boolean - votes Vote[] - scale String - logs Log[] - owner User @relation(fields: [userId], references: [id], onDelete: Cascade) - - @@index([userId]) -} - -model Vote { - id String @id @unique @default(cuid()) - createdAt DateTime @default(now()) - userId String - roomId String - value String - owner User @relation(fields: [userId], references: [id], onDelete: Cascade) - room Room @relation(fields: [roomId], references: [id], onDelete: Cascade) - - @@unique([userId, roomId]) - @@index([roomId]) -} - -model Log { - id String @id @unique @default(cuid()) - createdAt DateTime @default(now()) - userId String - roomId String - scale String - votes Json - roomName String - storyName String - owner User @relation(fields: [userId], references: [id], onDelete: Cascade) - room Room @relation(fields: [roomId], references: [id], onDelete: Cascade) - - @@index([userId]) - @@index([roomId]) -} diff --git a/src/components/Navbar.tsx b/src/components/Navbar.tsx index eabc8e3..8524ddb 100644 --- a/src/components/Navbar.tsx +++ b/src/components/Navbar.tsx @@ -1,4 +1,4 @@ -import { signIn, signOut, useSession } from "next-auth/react"; +import { UserButton, useUser } from "@clerk/nextjs"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/router"; @@ -9,19 +9,22 @@ interface NavbarProps { } const Navbar = ({ title }: NavbarProps) => { - const { data: sessionData, status: sessionStatus } = useSession(); + const { isLoaded, isSignedIn } = useUser(); const router = useRouter(); const navigationMenu = () => { - if (sessionStatus === "authenticated" && router.pathname !== "/dashboard") { + if (router.pathname !== "/dashboard" && isSignedIn) { return ( Dashboard ); - } else if (sessionStatus === "unauthenticated") { + } else if (!isSignedIn) { return ( - ); @@ -51,7 +54,7 @@ const Navbar = ({ title }: NavbarProps) => { - {sessionStatus === "loading" ? ( + {!isLoaded ? (
@@ -59,53 +62,7 @@ const Navbar = ({ title }: NavbarProps) => { navigationMenu() )} - {sessionData?.user.image && ( -
-
- - -
-
- )} + ); }; diff --git a/src/components/RoomList.tsx b/src/components/RoomList.tsx index bde86da..f59bf7a 100644 --- a/src/components/RoomList.tsx +++ b/src/components/RoomList.tsx @@ -1,25 +1,24 @@ -import { useSession } from "next-auth/react"; import Link from "next/link"; - import { configureAbly, useChannel } from "@ably-labs/react-hooks"; import { useState } from "react"; import { IoEnterOutline, IoTrashBinOutline } from "react-icons/io5"; import { env } from "~/env.mjs"; import { api } from "~/utils/api"; +import { useUser } from "@clerk/nextjs"; const RoomList = () => { - const { data: sessionData } = useSession(); + const { isSignedIn, user } = useUser(); configureAbly({ key: env.NEXT_PUBLIC_ABLY_PUBLIC_KEY, - clientId: sessionData?.user.id, + clientId: user?.id, recover: (_, cb) => { cb(true); }, }); const [] = useChannel( - `${env.NEXT_PUBLIC_APP_ENV}-${sessionData ? sessionData.user.id : ""}`, + `${env.NEXT_PUBLIC_APP_ENV}-${user?.id}`, () => void refetchRoomsFromDb() ); @@ -27,7 +26,7 @@ const RoomList = () => { const { data: roomsFromDb, refetch: refetchRoomsFromDb } = api.room.getAll.useQuery(undefined, { - enabled: sessionData?.user !== undefined, + enabled: isSignedIn, }); const createRoom = api.room.create.useMutation({}); @@ -43,7 +42,7 @@ const RoomList = () => { const deleteRoom = api.room.delete.useMutation({}); const deleteRoomHandler = (roomId: string) => { - if (sessionData) { + if (isSignedIn) { deleteRoom.mutate({ id: roomId }); } }; diff --git a/src/components/Stats.tsx b/src/components/Stats.tsx deleted file mode 100644 index 7dccda4..0000000 --- a/src/components/Stats.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import { configureAbly, useChannel } from "@ably-labs/react-hooks"; -import { env } from "~/env.mjs"; -import { api } from "~/utils/api"; - -const Stats = () => { - configureAbly({ - key: env.NEXT_PUBLIC_ABLY_PUBLIC_KEY, - recover: (_, cb) => { - cb(true); - }, - }); - - const [] = useChannel( - `${env.NEXT_PUBLIC_APP_ENV}-stats`, - () => void refetchData() - ); - - const { - data: usersCount, - isLoading: usersCountLoading, - isFetching: usersCountFetching, - refetch: refetchUsersCount, - } = api.rest.userCount.useQuery(); - const { - data: roomsCount, - isLoading: roomsCountLoading, - isFetching: roomsCountFetching, - refetch: refetchRoomsCount, - } = api.rest.roomCount.useQuery(); - const { - data: votesCount, - isLoading: votesCountLoading, - isFetching: votesCountFetching, - refetch: refetchVotesCount, - } = api.rest.voteCount.useQuery(); - - const refetchData = async () => { - await Promise.all([ - refetchUsersCount(), - refetchRoomsCount(), - refetchVotesCount(), - ]); - }; - - return ( -
-
-
Users
-
- {usersCountLoading || usersCountFetching ? ( - - ) : ( - <>{usersCount ? usersCount : "0"} - )} -
-
- -
-
Rooms
-
- {roomsCountLoading || roomsCountFetching ? ( - - ) : ( - <>{roomsCount ? roomsCount : "0"} - )} -
-
- -
-
Votes
-
- {votesCountLoading || votesCountFetching ? ( - - ) : ( - <>{votesCount ? votesCount : "0"} - )} -
-
-
- ); -}; - -export default Stats; diff --git a/src/env.mjs b/src/env.mjs index 6212cc3..57cf2d4 100644 --- a/src/env.mjs +++ b/src/env.mjs @@ -12,17 +12,6 @@ const server = z.object({ UPSTASH_RATELIMIT_REQUESTS: z.string(), UPSTASH_RATELIMIT_SECONDS: z.string(), NODE_ENV: z.enum(["development", "test", "production"]), - NEXTAUTH_SECRET: - process.env.NODE_ENV === "production" - ? z.string().min(1) - : z.string().min(1).optional(), - NEXTAUTH_URL: z.preprocess( - // This makes Vercel deployments not fail if you don't set NEXTAUTH_URL - // Since NextAuth.js automatically uses the VERCEL_URL if present. - (str) => process.env.VERCEL_URL ?? str, - // VERCEL_URL doesn't include `https` so it cant be validated as a URL - process.env.VERCEL ? z.string().min(1) : z.string().url() - ), GITHUB_CLIENT_ID: z.string(), GITHUB_CLIENT_SECRET: z.string(), GOOGLE_CLIENT_ID: z.string(), @@ -31,6 +20,7 @@ const server = z.object({ APP_ENV: z.string(), RESEND_API_KEY: z.string(), UNKEY_ROOT_KEY: z.string(), + CLERK_SECRET_KEY: z.string(), }); /** @@ -40,6 +30,7 @@ const server = z.object({ const client = z.object({ NEXT_PUBLIC_ABLY_PUBLIC_KEY: z.string(), NEXT_PUBLIC_APP_ENV: z.string(), + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string(), }); /** @@ -56,8 +47,6 @@ const processEnv = { UPSTASH_RATELIMIT_REQUESTS: process.env.UPSTASH_RATELIMIT_REQUESTS, UPSTASH_RATELIMIT_SECONDS: process.env.UPSTASH_RATELIMIT_SECONDS, NODE_ENV: process.env.NODE_ENV, - NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET, - NEXTAUTH_URL: process.env.NEXTAUTH_URL, GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET, GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID, @@ -68,6 +57,9 @@ const processEnv = { NEXT_PUBLIC_APP_ENV: process.env.NEXT_PUBLIC_APP_ENV, RESEND_API_KEY: process.env.RESEND_API_KEY, UNKEY_ROOT_KEY: process.env.UNKEY_ROOT_KEY, + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: + process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, + CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, }; // Don't touch the part below diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..807e65c --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,9 @@ +import { authMiddleware } from "@clerk/nextjs"; + +export default authMiddleware({ + publicRoutes: ["/", "/api/(.*)"], +}); + +export const config = { + matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"], +}; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 0518f20..d8c87a0 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,56 +1,23 @@ -import { type Session } from "next-auth"; -import { SessionProvider } from "next-auth/react"; import { type AppType } from "next/app"; +import { ClerkProvider } from "@clerk/nextjs"; import { api } from "~/utils/api"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; import Footer from "~/components/Footer"; import Navbar from "~/components/Navbar"; import "~/styles/globals.css"; -const MyApp: AppType<{ session: Session | null }> = ({ - Component, - pageProps: { session, ...pageProps }, -}) => { - const [pageLoading, setPageLoading] = useState(false); - const router = useRouter(); - - useEffect(() => { - router.events.on("routeChangeStart", () => { - setPageLoading(true); - }); - - router.events.on("routeChangeComplete", () => { - setPageLoading(false); - }); - - return () => { - router.events.off("routeChangeStart", () => { - setPageLoading(true); - }); - - router.events.off("routeChangeComplete", () => { - setPageLoading(false); - }); - }; - }, [router.events]); - +const MyApp: AppType = ({ Component, pageProps }) => { return ( - +
- { pageLoading ? ( - - ) : ( - - ) } +
-
+ ); }; diff --git a/src/pages/admin/index.tsx b/src/pages/admin/index.tsx deleted file mode 100644 index 9c71901..0000000 --- a/src/pages/admin/index.tsx +++ /dev/null @@ -1,270 +0,0 @@ -import { type GetServerSideProps, type NextPage } from "next"; -import Head from "next/head"; - -import { AiOutlineClear } from "react-icons/ai"; -import { FaShieldAlt } from "react-icons/fa"; -import { IoTrashBinOutline } from "react-icons/io5"; -import { SiGithub, SiGoogle } from "react-icons/si"; -import { GiStarFormation } from "react-icons/gi"; -import { api } from "~/utils/api"; -import { getServerAuthSession } from "../../server/auth"; -import Stats from "~/components/Stats"; - -export const getServerSideProps: GetServerSideProps = async (ctx) => { - const session = await getServerAuthSession(ctx); - - // Redirect to login if not signed in - if (!session) { - return { - redirect: { - destination: `/api/auth/signin?callbackUrl=${ctx.resolvedUrl}`, - permanent: false, - }, - }; - } - - if (!session.user.isAdmin) { - ctx.res.statusCode = 403; - return { - redirect: { - destination: "/", - permanent: false, - }, - }; - } - // Return session if logged in - return { - props: { session }, - }; -}; - -const Admin: NextPage = () => { - return ( - <> - - Sprint Padawan - Admin - - -
-
- -
-
- - ); -}; - -export default Admin; - -const AdminBody = () => { - const { - data: users, - isLoading: usersLoading, - isFetching: usersFetching, - refetch: refetchUsers, - } = api.user.getAll.useQuery(); - - const getProviders = (user: { - createdAt: Date; - accounts: { - provider: string; - }[]; - sessions: { - id: string; - }[]; - id: string; - isAdmin: boolean; - isVIP: boolean; - name: string | null; - email: string | null; - }) => { - return user.accounts.map((account) => { - return account.provider; - }); - }; - - const deleteUserMutation = api.user.delete.useMutation({ - onSuccess: async () => { - await refetchData(); - }, - }); - - const clearSessionsByUserMutation = api.session.deleteAllByUserId.useMutation( - { - onSuccess: async () => { - await refetchData(); - }, - } - ); - - const clearSessionsMutation = api.session.deleteAll.useMutation({ - onSuccess: async () => { - await refetchData(); - }, - }); - - const setAdminMutation = api.user.setAdmin.useMutation({ - onSuccess: async () => { - await refetchData(); - }, - }); - - const setVIPMutation = api.user.setVIP.useMutation({ - onSuccess: async () => { - await refetchData(); - }, - }); - - const deleteUserHandler = async (userId: string) => { - await deleteUserMutation.mutateAsync({ userId }); - }; - - const clearSessionsByUserHandler = async (userId: string) => { - await clearSessionsByUserMutation.mutateAsync({ userId }); - }; - - const clearSessionsHandler = async () => { - await clearSessionsMutation.mutateAsync(); - }; - - const setAdmin = async (userId: string, value: boolean) => { - await setAdminMutation.mutateAsync({ userId, value }); - }; - - const setVIP = async (userId: string, value: boolean) => { - await setVIPMutation.mutateAsync({ userId, value }); - }; - - const refetchData = async () => { - await Promise.all([refetchUsers()]); - }; - - return ( - <> -

Admin Panel

- - - - {usersFetching ? ( - - ) : ( -
- - - -
- )} - -
-
-

Users:

- - {usersLoading || usersFetching ? ( - - ) : ( -
- - {/* head */} - - - - - - - - - - - - {users - ?.sort((user1, user2) => - user2.createdAt > user1.createdAt ? 1 : -1 - ) - .map((user) => { - return ( - - - - - - - - - - ); - })} - -
IDNameCreated At# SessionsProvidersActions
- {user.id} - - {user.name} - - {user.createdAt.toLocaleDateString()} - - {user.sessions.length} - - {getProviders(user).includes("google") && ( - - )} - {getProviders(user).includes("github") && ( - - )} - - - - - -
-
- )} -
-
- - ); -}; diff --git a/src/pages/api/auth/[...nextauth].ts b/src/pages/api/auth/[...nextauth].ts deleted file mode 100644 index 8aefbb6..0000000 --- a/src/pages/api/auth/[...nextauth].ts +++ /dev/null @@ -1,4 +0,0 @@ -import NextAuth from "next-auth"; -import { authOptions } from "~/server/auth"; - -export default NextAuth(authOptions); diff --git a/src/pages/api/trpc/[...trpc].ts b/src/pages/api/trpc/[...trpc].ts index 630df52..6c53746 100644 --- a/src/pages/api/trpc/[...trpc].ts +++ b/src/pages/api/trpc/[...trpc].ts @@ -10,9 +10,9 @@ export default createNextApiHandler({ onError: env.NODE_ENV === "development" ? ({ path, error }) => { - console.error( - `❌ tRPC failed on ${path ?? ""}: ${error.message}`, - ); - } + console.error( + `❌ tRPC failed on ${path ?? ""}: ${error.message}` + ); + } : undefined, }); diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx index 06c34dd..2056b14 100644 --- a/src/pages/dashboard/index.tsx +++ b/src/pages/dashboard/index.tsx @@ -1,5 +1,4 @@ -import type { GetServerSideProps, NextPage } from "next"; -import { useSession } from "next-auth/react"; +import type { NextPage } from "next"; import Head from "next/head"; import RoomList from "~/components/RoomList"; @@ -7,27 +6,8 @@ import RoomList from "~/components/RoomList"; import Link from "next/link"; import { useEffect, useState } from "react"; import { FaShieldAlt } from "react-icons/fa"; -import { getServerAuthSession } from "~/server/auth"; import { GiStarFormation } from "react-icons/gi"; - -export const getServerSideProps: GetServerSideProps = async (ctx) => { - const session = await getServerAuthSession(ctx); - - // Redirect to login if not signed in - if (!session) { - return { - redirect: { - destination: `/api/auth/signin?callbackUrl=${ctx.resolvedUrl}`, - permanent: false, - }, - }; - } - - // Return session if logged in - return { - props: { session }, - }; -}; +import { useUser } from "@clerk/nextjs"; const Home: NextPage = () => { return ( @@ -46,23 +26,27 @@ const Home: NextPage = () => { export default Home; const HomePageBody = () => { - const { data: sessionData } = useSession(); + const { isLoaded, user } = useUser(); const [joinRoomTextBox, setJoinRoomTextBox] = useState(""); const [tabIndex, setTabIndex] = useState(); useEffect(() => { const tabIndexLocal = localStorage.getItem(`dashboardTabIndex`); setTabIndex(tabIndexLocal !== null ? Number(tabIndexLocal) : 0); - }, [tabIndex, sessionData]); + }, [tabIndex, user]); - return ( + return !isLoaded ? ( +
+ +
+ ) : ( <>

- Hi, {sessionData?.user.name}!{" "} - {sessionData?.user.isAdmin && ( + Hi, {user?.fullName}!{" "} + {(user?.publicMetadata.isAdmin as boolean | undefined) && ( )} - {sessionData?.user.isVIP && ( + {(user?.publicMetadata.isVIP as boolean | undefined) && ( )}

diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 5c74764..485f66b 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,6 +1,5 @@ import { type NextPage } from "next"; import Head from "next/head"; -import Stats from "~/components/Stats"; const Home: NextPage = () => { return ( @@ -55,13 +54,6 @@ const HomePageBody = () => { - -
-
-

Stats:

- -
-
); }; diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx deleted file mode 100644 index bb864d6..0000000 --- a/src/pages/profile/index.tsx +++ /dev/null @@ -1,205 +0,0 @@ -import { type GetServerSideProps, type NextPage } from "next"; -import Head from "next/head"; -import Image from "next/image"; - -import { signIn, useSession } from "next-auth/react"; -import { useRouter } from "next/router"; -import { useEffect, useState } from "react"; -import { FaShieldAlt } from "react-icons/fa"; -import { SiGithub, SiGoogle } from "react-icons/si"; -import { api } from "~/utils/api"; -import { getServerAuthSession } from "../../server/auth"; -import { GiStarFormation } from "react-icons/gi"; - -export const getServerSideProps: GetServerSideProps = async (ctx) => { - const session = await getServerAuthSession(ctx); - - // Redirect to login if not signed in - if (!session) { - return { - redirect: { - destination: `/api/auth/signin?callbackUrl=${ctx.resolvedUrl}`, - permanent: false, - }, - }; - } - - // Return session if logged in - return { - props: { session }, - }; -}; - -const Profile: NextPage = () => { - return ( - <> - - Sprint Padawan - Profile - - -
-
- -
-
- - ); -}; - -export default Profile; - -const ProfileBody = () => { - const { data: sessionData } = useSession(); - const [nameText, setNameText] = useState(""); - const router = useRouter(); - - const { data: providers, isLoading: providersLoading } = - api.user.getProviders.useQuery(); - - const deleteUserMutation = api.user.delete.useMutation({}); - const saveUserMutation = api.user.save.useMutation({}); - - const deleteCurrentUser = async () => { - await deleteUserMutation.mutateAsync(); - (document.querySelector("#delete-user-modal") as HTMLInputElement).checked = - false; - router.reload(); - }; - - const saveUser = async () => { - await saveUserMutation.mutateAsync({ - name: nameText, - }); - router.reload(); - }; - - useEffect(() => { - setNameText(sessionData?.user.name || ""); - }, [sessionData]); - - if (sessionData) { - return ( - <> - -
-
- - -

- This action will delete ALL data associated with your account. The - same GitHub Account can be used, but none of your existing data - will be available. If you are sure, please confirm below: -

- -
- -
-
-
- -
-
-

Profile:

- {sessionData.user.image && ( - Profile picture. - )} - -
- {sessionData.user.isAdmin && ( -
- -
- )} - {sessionData.user.isVIP && ( -
- -
- )} -
- - {providersLoading ? ( -
- {" "} -
- ) : ( -
- - - -
- )} - - {sessionData.user.name && ( - setNameText(event.target.value)} - /> - )} - - {sessionData.user.email && ( - - )} - - - - {/* */} - - -
-
- - ); - } else { - return

Error getting login session!

; - } -}; diff --git a/src/pages/room/[id].tsx b/src/pages/room/[id].tsx index e161c4b..9dca889 100644 --- a/src/pages/room/[id].tsx +++ b/src/pages/room/[id].tsx @@ -1,10 +1,9 @@ -import { type GetServerSideProps, type NextPage } from "next"; +import { type NextPage } from "next"; import Head from "next/head"; import Image from "next/image"; import { useEffect, useState } from "react"; import { EventTypes } from "~/utils/types"; -import { useSession } from "next-auth/react"; import { useRouter } from "next/router"; import { IoCheckmarkCircleOutline, @@ -17,10 +16,7 @@ import { IoSaveOutline, } from "react-icons/io5"; import { GiStarFormation } from "react-icons/gi"; -import { z } from "zod"; import { api } from "~/utils/api"; -import { getServerAuthSession } from "../../server/auth"; - import { configureAbly, useChannel, usePresence } from "@ably-labs/react-hooks"; import Link from "next/link"; import { FaShieldAlt } from "react-icons/fa"; @@ -28,27 +24,10 @@ import { RiVipCrownFill } from "react-icons/ri"; import { env } from "~/env.mjs"; import { downloadCSV } from "~/utils/helpers"; import type { PresenceItem } from "~/utils/types"; - -export const getServerSideProps: GetServerSideProps = async (ctx) => { - const session = await getServerAuthSession(ctx); - - // Redirect to login if not signed in - if (!session) { - return { - redirect: { - destination: `/api/auth/signin?callbackUrl=${ctx.resolvedUrl}`, - permanent: false, - }, - }; - } - - // Return session if logged in - return { - props: { session }, - }; -}; +import { useUser } from "@clerk/nextjs"; const Room: NextPage = () => { + const { isSignedIn } = useUser(); return ( <> @@ -57,7 +36,13 @@ const Room: NextPage = () => {
- + {!isSignedIn ? ( +
+ +
+ ) : ( + + )}
); @@ -66,9 +51,9 @@ const Room: NextPage = () => { export default Room; const RoomBody = ({}) => { - const { data: sessionData } = useSession(); + const { isSignedIn, user } = useUser(); const { query } = useRouter(); - const roomId = z.string().parse(query.id); + const roomId = query.id as string; const [storyNameText, setStoryNameText] = useState(""); const [roomScale, setRoomScale] = useState(""); @@ -85,7 +70,7 @@ const RoomBody = ({}) => { configureAbly({ key: env.NEXT_PUBLIC_ABLY_PUBLIC_KEY, - clientId: sessionData?.user.id, + clientId: user?.id, recover: (_, cb) => { cb(true); }, @@ -108,11 +93,11 @@ const RoomBody = ({}) => { const [presenceData] = usePresence( `${env.NEXT_PUBLIC_APP_ENV}-${roomId}`, { - name: sessionData?.user.name || "", - image: sessionData?.user.image || "", - client_id: sessionData?.user.id || "", - isAdmin: sessionData?.user.isAdmin || false, - isVIP: sessionData?.user.isVIP || false, + name: user?.fullName || "", + image: user?.imageUrl || "", + client_id: user?.id || "", + isAdmin: (user?.publicMetadata.isAdmin as boolean | undefined) || false, + isVIP: (user?.publicMetadata.isVIP as boolean | undefined) || false, } ); @@ -129,19 +114,16 @@ const RoomBody = ({}) => { // Init story name useEffect(() => { - if (sessionData && roomFromDb) { + if (isSignedIn && roomFromDb) { setStoryNameText(roomFromDb.storyName || ""); setRoomScale(roomFromDb.scale || "ERROR"); } - }, [roomFromDb, roomId, sessionData]); + }, [roomFromDb, roomId, isSignedIn, user]); // Helper functions const getVoteForCurrentUser = () => { - if (roomFromDb && sessionData) { - return ( - votesFromDb && - votesFromDb.find((vote) => vote.userId === sessionData.user.id) - ); + if (roomFromDb && isSignedIn) { + return votesFromDb && votesFromDb.find((vote) => vote.userId === user.id); } else { return null; } @@ -183,16 +165,16 @@ const RoomBody = ({}) => { }) .concat({ id: "LATEST", - createdAt: new Date(), - userId: roomFromDb.owner.id, + created_at: new Date(), + userId: roomFromDb.userId, roomId: roomFromDb.id, scale: roomScale, votes: votesFromDb.map((vote) => { return { - name: vote.owner.name, value: vote.value, }; }), + room: roomFromDb, roomName: roomFromDb.roomName, storyName: storyNameText, }); @@ -365,111 +347,108 @@ const RoomBody = ({}) => { )} - {sessionData && - !!roomFromDb && - roomFromDb.userId === sessionData.user.id && ( - <> -
-
-

Room Settings

+ {isSignedIn && !!roomFromDb && roomFromDb.userId === user.id && ( + <> +
+
+

Room Settings

- + - { - setRoomScale(event.target.value); - }} - /> + { + setRoomScale(event.target.value); + }} + /> - + - { - setStoryNameText(event.target.value); - }} - /> + { + setStoryNameText(event.target.value); + }} + /> -
-
- -
- -
- -
- - {votesFromDb && - (roomFromDb.logs.length > 0 || - votesFromDb.length > 0) && ( -
- -
+
+
+
+ +
+ +
+ + {votesFromDb && + (roomFromDb.logs.length > 0 || votesFromDb.length > 0) && ( +
+ +
+ )}
- - )} +
+ + )} ); // Room does not exist diff --git a/src/pages/sign-in/[[...index]].tsx b/src/pages/sign-in/[[...index]].tsx new file mode 100644 index 0000000..f84cb7f --- /dev/null +++ b/src/pages/sign-in/[[...index]].tsx @@ -0,0 +1,17 @@ +import { SignIn } from "@clerk/nextjs"; + +const SignInPage = () => ( +
+ +
+); + +export default SignInPage; + +const styles = { + width: "100vw", + height: "100vh", + display: "flex", + justifyContent: "center", + alignItems: "center", +}; diff --git a/src/pages/sign-up/[[...index]].tsx b/src/pages/sign-up/[[...index]].tsx new file mode 100644 index 0000000..ce6c5ea --- /dev/null +++ b/src/pages/sign-up/[[...index]].tsx @@ -0,0 +1,17 @@ +import { SignUp } from "@clerk/nextjs"; + +const SignUpPage = () => ( +
+ +
+); + +export default SignUpPage; + +const styles = { + width: "100vw", + height: "100vh", + display: "flex", + justifyContent: "center", + alignItems: "center", +}; diff --git a/src/server/api/root.ts b/src/server/api/root.ts index 7d5426a..4acf4e6 100644 --- a/src/server/api/root.ts +++ b/src/server/api/root.ts @@ -1,7 +1,5 @@ import { roomRouter } from "~/server/api/routers/room"; import { createTRPCRouter } from "~/server/api/trpc"; -import { sessionRouter } from "./routers/session"; -import { userRouter } from "./routers/user"; import { voteRouter } from "./routers/vote"; import { restRouter } from "./routers/rest"; @@ -13,8 +11,6 @@ import { restRouter } from "./routers/rest"; export const appRouter = createTRPCRouter({ room: roomRouter, vote: voteRouter, - user: userRouter, - session: sessionRouter, rest: restRouter, }); diff --git a/src/server/api/routers/rest.ts b/src/server/api/routers/rest.ts index 3d6ff86..ad90207 100644 --- a/src/server/api/routers/rest.ts +++ b/src/server/api/routers/rest.ts @@ -4,6 +4,8 @@ import { z } from "zod"; import { createTRPCRouter, publicProcedure } from "~/server/api/trpc"; import { TRPCError } from "@trpc/server"; import { fetchCache, setCache } from "~/server/redis"; +import { sql } from "drizzle-orm"; +import { rooms, votes } from "~/server/schema"; export const restRouter = createTRPCRouter({ dbWarmer: publicProcedure @@ -13,7 +15,7 @@ export const restRouter = createTRPCRouter({ .query(async ({ ctx, input }) => { const isValidKey = await validateApiKey(input.key); if (isValidKey) { - await ctx.prisma.verificationToken.findMany(); + await ctx.db.query.votes.findMany(); return "Toasted the DB"; } else { throw new TRPCError({ code: "UNAUTHORIZED" }); @@ -30,7 +32,11 @@ export const restRouter = createTRPCRouter({ if (cachedResult) { return cachedResult; } else { - const votesCount = await ctx.prisma.vote.count(); + const votesResult = ( + await ctx.db.select({ count: sql`count(*)` }).from(votes) + )[0]; + + const votesCount = votesResult ? Number(votesResult.count) : 0; await setCache(`kv_votecount`, votesCount); @@ -38,24 +44,6 @@ export const restRouter = createTRPCRouter({ } }), - userCount: publicProcedure - .meta({ openapi: { method: "GET", path: "/rest/users/count" } }) - .input(z.void()) - .output(z.number()) - .query(async ({ ctx }) => { - const cachedResult = await fetchCache(`kv_usercount`); - - if (cachedResult) { - return cachedResult; - } else { - const usersCount = await ctx.prisma.user.count(); - - await setCache(`kv_usercount`, usersCount); - - return usersCount; - } - }), - roomCount: publicProcedure .meta({ openapi: { method: "GET", path: "/rest/rooms/count" } }) .input(z.void()) @@ -66,7 +54,11 @@ export const restRouter = createTRPCRouter({ if (cachedResult) { return cachedResult; } else { - const roomsCount = await ctx.prisma.room.count(); + const roomsResult = ( + await ctx.db.select({ count: sql`count(*)` }).from(rooms) + )[0]; + + const roomsCount = roomsResult ? Number(roomsResult.count) : 0; await setCache(`kv_roomcount`, roomsCount); diff --git a/src/server/api/routers/room.ts b/src/server/api/routers/room.ts index 598b818..cf8c096 100644 --- a/src/server/api/routers/room.ts +++ b/src/server/api/routers/room.ts @@ -3,7 +3,10 @@ import { publishToChannel } from "~/server/ably"; import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc"; import { fetchCache, invalidateCache, setCache } from "~/server/redis"; +import { logs, rooms, votes } from "~/server/schema"; import { EventTypes } from "~/utils/types"; +import { createId } from "@paralleldrive/cuid2"; +import { eq } from "drizzle-orm"; export const roomRouter = createTRPCRouter({ // Create @@ -14,57 +17,52 @@ export const roomRouter = createTRPCRouter({ }) ) .mutation(async ({ ctx, input }) => { - if (ctx.session) { - const room = await ctx.prisma.room.create({ - data: { - userId: ctx.session.user.id, - roomName: input.name, - storyName: "First Story!", - scale: "0.5,1,2,3,5,8", - visible: false, - }, - }); - if (room) { - await invalidateCache(`kv_roomcount`); - await invalidateCache(`kv_roomlist_${ctx.session.user.id}`); + const room = await ctx.db.insert(rooms).values({ + id: createId(), + userId: ctx.auth.userId, + roomName: input.name, + storyName: "First Story!", + scale: "0.5,1,2,3,5,8", + visible: false, + }); - await publishToChannel( - `${ctx.session.user.id}`, - EventTypes.ROOM_LIST_UPDATE, - JSON.stringify(room) - ); + const success = room.rowsAffected > 0; + if (room) { + await invalidateCache(`kv_roomcount`); + await invalidateCache(`kv_roomlist_${ctx.auth.userId}`); - await publishToChannel( - `stats`, - EventTypes.STATS_UPDATE, - JSON.stringify(room) - ); - } - // happy path - return !!room; + await publishToChannel( + `${ctx.auth.userId}`, + EventTypes.ROOM_LIST_UPDATE, + JSON.stringify(room) + ); + + await publishToChannel( + `stats`, + EventTypes.STATS_UPDATE, + JSON.stringify(room) + ); } - - // clinically depressed path - return false; + return success; }), // Get One get: protectedProcedure .input(z.object({ id: z.string() })) .query(({ ctx, input }) => { - return ctx.prisma.room.findUnique({ - where: { - id: input.id, - }, - select: { - id: true, - userId: true, - logs: true, - roomName: true, - storyName: true, - visible: true, - scale: true, - owner: true, + return ctx.db.query.rooms.findFirst({ + where: eq(rooms.id, input.id), + with: { + logs: { + with: { + room: true, + }, + }, + votes: { + with: { + room: true, + }, + }, }, }); }), @@ -77,23 +75,16 @@ export const roomRouter = createTRPCRouter({ createdAt: Date; roomName: string; }[] - >(`kv_roomlist_${ctx.session.user.id}`); + >(`kv_roomlist_${ctx.auth.userId}`); if (cachedResult) { return cachedResult; } else { - const roomList = await ctx.prisma.room.findMany({ - where: { - userId: ctx.session.user.id, - }, - select: { - id: true, - createdAt: true, - roomName: true, - }, + const roomList = await ctx.db.query.rooms.findMany({ + where: eq(rooms.userId, ctx.auth.userId), }); - await setCache(`kv_roomlist_${ctx.session.user.id}`, roomList); + await setCache(`kv_roomlist_${ctx.auth.userId}`, roomList); return roomList; } @@ -114,119 +105,88 @@ export const roomRouter = createTRPCRouter({ .mutation(async ({ ctx, input }) => { if (input.reset) { if (input.log) { - const oldRoom = await ctx.prisma.room.findUnique({ - where: { - id: input.roomId, - }, - select: { - roomName: true, - storyName: true, - scale: true, - votes: { - select: { - owner: { - select: { - name: true, - }, - }, - value: true, - }, - }, + const oldRoom = await ctx.db.query.rooms.findFirst({ + where: eq(rooms.id, input.roomId), + with: { + votes: true, + logs: true, }, }); oldRoom && - (await ctx.prisma.log.create({ - data: { - userId: ctx.session.user.id, - roomId: input.roomId, - scale: oldRoom.scale, - votes: oldRoom.votes.map((vote) => { - return { - name: vote.owner.name, - value: vote.value, - }; - }), - roomName: oldRoom.roomName, - storyName: oldRoom.storyName, - }, + (await ctx.db.insert(logs).values({ + id: createId(), + userId: ctx.auth.userId, + roomId: input.roomId, + scale: oldRoom.scale, + votes: oldRoom.votes.map((vote) => { + return { + name: vote.userId, + value: vote.value, + }; + }), + roomName: oldRoom.roomName, + storyName: oldRoom.storyName, })); } - await ctx.prisma.vote.deleteMany({ - where: { - roomId: input.roomId, - }, - }); + await ctx.db.delete(votes).where(eq(votes.roomId, input.roomId)); await invalidateCache(`kv_votes_${input.roomId}`); } - const newRoom = await ctx.prisma.room.update({ - where: { - id: input.roomId, - }, - data: { + const newRoom = await ctx.db + .update(rooms) + .set({ storyName: input.name, - userId: ctx.session.user.id, + userId: ctx.auth.userId, visible: input.visible, scale: [...new Set(input.scale.split(","))] .filter((item) => item !== "") .toString(), - }, - select: { - id: true, - roomName: true, - storyName: true, - visible: true, - scale: true, - votes: { - select: { - owner: { - select: { - name: true, - }, - }, - value: true, - }, - }, - }, - }); + }) + .where(eq(rooms.id, input.roomId)); - if (newRoom) { + const success = newRoom.rowsAffected > 0; + + if (success) { await publishToChannel( - `${newRoom.id}`, + `${input.roomId}`, EventTypes.ROOM_UPDATE, JSON.stringify(newRoom) ); } - return !!newRoom; + return success; }), // Delete One delete: protectedProcedure .input(z.object({ id: z.string() })) .mutation(async ({ ctx, input }) => { - const deletedRoom = await ctx.prisma.room.delete({ - where: { - id: input.id, - }, - }); + const deletedRoom = await ctx.db + .delete(rooms) + .where(eq(rooms.id, input.id)); + + const success = deletedRoom.rowsAffected > 0; + + if (success) { + await ctx.db.delete(votes).where(eq(votes.roomId, input.id)); + + await ctx.db.delete(logs).where(eq(logs.roomId, input.id)); - if (deletedRoom) { await invalidateCache(`kv_roomcount`); await invalidateCache(`kv_votecount`); - await invalidateCache(`kv_roomlist_${ctx.session.user.id}`); + await invalidateCache(`kv_roomlist_${ctx.auth.userId}`); await publishToChannel( - `${ctx.session.user.id}`, + `${ctx.auth.userId}`, EventTypes.ROOM_LIST_UPDATE, JSON.stringify(deletedRoom) ); await publishToChannel( - `${deletedRoom.id}`, + `${input.id}`, EventTypes.ROOM_UPDATE, JSON.stringify(deletedRoom) ); @@ -238,6 +198,6 @@ export const roomRouter = createTRPCRouter({ ); } - return !!deletedRoom; + return success; }), }); diff --git a/src/server/api/routers/session.ts b/src/server/api/routers/session.ts deleted file mode 100644 index 7db9918..0000000 --- a/src/server/api/routers/session.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { z } from "zod"; -import { adminProcedure, createTRPCRouter } from "~/server/api/trpc"; -import { invalidateCache } from "~/server/redis"; - -export const sessionRouter = createTRPCRouter({ - deleteAllByUserId: adminProcedure - .input( - z.object({ - userId: z.string(), - }) - ) - .mutation(async ({ ctx, input }) => { - const sessions = await ctx.prisma.session.deleteMany({ - where: { - userId: input.userId, - }, - }); - - if (!!sessions) { - await invalidateCache(`kv_userlist_admin`); - } - - return !!sessions; - }), - deleteAll: adminProcedure.mutation(async ({ ctx }) => { - const sessions = await ctx.prisma.session.deleteMany(); - - if (!!sessions) { - await invalidateCache(`kv_userlist_admin`); - } - - return !!sessions; - }), -}); diff --git a/src/server/api/routers/user.ts b/src/server/api/routers/user.ts deleted file mode 100644 index 923d9eb..0000000 --- a/src/server/api/routers/user.ts +++ /dev/null @@ -1,194 +0,0 @@ -import type { User } from "@prisma/client"; -import { Resend } from "resend"; -import { z } from "zod"; -import { Goodbye } from "~/components/templates/Goodbye"; -import { env } from "~/env.mjs"; -import { publishToChannel } from "~/server/ably"; -import { - adminProcedure, - createTRPCRouter, - protectedProcedure, -} from "~/server/api/trpc"; - -import { fetchCache, invalidateCache, setCache } from "~/server/redis"; -import { EventTypes } from "~/utils/types"; - -const resend = new Resend(process.env.RESEND_API_KEY); - -export const userRouter = createTRPCRouter({ - getProviders: protectedProcedure.query(async ({ ctx }) => { - const providers = await ctx.prisma.user.findUnique({ - where: { - id: ctx.session.user.id, - }, - select: { - accounts: { - select: { - provider: true, - }, - }, - }, - }); - - return providers?.accounts.map((account) => { - return account.provider; - }); - }), - getAll: protectedProcedure.query(async ({ ctx }) => { - const cachedResult = await fetchCache< - { - accounts: { - provider: string; - }[]; - sessions: { - id: string; - }[]; - id: string; - createdAt: Date; - isAdmin: boolean; - isVIP: boolean; - name: string | null; - email: string | null; - }[] - >(`kv_userlist_admin`); - - if (cachedResult) { - return cachedResult.map((user) => { - return { - ...user, - createdAt: new Date(user.createdAt), - }; - }); - } else { - const users = await ctx.prisma.user.findMany({ - select: { - id: true, - name: true, - isAdmin: true, - isVIP: true, - createdAt: true, - email: true, - sessions: { - select: { - id: true, - }, - }, - accounts: { - select: { - provider: true, - }, - }, - }, - }); - - await setCache(`${env.APP_ENV}_kv_userlist_admin`, users); - - return users; - } - }), - delete: protectedProcedure - .input( - z - .object({ - userId: z.string(), - }) - .optional() - ) - .mutation(async ({ ctx, input }) => { - let user: User; - if (input?.userId && ctx.session.user.isAdmin) { - user = await ctx.prisma.user.delete({ - where: { - id: input.userId, - }, - }); - } else { - user = await ctx.prisma.user.delete({ - where: { - id: ctx.session.user.id, - }, - }); - } - - if (!!user && user.name && user.email) { - await resend.emails.send({ - from: "Sprint Padawan ", - to: user.email, - subject: "Sorry to see you go... 😭", - react: Goodbye({ name: user.name }), - }); - - await invalidateCache(`kv_usercount`); - await invalidateCache(`kv_userlist_admin`); - - await publishToChannel( - `stats`, - EventTypes.STATS_UPDATE, - JSON.stringify(user) - ); - } - - return !!user; - }), - save: protectedProcedure - .input( - z.object({ - name: z.string(), - }) - ) - .mutation(async ({ ctx, input }) => { - const user = await ctx.prisma.user.update({ - where: { - id: ctx.session.user.id, - }, - data: { - name: input.name, - }, - }); - - return !!user; - }), - setAdmin: adminProcedure - .input( - z.object({ - userId: z.string(), - value: z.boolean(), - }) - ) - .mutation(async ({ ctx, input }) => { - const user = await ctx.prisma.user.update({ - where: { - id: input.userId, - }, - data: { - isAdmin: input.value, - }, - }); - - await invalidateCache(`kv_userlist_admin`); - - return !!user; - }), - - setVIP: adminProcedure - .input( - z.object({ - userId: z.string(), - value: z.boolean(), - }) - ) - .mutation(async ({ ctx, input }) => { - const user = await ctx.prisma.user.update({ - where: { - id: input.userId, - }, - data: { - isVIP: input.value, - }, - }); - - await invalidateCache(`kv_userlist_admin`); - - return !!user; - }), -}); diff --git a/src/server/api/routers/vote.ts b/src/server/api/routers/vote.ts index c3e524b..28cad1d 100644 --- a/src/server/api/routers/vote.ts +++ b/src/server/api/routers/vote.ts @@ -1,10 +1,12 @@ import { z } from "zod"; import { publishToChannel } from "~/server/ably"; -import type { Room } from "@prisma/client"; import { createTRPCRouter, protectedProcedure } from "~/server/api/trpc"; import { fetchCache, invalidateCache, setCache } from "~/server/redis"; import { EventTypes } from "~/utils/types"; +import { eq } from "drizzle-orm"; +import { votes } from "~/server/schema"; +import { createId } from "@paralleldrive/cuid2"; export const voteRouter = createTRPCRouter({ getAllByRoomId: protectedProcedure @@ -12,14 +14,10 @@ export const voteRouter = createTRPCRouter({ .query(async ({ ctx, input }) => { const cachedResult = await fetchCache< { - value: string; - room: Room; id: string; - createdAt: Date; + value: string; + created_at: Date; userId: string; - owner: { - name: string | null; - }; roomId: string; }[] >(`kv_votes_${input.roomId}`); @@ -27,23 +25,8 @@ export const voteRouter = createTRPCRouter({ if (cachedResult) { return cachedResult; } else { - const votesByRoomId = await ctx.prisma.vote.findMany({ - where: { - roomId: input.roomId, - }, - select: { - id: true, - createdAt: true, - owner: { - select: { - name: true, - }, - }, - room: true, - roomId: true, - userId: true, - value: true, - }, + const votesByRoomId = await ctx.db.query.votes.findMany({ + where: eq(votes.roomId, input.roomId), }); await setCache(`kv_votes_${input.roomId}`, votesByRoomId); @@ -54,42 +37,34 @@ export const voteRouter = createTRPCRouter({ set: protectedProcedure .input(z.object({ value: z.string(), roomId: z.string() })) .mutation(async ({ ctx, input }) => { - const vote = await ctx.prisma.vote.upsert({ - where: { - userId_roomId: { - roomId: input.roomId, - userId: ctx.session.user.id, - }, - }, - create: { + const updateResult = await ctx.db + .update(votes) + .set({ value: input.value, - userId: ctx.session.user.id, + userId: ctx.auth.userId, roomId: input.roomId, - }, - update: { - value: input.value, - userId: ctx.session.user.id, - roomId: input.roomId, - }, - select: { - value: true, - userId: true, - roomId: true, - id: true, - owner: { - select: { - name: true, - }, - }, - }, - }); + }) + .where(eq(votes.userId, ctx.auth.userId)); - if (vote) { + let success = updateResult.rowsAffected > 0; + + if (!success) { + const vote = await ctx.db.insert(votes).ignore().values({ + id: createId(), + value: input.value, + userId: ctx.auth.userId, + roomId: input.roomId, + }); + + success = vote.rowsAffected > 0; + } + + if (success) { await invalidateCache(`kv_votecount`); await invalidateCache(`kv_votes_${input.roomId}`); await publishToChannel( - `${vote.roomId}`, + `${input.roomId}`, EventTypes.VOTE_UPDATE, input.value ); @@ -97,10 +72,10 @@ export const voteRouter = createTRPCRouter({ await publishToChannel( `stats`, EventTypes.STATS_UPDATE, - JSON.stringify(vote) + JSON.stringify(success) ); } - return !!vote; + return success; }), }); diff --git a/src/server/api/trpc.ts b/src/server/api/trpc.ts index 2bf95d0..ebce472 100644 --- a/src/server/api/trpc.ts +++ b/src/server/api/trpc.ts @@ -1,81 +1,71 @@ /** * YOU PROBABLY DON'T NEED TO EDIT THIS FILE, UNLESS: - * 1. You want to modify request context (see Part 1). - * 2. You want to create a new middleware or type of procedure (see Part 3). + * 1. You want to modify request context (see Part 1) + * 2. You want to create a new middleware or type of procedure (see Part 3) * - * TL;DR - This is where all the tRPC server stuff is created and plugged in. The pieces you will - * need to use are documented accordingly near the end. + * tl;dr - this is where all the tRPC server stuff is created and plugged in. + * The pieces you will need to use are documented accordingly near the end */ /** * 1. CONTEXT * - * This section defines the "contexts" that are available in the backend API. + * This section defines the "contexts" that are available in the backend API + * + * These allow you to access things like the database, the session, etc, when + * processing a request * - * These allow you to access things when processing a request, like the database, the session, etc. */ import { type CreateNextContextOptions } from "@trpc/server/adapters/next"; -import { type Session } from "next-auth"; +import { getAuth } from "@clerk/nextjs/server"; +import type { + SignedInAuthObject, + SignedOutAuthObject, +} from "@clerk/nextjs/api"; -import { getServerAuthSession } from "~/server/auth"; -import { prisma } from "~/server/db"; - -type CreateContextOptions = { - session: Session | null; - ip: string | undefined; -}; +import { db } from "../db"; +interface AuthContext { + auth: SignedInAuthObject | SignedOutAuthObject; +} /** - * This helper generates the "internals" for a tRPC context. If you need to use it, you can export - * it from here. + * This helper generates the "internals" for a tRPC context. If you need to use + * it, you can export it from here * * Examples of things you may need it for: - * - testing, so we don't have to mock Next.js' req/res - * - tRPC's `createSSGHelpers`, where we don't have req/res - * + * - testing, so we dont have to mock Next.js' req/res + * - trpc's `createSSGHelpers` where we don't have req/res * @see https://create.t3.gg/en/usage/trpc#-servertrpccontextts */ -const createInnerTRPCContext = (opts: CreateContextOptions) => { +const createInnerTRPCContext = ({ auth }: AuthContext) => { return { - session: opts.session, - ip: opts.ip, - prisma, + auth, + db, }; }; /** - * This is the actual context you will use in your router. It will be used to process every request - * that goes through your tRPC endpoint. - * - * @see https://trpc.io/docs/context + * This is the actual context you'll use in your router. It will be used to + * process every request that goes through your tRPC endpoint + * @link https://trpc.io/docs/context */ -export const createTRPCContext = async (opts: CreateNextContextOptions) => { - const { req, res } = opts; - - // Get the session from the server using the getServerSession wrapper function - const session = await getServerAuthSession({ req, res }); - - return createInnerTRPCContext({ - ip: req.socket.remoteAddress, - session, - }); +export const createTRPCContext = (opts: CreateNextContextOptions) => { + return createInnerTRPCContext({ auth: getAuth(opts.req) }); }; /** * 2. INITIALIZATION * - * This is where the tRPC API is initialized, connecting the context and transformer. + * This is where the trpc api is initialized, connecting the context and + * transformer */ import { initTRPC, TRPCError } from "@trpc/server"; -import type { OpenApiMeta } from "trpc-openapi"; -import { Ratelimit } from "@upstash/ratelimit"; import superjson from "superjson"; -import { env } from "~/env.mjs"; -import { Redis } from "@upstash/redis"; +import type { OpenApiMeta } from "trpc-openapi"; const t = initTRPC - .meta() .context() + .meta() .create({ transformer: superjson, errorFormatter({ shape }) { @@ -83,91 +73,37 @@ const t = initTRPC }, }); +// check if the user is signed in, otherwise through a UNAUTHORIZED CODE +const isAuthed = t.middleware(({ next, ctx }) => { + if (!ctx.auth.userId) { + throw new TRPCError({ code: "UNAUTHORIZED" }); + } + + return next({ + ctx: { + auth: ctx.auth, + }, + }); +}); /** * 3. ROUTER & PROCEDURE (THE IMPORTANT BIT) * - * These are the pieces you use to build your tRPC API. You should import these a lot in the - * "/src/server/api/routers" directory. + * These are the pieces you use to build your tRPC API. You should import these + * a lot in the /src/server/api/routers folder */ /** - * This is how you create new routers and sub-routers in your tRPC API. - * + * This is how you create new routers and subrouters in your tRPC API * @see https://trpc.io/docs/router */ export const createTRPCRouter = t.router; /** - * Public (unauthenticated) procedure + * Public (unauthed) procedure * - * This is the base piece you use to build new queries and mutations on your tRPC API. It does not - * guarantee that a user querying is authorized, but you can still access user session data if they - * are logged in. + * This is the base piece you use to build new queries and mutations on your + * tRPC API. It does not guarantee that a user querying is authorized, but you + * can still access user session data if they are logged in */ export const publicProcedure = t.procedure; - -/** Reusable middleware that enforces users are logged in before running the procedure. */ -const enforceAuthSession = t.middleware(async ({ ctx, next }) => { - // Auth - if (!ctx.session || !ctx.session.user) { - throw new TRPCError({ code: "UNAUTHORIZED" }); - } - - const rateLimit = new Ratelimit({ - redis: Redis.fromEnv(), - limiter: Ratelimit.slidingWindow( - Number(env.UPSTASH_RATELIMIT_REQUESTS), - `${Number(env.UPSTASH_RATELIMIT_SECONDS)}s` - ), - analytics: true, - }); - - const { success } = await rateLimit.limit( - `${env.APP_ENV}_${ctx.session?.user.id}` - ); - - if (!success) throw new TRPCError({ code: "TOO_MANY_REQUESTS" }); - - return next({ - ctx: { - session: { ...ctx.session, user: ctx.session.user }, - }, - }); -}); - -const enforceAdminRole = t.middleware(async ({ ctx, next }) => { - if (!ctx.session || !ctx.session.user || !ctx.session?.user.isAdmin) - throw new TRPCError({ code: "UNAUTHORIZED" }); - - return next({ - ctx: { - session: { ...ctx.session, user: ctx.session.user }, - }, - }); -}); - -// const enforceApiToken = t.middleware(async ({ ctx, next, path }) => { -// const res = await unkey.keys.verify({ -// key: "" -// }) -// if (!ctx.session || !ctx.session.user || !ctx.session?.user.isAdmin) -// throw new TRPCError({ code: "UNAUTHORIZED" }); - -// return next({ -// ctx: { -// session: { ...ctx.session, user: ctx.session.user }, -// }, -// }); -// }); - -/** - * Protected (authenticated) procedure - * - * If you want a query or mutation to ONLY be accessible to logged in users, use this. It verifies - * the session is valid and guarantees `ctx.session.user` is not null. - * - * @see https://trpc.io/docs/procedures - */ -export const protectedProcedure = t.procedure.use(enforceAuthSession); - -export const adminProcedure = t.procedure.use(enforceAdminRole); +export const protectedProcedure = t.procedure.use(isAuthed); diff --git a/src/server/auth.ts b/src/server/auth.ts deleted file mode 100644 index fc9cf5d..0000000 --- a/src/server/auth.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { PrismaAdapter } from "@auth/prisma-adapter"; -import { type GetServerSidePropsContext } from "next"; -import { - getServerSession, - type DefaultSession, - type NextAuthOptions, -} from "next-auth"; -import GithubProvider from "next-auth/providers/github"; -import GoogleProvider from "next-auth/providers/google"; -import { Resend } from "resend"; -import { env } from "~/env.mjs"; -import { prisma } from "~/server/db"; -import { Welcome } from "../components/templates/Welcome"; -import { invalidateCache } from "./redis"; -import { publishToChannel } from "./ably"; -import { EventTypes } from "~/utils/types"; - -const resend = new Resend(process.env.RESEND_API_KEY); - -/** - * Module augmentation for `next-auth` types. Allows us to add custom properties to the `session` - * object and keep type safety. - * - * @see https://next-auth.js.org/getting-started/typescript#module-augmentation - */ -declare module "next-auth" { - interface Session extends DefaultSession { - user: { - id: string; - isAdmin: boolean; - isVIP: boolean; - } & DefaultSession["user"]; - } - - interface User { - isAdmin: boolean; - isVIP: boolean; - } -} - -/** - * Options for NextAuth.js used to configure adapters, providers, callbacks, etc. - * - * @see https://next-auth.js.org/configuration/options - */ -export const authOptions: NextAuthOptions = { - callbacks: { - session({ session, user }) { - if (session.user) { - session.user.id = user.id; - session.user.isAdmin = user.isAdmin; - session.user.isVIP = user.isVIP; - } - return session; - }, - }, - events: { - async createUser({ user }) { - if (user && user.name && user.email) { - await resend.sendEmail({ - from: "no-reply@sprintpadawan.dev", - to: user.email, - subject: "🎉 Welcome to Sprint Padawan! 🎉", - //@ts-ignore: IDK why this doesn't work... - - react: Welcome({ name: user.name }), - }); - await invalidateCache(`kv_userlist_admin`); - await invalidateCache(`kv_usercount`); - - await publishToChannel( - `stats`, - EventTypes.STATS_UPDATE, - JSON.stringify(user) - ); - } - }, - async signIn({}) { - await invalidateCache(`kv_userlist_admin`); - }, - async signOut() { - await invalidateCache(`kv_userlist_admin`); - }, - }, - // @ts-ignore This adapter should work... - adapter: PrismaAdapter(prisma), - providers: [ - GithubProvider({ - clientId: env.GITHUB_CLIENT_ID, - clientSecret: env.GITHUB_CLIENT_SECRET, - }), - GoogleProvider({ - clientId: env.GOOGLE_CLIENT_ID, - clientSecret: env.GOOGLE_CLIENT_SECRET, - }), - /** - * ...add more providers here. - * - * Most other providers require a bit more work than the Discord provider. For example, the - * GitHub provider requires you to add the `refresh_token_expires_in` field to the Account - * model. Refer to the NextAuth.js docs for the provider you want to use. Example: - * - * @see https://next-auth.js.org/providers/github - */ - ], -}; - -/** - * Wrapper for `getServerSession` so that you don't need to import the `authOptions` in every file. - * - * @see https://next-auth.js.org/configuration/nextjs - */ -export const getServerAuthSession = (ctx: { - req: GetServerSidePropsContext["req"]; - res: GetServerSidePropsContext["res"]; -}) => { - return getServerSession(ctx.req, ctx.res, authOptions); -}; diff --git a/src/server/db.ts b/src/server/db.ts index f3d7be3..8055892 100644 --- a/src/server/db.ts +++ b/src/server/db.ts @@ -1,14 +1,11 @@ -import { PrismaClient } from "@prisma/client"; - +import { drizzle } from "drizzle-orm/planetscale-serverless"; +import { connect } from "@planetscale/database"; import { env } from "~/env.mjs"; +import * as schema from "~/server/schema"; -const globalForPrisma = globalThis as unknown as { prisma: PrismaClient }; +// create the connection +const connection = connect({ + url: env.DATABASE_URL, +}); -export const prisma = - globalForPrisma.prisma || - new PrismaClient({ - log: - env.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], - }); - -if (env.NODE_ENV !== "production") globalForPrisma.prisma = prisma; +export const db = drizzle(connection, { schema }); diff --git a/src/server/redis.ts b/src/server/redis.ts index f09bb20..aeb0bcc 100644 --- a/src/server/redis.ts +++ b/src/server/redis.ts @@ -1,10 +1,7 @@ import { Redis } from "@upstash/redis"; -import https from "https"; import { env } from "~/env.mjs"; -export const redis = Redis.fromEnv({ - agent: new https.Agent({ keepAlive: true }), -}); +export const redis = Redis.fromEnv(); export const setCache = async (key: string, value: T) => { try { @@ -20,14 +17,8 @@ export const setCache = async (key: string, value: T) => { export const fetchCache = async (key: string) => { try { const result = await redis.get(`${env.APP_ENV}_${key}`); - if (result) { - console.log("CACHE HIT"); - } else { - console.log("CACHE MISS"); - } return result as T; } catch { - console.log("CACHE ERROR"); return null; } }; diff --git a/src/server/schema.ts b/src/server/schema.ts new file mode 100644 index 0000000..ea06c05 --- /dev/null +++ b/src/server/schema.ts @@ -0,0 +1,65 @@ +import { + timestamp, + mysqlTable, + varchar, + boolean, + json, +} from "drizzle-orm/mysql-core"; +import { relations } from "drizzle-orm"; + +export const rooms = mysqlTable("Room", { + id: varchar("id", { length: 255 }).notNull().primaryKey(), + created_at: timestamp("created_at", { + mode: "date", + fsp: 3, + }).defaultNow(), + userId: varchar("userId", { length: 255 }).notNull(), + roomName: varchar("roomName", { length: 255 }), + storyName: varchar("storyName", { length: 255 }), + visible: boolean("visible").default(false).notNull(), + scale: varchar("scale", { length: 255 }).default("0.5,1,2,3,5").notNull(), +}); + +export const roomsRelations = relations(rooms, ({ many }) => ({ + votes: many(votes), + logs: many(logs), +})); + +export const votes = mysqlTable("Vote", { + id: varchar("id", { length: 255 }).notNull().primaryKey(), + created_at: timestamp("created_at", { + mode: "date", + fsp: 3, + }).defaultNow(), + userId: varchar("userId", { length: 255 }).notNull(), + roomId: varchar("roomId", { length: 255 }).notNull(), + value: varchar("value", { length: 255 }).notNull(), +}); + +export const votesRelations = relations(votes, ({ one }) => ({ + room: one(rooms, { + fields: [votes.roomId], + references: [rooms.id], + }), +})); + +export const logs = mysqlTable("Log", { + id: varchar("id", { length: 255 }).notNull().primaryKey(), + created_at: timestamp("created_at", { + mode: "date", + fsp: 3, + }).defaultNow(), + userId: varchar("userId", { length: 255 }).notNull(), + roomId: varchar("roomId", { length: 255 }).notNull(), + scale: varchar("scale", { length: 255 }), + votes: json("votes"), + roomName: varchar("roomName", { length: 255 }), + storyName: varchar("storyName", { length: 255 }), +}); + +export const logsRelations = relations(logs, ({ one }) => ({ + room: one(rooms, { + fields: [logs.roomId], + references: [rooms.id], + }), +}));