diff --git a/Dockerfile b/Dockerfile index 5193ff8..5814324 100644 --- a/Dockerfile +++ b/Dockerfile @@ -42,11 +42,11 @@ COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/.next ./.next COPY --from=builder /app/public ./public COPY --from=builder /app/prisma ./prisma +COPY --from=builder /app/prisma.config.ts ./ COPY --from=builder /app/server.ts ./ COPY --from=builder /app/src ./src COPY --from=builder /app/tsconfig.json ./ COPY --from=builder /app/next.config.mjs ./ -COPY --from=builder /app/tailwind.config.ts ./ COPY --from=builder /app/postcss.config.mjs ./ # Create data directory for SQLite diff --git a/components.json b/components.json index dba50c6..fc0433c 100644 --- a/components.json +++ b/components.json @@ -4,7 +4,6 @@ "rsc": true, "tsx": true, "tailwind": { - "config": "tailwind.config.ts", "css": "src/app/globals.css", "baseColor": "slate", "cssVariables": true, diff --git a/docker-compose.yml b/docker-compose.yml index 7a3ff6e..75cff87 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,7 +6,7 @@ services: context: . target: runner ports: - - "3000:3000" + - "18081:3000" volumes: # Persist SQLite database - quiz-data:/app/prisma/data diff --git a/next.config.mjs b/next.config.mjs index d8fd9e3..e94439a 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -1,10 +1,7 @@ /** @type {import('next').NextConfig} */ const nextConfig = { reactStrictMode: true, - experimental: { - // Externalize @ngrok/ngrok to avoid webpack bundling native modules - serverComponentsExternalPackages: ["@ngrok/ngrok"], - }, + serverExternalPackages: ["@ngrok/ngrok"], images: { remotePatterns: [ { diff --git a/package-lock.json b/package-lock.json index b3b094c..5cc92b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,9 @@ "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@hookform/resolvers": "^5.4.0", + "@libsql/client": "^0.17.4", "@ngrok/ngrok": "^1.7.0", + "@prisma/adapter-libsql": "^7.9.1", "@prisma/client": "^7.8.0", "@radix-ui/react-alert-dialog": "^1.1.17", "@radix-ui/react-avatar": "^1.2.0", @@ -28,6 +30,7 @@ "@radix-ui/react-switch": "^1.3.1", "@radix-ui/react-tabs": "^1.1.15", "@radix-ui/react-tooltip": "^1.2.10", + "@tailwindcss/postcss": "^4.3.3", "@types/node": "^26.0.0", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", @@ -35,6 +38,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.4.0", + "dotenv": "^17.4.2", "file-saver": "^2.0.5", "html2canvas": "^1.4.1", "jszip": "^3.10.1", @@ -51,7 +55,6 @@ "socket.io-client": "^4.8.3", "sonner": "^2.0.7", "tailwind-merge": "^3.6.0", - "tailwindcss-animate": "^1.0.7", "typescript": "^6.0.3", "zod": "^4.4.3" }, @@ -66,6 +69,7 @@ "eslint": "^10.5.0", "eslint-config-next": "^16.2.9", "postcss": "^8.5.15", + "tailwind-animate": "^0.2.10", "tailwindcss": "^4.3.1", "tsx": "^4.22.4", "vitest": "^4.1.9" @@ -78,6 +82,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@alloc/quick-lru": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", + "integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -418,7 +434,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -440,7 +455,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -1203,9 +1217,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1222,9 +1233,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1241,9 +1249,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1260,9 +1265,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1279,9 +1281,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1298,9 +1297,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1317,9 +1313,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1336,9 +1329,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1355,9 +1345,6 @@ "cpu": [ "arm" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1380,9 +1367,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1405,9 +1389,6 @@ "cpu": [ "ppc64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1430,9 +1411,6 @@ "cpu": [ "riscv64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1455,9 +1433,6 @@ "cpu": [ "s390x" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1480,9 +1455,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1505,9 +1477,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1530,9 +1499,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "Apache-2.0", "optional": true, "os": [ @@ -1628,7 +1594,6 @@ "version": "0.3.13", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", @@ -1639,7 +1604,6 @@ "version": "2.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -1650,7 +1614,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.0.0" @@ -1660,14 +1623,12 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.31", "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", @@ -1680,11 +1641,169 @@ "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", "license": "MIT" }, + "node_modules/@libsql/client": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@libsql/client/-/client-0.17.4.tgz", + "integrity": "sha512-lYayFWasDV78A+TjlEhr6ubb3odBV6OHjb+wdp8VQcyWWAEIjuwbCHaraEUS4m4yWoo0BvZo96It4VdzZRmRWw==", + "license": "MIT", + "dependencies": { + "@libsql/core": "^0.17.4", + "@libsql/hrana-client": "^0.10.0", + "js-base64": "^3.7.5", + "libsql": "^0.5.28", + "promise-limit": "^2.7.0" + } + }, + "node_modules/@libsql/core": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@libsql/core/-/core-0.17.4.tgz", + "integrity": "sha512-LqF9gIvnJ38nmAH1y/ChizHqDO/MO1wLgA96XrraulEEbqXxLjleSH92YWTolbuJKgPUmGu4aJk9W3UnAcxLOQ==", + "license": "MIT", + "dependencies": { + "js-base64": "^3.7.5" + } + }, + "node_modules/@libsql/darwin-arm64": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/darwin-arm64/-/darwin-arm64-0.5.29.tgz", + "integrity": "sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@libsql/darwin-x64": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/darwin-x64/-/darwin-x64-0.5.29.tgz", + "integrity": "sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@libsql/hrana-client": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@libsql/hrana-client/-/hrana-client-0.10.0.tgz", + "integrity": "sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw==", + "license": "MIT", + "dependencies": { + "@libsql/isomorphic-ws": "^0.1.5", + "js-base64": "^3.7.5" + } + }, + "node_modules/@libsql/isomorphic-ws": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@libsql/isomorphic-ws/-/isomorphic-ws-0.1.5.tgz", + "integrity": "sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==", + "license": "MIT", + "dependencies": { + "@types/ws": "^8.5.4", + "ws": "^8.13.0" + } + }, + "node_modules/@libsql/linux-arm-gnueabihf": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/linux-arm-gnueabihf/-/linux-arm-gnueabihf-0.5.29.tgz", + "integrity": "sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/linux-arm-musleabihf": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/linux-arm-musleabihf/-/linux-arm-musleabihf-0.5.29.tgz", + "integrity": "sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/linux-arm64-gnu": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/linux-arm64-gnu/-/linux-arm64-gnu-0.5.29.tgz", + "integrity": "sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/linux-arm64-musl": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/linux-arm64-musl/-/linux-arm64-musl-0.5.29.tgz", + "integrity": "sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/linux-x64-gnu": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/linux-x64-gnu/-/linux-x64-gnu-0.5.29.tgz", + "integrity": "sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/linux-x64-musl": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/linux-x64-musl/-/linux-x64-musl-0.5.29.tgz", + "integrity": "sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@libsql/win32-x64-msvc": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/@libsql/win32-x64-msvc/-/win32-x64-msvc-0.5.29.tgz", + "integrity": "sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -1699,6 +1818,12 @@ "@emnapi/runtime": "^1.7.1" } }, + "node_modules/@neon-rs/load": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@neon-rs/load/-/load-0.0.4.tgz", + "integrity": "sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==", + "license": "MIT" + }, "node_modules/@next/env": { "version": "16.2.9", "resolved": "https://registry.npmjs.org/@next/env/-/env-16.2.9.tgz", @@ -1754,9 +1879,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1773,9 +1895,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1792,9 +1911,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1811,9 +1927,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1979,9 +2092,6 @@ "cpu": [ "arm64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1998,9 +2108,6 @@ "cpu": [ "arm64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2017,9 +2124,6 @@ "cpu": [ "x64" ], - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -2036,9 +2140,6 @@ "cpu": [ "x64" ], - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -2170,6 +2271,17 @@ "node": ">=18" } }, + "node_modules/@prisma/adapter-libsql": { + "version": "7.9.1", + "resolved": "https://registry.npmjs.org/@prisma/adapter-libsql/-/adapter-libsql-7.9.1.tgz", + "integrity": "sha512-bHfu0fnxF5ALP/AZLM0TyfhFjv9H/g0lRCt3j2aVuLMSQy6zgy3OAeWkp+UoLx+dP9Yuz+EsNXos6IN2e2eyvQ==", + "license": "Apache-2.0", + "dependencies": { + "@libsql/client": "^0.17.0", + "@prisma/driver-adapter-utils": "7.9.1", + "async-mutex": "0.5.0" + } + }, "node_modules/@prisma/client": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-7.8.0.tgz", @@ -2243,6 +2355,21 @@ "zeptomatch": "2.1.0" } }, + "node_modules/@prisma/driver-adapter-utils": { + "version": "7.9.1", + "resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-7.9.1.tgz", + "integrity": "sha512-vmHehG7nn/heW32DXXpp13DxxAxVVe6n250oEt3dOL2E/4bt3olktKZN0mzSuxMMronyMSkbeW2uCOn3F4g8RQ==", + "license": "Apache-2.0", + "dependencies": { + "@prisma/debug": "7.9.1" + } + }, + "node_modules/@prisma/driver-adapter-utils/node_modules/@prisma/debug": { + "version": "7.9.1", + "resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-7.9.1.tgz", + "integrity": "sha512-/cpVZ4itxtcgB8GHBvZtcmuEjq+lWsLrRJxFMbwZrT1RIdtuKmUm7PPGo/wzfbYpBrk+9WmmBE8CHJw2rybKDQ==", + "license": "Apache-2.0" + }, "node_modules/@prisma/engines": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-7.8.0.tgz", @@ -3557,9 +3684,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3577,9 +3701,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3597,9 +3718,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3617,9 +3735,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3637,9 +3752,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -3657,9 +3769,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -3830,6 +3939,262 @@ "tslib": "^2.8.0" } }, + "node_modules/@tailwindcss/node": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.3.3.tgz", + "integrity": "sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==", + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "enhanced-resolve": "^5.24.1", + "jiti": "^2.7.0", + "lightningcss": "1.32.0", + "magic-string": "^0.30.21", + "source-map-js": "^1.2.1", + "tailwindcss": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.3.3.tgz", + "integrity": "sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "optionalDependencies": { + "@tailwindcss/oxide-android-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-arm64": "4.3.3", + "@tailwindcss/oxide-darwin-x64": "4.3.3", + "@tailwindcss/oxide-freebsd-x64": "4.3.3", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.3.3", + "@tailwindcss/oxide-linux-arm64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-arm64-musl": "4.3.3", + "@tailwindcss/oxide-linux-x64-gnu": "4.3.3", + "@tailwindcss/oxide-linux-x64-musl": "4.3.3", + "@tailwindcss/oxide-wasm32-wasi": "4.3.3", + "@tailwindcss/oxide-win32-arm64-msvc": "4.3.3", + "@tailwindcss/oxide-win32-x64-msvc": "4.3.3" + } + }, + "node_modules/@tailwindcss/oxide-android-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.3.3.tgz", + "integrity": "sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-arm64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.3.3.tgz", + "integrity": "sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-darwin-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.3.3.tgz", + "integrity": "sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-freebsd-x64": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.3.3.tgz", + "integrity": "sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.3.3.tgz", + "integrity": "sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.3.3.tgz", + "integrity": "sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-arm64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.3.3.tgz", + "integrity": "sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-gnu": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.3.3.tgz", + "integrity": "sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-linux-x64-musl": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.3.3.tgz", + "integrity": "sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.3.3.tgz", + "integrity": "sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==", + "bundleDependencies": [ + "@napi-rs/wasm-runtime", + "@emnapi/core", + "@emnapi/runtime", + "@tybys/wasm-util", + "@emnapi/wasi-threads", + "tslib" + ], + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.11.1", + "@emnapi/runtime": "^1.11.1", + "@emnapi/wasi-threads": "^1.2.2", + "@napi-rs/wasm-runtime": "^1.1.4", + "@tybys/wasm-util": "^0.10.2", + "tslib": "^2.8.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz", + "integrity": "sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/oxide-win32-x64-msvc": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.3.3.tgz", + "integrity": "sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 20" + } + }, + "node_modules/@tailwindcss/postcss": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.3.3.tgz", + "integrity": "sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==", + "license": "MIT", + "dependencies": { + "@alloc/quick-lru": "^5.2.0", + "@tailwindcss/node": "4.3.3", + "@tailwindcss/oxide": "4.3.3", + "postcss": "^8.5.16", + "tailwindcss": "4.3.3" + } + }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", @@ -3935,7 +4300,6 @@ "version": "0.10.3", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", - "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4038,6 +4402,15 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.62.0.tgz", @@ -4387,9 +4760,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4404,9 +4774,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -4421,9 +4788,6 @@ "loong64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4438,9 +4802,6 @@ "loong64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -4455,9 +4816,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4472,9 +4830,6 @@ "riscv64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4489,9 +4844,6 @@ "riscv64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -4506,9 +4858,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4523,9 +4872,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -4540,9 +4886,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -5083,6 +5426,15 @@ "node": ">= 0.4" } }, + "node_modules/async-mutex": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/async-mutex/-/async-mutex-0.5.0.tgz", + "integrity": "sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/autoprefixer": { "version": "10.5.1", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.1.tgz", @@ -5329,15 +5681,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/c12/node_modules/jiti": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", - "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, "node_modules/c12/node_modules/readdirp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", @@ -5784,7 +6127,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -6002,6 +6344,19 @@ } } }, + "node_modules/enhanced-resolve": { + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/env-paths": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", @@ -7928,6 +8283,21 @@ "node": ">= 0.4" } }, + "node_modules/jiti": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", + "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/js-base64": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.9.2.tgz", + "integrity": "sha512-6zayE8QlUdiweYI6cETD/XBSqFcoCUlufn/29PJR99r82x1yDnIprRca0YvAYpAW+ez0GuQkVBC6xG5QkD7OjA==", + "license": "BSD-3-Clause" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8053,6 +8423,47 @@ "node": ">= 0.8.0" } }, + "node_modules/libsql": { + "version": "0.5.29", + "resolved": "https://registry.npmjs.org/libsql/-/libsql-0.5.29.tgz", + "integrity": "sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg==", + "cpu": [ + "x64", + "arm64", + "wasm32", + "arm" + ], + "license": "MIT", + "os": [ + "darwin", + "linux", + "win32" + ], + "dependencies": { + "@neon-rs/load": "^0.0.4", + "detect-libc": "2.0.2" + }, + "optionalDependencies": { + "@libsql/darwin-arm64": "0.5.29", + "@libsql/darwin-x64": "0.5.29", + "@libsql/linux-arm-gnueabihf": "0.5.29", + "@libsql/linux-arm-musleabihf": "0.5.29", + "@libsql/linux-arm64-gnu": "0.5.29", + "@libsql/linux-arm64-musl": "0.5.29", + "@libsql/linux-x64-gnu": "0.5.29", + "@libsql/linux-x64-musl": "0.5.29", + "@libsql/win32-x64-msvc": "0.5.29" + } + }, + "node_modules/libsql/node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/lie": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", @@ -8065,7 +8476,6 @@ "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", - "dev": true, "license": "MPL-2.0", "dependencies": { "detect-libc": "^2.0.3" @@ -8098,7 +8508,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8119,7 +8528,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8140,7 +8548,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8161,7 +8568,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8182,7 +8588,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8203,10 +8608,6 @@ "cpu": [ "arm64" ], - "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8227,10 +8628,6 @@ "cpu": [ "arm64" ], - "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8251,10 +8648,6 @@ "cpu": [ "x64" ], - "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8275,10 +8668,6 @@ "cpu": [ "x64" ], - "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -8299,7 +8688,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8320,7 +8708,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -8428,7 +8815,6 @@ "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -9129,6 +9515,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, @@ -9150,10 +9537,9 @@ } }, "node_modules/postcss": { - "version": "8.5.15", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz", - "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==", - "dev": true, + "version": "8.5.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", + "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", "funding": [ { "type": "opencollective", @@ -9170,7 +9556,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.12", + "nanoid": "^3.3.17", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -9185,10 +9571,9 @@ "license": "MIT" }, "node_modules/postcss/node_modules/nanoid": { - "version": "3.3.15", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", - "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", - "dev": true, + "version": "3.3.17", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.17.tgz", + "integrity": "sha512-xQLf0A3HOMlgHq0n247/LRuAOYmB7dXJ/DvAxGvsSBij45XtBSmQycu+F8ODbHwns/XyFZagyL1+J0Offw1E0g==", "funding": [ { "type": "github", @@ -9302,6 +9687,12 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/promise-limit": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/promise-limit/-/promise-limit-2.7.0.tgz", + "integrity": "sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==", + "license": "ISC" + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -10421,6 +10812,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tailwind-animate": { + "version": "0.2.10", + "resolved": "https://registry.npmjs.org/tailwind-animate/-/tailwind-animate-0.2.10.tgz", + "integrity": "sha512-9vczT78R9O7HIrydvGJNz4/19ogjSQSFlYpwleAxcxIT1m9pvAIGQr/+f6qG9sB5gq3JLB6IRKmw9RGJUrLeXQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/nrjdalal" + } + }, "node_modules/tailwind-merge": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz", @@ -10432,18 +10833,22 @@ } }, "node_modules/tailwindcss": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.1.tgz", - "integrity": "sha512-hk+TB1m+K8CYNrP6rjQaq/Y+4Zylwpa87mLYBKCunwnnQ9p+fHb7kmSfGqyEJoxF/O6CDyABWVFEafNSYKll+Q==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz", + "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==", "license": "MIT" }, - "node_modules/tailwindcss-animate": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", - "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", "license": "MIT", - "peerDependencies": { - "tailwindcss": ">=3.0.0 || insiders" + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/text-segmentation": { @@ -11272,6 +11677,27 @@ "node": ">=0.10.0" } }, + "node_modules/ws": { + "version": "8.21.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.2.tgz", + "integrity": "sha512-54dMVAo4WIe6SKy3vBgN+9bJZqqQ8IMRevAkOLQALhi49qkkQDQfWdAZ8KQlXiEabw88ARXXdUrlvtbKQX+aKw==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xmlhttprequest-ssl": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz", diff --git a/package.json b/package.json index 44fae2f..a7dad8c 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,9 @@ "@dnd-kit/sortable": "^10.0.0", "@dnd-kit/utilities": "^3.2.2", "@hookform/resolvers": "^5.4.0", + "@libsql/client": "^0.17.4", "@ngrok/ngrok": "^1.7.0", + "@prisma/adapter-libsql": "^7.9.1", "@prisma/client": "^7.8.0", "@radix-ui/react-alert-dialog": "^1.1.17", "@radix-ui/react-avatar": "^1.2.0", @@ -36,6 +38,7 @@ "@radix-ui/react-switch": "^1.3.1", "@radix-ui/react-tabs": "^1.1.15", "@radix-ui/react-tooltip": "^1.2.10", + "@tailwindcss/postcss": "^4.3.3", "@types/node": "^26.0.0", "@types/react": "^19.2.17", "@types/react-dom": "^19.2.3", @@ -43,6 +46,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.4.0", + "dotenv": "^17.4.2", "file-saver": "^2.0.5", "html2canvas": "^1.4.1", "jszip": "^3.10.1", @@ -59,23 +63,23 @@ "socket.io-client": "^4.8.3", "sonner": "^2.0.7", "tailwind-merge": "^3.6.0", - "tailwindcss-animate": "^1.0.7", "typescript": "^6.0.3", "zod": "^4.4.3" }, "devDependencies": { + "@playwright/test": "^1.61.1", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/react": "^16.3.2", + "@testing-library/user-event": "^14.5.2", "@types/file-saver": "^2.0.7", + "@vitest/coverage-v8": "^4.1.9", "autoprefixer": "^10.5.1", "eslint": "^10.5.0", "eslint-config-next": "^16.2.9", "postcss": "^8.5.15", + "tailwind-animate": "^0.2.10", "tailwindcss": "^4.3.1", "tsx": "^4.22.4", - "@vitest/coverage-v8": "^4.1.9", - "vitest": "^4.1.9", - "@testing-library/react": "^16.3.2", - "@testing-library/jest-dom": "^6.6.3", - "@testing-library/user-event": "^14.5.2", - "@playwright/test": "^1.61.1" + "vitest": "^4.1.9" } -} \ No newline at end of file +} diff --git a/postcss.config.mjs b/postcss.config.mjs index 2ef30fc..79bcf13 100644 --- a/postcss.config.mjs +++ b/postcss.config.mjs @@ -1,8 +1,7 @@ /** @type {import('postcss-load-config').Config} */ const config = { plugins: { - tailwindcss: {}, - autoprefixer: {}, + "@tailwindcss/postcss": {}, }, }; diff --git a/prisma.config.ts b/prisma.config.ts new file mode 100644 index 0000000..9060a4a --- /dev/null +++ b/prisma.config.ts @@ -0,0 +1,12 @@ +import "dotenv/config"; +import { defineConfig } from "prisma/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + }, + datasource: { + url: process.env["DATABASE_URL"] ?? "file:./data/quiz.db", + }, +}); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 07b481c..7b4d4c6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -4,7 +4,6 @@ generator client { datasource db { provider = "sqlite" - url = env("DATABASE_URL") } // Saved themes (user-created) diff --git a/src/app/api/admin/games/[gameId]/route.ts b/src/app/api/admin/games/[gameId]/route.ts index 5450e30..735e1eb 100644 --- a/src/app/api/admin/games/[gameId]/route.ts +++ b/src/app/api/admin/games/[gameId]/route.ts @@ -3,11 +3,12 @@ import { prisma } from "@/lib/db"; export async function GET( request: NextRequest, - { params }: { params: { gameId: string } } + { params }: { params: Promise<{ gameId: string }> } ) { + const { gameId } = await params; try { const game = await prisma.gameSession.findUnique({ - where: { id: params.gameId }, + where: { id: gameId }, include: { quiz: { select: { @@ -70,11 +71,12 @@ export async function GET( export async function DELETE( _request: NextRequest, - { params }: { params: { gameId: string } } + { params }: { params: Promise<{ gameId: string }> } ) { + const { gameId } = await params; try { const game = await prisma.gameSession.findUnique({ - where: { id: params.gameId }, + where: { id: gameId }, select: { status: true } }); @@ -90,7 +92,7 @@ export async function DELETE( } await prisma.gameSession.delete({ - where: { id: params.gameId } + where: { id: gameId } }); return Response.json({ success: true }); diff --git a/src/app/api/games/[gameCode]/certificates/download/route.ts b/src/app/api/games/[gameCode]/certificates/download/route.ts index 87dbc26..d2f1602 100644 --- a/src/app/api/games/[gameCode]/certificates/download/route.ts +++ b/src/app/api/games/[gameCode]/certificates/download/route.ts @@ -5,8 +5,9 @@ import path from "path"; export async function POST( request: NextRequest, - { params }: { params: { gameCode: string } } + { params }: { params: Promise<{ gameCode: string }> } ) { + const { gameCode } = await params; try { const body = await request.json(); const { type, playerId } = body; @@ -14,7 +15,7 @@ export async function POST( // Find certificate const certificate = await prisma.certificate.findFirst({ where: { - gameSession: { gameCode: params.gameCode.toUpperCase() }, + gameSession: { gameCode: gameCode.toUpperCase() }, type, playerId: type === "player" ? playerId : null, }, diff --git a/src/app/api/games/[gameCode]/certificates/generate/route.ts b/src/app/api/games/[gameCode]/certificates/generate/route.ts index 51e2792..e6acb8b 100644 --- a/src/app/api/games/[gameCode]/certificates/generate/route.ts +++ b/src/app/api/games/[gameCode]/certificates/generate/route.ts @@ -17,13 +17,13 @@ import { QuizTheme, DEFAULT_THEME } from "@/types/theme"; export async function POST( request: NextRequest, - { params }: { params: { gameCode: string } } + { params }: { params: Promise<{ gameCode: string }> } ) { try { // Parse request const body = (await request.json()) as CertificateRequest; const { type, playerId } = body; - const { gameCode } = params; + const { gameCode } = await params; // Fetch game data const gameData = await prisma.gameSession.findUnique({ diff --git a/src/app/api/games/[gameCode]/certificates/regenerate/route.ts b/src/app/api/games/[gameCode]/certificates/regenerate/route.ts index e906a91..e258435 100644 --- a/src/app/api/games/[gameCode]/certificates/regenerate/route.ts +++ b/src/app/api/games/[gameCode]/certificates/regenerate/route.ts @@ -3,8 +3,9 @@ import { CertificateService } from "@/lib/certificate-service"; export async function POST( request: NextRequest, - { params }: { params: { gameCode: string } } + { params }: { params: Promise<{ gameCode: string }> } ) { + const { gameCode } = await params; try { const body = await request.json(); const { certificateIds } = body; diff --git a/src/app/api/games/[gameCode]/certificates/status/route.ts b/src/app/api/games/[gameCode]/certificates/status/route.ts index ef0d5f1..2980c7b 100644 --- a/src/app/api/games/[gameCode]/certificates/status/route.ts +++ b/src/app/api/games/[gameCode]/certificates/status/route.ts @@ -3,12 +3,11 @@ import { CertificateService } from "@/lib/certificate-service"; export async function GET( request: NextRequest, - { params }: { params: { gameCode: string } } + { params }: { params: Promise<{ gameCode: string }> } ) { + const { gameCode } = await params; try { - const status = await CertificateService.getCertificateStatus( - params.gameCode - ); + const status = await CertificateService.getCertificateStatus(gameCode); return NextResponse.json(status); } catch (error) { console.error("Failed to fetch certificate status:", error); diff --git a/src/app/api/quizzes/[quizId]/questions/[questionId]/translate/route.ts b/src/app/api/quizzes/[quizId]/questions/[questionId]/translate/route.ts index f1ca72f..2a1416c 100644 --- a/src/app/api/quizzes/[quizId]/questions/[questionId]/translate/route.ts +++ b/src/app/api/quizzes/[quizId]/questions/[questionId]/translate/route.ts @@ -8,10 +8,10 @@ export const dynamic = "force-dynamic"; // POST /api/quizzes/[quizId]/questions/[questionId]/translate - Translate single question or section export async function POST( request: Request, - { params }: { params: { quizId: string; questionId: string } } + { params }: { params: Promise<{ quizId: string; questionId: string }> } ) { + const { questionId } = await params; try { - const { questionId } = params; const body = await request.json(); const { targetLanguage } = body; diff --git a/src/app/api/quizzes/[quizId]/questions/[questionId]/translations/[language]/route.ts b/src/app/api/quizzes/[quizId]/questions/[questionId]/translations/[language]/route.ts index 399f656..918dd1c 100644 --- a/src/app/api/quizzes/[quizId]/questions/[questionId]/translations/[language]/route.ts +++ b/src/app/api/quizzes/[quizId]/questions/[questionId]/translations/[language]/route.ts @@ -7,10 +7,10 @@ export const dynamic = "force-dynamic"; // PUT /api/quizzes/[quizId]/questions/[questionId]/translations/[language] - Update manual translation export async function PUT( request: Request, - { params }: { params: { quizId: string; questionId: string; language: string } } + { params }: { params: Promise<{ quizId: string; questionId: string; language: string }> } ) { + const { questionId, language } = await params; try { - const { questionId, language } = params; const body = await request.json(); // Validate language @@ -107,10 +107,10 @@ export async function PUT( // DELETE /api/quizzes/[quizId]/questions/[questionId]/translations/[language] - Delete translation export async function DELETE( request: Request, - { params }: { params: { quizId: string; questionId: string; language: string } } + { params }: { params: Promise<{ quizId: string; questionId: string; language: string }> } ) { + const { questionId, language } = await params; try { - const { questionId, language } = params; // Validate language if (!(language in SupportedLanguages)) { diff --git a/src/app/api/quizzes/[quizId]/questions/[questionId]/translations/route.ts b/src/app/api/quizzes/[quizId]/questions/[questionId]/translations/route.ts index 44976e2..ea5fe17 100644 --- a/src/app/api/quizzes/[quizId]/questions/[questionId]/translations/route.ts +++ b/src/app/api/quizzes/[quizId]/questions/[questionId]/translations/route.ts @@ -6,10 +6,10 @@ export const dynamic = "force-dynamic"; // GET /api/quizzes/[quizId]/questions/[questionId]/translations - Get all translations for a question export async function GET( request: Request, - { params }: { params: { quizId: string; questionId: string } } + { params }: { params: Promise<{ quizId: string; questionId: string }> } ) { + const { questionId } = await params; try { - const { questionId } = params; // Fetch question with translations const question = await prisma.question.findUnique({ diff --git a/src/app/api/quizzes/[quizId]/translate/route.ts b/src/app/api/quizzes/[quizId]/translate/route.ts index a737717..f78d231 100644 --- a/src/app/api/quizzes/[quizId]/translate/route.ts +++ b/src/app/api/quizzes/[quizId]/translate/route.ts @@ -7,10 +7,10 @@ export const dynamic = "force-dynamic"; // POST /api/quizzes/[quizId]/translate - Translate entire quiz to target language export async function POST( request: Request, - { params }: { params: { quizId: string } } + { params }: { params: Promise<{ quizId: string }> } ) { + const { quizId } = await params; try { - const { quizId } = params; const body = await request.json(); const { targetLanguage } = body; diff --git a/src/app/api/quizzes/[quizId]/translations/[language]/route.ts b/src/app/api/quizzes/[quizId]/translations/[language]/route.ts index d15e31b..177fc23 100644 --- a/src/app/api/quizzes/[quizId]/translations/[language]/route.ts +++ b/src/app/api/quizzes/[quizId]/translations/[language]/route.ts @@ -7,10 +7,10 @@ export const dynamic = "force-dynamic"; // DELETE /api/quizzes/[quizId]/translations/[language] - Delete all translations for a language export async function DELETE( request: Request, - { params }: { params: { quizId: string; language: string } } + { params }: { params: Promise<{ quizId: string; language: string }> } ) { + const { quizId, language } = await params; try { - const { quizId, language } = params; // Validate language if (!(language in SupportedLanguages)) { diff --git a/src/app/api/quizzes/[quizId]/translations/route.ts b/src/app/api/quizzes/[quizId]/translations/route.ts index 9b3511b..378c1f2 100644 --- a/src/app/api/quizzes/[quizId]/translations/route.ts +++ b/src/app/api/quizzes/[quizId]/translations/route.ts @@ -6,10 +6,10 @@ export const dynamic = "force-dynamic"; // GET /api/quizzes/[quizId]/translations - Get translation status for all languages export async function GET( request: Request, - { params }: { params: { quizId: string } } + { params }: { params: Promise<{ quizId: string }> } ) { + const { quizId } = await params; try { - const { quizId } = params; const statuses = await getQuizTranslationStatus(quizId); diff --git a/src/app/globals.css b/src/app/globals.css index 860e7a9..a24f62f 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,6 +1,31 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; +@import "tailwindcss"; +@import "tailwind-animate"; + +@theme { + --color-border: hsl(var(--border)); + --color-input: hsl(var(--input)); + --color-ring: hsl(var(--ring)); + --color-background: hsl(var(--background)); + --color-foreground: hsl(var(--foreground)); + --color-primary: hsl(var(--primary)); + --color-primary-foreground: hsl(var(--primary-foreground)); + --color-secondary: hsl(var(--secondary)); + --color-secondary-foreground: hsl(var(--secondary-foreground)); + --color-destructive: hsl(var(--destructive)); + --color-destructive-foreground: hsl(var(--destructive-foreground)); + --color-muted: hsl(var(--muted)); + --color-muted-foreground: hsl(var(--muted-foreground)); + --color-accent: hsl(var(--accent)); + --color-accent-foreground: hsl(var(--accent-foreground)); + --color-popover: hsl(var(--popover)); + --color-popover-foreground: hsl(var(--popover-foreground)); + --color-card: hsl(var(--card)); + --color-card-foreground: hsl(var(--card-foreground)); + --radius-lg: var(--radius); + --radius-md: calc(var(--radius) - 2px); + --radius-sm: calc(var(--radius) - 4px); + --font-family-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; +} @layer base { :root { diff --git a/src/app/uploads/[...path]/route.ts b/src/app/uploads/[...path]/route.ts index 4ae0df9..a9c52f5 100644 --- a/src/app/uploads/[...path]/route.ts +++ b/src/app/uploads/[...path]/route.ts @@ -5,14 +5,15 @@ import path from "path"; // Fallback handler to serve uploaded files even when Next static serving misses. export async function GET( _req: Request, - { params }: { params: { path: string[] } } + { params }: { params: Promise<{ path: string[] }> } ) { + const { path: filePathSegments } = await params; try { const filePath = path.join( process.cwd(), "public", "uploads", - ...params.path + ...filePathSegments ); const data = await readFile(filePath); @@ -35,7 +36,7 @@ export async function GET( }, }); } catch (error) { - console.warn("[uploads-route] File not found", params.path, error); + console.warn("[uploads-route] File not found", filePathSegments, error); return NextResponse.json({ error: "File not found" }, { status: 404 }); } } diff --git a/src/lib/db.ts b/src/lib/db.ts index ef41cd7..8f3c966 100644 --- a/src/lib/db.ts +++ b/src/lib/db.ts @@ -1,9 +1,17 @@ +import "dotenv/config"; import { PrismaClient } from "@prisma/client"; +import { PrismaLibSql } from "@prisma/adapter-libsql"; const globalForPrisma = globalThis as unknown as { prisma: PrismaClient | undefined; }; -export const prisma = globalForPrisma.prisma ?? new PrismaClient(); +function createPrismaClient() { + const databaseUrl = process.env.DATABASE_URL ?? "file:./data/quiz.db"; + const adapter = new PrismaLibSql({ url: databaseUrl }); + return new PrismaClient({ adapter }); +} + +export const prisma = globalForPrisma.prisma ?? createPrismaClient(); if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma; diff --git a/src/middleware.ts b/src/proxy.ts similarity index 98% rename from src/middleware.ts rename to src/proxy.ts index 4489b25..c6fd04f 100644 --- a/src/middleware.ts +++ b/src/proxy.ts @@ -54,7 +54,7 @@ function isLocalhostOnlyRoute(pathname: string): boolean { return LOCALHOST_ONLY_PATTERNS.some((pattern) => pathname.startsWith(pattern)); } -export function middleware(request: NextRequest) { +export function proxy(request: NextRequest) { const { pathname } = request.nextUrl; // Allow all static files and Next.js internals diff --git a/src/server/game-manager.ts b/src/server/game-manager.ts index 9619b9e..31e37c7 100644 --- a/src/server/game-manager.ts +++ b/src/server/game-manager.ts @@ -1,5 +1,4 @@ import { Server, Socket } from "socket.io"; -import { PrismaClient } from "@prisma/client"; import { GameState, PlayerInfo, @@ -25,8 +24,7 @@ import { generateAvatarColor, } from "@/lib/scoring"; import { parseTheme } from "@/lib/theme"; - -const prisma = new PrismaClient(); +import { prisma } from "@/lib/db"; interface ActiveGame { gameCode: string; diff --git a/tailwind.config.ts b/tailwind.config.ts deleted file mode 100644 index 9ed1e30..0000000 --- a/tailwind.config.ts +++ /dev/null @@ -1,66 +0,0 @@ -import type { Config } from "tailwindcss"; - -export default { - darkMode: ["class"], - content: [ - "./src/pages/**/*.{js,ts,jsx,tsx,mdx}", - "./src/components/**/*.{js,ts,jsx,tsx,mdx}", - "./src/app/**/*.{js,ts,jsx,tsx,mdx}", - ], - theme: { - extend: { - colors: { - border: "hsl(var(--border))", - input: "hsl(var(--input))", - ring: "hsl(var(--ring))", - background: "hsl(var(--background))", - foreground: "hsl(var(--foreground))", - primary: { - DEFAULT: "hsl(var(--primary))", - foreground: "hsl(var(--primary-foreground))", - }, - secondary: { - DEFAULT: "hsl(var(--secondary))", - foreground: "hsl(var(--secondary-foreground))", - }, - destructive: { - DEFAULT: "hsl(var(--destructive))", - foreground: "hsl(var(--destructive-foreground))", - }, - muted: { - DEFAULT: "hsl(var(--muted))", - foreground: "hsl(var(--muted-foreground))", - }, - accent: { - DEFAULT: "hsl(var(--accent))", - foreground: "hsl(var(--accent-foreground))", - }, - popover: { - DEFAULT: "hsl(var(--popover))", - foreground: "hsl(var(--popover-foreground))", - }, - card: { - DEFAULT: "hsl(var(--card))", - foreground: "hsl(var(--card-foreground))", - }, - }, - fontFamily: { - sans: [ - "-apple-system", - "BlinkMacSystemFont", - "Segoe UI", - "Roboto", - "Helvetica Neue", - "Arial", - "sans-serif", - ], - }, - borderRadius: { - lg: "var(--radius)", - md: "calc(var(--radius) - 2px)", - sm: "calc(var(--radius) - 4px)", - }, - }, - }, - plugins: [require("tailwindcss-animate")], -} satisfies Config; diff --git a/tsconfig.json b/tsconfig.json index 7b28589..877b650 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,10 @@ { "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext"], + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], "allowJs": true, "skipLibCheck": true, "strict": true, @@ -10,7 +14,7 @@ "moduleResolution": "bundler", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve", + "jsx": "react-jsx", "incremental": true, "plugins": [ { @@ -18,9 +22,20 @@ } ], "paths": { - "@/*": ["./src/*"] - } + "@/*": [ + "./src/*" + ] + }, + "target": "ES2017" }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], - "exclude": ["node_modules"] + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] }