Compare commits
57
Commits
57e3595c0b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a433f57a58
|
||
|
|
c205c1bdaf
|
||
|
|
ffe3d99a9f
|
||
|
|
de189bb7b7
|
||
|
|
c80a8465a7
|
||
|
|
b0dfab3b6a
|
||
|
|
4a12643098
|
||
|
|
b35f0da493
|
||
|
|
626fc4e6df
|
||
|
|
11c6017429
|
||
|
|
f9b0098375
|
||
|
|
4069648732
|
||
|
|
d7befe30ca
|
||
|
|
5aa3ed5820
|
||
|
|
ba492caca4
|
||
|
|
d7da88fc90
|
||
|
|
1b78f36a8a
|
||
|
|
c19f2f533a
|
||
|
|
48bb6bef76
|
||
|
|
67034897da
|
||
|
|
fbb44e42ad
|
||
|
|
f3e9077dd3
|
||
|
|
736d2fe9a6
|
||
|
|
bab60740d2
|
||
|
|
dffd9aa3c5
|
||
|
|
61c1dba9df
|
||
|
|
aa296ab53d
|
||
|
|
3d8153069d
|
||
|
|
b2aa8d6e8e
|
||
|
|
f1a9df30bc
|
||
|
|
36865fd1df
|
||
|
|
37266c1dd0
|
||
|
|
46f8c45f53
|
||
|
|
1d4f274f58
|
||
|
|
c65974ff43
|
||
|
|
ae40455c5a
|
||
|
|
ba51412592
|
||
|
|
5ba9b364d0
|
||
|
|
414f8f6cec
|
||
|
|
ad2b6a0bbb
|
||
|
|
53c5642b4e
|
||
|
|
3653c671f2
|
||
|
|
da0a38eec3
|
||
|
|
9600a8ea6b
|
||
|
|
a186243b26
|
||
|
|
5b40359cb8
|
||
|
|
7a427cb730
|
||
|
|
a2daf2bbfc
|
||
|
|
b8a3de36a6
|
||
|
|
5c9b4f9910
|
||
|
|
fcdee21ab5
|
||
|
|
02bad685da
|
||
|
|
29a7903d6c
|
||
|
|
9caea847ec
|
||
|
|
2c199339e0 | ||
|
|
8ecfbf5f39 | ||
|
|
9c54a4583b |
No files matched your search
+3
-4
@@ -1,11 +1,10 @@
|
|||||||
GAMES_DB_HOST=
|
DB_HOST=
|
||||||
GAMES_DB_PORT=
|
DB_PORT=
|
||||||
GAMES_DB_USER=
|
GAMES_DB_USER=
|
||||||
GAMES_DB_PASS=
|
GAMES_DB_PASS=
|
||||||
GAMES_DB_NAME=
|
GAMES_DB_NAME=
|
||||||
BERRYDASH_DB_HOST=
|
|
||||||
BERRYDASH_DB_PORT=
|
|
||||||
BERRYDASH_DB_USER=
|
BERRYDASH_DB_USER=
|
||||||
BERRYDASH_DB_PASS=
|
BERRYDASH_DB_PASS=
|
||||||
BERRYDASH_DB_NAME=
|
BERRYDASH_DB_NAME=
|
||||||
TURNSTILE_SECRET_KEY=
|
TURNSTILE_SECRET_KEY=
|
||||||
|
PRIVATE_SIGNING_KEY=
|
||||||
@@ -4,6 +4,10 @@ The server code for Lncvrt Games!
|
|||||||
|
|
||||||
You **must** have Bun installed, install it [here](https://bun.com/)
|
You **must** have Bun installed, install it [here](https://bun.com/)
|
||||||
|
|
||||||
## Running
|
## Building
|
||||||
|
|
||||||
Run `bun start`, if you are modifying code, run `bun dev`.
|
Run `bun run build` to build. Then run `bun run start` to start the server.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
Run `bun run dev`. That will start a server that will auto reload on file change (note: not as performant as running bun run build, if you need that)
|
||||||
@@ -1,89 +1,92 @@
|
|||||||
{
|
{
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 2,
|
||||||
"configVersion": 1,
|
"configVersion": 1,
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"": {
|
"": {
|
||||||
"name": "lncvrt-games-api",
|
"name": "lncvrt-games-api",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@elysiajs/cors": "1.4.1",
|
"@elysiajs/cors": "1.4.2",
|
||||||
"@elysiajs/swagger": "1.3.1",
|
"@elysiajs/swagger": "1.3.1",
|
||||||
"axios": "1.13.5",
|
"axios": "1.20.0",
|
||||||
"bcryptjs": "3.0.3",
|
"bcryptjs": "3.0.3",
|
||||||
"crypto": "1.0.1",
|
"dotenv": "18.0.5",
|
||||||
"dotenv": "17.3.1",
|
"drizzle-orm": "0.45.3",
|
||||||
"drizzle-orm": "0.45.1",
|
"elysia": "1.4.30",
|
||||||
"elysia": "1.4.25",
|
"image-size": "2.0.4",
|
||||||
"image-size": "2.0.2",
|
"mysql2": "3.24.5",
|
||||||
"mysql2": "3.17.2",
|
"nodemailer": "10.0.13",
|
||||||
"nodemailer": "8.0.1",
|
"sharp": "0.35.5",
|
||||||
"sharp": "0.34.5",
|
"validator": "13.15.35",
|
||||||
"validator": "13.15.26",
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/nodemailer": "7.0.10",
|
"@types/nodemailer": "8.0.2",
|
||||||
"@types/validator": "13.15.10",
|
"@types/validator": "13.15.10",
|
||||||
"bun-types": "1.3.9",
|
"bun-types": "1.4.2",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
"@borewit/text-codec": ["@borewit/text-codec@0.2.1", "", {}, "sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw=="],
|
"@borewit/text-codec": ["@borewit/text-codec@0.2.2", "", {}, "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ=="],
|
||||||
|
|
||||||
"@elysiajs/cors": ["@elysiajs/cors@1.4.1", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-lQfad+F3r4mNwsxRKbXyJB8Jg43oAOXjRwn7sKUL6bcOW3KjUqUimTS+woNpO97efpzjtDE0tEjGk9DTw8lqTQ=="],
|
"@elysiajs/cors": ["@elysiajs/cors@1.4.2", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-FTCcbH35brTLigF1W7BYySRZomgI/dBEMK9BgK9RP9Nez7zmpGh4koL/Yr1BFv8nYz7CfhRvcM8d/c+XnwMaVQ=="],
|
||||||
|
|
||||||
"@elysiajs/swagger": ["@elysiajs/swagger@1.3.1", "", { "dependencies": { "@scalar/themes": "^0.9.52", "@scalar/types": "^0.0.12", "openapi-types": "^12.1.3", "pathe": "^1.1.2" }, "peerDependencies": { "elysia": ">= 1.3.0" } }, "sha512-LcbLHa0zE6FJKWPWKsIC/f+62wbDv3aXydqcNPVPyqNcaUgwvCajIi+5kHEU6GO3oXUCpzKaMsb3gsjt8sLzFQ=="],
|
"@elysiajs/swagger": ["@elysiajs/swagger@1.3.1", "", { "dependencies": { "@scalar/themes": "^0.9.52", "@scalar/types": "^0.0.12", "openapi-types": "^12.1.3", "pathe": "^1.1.2" }, "peerDependencies": { "elysia": ">= 1.3.0" } }, "sha512-LcbLHa0zE6FJKWPWKsIC/f+62wbDv3aXydqcNPVPyqNcaUgwvCajIi+5kHEU6GO3oXUCpzKaMsb3gsjt8sLzFQ=="],
|
||||||
|
|
||||||
"@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
|
"@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
|
||||||
|
|
||||||
"@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
|
"@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="],
|
||||||
|
|
||||||
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
|
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.3.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg=="],
|
||||||
|
|
||||||
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
|
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.3.4" }, "os": "darwin", "cpu": "x64" }, "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
|
"@img/sharp-freebsd-wasm32": ["@img/sharp-freebsd-wasm32@0.35.5", "", { "dependencies": { "@img/sharp-wasm32": "0.35.5" }, "os": "freebsd" }, "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
|
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.3.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
|
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.3.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
|
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.3.4", "", { "os": "linux", "cpu": "arm" }, "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
|
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.3.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
|
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.3.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
|
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.3.4", "", { "os": "linux", "cpu": "none" }, "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
|
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.3.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
|
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.3.4", "", { "os": "linux", "cpu": "x64" }, "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw=="],
|
||||||
|
|
||||||
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
|
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.3.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA=="],
|
||||||
|
|
||||||
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
|
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.3.4", "", { "os": "linux", "cpu": "x64" }, "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg=="],
|
||||||
|
|
||||||
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
|
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.3.4" }, "os": "linux", "cpu": "arm" }, "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ=="],
|
||||||
|
|
||||||
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
|
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.3.4" }, "os": "linux", "cpu": "arm64" }, "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ=="],
|
||||||
|
|
||||||
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
|
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.3.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA=="],
|
||||||
|
|
||||||
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
|
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.3.4" }, "os": "linux", "cpu": "none" }, "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ=="],
|
||||||
|
|
||||||
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
|
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.3.4" }, "os": "linux", "cpu": "s390x" }, "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA=="],
|
||||||
|
|
||||||
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
|
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.3.4" }, "os": "linux", "cpu": "x64" }, "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog=="],
|
||||||
|
|
||||||
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
|
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" }, "os": "linux", "cpu": "arm64" }, "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg=="],
|
||||||
|
|
||||||
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
|
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.35.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.3.4" }, "os": "linux", "cpu": "x64" }, "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A=="],
|
||||||
|
|
||||||
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
|
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.35.5", "", { "dependencies": { "@emnapi/runtime": "^1.11.3" } }, "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ=="],
|
||||||
|
|
||||||
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
|
"@img/sharp-webcontainers-wasm32": ["@img/sharp-webcontainers-wasm32@0.35.5", "", { "dependencies": { "@img/sharp-wasm32": "0.35.5" }, "cpu": "none" }, "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA=="],
|
||||||
|
|
||||||
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
|
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.35.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q=="],
|
||||||
|
|
||||||
|
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.35.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A=="],
|
||||||
|
|
||||||
|
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.35.5", "", { "os": "win32", "cpu": "x64" }, "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg=="],
|
||||||
|
|
||||||
"@scalar/openapi-types": ["@scalar/openapi-types@0.1.1", "", {}, "sha512-NMy3QNk6ytcCoPUGJH0t4NNr36OWXgZhA3ormr3TvhX1NDgoF95wFyodGVH8xiHeUyn2/FxtETm8UBLbB5xEmg=="],
|
"@scalar/openapi-types": ["@scalar/openapi-types@0.1.1", "", {}, "sha512-NMy3QNk6ytcCoPUGJH0t4NNr36OWXgZhA3ormr3TvhX1NDgoF95wFyodGVH8xiHeUyn2/FxtETm8UBLbB5xEmg=="],
|
||||||
|
|
||||||
@@ -91,29 +94,31 @@
|
|||||||
|
|
||||||
"@scalar/types": ["@scalar/types@0.0.12", "", { "dependencies": { "@scalar/openapi-types": "0.1.1", "@unhead/schema": "^1.9.5" } }, "sha512-XYZ36lSEx87i4gDqopQlGCOkdIITHHEvgkuJFrXFATQs9zHARop0PN0g4RZYWj+ZpCUclOcaOjbCt8JGe22mnQ=="],
|
"@scalar/types": ["@scalar/types@0.0.12", "", { "dependencies": { "@scalar/openapi-types": "0.1.1", "@unhead/schema": "^1.9.5" } }, "sha512-XYZ36lSEx87i4gDqopQlGCOkdIITHHEvgkuJFrXFATQs9zHARop0PN0g4RZYWj+ZpCUclOcaOjbCt8JGe22mnQ=="],
|
||||||
|
|
||||||
"@sinclair/typebox": ["@sinclair/typebox@0.34.48", "", {}, "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA=="],
|
"@sinclair/typebox": ["@sinclair/typebox@0.34.52", "", {}, "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw=="],
|
||||||
|
|
||||||
"@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
|
"@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="],
|
||||||
|
|
||||||
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
"@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@25.2.3", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ=="],
|
"@types/node": ["@types/node@26.6.4", "", { "dependencies": { "undici-types": "~8.9.0" } }, "sha512-ldVPDCzj7fsaGZrLB0NuHuTvJcsNasysBAqMolr/cgxrLd1xbqxIr3XJiPnHHJUCxj5sNF1vnRj9aWnrVh5Jcg=="],
|
||||||
|
|
||||||
"@types/nodemailer": ["@types/nodemailer@7.0.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tP+9WggTFN22Zxh0XFyst7239H0qwiRCogsk7v9aQS79sYAJY+WEbTHbNYcxUMaalHKmsNpxmoTe35hBEMMd6g=="],
|
"@types/nodemailer": ["@types/nodemailer@8.0.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-c7M5ox8p0nEOfbJ2E9Qcmt8/QCu/VzsiAhzBiZbvky2PhKZDHpKB3sQHBM5MEZNkCfBOaS6S9//AGPRTNB7IaA=="],
|
||||||
|
|
||||||
"@types/validator": ["@types/validator@13.15.10", "", {}, "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA=="],
|
"@types/validator": ["@types/validator@13.15.10", "", {}, "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA=="],
|
||||||
|
|
||||||
"@unhead/schema": ["@unhead/schema@1.11.20", "", { "dependencies": { "hookable": "^5.5.3", "zhead": "^2.2.4" } }, "sha512-0zWykKAaJdm+/Y7yi/Yds20PrUK7XabLe9c3IRcjnwYmSWY6z0Cr19VIs3ozCj8P+GhR+/TI2mwtGlueCEYouA=="],
|
"@unhead/schema": ["@unhead/schema@1.11.20", "", { "dependencies": { "hookable": "^5.5.3", "zhead": "^2.2.4" } }, "sha512-0zWykKAaJdm+/Y7yi/Yds20PrUK7XabLe9c3IRcjnwYmSWY6z0Cr19VIs3ozCj8P+GhR+/TI2mwtGlueCEYouA=="],
|
||||||
|
|
||||||
|
"agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
|
||||||
|
|
||||||
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||||
|
|
||||||
"aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="],
|
"aws-ssl-profiles": ["aws-ssl-profiles@1.1.2", "", {}, "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g=="],
|
||||||
|
|
||||||
"axios": ["axios@1.13.5", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "sha512-cz4ur7Vb0xS4/KUN0tPWe44eqxrIu31me+fbang3ijiNscE129POzipJJA6zniq2C/Z6sJCjMimjS8Lc/GAs8Q=="],
|
"axios": ["axios@1.20.0", "", { "dependencies": { "follow-redirects": "^1.16.0", "form-data": "^4.0.6", "https-proxy-agent": "^5.0.1", "proxy-from-env": "^2.1.0" } }, "sha512-r8aOh8j9cGKpgQAqpzrUHnSIc6a59Y3Xf/cv8sy1DrHCkZHzQGEuoq1tARk6qSyDdtQGSDgpb9kFlruzPvrgwg=="],
|
||||||
|
|
||||||
"bcryptjs": ["bcryptjs@3.0.3", "", { "bin": { "bcrypt": "bin/bcrypt" } }, "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g=="],
|
"bcryptjs": ["bcryptjs@3.0.3", "", { "bin": { "bcrypt": "bin/bcrypt" } }, "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g=="],
|
||||||
|
|
||||||
"bun-types": ["bun-types@1.3.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg=="],
|
"bun-types": ["bun-types@1.4.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-bxV1FgK7yBIzjRe5zBozIM4Bem11ZJcCXSrjWRG3YWLt8yFDePu4cLjpebO8OvPeIE9trbyPF4fuj3Cia4Fj3w=="],
|
||||||
|
|
||||||
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
||||||
|
|
||||||
@@ -121,29 +126,25 @@
|
|||||||
|
|
||||||
"cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
|
"cookie": ["cookie@1.1.1", "", {}, "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ=="],
|
||||||
|
|
||||||
"crypto": ["crypto@1.0.1", "", {}, "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig=="],
|
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" }, "peerDependencies": { "supports-color": "*" }, "optionalPeers": ["supports-color"] }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||||
|
|
||||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
|
||||||
|
|
||||||
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
||||||
|
|
||||||
"denque": ["denque@2.1.0", "", {}, "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw=="],
|
|
||||||
|
|
||||||
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||||
|
|
||||||
"dotenv": ["dotenv@17.3.1", "", {}, "sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA=="],
|
"dotenv": ["dotenv@18.0.5", "", { "bin": { "dotenv": "dist/index.cjs" } }, "sha512-aBrGvt6KhjxbEnatqMWOMidftwsrCiCvqh1yNIGB9QyF0J+VcWkKDMsvYOEm7ZS82oiV+BT1sTOtIlAmUlTpwQ=="],
|
||||||
|
|
||||||
"drizzle-orm": ["drizzle-orm@0.45.1", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@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.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "sql.js", "sqlite3"] }, "sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA=="],
|
"drizzle-orm": ["drizzle-orm@0.45.3", "", { "peerDependencies": { "@aws-sdk/client-rds-data": ">=3", "@cloudflare/workers-types": ">=4", "@electric-sql/pglite": ">=0.2.0", "@libsql/client": ">=0.10.0", "@libsql/client-wasm": ">=0.10.0", "@neondatabase/serverless": ">=0.10.0", "@netlify/db": ">=0.4.0", "@op-engineering/op-sqlite": ">=2", "@opentelemetry/api": "^1.4.1", "@planetscale/database": ">=1.13", "@prisma/client": "*", "@tidbcloud/serverless": "*", "@types/better-sqlite3": "*", "@types/pg": "*", "@types/sql.js": "*", "@upstash/redis": ">=1.34.7", "@vercel/postgres": ">=0.8.0", "@xata.io/client": "*", "better-sqlite3": ">=7", "bun-types": "*", "expo-sqlite": ">=14.0.0", "gel": ">=2", "knex": "*", "kysely": "*", "mysql2": ">=2", "pg": ">=8", "postgres": ">=3", "prisma": "*", "sql.js": ">=1", "sqlite3": ">=5" }, "optionalPeers": ["@aws-sdk/client-rds-data", "@cloudflare/workers-types", "@electric-sql/pglite", "@libsql/client", "@libsql/client-wasm", "@neondatabase/serverless", "@netlify/db", "@op-engineering/op-sqlite", "@opentelemetry/api", "@planetscale/database", "@prisma/client", "@tidbcloud/serverless", "@types/better-sqlite3", "@types/pg", "@types/sql.js", "@upstash/redis", "@vercel/postgres", "@xata.io/client", "better-sqlite3", "bun-types", "expo-sqlite", "gel", "knex", "kysely", "mysql2", "pg", "postgres", "prisma", "sql.js", "sqlite3"] }, "sha512-CAloER21cDdcgZ1OmjrZX82EeRNsdP+y0onX/eyoYDaYzki/adrAa91lzM5jWh7zZPK4qUbw/6LGv9J+A+uizA=="],
|
||||||
|
|
||||||
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||||
|
|
||||||
"elysia": ["elysia@1.4.25", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.7", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-liKjavH99Gpzrv9cDil6uYWmPuqESfPFV1FIaFSd3iNqo3y7e29sN43VxFIK8tWWnyi6eDAmi2SZk8hNAMQMyg=="],
|
"elysia": ["elysia@1.4.30", "", { "dependencies": { "cookie": "^1.1.1", "exact-mirror": "^0.2.7", "fast-decode-uri-component": "^1.0.1", "memoirist": "^0.4.0" }, "peerDependencies": { "@sinclair/typebox": ">= 0.34.0 < 1", "@types/bun": ">= 1.2.0", "file-type": ">= 20.0.0", "openapi-types": ">= 12.0.0", "typescript": ">= 5.0.0" }, "optionalPeers": ["@types/bun", "typescript"] }, "sha512-S2qqV0CbM4faB1hQQ5IYoeYnAUinjHlzRduxaBc4OoNqh0GjOc8k6tt3hv5ozWcG6Svr6hugw6JL4zNke4jwfA=="],
|
||||||
|
|
||||||
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
||||||
|
|
||||||
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
||||||
|
|
||||||
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
|
"es-object-atoms": ["es-object-atoms@1.1.2", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw=="],
|
||||||
|
|
||||||
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
|
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
|
||||||
|
|
||||||
@@ -151,11 +152,11 @@
|
|||||||
|
|
||||||
"fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
|
"fast-decode-uri-component": ["fast-decode-uri-component@1.0.1", "", {}, "sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg=="],
|
||||||
|
|
||||||
"file-type": ["file-type@21.3.0", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.4", "token-types": "^6.1.1", "uint8array-extras": "^1.4.0" } }, "sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA=="],
|
"file-type": ["file-type@22.1.1", "", { "dependencies": { "@tokenizer/inflate": "^0.4.1", "strtok3": "^10.3.5", "token-types": "^6.1.2", "uint8array-extras": "^1.5.0" } }, "sha512-sEB0oStmeLGtpmSAD88RDNuLsvhv4iC3u0lE25CUvfCULvj49xoQ3l3K525Vn+ZzsZ6DOLajQCV6RmhwwhqiJg=="],
|
||||||
|
|
||||||
"follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="],
|
"follow-redirects": ["follow-redirects@1.16.1", "", { "peerDependencies": { "debug": "*" }, "optionalPeers": ["debug"] }, "sha512-FNvFGzoMLWmE6Yj9spb/zjd7yiNCHiAW9/Tg9CXrQ8wuu32HtlJOwWO11OJafl5FfY3DxTdQ0vj42zU1kvv5jg=="],
|
||||||
|
|
||||||
"form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="],
|
"form-data": ["form-data@4.0.6", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.4", "mime-types": "^2.1.35" } }, "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ=="],
|
||||||
|
|
||||||
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||||
|
|
||||||
@@ -171,21 +172,23 @@
|
|||||||
|
|
||||||
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
||||||
|
|
||||||
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
"hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
|
||||||
|
|
||||||
"hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
|
"hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="],
|
||||||
|
|
||||||
"iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
|
"https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
|
||||||
|
|
||||||
|
"iconv-lite": ["iconv-lite@0.7.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ=="],
|
||||||
|
|
||||||
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
"ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
|
||||||
|
|
||||||
"image-size": ["image-size@2.0.2", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w=="],
|
"image-size": ["image-size@2.0.4", "", { "bin": { "image-size": "bin/image-size.js" } }, "sha512-QRUkFFsRV/6fuESxb9Vkq+a0LkSrgKXuc2NEqfikiXxxN/G3tjWt5EVUlMaImRBZRZK/jRBEbYvpPYZL8t08Zw=="],
|
||||||
|
|
||||||
"is-property": ["is-property@1.0.2", "", {}, "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="],
|
"is-property": ["is-property@1.0.2", "", {}, "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g=="],
|
||||||
|
|
||||||
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
|
||||||
|
|
||||||
"lru.min": ["lru.min@1.1.4", "", {}, "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA=="],
|
"lru.min": ["lru.min@1.1.5", "", {}, "sha512-5J9ysMYUpYIg9RF2vJpy9SinEmSviFSe0GyPpCQ4L5QSkLAgeLXlTAOu2ZwWUU5m+0SBl6gUU1R1ZQB3aKypfA=="],
|
||||||
|
|
||||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||||
|
|
||||||
@@ -197,31 +200,29 @@
|
|||||||
|
|
||||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
"mysql2": ["mysql2@3.17.2", "", { "dependencies": { "aws-ssl-profiles": "^1.1.2", "denque": "^2.1.0", "generate-function": "^2.3.1", "iconv-lite": "^0.7.2", "long": "^5.3.2", "lru.min": "^1.1.3", "named-placeholders": "^1.1.6", "seq-queue": "^0.0.5", "sql-escaper": "^1.3.3" } }, "sha512-/tFCtdqk5V5Aowpnzshryxuxp63ti4I7kcp3yqAKgWmhYXEXs8+F/IbQ6JTMzQPYc+ElnnhmMD2SqUYLtRVcTQ=="],
|
"mysql2": ["mysql2@3.24.5", "", { "dependencies": { "aws-ssl-profiles": "^1.1.2", "generate-function": "^2.3.1", "iconv-lite": "^0.7.3", "long": "^5.3.2", "lru.min": "^1.1.4", "named-placeholders": "^1.1.6", "sql-escaper": "^1.5.1" }, "peerDependencies": { "@types/node": ">= 8" } }, "sha512-X6Ujsr2QSkkLpkQGjxzpKRAPn9nu4axpR63ntBzquFVEvPOArgbUQ1sJjFKI7hnaYtiVZxa17Z7q18KSubW0IQ=="],
|
||||||
|
|
||||||
"named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "^1.1.0" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="],
|
"named-placeholders": ["named-placeholders@1.1.6", "", { "dependencies": { "lru.min": "^1.1.0" } }, "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w=="],
|
||||||
|
|
||||||
"nanoid": ["nanoid@5.1.6", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg=="],
|
"nanoid": ["nanoid@5.1.16", "", { "bin": { "nanoid": "bin/nanoid.js" } }, "sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ=="],
|
||||||
|
|
||||||
"nodemailer": ["nodemailer@8.0.1", "", {}, "sha512-5kcldIXmaEjZcHR6F28IKGSgpmZHaF1IXLWFTG+Xh3S+Cce4MiakLtWY+PlBU69fLbRa8HlaGIrC/QolUpHkhg=="],
|
"nodemailer": ["nodemailer@10.0.13", "", {}, "sha512-SzG86OlvcW/NNhUFC6uROMwRTL4n7MswfQqC/T8mhkmnY1YVa23zUEMYi4ijSeXSl9GLz9ZeTJDUatEDuY5FeQ=="],
|
||||||
|
|
||||||
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
|
"openapi-types": ["openapi-types@12.1.3", "", {}, "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw=="],
|
||||||
|
|
||||||
"pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
|
"pathe": ["pathe@1.1.2", "", {}, "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ=="],
|
||||||
|
|
||||||
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
|
"proxy-from-env": ["proxy-from-env@2.1.0", "", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="],
|
||||||
|
|
||||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||||
|
|
||||||
"semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
"semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||||
|
|
||||||
"seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="],
|
"sharp": ["sharp@0.35.5", "", { "dependencies": { "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", "semver": "^7.8.5" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.35.5", "@img/sharp-darwin-x64": "0.35.5", "@img/sharp-freebsd-wasm32": "0.35.5", "@img/sharp-libvips-darwin-arm64": "1.3.4", "@img/sharp-libvips-darwin-x64": "1.3.4", "@img/sharp-libvips-linux-arm": "1.3.4", "@img/sharp-libvips-linux-arm64": "1.3.4", "@img/sharp-libvips-linux-ppc64": "1.3.4", "@img/sharp-libvips-linux-riscv64": "1.3.4", "@img/sharp-libvips-linux-s390x": "1.3.4", "@img/sharp-libvips-linux-x64": "1.3.4", "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", "@img/sharp-libvips-linuxmusl-x64": "1.3.4", "@img/sharp-linux-arm": "0.35.5", "@img/sharp-linux-arm64": "0.35.5", "@img/sharp-linux-ppc64": "0.35.5", "@img/sharp-linux-riscv64": "0.35.5", "@img/sharp-linux-s390x": "0.35.5", "@img/sharp-linux-x64": "0.35.5", "@img/sharp-linuxmusl-arm64": "0.35.5", "@img/sharp-linuxmusl-x64": "0.35.5", "@img/sharp-webcontainers-wasm32": "0.35.5", "@img/sharp-win32-arm64": "0.35.5", "@img/sharp-win32-ia32": "0.35.5", "@img/sharp-win32-x64": "0.35.5" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g=="],
|
||||||
|
|
||||||
"sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
|
"sql-escaper": ["sql-escaper@1.5.2", "", {}, "sha512-6CKD38c31SENivxOADeMNLdukOnUxUcflKtzVWzace7Riv1v7cAEym5Cx9Q7gYZ3ezIJI7ZpqecQq8cqNeSSFg=="],
|
||||||
|
|
||||||
"sql-escaper": ["sql-escaper@1.3.3", "", {}, "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw=="],
|
"strtok3": ["strtok3@10.3.5", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA=="],
|
||||||
|
|
||||||
"strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
|
|
||||||
|
|
||||||
"token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
|
"token-types": ["token-types@6.1.2", "", { "dependencies": { "@borewit/text-codec": "^0.2.1", "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww=="],
|
||||||
|
|
||||||
@@ -229,11 +230,11 @@
|
|||||||
|
|
||||||
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
|
"type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
|
||||||
|
|
||||||
"uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
|
"uint8array-extras": ["uint8array-extras@1.6.0", "", {}, "sha512-8iAasVS4wUx0gPLjH8Xtz2PeDzTSiy8QiLGu2DT3X5GU+egFEQhpnbtkehbAwjvDcxIERmCYcysiODFmE3Ud0Q=="],
|
||||||
|
|
||||||
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
"undici-types": ["undici-types@8.9.0", "", {}, "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg=="],
|
||||||
|
|
||||||
"validator": ["validator@13.15.26", "", {}, "sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA=="],
|
"validator": ["validator@13.15.35", "", {}, "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw=="],
|
||||||
|
|
||||||
"zhead": ["zhead@2.2.4", "", {}, "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag=="],
|
"zhead": ["zhead@2.2.4", "", {}, "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag=="],
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
-- https://www.phpmyadmin.net/
|
-- https://www.phpmyadmin.net/
|
||||||
--
|
--
|
||||||
-- Host: localhost
|
-- Host: localhost
|
||||||
-- Generation Time: Feb 21, 2026 at 09:07 PM
|
-- Generation Time: Mar 05, 2026 at 06:35 PM
|
||||||
-- Server version: 11.8.6-MariaDB-log
|
-- Server version: 11.8.6-MariaDB-log
|
||||||
-- PHP Version: 8.5.3
|
-- PHP Version: 8.5.3
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ CREATE TABLE `userposts` (
|
|||||||
--
|
--
|
||||||
ALTER TABLE `chatroom_reports`
|
ALTER TABLE `chatroom_reports`
|
||||||
ADD PRIMARY KEY (`id`),
|
ADD PRIMARY KEY (`id`),
|
||||||
ADD KEY `chatId` (`chatId`);
|
ADD KEY `chatroom_reports?chatId` (`chatId`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `chats`
|
-- Indexes for table `chats`
|
||||||
@@ -199,7 +199,7 @@ ALTER TABLE `userposts`
|
|||||||
-- Constraints for table `chatroom_reports`
|
-- Constraints for table `chatroom_reports`
|
||||||
--
|
--
|
||||||
ALTER TABLE `chatroom_reports`
|
ALTER TABLE `chatroom_reports`
|
||||||
ADD CONSTRAINT `chatId` FOREIGN KEY (`chatId`) REFERENCES `chats` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
ADD CONSTRAINT `chatroom_reports?chatId` FOREIGN KEY (`chatId`) REFERENCES `chats` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
|||||||
+89
-24
@@ -3,9 +3,9 @@
|
|||||||
-- https://www.phpmyadmin.net/
|
-- https://www.phpmyadmin.net/
|
||||||
--
|
--
|
||||||
-- Host: localhost
|
-- Host: localhost
|
||||||
-- Generation Time: Feb 22, 2026 at 03:13 PM
|
-- Generation Time: Apr 19, 2026 at 10:03 PM
|
||||||
-- Server version: 11.8.6-MariaDB-log
|
-- Server version: 10.11.14-MariaDB-0ubuntu0.24.04.1
|
||||||
-- PHP Version: 8.5.3
|
-- PHP Version: 8.3.30
|
||||||
|
|
||||||
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
|
||||||
START TRANSACTION;
|
START TRANSACTION;
|
||||||
@@ -23,6 +23,21 @@ SET time_zone = "+00:00";
|
|||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `files`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE `files` (
|
||||||
|
`id` bigint(20) NOT NULL,
|
||||||
|
`path` varchar(4096) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||||
|
`hash` char(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||||
|
`size` bigint(20) NOT NULL,
|
||||||
|
`host` int(1) NOT NULL DEFAULT 0,
|
||||||
|
`mimeType` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `games`
|
-- Table structure for table `games`
|
||||||
--
|
--
|
||||||
@@ -43,13 +58,11 @@ CREATE TABLE `games` (
|
|||||||
--
|
--
|
||||||
|
|
||||||
CREATE TABLE `launcherupdates` (
|
CREATE TABLE `launcherupdates` (
|
||||||
`id` varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
`id` bigint(20) NOT NULL,
|
||||||
`releaseDate` bigint(20) NOT NULL,
|
`version` varchar(32) NOT NULL,
|
||||||
`downloadUrls` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
`notes` text NOT NULL,
|
||||||
`platforms` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
`release_date` timestamp NOT NULL,
|
||||||
`hidden` tinyint(1) NOT NULL DEFAULT 1,
|
`download_data` text NOT NULL
|
||||||
`place` bigint(20) NOT NULL DEFAULT 0,
|
|
||||||
`sha512sums` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '[]'
|
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPRESSED;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPRESSED;
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
@@ -61,33 +74,48 @@ CREATE TABLE `launcherupdates` (
|
|||||||
CREATE TABLE `launcherversionmanifest` (
|
CREATE TABLE `launcherversionmanifest` (
|
||||||
`id` varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
`id` varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||||
`displayName` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
`displayName` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||||
|
`versionName` text NOT NULL,
|
||||||
|
`downloads` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '{}',
|
||||||
|
`executables` text NOT NULL DEFAULT '[]',
|
||||||
|
`modSupportDownloads` text NOT NULL DEFAULT '{}',
|
||||||
`releaseDate` bigint(20) NOT NULL,
|
`releaseDate` bigint(20) NOT NULL,
|
||||||
`downloadUrlVersion` text NOT NULL,
|
|
||||||
`downloadUrls` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
||||||
`platforms` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
||||||
`executables` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
|
||||||
`hidden` tinyint(1) NOT NULL DEFAULT 1,
|
`hidden` tinyint(1) NOT NULL DEFAULT 1,
|
||||||
`game` bigint(20) NOT NULL DEFAULT 0,
|
`game` bigint(20) NOT NULL DEFAULT 0,
|
||||||
`place` bigint(20) NOT NULL DEFAULT 0,
|
`place` bigint(20) NOT NULL DEFAULT 0,
|
||||||
`sha512sums` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '[]',
|
|
||||||
`sizes` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '[]',
|
|
||||||
`changelog` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
`changelog` text CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||||
`category` int(11) NOT NULL DEFAULT -1,
|
`category` int(11) NOT NULL DEFAULT -1,
|
||||||
`lastRevision` bigint(20) NOT NULL DEFAULT 0,
|
`lastRevision` bigint(20) NOT NULL DEFAULT 0,
|
||||||
`downloads` bigint(20) NOT NULL DEFAULT 0
|
`downloadCount` bigint(20) NOT NULL DEFAULT 0
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPRESSED;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPRESSED;
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `loaderupdates`
|
-- Table structure for table `mods`
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE TABLE `loaderupdates` (
|
CREATE TABLE `mods` (
|
||||||
`id` varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
`id` bigint(20) NOT NULL,
|
||||||
|
`name` text NOT NULL,
|
||||||
|
`creators` text NOT NULL DEFAULT '[]',
|
||||||
|
`description` text DEFAULT NULL,
|
||||||
|
`downloadCount` bigint(20) NOT NULL DEFAULT 0,
|
||||||
|
`hidden` tinyint(1) NOT NULL DEFAULT 1
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPRESSED;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `modversions`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE `modversions` (
|
||||||
|
`id` text NOT NULL,
|
||||||
|
`downloads` text NOT NULL DEFAULT '{}',
|
||||||
|
`gameVersion` varchar(24) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
|
||||||
`releaseDate` bigint(20) NOT NULL,
|
`releaseDate` bigint(20) NOT NULL,
|
||||||
`hidden` tinyint(1) NOT NULL DEFAULT 1,
|
`changelog` text DEFAULT NULL,
|
||||||
`place` bigint(20) NOT NULL DEFAULT 0
|
`hidden` tinyint(1) NOT NULL DEFAULT 1
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPRESSED;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPRESSED;
|
||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
@@ -142,6 +170,12 @@ CREATE TABLE `verifycodes` (
|
|||||||
-- Indexes for dumped tables
|
-- Indexes for dumped tables
|
||||||
--
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Indexes for table `files`
|
||||||
|
--
|
||||||
|
ALTER TABLE `files`
|
||||||
|
ADD PRIMARY KEY (`id`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `games`
|
-- Indexes for table `games`
|
||||||
--
|
--
|
||||||
@@ -162,11 +196,18 @@ ALTER TABLE `launcherversionmanifest`
|
|||||||
ADD KEY `fk_game` (`game`);
|
ADD KEY `fk_game` (`game`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `loaderupdates`
|
-- Indexes for table `mods`
|
||||||
--
|
--
|
||||||
ALTER TABLE `loaderupdates`
|
ALTER TABLE `mods`
|
||||||
ADD PRIMARY KEY (`id`);
|
ADD PRIMARY KEY (`id`);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Indexes for table `modversions`
|
||||||
|
--
|
||||||
|
ALTER TABLE `modversions`
|
||||||
|
ADD PRIMARY KEY (`id`(255)),
|
||||||
|
ADD KEY `fk_gameVersion` (`gameVersion`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `resetcodes`
|
-- Indexes for table `resetcodes`
|
||||||
--
|
--
|
||||||
@@ -189,12 +230,30 @@ ALTER TABLE `verifycodes`
|
|||||||
-- AUTO_INCREMENT for dumped tables
|
-- AUTO_INCREMENT for dumped tables
|
||||||
--
|
--
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for table `files`
|
||||||
|
--
|
||||||
|
ALTER TABLE `files`
|
||||||
|
MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- AUTO_INCREMENT for table `games`
|
-- AUTO_INCREMENT for table `games`
|
||||||
--
|
--
|
||||||
ALTER TABLE `games`
|
ALTER TABLE `games`
|
||||||
MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
|
MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for table `launcherupdates`
|
||||||
|
--
|
||||||
|
ALTER TABLE `launcherupdates`
|
||||||
|
MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for table `mods`
|
||||||
|
--
|
||||||
|
ALTER TABLE `mods`
|
||||||
|
MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- AUTO_INCREMENT for table `resetcodes`
|
-- AUTO_INCREMENT for table `resetcodes`
|
||||||
--
|
--
|
||||||
@@ -222,6 +281,12 @@ ALTER TABLE `verifycodes`
|
|||||||
--
|
--
|
||||||
ALTER TABLE `launcherversionmanifest`
|
ALTER TABLE `launcherversionmanifest`
|
||||||
ADD CONSTRAINT `fk_category` FOREIGN KEY (`game`) REFERENCES `games` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
ADD CONSTRAINT `fk_category` FOREIGN KEY (`game`) REFERENCES `games` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Constraints for table `modversions`
|
||||||
|
--
|
||||||
|
ALTER TABLE `modversions`
|
||||||
|
ADD CONSTRAINT `fk_gameVersion` FOREIGN KEY (`gameVersion`) REFERENCES `launcherversionmanifest` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
|||||||
+13
-14
@@ -2,29 +2,28 @@
|
|||||||
"name": "lncvrt-games-api",
|
"name": "lncvrt-games-api",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "bun run src/index.ts",
|
"start": "bun run dist/index.js",
|
||||||
"dev": "bun run --watch src/index.ts",
|
"dev": "bun run --watch src/index.ts",
|
||||||
"build": "rm -rf dist; bun build src/index.ts --target=bun --outdir=dist"
|
"build": "rm -rf dist; bun build src/index.ts --target=bun --outdir=dist"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@elysiajs/cors": "1.4.1",
|
"@elysiajs/cors": "1.4.2",
|
||||||
"@elysiajs/swagger": "1.3.1",
|
"@elysiajs/swagger": "1.3.1",
|
||||||
"axios": "1.13.5",
|
"axios": "1.20.0",
|
||||||
"bcryptjs": "3.0.3",
|
"bcryptjs": "3.0.3",
|
||||||
"crypto": "1.0.1",
|
"dotenv": "18.0.5",
|
||||||
"dotenv": "17.3.1",
|
"drizzle-orm": "0.45.3",
|
||||||
"drizzle-orm": "0.45.1",
|
"elysia": "1.4.30",
|
||||||
"elysia": "1.4.25",
|
"image-size": "2.0.4",
|
||||||
"image-size": "2.0.2",
|
"mysql2": "3.24.5",
|
||||||
"mysql2": "3.17.2",
|
"nodemailer": "10.0.13",
|
||||||
"nodemailer": "8.0.1",
|
"sharp": "0.35.5",
|
||||||
"sharp": "0.34.5",
|
"validator": "13.15.35"
|
||||||
"validator": "13.15.26"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/nodemailer": "7.0.10",
|
"@types/nodemailer": "8.0.2",
|
||||||
"@types/validator": "13.15.10",
|
"@types/validator": "13.15.10",
|
||||||
"bun-types": "1.3.9"
|
"bun-types": "1.4.2"
|
||||||
},
|
},
|
||||||
"module": "src/index.js"
|
"module": "src/index.js"
|
||||||
}
|
}
|
||||||
+483
-146
@@ -1,4 +1,4 @@
|
|||||||
import { Elysia, t } from 'elysia'
|
import { Elysia, redirect, t } from 'elysia'
|
||||||
import { cors } from '@elysiajs/cors'
|
import { cors } from '@elysiajs/cors'
|
||||||
import { ElysiaWS } from 'elysia/dist/ws'
|
import { ElysiaWS } from 'elysia/dist/ws'
|
||||||
import { getDatabaseConnection, jsonResponse } from './lib/util'
|
import { getDatabaseConnection, jsonResponse } from './lib/util'
|
||||||
@@ -7,16 +7,18 @@ import swagger from '@elysiajs/swagger'
|
|||||||
import { berryDashChats, berryDashUserData, users } from './lib/tables'
|
import { berryDashChats, berryDashUserData, users } from './lib/tables'
|
||||||
import { and, desc, eq } from 'drizzle-orm'
|
import { and, desc, eq } from 'drizzle-orm'
|
||||||
import { checkAuthorization } from './lib/auth'
|
import { checkAuthorization } from './lib/auth'
|
||||||
|
import { randomBytes } from 'node:crypto'
|
||||||
|
|
||||||
import { handler as getVerifyCodeHandler } from './routes/get-verify-code'
|
import { handler as getVerifyCodeHandler } from './routes/get-verify-code'
|
||||||
|
|
||||||
import { handler as canLoadClientHandler } from './routes/can-load-client'
|
import { handler as canLoadClientHandler } from './routes/can-load-client'
|
||||||
|
|
||||||
import { handler as launcherVersionsHandler } from './routes/launcher/versions'
|
import { handler as launcherModsGetHandler } from './routes/launcher/mods/get'
|
||||||
import { handler as launcherLatestHandler } from './routes/launcher/latest'
|
import { handler as launcherVersionsHandler } from './routes/launcher/versions/get'
|
||||||
import { handler as launcherDownloadHandler } from './routes/launcher/download'
|
import { handler as launcherLatestHandler } from './routes/launcher/latest/get'
|
||||||
import { handler as launcherLoaderLatestHandler } from './routes/launcher/loader/latest'
|
import { handler as launcherUpdateHandler } from './routes/launcher/update/get'
|
||||||
import { handler as launcherLoaderUpdateDataHandler } from './routes/launcher/loader/update-data'
|
import { handler as launcherDownloadHandler } from './routes/launcher/download/get'
|
||||||
|
import { handler as launcherLoaderLatestHandler } from './routes/launcher/loader/latest/get'
|
||||||
|
|
||||||
import { handler as accountLoginPostHandler } from './routes/account/login/post'
|
import { handler as accountLoginPostHandler } from './routes/account/login/post'
|
||||||
import { handler as accountRegisterPostHandler } from './routes/account/register/post'
|
import { handler as accountRegisterPostHandler } from './routes/account/register/post'
|
||||||
@@ -80,7 +82,8 @@ const app = new Elysia({
|
|||||||
.use(
|
.use(
|
||||||
cors({
|
cors({
|
||||||
origin: '*',
|
origin: '*',
|
||||||
methods: ['POST', 'GET']
|
methods: ['POST', 'GET'],
|
||||||
|
exposeHeaders: '*'
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.use(
|
.use(
|
||||||
@@ -106,19 +109,384 @@ interface ClientInfoData {
|
|||||||
ClientPlatform: string
|
ClientPlatform: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MultiplayerClient {
|
||||||
|
Id: string
|
||||||
|
PosX: number
|
||||||
|
PosY: number
|
||||||
|
Flipped: boolean
|
||||||
|
Paused: boolean
|
||||||
|
FlaggedReason: string | null
|
||||||
|
Token: string
|
||||||
|
Username: string
|
||||||
|
UserID: number
|
||||||
|
Admin: boolean
|
||||||
|
Platform: number | null
|
||||||
|
JoinTimestamp: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MultiplayerBerry {
|
||||||
|
Id: string
|
||||||
|
Type: string
|
||||||
|
Timestamp: number
|
||||||
|
PosX: number
|
||||||
|
}
|
||||||
|
|
||||||
const clients = new Set<ElysiaWS>()
|
const clients = new Set<ElysiaWS>()
|
||||||
const clientInfo: ClientInfoData[] = []
|
let clientInfo: ClientInfoData[] = []
|
||||||
|
let multiplayerClients: MultiplayerClient[] = []
|
||||||
|
let multiplayerBerries: MultiplayerBerry[] = []
|
||||||
|
|
||||||
|
setInterval(async () => {
|
||||||
|
if (multiplayerClients.length == 0) return
|
||||||
|
let berry = ''
|
||||||
|
const spawnProbability = Math.random()
|
||||||
|
const id = randomBytes(16).toString('hex')
|
||||||
|
if (spawnProbability <= 0.575) {
|
||||||
|
berry = 'NormalBerry'
|
||||||
|
} else if (spawnProbability <= 0.75) {
|
||||||
|
berry = 'PoisonBerry'
|
||||||
|
} else if (spawnProbability <= 0.85) {
|
||||||
|
berry = 'SlowBerry'
|
||||||
|
} else if (spawnProbability <= 0.95) {
|
||||||
|
berry = 'UltraBerry'
|
||||||
|
} else {
|
||||||
|
berry = 'RandomBerry'
|
||||||
|
}
|
||||||
|
const time = Date.now()
|
||||||
|
const posX = Math.random()
|
||||||
|
const data: MultiplayerBerry = {
|
||||||
|
Id: id,
|
||||||
|
Type: berry,
|
||||||
|
Timestamp: time,
|
||||||
|
PosX: posX
|
||||||
|
}
|
||||||
|
multiplayerBerries.push(data)
|
||||||
|
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_berry_spawn',
|
||||||
|
id,
|
||||||
|
berryType: berry,
|
||||||
|
posX,
|
||||||
|
timestamp: time
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
app.ws('/ws', {
|
app.ws('/ws', {
|
||||||
maxPayloadLength: 10 * 1024 * 1024,
|
maxPayloadLength: 10 * 1024 * 1024,
|
||||||
open (ws) {
|
open(ws) {
|
||||||
clients.add(ws)
|
clients.add(ws)
|
||||||
console.log(ws.id, 'connected')
|
// console.log(ws.id, 'connected')
|
||||||
},
|
},
|
||||||
async message (ws, message: any) {
|
async message(ws, message: any) {
|
||||||
// console.log('received:', message, 'from', ws.id)
|
console.log('received:', message, 'from', ws.id)
|
||||||
|
if (message == 'ping') ws.send('ping')
|
||||||
if (message.type) {
|
if (message.type) {
|
||||||
if (message.type == 'connected_with_current_scene') {
|
if (message.type == 'multiplayer_player_unpause') {
|
||||||
|
const multiplayerInfo = multiplayerClients.find(
|
||||||
|
client => client.Id == ws.id
|
||||||
|
)
|
||||||
|
if (!multiplayerInfo) return
|
||||||
|
multiplayerInfo.Paused = false
|
||||||
|
const index = multiplayerClients.findIndex(client => client.Id == ws.id)
|
||||||
|
if (index === -1) return
|
||||||
|
multiplayerClients[index] = multiplayerInfo
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_unpause',
|
||||||
|
id: multiplayerInfo.UserID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (message.type == 'multiplayer_player_pause') {
|
||||||
|
const multiplayerInfo = multiplayerClients.find(
|
||||||
|
client => client.Id == ws.id
|
||||||
|
)
|
||||||
|
if (!multiplayerInfo) return
|
||||||
|
multiplayerInfo.Paused = true
|
||||||
|
const index = multiplayerClients.findIndex(client => client.Id == ws.id)
|
||||||
|
if (index === -1) return
|
||||||
|
multiplayerClients[index] = multiplayerInfo
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_pause',
|
||||||
|
id: multiplayerInfo.UserID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
message.type == 'multiplayer_player_move' &&
|
||||||
|
message.x !== undefined &&
|
||||||
|
message.y !== undefined &&
|
||||||
|
message.f !== undefined
|
||||||
|
) {
|
||||||
|
const multiplayerInfo = multiplayerClients.find(
|
||||||
|
client => client.Id == ws.id
|
||||||
|
)
|
||||||
|
if (!multiplayerInfo) return
|
||||||
|
multiplayerInfo.PosX = Number(message.x)
|
||||||
|
multiplayerInfo.PosY = Number(message.y)
|
||||||
|
multiplayerInfo.Flipped = Boolean(message.f)
|
||||||
|
const index = multiplayerClients.findIndex(client => client.Id == ws.id)
|
||||||
|
if (index === -1) return
|
||||||
|
multiplayerClients[index] = multiplayerInfo
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_move',
|
||||||
|
id: multiplayerInfo.UserID,
|
||||||
|
x: Number(message.x),
|
||||||
|
y: Number(message.y),
|
||||||
|
f: Boolean(message.f)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (message.type == 'multiplayer_leave') {
|
||||||
|
const multiplayerInfo = multiplayerClients.find(
|
||||||
|
client => client.Id == ws.id
|
||||||
|
)
|
||||||
|
if (!multiplayerInfo) return
|
||||||
|
multiplayerClients = multiplayerClients.filter(
|
||||||
|
client => client.Id !== ws.id
|
||||||
|
)
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_leave',
|
||||||
|
id: multiplayerInfo.UserID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (message.type == 'multiplayer_join_request' && message.auth) {
|
||||||
|
const dbInfo0 = getDatabaseConnection(0)
|
||||||
|
const dbInfo1 = getDatabaseConnection(1)
|
||||||
|
|
||||||
|
if (!dbInfo0 || !dbInfo1) {
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: false,
|
||||||
|
denyReason: 'Unable to authenticate',
|
||||||
|
key: null,
|
||||||
|
players: []
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { connection: connection0, db: db0 } = dbInfo0
|
||||||
|
const { connection: connection1, db: db1 } = dbInfo1
|
||||||
|
|
||||||
|
const ip = ws.remoteAddress
|
||||||
|
const authResult = await checkAuthorization(
|
||||||
|
message.auth as string,
|
||||||
|
db0,
|
||||||
|
ip
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!authResult.valid) {
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: false,
|
||||||
|
denyReason: 'Unable to authenticate',
|
||||||
|
id: null,
|
||||||
|
players: []
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = authResult.id
|
||||||
|
|
||||||
|
const userResult = await db0
|
||||||
|
.select({
|
||||||
|
username: users.username,
|
||||||
|
admin: users.admin,
|
||||||
|
token: users.token
|
||||||
|
})
|
||||||
|
.from(users)
|
||||||
|
.where(eq(users.id, userId))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
if (userResult.length !== 1) {
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: false,
|
||||||
|
denyReason: 'Unable to authenticate',
|
||||||
|
id: null,
|
||||||
|
players: null
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentUserData = await db1
|
||||||
|
.select({
|
||||||
|
saveData: berryDashUserData.saveData
|
||||||
|
})
|
||||||
|
.from(berryDashUserData)
|
||||||
|
.where(eq(berryDashUserData.id, userId))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
const currentSavedata = currentUserData[0]?.saveData
|
||||||
|
? JSON.parse(currentUserData[0].saveData)
|
||||||
|
: null
|
||||||
|
|
||||||
|
if (!currentSavedata) {
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: false,
|
||||||
|
denyReason: 'Unable to load save data',
|
||||||
|
id: null,
|
||||||
|
players: null
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCustomIcon =
|
||||||
|
currentSavedata.bird?.customIcon?.selected ?? null
|
||||||
|
const currentIcon = currentCustomIcon
|
||||||
|
? 0
|
||||||
|
: currentSavedata.bird?.icon ?? 1
|
||||||
|
const currentOverlay = currentCustomIcon
|
||||||
|
? 1
|
||||||
|
: currentSavedata.bird?.overlay ?? 0
|
||||||
|
const currentIconColor = currentCustomIcon
|
||||||
|
? [255, 255, 255]
|
||||||
|
: currentSavedata?.settings?.colors?.icon ?? [255, 255, 255]
|
||||||
|
const currentOverlayColor = currentCustomIcon
|
||||||
|
? [255, 255, 255]
|
||||||
|
: currentSavedata?.settings?.colors?.overlay ?? [255, 255, 255]
|
||||||
|
|
||||||
|
const players: any = []
|
||||||
|
for (const marketplaceInfo of multiplayerClients) {
|
||||||
|
const playerUserData = await db1
|
||||||
|
.select({
|
||||||
|
saveData: berryDashUserData.saveData
|
||||||
|
})
|
||||||
|
.from(berryDashUserData)
|
||||||
|
.where(eq(berryDashUserData.id, marketplaceInfo.UserID))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
const playerSavedata = playerUserData[0]?.saveData
|
||||||
|
? JSON.parse(playerUserData[0].saveData)
|
||||||
|
: null
|
||||||
|
|
||||||
|
if (!playerSavedata) continue
|
||||||
|
|
||||||
|
const playerInfo = await db0
|
||||||
|
.select({
|
||||||
|
username: users.username,
|
||||||
|
admin: users.admin
|
||||||
|
})
|
||||||
|
.from(users)
|
||||||
|
.where(eq(users.id, marketplaceInfo.UserID))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
if (playerInfo.length !== 1) continue
|
||||||
|
|
||||||
|
const playerCustomIcon =
|
||||||
|
playerSavedata.bird?.customIcon?.selected ?? null
|
||||||
|
const playerIcon = playerCustomIcon
|
||||||
|
? 0
|
||||||
|
: playerSavedata.bird?.icon ?? 1
|
||||||
|
const playerOverlay = playerCustomIcon
|
||||||
|
? 1
|
||||||
|
: playerSavedata.bird?.overlay ?? 0
|
||||||
|
const playerIconColor = playerCustomIcon
|
||||||
|
? [255, 255, 255]
|
||||||
|
: playerSavedata?.settings?.colors?.icon ?? [255, 255, 255]
|
||||||
|
const playerOverlayColor = playerCustomIcon
|
||||||
|
? [255, 255, 255]
|
||||||
|
: playerSavedata?.settings?.colors?.overlay ?? [255, 255, 255]
|
||||||
|
|
||||||
|
players.push({
|
||||||
|
id: marketplaceInfo.UserID,
|
||||||
|
username: playerInfo[0].username,
|
||||||
|
admin: playerInfo[0].admin,
|
||||||
|
timestamp: marketplaceInfo.JoinTimestamp,
|
||||||
|
iconData: {
|
||||||
|
icon: playerIcon,
|
||||||
|
overlay: playerOverlay,
|
||||||
|
iconColor: playerIconColor,
|
||||||
|
overlayColor: playerOverlayColor,
|
||||||
|
customIcon: playerCustomIcon ?? ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const time = Date.now()
|
||||||
|
const newClient: MultiplayerClient = {
|
||||||
|
Id: ws.id,
|
||||||
|
PosX: 0,
|
||||||
|
PosY: -1,
|
||||||
|
Flipped: false,
|
||||||
|
Paused: false,
|
||||||
|
FlaggedReason: null,
|
||||||
|
Token: userResult[0].token,
|
||||||
|
Username: userResult[0].username,
|
||||||
|
UserID: userId,
|
||||||
|
Admin: userResult[0].admin,
|
||||||
|
Platform: null,
|
||||||
|
JoinTimestamp: time
|
||||||
|
}
|
||||||
|
multiplayerClients.push(newClient)
|
||||||
|
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: true,
|
||||||
|
denyReason: null,
|
||||||
|
players
|
||||||
|
})
|
||||||
|
|
||||||
|
for (const existingClient of multiplayerClients) {
|
||||||
|
if (ws.id === existingClient.Id) continue
|
||||||
|
|
||||||
|
const clientSocket = Array.from(clients).find(
|
||||||
|
client => client.id === existingClient.Id
|
||||||
|
)
|
||||||
|
if (!clientSocket) continue
|
||||||
|
|
||||||
|
clientSocket.send({
|
||||||
|
type: 'multiplayer_player_join',
|
||||||
|
id: userId,
|
||||||
|
username: userResult[0].username,
|
||||||
|
admin: userResult[0].admin,
|
||||||
|
timestamp: time,
|
||||||
|
iconData: {
|
||||||
|
icon: currentIcon,
|
||||||
|
overlay: currentOverlay,
|
||||||
|
iconColor: currentIconColor,
|
||||||
|
overlayColor: currentOverlayColor,
|
||||||
|
customIcon: currentCustomIcon ?? ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
} else if (message.type == 'connected_with_current_scene') {
|
||||||
if (
|
if (
|
||||||
!message.sceneName ||
|
!message.sceneName ||
|
||||||
!message.Requester ||
|
!message.Requester ||
|
||||||
@@ -535,12 +903,33 @@ app.ws('/ws', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close (ws) {
|
async close(ws) {
|
||||||
clients.forEach(client => {
|
clients.forEach(client => {
|
||||||
if (client.id === ws.id) clients.delete(client)
|
if (client.id === ws.id) clients.delete(client)
|
||||||
})
|
})
|
||||||
|
clientInfo = clientInfo.filter(client => client.Id !== ws.id)
|
||||||
|
|
||||||
console.log(ws.id, 'disconnected')
|
const multiplayerInfo = multiplayerClients.find(
|
||||||
|
client => client.Id == ws.id
|
||||||
|
)
|
||||||
|
if (multiplayerInfo) {
|
||||||
|
multiplayerClients = multiplayerClients.filter(
|
||||||
|
client => client.Id !== ws.id
|
||||||
|
)
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_leave',
|
||||||
|
id: multiplayerInfo.UserID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(ws.id, 'disconnected')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -568,22 +957,37 @@ app.get('/can-load-client', context => canLoadClientHandler(context), {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
app.get('/launcher/versions', context => launcherVersionsHandler(context), {
|
app.get('/launcher/mods', context => launcherModsGetHandler(context), {
|
||||||
detail: {
|
detail: {
|
||||||
description:
|
description: 'The endpoint for getting mods for a version.',
|
||||||
'The endpoint for getting the launcher manifest.\n\nNote: if going to use the params, both must be provided at the same time.',
|
|
||||||
tags: ['Launcher']
|
tags: ['Launcher']
|
||||||
},
|
},
|
||||||
query: t.Object({
|
query: t.Object({
|
||||||
platform: t.Optional(t.String({ examples: ['windows', 'macos', 'linux'] })),
|
version: t.String()
|
||||||
arch: t.Optional(t.String({ examples: ['x86_64', 'aarch64'] }))
|
|
||||||
}),
|
}),
|
||||||
headers: t.Object({
|
headers: t.Object({
|
||||||
'x-forwarded-for': t.Optional(
|
'x-forwarded-for': t.Optional(
|
||||||
t.String({
|
t.String({
|
||||||
hide: true
|
hide: true
|
||||||
})
|
})
|
||||||
)
|
),
|
||||||
|
clientplatform: t.String()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
app.get('/launcher/versions', context => launcherVersionsHandler(context), {
|
||||||
|
detail: {
|
||||||
|
description:
|
||||||
|
'The endpoint for getting the launcher manifest.\n\nNote: if going to use the params, both must be provided at the same time.',
|
||||||
|
tags: ['Launcher']
|
||||||
|
},
|
||||||
|
headers: t.Object({
|
||||||
|
'x-forwarded-for': t.Optional(
|
||||||
|
t.String({
|
||||||
|
hide: true
|
||||||
|
})
|
||||||
|
),
|
||||||
|
clientplatform: t.Optional(t.String()),
|
||||||
|
authorization: t.Optional(t.String())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
app.get('/launcher/latest', launcherLatestHandler, {
|
app.get('/launcher/latest', launcherLatestHandler, {
|
||||||
@@ -599,12 +1003,29 @@ app.get('/launcher/latest', launcherLatestHandler, {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
app.get('/launcher/download', context => launcherDownloadHandler(context), {
|
app.get('/launcher/update', launcherUpdateHandler, {
|
||||||
detail: {
|
detail: {
|
||||||
hide: true
|
description: "The endpoint for getting the launcher's update data.",
|
||||||
|
tags: ['Launcher']
|
||||||
},
|
},
|
||||||
query: t.Object({
|
query: t.Object({
|
||||||
id: t.String()
|
target: t.String(),
|
||||||
|
arch: t.Optional(t.String()),
|
||||||
|
currentVersion: t.String()
|
||||||
|
}),
|
||||||
|
headers: t.Object({
|
||||||
|
'x-forwarded-for': t.Optional(
|
||||||
|
t.String({
|
||||||
|
hide: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
app.get('/launcher/download', context => launcherDownloadHandler(context), {
|
||||||
|
query: t.Object({
|
||||||
|
versionId: t.Optional(t.String({ hide: true })),
|
||||||
|
modId: t.Optional(t.String({ hide: true })),
|
||||||
|
downloadId: t.String()
|
||||||
}),
|
}),
|
||||||
headers: t.Object({
|
headers: t.Object({
|
||||||
'x-forwarded-for': t.Optional(
|
'x-forwarded-for': t.Optional(
|
||||||
@@ -628,31 +1049,6 @@ app.get('/launcher/loader/latest', launcherLoaderLatestHandler, {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
app.get(
|
|
||||||
'/launcher/loader/update-data',
|
|
||||||
context => launcherLoaderUpdateDataHandler(context),
|
|
||||||
{
|
|
||||||
detail: {
|
|
||||||
description:
|
|
||||||
'The endpoint for getting Launcher Update data for when a new Update is released. It will be send & read by the updater.\n\nNote: if going to use the params, both must be provided at the same time.',
|
|
||||||
tags: ['Launcher']
|
|
||||||
},
|
|
||||||
query: t.Object({
|
|
||||||
platform: t.Optional(
|
|
||||||
t.String({ examples: ['windows', 'macos', 'linux'] })
|
|
||||||
),
|
|
||||||
arch: t.Optional(t.String({ examples: ['x86_64', 'aarch64'] }))
|
|
||||||
}),
|
|
||||||
headers: t.Object({
|
|
||||||
'x-forwarded-for': t.Optional(
|
|
||||||
t.String({
|
|
||||||
description:
|
|
||||||
'Ignore this header. It cannot be set or overridden and is required for endpoints to work properly'
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
)
|
|
||||||
app.post('/account/login', context => accountLoginPostHandler(context), {
|
app.post('/account/login', context => accountLoginPostHandler(context), {
|
||||||
detail: {
|
detail: {
|
||||||
description:
|
description:
|
||||||
@@ -810,105 +1206,65 @@ app.get('/berrydash/latest-version', berryDashLatestVersionGetHandler, {
|
|||||||
})
|
})
|
||||||
app.get(
|
app.get(
|
||||||
'/berrydash/leaderboards/score',
|
'/berrydash/leaderboards/score',
|
||||||
context => berrydashLeaderboardGetHandler(context, 0),
|
({ query, redirect }) => {
|
||||||
|
return redirect(
|
||||||
|
`/api/berrydash/leaderboard/score?${new URLSearchParams(
|
||||||
|
query
|
||||||
|
).toString()}`
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
detail: {
|
detail: { hide: true }
|
||||||
deprecated: true,
|
|
||||||
description:
|
|
||||||
'This endpoint was renamed to `/berrydash/leaderboard/score` and will be removed on March 19th 2026.',
|
|
||||||
tags: ['Berry Dash', 'Leaderboards']
|
|
||||||
},
|
|
||||||
headers: t.Object({
|
|
||||||
'x-forwarded-for': t.Optional(
|
|
||||||
t.String({
|
|
||||||
description:
|
|
||||||
'Ignore this header. It cannot be set or overridden and is required for endpoints to work properly'
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
app.get(
|
app.get(
|
||||||
'/berrydash/leaderboards/berry',
|
'/berrydash/leaderboards/berry',
|
||||||
context => berrydashLeaderboardGetHandler(context, 1),
|
({ query, redirect }) => {
|
||||||
|
return redirect(
|
||||||
|
`/api/berrydash/leaderboard/berry?${new URLSearchParams(
|
||||||
|
query
|
||||||
|
).toString()}`
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
detail: {
|
detail: { hide: true }
|
||||||
deprecated: true,
|
|
||||||
description:
|
|
||||||
'This endpoint was renamed to `/berrydash/leaderboard/berry` and will be removed on March 19th 2026.',
|
|
||||||
tags: ['Berry Dash', 'Leaderboards']
|
|
||||||
},
|
|
||||||
query: t.Object({
|
|
||||||
berry: t.String()
|
|
||||||
}),
|
|
||||||
headers: t.Object({
|
|
||||||
'x-forwarded-for': t.Optional(
|
|
||||||
t.String({
|
|
||||||
description:
|
|
||||||
'Ignore this header. It cannot be set or overridden and is required for endpoints to work properly'
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
app.get(
|
app.get(
|
||||||
'/berrydash/leaderboards/coin',
|
'/berrydash/leaderboards/coin',
|
||||||
context => berrydashLeaderboardGetHandler(context, 2),
|
({ query, redirect }) => {
|
||||||
|
return redirect(
|
||||||
|
`/api/berrydash/leaderboard/coin?${new URLSearchParams(query).toString()}`
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
detail: {
|
detail: { hide: true }
|
||||||
deprecated: true,
|
|
||||||
description:
|
|
||||||
'This endpoint was renamed to `/berrydash/leaderboard/coin` and will be removed on March 19th 2026.',
|
|
||||||
tags: ['Berry Dash', 'Leaderboards']
|
|
||||||
},
|
|
||||||
headers: t.Object({
|
|
||||||
'x-forwarded-for': t.Optional(
|
|
||||||
t.String({
|
|
||||||
description:
|
|
||||||
'Ignore this header. It cannot be set or overridden and is required for endpoints to work properly'
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
app.get(
|
app.get(
|
||||||
'/berrydash/leaderboards/legacy',
|
'/berrydash/leaderboards/legacy',
|
||||||
context => berrydashLeaderboardGetHandler(context, 3),
|
({ query, redirect }) => {
|
||||||
|
return redirect(
|
||||||
|
`/api/berrydash/leaderboard/legacy?${new URLSearchParams(
|
||||||
|
query
|
||||||
|
).toString()}`
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
detail: {
|
detail: { hide: true }
|
||||||
deprecated: true,
|
|
||||||
description:
|
|
||||||
'This endpoint was renamed to `/berrydash/leaderboard/legacy` and will be removed on March 19th 2026.',
|
|
||||||
tags: ['Berry Dash', 'Leaderboards']
|
|
||||||
},
|
|
||||||
headers: t.Object({
|
|
||||||
'x-forwarded-for': t.Optional(
|
|
||||||
t.String({
|
|
||||||
description:
|
|
||||||
'Ignore this header. It cannot be set or overridden and is required for endpoints to work properly'
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
app.get(
|
app.get(
|
||||||
'/berrydash/leaderboards/total',
|
'/berrydash/leaderboards/total',
|
||||||
context => berrydashLeaderboardGetHandler(context, 4),
|
({ query, redirect }) => {
|
||||||
|
return redirect(
|
||||||
|
`/api/berrydash/leaderboard/total?${new URLSearchParams(
|
||||||
|
query
|
||||||
|
).toString()}`
|
||||||
|
)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
detail: {
|
detail: { hide: true }
|
||||||
deprecated: true,
|
|
||||||
description:
|
|
||||||
'This endpoint was renamed to `/berrydash/leaderboard/total` and will be removed on March 19th 2026.',
|
|
||||||
tags: ['Berry Dash', 'Leaderboards']
|
|
||||||
},
|
|
||||||
headers: t.Object({
|
|
||||||
'x-forwarded-for': t.Optional(
|
|
||||||
t.String({
|
|
||||||
description:
|
|
||||||
'Ignore this header. It cannot be set or overridden and is required for endpoints to work properly'
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
app.get(
|
app.get(
|
||||||
@@ -1005,25 +1361,6 @@ app.get(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
app.get('/berrydash/profile', context => berrydashProfileGetHandler(context), {
|
|
||||||
detail: {
|
|
||||||
description:
|
|
||||||
"The endpoint for getting a user's profile.\n\n**Do not use this endpoint. It is the same as `/api/berrydash/account?id=(id)&exact=true` and will be removed on March 19th 2026.**" +
|
|
||||||
intNotStr('userId'),
|
|
||||||
tags: ['Berry Dash', 'Profiles'],
|
|
||||||
deprecated: true
|
|
||||||
},
|
|
||||||
query: t.Object({
|
|
||||||
userId: t.String()
|
|
||||||
}),
|
|
||||||
headers: t.Object({
|
|
||||||
'x-forwarded-for': t.Optional(
|
|
||||||
t.String({
|
|
||||||
hide: true
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
app.delete(
|
app.delete(
|
||||||
'/berrydash/profile/posts',
|
'/berrydash/profile/posts',
|
||||||
context => berrydashProfilePostsDeleteHandler(context),
|
context => berrydashProfilePostsDeleteHandler(context),
|
||||||
|
|||||||
+48
-25
@@ -1,10 +1,12 @@
|
|||||||
import {
|
import {
|
||||||
bigint,
|
bigint,
|
||||||
boolean,
|
boolean,
|
||||||
|
char,
|
||||||
int,
|
int,
|
||||||
longtext,
|
longtext,
|
||||||
mysqlTable,
|
mysqlTable,
|
||||||
text,
|
text,
|
||||||
|
timestamp,
|
||||||
tinyint,
|
tinyint,
|
||||||
varchar
|
varchar
|
||||||
} from 'drizzle-orm/mysql-core'
|
} from 'drizzle-orm/mysql-core'
|
||||||
@@ -23,24 +25,6 @@ export const users = mysqlTable('users', {
|
|||||||
leaderboardsBanned: boolean('leaderboards_banned').default(false).notNull()
|
leaderboardsBanned: boolean('leaderboards_banned').default(false).notNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const launcherUpdates = mysqlTable('launcherupdates', {
|
|
||||||
id: varchar('id', { length: 24 }).primaryKey().notNull(),
|
|
||||||
releaseDate: bigint('releaseDate', { mode: 'number' }).notNull(),
|
|
||||||
downloadUrls: text('downloadUrls').notNull(),
|
|
||||||
platforms: text('platforms').notNull(),
|
|
||||||
executables: text('executables').notNull(),
|
|
||||||
hidden: boolean('hidden').default(false).notNull(),
|
|
||||||
place: bigint('place', { mode: 'number' }).default(0).notNull(),
|
|
||||||
sha512sums: text('sha512sums').default('[]').notNull()
|
|
||||||
})
|
|
||||||
|
|
||||||
export const loaderUpdates = mysqlTable('loaderupdates', {
|
|
||||||
id: varchar('id', { length: 24 }).primaryKey().notNull(),
|
|
||||||
releaseDate: bigint('releaseDate', { mode: 'number' }).notNull(),
|
|
||||||
hidden: boolean('hidden').default(false).notNull(),
|
|
||||||
place: bigint('place', { mode: 'number' }).default(0).notNull()
|
|
||||||
})
|
|
||||||
|
|
||||||
export const games = mysqlTable('games', {
|
export const games = mysqlTable('games', {
|
||||||
id: bigint('id', { mode: 'number' }).primaryKey().autoincrement().notNull(),
|
id: bigint('id', { mode: 'number' }).primaryKey().autoincrement().notNull(),
|
||||||
name: text('name').notNull(),
|
name: text('name').notNull(),
|
||||||
@@ -53,23 +37,23 @@ export const games = mysqlTable('games', {
|
|||||||
export const launcherVersionManifest = mysqlTable('launcherversionmanifest', {
|
export const launcherVersionManifest = mysqlTable('launcherversionmanifest', {
|
||||||
id: varchar('id', { length: 24 }).primaryKey().notNull(),
|
id: varchar('id', { length: 24 }).primaryKey().notNull(),
|
||||||
displayName: text('displayName').notNull(),
|
displayName: text('displayName').notNull(),
|
||||||
|
versionName: text('versionName').notNull(),
|
||||||
|
downloads: text('downloads').default('{}').notNull(),
|
||||||
|
executables: text('executables').default('[]').notNull(),
|
||||||
|
modSupportDownloads: text('modSupportDownloads').default('{}').notNull(),
|
||||||
releaseDate: bigint('releaseDate', { mode: 'number' }).notNull(),
|
releaseDate: bigint('releaseDate', { mode: 'number' }).notNull(),
|
||||||
downloadUrlVersion: text('downloadUrlVersion').notNull(),
|
|
||||||
downloadUrls: text('downloadUrls').notNull(),
|
|
||||||
platforms: text('platforms').notNull(),
|
|
||||||
executables: text('executables').notNull(),
|
|
||||||
hidden: boolean('hidden').default(false).notNull(),
|
hidden: boolean('hidden').default(false).notNull(),
|
||||||
game: bigint('game', { mode: 'number' })
|
game: bigint('game', { mode: 'number' })
|
||||||
.default(0)
|
.default(0)
|
||||||
.references(() => games.id)
|
.references(() => games.id)
|
||||||
.notNull(),
|
.notNull(),
|
||||||
place: bigint('place', { mode: 'number' }).default(0).notNull(),
|
place: bigint('place', { mode: 'number' }).default(0).notNull(),
|
||||||
sha512sums: text('sha512sums').default('[]').notNull(),
|
|
||||||
sizes: text('sizes').default('[]').notNull(),
|
|
||||||
changelog: text('changelog'),
|
changelog: text('changelog'),
|
||||||
category: int('category').notNull().default(-1),
|
category: int('category').notNull().default(-1),
|
||||||
lastRevision: bigint('lastRevision', { mode: 'number' }).notNull().default(0),
|
lastRevision: bigint('lastRevision', { mode: 'number' }).notNull().default(0),
|
||||||
downloads: bigint('downloads', { mode: 'number' }).notNull().default(0)
|
downloadCount: bigint('downloadCount', { mode: 'number' })
|
||||||
|
.notNull()
|
||||||
|
.default(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
export const verifyCodes = mysqlTable('verifycodes', {
|
export const verifyCodes = mysqlTable('verifycodes', {
|
||||||
@@ -94,6 +78,45 @@ export const resetCodes = mysqlTable('resetcodes', {
|
|||||||
type: int('type').notNull()
|
type: int('type').notNull()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const files = mysqlTable('files', {
|
||||||
|
id: bigint('id', { mode: 'number' }).primaryKey().autoincrement().notNull(),
|
||||||
|
path: varchar('path', { length: 4096 }).notNull(),
|
||||||
|
hash: char('hash', { length: 128 }).notNull(),
|
||||||
|
size: bigint('size', { mode: 'number' }).notNull(),
|
||||||
|
host: int('host').notNull().default(0),
|
||||||
|
mimeType: varchar('mimeType', { length: 255 })
|
||||||
|
})
|
||||||
|
|
||||||
|
export const mods = mysqlTable('mods', {
|
||||||
|
id: bigint('id', { mode: 'number' }).primaryKey().autoincrement().notNull(),
|
||||||
|
name: text('name').notNull(),
|
||||||
|
creators: text('creators').default('{}').notNull(),
|
||||||
|
description: text('description').notNull(),
|
||||||
|
downloadCount: bigint('downloadCount', { mode: 'number' })
|
||||||
|
.notNull()
|
||||||
|
.default(0),
|
||||||
|
hidden: boolean('hidden').default(false).notNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const modVersions = mysqlTable('modversions', {
|
||||||
|
id: text('id').primaryKey().notNull(),
|
||||||
|
downloads: text('downloads').default('{}').notNull(),
|
||||||
|
gameVersion: varchar('gameVersion', { length: 24 })
|
||||||
|
.notNull()
|
||||||
|
.references(() => launcherVersionManifest.id),
|
||||||
|
releaseDate: bigint('releaseDate', { mode: 'number' }).notNull(),
|
||||||
|
changelog: text('changelog'),
|
||||||
|
hidden: boolean('hidden').default(false).notNull()
|
||||||
|
})
|
||||||
|
|
||||||
|
export const launcherUpdates = mysqlTable('launcherupdates', {
|
||||||
|
id: bigint('id', { mode: 'number' }).primaryKey().autoincrement().notNull(),
|
||||||
|
version: varchar('version', { length: 32 }).notNull(),
|
||||||
|
notes: text('notes').notNull(),
|
||||||
|
releaseDate: timestamp('release_date').notNull(),
|
||||||
|
downloadData: text('download_data').notNull()
|
||||||
|
})
|
||||||
|
|
||||||
// berrydashdatabase
|
// berrydashdatabase
|
||||||
|
|
||||||
export const berryDashUserData = mysqlTable('userdata', {
|
export const berryDashUserData = mysqlTable('userdata', {
|
||||||
|
|||||||
+29
-15
@@ -10,14 +10,28 @@ import { Context } from 'elysia'
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import FormData from 'form-data'
|
import FormData from 'form-data'
|
||||||
import nodemailer from 'nodemailer'
|
import nodemailer from 'nodemailer'
|
||||||
import { createHash } from 'crypto'
|
import { createHash, createPrivateKey, sign } from 'node:crypto'
|
||||||
import { and, eq, sql } from 'drizzle-orm'
|
import { and, eq, sql } from 'drizzle-orm'
|
||||||
import { verifyCodes } from './tables'
|
import { verifyCodes } from './tables'
|
||||||
|
|
||||||
|
const privateKey = createPrivateKey({
|
||||||
|
key: Buffer.from(process.env.PRIVATE_SIGNING_KEY!, 'base64').toString('utf8'),
|
||||||
|
format: 'pem'
|
||||||
|
})
|
||||||
|
|
||||||
|
export const generateSignature = (body: string) => {
|
||||||
|
return sign(null, Buffer.from(body), privateKey).toString('base64')
|
||||||
|
}
|
||||||
|
|
||||||
export const jsonResponse = (data: any, status = 200) => {
|
export const jsonResponse = (data: any, status = 200) => {
|
||||||
return new Response(JSON.stringify(data, null, 2), {
|
const body = JSON.stringify(data)
|
||||||
|
|
||||||
|
return new Response(body, {
|
||||||
status,
|
status,
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'X-Signature': generateSignature(body)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,19 +41,19 @@ export const getDatabaseConnection = (type: number) => {
|
|||||||
const env =
|
const env =
|
||||||
type === 0
|
type === 0
|
||||||
? {
|
? {
|
||||||
host: process.env.GAMES_DB_HOST ?? 'localhost',
|
host: process.env.DB_HOST ?? 'localhost',
|
||||||
port: Number(process.env.GAMES_DB_PORT) || 3306,
|
port: Number(process.env.DB_PORT) || 3306,
|
||||||
user: process.env.GAMES_DB_USER ?? '',
|
user: process.env.GAMES_DB_USER ?? '',
|
||||||
pass: process.env.GAMES_DB_PASS ?? '',
|
pass: process.env.GAMES_DB_PASS ?? '',
|
||||||
name: process.env.GAMES_DB_NAME ?? ''
|
name: process.env.GAMES_DB_NAME ?? ''
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
host: process.env.BERRYDASH_DB_HOST ?? 'localhost',
|
host: process.env.DB_HOST ?? 'localhost',
|
||||||
port: Number(process.env.BERRYDASH_DB_PORT) || 3306,
|
port: Number(process.env.DB_PORT) || 3306,
|
||||||
user: process.env.BERRYDASH_DB_USER ?? '',
|
user: process.env.BERRYDASH_DB_USER ?? '',
|
||||||
pass: process.env.BERRYDASH_DB_PASS ?? '',
|
pass: process.env.BERRYDASH_DB_PASS ?? '',
|
||||||
name: process.env.BERRYDASH_DB_NAME ?? ''
|
name: process.env.BERRYDASH_DB_NAME ?? ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const connection = mysql.createConnection({
|
const connection = mysql.createConnection({
|
||||||
host: env.host,
|
host: env.host,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { checkAuthorization } from '../../../lib/auth'
|
|||||||
import { users } from '../../../lib/tables'
|
import { users } from '../../../lib/tables'
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import bcrypt from 'bcryptjs'
|
import bcrypt from 'bcryptjs'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'node:crypto'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
newPassword: string
|
newPassword: string
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
import { checkAuthorization } from '../../../lib/auth'
|
import { checkAuthorization } from '../../../lib/auth'
|
||||||
import { users } from '../../../lib/tables'
|
import { users } from '../../../lib/tables'
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'node:crypto'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
newUsername: string
|
newUsername: string
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
import { resetCodes, users } from '../../../lib/tables'
|
import { resetCodes, users } from '../../../lib/tables'
|
||||||
import { and, desc, eq, sql } from 'drizzle-orm'
|
import { and, desc, eq, sql } from 'drizzle-orm'
|
||||||
import isEmail from 'validator/lib/isEmail'
|
import isEmail from 'validator/lib/isEmail'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'node:crypto'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
token: string | null
|
token: string | null
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ export const handler = async (context: Context) => {
|
|||||||
id: users.id,
|
id: users.id,
|
||||||
username: users.username,
|
username: users.username,
|
||||||
password: users.password,
|
password: users.password,
|
||||||
token: users.token
|
token: users.token,
|
||||||
|
admin: users.admin
|
||||||
})
|
})
|
||||||
.from(users)
|
.from(users)
|
||||||
.where(eq(users.username, body.username))
|
.where(eq(users.username, body.username))
|
||||||
@@ -61,7 +62,8 @@ export const handler = async (context: Context) => {
|
|||||||
data: {
|
data: {
|
||||||
session: user[0].token,
|
session: user[0].token,
|
||||||
username: user[0].username,
|
username: user[0].username,
|
||||||
id: user[0].id
|
id: user[0].id,
|
||||||
|
admin: user[0].admin
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
import isEmail from 'validator/lib/isEmail'
|
import isEmail from 'validator/lib/isEmail'
|
||||||
import { berryDashUserData, users } from '../../../lib/tables'
|
import { berryDashUserData, users } from '../../../lib/tables'
|
||||||
import bcrypt from 'bcryptjs'
|
import bcrypt from 'bcryptjs'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'node:crypto'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
token: string | null
|
token: string | null
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
import { resetCodes, users } from '../../../lib/tables'
|
import { resetCodes, users } from '../../../lib/tables'
|
||||||
import { and, desc, eq, sql } from 'drizzle-orm'
|
import { and, desc, eq, sql } from 'drizzle-orm'
|
||||||
import bcrypt from 'bcryptjs'
|
import bcrypt from 'bcryptjs'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'node:crypto'
|
||||||
|
|
||||||
type Body = {
|
type Body = {
|
||||||
token: string | null
|
token: string | null
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const handler = async () => {
|
|||||||
|
|
||||||
const version = await db
|
const version = await db
|
||||||
.select({
|
.select({
|
||||||
downloadUrlVersion: launcherVersionManifest.downloadUrlVersion
|
versionName: launcherVersionManifest.versionName
|
||||||
})
|
})
|
||||||
.from(launcherVersionManifest)
|
.from(launcherVersionManifest)
|
||||||
.where(
|
.where(
|
||||||
@@ -25,5 +25,5 @@ export const handler = async () => {
|
|||||||
|
|
||||||
connection.end()
|
connection.end()
|
||||||
|
|
||||||
return version[0] ? version[0].downloadUrlVersion : '-1'
|
return version[0] ? version[0].versionName : '-1'
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
import { getDatabaseConnection, jsonResponse } from '../../../lib/util'
|
import {
|
||||||
|
generateSignature,
|
||||||
|
getDatabaseConnection,
|
||||||
|
jsonResponse
|
||||||
|
} from '../../../lib/util'
|
||||||
import { berryDashSplashTexts } from '../../../lib/tables'
|
import { berryDashSplashTexts } from '../../../lib/tables'
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
import { Context } from 'elysia'
|
import { Context } from 'elysia'
|
||||||
@@ -40,9 +44,13 @@ export const handler = async (context: Context) => {
|
|||||||
})
|
})
|
||||||
.map(i => atob(i.content))
|
.map(i => atob(i.content))
|
||||||
|
|
||||||
return new Response(data.join('\n'), {
|
const body = data.join('\n')
|
||||||
|
return new Response(body, {
|
||||||
status: 200,
|
status: 200,
|
||||||
headers: { 'Content-Type': 'text/plain' }
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
'X-Signature': generateSignature(body)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return jsonResponse(
|
return jsonResponse(
|
||||||
|
|||||||
@@ -11,7 +11,19 @@ export const handler = async ({ request, set }: Context) => {
|
|||||||
const requester = request.headers.get('Requester') ?? '0'
|
const requester = request.headers.get('Requester') ?? '0'
|
||||||
const clientVersion = request.headers.get('ClientVersion') ?? '0'
|
const clientVersion = request.headers.get('ClientVersion') ?? '0'
|
||||||
|
|
||||||
if (requester === 'BerryDashGodotClient') return 'all;1.0.0'
|
if (requester === 'BerryDashGodotClient') {
|
||||||
|
const allowedVersions = ["1.0.0", "1.1.0"]
|
||||||
|
|
||||||
|
let permissions = "all"
|
||||||
|
|
||||||
|
if (allowedVersions.indexOf(clientVersion) !== -1) {
|
||||||
|
permissions = "all"
|
||||||
|
} else {
|
||||||
|
permissions = "client"
|
||||||
|
}
|
||||||
|
|
||||||
|
return permissions + ';' + allowedVersions[allowedVersions.length - 1]
|
||||||
|
}
|
||||||
else if (isLatestVersion(clientVersion)) return '1'
|
else if (isLatestVersion(clientVersion)) return '1'
|
||||||
else if (isBetaVersion(clientVersion)) return '4'
|
else if (isBetaVersion(clientVersion)) return '4'
|
||||||
else if (
|
else if (
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
jsonResponse,
|
jsonResponse,
|
||||||
validateTurnstile
|
validateTurnstile
|
||||||
} from '../lib/util'
|
} from '../lib/util'
|
||||||
import { randomBytes } from 'crypto'
|
import { randomBytes } from 'node:crypto'
|
||||||
import { verifyCodes } from '../lib/tables'
|
import { verifyCodes } from '../lib/tables'
|
||||||
import { and, desc, eq, sql } from 'drizzle-orm'
|
import { and, desc, eq, sql } from 'drizzle-orm'
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
import { Context } from 'elysia'
|
|
||||||
import { launcherVersionManifest } from '../../lib/tables'
|
|
||||||
import { getDatabaseConnection } from '../../lib/util'
|
|
||||||
import { eq, sql } from 'drizzle-orm'
|
|
||||||
|
|
||||||
export const handler = async (context: Context) => {
|
|
||||||
const dbResult = getDatabaseConnection(0)
|
|
||||||
if (!dbResult) return null
|
|
||||||
const { connection, db } = dbResult
|
|
||||||
|
|
||||||
await db
|
|
||||||
.update(launcherVersionManifest)
|
|
||||||
.set({
|
|
||||||
downloads: sql`${launcherVersionManifest.downloads} + 1`
|
|
||||||
})
|
|
||||||
.where(eq(launcherVersionManifest.id, context.query.id))
|
|
||||||
|
|
||||||
connection.end()
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
import { Context } from 'elysia'
|
||||||
|
import { files, launcherVersionManifest, mods } from '../../../lib/tables'
|
||||||
|
import { getDatabaseConnection, jsonResponse } from '../../../lib/util'
|
||||||
|
import { eq, sql } from 'drizzle-orm'
|
||||||
|
|
||||||
|
export const handler = async (context: Context) => {
|
||||||
|
const dbResult = getDatabaseConnection(0)
|
||||||
|
if (!dbResult) return jsonResponse({ success: false, data: null }, 400)
|
||||||
|
const { connection, db } = dbResult
|
||||||
|
|
||||||
|
const versionId = context.query.versionId
|
||||||
|
const modId = context.query.modId
|
||||||
|
const downloadId = Number(context.query.downloadId)
|
||||||
|
|
||||||
|
const result = await db
|
||||||
|
.select({ path: files.path, hash: files.hash, host: files.host })
|
||||||
|
.from(files)
|
||||||
|
.where(eq(files.id, downloadId))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
if (result.length != 1)
|
||||||
|
return jsonResponse({ success: false, data: null }, 400)
|
||||||
|
|
||||||
|
if (versionId)
|
||||||
|
await db
|
||||||
|
.update(launcherVersionManifest)
|
||||||
|
.set({ downloadCount: sql`${launcherVersionManifest.downloadCount} + 1` })
|
||||||
|
.where(eq(launcherVersionManifest.id, versionId))
|
||||||
|
|
||||||
|
if (modId)
|
||||||
|
await db
|
||||||
|
.update(mods)
|
||||||
|
.set({ downloadCount: sql`${mods.downloadCount} + 1` })
|
||||||
|
.where(eq(mods.id, Number(modId)))
|
||||||
|
|
||||||
|
connection.end()
|
||||||
|
|
||||||
|
return jsonResponse({
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
url:
|
||||||
|
result[0].host == 1
|
||||||
|
? 'https://github.com/' + result[0].path
|
||||||
|
: 'https://archive.org/download/lncvrt-games-archive/' + result[0].path,
|
||||||
|
hash: result[0].hash
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { launcherUpdates } from '../../lib/tables'
|
|
||||||
import { desc, eq } from 'drizzle-orm'
|
|
||||||
import { getDatabaseConnection, jsonResponse } from '../../lib/util'
|
|
||||||
|
|
||||||
export const handler = async () => {
|
|
||||||
const dbResult = getDatabaseConnection(0)
|
|
||||||
if (!dbResult)
|
|
||||||
return jsonResponse({ error: 'Failed to connect to database' }, 500)
|
|
||||||
const { connection, db } = dbResult
|
|
||||||
|
|
||||||
const version = await db
|
|
||||||
.select({
|
|
||||||
id: launcherUpdates.id
|
|
||||||
})
|
|
||||||
.from(launcherUpdates)
|
|
||||||
.where(eq(launcherUpdates.hidden, false))
|
|
||||||
.orderBy(desc(launcherUpdates.place))
|
|
||||||
.limit(1)
|
|
||||||
|
|
||||||
connection.end()
|
|
||||||
|
|
||||||
return version[0].id
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
import { launcherUpdates } from '../../../lib/tables'
|
||||||
|
import { desc } from 'drizzle-orm'
|
||||||
|
import {
|
||||||
|
generateSignature,
|
||||||
|
getDatabaseConnection,
|
||||||
|
jsonResponse
|
||||||
|
} from '../../../lib/util'
|
||||||
|
|
||||||
|
export const handler = async () => {
|
||||||
|
const dbResult = getDatabaseConnection(0)
|
||||||
|
if (!dbResult)
|
||||||
|
return jsonResponse({ error: 'Failed to connect to database' }, 500)
|
||||||
|
const { connection, db } = dbResult
|
||||||
|
|
||||||
|
const version = await db
|
||||||
|
.select({
|
||||||
|
version: launcherUpdates.version
|
||||||
|
})
|
||||||
|
.from(launcherUpdates)
|
||||||
|
.orderBy(desc(launcherUpdates.id))
|
||||||
|
.limit(1)
|
||||||
|
|
||||||
|
connection.end()
|
||||||
|
|
||||||
|
return new Response(version[0].version, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'text/plain',
|
||||||
|
'X-Signature': generateSignature(version[0].version)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import { loaderUpdates } from '../../../lib/tables'
|
|
||||||
import { desc, eq } from 'drizzle-orm'
|
|
||||||
import { getDatabaseConnection, jsonResponse } from '../../../lib/util'
|
|
||||||
|
|
||||||
export const handler = async () => {
|
|
||||||
const dbResult = getDatabaseConnection(0)
|
|
||||||
if (!dbResult)
|
|
||||||
return jsonResponse({ error: 'Failed to connect to database' }, 500)
|
|
||||||
const { connection, db } = dbResult
|
|
||||||
|
|
||||||
const version = await db
|
|
||||||
.select({
|
|
||||||
id: loaderUpdates.id
|
|
||||||
})
|
|
||||||
.from(loaderUpdates)
|
|
||||||
.where(eq(loaderUpdates.hidden, false))
|
|
||||||
.orderBy(desc(loaderUpdates.place))
|
|
||||||
.limit(1)
|
|
||||||
|
|
||||||
connection.end()
|
|
||||||
|
|
||||||
return version[0].id
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export const handler = async () => {
|
||||||
|
return '-1'
|
||||||
|
}
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
import { launcherUpdates } from '../../../lib/tables'
|
|
||||||
import { desc, eq } from 'drizzle-orm'
|
|
||||||
import { getDatabaseConnection, jsonResponse } from '../../../lib/util'
|
|
||||||
import { Context } from 'elysia'
|
|
||||||
|
|
||||||
export const handler = async (context: Context) => {
|
|
||||||
const dbResult = getDatabaseConnection(0)
|
|
||||||
if (!dbResult)
|
|
||||||
return jsonResponse({ error: 'Failed to connect to database' }, 500)
|
|
||||||
const { connection, db } = dbResult
|
|
||||||
|
|
||||||
const platform = context.query.platform as string | undefined
|
|
||||||
const arch = context.query.arch as string | undefined
|
|
||||||
let showAll = false
|
|
||||||
|
|
||||||
if (!platform || !arch) {
|
|
||||||
showAll = true
|
|
||||||
}
|
|
||||||
|
|
||||||
let platString = null
|
|
||||||
if (!showAll) {
|
|
||||||
if (platform == 'windows') {
|
|
||||||
if (arch == 'x86_64') platString = 'windows'
|
|
||||||
else if (arch == 'aarch64') platString = 'windows-arm64'
|
|
||||||
else {
|
|
||||||
connection.end()
|
|
||||||
return jsonResponse(
|
|
||||||
{ error: 'Unsupported architecture for Windows' },
|
|
||||||
400
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (platform == 'linux') {
|
|
||||||
if (arch == 'x86_64') platString = 'linux'
|
|
||||||
else {
|
|
||||||
connection.end()
|
|
||||||
return jsonResponse(
|
|
||||||
{ error: 'Unsupported architecture for Linux' },
|
|
||||||
400
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (platform == 'macos') {
|
|
||||||
if (arch == 'x86_64') platString = 'macos-intel'
|
|
||||||
else if (arch == 'aarch64') platString = 'macos-silicon'
|
|
||||||
else {
|
|
||||||
connection.end()
|
|
||||||
return jsonResponse(
|
|
||||||
{ error: 'Unsupported architecture for macOS' },
|
|
||||||
400
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
connection.end()
|
|
||||||
return jsonResponse({ error: 'Unsupported platform' }, 400)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const versionsRaw = await db
|
|
||||||
.select({
|
|
||||||
id: launcherUpdates.id,
|
|
||||||
releaseDate: launcherUpdates.releaseDate,
|
|
||||||
downloadUrls: launcherUpdates.downloadUrls,
|
|
||||||
platforms: launcherUpdates.platforms,
|
|
||||||
sha512sums: launcherUpdates.sha512sums
|
|
||||||
})
|
|
||||||
.from(launcherUpdates)
|
|
||||||
.where(eq(launcherUpdates.hidden, false))
|
|
||||||
.orderBy(desc(launcherUpdates.place))
|
|
||||||
.limit(1)
|
|
||||||
.execute()
|
|
||||||
|
|
||||||
const versions = versionsRaw
|
|
||||||
.map(v => ({
|
|
||||||
...v,
|
|
||||||
downloadUrls: JSON.parse(v.downloadUrls),
|
|
||||||
platforms: JSON.parse(v.platforms),
|
|
||||||
sha512sums: JSON.parse(v.sha512sums),
|
|
||||||
downloadUrl: undefined as string | undefined,
|
|
||||||
sha512sum: undefined as string | undefined
|
|
||||||
}))
|
|
||||||
.filter(v => {
|
|
||||||
if (showAll || !platString) {
|
|
||||||
delete v.downloadUrl
|
|
||||||
delete v.sha512sum
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
const i = v.platforms.indexOf(platString)
|
|
||||||
if (i !== -1) {
|
|
||||||
v.downloadUrl = v.downloadUrls[i]
|
|
||||||
v.sha512sum = v.sha512sums[i]
|
|
||||||
delete v.downloadUrls
|
|
||||||
delete v.platforms
|
|
||||||
delete v.sha512sums
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
connection.end()
|
|
||||||
|
|
||||||
return jsonResponse(versions[0])
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,152 @@
|
|||||||
|
import { mods, modVersions, users } from '../../../lib/tables'
|
||||||
|
import { and, asc, desc, eq, inArray, like } from 'drizzle-orm'
|
||||||
|
import { getDatabaseConnection, jsonResponse } from '../../../lib/util'
|
||||||
|
import { Context } from 'elysia'
|
||||||
|
|
||||||
|
export const handler = async (context: Context) => {
|
||||||
|
const dbResult = getDatabaseConnection(0)
|
||||||
|
if (!dbResult)
|
||||||
|
return jsonResponse({ error: 'Failed to connect to database' }, 500)
|
||||||
|
const { connection, db } = dbResult
|
||||||
|
|
||||||
|
const clientplatform = context.headers.clientplatform
|
||||||
|
const platform = clientplatform?.split('-')[0]
|
||||||
|
const arch = clientplatform?.split('-')[1]
|
||||||
|
const version = context.query.version
|
||||||
|
|
||||||
|
let platformsToShow: string[] | null = null
|
||||||
|
if (platform == 'windows') {
|
||||||
|
if (arch == 'x86') platformsToShow = ['windows-x86']
|
||||||
|
else if (arch == 'x86_64' || arch == 'x64')
|
||||||
|
platformsToShow = ['windows-x64', 'windows-x86']
|
||||||
|
else if (arch == 'aarch64' || arch == 'arm64')
|
||||||
|
platformsToShow = ['windows-arm64']
|
||||||
|
else {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{
|
||||||
|
message: 'Unsupported architecture for Windows',
|
||||||
|
versions: null,
|
||||||
|
games: null
|
||||||
|
},
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (platform == 'linux') {
|
||||||
|
if (arch == 'x86') platformsToShow = ['linux-x64']
|
||||||
|
else if (arch == 'x86_64' || arch == 'x64')
|
||||||
|
platformsToShow = ['linux-x64', 'linux-x86', 'windows-x64', 'windows-x86']
|
||||||
|
else if (arch == 'aarch64' || arch == 'arm64')
|
||||||
|
platformsToShow = ['linux-arm64']
|
||||||
|
else {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{
|
||||||
|
message: 'Unsupported architecture for Linux',
|
||||||
|
versions: null,
|
||||||
|
games: null
|
||||||
|
},
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (platform == 'macos') {
|
||||||
|
if (arch == 'x86_64' || arch == 'x64')
|
||||||
|
platformsToShow = ['macos-x64', 'macos-universal']
|
||||||
|
else if (arch == 'aarch64' || arch == 'arm64')
|
||||||
|
platformsToShow = ['macos-arm64', 'macos-universal', 'macos-x64']
|
||||||
|
else {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{
|
||||||
|
message: 'Unsupported architecture for macOS',
|
||||||
|
versions: null,
|
||||||
|
games: null
|
||||||
|
},
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (platform == 'android') platformsToShow = ['android']
|
||||||
|
else if (platform == 'ios') platformsToShow = ['ios']
|
||||||
|
else {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{ message: 'Unsupported platform', versions: null, games: null },
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const modsRaw = await db
|
||||||
|
.select({
|
||||||
|
id: mods.id,
|
||||||
|
name: mods.name,
|
||||||
|
creators: mods.creators,
|
||||||
|
description: mods.description,
|
||||||
|
downloadCount: mods.downloadCount
|
||||||
|
})
|
||||||
|
.from(mods)
|
||||||
|
.where(eq(mods.hidden, false))
|
||||||
|
.orderBy(asc(mods.downloadCount), asc(mods.id))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
const modsFinal = (
|
||||||
|
await Promise.all(
|
||||||
|
modsRaw.map(async v => {
|
||||||
|
const vi = await db
|
||||||
|
.select({
|
||||||
|
id: modVersions.id,
|
||||||
|
downloads: modVersions.downloads,
|
||||||
|
gameVersion: modVersions.gameVersion,
|
||||||
|
releaseDate: modVersions.releaseDate,
|
||||||
|
changelog: modVersions.changelog
|
||||||
|
})
|
||||||
|
.from(modVersions)
|
||||||
|
.where(
|
||||||
|
and(
|
||||||
|
eq(modVersions.hidden, false),
|
||||||
|
eq(modVersions.gameVersion, version),
|
||||||
|
like(modVersions.id, `${v.id}%`)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.orderBy(desc(modVersions.releaseDate))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
if (!vi || vi.length < 1) return
|
||||||
|
|
||||||
|
const downloads: Record<string, number> = JSON.parse(vi[0].downloads)
|
||||||
|
let download: string | undefined = undefined
|
||||||
|
|
||||||
|
for (const key of platformsToShow) {
|
||||||
|
if (key in downloads) {
|
||||||
|
download = key
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!download || !downloads[download]) return
|
||||||
|
|
||||||
|
const creators = await db
|
||||||
|
.select({ username: users.username })
|
||||||
|
.from(users)
|
||||||
|
.where(inArray(users.id, JSON.parse(v.creators)))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: v.id,
|
||||||
|
name: v.name,
|
||||||
|
description: v.description,
|
||||||
|
creators: creators.map(u => u.username),
|
||||||
|
downloads: v.downloadCount,
|
||||||
|
released: vi[vi.length - 1].releaseDate,
|
||||||
|
updated: vi[0].releaseDate,
|
||||||
|
latestVersion: vi[0].id.substring(String(v.id).length + 1),
|
||||||
|
latestDownload: downloads[download],
|
||||||
|
changelog: vi[0].changelog
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
).filter(v => v != null)
|
||||||
|
|
||||||
|
connection.end()
|
||||||
|
|
||||||
|
return jsonResponse(modsFinal)
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import { files, launcherUpdates } from '../../../lib/tables'
|
||||||
|
import { desc, eq } from 'drizzle-orm'
|
||||||
|
import { getDatabaseConnection, jsonResponse } from '../../../lib/util'
|
||||||
|
import { Context } from 'elysia'
|
||||||
|
|
||||||
|
export const handler = async (context: Context) => {
|
||||||
|
const dbResult = getDatabaseConnection(0)
|
||||||
|
if (!dbResult) return
|
||||||
|
const { connection, db } = dbResult
|
||||||
|
|
||||||
|
const target = context.query.target
|
||||||
|
const arch = context.query.arch ?? undefined
|
||||||
|
// const currentVersion = context.query.currentVersion
|
||||||
|
|
||||||
|
const versionsData = await db
|
||||||
|
.select({
|
||||||
|
version: launcherUpdates.version,
|
||||||
|
notes: launcherUpdates.notes,
|
||||||
|
releaseDate: launcherUpdates.releaseDate,
|
||||||
|
downloadData: launcherUpdates.downloadData
|
||||||
|
})
|
||||||
|
.from(launcherUpdates)
|
||||||
|
.orderBy(desc(launcherUpdates.id))
|
||||||
|
.limit(1)
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
if (versionsData.length != 1) return
|
||||||
|
|
||||||
|
const downloadData = JSON.parse(versionsData[0].downloadData)[
|
||||||
|
(target.split('-')[0] == 'linux' && arch ? target + '-' + arch : target)
|
||||||
|
.replace('windows', 'win')
|
||||||
|
.replace('darwin', 'macos')
|
||||||
|
.replace('x86_64', 'x64')
|
||||||
|
.replace('aarch64', 'arm64')
|
||||||
|
.replace('fedora', 'redhat')
|
||||||
|
]
|
||||||
|
|
||||||
|
if (!downloadData) return
|
||||||
|
|
||||||
|
const fileInfo = await db
|
||||||
|
.select({ path: files.path })
|
||||||
|
.from(files)
|
||||||
|
.where(eq(files.id, downloadData.download))
|
||||||
|
|
||||||
|
if (fileInfo.length != 1) return
|
||||||
|
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse({
|
||||||
|
version: versionsData[0].version,
|
||||||
|
notes: versionsData[0].notes,
|
||||||
|
pub_date: versionsData[0].releaseDate,
|
||||||
|
url: 'https://archive.org/download/lncvrt-games-archive/' + fileInfo[0].path,
|
||||||
|
signature: downloadData.signature
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -1,177 +0,0 @@
|
|||||||
import { games, launcherVersionManifest } from '../../lib/tables'
|
|
||||||
import { asc, desc, eq } from 'drizzle-orm'
|
|
||||||
import { getDatabaseConnection, jsonResponse } from '../../lib/util'
|
|
||||||
import { Context } from 'elysia'
|
|
||||||
|
|
||||||
export const handler = async (context: Context) => {
|
|
||||||
const dbResult = getDatabaseConnection(0)
|
|
||||||
if (!dbResult)
|
|
||||||
return jsonResponse({ error: 'Failed to connect to database' }, 500)
|
|
||||||
const { connection, db } = dbResult
|
|
||||||
|
|
||||||
const platform = context.query.platform as string | undefined
|
|
||||||
const arch = context.query.arch as string | undefined
|
|
||||||
let showAll = false
|
|
||||||
|
|
||||||
if (!platform || !arch) {
|
|
||||||
showAll = true
|
|
||||||
}
|
|
||||||
|
|
||||||
let platString = null
|
|
||||||
if (!showAll) {
|
|
||||||
if (platform == 'windows') {
|
|
||||||
if (arch == 'x86_64' || arch == 'x64') platString = 'windows'
|
|
||||||
else if (arch == 'aarch64' || arch == 'arm64')
|
|
||||||
platString = 'windows-arm64'
|
|
||||||
else {
|
|
||||||
connection.end()
|
|
||||||
return jsonResponse(
|
|
||||||
{
|
|
||||||
message: 'Unsupported architecture for Windows',
|
|
||||||
versions: null,
|
|
||||||
games: null
|
|
||||||
},
|
|
||||||
400
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (platform == 'linux') {
|
|
||||||
if (arch == 'x86_64' || arch == 'x64') platString = 'linux'
|
|
||||||
else {
|
|
||||||
connection.end()
|
|
||||||
return jsonResponse(
|
|
||||||
{
|
|
||||||
message: 'Unsupported architecture for Linux',
|
|
||||||
versions: null,
|
|
||||||
games: null
|
|
||||||
},
|
|
||||||
400
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (platform == 'macos') {
|
|
||||||
if (arch == 'x86_64' || arch == 'x64') platString = 'macos'
|
|
||||||
else if (arch == 'aarch64' || arch == 'arm64') platString = 'macos'
|
|
||||||
else {
|
|
||||||
connection.end()
|
|
||||||
return jsonResponse(
|
|
||||||
{
|
|
||||||
message: 'Unsupported architecture for macOS',
|
|
||||||
versions: null,
|
|
||||||
games: null
|
|
||||||
},
|
|
||||||
400
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if (platform == 'android') platString = 'android'
|
|
||||||
else if (platform == 'ios') platString = 'ios'
|
|
||||||
else {
|
|
||||||
connection.end()
|
|
||||||
return jsonResponse(
|
|
||||||
{ message: 'Unsupported platform', versions: null, games: null },
|
|
||||||
400
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const versionsRaw = await db
|
|
||||||
.select({
|
|
||||||
id: launcherVersionManifest.id,
|
|
||||||
displayName: launcherVersionManifest.displayName,
|
|
||||||
releaseDate: launcherVersionManifest.releaseDate,
|
|
||||||
game: launcherVersionManifest.game,
|
|
||||||
downloadUrlVersion: launcherVersionManifest.downloadUrlVersion,
|
|
||||||
downloadUrls: launcherVersionManifest.downloadUrls,
|
|
||||||
platforms: launcherVersionManifest.platforms,
|
|
||||||
executables: launcherVersionManifest.executables,
|
|
||||||
sha512sums: launcherVersionManifest.sha512sums,
|
|
||||||
sizes: launcherVersionManifest.sizes,
|
|
||||||
place: launcherVersionManifest.place,
|
|
||||||
changelog: launcherVersionManifest.changelog,
|
|
||||||
category: launcherVersionManifest.category,
|
|
||||||
lastRevision: launcherVersionManifest.lastRevision
|
|
||||||
})
|
|
||||||
.from(launcherVersionManifest)
|
|
||||||
.where(eq(launcherVersionManifest.hidden, false))
|
|
||||||
.orderBy(
|
|
||||||
asc(launcherVersionManifest.game),
|
|
||||||
desc(launcherVersionManifest.place)
|
|
||||||
)
|
|
||||||
.execute()
|
|
||||||
|
|
||||||
const versions = versionsRaw
|
|
||||||
.map(v => ({
|
|
||||||
...v,
|
|
||||||
downloadUrls: JSON.parse(
|
|
||||||
v.downloadUrls.replaceAll('%version%', v.downloadUrlVersion)
|
|
||||||
),
|
|
||||||
platforms: JSON.parse(v.platforms),
|
|
||||||
executables: JSON.parse(v.executables),
|
|
||||||
sha512sums: JSON.parse(v.sha512sums),
|
|
||||||
sizes: JSON.parse(v.sizes),
|
|
||||||
downloadUrlVersion: undefined,
|
|
||||||
downloadUrl: undefined as string | undefined,
|
|
||||||
executable: undefined as string | undefined,
|
|
||||||
sha512sum: undefined as string | undefined,
|
|
||||||
size: undefined as number | undefined,
|
|
||||||
wine: undefined as boolean | undefined
|
|
||||||
}))
|
|
||||||
.filter(v => {
|
|
||||||
delete v.downloadUrlVersion
|
|
||||||
if (showAll || !platString) {
|
|
||||||
delete v.downloadUrl
|
|
||||||
delete v.executable
|
|
||||||
delete v.sha512sum
|
|
||||||
delete v.size
|
|
||||||
delete v.wine
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
let i = v.platforms.indexOf(platString)
|
|
||||||
if (i !== -1) {
|
|
||||||
v.downloadUrl = v.downloadUrls[i]
|
|
||||||
v.executable = v.executables[i]
|
|
||||||
v.sha512sum = v.sha512sums[i]
|
|
||||||
v.size = v.sizes[i]
|
|
||||||
delete v.downloadUrls
|
|
||||||
delete v.platforms
|
|
||||||
delete v.executables
|
|
||||||
delete v.sha512sums
|
|
||||||
delete v.sizes
|
|
||||||
delete v.wine
|
|
||||||
return true
|
|
||||||
} else if (platString == 'linux') {
|
|
||||||
i = v.platforms.indexOf('windows')
|
|
||||||
if (i !== -1) {
|
|
||||||
v.downloadUrl = v.downloadUrls[i]
|
|
||||||
v.executable = v.executables[i]
|
|
||||||
v.sha512sum = v.sha512sums[i]
|
|
||||||
v.size = v.sizes[i]
|
|
||||||
v.wine = true
|
|
||||||
delete v.downloadUrls
|
|
||||||
delete v.platforms
|
|
||||||
delete v.executables
|
|
||||||
delete v.sha512sums
|
|
||||||
delete v.sizes
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
const gamesListRaw = await db.select().from(games).execute()
|
|
||||||
|
|
||||||
const gamesList = gamesListRaw.map(v => ({
|
|
||||||
...v,
|
|
||||||
categoryNames: JSON.parse(v.categoryNames)
|
|
||||||
}))
|
|
||||||
|
|
||||||
connection.end()
|
|
||||||
|
|
||||||
const seenGames = new Set<number>()
|
|
||||||
const finalVersions = versions.filter(v => {
|
|
||||||
if (platString !== 'android' && platString !== 'ios') return true
|
|
||||||
if (seenGames.has(v.game)) return false
|
|
||||||
seenGames.add(v.game)
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
return jsonResponse({ versions: finalVersions, games: gamesList })
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
import { games, launcherVersionManifest } from '../../../lib/tables'
|
||||||
|
import { and, asc, desc, eq } from 'drizzle-orm'
|
||||||
|
import { getDatabaseConnection, jsonResponse } from '../../../lib/util'
|
||||||
|
import { Context } from 'elysia'
|
||||||
|
|
||||||
|
export const handler = async (context: Context) => {
|
||||||
|
const dbResult = getDatabaseConnection(0)
|
||||||
|
if (!dbResult)
|
||||||
|
return jsonResponse({ error: 'Failed to connect to database' }, 500)
|
||||||
|
const { connection, db } = dbResult
|
||||||
|
|
||||||
|
const authorization =
|
||||||
|
context.headers.authorization?.trim() == '' ||
|
||||||
|
context.headers.authorization == null
|
||||||
|
? null
|
||||||
|
: context.headers.authorization
|
||||||
|
const clientplatform = context.headers.clientplatform
|
||||||
|
const platform = clientplatform?.split('-')[0]
|
||||||
|
const arch = clientplatform?.split('-')[1]
|
||||||
|
|
||||||
|
let showAll = false
|
||||||
|
if (!platform || !arch) showAll = true
|
||||||
|
|
||||||
|
let platformsToShow: string[] | null = null
|
||||||
|
if (!showAll) {
|
||||||
|
if (platform == 'windows') {
|
||||||
|
if (arch == 'x86') platformsToShow = ['windows-x86']
|
||||||
|
else if (arch == 'x86_64' || arch == 'x64')
|
||||||
|
platformsToShow = ['windows-x64', 'windows-x86']
|
||||||
|
else if (arch == 'aarch64' || arch == 'arm64')
|
||||||
|
platformsToShow = ['windows-arm64']
|
||||||
|
else {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{
|
||||||
|
message: 'Unsupported architecture for Windows',
|
||||||
|
versions: null,
|
||||||
|
games: null
|
||||||
|
},
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (platform == 'linux') {
|
||||||
|
if (arch == 'x86') platformsToShow = ['linux-x86']
|
||||||
|
else if (arch == 'x86_64' || arch == 'x64')
|
||||||
|
platformsToShow = [
|
||||||
|
'linux-x64',
|
||||||
|
'linux-x86',
|
||||||
|
'windows-x64',
|
||||||
|
'windows-x86'
|
||||||
|
]
|
||||||
|
else if (arch == 'aarch64' || arch == 'arm64')
|
||||||
|
platformsToShow = ['linux-arm64']
|
||||||
|
else {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{
|
||||||
|
message: 'Unsupported architecture for Linux',
|
||||||
|
versions: null,
|
||||||
|
games: null
|
||||||
|
},
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (platform == 'macos') {
|
||||||
|
if (arch == 'x86_64' || arch == 'x64')
|
||||||
|
platformsToShow = ['macos-x64', 'macos-universal']
|
||||||
|
else if (arch == 'aarch64' || arch == 'arm64')
|
||||||
|
platformsToShow = ['macos-arm64', 'macos-universal', 'macos-x64']
|
||||||
|
else {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{
|
||||||
|
message: 'Unsupported architecture for macOS',
|
||||||
|
versions: null,
|
||||||
|
games: null
|
||||||
|
},
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else if (platform == 'android') platformsToShow = ['android']
|
||||||
|
else if (platform == 'ios') platformsToShow = ['ios']
|
||||||
|
else {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{ message: 'Unsupported platform', versions: null, games: null },
|
||||||
|
400
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const versionsRaw = await db
|
||||||
|
.select({
|
||||||
|
id: launcherVersionManifest.id,
|
||||||
|
displayName: launcherVersionManifest.displayName,
|
||||||
|
releaseDate: launcherVersionManifest.releaseDate,
|
||||||
|
game: launcherVersionManifest.game,
|
||||||
|
versionName: launcherVersionManifest.versionName,
|
||||||
|
downloads: launcherVersionManifest.downloads,
|
||||||
|
executables: launcherVersionManifest.executables,
|
||||||
|
modSupportDownloads: launcherVersionManifest.modSupportDownloads,
|
||||||
|
place: launcherVersionManifest.place,
|
||||||
|
changelog: launcherVersionManifest.changelog,
|
||||||
|
category: launcherVersionManifest.category,
|
||||||
|
lastRevision: launcherVersionManifest.lastRevision
|
||||||
|
})
|
||||||
|
.from(launcherVersionManifest)
|
||||||
|
.where(eq(launcherVersionManifest.hidden, false))
|
||||||
|
.orderBy(
|
||||||
|
asc(launcherVersionManifest.game),
|
||||||
|
desc(launcherVersionManifest.place)
|
||||||
|
)
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
const versions = versionsRaw
|
||||||
|
.map(v => {
|
||||||
|
const downloads: Record<string, number> = JSON.parse(v.downloads)
|
||||||
|
const executables: (string | null)[] = JSON.parse(v.executables)
|
||||||
|
const modSupportDownload: Record<string, number> = JSON.parse(
|
||||||
|
v.modSupportDownloads
|
||||||
|
)
|
||||||
|
|
||||||
|
let download: string | undefined = undefined
|
||||||
|
let executable: string | null | undefined = undefined
|
||||||
|
|
||||||
|
if (platformsToShow) {
|
||||||
|
const downloadKeys = Object.keys(downloads)
|
||||||
|
for (const key of platformsToShow) {
|
||||||
|
if (key in downloads) {
|
||||||
|
download = key
|
||||||
|
const idx = downloadKeys.indexOf(key)
|
||||||
|
executable = executables[idx] ?? null
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const { versionName, ...rest } = v
|
||||||
|
return {
|
||||||
|
...rest,
|
||||||
|
executables: platformsToShow ? undefined : executables,
|
||||||
|
executable: platformsToShow ? executable : undefined,
|
||||||
|
downloads: platformsToShow ? undefined : downloads,
|
||||||
|
modSupportDownloads: platformsToShow ? undefined : modSupportDownload,
|
||||||
|
download: platformsToShow
|
||||||
|
? download
|
||||||
|
? downloads[download]
|
||||||
|
: undefined
|
||||||
|
: undefined,
|
||||||
|
modSupportDownload: platformsToShow
|
||||||
|
? download
|
||||||
|
? modSupportDownload[download]
|
||||||
|
: undefined
|
||||||
|
: undefined,
|
||||||
|
wine:
|
||||||
|
platformsToShow &&
|
||||||
|
platform == 'linux' &&
|
||||||
|
download?.startsWith('windows')
|
||||||
|
? true
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(v => {
|
||||||
|
if (!platformsToShow) return true
|
||||||
|
return v.download !== undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
const gamesListRaw = await db.select().from(games).execute()
|
||||||
|
const gamesList = gamesListRaw.map(v => ({
|
||||||
|
...v,
|
||||||
|
categoryNames: JSON.parse(v.categoryNames)
|
||||||
|
}))
|
||||||
|
|
||||||
|
connection.end()
|
||||||
|
|
||||||
|
return jsonResponse({ versions: versions, games: gamesList })
|
||||||
|
}
|
||||||
Reference in new issue
Block a user