From 3f1635880a77dd4e0d2ddfc9b4f3009584e6171b Mon Sep 17 00:00:00 2001 From: Daniel McCrystal Date: Mon, 18 Aug 2025 17:47:39 -0400 Subject: [PATCH] tokens fr --- packages/client/src/app.tsx | 5 +- .../20250818213152_tokens/migration.sql | 45 ++++++ packages/server/db/schema.prisma | 19 ++- packages/server/package.json | 3 + packages/server/src/api.ts | 27 ++-- packages/server/src/{db => }/db.ts | 2 +- packages/server/src/db/Games.ts | 4 - packages/server/src/db/Instances.ts | 25 --- packages/server/src/games/simple.ts | 23 ++- packages/server/src/human.ts | 7 +- pnpm-lock.yaml | 150 +++++++++++++----- 11 files changed, 204 insertions(+), 106 deletions(-) create mode 100644 packages/server/db/migrations/20250818213152_tokens/migration.sql rename packages/server/src/{db => }/db.ts (60%) delete mode 100644 packages/server/src/db/Games.ts delete mode 100644 packages/server/src/db/Instances.ts diff --git a/packages/client/src/app.tsx b/packages/client/src/app.tsx index 3117a55..6e22a44 100644 --- a/packages/client/src/app.tsx +++ b/packages/client/src/app.tsx @@ -60,7 +60,4 @@ const App = () => ( ); -// todo: fix this -(Cookies.get("token") == null ? api.whoami.post() : Promise.resolve()).then( - () => render(App, document.getElementById("app")!) -); +api.whoami.post().then(() => render(App, document.getElementById("app")!)); diff --git a/packages/server/db/migrations/20250818213152_tokens/migration.sql b/packages/server/db/migrations/20250818213152_tokens/migration.sql new file mode 100644 index 0000000..117242a --- /dev/null +++ b/packages/server/db/migrations/20250818213152_tokens/migration.sql @@ -0,0 +1,45 @@ +/* + Warnings: + + - The required column `token` was added to the `Human` table with a prisma-level default value. This is not possible if the table is not empty. Please add this column as optional, then populate it before making it required. + +*/ +-- CreateTable +CREATE TABLE "_HumanToInstance" ( + "A" TEXT NOT NULL, + "B" TEXT NOT NULL, + CONSTRAINT "_HumanToInstance_A_fkey" FOREIGN KEY ("A") REFERENCES "Human" ("key") ON DELETE CASCADE ON UPDATE CASCADE, + CONSTRAINT "_HumanToInstance_B_fkey" FOREIGN KEY ("B") REFERENCES "Instance" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); + +-- RedefineTables +PRAGMA defer_foreign_keys=ON; +PRAGMA foreign_keys=OFF; +CREATE TABLE "new_Human" ( + "key" TEXT NOT NULL PRIMARY KEY, + "token" TEXT NOT NULL, + "name" TEXT NOT NULL DEFAULT '__name__', + "lastActive" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); +INSERT INTO "new_Human" ("key", "name") SELECT "key", "name" FROM "Human"; +DROP TABLE "Human"; +ALTER TABLE "new_Human" RENAME TO "Human"; +CREATE UNIQUE INDEX "Human_token_key" ON "Human"("token"); +CREATE TABLE "new_Instance" ( + "id" TEXT NOT NULL PRIMARY KEY, + "createdByKey" TEXT NOT NULL, + "gameKey" TEXT NOT NULL, + "gameState" JSONB NOT NULL, + CONSTRAINT "Instance_gameKey_fkey" FOREIGN KEY ("gameKey") REFERENCES "Game" ("key") ON DELETE RESTRICT ON UPDATE CASCADE +); +INSERT INTO "new_Instance" ("createdByKey", "gameKey", "gameState", "id") SELECT "createdByKey", "gameKey", "gameState", "id" FROM "Instance"; +DROP TABLE "Instance"; +ALTER TABLE "new_Instance" RENAME TO "Instance"; +PRAGMA foreign_keys=ON; +PRAGMA defer_foreign_keys=OFF; + +-- CreateIndex +CREATE UNIQUE INDEX "_HumanToInstance_AB_unique" ON "_HumanToInstance"("A", "B"); + +-- CreateIndex +CREATE INDEX "_HumanToInstance_B_index" ON "_HumanToInstance"("B"); diff --git a/packages/server/db/schema.prisma b/packages/server/db/schema.prisma index a5f916f..9e46f85 100644 --- a/packages/server/db/schema.prisma +++ b/packages/server/db/schema.prisma @@ -17,16 +17,21 @@ model Game { } model Human { - key String @id @default(cuid(2)) - name String @default("") - Instance Instance[] + key String @id @default(cuid()) + token String @unique @default(cuid()) + name String @default("__name__") + lastActive DateTime @default(now()) + + playingInstances Instance[] } model Instance { - id String @id @default(cuid(2)) + id String @id @default(cuid()) createdByKey String - createdBy Human @relation(fields: [createdByKey], references: [key]) gameKey String - game Game @relation(fields: [gameKey], references: [key]) - gameState Json + + players Human[] + + game Game @relation(fields: [gameKey], references: [key]) + gameState Json } diff --git a/packages/server/package.json b/packages/server/package.json index 1a84e15..f2e6bc9 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -16,7 +16,10 @@ "@elysiajs/static": "^1.3.0", "@games/shared": "workspace:*", "@prisma/client": "6.13.0", + "dayjs": "^1.11.13", "elysia": "^1.3.8", + "elysia-ip": "^1.0.10", + "elysia-rate-limit": "^4.4.0", "object-hash": "^3.0.0" }, "devDependencies": { diff --git a/packages/server/src/api.ts b/packages/server/src/api.ts index 27bcbee..5f1606a 100644 --- a/packages/server/src/api.ts +++ b/packages/server/src/api.ts @@ -1,16 +1,20 @@ -import { prisma } from "./db/db"; import { Elysia, t } from "elysia"; -import { Prisma } from "@prisma/client"; import { simpleApi } from "./games/simple"; import { human } from "./human"; +import dayjs from "dayjs"; +import db from "./db"; const api = new Elysia({ prefix: "/api" }) .post("/whoami", async ({ cookie: { token } }) => { if (token.value == null) { - const newHuman = await prisma.human.create({ + const newHuman = await db.human.create({ data: {}, }); - token.value = newHuman.key; + token.set({ + value: newHuman.token, + expires: dayjs().add(1, "year").toDate(), + httpOnly: true, + }); } return token.value; }) @@ -18,7 +22,7 @@ const api = new Elysia({ prefix: "/api" }) .post( "/setName", ({ body: { name }, humanKey }) => - prisma.human.update({ + db.human.update({ where: { key: humanKey, }, @@ -33,16 +37,21 @@ const api = new Elysia({ prefix: "/api" }) } ) .get("/profile", ({ humanKey }) => - prisma.human.findFirst({ where: { key: humanKey } }) + db.human.findFirst({ where: { key: humanKey } }) ) - .get("/games", () => prisma.game.findMany()) + .get("/games", () => [{ key: "simple", name: "simple" }]) - .get("/instances", ({ query: { game } }) => - prisma.instance.findMany({ + .get("/instances", ({ query: { game }, humanKey }) => + db.instance.findMany({ where: { game: { name: game, }, + players: { + some: { + key: humanKey, + }, + }, }, select: { id: true, diff --git a/packages/server/src/db/db.ts b/packages/server/src/db.ts similarity index 60% rename from packages/server/src/db/db.ts rename to packages/server/src/db.ts index 1d6da6d..3cfc482 100644 --- a/packages/server/src/db/db.ts +++ b/packages/server/src/db.ts @@ -2,4 +2,4 @@ import { PrismaClient } from "@prisma/client"; -export const prisma = new PrismaClient(); +export default new PrismaClient(); diff --git a/packages/server/src/db/Games.ts b/packages/server/src/db/Games.ts deleted file mode 100644 index 86d11e0..0000000 --- a/packages/server/src/db/Games.ts +++ /dev/null @@ -1,4 +0,0 @@ -"use server"; -import { prisma } from "./db"; - -export const queryAll = async () => await prisma.game.findMany(); diff --git a/packages/server/src/db/Instances.ts b/packages/server/src/db/Instances.ts deleted file mode 100644 index 71380ee..0000000 --- a/packages/server/src/db/Instances.ts +++ /dev/null @@ -1,25 +0,0 @@ -"use server"; - -import { GameState, newDeck, shuffle } from "../types/cards"; -import { prisma } from "./db"; - -export const queryInstances = async (gameName: string) => - prisma.instance.findMany({ where: { game: { name: gameName } } }); - -export const createInstance = (gameName: string) => - prisma.instance.create({ - data: { - gameState: { deck: shuffle(newDeck()), hand: [] } as GameState, - game: { connect: { name: gameName } }, - }, - }); - -export const getGameState = (instanceId: number) => - prisma.instance - .findUnique({ where: { id: instanceId } }) - .then((i) => i?.gameState as GameState | undefined); - -export const updateGameState = async ( - instanceId: number, - gameState: GameState -) => prisma.instance.update({ where: { id: instanceId }, data: { gameState } }); diff --git a/packages/server/src/games/simple.ts b/packages/server/src/games/simple.ts index e476e2f..3af847b 100644 --- a/packages/server/src/games/simple.ts +++ b/packages/server/src/games/simple.ts @@ -1,14 +1,7 @@ -import { - Card, - Hand, - newDeck, - Pile, - shuffle, - vCard, -} from "../../../shared/cards"; +import { Card, Hand, newDeck, Pile, shuffle, vCard } from "@games/shared/cards"; import { heq } from "@games/shared/utils"; import { Elysia, t } from "elysia"; -import { prisma } from "../db/db"; +import db from "../db"; import { human } from "../human"; // omniscient game state @@ -114,18 +107,22 @@ export const resolveAction = ( export const simpleApi = new Elysia({ prefix: "/simple" }) .use(human) .post("/newGame", ({ humanKey }) => { - return prisma.instance.create({ + console.log("KEY", humanKey); + return db.instance.create({ data: { gameState: newGame([humanKey]), gameKey: "simple", createdByKey: humanKey, + players: { + connect: [{ key: humanKey }], + }, }, }); }) .group("/:instanceId", (app) => app .get("/", ({ params: { instanceId }, humanKey }) => - prisma.instance + db.instance .findUnique({ where: { id: instanceId, @@ -144,7 +141,7 @@ export const simpleApi = new Elysia({ prefix: "/simple" }) .post( "/", ({ params: { instanceId }, body: { action }, humanKey }) => - prisma.instance + db.instance .findUniqueOrThrow({ where: { id: instanceId, @@ -156,7 +153,7 @@ export const simpleApi = new Elysia({ prefix: "/simple" }) humanKey, action ); - await prisma.instance.update({ + await db.instance.update({ data: { gameState: newState }, where: { id: instanceId, diff --git a/packages/server/src/human.ts b/packages/server/src/human.ts index ad28947..52d2848 100644 --- a/packages/server/src/human.ts +++ b/packages/server/src/human.ts @@ -1,8 +1,13 @@ import Elysia from "elysia"; +import db from "./db"; export const human = new Elysia({ name: "human" }) .derive(async ({ cookie: { token }, status }) => { - const humanKey = token.value; + const humanKey = await db.human + .findUnique({ + where: { token: token.value }, + }) + .then((human) => human?.key); return humanKey != null ? { humanKey } : status(401); }) .as("scoped"); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0c44f2e..6cf7b9b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -19,13 +19,13 @@ importers: dependencies: '@elysiajs/eden': specifier: ^1.3.2 - version: 1.3.2(elysia@1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) + version: 1.3.2(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) '@solid-primitives/scheduled': specifier: ^1.5.2 - version: 1.5.2(solid-js@1.9.8) + version: 1.5.2(solid-js@1.9.9) '@solidjs/router': specifier: ^0.15.3 - version: 0.15.3(solid-js@1.9.8) + version: 0.15.3(solid-js@1.9.9) js-cookie: specifier: ^3.0.5 version: 3.0.5 @@ -34,7 +34,7 @@ importers: version: 3.0.0 solid-js: specifier: ^1.9.5 - version: 1.9.8 + version: 1.9.9 devDependencies: '@iconify-json/solar': specifier: ^1.2.4 @@ -56,25 +56,34 @@ importers: version: 4.5.14(@types/node@24.2.0) vite-plugin-solid: specifier: ^2.11.8 - version: 2.11.8(solid-js@1.9.8)(vite@4.5.14(@types/node@24.2.0)) + version: 2.11.8(solid-js@1.9.9)(vite@4.5.14(@types/node@24.2.0)) packages/server: dependencies: '@elysiajs/cors': specifier: ^1.3.3 - version: 1.3.3(elysia@1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) + version: 1.3.3(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) '@elysiajs/static': specifier: ^1.3.0 - version: 1.3.0(elysia@1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) + version: 1.3.0(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) '@games/shared': specifier: workspace:* version: link:../shared '@prisma/client': specifier: 6.13.0 version: 6.13.0(prisma@6.13.0(typescript@5.9.2))(typescript@5.9.2) + dayjs: + specifier: ^1.11.13 + version: 1.11.13 elysia: specifier: ^1.3.8 - version: 1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) + version: 1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) + elysia-ip: + specifier: ^1.0.10 + version: 1.0.10(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) + elysia-rate-limit: + specifier: ^4.4.0 + version: 4.4.0(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)) object-hash: specifier: ^3.0.0 version: 3.0.0 @@ -97,6 +106,10 @@ importers: packages: + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} @@ -188,6 +201,9 @@ packages: resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} engines: {node: '>=6.9.0'} + '@borewit/text-codec@0.1.1': + resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} + '@elysiajs/cors@1.3.3': resolution: {integrity: sha512-mYIU6PyMM6xIJuj7d27Vt0/wuzVKIEnFPjcvlkyd7t/m9xspAG37cwNjFxVOnyvY43oOd2I/oW2DB85utXpA2Q==} peerDependencies: @@ -658,6 +674,18 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.1: resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} @@ -690,8 +718,18 @@ packages: electron-to-chromium@1.5.198: resolution: {integrity: sha512-G5COfnp3w+ydVu80yprgWSfmfQaYRh9DOxfhAxstLyetKaLyl55QrNjx8C38Pc/C+RaDmb1M0Lk8wPEMQ+bGgQ==} - elysia@1.3.8: - resolution: {integrity: sha512-kxYFhegJbUEf5otzmisEvGt3R7d/dPBNVERO2nHo0kFqKBHyj5slArc90mSRKLfi1vamMtPcz67rL6Zeg5F2yg==} + elysia-ip@1.0.10: + resolution: {integrity: sha512-xmCxPOl4266sq6CLk5d82P3BZOatG9z0gMP473cYEnORssuopbEI8GAwpOhiaz69X76AOrkYgvCdLkqMJC49dQ==} + peerDependencies: + elysia: '>= 1.0.9' + + elysia-rate-limit@4.4.0: + resolution: {integrity: sha512-pyQdFEdjgf5ELx5CAEfOZ2IWhPaYv8WIQMrXimzHzslsJ9awDHoK6rcF9K7k/yAOh4qB1UhiasNeMMBGtxAwYQ==} + peerDependencies: + elysia: '>= 1.0.0' + + elysia@1.3.11: + resolution: {integrity: sha512-iTBdfLe+CL8UvnqP+TB4NlUUqxhlKGEIxLMUZqlylUp4yGq2lTdFbxlItZuA7Z4/mlv5wC3GfjTd587Iwo552Q==} peerDependencies: exact-mirror: '>= 0.0.9' file-type: '>= 20.0.0' @@ -879,6 +917,9 @@ packages: resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -1034,8 +1075,8 @@ packages: resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} engines: {node: '>=18'} - solid-js@1.9.8: - resolution: {integrity: sha512-zF9Whfqk+s8wWuyDKnE7ekl+dJburjdZq54O6X1k4XChA57uZ5FOauYAa0s4I44XkBOM3CZmPrZC0DGjH9fKjQ==} + solid-js@1.9.9: + resolution: {integrity: sha512-A0ZBPJQldAeGCTW0YRYJmt7RCeh5rbFfPZ2aOttgYnctHE7HgKeHCBB/PVc2P7eOfmNXqMFFFoYYdm3S4dcbkA==} solid-refresh@0.6.3: resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==} @@ -1089,8 +1130,8 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - token-types@6.0.4: - resolution: {integrity: sha512-MD9MjpVNhVyH4fyd5rKphjvt/1qj+PtQUz65aFqAZA6XniWAuSFRjLk3e2VALEFlh9OwBpXUN7rfeqSnT/Fmkw==} + token-types@6.1.1: + resolution: {integrity: sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==} engines: {node: '>=14.16'} totalist@3.0.1: @@ -1116,8 +1157,8 @@ packages: ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - uint8array-extras@1.4.0: - resolution: {integrity: sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==} + uint8array-extras@1.4.1: + resolution: {integrity: sha512-+NWHrac9dvilNgme+gP4YrBSumsaMZP0fNBtXXFIf33RLLKEcBUKaQZ7ULUbS0sBfcjxIZ4V96OTRkCbM7hxpw==} engines: {node: '>=18'} unconfig@7.3.2: @@ -1228,6 +1269,8 @@ packages: snapshots: + '@alloc/quick-lru@5.2.0': {} + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.12 @@ -1351,17 +1394,19 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@elysiajs/cors@1.3.3(elysia@1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2))': - dependencies: - elysia: 1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) + '@borewit/text-codec@0.1.1': {} - '@elysiajs/eden@1.3.2(elysia@1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2))': + '@elysiajs/cors@1.3.3(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2))': dependencies: - elysia: 1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) + elysia: 1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) - '@elysiajs/static@1.3.0(elysia@1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2))': + '@elysiajs/eden@1.3.2(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2))': dependencies: - elysia: 1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) + elysia: 1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) + + '@elysiajs/static@1.3.0(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2))': + dependencies: + elysia: 1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) node-cache: 5.1.2 '@esbuild/android-arm64@0.18.20': @@ -1507,13 +1552,13 @@ snapshots: '@sinclair/typebox@0.34.38': optional: true - '@solid-primitives/scheduled@1.5.2(solid-js@1.9.8)': + '@solid-primitives/scheduled@1.5.2(solid-js@1.9.9)': dependencies: - solid-js: 1.9.8 + solid-js: 1.9.9 - '@solidjs/router@0.15.3(solid-js@1.9.8)': + '@solidjs/router@0.15.3(solid-js@1.9.9)': dependencies: - solid-js: 1.9.8 + solid-js: 1.9.9 '@standard-schema/spec@1.0.0': {} @@ -1521,7 +1566,7 @@ snapshots: dependencies: debug: 4.4.1 fflate: 0.8.2 - token-types: 6.0.4 + token-types: 6.1.1 transitivePeerDependencies: - supports-color @@ -1741,12 +1786,12 @@ snapshots: parse5: 7.3.0 validate-html-nesting: 1.2.3 - babel-preset-solid@1.9.8(@babel/core@7.28.0)(solid-js@1.9.8): + babel-preset-solid@1.9.8(@babel/core@7.28.0)(solid-js@1.9.9): dependencies: '@babel/core': 7.28.0 babel-plugin-jsx-dom-expressions: 0.40.0(@babel/core@7.28.0) optionalDependencies: - solid-js: 1.9.8 + solid-js: 1.9.9 binary-extensions@2.3.0: {} @@ -1853,6 +1898,12 @@ snapshots: csstype@3.1.3: {} + dayjs@1.11.13: {} + + debug@4.3.4: + dependencies: + ms: 2.1.2 + debug@4.4.1: dependencies: ms: 2.1.3 @@ -1874,7 +1925,19 @@ snapshots: electron-to-chromium@1.5.198: {} - elysia@1.3.8(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2): + elysia-ip@1.0.10(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)): + dependencies: + elysia: 1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) + + elysia-rate-limit@4.4.0(elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2)): + dependencies: + '@alloc/quick-lru': 5.2.0 + debug: 4.3.4 + elysia: 1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2) + transitivePeerDependencies: + - supports-color + + elysia@1.3.11(exact-mirror@0.1.5(@sinclair/typebox@0.34.38))(file-type@21.0.0)(typescript@5.9.2): dependencies: cookie: 1.0.2 exact-mirror: 0.1.5(@sinclair/typebox@0.34.38) @@ -1938,8 +2001,8 @@ snapshots: dependencies: '@tokenizer/inflate': 0.2.7 strtok3: 10.3.4 - token-types: 6.0.4 - uint8array-extras: 1.4.0 + token-types: 6.1.1 + uint8array-extras: 1.4.1 transitivePeerDependencies: - supports-color @@ -2048,6 +2111,8 @@ snapshots: mrmime@2.0.1: {} + ms@2.1.2: {} + ms@2.1.3: {} nanoid@3.3.11: {} @@ -2195,18 +2260,18 @@ snapshots: mrmime: 2.0.1 totalist: 3.0.1 - solid-js@1.9.8: + solid-js@1.9.9: dependencies: csstype: 3.1.3 seroval: 1.3.2 seroval-plugins: 1.3.2(seroval@1.3.2) - solid-refresh@0.6.3(solid-js@1.9.8): + solid-refresh@0.6.3(solid-js@1.9.9): dependencies: '@babel/generator': 7.28.0 '@babel/helper-module-imports': 7.27.1 '@babel/types': 7.28.2 - solid-js: 1.9.8 + solid-js: 1.9.9 transitivePeerDependencies: - supports-color @@ -2259,8 +2324,9 @@ snapshots: dependencies: is-number: 7.0.0 - token-types@6.0.4: + token-types@6.1.1: dependencies: + '@borewit/text-codec': 0.1.1 '@tokenizer/token': 0.3.0 ieee754: 1.2.1 @@ -2276,7 +2342,7 @@ snapshots: ufo@1.6.1: {} - uint8array-extras@1.4.0: {} + uint8array-extras@1.4.1: {} unconfig@7.3.2: dependencies: @@ -2334,14 +2400,14 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vite-plugin-solid@2.11.8(solid-js@1.9.8)(vite@4.5.14(@types/node@24.2.0)): + vite-plugin-solid@2.11.8(solid-js@1.9.9)(vite@4.5.14(@types/node@24.2.0)): dependencies: '@babel/core': 7.28.0 '@types/babel__core': 7.20.5 - babel-preset-solid: 1.9.8(@babel/core@7.28.0)(solid-js@1.9.8) + babel-preset-solid: 1.9.8(@babel/core@7.28.0)(solid-js@1.9.9) merge-anything: 5.1.7 - solid-js: 1.9.8 - solid-refresh: 0.6.3(solid-js@1.9.8) + solid-js: 1.9.9 + solid-refresh: 0.6.3(solid-js@1.9.9) vite: 4.5.14(@types/node@24.2.0) vitefu: 1.1.1(vite@4.5.14(@types/node@24.2.0)) transitivePeerDependencies: