diff --git a/.gitignore b/.gitignore index e5ff748..8b8da56 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ /.pnp .pnp.js +#db +nmig + # testing /coverage diff --git a/drizzle.config.ts b/drizzle.config.ts new file mode 100644 index 0000000..a0b9624 --- /dev/null +++ b/drizzle.config.ts @@ -0,0 +1,13 @@ +import { type Config } from "drizzle-kit"; + +import { environment } from "~/environment.mjs"; +const { DATABASE_URL } = environment; + +export default { + schema: "./src/server/db/drizzle.schema.ts", + dialect: "postgresql", + out: "./src/server/migrations", + dbCredentials: { + url: DATABASE_URL, + }, +} satisfies Config; diff --git a/package.json b/package.json index 2d34e20..3728d45 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "commit": "sh ./commit.sh", "build": "pnpm run db:generate && next build", "postbuild": "next-sitemap", + "db:pull": "prisma db pull", "db:push": "prisma db push", + "db:validate": "prisma validate", "db:studio": "prisma studio", "db:generate": "prisma generate", "next:dev": "pnpm run db:generate && next dev --hostname dev.localhost", @@ -28,8 +30,8 @@ "prepare": "husky install" }, "dependencies": { - "@next-auth/prisma-adapter": "^1.0.7", - "@prisma/client": "^5.18.0", + "@auth/drizzle-adapter": "^1.7.4", + "@prisma/client": "^6.0.1", "@react-email/button": "0.0.16", "@react-email/container": "0.0.13", "@react-email/heading": "0.0.13", @@ -46,6 +48,7 @@ "@types/next-pwa": "^5.6.9", "@uidotdev/usehooks": "^2.4.1", "@vercel/postgres": "^0.9.0", + "drizzle-orm": "^0.36.4", "focus-trap-react": "^10.2.3", "mailersend": "^2.2.0", "next": "^14.2.5", @@ -63,6 +66,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@auth/drizzle-adapter": "^0.9.0", "@commitlint/cli": "^19.4.0", "@storybook/addon-essentials": "^7.6.20", "@storybook/addon-interactions": "^7.6.20", @@ -90,6 +94,8 @@ "concurrently": "^8.2.2", "cz-conventional-changelog": "^3.3.0", "cz-customizable": "^7.2.1", + "drizzle-kit": "^0.28.1", + "drizzle-prisma-generator": "^0.1.7", "eslint": "^8.57.0", "eslint-config-next": "^14.0.4", "eslint-config-xo": "^0.45.0", @@ -103,9 +109,10 @@ "jsdom": "^22.1.0", "next-sitemap": "^4.2.3", "postcss": "^8.4.41", + "postgres": "^3.4.5", "prettier": "^3.3.3", "prettier-plugin-tailwindcss": "^0.5.14", - "prisma": "^5.18.0", + "prisma": "^6.0.1", "storybook": "^7.5.3", "tailwindcss": "^3.4.9", "typescript": "^5.5.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44c3c79..bbcfe5f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,12 +8,12 @@ importers: .: dependencies: - '@next-auth/prisma-adapter': - specifier: ^1.0.7 - version: 1.0.7(@prisma/client@5.18.0(prisma@5.18.0))(next-auth@4.24.7(next@14.2.5(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)) + '@auth/drizzle-adapter': + specifier: ^1.7.4 + version: 1.7.4 '@prisma/client': - specifier: ^5.18.0 - version: 5.18.0(prisma@5.18.0) + specifier: ^6.0.1 + version: 6.0.1(prisma@6.0.1) '@react-email/button': specifier: 0.0.16 version: 0.0.16(react@18.3.1) @@ -62,6 +62,9 @@ importers: '@vercel/postgres': specifier: ^0.9.0 version: 0.9.0 + drizzle-orm: + specifier: ^0.36.4 + version: 0.36.4(@prisma/client@6.0.1(prisma@6.0.1))(@types/pg@8.11.6)(@types/react@18.3.3)(@vercel/postgres@0.9.0)(postgres@3.4.5)(prisma@6.0.1)(react@18.3.1) focus-trap-react: specifier: ^10.2.3 version: 10.2.3(prop-types@15.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -189,6 +192,12 @@ importers: cz-customizable: specifier: ^7.2.1 version: 7.2.1 + drizzle-kit: + specifier: ^0.28.1 + version: 0.28.1 + drizzle-prisma-generator: + specifier: ^0.1.7 + version: 0.1.7 eslint: specifier: ^8.57.0 version: 8.57.0 @@ -228,6 +237,9 @@ importers: postcss: specifier: ^8.4.41 version: 8.4.41 + postgres: + specifier: ^3.4.5 + version: 3.4.5 prettier: specifier: ^3.3.3 version: 3.3.3 @@ -235,8 +247,8 @@ importers: specifier: ^0.5.14 version: 0.5.14(prettier@3.3.3) prisma: - specifier: ^5.18.0 - version: 5.18.0 + specifier: ^6.0.1 + version: 6.0.1 storybook: specifier: ^7.5.3 version: 7.6.20(bufferutil@4.0.8)(utf-8-validate@6.0.4) @@ -269,6 +281,23 @@ packages: peerDependencies: ajv: '>=8' + '@auth/core@0.37.4': + resolution: {integrity: sha512-HOXJwXWXQRhbBDHlMU0K/6FT1v+wjtzdKhsNg0ZN7/gne6XPsIrjZ4daMcFnbq0Z/vsAbYBinQhhua0d77v7qw==} + peerDependencies: + '@simplewebauthn/browser': ^9.0.1 + '@simplewebauthn/server': ^9.0.2 + nodemailer: ^6.8.0 + peerDependenciesMeta: + '@simplewebauthn/browser': + optional: true + '@simplewebauthn/server': + optional: true + nodemailer: + optional: true + + '@auth/drizzle-adapter@1.7.4': + resolution: {integrity: sha512-OPZQakWWm5Hbx6okVMbtgI08WBliz/dCbFUXiPg9TThpp3Wh7MME/ubg4fW1oOp8P0gul6MkFvMVO733sVtd2w==} + '@aw-web-design/x-default-browser@1.4.126': resolution: {integrity: sha512-Xk1sIhyNC/esHGGVjL/niHLowM0csl/kFO5uawBy4IrWwy0o1G8LGt3jP6nmWGz+USxeeqbihAmp/oVZju6wug==} hasBin: true @@ -1034,11 +1063,28 @@ packages: resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} + '@drizzle-team/brocli@0.10.2': + resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} + '@emotion/use-insertion-effect-with-fallbacks@1.1.0': resolution: {integrity: sha512-+wBOcIV5snwGgI2ya3u99D7/FJquOIniQT1IKyDsBmEgwvpxMNeS65Oib7OnE2d2aY+3BU4OiH+0Wchf8yk3Hw==} peerDependencies: react: '>=16.8.0' + '@esbuild-kit/core-utils@3.3.2': + resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} + deprecated: 'Merged into tsx: https://tsx.is' + + '@esbuild-kit/esm-loader@2.6.5': + resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} + deprecated: 'Merged into tsx: https://tsx.is' + + '@esbuild/aix-ppc64@0.19.12': + resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -1057,6 +1103,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.19.12': + resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.21.5': resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} engines: {node: '>=12'} @@ -1075,6 +1127,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.19.12': + resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.21.5': resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} engines: {node: '>=12'} @@ -1093,6 +1151,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.19.12': + resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.21.5': resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} engines: {node: '>=12'} @@ -1111,6 +1175,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.19.12': + resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.21.5': resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} engines: {node: '>=12'} @@ -1129,6 +1199,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.19.12': + resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.21.5': resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} engines: {node: '>=12'} @@ -1147,6 +1223,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.19.12': + resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.21.5': resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} engines: {node: '>=12'} @@ -1165,6 +1247,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.19.12': + resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.21.5': resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} engines: {node: '>=12'} @@ -1183,6 +1271,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.19.12': + resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.21.5': resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} engines: {node: '>=12'} @@ -1201,6 +1295,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.19.12': + resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.21.5': resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} engines: {node: '>=12'} @@ -1219,6 +1319,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.19.12': + resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.21.5': resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} engines: {node: '>=12'} @@ -1237,6 +1343,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.19.12': + resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.21.5': resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} engines: {node: '>=12'} @@ -1255,6 +1367,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.19.12': + resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.21.5': resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} engines: {node: '>=12'} @@ -1273,6 +1391,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.19.12': + resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.21.5': resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} engines: {node: '>=12'} @@ -1291,6 +1415,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.19.12': + resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.21.5': resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} engines: {node: '>=12'} @@ -1309,6 +1439,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.19.12': + resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.21.5': resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} engines: {node: '>=12'} @@ -1327,6 +1463,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.19.12': + resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.21.5': resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} engines: {node: '>=12'} @@ -1345,6 +1487,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.19.12': + resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.21.5': resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} engines: {node: '>=12'} @@ -1363,6 +1511,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.19.12': + resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.21.5': resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} engines: {node: '>=12'} @@ -1381,6 +1535,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.19.12': + resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.21.5': resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} engines: {node: '>=12'} @@ -1399,6 +1559,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.19.12': + resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.21.5': resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} engines: {node: '>=12'} @@ -1417,6 +1583,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.19.12': + resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.21.5': resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} engines: {node: '>=12'} @@ -1435,6 +1607,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.19.12': + resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.21.5': resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} engines: {node: '>=12'} @@ -1570,12 +1748,6 @@ packages: '@neondatabase/serverless@0.9.4': resolution: {integrity: sha512-D0AXgJh6xkf+XTlsO7iwE2Q1w8981E1cLCPAALMU2YKtkF/1SF6BiAzYARZFYo175ON+b1RNIy9TdSFHm5nteg==} - '@next-auth/prisma-adapter@1.0.7': - resolution: {integrity: sha512-Cdko4KfcmKjsyHFrWwZ//lfLUbcLqlyFqjd/nYE2m3aZ7tjMNUjpks47iw7NTCnXf+5UWz5Ypyt1dSs1EP5QJw==} - peerDependencies: - '@prisma/client': '>=2.26.0 || >=3' - next-auth: ^4 - '@next/env@13.5.6': resolution: {integrity: sha512-Yac/bV5sBGkkEXmAX5FWPS9Mmo2rthrOPRQQNfycJPkjUAUclomCPH7QFVCDQ4Mp2k2K1SSM6m0zrxYrOwtFQw==} @@ -1798,29 +1970,35 @@ packages: webpack-plugin-serve: optional: true - '@prisma/client@5.18.0': - resolution: {integrity: sha512-BWivkLh+af1kqC89zCJYkHsRcyWsM8/JHpsDMM76DjP3ZdEquJhXa4IeX+HkWPnwJ5FanxEJFZZDTWiDs/Kvyw==} - engines: {node: '>=16.13'} + '@prisma/client@6.0.1': + resolution: {integrity: sha512-60w7kL6bUxz7M6Gs/V+OWMhwy94FshpngVmOY05TmGD0Lhk+Ac0ZgtjlL6Wll9TD4G03t4Sq1wZekNVy+Xdlbg==} + engines: {node: '>=18.18'} peerDependencies: prisma: '*' peerDependenciesMeta: prisma: optional: true - '@prisma/debug@5.18.0': - resolution: {integrity: sha512-f+ZvpTLidSo3LMJxQPVgAxdAjzv5OpzAo/eF8qZqbwvgi2F5cTOI9XCpdRzJYA0iGfajjwjOKKrVq64vkxEfUw==} + '@prisma/debug@5.22.0': + resolution: {integrity: sha512-AUt44v3YJeggO2ZU5BkXI7M4hu9BF2zzH2iF2V5pyXT/lRTyWiElZ7It+bRH1EshoMRxHgpYg4VB6rCM+mG5jQ==} + + '@prisma/debug@6.0.1': + resolution: {integrity: sha512-jQylgSOf7ibTVxqBacnAlVGvek6fQxJIYCQOeX2KexsfypNzXjJQSS2o5s+Mjj2Np93iSOQUaw6TvPj8syhG4w==} + + '@prisma/engines-version@5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e': + resolution: {integrity: sha512-JmIds0Q2/vsOmnuTJYxY4LE+sajqjYKhLtdOT6y4imojqv5d/aeVEfbBGC74t8Be1uSp0OP8lxIj2OqoKbLsfQ==} - '@prisma/engines-version@5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169': - resolution: {integrity: sha512-a/+LpJj8vYU3nmtkg+N3X51ddbt35yYrRe8wqHTJtYQt7l1f8kjIBcCs6sHJvodW/EK5XGvboOiwm47fmNrbgg==} + '@prisma/engines@6.0.1': + resolution: {integrity: sha512-4hxzI+YQIR2uuDyVsDooFZGu5AtixbvM2psp+iayDZ4hRrAHo/YwgA17N23UWq7G6gRu18NvuNMb48qjP3DPQw==} - '@prisma/engines@5.18.0': - resolution: {integrity: sha512-ofmpGLeJ2q2P0wa/XaEgTnX/IsLnvSp/gZts0zjgLNdBhfuj2lowOOPmDcfKljLQUXMvAek3lw5T01kHmCG8rg==} + '@prisma/fetch-engine@6.0.1': + resolution: {integrity: sha512-T36bWFVGeGYYSyYOj9d+O9G3sBC+pAyMC+jc45iSL63/Haq1GrYjQPgPMxrEj9m739taXrupoysRedQ+VyvM/Q==} - '@prisma/fetch-engine@5.18.0': - resolution: {integrity: sha512-I/3u0x2n31rGaAuBRx2YK4eB7R/1zCuayo2DGwSpGyrJWsZesrV7QVw7ND0/Suxeo/vLkJ5OwuBqHoCxvTHpOg==} + '@prisma/generator-helper@5.22.0': + resolution: {integrity: sha512-LwqcBQ5/QsuAaLNQZAIVIAJDJBMjHwMwn16e06IYx/3Okj/xEEfw9IvrqB2cJCl3b2mCBlh3eVH0w9WGmi4aHg==} - '@prisma/get-platform@5.18.0': - resolution: {integrity: sha512-Tk+m7+uhqcKDgnMnFN0lRiH7Ewea0OEsZZs9pqXa7i3+7svS3FSCqDBCaM9x5fmhhkufiG0BtunJVDka+46DlA==} + '@prisma/get-platform@6.0.1': + resolution: {integrity: sha512-zspC9vlxAqx4E6epMPMLLBMED2VD8axDe8sPnquZ8GOsn6tiacWK0oxrGK4UAHYzYUVuMVUApJbdXB2dFpLhvg==} '@radix-ui/number@1.0.1': resolution: {integrity: sha512-T5gIdVO2mmPW3NNhjNgEP3cqMXjXL9UbO0BzWcXfvdBs+BohbQxvd/K5hSVKmn9/lbTdsQVKbUcP5WLCwvUbBg==} @@ -4266,6 +4444,106 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} + drizzle-kit@0.28.1: + resolution: {integrity: sha512-JimOV+ystXTWMgZkLHYHf2w3oS28hxiH1FR0dkmJLc7GHzdGJoJAQtQS5DRppnabsRZwE2U1F6CuezVBgmsBBQ==} + hasBin: true + + drizzle-orm@0.36.4: + resolution: {integrity: sha512-1OZY3PXD7BR00Gl61UUOFihslDldfH4NFRH2MbP54Yxi0G/PKn4HfO65JYZ7c16DeP3SpM3Aw+VXVG9j6CRSXA==} + peerDependencies: + '@aws-sdk/client-rds-data': '>=3' + '@cloudflare/workers-types': '>=3' + '@electric-sql/pglite': '>=0.2.0' + '@libsql/client': '>=0.10.0' + '@libsql/client-wasm': '>=0.10.0' + '@neondatabase/serverless': '>=0.10.0' + '@op-engineering/op-sqlite': '>=2' + '@opentelemetry/api': ^1.4.1 + '@planetscale/database': '>=1' + '@prisma/client': '*' + '@tidbcloud/serverless': '*' + '@types/better-sqlite3': '*' + '@types/pg': '*' + '@types/react': '>=18' + '@types/sql.js': '*' + '@vercel/postgres': '>=0.8.0' + '@xata.io/client': '*' + better-sqlite3: '>=7' + bun-types: '*' + expo-sqlite: '>=14.0.0' + knex: '*' + kysely: '*' + mysql2: '>=2' + pg: '>=8' + postgres: '>=3' + prisma: '*' + react: '>=18' + sql.js: '>=1' + sqlite3: '>=5' + peerDependenciesMeta: + '@aws-sdk/client-rds-data': + optional: true + '@cloudflare/workers-types': + optional: true + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + '@libsql/client-wasm': + optional: true + '@neondatabase/serverless': + optional: true + '@op-engineering/op-sqlite': + optional: true + '@opentelemetry/api': + optional: true + '@planetscale/database': + optional: true + '@prisma/client': + optional: true + '@tidbcloud/serverless': + optional: true + '@types/better-sqlite3': + optional: true + '@types/pg': + optional: true + '@types/react': + optional: true + '@types/sql.js': + optional: true + '@vercel/postgres': + optional: true + '@xata.io/client': + optional: true + better-sqlite3: + optional: true + bun-types: + optional: true + expo-sqlite: + optional: true + knex: + optional: true + kysely: + optional: true + mysql2: + optional: true + pg: + optional: true + postgres: + optional: true + prisma: + optional: true + react: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + + drizzle-prisma-generator@0.1.7: + resolution: {integrity: sha512-KW+Z6W4hjvsiOCCPEmGyO+Oal7KPv2yQ3uZzHasaVIn+gUWGrkcy8BCDEp1h7uRBRSAd/l17EM4DfljhgYXxBw==} + hasBin: true + duplexify@3.7.1: resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} @@ -4398,6 +4676,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.19.12: + resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -5488,6 +5771,9 @@ packages: jose@4.15.9: resolution: {integrity: sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA==} + jose@5.9.6: + resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} + js-beautify@1.15.1: resolution: {integrity: sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==} engines: {node: '>=14'} @@ -6129,6 +6415,9 @@ packages: engines: {node: ^14.16.0 || >=16.10.0} hasBin: true + oauth4webapi@3.1.4: + resolution: {integrity: sha512-eVfN3nZNbok2s/ROifO0UAc5G8nRoLSbrcKJ09OqmucgnhXEfdIQOR4gq1eJH1rN3gV7rNw62bDEgftsgFtBEg==} + oauth@0.9.15: resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} @@ -6558,14 +6847,26 @@ packages: postgres-range@1.1.4: resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==} + postgres@3.4.5: + resolution: {integrity: sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg==} + engines: {node: '>=12'} + preact-render-to-string@5.2.6: resolution: {integrity: sha512-JyhErpYOvBV1hEPwIxc/fHWXPfnEGdRKxc8gFdAZ7XV4tlzyzG847XAyEZqoDnynP88akM4eaHcSOzNcLWFguw==} peerDependencies: preact: '>=10' + preact-render-to-string@6.5.11: + resolution: {integrity: sha512-ubnauqoGczeGISiOh6RjX0/cdaF8v/oDXIjO85XALCQjwQP+SB4RDXXtvZ6yTYSjG+PC1QRP2AhPgCEsM2EvUw==} + peerDependencies: + preact: '>=10' + preact@10.23.1: resolution: {integrity: sha512-O5UdRsNh4vdZaTieWe3XOgSpdMAmkIYBCT3VhQDlKrzyCm8lUYsk0fmVEvoQQifoOjFRTaHZO69ylrzTW2BH+A==} + preact@10.24.3: + resolution: {integrity: sha512-Z2dPnBnMUfyQfSQ+GBdsGa16hz35YmLmtTLhM169uW944hYL6xzTYkJjC07j+Wosz733pMWx0fgON3JNw1jJQA==} + prebuild-install@7.1.2: resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==} engines: {node: '>=10'} @@ -6659,9 +6960,9 @@ packages: resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} engines: {node: '>= 0.8'} - prisma@5.18.0: - resolution: {integrity: sha512-+TrSIxZsh64OPOmaSgVPH7ALL9dfU0jceYaMJXsNrTkFHO7/3RANi5K2ZiPB1De9+KDxCWn7jvRq8y8pvk+o9g==} - engines: {node: '>=16.13'} + prisma@6.0.1: + resolution: {integrity: sha512-CaMNFHkf+DDq8zq3X/JJsQ4Koy7dyWwwtOKibkT/Am9j/tDxcfbg7+lB1Dzhx18G/+RQCMgjPYB61bhRqteNBQ==} + engines: {node: '>=18.18'} hasBin: true process-nextick-args@2.0.1: @@ -8278,6 +8579,22 @@ snapshots: jsonpointer: 5.0.1 leven: 3.1.0 + '@auth/core@0.37.4': + dependencies: + '@panva/hkdf': 1.2.1 + jose: 5.9.6 + oauth4webapi: 3.1.4 + preact: 10.24.3 + preact-render-to-string: 6.5.11(preact@10.24.3) + + '@auth/drizzle-adapter@1.7.4': + dependencies: + '@auth/core': 0.37.4 + transitivePeerDependencies: + - '@simplewebauthn/browser' + - '@simplewebauthn/server' + - nodemailer + '@aw-web-design/x-default-browser@1.4.126': dependencies: default-browser-id: 3.0.0 @@ -9293,10 +9610,25 @@ snapshots: '@discoveryjs/json-ext@0.5.7': {} + '@drizzle-team/brocli@0.10.2': {} + '@emotion/use-insertion-effect-with-fallbacks@1.1.0(react@18.3.1)': dependencies: react: 18.3.1 + '@esbuild-kit/core-utils@3.3.2': + dependencies: + esbuild: 0.18.20 + source-map-support: 0.5.21 + + '@esbuild-kit/esm-loader@2.6.5': + dependencies: + '@esbuild-kit/core-utils': 3.3.2 + get-tsconfig: 4.7.6 + + '@esbuild/aix-ppc64@0.19.12': + optional: true + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -9306,6 +9638,9 @@ snapshots: '@esbuild/android-arm64@0.18.20': optional: true + '@esbuild/android-arm64@0.19.12': + optional: true + '@esbuild/android-arm64@0.21.5': optional: true @@ -9315,6 +9650,9 @@ snapshots: '@esbuild/android-arm@0.18.20': optional: true + '@esbuild/android-arm@0.19.12': + optional: true + '@esbuild/android-arm@0.21.5': optional: true @@ -9324,6 +9662,9 @@ snapshots: '@esbuild/android-x64@0.18.20': optional: true + '@esbuild/android-x64@0.19.12': + optional: true + '@esbuild/android-x64@0.21.5': optional: true @@ -9333,6 +9674,9 @@ snapshots: '@esbuild/darwin-arm64@0.18.20': optional: true + '@esbuild/darwin-arm64@0.19.12': + optional: true + '@esbuild/darwin-arm64@0.21.5': optional: true @@ -9342,6 +9686,9 @@ snapshots: '@esbuild/darwin-x64@0.18.20': optional: true + '@esbuild/darwin-x64@0.19.12': + optional: true + '@esbuild/darwin-x64@0.21.5': optional: true @@ -9351,6 +9698,9 @@ snapshots: '@esbuild/freebsd-arm64@0.18.20': optional: true + '@esbuild/freebsd-arm64@0.19.12': + optional: true + '@esbuild/freebsd-arm64@0.21.5': optional: true @@ -9360,6 +9710,9 @@ snapshots: '@esbuild/freebsd-x64@0.18.20': optional: true + '@esbuild/freebsd-x64@0.19.12': + optional: true + '@esbuild/freebsd-x64@0.21.5': optional: true @@ -9369,6 +9722,9 @@ snapshots: '@esbuild/linux-arm64@0.18.20': optional: true + '@esbuild/linux-arm64@0.19.12': + optional: true + '@esbuild/linux-arm64@0.21.5': optional: true @@ -9378,6 +9734,9 @@ snapshots: '@esbuild/linux-arm@0.18.20': optional: true + '@esbuild/linux-arm@0.19.12': + optional: true + '@esbuild/linux-arm@0.21.5': optional: true @@ -9387,6 +9746,9 @@ snapshots: '@esbuild/linux-ia32@0.18.20': optional: true + '@esbuild/linux-ia32@0.19.12': + optional: true + '@esbuild/linux-ia32@0.21.5': optional: true @@ -9396,6 +9758,9 @@ snapshots: '@esbuild/linux-loong64@0.18.20': optional: true + '@esbuild/linux-loong64@0.19.12': + optional: true + '@esbuild/linux-loong64@0.21.5': optional: true @@ -9405,6 +9770,9 @@ snapshots: '@esbuild/linux-mips64el@0.18.20': optional: true + '@esbuild/linux-mips64el@0.19.12': + optional: true + '@esbuild/linux-mips64el@0.21.5': optional: true @@ -9414,6 +9782,9 @@ snapshots: '@esbuild/linux-ppc64@0.18.20': optional: true + '@esbuild/linux-ppc64@0.19.12': + optional: true + '@esbuild/linux-ppc64@0.21.5': optional: true @@ -9423,6 +9794,9 @@ snapshots: '@esbuild/linux-riscv64@0.18.20': optional: true + '@esbuild/linux-riscv64@0.19.12': + optional: true + '@esbuild/linux-riscv64@0.21.5': optional: true @@ -9432,6 +9806,9 @@ snapshots: '@esbuild/linux-s390x@0.18.20': optional: true + '@esbuild/linux-s390x@0.19.12': + optional: true + '@esbuild/linux-s390x@0.21.5': optional: true @@ -9441,6 +9818,9 @@ snapshots: '@esbuild/linux-x64@0.18.20': optional: true + '@esbuild/linux-x64@0.19.12': + optional: true + '@esbuild/linux-x64@0.21.5': optional: true @@ -9450,6 +9830,9 @@ snapshots: '@esbuild/netbsd-x64@0.18.20': optional: true + '@esbuild/netbsd-x64@0.19.12': + optional: true + '@esbuild/netbsd-x64@0.21.5': optional: true @@ -9459,6 +9842,9 @@ snapshots: '@esbuild/openbsd-x64@0.18.20': optional: true + '@esbuild/openbsd-x64@0.19.12': + optional: true + '@esbuild/openbsd-x64@0.21.5': optional: true @@ -9468,6 +9854,9 @@ snapshots: '@esbuild/sunos-x64@0.18.20': optional: true + '@esbuild/sunos-x64@0.19.12': + optional: true + '@esbuild/sunos-x64@0.21.5': optional: true @@ -9477,6 +9866,9 @@ snapshots: '@esbuild/win32-arm64@0.18.20': optional: true + '@esbuild/win32-arm64@0.19.12': + optional: true + '@esbuild/win32-arm64@0.21.5': optional: true @@ -9486,6 +9878,9 @@ snapshots: '@esbuild/win32-ia32@0.18.20': optional: true + '@esbuild/win32-ia32@0.19.12': + optional: true + '@esbuild/win32-ia32@0.21.5': optional: true @@ -9495,6 +9890,9 @@ snapshots: '@esbuild/win32-x64@0.18.20': optional: true + '@esbuild/win32-x64@0.19.12': + optional: true + '@esbuild/win32-x64@0.21.5': optional: true @@ -9676,11 +10074,6 @@ snapshots: dependencies: '@types/pg': 8.11.6 - '@next-auth/prisma-adapter@1.0.7(@prisma/client@5.18.0(prisma@5.18.0))(next-auth@4.24.7(next@14.2.5(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))': - dependencies: - '@prisma/client': 5.18.0(prisma@5.18.0) - next-auth: 4.24.7(next@14.2.5(@babel/core@7.25.2)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@next/env@13.5.6': {} '@next/env@14.2.5': {} @@ -9858,30 +10251,36 @@ snapshots: type-fest: 2.19.0 webpack-hot-middleware: 2.26.1 - '@prisma/client@5.18.0(prisma@5.18.0)': + '@prisma/client@6.0.1(prisma@6.0.1)': optionalDependencies: - prisma: 5.18.0 + prisma: 6.0.1 + + '@prisma/debug@5.22.0': {} + + '@prisma/debug@6.0.1': {} - '@prisma/debug@5.18.0': {} + '@prisma/engines-version@5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e': {} - '@prisma/engines-version@5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169': {} + '@prisma/engines@6.0.1': + dependencies: + '@prisma/debug': 6.0.1 + '@prisma/engines-version': 5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e + '@prisma/fetch-engine': 6.0.1 + '@prisma/get-platform': 6.0.1 - '@prisma/engines@5.18.0': + '@prisma/fetch-engine@6.0.1': dependencies: - '@prisma/debug': 5.18.0 - '@prisma/engines-version': 5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169 - '@prisma/fetch-engine': 5.18.0 - '@prisma/get-platform': 5.18.0 + '@prisma/debug': 6.0.1 + '@prisma/engines-version': 5.23.0-27.5dbef10bdbfb579e07d35cc85fb1518d357cb99e + '@prisma/get-platform': 6.0.1 - '@prisma/fetch-engine@5.18.0': + '@prisma/generator-helper@5.22.0': dependencies: - '@prisma/debug': 5.18.0 - '@prisma/engines-version': 5.18.0-25.4c784e32044a8a016d99474bd02a3b6123742169 - '@prisma/get-platform': 5.18.0 + '@prisma/debug': 5.22.0 - '@prisma/get-platform@5.18.0': + '@prisma/get-platform@6.0.1': dependencies: - '@prisma/debug': 5.18.0 + '@prisma/debug': 6.0.1 '@radix-ui/number@1.0.1': dependencies: @@ -12975,6 +13374,29 @@ snapshots: dotenv@16.4.5: {} + drizzle-kit@0.28.1: + dependencies: + '@drizzle-team/brocli': 0.10.2 + '@esbuild-kit/esm-loader': 2.6.5 + esbuild: 0.19.12 + esbuild-register: 3.6.0(esbuild@0.19.12) + transitivePeerDependencies: + - supports-color + + drizzle-orm@0.36.4(@prisma/client@6.0.1(prisma@6.0.1))(@types/pg@8.11.6)(@types/react@18.3.3)(@vercel/postgres@0.9.0)(postgres@3.4.5)(prisma@6.0.1)(react@18.3.1): + optionalDependencies: + '@prisma/client': 6.0.1(prisma@6.0.1) + '@types/pg': 8.11.6 + '@types/react': 18.3.3 + '@vercel/postgres': 0.9.0 + postgres: 3.4.5 + prisma: 6.0.1 + react: 18.3.1 + + drizzle-prisma-generator@0.1.7: + dependencies: + '@prisma/generator-helper': 5.22.0 + duplexify@3.7.1: dependencies: end-of-stream: 1.4.4 @@ -13167,6 +13589,13 @@ snapshots: transitivePeerDependencies: - supports-color + esbuild-register@3.6.0(esbuild@0.19.12): + dependencies: + debug: 4.3.6 + esbuild: 0.19.12 + transitivePeerDependencies: + - supports-color + esbuild@0.16.4: optionalDependencies: '@esbuild/android-arm': 0.16.4 @@ -13217,6 +13646,32 @@ snapshots: '@esbuild/win32-ia32': 0.18.20 '@esbuild/win32-x64': 0.18.20 + esbuild@0.19.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.19.12 + '@esbuild/android-arm': 0.19.12 + '@esbuild/android-arm64': 0.19.12 + '@esbuild/android-x64': 0.19.12 + '@esbuild/darwin-arm64': 0.19.12 + '@esbuild/darwin-x64': 0.19.12 + '@esbuild/freebsd-arm64': 0.19.12 + '@esbuild/freebsd-x64': 0.19.12 + '@esbuild/linux-arm': 0.19.12 + '@esbuild/linux-arm64': 0.19.12 + '@esbuild/linux-ia32': 0.19.12 + '@esbuild/linux-loong64': 0.19.12 + '@esbuild/linux-mips64el': 0.19.12 + '@esbuild/linux-ppc64': 0.19.12 + '@esbuild/linux-riscv64': 0.19.12 + '@esbuild/linux-s390x': 0.19.12 + '@esbuild/linux-x64': 0.19.12 + '@esbuild/netbsd-x64': 0.19.12 + '@esbuild/openbsd-x64': 0.19.12 + '@esbuild/sunos-x64': 0.19.12 + '@esbuild/win32-arm64': 0.19.12 + '@esbuild/win32-ia32': 0.19.12 + '@esbuild/win32-x64': 0.19.12 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -13301,7 +13756,7 @@ snapshots: debug: 4.3.6 enhanced-resolve: 5.17.1 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.6 @@ -13313,7 +13768,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: debug: 3.2.7 optionalDependencies: @@ -13334,7 +13789,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0))(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.5.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.15.0 is-glob: 4.0.3 @@ -14558,6 +15013,8 @@ snapshots: jose@4.15.9: {} + jose@5.9.6: {} + js-beautify@1.15.1: dependencies: config-chain: 1.1.13 @@ -15219,6 +15676,8 @@ snapshots: pkg-types: 1.1.3 ufo: 1.5.4 + oauth4webapi@3.1.4: {} + oauth@0.9.15: {} object-assign@4.1.1: {} @@ -15630,13 +16089,21 @@ snapshots: postgres-range@1.1.4: {} + postgres@3.4.5: {} + preact-render-to-string@5.2.6(preact@10.23.1): dependencies: preact: 10.23.1 pretty-format: 3.8.0 + preact-render-to-string@6.5.11(preact@10.24.3): + dependencies: + preact: 10.24.3 + preact@10.23.1: {} + preact@10.24.3: {} + prebuild-install@7.1.2: dependencies: detect-libc: 2.0.3 @@ -15685,9 +16152,11 @@ snapshots: pretty-hrtime@1.0.3: {} - prisma@5.18.0: + prisma@6.0.1: dependencies: - '@prisma/engines': 5.18.0 + '@prisma/engines': 6.0.1 + optionalDependencies: + fsevents: 2.3.3 process-nextick-args@2.0.1: {} diff --git a/prisma/drizzle/schema.ts b/prisma/drizzle/schema.ts new file mode 100644 index 0000000..5257267 --- /dev/null +++ b/prisma/drizzle/schema.ts @@ -0,0 +1,174 @@ +import { relations, sql } from 'drizzle-orm' +import { boolean, foreignKey, integer, jsonb, pgEnum, pgTable, text, timestamp, uniqueIndex } from 'drizzle-orm/pg-core' + +export const UserRole = pgEnum('UserRole', ['ADMIN', 'EDITOR', 'CONTRIBUTOR']) + +export const TagName = pgEnum('TagName', ['Aeronautics', 'Animals', 'Art', 'Astronomy', 'Aviation', 'Biology', 'Business', 'Chemistry', 'Cinema', 'Civics', 'Communications', 'Computing', 'Construction', 'Crafts', 'Cultural', 'Economics', 'Engineering', 'Entertainment', 'Environment', 'Finance', 'Games', 'Gender', 'Geography', 'Geology', 'Graphic_Novels', 'Hardware', 'Health', 'History', 'Internet', 'Journalism', 'Languages', 'Law', 'Linguistics', 'Literature', 'Mathematics', 'Medicine', 'Military', 'Miscellaneous', 'Music', 'Mythology', 'Networking', 'Oceanography', 'Performance', 'Philosophy', 'Physics', 'Politics', 'Programming', 'Psychology', 'Religion', 'Science', 'Security', 'Slang', 'Sociology', 'Software', 'Space', 'Sports', 'Teaching', 'Technology', 'Television']) + +export const Post = pgTable('Post', { + id: text('id').notNull().primaryKey().default(sql`cuid(1)`), + createdAt: timestamp('createdAt', { precision: 3 }).notNull().defaultNow(), + title: text('title').notNull().unique(), + slug: text('slug').notNull().unique(), + abbreviation: text('abbreviation').notNull(), + acronym: text('acronym').notNull(), + initialism: text('initialism').notNull(), + authorId: text('authorId').notNull() +}, (Post) => ({ + 'Post_author_fkey': foreignKey({ + name: 'Post_author_fkey', + columns: [Post.authorId], + foreignColumns: [User.id] + }) + .onDelete('cascade') + .onUpdate('cascade') +})); + +export const PostVersion = pgTable('PostVersion', { + id: text('id').notNull().primaryKey().default(sql`cuid(1)`), + postId: text('postId').notNull(), + updatedAt: timestamp('updatedAt', { precision: 3 }).notNull().defaultNow(), + slug: text('slug').notNull(), + title: text('title').notNull(), + body: text('body').notNull(), + abbreviation: text('abbreviation').notNull(), + acronym: text('acronym').notNull(), + initialism: text('initialism').notNull(), + published: boolean('published').notNull(), + link: text('link').notNull(), + authorId: text('authorId').notNull(), + fileUnder: TagName('fileUnder').notNull(), + tags: jsonb('tags').notNull(), + relatedPostId1: text('relatedPostId1'), + relatedPostId2: text('relatedPostId2') +}, (PostVersion) => ({ + 'PostVersion_post_fkey': foreignKey({ + name: 'PostVersion_post_fkey', + columns: [PostVersion.postId], + foreignColumns: [Post.id] + }) + .onDelete('cascade') + .onUpdate('cascade'), + 'PostVersion_author_fkey': foreignKey({ + name: 'PostVersion_author_fkey', + columns: [PostVersion.authorId], + foreignColumns: [User.id] + }) + .onDelete('cascade') + .onUpdate('cascade') +})); + +export const Account = pgTable('Account', { + id: text('id').notNull().primaryKey().default(sql`cuid(1)`), + userId: text('userId').notNull(), + type: text('type').notNull(), + provider: text('provider').notNull(), + providerAccountId: text('providerAccountId').notNull(), + refresh_token: text('refresh_token'), + access_token: text('access_token'), + expires_at: integer('expires_at'), + token_type: text('token_type'), + scope: text('scope'), + id_token: text('id_token'), + session_state: text('session_state') +}, (Account) => ({ + 'Account_user_fkey': foreignKey({ + name: 'Account_user_fkey', + columns: [Account.userId], + foreignColumns: [User.id] + }) + .onDelete('cascade') + .onUpdate('cascade'), + 'Account_provider_providerAccountId_unique_idx': uniqueIndex('Account_provider_providerAccountId_key') + .on(Account.provider, Account.providerAccountId) +})); + +export const Session = pgTable('Session', { + id: text('id').notNull().primaryKey().default(sql`cuid(1)`), + sessionToken: text('sessionToken').notNull().unique(), + userId: text('userId').notNull(), + expires: timestamp('expires', { precision: 3 }).notNull() +}, (Session) => ({ + 'Session_user_fkey': foreignKey({ + name: 'Session_user_fkey', + columns: [Session.userId], + foreignColumns: [User.id] + }) + .onDelete('cascade') + .onUpdate('cascade') +})); + +export const User = pgTable('User', { + id: text('id').notNull().primaryKey().default(sql`cuid(1)`), + name: text('name'), + username: text('username').unique(), + hasPersonalizedUsername: boolean('hasPersonalizedUsername').notNull(), + email: text('email').unique(), + emailVerified: timestamp('emailVerified', { precision: 3 }), + image: text('image'), + role: UserRole('role').notNull().default("CONTRIBUTOR") +}); + +export const VerificationToken = pgTable('VerificationToken', { + identifier: text('identifier').notNull(), + token: text('token').notNull().unique(), + expires: timestamp('expires', { precision: 3 }).notNull() +}, (VerificationToken) => ({ + 'VerificationToken_identifier_token_unique_idx': uniqueIndex('VerificationToken_identifier_token_key') + .on(VerificationToken.identifier, VerificationToken.token) +})); + +export const PostRelations = relations(Post, ({ one, many }) => ({ + author: one(User, { + relationName: 'PostToUser', + fields: [Post.authorId], + references: [User.id] + }), + versions: many(PostVersion, { + relationName: 'PostToPostVersion' + }) +})); + +export const PostVersionRelations = relations(PostVersion, ({ one }) => ({ + post: one(Post, { + relationName: 'PostToPostVersion', + fields: [PostVersion.postId], + references: [Post.id] + }), + author: one(User, { + relationName: 'PostVersionToUser', + fields: [PostVersion.authorId], + references: [User.id] + }) +})); + +export const AccountRelations = relations(Account, ({ one }) => ({ + user: one(User, { + relationName: 'AccountToUser', + fields: [Account.userId], + references: [User.id] + }) +})); + +export const SessionRelations = relations(Session, ({ one }) => ({ + user: one(User, { + relationName: 'SessionToUser', + fields: [Session.userId], + references: [User.id] + }) +})); + +export const UserRelations = relations(User, ({ many }) => ({ + accounts: many(Account, { + relationName: 'AccountToUser' + }), + sessions: many(Session, { + relationName: 'SessionToUser' + }), + posts: many(Post, { + relationName: 'PostToUser' + }), + PostVersion: many(PostVersion, { + relationName: 'PostVersionToUser' + }) +})); \ No newline at end of file diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 18b4e96..a168c9b 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -3,19 +3,17 @@ generator client { provider = "prisma-client-js" - previewFeatures = ["fullTextSearch", "fullTextIndex"] - binaryTargets = ["native", "rhel-openssl-3.0.x"] + previewFeatures = ["driverAdapters"] +} + +generator drizzle { + provider = "drizzle-prisma-generator" + output = "./drizzle" // Where to put generated Drizle tables } datasource db { - provider = "mysql" - // NOTE: When using mysql or sqlserver, uncomment the @db.Text annotations in model Account below - // Further reading: - // https://next-auth.js.org/adapters/prisma#create-the-prisma-schema - // https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#string - url = env("DATABASE_URL") - // https://www.prisma.io/docs/concepts/components/prisma-schema/relations/relation-mode#how-to-set-the-relation-mode-in-your-prisma-schema - relationMode = "prisma" + provider = "postgresql" + url = env("DATABASE_URL") } enum UserRole { @@ -91,19 +89,14 @@ model Post { createdAt DateTime @default(now()) title String @unique slug String @unique - abbreviation String @db.VarChar(30) @default("") - acronym String @db.VarChar(20) @default("") - initialism String @db.VarChar(10) @default("") + abbreviation String @default("") @db.VarChar(30) + acronym String @default("") @db.VarChar(20) + initialism String @default("") @db.VarChar(10) author User @relation(fields: [authorId], references: [id]) authorId String versions PostVersion[] @@index([authorId]) - @@fulltext([title]) - @@fulltext([abbreviation]) - @@fulltext([acronym]) - @@fulltext([initialism]) - @@fulltext([title, abbreviation, acronym, initialism ]) } model PostVersion { @@ -137,12 +130,12 @@ model Account { type String provider String providerAccountId String - refresh_token String? @db.Text - access_token String? @db.Text + refresh_token String? + access_token String? expires_at Int? token_type String? scope String? - id_token String? @db.Text + id_token String? session_state String? user User @relation(fields: [userId], references: [id], onDelete: Cascade) diff --git a/src/server/auth.ts b/src/server/auth.ts index 1acccb6..7d4ac92 100644 --- a/src/server/auth.ts +++ b/src/server/auth.ts @@ -1,4 +1,4 @@ -import { PrismaAdapter as prismaAdapter } from "@next-auth/prisma-adapter"; +import { DrizzleAdapter as drizzleAdapter } from "@auth/drizzle-adapter"; import type { UserRole } from "@prisma/client"; import { type GetServerSidePropsContext } from "next"; import { @@ -6,6 +6,7 @@ import { type DefaultSession, type NextAuthOptions, } from "next-auth"; + import facebookProvider from "next-auth/providers/facebook"; import githubProvider from "next-auth/providers/github"; import googleProvider from "next-auth/providers/google"; @@ -16,6 +17,11 @@ import { environment } from "~/environment.mjs"; import { database } from "~/server/database"; import { EURLS } from "~/settings/constants"; +import { + Session, Account, User, Post, VerificationToken, + PostVersion, +} from "./db/drizzle.schema"; + /** * Module augmentation for `next-auth` types. Allows us to add custom properties to the `session` * object and keep type safety. @@ -58,7 +64,14 @@ export const authOptions: NextAuthOptions = { }, }), }, - adapter: prismaAdapter(database), + adapter: drizzleAdapter(database, { + usersTable: User, + accountsTable: Account, + sessionsTable: Session, + postsTable: Post, + postsVersionsTable: PostVersion, + verificationTokensTable: VerificationToken, + }), pages: { signIn: EURLS.SignIn, verifyRequest: EURLS.SignInMagicLink, diff --git a/src/server/database.ts b/src/server/database.ts index 09dfa96..7fcb94f 100644 --- a/src/server/database.ts +++ b/src/server/database.ts @@ -1,18 +1,23 @@ -import { PrismaClient } from "@prisma/client"; +import { drizzle } from "drizzle-orm/postgres-js"; +import postgres from "postgres"; import { environment } from "~/environment.mjs"; -const globalForPrisma = globalThis as unknown as { - prisma: PrismaClient | undefined; -}; +import * as schema from "./db/drizzle.schema"; + +const { DATABASE_URL, NODE_ENV } = environment; -export const database = - globalForPrisma.prisma ?? - new PrismaClient({ - log: - environment.NODE_ENV === "development" ? ["query", "error", "warn"] : ["error"], - }); +/** + * Cache the database connection in development. This avoids creating a new connection on every HMR + * update. + */ +const globalForDatabase = globalThis as unknown as { + conn: postgres.Sql | undefined; +}; -if (environment.NODE_ENV !== "production") { - globalForPrisma.prisma = database; +const conn = globalForDatabase.conn ?? postgres(DATABASE_URL); +if (NODE_ENV !== "production") { + globalForDatabase.conn = conn; } + +export const database = drizzle(conn, { schema }); diff --git a/src/server/db/drizzle.schema.ts b/src/server/db/drizzle.schema.ts new file mode 100644 index 0000000..ee7d8d6 --- /dev/null +++ b/src/server/db/drizzle.schema.ts @@ -0,0 +1,178 @@ +/* eslint-disable new-cap */ +/* eslint-disable camelcase */ +import { relations, sql } from "drizzle-orm"; +import { + boolean, foreignKey, integer, jsonb, pgEnum, pgTable, text, timestamp, uniqueIndex, +} from "drizzle-orm/pg-core"; + +export const UserRole = pgEnum("UserRole", ["ADMIN", "EDITOR", "CONTRIBUTOR"]); + +export const TagName = pgEnum("TagName", ["Aeronautics", "Animals", "Art", "Astronomy", "Aviation", "Biology", "Business", "Chemistry", "Cinema", "Civics", "Communications", "Computing", "Construction", "Crafts", "Cultural", "Economics", "Engineering", "Entertainment", "Environment", "Finance", "Games", "Gender", "Geography", "Geology", "Graphic_Novels", "Hardware", "Health", "History", "Internet", "Journalism", "Languages", "Law", "Linguistics", "Literature", "Mathematics", "Medicine", "Military", "Miscellaneous", "Music", "Mythology", "Networking", "Oceanography", "Performance", "Philosophy", "Physics", "Politics", "Programming", "Psychology", "Religion", "Science", "Security", "Slang", "Sociology", "Software", "Space", "Sports", "Teaching", "Technology", "Television"]); + +export const Post = pgTable("Post", { + id: text("id").notNull().primaryKey().default(sql`cuid(1)`), + createdAt: timestamp("createdAt", { precision: 3 }).notNull().defaultNow(), + title: text("title").notNull().unique(), + slug: text("slug").notNull().unique(), + abbreviation: text("abbreviation").notNull(), + acronym: text("acronym").notNull(), + initialism: text("initialism").notNull(), + authorId: text("authorId").notNull(), +}, (Post) => ({ + Post_author_fkey: foreignKey({ + name: "Post_author_fkey", + columns: [Post.authorId], + foreignColumns: [User.id], + }) + .onDelete("cascade") + .onUpdate("cascade"), +})); + +export const PostVersion = pgTable("PostVersion", { + id: text("id").notNull().primaryKey().default(sql`cuid(1)`), + postId: text("postId").notNull(), + updatedAt: timestamp("updatedAt", { precision: 3 }).notNull().defaultNow(), + slug: text("slug").notNull(), + title: text("title").notNull(), + body: text("body").notNull(), + abbreviation: text("abbreviation").notNull(), + acronym: text("acronym").notNull(), + initialism: text("initialism").notNull(), + published: boolean("published").notNull(), + link: text("link").notNull(), + authorId: text("authorId").notNull(), + fileUnder: TagName("fileUnder").notNull(), + tags: jsonb("tags").notNull(), + relatedPostId1: text("relatedPostId1"), + relatedPostId2: text("relatedPostId2"), +}, (PostVersion) => ({ + PostVersion_post_fkey: foreignKey({ + name: "PostVersion_post_fkey", + columns: [PostVersion.postId], + foreignColumns: [Post.id], + }) + .onDelete("cascade") + .onUpdate("cascade"), + PostVersion_author_fkey: foreignKey({ + name: "PostVersion_author_fkey", + columns: [PostVersion.authorId], + foreignColumns: [User.id], + }) + .onDelete("cascade") + .onUpdate("cascade"), +})); + +export const Account = pgTable("Account", { + id: text("id").notNull().primaryKey().default(sql`cuid(1)`), + userId: text("userId").notNull(), + type: text("type").notNull(), + provider: text("provider").notNull(), + providerAccountId: text("providerAccountId").notNull(), + refresh_token: text("refresh_token"), + access_token: text("access_token"), + expires_at: integer("expires_at"), + token_type: text("token_type"), + scope: text("scope"), + id_token: text("id_token"), + session_state: text("session_state"), +}, (Account) => ({ + Account_user_fkey: foreignKey({ + name: "Account_user_fkey", + columns: [Account.userId], + foreignColumns: [User.id], + }) + .onDelete("cascade") + .onUpdate("cascade"), + Account_provider_providerAccountId_unique_idx: uniqueIndex("Account_provider_providerAccountId_key") + .on(Account.provider, Account.providerAccountId), +})); + +export const Session = pgTable("Session", { + id: text("id").notNull().primaryKey().default(sql`cuid(1)`), + sessionToken: text("sessionToken").primaryKey().notNull().unique(), + userId: text("userId").notNull(), + expires: timestamp("expires", { precision: 3 }).notNull(), +}, (Session) => ({ + Session_user_fkey: foreignKey({ + name: "Session_user_fkey", + columns: [Session.userId], + foreignColumns: [User.id], + }) + .onDelete("cascade") + .onUpdate("cascade"), +})); + +export const User = pgTable("User", { + id: text("id").notNull().primaryKey().default(sql`cuid(1)`), + name: text("name"), + username: text("username").unique(), + hasPersonalizedUsername: boolean("hasPersonalizedUsername").notNull(), + email: text("email").unique(), + emailVerified: timestamp("emailVerified", { precision: 3 }), + image: text("image"), + role: UserRole("role").notNull().default("CONTRIBUTOR"), +}); + +export const VerificationToken = pgTable("VerificationToken", { + identifier: text("identifier").notNull(), + token: text("token").notNull().unique(), + expires: timestamp("expires", { precision: 3 }).notNull(), +}, (VerificationToken) => ({ + VerificationToken_identifier_token_unique_idx: uniqueIndex("VerificationToken_identifier_token_key") + .on(VerificationToken.identifier, VerificationToken.token), +})); + +export const PostRelations = relations(Post, ({ one, many }) => ({ + author: one(User, { + relationName: "PostToUser", + fields: [Post.authorId], + references: [User.id], + }), + versions: many(PostVersion, { + relationName: "PostToPostVersion", + }), +})); + +export const PostVersionRelations = relations(PostVersion, ({ one }) => ({ + post: one(Post, { + relationName: "PostToPostVersion", + fields: [PostVersion.postId], + references: [Post.id], + }), + author: one(User, { + relationName: "PostVersionToUser", + fields: [PostVersion.authorId], + references: [User.id], + }), +})); + +export const AccountRelations = relations(Account, ({ one }) => ({ + user: one(User, { + relationName: "AccountToUser", + fields: [Account.userId], + references: [User.id], + }), +})); + +export const SessionRelations = relations(Session, ({ one }) => ({ + user: one(User, { + relationName: "SessionToUser", + fields: [Session.userId], + references: [User.id], + }), +})); + +export const UserRelations = relations(User, ({ many }) => ({ + accounts: many(Account, { + relationName: "AccountToUser", + }), + sessions: many(Session, { + relationName: "SessionToUser", + }), + posts: many(Post, { + relationName: "PostToUser", + }), + PostVersion: many(PostVersion, { + relationName: "PostVersionToUser", + }), +}));