Migration from Prisma to Drizzle-ORM
This commit is contained in:
parent
ed472e40ed
commit
2479dd518d
30 changed files with 1018 additions and 6504 deletions
3
.github/workflows/playwright.yml
vendored
3
.github/workflows/playwright.yml
vendored
|
@ -53,8 +53,7 @@ jobs:
|
|||
- name: 'Compiling page'
|
||||
run: |
|
||||
echo "${{ secrets.ENV_FILE }}" > .env
|
||||
pnpm prisma generate
|
||||
pnpm run build
|
||||
pnpm build
|
||||
|
||||
- name: Run Playwright tests
|
||||
run: pnpm playwright test
|
||||
|
|
4
leaky-ships/.gitignore
vendored
4
leaky-ships/.gitignore
vendored
|
@ -3,8 +3,8 @@
|
|||
# logs
|
||||
/log
|
||||
|
||||
# prisma
|
||||
/prisma/migrations
|
||||
# drizzle
|
||||
/drizzle/migrations
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
|
11
leaky-ships/drizzle.config.ts
Normal file
11
leaky-ships/drizzle.config.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
import "dotenv/config"
|
||||
import type { Config } from "drizzle-kit"
|
||||
|
||||
export default {
|
||||
schema: "./src/drizzle/schema.ts",
|
||||
out: "./src/drizzle/migrations",
|
||||
driver: "pg",
|
||||
dbCredentials: {
|
||||
connectionString: process.env.DATABASE_URL ?? "",
|
||||
},
|
||||
} satisfies Config
|
|
@ -5,7 +5,9 @@ import {
|
|||
type Page,
|
||||
} from "@playwright/test"
|
||||
import { createHash, randomBytes } from "crypto"
|
||||
import prisma from "~/lib/prisma"
|
||||
import { and, desc, eq } from "drizzle-orm"
|
||||
import db from "~/drizzle"
|
||||
import { verificationTokens } from "~/drizzle/schemas/Tables"
|
||||
|
||||
const callbackUrl = process.env.NEXTAUTH_URL + "/"
|
||||
const player1Email = (browser: Browser) =>
|
||||
|
@ -46,20 +48,20 @@ test.describe.serial("Check Email auth", () => {
|
|||
.update(`${token}${process.env.AUTH_SECRET}`)
|
||||
.digest("hex")
|
||||
|
||||
// Use Prisma to fetch the latest token for the email
|
||||
const latestToken = await prisma.verificationToken.findFirst({
|
||||
where: { identifier: player1Email(browser) },
|
||||
orderBy: { expires: "desc" },
|
||||
})
|
||||
await prisma.verificationToken.update({
|
||||
where: {
|
||||
identifier_token: {
|
||||
identifier: player1Email(browser),
|
||||
token: latestToken?.token ?? "",
|
||||
},
|
||||
},
|
||||
data: { token: hash },
|
||||
// Use drizzle to fetch the latest token for the email
|
||||
const latestToken = await db.query.verificationTokens.findFirst({
|
||||
where: eq(verificationTokens.identifier, player1Email(browser)),
|
||||
orderBy: [desc(verificationTokens.expires)],
|
||||
})
|
||||
await db
|
||||
.update(verificationTokens)
|
||||
.set({ token: hash })
|
||||
.where(
|
||||
and(
|
||||
eq(verificationTokens.identifier, player1Email(browser)),
|
||||
eq(verificationTokens.token, latestToken?.token ?? ""),
|
||||
),
|
||||
)
|
||||
|
||||
const params = new URLSearchParams({
|
||||
callbackUrl,
|
||||
|
|
6
leaky-ships/global.d.ts
vendored
6
leaky-ships/global.d.ts
vendored
|
@ -1,6 +0,0 @@
|
|||
import { PrismaClient } from "@prisma/client"
|
||||
import "@total-typescript/ts-reset"
|
||||
|
||||
declare global {
|
||||
let prismaClient: PrismaClient
|
||||
}
|
|
@ -5,14 +5,13 @@
|
|||
"start": "solid-start start --port 3000",
|
||||
"build": "solid-start build",
|
||||
"lint": "eslint --fix \"**/*.{ts,tsx,js,jsx}\"",
|
||||
"push": "prisma db push",
|
||||
"postinstall": "prisma generate",
|
||||
"push": "drizzle-kit push:pg",
|
||||
"test": "pnpm playwright test --ui"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@auth/core": "0.12.0",
|
||||
"@auth/prisma-adapter": "^1.0.1",
|
||||
"@auth/drizzle-adapter": "^0.3.1",
|
||||
"@auth/solid-start": "^0.1.1",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.4.2",
|
||||
"@fortawesome/pro-duotone-svg-icons": "^6.4.2",
|
||||
|
@ -22,22 +21,23 @@
|
|||
"@fortawesome/pro-thin-svg-icons": "^6.4.2",
|
||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
||||
"@fortawesome/sharp-solid-svg-icons": "^6.4.2",
|
||||
"@prisma/client": "^5.1.1",
|
||||
"@paralleldrive/cuid2": "^2.2.2",
|
||||
"@solidjs/meta": "^0.28.6",
|
||||
"@solidjs/router": "^0.8.3",
|
||||
"classnames": "^2.3.2",
|
||||
"colors": "^1.4.0",
|
||||
"drizzle-orm": "^0.28.2",
|
||||
"drizzle-zod": "^0.5.0",
|
||||
"http-status": "^1.6.2",
|
||||
"nodemailer": "6.9.4",
|
||||
"prisma": "^5.1.1",
|
||||
"postgres": "^3.3.5",
|
||||
"socket.io": "^4.7.2",
|
||||
"socket.io-client": "^4.7.2",
|
||||
"solid-js": "^1.7.11",
|
||||
"solid-start": "^0.3.3",
|
||||
"solid-zustand": "^1.7.0",
|
||||
"unique-names-generator": "^4.7.1",
|
||||
"zod": "3.21.1",
|
||||
"zod-prisma-types": "^2.7.9"
|
||||
"zod": "3.21.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.37.0",
|
||||
|
@ -48,9 +48,11 @@
|
|||
"@typescript-eslint/eslint-plugin": "^6.4.0",
|
||||
"autoprefixer": "^10.4.15",
|
||||
"dotenv": "^16.3.1",
|
||||
"drizzle-kit": "^0.19.12",
|
||||
"eslint": "^8.47.0",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"eslint-plugin-solid": "^0.12.1",
|
||||
"pg": "^8.11.2",
|
||||
"postcss": "^8.4.28",
|
||||
"prettier": "^3.0.2",
|
||||
"prettier-plugin-organize-imports": "^3.2.3",
|
||||
|
|
570
leaky-ships/pnpm-lock.yaml
generated
570
leaky-ships/pnpm-lock.yaml
generated
|
@ -8,9 +8,9 @@ dependencies:
|
|||
'@auth/core':
|
||||
specifier: 0.12.0
|
||||
version: 0.12.0(nodemailer@6.9.4)
|
||||
'@auth/prisma-adapter':
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1(@prisma/client@5.1.1)(nodemailer@6.9.4)
|
||||
'@auth/drizzle-adapter':
|
||||
specifier: ^0.3.1
|
||||
version: 0.3.1(nodemailer@6.9.4)
|
||||
'@auth/solid-start':
|
||||
specifier: ^0.1.1
|
||||
version: 0.1.1(@auth/core@0.12.0)(solid-js@1.7.11)(solid-start@0.3.3)
|
||||
|
@ -38,9 +38,9 @@ dependencies:
|
|||
'@fortawesome/sharp-solid-svg-icons':
|
||||
specifier: ^6.4.2
|
||||
version: 6.4.2
|
||||
'@prisma/client':
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1(prisma@5.1.1)
|
||||
'@paralleldrive/cuid2':
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2
|
||||
'@solidjs/meta':
|
||||
specifier: ^0.28.6
|
||||
version: 0.28.6(solid-js@1.7.11)
|
||||
|
@ -53,15 +53,21 @@ dependencies:
|
|||
colors:
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
drizzle-orm:
|
||||
specifier: ^0.28.2
|
||||
version: 0.28.2(pg@8.11.2)(postgres@3.3.5)
|
||||
drizzle-zod:
|
||||
specifier: ^0.5.0
|
||||
version: 0.5.0(drizzle-orm@0.28.2)(zod@3.21.1)
|
||||
http-status:
|
||||
specifier: ^1.6.2
|
||||
version: 1.6.2
|
||||
nodemailer:
|
||||
specifier: 6.9.4
|
||||
version: 6.9.4
|
||||
prisma:
|
||||
specifier: ^5.1.1
|
||||
version: 5.1.1
|
||||
postgres:
|
||||
specifier: ^3.3.5
|
||||
version: 3.3.5
|
||||
socket.io:
|
||||
specifier: ^4.7.2
|
||||
version: 4.7.2
|
||||
|
@ -83,9 +89,6 @@ dependencies:
|
|||
zod:
|
||||
specifier: 3.21.1
|
||||
version: 3.21.1
|
||||
zod-prisma-types:
|
||||
specifier: ^2.7.9
|
||||
version: 2.7.9
|
||||
|
||||
devDependencies:
|
||||
'@playwright/test':
|
||||
|
@ -112,6 +115,9 @@ devDependencies:
|
|||
dotenv:
|
||||
specifier: ^16.3.1
|
||||
version: 16.3.1
|
||||
drizzle-kit:
|
||||
specifier: ^0.19.12
|
||||
version: 0.19.12
|
||||
eslint:
|
||||
specifier: ^8.47.0
|
||||
version: 8.47.0
|
||||
|
@ -121,6 +127,9 @@ devDependencies:
|
|||
eslint-plugin-solid:
|
||||
specifier: ^0.12.1
|
||||
version: 0.12.1(eslint@8.47.0)(typescript@5.1.6)
|
||||
pg:
|
||||
specifier: ^8.11.2
|
||||
version: 8.11.2
|
||||
postcss:
|
||||
specifier: ^8.4.28
|
||||
version: 8.4.28
|
||||
|
@ -171,6 +180,23 @@ packages:
|
|||
/@antfu/utils@0.7.6:
|
||||
resolution: {integrity: sha512-pvFiLP2BeOKA/ZOS6jxx4XhKzdVLHDhGlFEaZ2flWWYf2xOqVniqpk38I04DFRyz+L0ASggl7SkItTc+ZLju4w==}
|
||||
|
||||
/@auth/core@0.11.1(nodemailer@6.9.4):
|
||||
resolution: {integrity: sha512-PzvebszgJ4NpQNz8Fsjn39oEY8MzULKppr7Um7DX/HLrS3zthgLY0yAnwkA+2/kxwAb36dIkX+C72q6TziiTaA==}
|
||||
peerDependencies:
|
||||
nodemailer: ^6.8.0
|
||||
peerDependenciesMeta:
|
||||
nodemailer:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@panva/hkdf': 1.1.1
|
||||
cookie: 0.5.0
|
||||
jose: 4.14.4
|
||||
nodemailer: 6.9.4
|
||||
oauth4webapi: 2.3.0
|
||||
preact: 10.11.3
|
||||
preact-render-to-string: 5.2.3(preact@10.11.3)
|
||||
dev: false
|
||||
|
||||
/@auth/core@0.12.0(nodemailer@6.9.4):
|
||||
resolution: {integrity: sha512-XYipdAc/nKu014VOgpcPyLlj1ghWlnwyloaB1UjQd9ElZRZQ9YpSizzXGLON23t/a0FyabOBBl0/awD2tW58Rg==}
|
||||
peerDependencies:
|
||||
|
@ -188,30 +214,10 @@ packages:
|
|||
preact-render-to-string: 5.2.3(preact@10.11.3)
|
||||
dev: false
|
||||
|
||||
/@auth/core@0.9.0(nodemailer@6.9.4):
|
||||
resolution: {integrity: sha512-W2WO0WCBg1T3P8+yjQPzurTQhPv6ecBYfJ2oE3uvXPAX5ZLWAMSjKFAIa9oLZy5pwrB+YehJZPnlIxVilhrVcg==}
|
||||
peerDependencies:
|
||||
nodemailer: ^6.8.0
|
||||
peerDependenciesMeta:
|
||||
nodemailer:
|
||||
optional: true
|
||||
/@auth/drizzle-adapter@0.3.1(nodemailer@6.9.4):
|
||||
resolution: {integrity: sha512-zSuewnrozY0EZYVrt2T5VY0R+wA3chXncanmUgvAgoX+pcussKMVFmnSrSYuc3i4vfM2qCmAa6S6dkSH5RViSA==}
|
||||
dependencies:
|
||||
'@panva/hkdf': 1.1.1
|
||||
cookie: 0.5.0
|
||||
jose: 4.14.4
|
||||
nodemailer: 6.9.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)(nodemailer@6.9.4):
|
||||
resolution: {integrity: sha512-sBp9l/jVr7l9y7rp2Pv6eoP7i8X2CgRNE3jDWJ0B/u+HnKRofXflD1cldPqRSAkJhqH3UxhVtMTEijT9FoofmQ==}
|
||||
peerDependencies:
|
||||
'@prisma/client': '>=2.26.0 || >=3 || >=4'
|
||||
dependencies:
|
||||
'@auth/core': 0.9.0(nodemailer@6.9.4)
|
||||
'@prisma/client': 5.1.1(prisma@5.1.1)
|
||||
'@auth/core': 0.11.1(nodemailer@6.9.4)
|
||||
transitivePeerDependencies:
|
||||
- nodemailer
|
||||
dev: false
|
||||
|
@ -1325,6 +1331,24 @@ packages:
|
|||
'@babel/helper-validator-identifier': 7.22.5
|
||||
to-fast-properties: 2.0.0
|
||||
|
||||
/@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.17.19:
|
||||
resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -1846,6 +1870,11 @@ packages:
|
|||
'@jridgewell/resolve-uri': 3.1.1
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
||||
/@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'}
|
||||
|
@ -1868,6 +1897,12 @@ packages:
|
|||
resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==}
|
||||
dev: false
|
||||
|
||||
/@paralleldrive/cuid2@2.2.2:
|
||||
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
||||
dependencies:
|
||||
'@noble/hashes': 1.3.1
|
||||
dev: false
|
||||
|
||||
/@playwright/test@1.37.0:
|
||||
resolution: {integrity: sha512-181WBLk4SRUyH1Q96VZl7BP6HcK0b7lbdeKisn3N/vnjitk+9HbdlFz/L5fey05vxaAhldIDnzo8KUoy8S3mmQ==}
|
||||
engines: {node: '>=16'}
|
||||
|
@ -1882,50 +1917,6 @@ packages:
|
|||
/@polka/url@1.0.0-next.21:
|
||||
resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==}
|
||||
|
||||
/@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
|
||||
dependencies:
|
||||
'@prisma/engines-version': 5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e
|
||||
prisma: 5.1.1
|
||||
dev: false
|
||||
|
||||
/@prisma/debug@5.1.1:
|
||||
resolution: {integrity: sha512-R9e2Tn8f+ujVjwn6ne1YkXY35BXzUmxJbGsmD1c8RAZ/NXgbYktEFAwIkOZn5H5zRfY2VDSBvGI6TFpnOu50cg==}
|
||||
dependencies:
|
||||
'@types/debug': 4.1.8
|
||||
debug: 4.3.4
|
||||
strip-ansi: 6.0.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@prisma/engines-version@5.1.1-1.6a3747c37ff169c90047725a05a6ef02e32ac97e:
|
||||
resolution: {integrity: sha512-owZqbY/wucbr65bXJ/ljrHPgQU5xXTSkmcE/JcbqE1kusuAXV/TLN3/exmz21SZ5rJ7WDkyk70J2G/n68iogbQ==}
|
||||
dev: false
|
||||
|
||||
/@prisma/engines@5.1.1:
|
||||
resolution: {integrity: sha512-NV/4nVNWFZSJCCIA3HIFJbbDKO/NARc9ej0tX5S9k2EVbkrFJC4Xt9b0u4rNZWL4V+F5LAjvta8vzEUw0rw+HA==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/@prisma/generator-helper@5.1.1:
|
||||
resolution: {integrity: sha512-Qk9iiVk4JZQYZrYsc1Wx9fXFFnS1AH4T7WyLxCIFnX/end0K5tOK75Qxv6mjZAHE0XUGrzoTlZUkbSDVYz/CvQ==}
|
||||
dependencies:
|
||||
'@prisma/debug': 5.1.1
|
||||
'@types/cross-spawn': 6.0.2
|
||||
cross-spawn: 7.0.3
|
||||
kleur: 4.1.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/@rollup/plugin-commonjs@24.1.0(rollup@3.28.0):
|
||||
resolution: {integrity: sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
@ -2057,12 +2048,6 @@ packages:
|
|||
'@types/node': 18.17.5
|
||||
dev: false
|
||||
|
||||
/@types/cross-spawn@6.0.2:
|
||||
resolution: {integrity: sha512-KuwNhp3eza+Rhu8IFI5HUXRP0LIhqH5cAjubUvGXXthh4YYBuP2ntwEX+Cz8GJoZUHlKo247wPWOfA9LYEq4cw==}
|
||||
dependencies:
|
||||
'@types/node': 18.17.5
|
||||
dev: false
|
||||
|
||||
/@types/debug@4.1.8:
|
||||
resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==}
|
||||
dependencies:
|
||||
|
@ -2537,6 +2522,10 @@ packages:
|
|||
/buffer-from@1.1.2:
|
||||
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
|
||||
|
||||
/buffer-writer@2.0.0:
|
||||
resolution: {integrity: sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
/builtin-modules@3.3.0:
|
||||
resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -2574,6 +2563,11 @@ packages:
|
|||
engines: {node: '>= 6'}
|
||||
dev: true
|
||||
|
||||
/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==}
|
||||
|
||||
|
@ -2593,6 +2587,11 @@ packages:
|
|||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
||||
/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'}
|
||||
|
@ -2611,6 +2610,17 @@ packages:
|
|||
resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==}
|
||||
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
|
||||
|
||||
/cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -2619,10 +2629,6 @@ packages:
|
|||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 7.0.0
|
||||
|
||||
/code-block-writer@12.0.0:
|
||||
resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==}
|
||||
dev: false
|
||||
|
||||
/color-convert@1.9.3:
|
||||
resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
|
||||
dependencies:
|
||||
|
@ -2653,6 +2659,11 @@ packages:
|
|||
engines: {node: '>= 6'}
|
||||
dev: true
|
||||
|
||||
/commander@9.5.0:
|
||||
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
|
||||
engines: {node: ^12.20.0 || >=14}
|
||||
dev: true
|
||||
|
||||
/commondir@1.0.1:
|
||||
resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==}
|
||||
|
||||
|
@ -2734,6 +2745,13 @@ packages:
|
|||
/csstype@3.1.2:
|
||||
resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==}
|
||||
|
||||
/d@1.0.1:
|
||||
resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==}
|
||||
dependencies:
|
||||
es5-ext: 0.10.62
|
||||
type: 1.2.0
|
||||
dev: true
|
||||
|
||||
/debug@2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
|
@ -2803,6 +2821,12 @@ packages:
|
|||
resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
|
||||
dev: true
|
||||
|
||||
/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'}
|
||||
|
@ -2825,6 +2849,109 @@ packages:
|
|||
resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
/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.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/drizzle-orm@0.28.2(pg@8.11.2)(postgres@3.3.5):
|
||||
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:
|
||||
pg: 8.11.2
|
||||
postgres: 3.3.5
|
||||
dev: false
|
||||
|
||||
/drizzle-zod@0.5.0(drizzle-orm@0.28.2)(zod@3.21.1):
|
||||
resolution: {integrity: sha512-gIOXclphhaleYFEGZFxSyJBoiPRyksGyIPgmgWz6a+j5JeaOrOf1QOPjf1p5AHYA+1O3Q01ondGOZfgObxBTsg==}
|
||||
peerDependencies:
|
||||
drizzle-orm: '>=0.23.13'
|
||||
zod: '*'
|
||||
dependencies:
|
||||
drizzle-orm: 0.28.2(pg@8.11.2)(postgres@3.3.5)
|
||||
zod: 3.21.1
|
||||
dev: false
|
||||
|
||||
/ee-first@1.1.1:
|
||||
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
|
||||
|
||||
|
@ -2952,6 +3079,40 @@ 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-plugin-solid@0.5.0(esbuild@0.17.19)(solid-js@1.7.11):
|
||||
resolution: {integrity: sha512-ITK6n+0ayGFeDVUZWNMxX+vLsasEN1ILrg4pISsNOQ+mq4ljlJJiuXotInd+HE0MzwTcA9wExT1yzDE2hsqPsg==}
|
||||
peerDependencies:
|
||||
|
@ -2966,6 +3127,17 @@ packages:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
/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.17.19:
|
||||
resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -3174,6 +3346,13 @@ packages:
|
|||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/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'}
|
||||
|
@ -3202,6 +3381,12 @@ packages:
|
|||
signal-exit: 3.0.7
|
||||
strip-final-newline: 3.0.0
|
||||
|
||||
/ext@1.7.0:
|
||||
resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==}
|
||||
dependencies:
|
||||
type: 2.7.2
|
||||
dev: true
|
||||
|
||||
/fast-deep-equal@3.1.3:
|
||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||
dev: true
|
||||
|
@ -3365,6 +3550,12 @@ packages:
|
|||
get-intrinsic: 1.2.1
|
||||
dev: true
|
||||
|
||||
/get-tsconfig@4.7.0:
|
||||
resolution: {integrity: sha512-pmjiZ7xtB8URYm74PlGJozDNyhvsVLUcpBa8DZBG3bWHwaHa9bPiRpiSfovw+fjhwONSCWKRyk+JQHEGZmMrzw==}
|
||||
dependencies:
|
||||
resolve-pkg-maps: 1.0.0
|
||||
dev: true
|
||||
|
||||
/glob-parent@5.1.2:
|
||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||
engines: {node: '>= 6'}
|
||||
|
@ -3453,6 +3644,13 @@ packages:
|
|||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
dev: true
|
||||
|
||||
/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
|
||||
|
@ -3495,6 +3693,10 @@ packages:
|
|||
dependencies:
|
||||
function-bind: 1.1.1
|
||||
|
||||
/heap@0.2.7:
|
||||
resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==}
|
||||
dev: true
|
||||
|
||||
/html-entities@2.3.3:
|
||||
resolution: {integrity: sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==}
|
||||
|
||||
|
@ -3672,6 +3874,10 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/is-promise@2.2.2:
|
||||
resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==}
|
||||
dev: true
|
||||
|
||||
/is-reference@1.2.1:
|
||||
resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==}
|
||||
dependencies:
|
||||
|
@ -3780,6 +3986,15 @@ packages:
|
|||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
|
||||
/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-schema-traverse@0.4.1:
|
||||
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
|
||||
dev: true
|
||||
|
@ -3814,11 +4029,6 @@ packages:
|
|||
resolution: {integrity: sha512-7n6wXq4gNgBELfDCpzKc+mRrZFs7D+wgfF5WRFLNAr4DA/qtr9Js8uOAVAfHhuLMfAcQ0pRKqbpjx+TcJVdE1Q==}
|
||||
dev: true
|
||||
|
||||
/kleur@4.1.5:
|
||||
resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/known-css-properties@0.24.0:
|
||||
resolution: {integrity: sha512-RTSoaUAfLvpR357vWzAz/50Q/BmHfmE6ETSWfutT0AJiw10e6CmcdYRQJlLRd95B53D0Y2aD1jSxD3V3ySF+PA==}
|
||||
dev: true
|
||||
|
@ -3854,6 +4064,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
|
||||
|
||||
/lodash@4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
|
||||
|
@ -3876,12 +4090,31 @@ packages:
|
|||
yallist: 4.0.0
|
||||
dev: true
|
||||
|
||||
/lru-queue@0.1.0:
|
||||
resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==}
|
||||
dependencies:
|
||||
es5-ext: 0.10.62
|
||||
dev: true
|
||||
|
||||
/magic-string@0.27.0:
|
||||
resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==}
|
||||
engines: {node: '>=12'}
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
|
||||
/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-anything@5.1.7:
|
||||
resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==}
|
||||
engines: {node: '>=12.13'}
|
||||
|
@ -3935,6 +4168,13 @@ packages:
|
|||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
|
||||
/minimatch@7.4.6:
|
||||
resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
dev: true
|
||||
|
||||
/minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
|
||||
|
@ -3973,6 +4213,10 @@ packages:
|
|||
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
/next-tick@1.1.0:
|
||||
resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==}
|
||||
dev: true
|
||||
|
||||
/node-releases@2.0.13:
|
||||
resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==}
|
||||
|
||||
|
@ -4113,6 +4357,9 @@ packages:
|
|||
p-limit: 3.1.0
|
||||
dev: true
|
||||
|
||||
/packet-reader@1.0.0:
|
||||
resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==}
|
||||
|
||||
/parent-module@1.0.1:
|
||||
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -4153,6 +4400,62 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/pg-cloudflare@1.1.1:
|
||||
resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==}
|
||||
requiresBuild: true
|
||||
optional: true
|
||||
|
||||
/pg-connection-string@2.6.2:
|
||||
resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==}
|
||||
|
||||
/pg-int8@1.0.1:
|
||||
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
/pg-pool@3.6.1(pg@8.11.2):
|
||||
resolution: {integrity: sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==}
|
||||
peerDependencies:
|
||||
pg: '>=8.0'
|
||||
dependencies:
|
||||
pg: 8.11.2
|
||||
|
||||
/pg-protocol@1.6.0:
|
||||
resolution: {integrity: sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==}
|
||||
|
||||
/pg-types@2.2.0:
|
||||
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
pg-int8: 1.0.1
|
||||
postgres-array: 2.0.0
|
||||
postgres-bytea: 1.0.0
|
||||
postgres-date: 1.0.7
|
||||
postgres-interval: 1.2.0
|
||||
|
||||
/pg@8.11.2:
|
||||
resolution: {integrity: sha512-l4rmVeV8qTIrrPrIR3kZQqBgSN93331s9i6wiUiLOSk0Q7PmUxZD/m1rQI622l3NfqBby9Ar5PABfS/SulfieQ==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
peerDependencies:
|
||||
pg-native: '>=3.0.1'
|
||||
peerDependenciesMeta:
|
||||
pg-native:
|
||||
optional: true
|
||||
dependencies:
|
||||
buffer-writer: 2.0.0
|
||||
packet-reader: 1.0.0
|
||||
pg-connection-string: 2.6.2
|
||||
pg-pool: 3.6.1(pg@8.11.2)
|
||||
pg-protocol: 1.6.0
|
||||
pg-types: 2.2.0
|
||||
pgpass: 1.0.5
|
||||
optionalDependencies:
|
||||
pg-cloudflare: 1.1.1
|
||||
|
||||
/pgpass@1.0.5:
|
||||
resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
|
||||
/picocolors@1.0.0:
|
||||
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
|
||||
|
||||
|
@ -4252,6 +4555,28 @@ packages:
|
|||
picocolors: 1.0.0
|
||||
source-map-js: 1.0.2
|
||||
|
||||
/postgres-array@2.0.0:
|
||||
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
/postgres-bytea@1.0.0:
|
||||
resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/postgres-date@1.0.7:
|
||||
resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
/postgres-interval@1.2.0:
|
||||
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dependencies:
|
||||
xtend: 4.0.2
|
||||
|
||||
/postgres@3.3.5:
|
||||
resolution: {integrity: sha512-+JD93VELV9gHkqpV5gdL5/70HdGtEw4/XE1S4BC8f1mcPmdib3K5XsKVbnR1XcAyC41zOnifJ+9YRKxdIsXiUw==}
|
||||
dev: false
|
||||
|
||||
/preact-render-to-string@5.2.3(preact@10.11.3):
|
||||
resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==}
|
||||
peerDependencies:
|
||||
|
@ -4353,15 +4678,6 @@ packages:
|
|||
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
|
||||
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
|
||||
dev: false
|
||||
|
||||
/prop-types@15.8.1:
|
||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||
dependencies:
|
||||
|
@ -4457,6 +4773,10 @@ packages:
|
|||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/resolve-pkg-maps@1.0.0:
|
||||
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
|
||||
dev: true
|
||||
|
||||
/resolve@1.22.4:
|
||||
resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==}
|
||||
hasBin: true
|
||||
|
@ -4612,6 +4932,10 @@ packages:
|
|||
mrmime: 1.0.1
|
||||
totalist: 3.0.1
|
||||
|
||||
/sisteransi@1.0.5:
|
||||
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
|
||||
dev: true
|
||||
|
||||
/slash@3.0.0:
|
||||
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -4806,6 +5130,10 @@ packages:
|
|||
resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
/split2@4.2.0:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
|
||||
/statuses@1.5.0:
|
||||
resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
@ -4961,6 +5289,13 @@ packages:
|
|||
any-promise: 1.3.0
|
||||
dev: true
|
||||
|
||||
/timers-ext@0.1.7:
|
||||
resolution: {integrity: sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==}
|
||||
dependencies:
|
||||
es5-ext: 0.10.62
|
||||
next-tick: 1.1.0
|
||||
dev: true
|
||||
|
||||
/titleize@3.0.0:
|
||||
resolution: {integrity: sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -5027,6 +5362,14 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/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'}
|
||||
|
@ -5289,6 +5632,10 @@ packages:
|
|||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
/wordwrap@1.0.0:
|
||||
resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==}
|
||||
dev: true
|
||||
|
||||
/wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -5318,6 +5665,10 @@ packages:
|
|||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/xtend@4.0.2:
|
||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
||||
/y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
|
@ -5355,21 +5706,8 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/zod-prisma-types@2.7.9:
|
||||
resolution: {integrity: sha512-JgPN32d/Wm6/E61oHXek2jDT6VxBpKVPmLom7585SmdCyj+xb+OAg8O3G0BLU+gWNiC+Eyt3blo1S/8W9sIaxA==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@prisma/generator-helper': 5.1.1
|
||||
code-block-writer: 12.0.0
|
||||
lodash: 4.17.21
|
||||
zod: 3.21.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/zod@3.21.1:
|
||||
resolution: {integrity: sha512-+dTu2m6gmCbO9Ahm4ZBDapx2O6ZY9QSPXst2WXjcznPMwf2YNpn3RevLx4KkZp1OPW/ouFcoBtBzFz/LeY69oA==}
|
||||
dev: false
|
||||
|
||||
/zustand@4.4.1(react@18.2.0):
|
||||
resolution: {integrity: sha512-QCPfstAS4EBiTQzlaGP1gmorkh/UL1Leaj2tdj+zZCZ/9bm0WS7sI2wnfD5lpOszFqWJ1DcPnGoY8RDL61uokw==}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -50,13 +50,13 @@ model User {
|
|||
email String? @unique
|
||||
emailVerified DateTime? @map("email_verified")
|
||||
image String?
|
||||
createdAt DateTime @default(now()) @map(name: "created_at")
|
||||
updatedAt DateTime @updatedAt @map(name: "updated_at")
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
games User_Game[]
|
||||
accounts Account[]
|
||||
sessions Session[]
|
||||
|
||||
@@map(name: "users")
|
||||
@@map("users")
|
||||
}
|
||||
|
||||
model VerificationToken {
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import classNames from "classnames"
|
||||
|
||||
function BurgerMenu(props: {
|
||||
onClick?: () => void
|
||||
blur?: boolean
|
||||
}) {
|
||||
function BurgerMenu(props: { onClick?: () => void; blur?: boolean }) {
|
||||
return (
|
||||
<button
|
||||
id="menu"
|
||||
|
|
10
leaky-ships/src/drizzle/index.ts
Normal file
10
leaky-ships/src/drizzle/index.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { drizzle } from "drizzle-orm/postgres-js"
|
||||
import postgres from "postgres"
|
||||
import * as schema from "./schemas/Tables"
|
||||
|
||||
const queryClient = postgres(process.env.DATABASE_URL ?? "")
|
||||
const db = drizzle(queryClient, {
|
||||
schema,
|
||||
})
|
||||
|
||||
export default db
|
214
leaky-ships/src/drizzle/schemas/Tables.ts
Normal file
214
leaky-ships/src/drizzle/schemas/Tables.ts
Normal file
|
@ -0,0 +1,214 @@
|
|||
import type { AdapterAccount } from "@auth/core/adapters"
|
||||
import { createId } from "@paralleldrive/cuid2"
|
||||
import { relations } from "drizzle-orm"
|
||||
import {
|
||||
AnyPgColumn,
|
||||
boolean,
|
||||
integer,
|
||||
pgTable,
|
||||
primaryKey,
|
||||
text,
|
||||
timestamp,
|
||||
unique,
|
||||
} from "drizzle-orm/pg-core"
|
||||
import { gameState, moveType, orientation } from "./Types"
|
||||
|
||||
export const users = pgTable("user", {
|
||||
id: text("id").notNull().primaryKey(),
|
||||
name: text("name"),
|
||||
email: text("email").notNull().unique(),
|
||||
emailVerified: timestamp("emailVerified", { mode: "date" }),
|
||||
image: text("image"),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
||||
})
|
||||
|
||||
export const accounts = pgTable(
|
||||
"account",
|
||||
{
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
type: text("type").$type<AdapterAccount["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"),
|
||||
extExpiresIn: integer("ext_expires_in"),
|
||||
token_type: text("token_type"),
|
||||
scope: text("scope"),
|
||||
id_token: text("id_token"),
|
||||
session_state: text("session_state"),
|
||||
oauthTokenSecret: text("oauth_token_secret"),
|
||||
oauthToken: text("oauth_token"),
|
||||
},
|
||||
(account) => ({
|
||||
compoundKey: primaryKey(account.provider, account.providerAccountId),
|
||||
}),
|
||||
)
|
||||
|
||||
export const sessions = pgTable("session", {
|
||||
sessionToken: text("sessionToken").notNull().primaryKey(),
|
||||
userId: text("userId")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
expires: timestamp("expires", { mode: "date" }).notNull(),
|
||||
})
|
||||
|
||||
export const verificationTokens = pgTable(
|
||||
"verificationToken",
|
||||
{
|
||||
identifier: text("identifier").notNull(),
|
||||
token: text("token").notNull(),
|
||||
expires: timestamp("expires", { mode: "date" }).notNull(),
|
||||
},
|
||||
(vt) => ({
|
||||
compoundKey: primaryKey(vt.identifier, vt.token),
|
||||
}),
|
||||
)
|
||||
|
||||
export const games = pgTable("game", {
|
||||
id: text("id").notNull().primaryKey().default(createId()),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
updatedAt: timestamp("updated_at").notNull().defaultNow(),
|
||||
state: gameState("state").notNull().default("lobby"),
|
||||
allowSpectators: boolean("allow_spectators").notNull().default(true),
|
||||
allowSpecials: boolean("allow_specials").notNull().default(true),
|
||||
allowChat: boolean("allow_chat").notNull().default(true),
|
||||
allowMarkDraw: boolean("allow_mark_draw").notNull().default(true),
|
||||
})
|
||||
|
||||
export const gamepins = pgTable("gamepin", {
|
||||
id: text("id").notNull().primaryKey().default(createId()),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
pin: text("pin").notNull().unique(),
|
||||
gameId: text("game_id")
|
||||
.notNull()
|
||||
.unique()
|
||||
.references((): AnyPgColumn => games.id),
|
||||
})
|
||||
|
||||
export const ships = pgTable("ship", {
|
||||
id: text("id").notNull().primaryKey().default(createId()),
|
||||
size: integer("size").notNull(),
|
||||
variant: integer("variant").notNull(),
|
||||
x: integer("x").notNull(),
|
||||
y: integer("y").notNull(),
|
||||
orientation: orientation("orientation").notNull(),
|
||||
user_game_id: text("user_game_id")
|
||||
.notNull()
|
||||
.references(() => user_games.id, { onDelete: "cascade" }),
|
||||
})
|
||||
|
||||
export const hits = pgTable("hit", {
|
||||
id: text("id").notNull().primaryKey().default(createId()),
|
||||
x: integer("x").notNull(),
|
||||
y: integer("y").notNull(),
|
||||
hit: boolean("hit").notNull(),
|
||||
user_game_id: text("user_game_id")
|
||||
.notNull()
|
||||
.references(() => user_games.id, { onDelete: "cascade" }),
|
||||
})
|
||||
|
||||
export const moves = pgTable("move", {
|
||||
id: text("id").notNull().primaryKey().default(createId()),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
index: integer("index").notNull(),
|
||||
type: moveType("type").notNull(),
|
||||
x: integer("x").notNull(),
|
||||
y: integer("y").notNull(),
|
||||
orientation: orientation("orientation").notNull(),
|
||||
user_game_id: text("user_game_id")
|
||||
.notNull()
|
||||
.references(() => user_games.id, { onDelete: "cascade" }),
|
||||
})
|
||||
|
||||
export const chats = pgTable("chat", {
|
||||
id: text("id").notNull().primaryKey().default(createId()),
|
||||
createdAt: timestamp("created_at").notNull().defaultNow(),
|
||||
message: text("message"),
|
||||
event: text("event"),
|
||||
user_game_id: text("user_game_id")
|
||||
.notNull()
|
||||
.references(() => user_games.id, { onDelete: "cascade" }),
|
||||
})
|
||||
|
||||
export const user_games = pgTable(
|
||||
"user_game",
|
||||
{
|
||||
id: text("id").notNull().primaryKey().default(createId()),
|
||||
createdAt: timestamp("created_at").defaultNow(),
|
||||
gameId: text("game_id")
|
||||
.notNull()
|
||||
.references(() => games.id, { onDelete: "cascade" }),
|
||||
userId: text("user_id")
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: "cascade" }),
|
||||
index: integer("index").notNull(),
|
||||
},
|
||||
(t) => ({
|
||||
gameIndex: unique().on(t.gameId, t.index),
|
||||
}),
|
||||
)
|
||||
|
||||
export const usersRelations = relations(users, ({ many }) => ({
|
||||
user_games: many(user_games),
|
||||
sessions: many(sessions),
|
||||
}))
|
||||
|
||||
export const sessionsRelations = relations(sessions, ({ one }) => ({
|
||||
user: one(users, {
|
||||
fields: [sessions.userId],
|
||||
references: [users.id],
|
||||
}),
|
||||
}))
|
||||
|
||||
export const gamesRelations = relations(games, ({ one, many }) => ({
|
||||
gamePin: one(gamepins, {
|
||||
fields: [games.id],
|
||||
references: [gamepins.gameId],
|
||||
}),
|
||||
users: many(user_games),
|
||||
}))
|
||||
|
||||
export const gamepinsRelations = relations(gamepins, ({ one }) => ({
|
||||
game: one(games, { fields: [gamepins.gameId], references: [games.id] }),
|
||||
}))
|
||||
|
||||
export const shipsRelations = relations(ships, ({ one }) => ({
|
||||
userGame: one(user_games, {
|
||||
fields: [ships.user_game_id],
|
||||
references: [user_games.id],
|
||||
}),
|
||||
}))
|
||||
|
||||
export const hitsRelations = relations(hits, ({ one }) => ({
|
||||
userGame: one(user_games, {
|
||||
fields: [hits.user_game_id],
|
||||
references: [user_games.id],
|
||||
}),
|
||||
}))
|
||||
|
||||
export const userGamesRelations = relations(user_games, ({ one, many }) => ({
|
||||
user: one(users, { fields: [user_games.userId], references: [users.id] }),
|
||||
game: one(games, { fields: [user_games.gameId], references: [games.id] }),
|
||||
moves: many(moves),
|
||||
ships: many(ships),
|
||||
hits: many(hits),
|
||||
chats: many(chats),
|
||||
}))
|
||||
|
||||
export const movesRelations = relations(moves, ({ one }) => ({
|
||||
userGame: one(user_games, {
|
||||
fields: [moves.user_game_id],
|
||||
references: [user_games.id],
|
||||
}),
|
||||
}))
|
||||
|
||||
export const chatsRelations = relations(chats, ({ one }) => ({
|
||||
userGame: one(user_games, {
|
||||
fields: [chats.user_game_id],
|
||||
references: [user_games.id],
|
||||
}),
|
||||
}))
|
16
leaky-ships/src/drizzle/schemas/Types.ts
Normal file
16
leaky-ships/src/drizzle/schemas/Types.ts
Normal file
|
@ -0,0 +1,16 @@
|
|||
import { pgEnum } from "drizzle-orm/pg-core"
|
||||
|
||||
export const gameState = pgEnum("game_state", [
|
||||
"lobby",
|
||||
"starting",
|
||||
"running",
|
||||
"ended",
|
||||
"aborted",
|
||||
])
|
||||
export const moveType = pgEnum("move_type", [
|
||||
"missile",
|
||||
"vtorpedo",
|
||||
"htorpedo",
|
||||
"radar",
|
||||
])
|
||||
export const orientation = pgEnum("orientation", ["h", "v"])
|
|
@ -1,4 +1,3 @@
|
|||
import { produce } from "immer"
|
||||
import create from "solid-zustand"
|
||||
|
||||
const initialState: {
|
||||
|
@ -20,12 +19,7 @@ export type Action = {
|
|||
|
||||
export const useDrawProps = create<State & Action>()((set) => ({
|
||||
...initialState,
|
||||
setColor: (color) =>
|
||||
set(
|
||||
produce((state) => {
|
||||
state.color = color
|
||||
}),
|
||||
),
|
||||
setColor: (color) => set((state) => ({ ...state, color })),
|
||||
reset: () => {
|
||||
set(initialState)
|
||||
},
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { GameState, MoveType } from "@prisma/client"
|
||||
import { getPayloadwithChecksum } from "~/lib/getPayloadwithChecksum"
|
||||
import { socket } from "~/lib/socket"
|
||||
import {
|
||||
|
@ -10,6 +9,8 @@ import {
|
|||
} from "~/lib/utils/helpers"
|
||||
import {
|
||||
GamePropsSchema,
|
||||
GameState,
|
||||
MoveType,
|
||||
PlayerSchema,
|
||||
optionalGamePropsSchema,
|
||||
} from "~/lib/zodSchemas"
|
||||
|
@ -100,7 +101,7 @@ export const useGameProps = create<State & Action>()((set) => ({
|
|||
state.payload.users.map((e) => {
|
||||
if (!e) return e
|
||||
if (i === e.index) e.moves.push(move)
|
||||
else if (move.type !== MoveType.radar)
|
||||
else if (move.type !== MoveType.Enum.radar)
|
||||
e.hits.push(
|
||||
...list.map(({ x, y }) => ({
|
||||
hit: !!intersectingShip(e.ships, {
|
||||
|
|
|
@ -155,7 +155,7 @@ function useSocket() {
|
|||
.then(isAuthenticated)
|
||||
.then((game) => GamePropsSchema.parse(game))
|
||||
.then((res) => full(res))
|
||||
.catch((e) => console.log(e))
|
||||
.catch((e) => console.log("Failed to get /api/game/running: ", e))
|
||||
return
|
||||
}
|
||||
if (isConnected()) return
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import { Session } from "@auth/core/types"
|
||||
import { GameState } from "@prisma/client"
|
||||
import type { Server as HTTPServer } from "http"
|
||||
import type { Socket as NetSocket } from "net"
|
||||
import type {
|
||||
|
@ -9,6 +8,7 @@ import type {
|
|||
} from "socket.io"
|
||||
import type { Socket as SocketforClient } from "socket.io-client"
|
||||
import { GamePropsSchema } from "~/lib/zodSchemas"
|
||||
import { GameState } from "../lib/zodSchemas"
|
||||
import {
|
||||
DrawLineProps,
|
||||
GameSettings,
|
||||
|
@ -25,7 +25,7 @@ interface SocketWithIO extends NetSocket {
|
|||
server: SocketServer
|
||||
}
|
||||
|
||||
export interface RequestWithSocket extends Request {
|
||||
export interface ResponseWithSocket extends Response {
|
||||
socket: SocketWithIO
|
||||
}
|
||||
|
||||
|
@ -74,7 +74,7 @@ interface SocketData {
|
|||
index: number
|
||||
}
|
||||
user: Session["user"]
|
||||
gameId: string | null
|
||||
gameId: string
|
||||
index: number
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { IconDefinition } from "@fortawesome/pro-solid-svg-icons"
|
||||
import { MoveType, Orientation } from "@prisma/client"
|
||||
import { PlayerSchema } from "~/lib/zodSchemas"
|
||||
import { MoveType, Orientation, PlayerSchema } from "~/lib/zodSchemas"
|
||||
|
||||
export interface Position {
|
||||
x: number
|
||||
|
|
|
@ -56,15 +56,19 @@ async function logging(
|
|||
`[${new Date().toString().slice(0, 33)}] ` + messages.console
|
||||
messages.file = `[${new Date().toString().slice(0, 33)}] ` + messages.file
|
||||
if (request) {
|
||||
const forwardedFor = request.headers
|
||||
console.log(JSON.stringify(forwardedFor))
|
||||
const xForwardedFor =
|
||||
typeof request.headers.get === "function"
|
||||
? request.headers.get("x-forwarded-for")
|
||||
: "0.0.0.0" // request.headers
|
||||
if (typeof request.headers.get !== "function")
|
||||
console.log("IncomingHttpHeaders", request.headers)
|
||||
// ("x-forwarded-for")
|
||||
// const ip = (forwardedFor || "127.0.0.1, 192.168.178.1").split(",")
|
||||
// const route = request.url
|
||||
// messages.console = [ip[0].yellow, route?.green, messages.console].join(
|
||||
// " - ",
|
||||
// )
|
||||
// messages.file = [ip[0], route, messages.file].join(" - ")
|
||||
const ip = (xForwardedFor || "127.0.0.1, 192.168.178.1").split(",")
|
||||
const route = request.url
|
||||
messages.console = [ip[0].yellow, route?.green, messages.console].join(
|
||||
" - ",
|
||||
)
|
||||
messages.file = [ip[0], route, messages.file].join(" - ")
|
||||
}
|
||||
await fs.promises.appendFile("log/log.txt", messages.file + "\n")
|
||||
console.log(messages.console)
|
||||
|
|
|
@ -13,7 +13,7 @@ export default function sendError(
|
|||
: ["solved" in err && err.solved ? "debug" : "error"],
|
||||
request,
|
||||
)
|
||||
if ("name" in err) console.log(err)
|
||||
if ("name" in err) console.log("Sending Respons: " + err)
|
||||
// If something went wrong, let the client know with status 500
|
||||
return json(null, { status: "statusCode" in err ? err.statusCode : 500 })
|
||||
}
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
// lib/prisma.ts
|
||||
import { PrismaClient } from "@prisma/client"
|
||||
|
||||
let prisma: PrismaClient
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
prisma = new PrismaClient()
|
||||
} else {
|
||||
if (!global.prismaClient) {
|
||||
global.prismaClient = new PrismaClient()
|
||||
}
|
||||
prisma = global.prismaClient
|
||||
}
|
||||
|
||||
export default prisma
|
|
@ -1,4 +1,3 @@
|
|||
import { Orientation } from "@prisma/client"
|
||||
import { count } from "~/components/Gamefield/Gamefield"
|
||||
import type {
|
||||
Hit,
|
||||
|
@ -9,7 +8,9 @@ import type {
|
|||
ShipProps,
|
||||
Target,
|
||||
TargetList,
|
||||
TargetPreview,
|
||||
} from "../../interfaces/frontend"
|
||||
import { Orientation } from "../zodSchemas"
|
||||
|
||||
export function borderCN(count: number, x: number, y: number) {
|
||||
if (x === 0) return "left"
|
||||
|
@ -115,13 +116,13 @@ export const initlialTarget = {
|
|||
x: 2,
|
||||
y: 2,
|
||||
show: false,
|
||||
orientation: Orientation.h,
|
||||
orientation: Orientation.Enum.h,
|
||||
}
|
||||
export const initlialTargetPreview = {
|
||||
x: 2,
|
||||
y: 2,
|
||||
show: false,
|
||||
orientation: Orientation.h,
|
||||
orientation: Orientation.Enum.h,
|
||||
}
|
||||
export const initlialMouseCursor = {
|
||||
shouldShow: false,
|
||||
|
@ -132,7 +133,7 @@ export const initlialMouseCursor = {
|
|||
export const shipProps = (
|
||||
ships: ShipProps[],
|
||||
mode: number,
|
||||
targetPreview: Position & { orientation: Orientation },
|
||||
targetPreview: Omit<TargetPreview, "show">,
|
||||
) => ({
|
||||
size: mode + 2,
|
||||
variant:
|
||||
|
|
|
@ -1,5 +1,38 @@
|
|||
import { GameState, MoveType, Orientation } from "@prisma/client"
|
||||
import { createSelectSchema } from "drizzle-zod"
|
||||
import { z } from "zod"
|
||||
import {
|
||||
accounts,
|
||||
chats,
|
||||
gamepins,
|
||||
games,
|
||||
hits,
|
||||
moves,
|
||||
sessions,
|
||||
ships,
|
||||
user_games,
|
||||
users,
|
||||
verificationTokens,
|
||||
} from "~/drizzle/schemas/Tables"
|
||||
import { gameState, moveType, orientation } from "~/drizzle/schemas/Types"
|
||||
|
||||
export const GameState = z.enum(gameState.enumValues)
|
||||
export const MoveType = z.enum(moveType.enumValues)
|
||||
export const Orientation = z.enum(orientation.enumValues)
|
||||
export type GameState = z.infer<typeof GameState>
|
||||
export type MoveType = z.infer<typeof MoveType>
|
||||
export type Orientation = z.infer<typeof Orientation>
|
||||
|
||||
export const usersSchema = createSelectSchema(users)
|
||||
export const accountsSchema = createSelectSchema(accounts)
|
||||
export const sessionsSchema = createSelectSchema(sessions)
|
||||
export const verificationTokensSchema = createSelectSchema(verificationTokens)
|
||||
export const gamesSchema = createSelectSchema(games)
|
||||
export const gamepinsSchema = createSelectSchema(gamepins)
|
||||
export const shipsSchema = createSelectSchema(ships)
|
||||
export const hitsSchema = createSelectSchema(hits)
|
||||
export const movesSchema = createSelectSchema(moves)
|
||||
export const chatsSchema = createSelectSchema(chats)
|
||||
export const user_gamesSchema = createSelectSchema(user_games)
|
||||
|
||||
export const PlayerSchema = z
|
||||
.object({
|
||||
|
@ -17,10 +50,10 @@ export const PlayerSchema = z
|
|||
moves: z
|
||||
.object({
|
||||
index: z.number(),
|
||||
type: z.nativeEnum(MoveType),
|
||||
type: MoveType,
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
orientation: z.nativeEnum(Orientation),
|
||||
orientation: Orientation,
|
||||
})
|
||||
.array(),
|
||||
ships: z
|
||||
|
@ -29,7 +62,7 @@ export const PlayerSchema = z
|
|||
variant: z.number(),
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
orientation: z.nativeEnum(Orientation),
|
||||
orientation: Orientation,
|
||||
})
|
||||
.array(),
|
||||
hits: z
|
||||
|
@ -48,7 +81,7 @@ export const CreateSchema = z.object({
|
|||
game: z
|
||||
.object({
|
||||
id: z.string(),
|
||||
state: z.nativeEnum(GameState),
|
||||
state: GameState,
|
||||
allowSpectators: z.boolean(),
|
||||
allowSpecials: z.boolean(),
|
||||
allowChat: z.boolean(),
|
||||
|
|
|
@ -1,11 +1,16 @@
|
|||
import { getSession } from "@auth/solid-start"
|
||||
import { Game } from "@prisma/client"
|
||||
import { eq } from "drizzle-orm"
|
||||
import { APIEvent } from "solid-start"
|
||||
import { z } from "zod"
|
||||
import db from "~/drizzle"
|
||||
import { games } from "~/drizzle/schemas/Tables"
|
||||
import { rejectionErrors } from "~/lib/backend/errors"
|
||||
import sendResponse from "~/lib/backend/sendResponse"
|
||||
import prisma from "~/lib/prisma"
|
||||
import { gamesSchema } from "~/lib/zodSchemas"
|
||||
import { authOptions } from "~/server/auth"
|
||||
|
||||
type Game = z.infer<typeof gamesSchema>
|
||||
|
||||
interface Data {
|
||||
game: Game
|
||||
}
|
||||
|
@ -20,19 +25,14 @@ export async function GET({ request }: APIEvent) {
|
|||
return sendResponse(request, rejectionErrors.unauthorized)
|
||||
}
|
||||
|
||||
let game: Game | null
|
||||
switch (request.method) {
|
||||
case "DELETE":
|
||||
game = await prisma.game.delete({
|
||||
where: { id: gameId },
|
||||
})
|
||||
break
|
||||
let game: Game | undefined
|
||||
|
||||
default:
|
||||
game = await prisma.game.findFirst({
|
||||
where: { id: gameId },
|
||||
})
|
||||
}
|
||||
if (request.method === "DELETE")
|
||||
game = (await db.delete(games).where(eq(games.id, gameId)).returning())[0]
|
||||
else
|
||||
game = await db.query.games.findFirst({
|
||||
where: (game) => eq(game.id, gameId),
|
||||
})
|
||||
|
||||
if (!game) {
|
||||
return sendResponse(request, rejectionErrors.gameNotFound)
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { getSession } from "@auth/solid-start"
|
||||
import { eq } from "drizzle-orm"
|
||||
import { APIEvent } from "solid-start"
|
||||
import db from "~/drizzle"
|
||||
import { chats, gamepins, games, user_games } from "~/drizzle/schemas/Tables"
|
||||
import { rejectionErrors } from "~/lib/backend/errors"
|
||||
import sendResponse from "~/lib/backend/sendResponse"
|
||||
import prisma from "~/lib/prisma"
|
||||
import { authOptions } from "~/server/auth"
|
||||
import { composeBody, gameSelects, getAnyRunningGame } from "./running"
|
||||
import { composeBody, gameSelects, getRunningGameToUser } from "./running"
|
||||
|
||||
export async function POST({ request }: APIEvent) {
|
||||
const session = await getSession(request, authOptions)
|
||||
|
@ -21,36 +23,32 @@ export async function POST({ request }: APIEvent) {
|
|||
|
||||
const created = false
|
||||
|
||||
let game = await getAnyRunningGame(id)
|
||||
let game = await getRunningGameToUser(id)
|
||||
if (game) {
|
||||
return sendResponse(request, {
|
||||
redirectUrl: "/api/game/running",
|
||||
message: "Running game already exists.",
|
||||
})
|
||||
} else {
|
||||
game = await prisma.game.create({
|
||||
data: {
|
||||
gamePin: {
|
||||
create: {
|
||||
pin,
|
||||
},
|
||||
},
|
||||
users: {
|
||||
create: {
|
||||
userId: id,
|
||||
index: 0,
|
||||
chats: {
|
||||
create: {
|
||||
event: "created",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
const gameId = (await db.insert(games).values({}).returning())[0].id
|
||||
const user_Game = (
|
||||
await db
|
||||
.insert(user_games)
|
||||
.values({ gameId, userId: id, index: 0 })
|
||||
.returning()
|
||||
)[0]
|
||||
await db.insert(gamepins).values({ gameId, pin })
|
||||
await db
|
||||
.insert(chats)
|
||||
.values({ user_game_id: user_Game.id, event: "created" })
|
||||
game = await db.query.games.findFirst({
|
||||
where: eq(games.id, gameId),
|
||||
...gameSelects,
|
||||
})
|
||||
}
|
||||
|
||||
if (!game) return
|
||||
|
||||
const body = composeBody(game)
|
||||
|
||||
return sendResponse(request, {
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
import { getSession } from "@auth/solid-start"
|
||||
import { and, eq, exists, inArray, ne } from "drizzle-orm"
|
||||
import { APIEvent } from "solid-start"
|
||||
import db from "~/drizzle"
|
||||
import { user_games, users } from "~/drizzle/schemas/Tables"
|
||||
import { rejectionErrors } from "~/lib/backend/errors"
|
||||
import getPinFromBody from "~/lib/backend/getPinFromBody"
|
||||
import logging from "~/lib/backend/logging"
|
||||
import sendError from "~/lib/backend/sendError"
|
||||
import sendResponse from "~/lib/backend/sendResponse"
|
||||
import prisma from "~/lib/prisma"
|
||||
import { authOptions } from "~/server/auth"
|
||||
import { composeBody, gameSelects } from "./running"
|
||||
import { composeBody, gameSelects, getGameById } from "./running"
|
||||
|
||||
export async function POST({ request }: APIEvent) {
|
||||
const session = await getSession(request, authOptions)
|
||||
|
@ -20,14 +22,11 @@ export async function POST({ request }: APIEvent) {
|
|||
const { email, id } = session.user
|
||||
|
||||
try {
|
||||
const game = await prisma.game.findFirst({
|
||||
where: {
|
||||
gamePin: {
|
||||
pin,
|
||||
},
|
||||
},
|
||||
const gamePin = await db.query.gamepins.findFirst({
|
||||
where: (gamePin) => eq(gamePin.pin, pin ?? ""),
|
||||
with: { game: true },
|
||||
})
|
||||
if (!game) {
|
||||
if (!gamePin?.game) {
|
||||
return sendResponse(request, {
|
||||
message: "Spiel existiert nicht",
|
||||
statusCode: 404,
|
||||
|
@ -35,20 +34,28 @@ export async function POST({ request }: APIEvent) {
|
|||
})
|
||||
}
|
||||
|
||||
const games = await prisma.game.findMany({
|
||||
where: {
|
||||
NOT: {
|
||||
state: "ended",
|
||||
},
|
||||
users: {
|
||||
some: {
|
||||
userId: id,
|
||||
},
|
||||
},
|
||||
},
|
||||
let game = await db.query.games.findFirst({
|
||||
where: (game) =>
|
||||
and(
|
||||
ne(game.state, "ended"),
|
||||
exists(
|
||||
db
|
||||
.select()
|
||||
.from(user_games)
|
||||
.where(
|
||||
inArray(
|
||||
user_games.userId,
|
||||
db
|
||||
.select({ data: users.id })
|
||||
.from(users)
|
||||
.where(eq(users.id, id)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
...gameSelects,
|
||||
})
|
||||
if (games.length) {
|
||||
if (!game) {
|
||||
return sendResponse(request, {
|
||||
message: "Spieler ist bereits in Spiel!",
|
||||
redirectUrl: "/api/game/running",
|
||||
|
@ -56,18 +63,22 @@ export async function POST({ request }: APIEvent) {
|
|||
})
|
||||
}
|
||||
|
||||
const user_Game = await prisma.user_Game.create({
|
||||
data: {
|
||||
gameId: game.id,
|
||||
userId: id,
|
||||
index: 1,
|
||||
},
|
||||
select: {
|
||||
game: gameSelects,
|
||||
},
|
||||
})
|
||||
const gameId = (
|
||||
await db
|
||||
.insert(user_games)
|
||||
.values({
|
||||
gameId: game.id,
|
||||
userId: id,
|
||||
index: 1,
|
||||
})
|
||||
.returning()
|
||||
)[0].gameId
|
||||
|
||||
const body = composeBody(user_Game.game)
|
||||
game = await getGameById(gameId)
|
||||
|
||||
if (!game) return
|
||||
|
||||
const body = composeBody(game)
|
||||
|
||||
return sendResponse(request, {
|
||||
message: `User <${email}> joined game: ${game.id}`,
|
||||
|
|
|
@ -1,31 +1,37 @@
|
|||
import { getSession } from "@auth/solid-start"
|
||||
import { type APIEvent } from "solid-start/api"
|
||||
import { and, eq, exists, ne } from "drizzle-orm"
|
||||
import { APIEvent } from "solid-start/api"
|
||||
import db from "~/drizzle"
|
||||
import { games, user_games, users } from "~/drizzle/schemas/Tables"
|
||||
import { rejectionErrors } from "~/lib/backend/errors"
|
||||
import sendResponse from "~/lib/backend/sendResponse"
|
||||
import { getPayloadwithChecksum } from "~/lib/getPayloadwithChecksum"
|
||||
import prisma from "~/lib/prisma"
|
||||
import { GamePropsSchema } from "~/lib/zodSchemas"
|
||||
import { authOptions } from "~/server/auth"
|
||||
|
||||
export const gameSelects = {
|
||||
select: {
|
||||
columns: {
|
||||
id: true,
|
||||
allowChat: true,
|
||||
allowMarkDraw: true,
|
||||
allowSpecials: true,
|
||||
allowSpectators: true,
|
||||
state: true,
|
||||
},
|
||||
with: {
|
||||
gamePin: {
|
||||
select: {
|
||||
columns: {
|
||||
pin: true,
|
||||
},
|
||||
},
|
||||
users: {
|
||||
select: {
|
||||
columns: {
|
||||
id: true,
|
||||
index: true,
|
||||
},
|
||||
with: {
|
||||
chats: {
|
||||
select: {
|
||||
columns: {
|
||||
id: true,
|
||||
event: true,
|
||||
message: true,
|
||||
|
@ -33,7 +39,7 @@ export const gameSelects = {
|
|||
},
|
||||
},
|
||||
moves: {
|
||||
select: {
|
||||
columns: {
|
||||
index: true,
|
||||
type: true,
|
||||
x: true,
|
||||
|
@ -42,7 +48,7 @@ export const gameSelects = {
|
|||
},
|
||||
},
|
||||
ships: {
|
||||
select: {
|
||||
columns: {
|
||||
size: true,
|
||||
variant: true,
|
||||
x: true,
|
||||
|
@ -51,14 +57,14 @@ export const gameSelects = {
|
|||
},
|
||||
},
|
||||
hits: {
|
||||
select: {
|
||||
columns: {
|
||||
x: true,
|
||||
y: true,
|
||||
hit: true,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
select: {
|
||||
columns: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
|
@ -66,40 +72,33 @@ export const gameSelects = {
|
|||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
} as const
|
||||
|
||||
export const getAnyGame = (gameId: string) => {
|
||||
const game = prisma.game.findFirst({
|
||||
where: {
|
||||
NOT: {
|
||||
state: "ended",
|
||||
},
|
||||
id: gameId,
|
||||
},
|
||||
export const getGameById = async (gameId: string) => {
|
||||
return db.query.games.findFirst({
|
||||
where: and(ne(games.state, "ended"), eq(games.id, gameId)),
|
||||
...gameSelects,
|
||||
})
|
||||
return game
|
||||
}
|
||||
|
||||
export const getAnyRunningGame = (userId: string) => {
|
||||
const game = prisma.game.findFirst({
|
||||
where: {
|
||||
NOT: {
|
||||
state: "ended",
|
||||
},
|
||||
users: {
|
||||
some: {
|
||||
userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
export const getRunningGameToUser = async (userId: string) => {
|
||||
return db.query.games.findFirst({
|
||||
where: (game) =>
|
||||
and(
|
||||
ne(game.state, "ended"),
|
||||
exists(
|
||||
db
|
||||
.select()
|
||||
.from(user_games)
|
||||
.where(exists(db.select().from(users).where(eq(users.id, userId)))),
|
||||
),
|
||||
),
|
||||
...gameSelects,
|
||||
})
|
||||
return game
|
||||
}
|
||||
|
||||
export function composeBody(
|
||||
gameDB: NonNullable<Awaited<ReturnType<typeof getAnyRunningGame>>>,
|
||||
gameDB: NonNullable<Awaited<ReturnType<typeof getRunningGameToUser>>>,
|
||||
): GamePropsSchema {
|
||||
const { gamePin, ...game } = gameDB
|
||||
const users = gameDB.users
|
||||
|
@ -132,7 +131,7 @@ export async function GET({ request }: APIEvent) {
|
|||
|
||||
const { email, id } = session.user
|
||||
|
||||
const game = await getAnyRunningGame(id)
|
||||
const game = await getRunningGameToUser(id)
|
||||
|
||||
if (!game)
|
||||
return sendResponse(request, {
|
||||
|
|
|
@ -1,34 +1,39 @@
|
|||
import { getSession } from "@auth/solid-start"
|
||||
import colors from "colors"
|
||||
import { and, eq } from "drizzle-orm"
|
||||
import status from "http-status"
|
||||
import { Server } from "socket.io"
|
||||
import { RequestWithSocket, sServer } from "~/interfaces/NextApiSocket"
|
||||
import { APIEvent } from "solid-start"
|
||||
import db from "~/drizzle"
|
||||
import { games, moves, ships, user_games } from "~/drizzle/schemas/Tables"
|
||||
import { ResponseWithSocket, sServer } from "~/interfaces/NextApiSocket"
|
||||
import logging from "~/lib/backend/logging"
|
||||
import prisma from "~/lib/prisma"
|
||||
import { GamePropsSchema } from "~/lib/zodSchemas"
|
||||
import { authOptions } from "~/server/auth"
|
||||
import {
|
||||
composeBody,
|
||||
gameSelects,
|
||||
getAnyGame,
|
||||
getAnyRunningGame,
|
||||
getGameById,
|
||||
getRunningGameToUser,
|
||||
} from "./game/running"
|
||||
|
||||
colors.enable()
|
||||
|
||||
export async function GET({ request }: { request: RequestWithSocket }) {
|
||||
if (request.socket.server.io) {
|
||||
const res = new Response() as ResponseWithSocket
|
||||
|
||||
export async function GET({ request }: APIEvent) {
|
||||
if (res.socket.server.io) {
|
||||
logging("Socket is already running " + request.url, ["infoCyan"], request)
|
||||
} else {
|
||||
logging("Socket is initializing " + request.url, ["infoCyan"], request)
|
||||
const io: sServer = new Server(request.socket.server, {
|
||||
const io: sServer = new Server(res.socket.server, {
|
||||
path: "/api/ws",
|
||||
cors: {
|
||||
origin: "https://leaky-ships.mal-noh.de",
|
||||
},
|
||||
})
|
||||
|
||||
request.socket.server.io = io
|
||||
res.socket.server.io = io
|
||||
|
||||
// io.use(authenticate)
|
||||
io.use(async (socket, next) => {
|
||||
|
@ -38,7 +43,7 @@ export async function GET({ request }: { request: RequestWithSocket }) {
|
|||
if (!session) return next(new Error(status["401"]))
|
||||
socket.data.user = session.user
|
||||
|
||||
const game = await getAnyRunningGame(socket.data.user?.id ?? "")
|
||||
const game = await getRunningGameToUser(socket.data.user?.id ?? "")
|
||||
if (!game) {
|
||||
logging(
|
||||
"Forbidden, no game found: " +
|
||||
|
@ -82,63 +87,74 @@ export async function GET({ request }: { request: RequestWithSocket }) {
|
|||
)
|
||||
|
||||
socket.on("update", async (cb) => {
|
||||
const game = await getAnyGame(socket.data.gameId ?? "")
|
||||
const game = await getGameById(socket.data.gameId ?? "")
|
||||
if (!game) return
|
||||
const body = composeBody(game)
|
||||
cb(body)
|
||||
})
|
||||
|
||||
socket.on("gameSetting", async (payload, cb) => {
|
||||
const game = await prisma.game.update({
|
||||
where: { id: socket.data.gameId ?? "" },
|
||||
data: payload,
|
||||
...gameSelects,
|
||||
})
|
||||
const game = await db
|
||||
.update(games)
|
||||
.set(payload)
|
||||
.where(eq(games.id, socket.data.gameId))
|
||||
.returning()
|
||||
.then((updatedGame) =>
|
||||
db.query.games.findFirst({
|
||||
where: eq(games.id, updatedGame[0].id),
|
||||
...gameSelects,
|
||||
}),
|
||||
)
|
||||
if (!game) return
|
||||
const { hash } = composeBody(game)
|
||||
if (!hash) return
|
||||
cb(hash)
|
||||
socket.to(game.id).emit("gameSetting", payload, hash)
|
||||
socket.to(game?.id).emit("gameSetting", payload, hash)
|
||||
})
|
||||
|
||||
socket.on("ping", (callback) => callback())
|
||||
|
||||
socket.on("leave", async (cb) => {
|
||||
if (!socket.data.gameId || !socket.data.user?.id) return cb(false)
|
||||
const user_Game = await prisma.user_Game.delete({
|
||||
where: {
|
||||
gameId_userId: {
|
||||
gameId: socket.data.gameId,
|
||||
userId: socket.data.user?.id,
|
||||
},
|
||||
},
|
||||
})
|
||||
const enemy = await prisma.user_Game.findFirst({
|
||||
where: {
|
||||
gameId: socket.data.gameId,
|
||||
},
|
||||
const user_Game = await db
|
||||
.delete(user_games)
|
||||
.where(
|
||||
and(
|
||||
eq(user_games.gameId, socket.data.gameId),
|
||||
eq(user_games.userId, socket.data.user?.id ?? ""),
|
||||
),
|
||||
)
|
||||
.returning()
|
||||
if (!user_Game) return
|
||||
const enemy = await db.query.user_games.findFirst({
|
||||
where: eq(user_games.gameId, socket.data.gameId),
|
||||
})
|
||||
let body: GamePropsSchema
|
||||
if (user_Game.index === 1 && enemy) {
|
||||
const { game } = await prisma.user_Game.update({
|
||||
where: {
|
||||
gameId_index: {
|
||||
gameId: socket.data.gameId,
|
||||
index: 2,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
if (user_Game[0].index === 1 && enemy) {
|
||||
const game = await db
|
||||
.update(user_games)
|
||||
.set({
|
||||
index: 1,
|
||||
},
|
||||
select: {
|
||||
game: { ...gameSelects },
|
||||
},
|
||||
})
|
||||
})
|
||||
.where(
|
||||
and(
|
||||
eq(user_games.gameId, socket.data.gameId),
|
||||
eq(user_games.index, 2),
|
||||
),
|
||||
)
|
||||
.returning()
|
||||
|
||||
.then((user_Game) =>
|
||||
db.query.games.findFirst({
|
||||
where: eq(games.id, user_Game[0].gameId),
|
||||
...gameSelects,
|
||||
}),
|
||||
)
|
||||
if (!game) return
|
||||
body = composeBody(game)
|
||||
} else {
|
||||
const game = await prisma.game.findUnique({
|
||||
where: {
|
||||
id: socket.data.gameId,
|
||||
},
|
||||
const game = await db.query.games.findFirst({
|
||||
where: eq(games.id, socket.data.gameId),
|
||||
...gameSelects,
|
||||
})
|
||||
if (!game) return cb(false)
|
||||
|
@ -156,11 +172,7 @@ export async function GET({ request }: { request: RequestWithSocket }) {
|
|||
cb(true)
|
||||
|
||||
if (!payload.users.length) {
|
||||
await prisma.game.delete({
|
||||
where: {
|
||||
id: socket.data.gameId,
|
||||
},
|
||||
})
|
||||
await db.delete(games).where(eq(games.id, socket.data.gameId))
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -200,41 +212,42 @@ export async function GET({ request }: { request: RequestWithSocket }) {
|
|||
|
||||
socket.on("gameState", async (newState) => {
|
||||
if (socket.data.index !== 0 || !socket.data.gameId) return
|
||||
await prisma.game.update({
|
||||
where: { id: socket.data.gameId },
|
||||
data: {
|
||||
await db
|
||||
.update(games)
|
||||
.set({
|
||||
state: newState,
|
||||
},
|
||||
})
|
||||
})
|
||||
.where(eq(games.id, socket.data.gameId))
|
||||
io.to(socket.data.gameId).emit("gameState", newState)
|
||||
if (newState === "running")
|
||||
io.to(socket.data.gameId).emit("activeIndex", 0)
|
||||
})
|
||||
|
||||
socket.on("ships", async (ships) => {
|
||||
socket.on("ships", async (shipsData) => {
|
||||
if (
|
||||
!socket.data.gameId ||
|
||||
!socket.data.user?.id ||
|
||||
typeof socket.data.index === "undefined"
|
||||
)
|
||||
return
|
||||
await prisma.user_Game.update({
|
||||
where: {
|
||||
gameId_userId: {
|
||||
gameId: socket.data.gameId,
|
||||
userId: socket.data.user.id,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
ships: {
|
||||
deleteMany: {},
|
||||
createMany: {
|
||||
data: ships,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
const user_Game = await db.query.user_games.findFirst({
|
||||
where: and(
|
||||
eq(user_games.gameId, socket.data.gameId),
|
||||
eq(user_games.userId, socket.data.user?.id ?? ""),
|
||||
),
|
||||
})
|
||||
socket.to(socket.data.gameId).emit("ships", ships, socket.data.index)
|
||||
|
||||
if (!user_Game) return
|
||||
await db
|
||||
.insert(ships)
|
||||
.values(
|
||||
shipsData.map((ship) => ({ ...ship, user_game_id: user_Game.id })),
|
||||
)
|
||||
|
||||
socket
|
||||
.to(socket.data.gameId)
|
||||
.emit("ships", shipsData, socket.data.index)
|
||||
})
|
||||
|
||||
socket.on("dispatchMove", async (props) => {
|
||||
|
@ -244,23 +257,22 @@ export async function GET({ request }: { request: RequestWithSocket }) {
|
|||
typeof socket.data.index === "undefined"
|
||||
)
|
||||
return
|
||||
const user_Game = await prisma.user_Game
|
||||
.update({
|
||||
where: {
|
||||
gameId_userId: {
|
||||
gameId: socket.data.gameId,
|
||||
userId: socket.data.user?.id,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
moves: {
|
||||
create: props,
|
||||
},
|
||||
},
|
||||
select: { game: gameSelects },
|
||||
})
|
||||
.catch((e) => console.log(e, props))
|
||||
|
||||
const user_Game = await db.query.user_games.findFirst({
|
||||
where: (uG) =>
|
||||
and(
|
||||
eq(uG.gameId, socket.data.gameId),
|
||||
eq(uG.userId, socket.data.user?.id ?? ""),
|
||||
),
|
||||
with: { game: gameSelects },
|
||||
})
|
||||
|
||||
if (!user_Game?.game) return
|
||||
await db
|
||||
.insert(moves)
|
||||
.values({ ...props, user_game_id: user_Game.id })
|
||||
.returning()
|
||||
|
||||
const game = user_Game.game
|
||||
const l1 = game.users[0].moves.length
|
||||
const l2 = game.users[1].moves.length
|
||||
|
@ -286,4 +298,5 @@ export async function GET({ request }: { request: RequestWithSocket }) {
|
|||
})
|
||||
})
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import AzureADProvider from "@auth/core/providers/azure-ad"
|
||||
import EmailProvider from "@auth/core/providers/email"
|
||||
import { PrismaAdapter } from "@auth/prisma-adapter"
|
||||
import { DrizzleAdapter } from "@auth/drizzle-adapter"
|
||||
import { type SolidAuthConfig } from "@auth/solid-start"
|
||||
import {
|
||||
animals,
|
||||
|
@ -8,7 +8,7 @@ import {
|
|||
NumberDictionary,
|
||||
uniqueNamesGenerator,
|
||||
} from "unique-names-generator"
|
||||
import prisma from "~/lib/prisma"
|
||||
import db from "~/drizzle"
|
||||
|
||||
const numberDictionary = NumberDictionary.generate({ min: 0, max: 9999 })
|
||||
const customConfig: Config = {
|
||||
|
@ -31,7 +31,7 @@ export const authOptions: SolidAuthConfig = {
|
|||
tenantId: process.env.AZURE_AD_TENANT_ID,
|
||||
}),
|
||||
],
|
||||
adapter: PrismaAdapter(prisma),
|
||||
adapter: DrizzleAdapter(db),
|
||||
secret: process.env.AUTH_SECRET,
|
||||
callbacks: {
|
||||
signIn: ({ user, account }) => {
|
||||
|
|
|
@ -7,5 +7,4 @@ export default defineConfig({
|
|||
host: "0.0.0.0",
|
||||
strictPort: true,
|
||||
},
|
||||
ssr: { external: ["@prisma/client"] },
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue