diff --git a/.env.example b/.env.example index 28c12cd..5d261ca 100644 --- a/.env.example +++ b/.env.example @@ -3,6 +3,7 @@ SMTP_HOST="host_url_for_smtp" SMTP_PORT="port_number_for smtp" SMTP_EMAIL="email_for_smtp" SMTP_PASS="password_for_smtp" + POSTGRES_DB="acm" POSTGRES_USER="acmsecy" POSTGRES_PASSWORD="acmheads" diff --git a/README.md b/README.md index d3270f6..9a8ee63 100644 --- a/README.md +++ b/README.md @@ -8,19 +8,8 @@ The official website for PEC ACM. # Install dependencies pnpm install -<<<<<<< vidhi/backendstuff -Or - -``bash -pnpm install -pnpm dev -`` - -# Building For Production -======= # Start development server pnpm dev ->>>>>>> main # Build for production pnpm build diff --git a/biome.json b/biome.json index 2442e34..f373bb3 100644 --- a/biome.json +++ b/biome.json @@ -22,11 +22,45 @@ "indentWidth": 2, "attributePosition": "multiline" }, - "assist": { "actions": { "source": { "organizeImports": "on" } } }, + "assist": { + "actions": { + "source": { + "organizeImports": { + "level": "on", + "options": { + "groups": [ + { "type": true, "source": ["**"] }, + ":BLANK_LINE:", + [":URL:", ":PACKAGE_WITH_PROTOCOL:"], + ":BLANK_LINE:", + ":NODE:", + ":BUN:", + ":PACKAGE:", + ":BLANK_LINE:", + "$assets/**", + ":BLANK_LINE:", + "$components/**", + ":BLANK_LINE:", + "$data/**", + ":BLANK_LINE:", + "$hooks/**", + ":BLANK_LINE:", + "$lib/**", + ":BLANK_LINE:", + "$styles/**" + ] + } + } + } + } + }, "linter": { "enabled": true, "rules": { - "recommended": true + "recommended": true, + "correctness": { + "noUnusedImports": "error" + } } }, "javascript": { diff --git a/package.json b/package.json index 7fd5f09..74b80dc 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,10 @@ "private": true, "type": "module", "scripts": { - "dev": "vite dev --port 3000", + "container:up": "docker compose up -d", + "container:down": "docker compose down -v", + "dev:app": "vite dev", + "dev": "concurrently -n 'api,app' -c blue,green,magenta 'pnpm container:up' 'pnpm dev:app'", "build": "vite build", "serve": "vite preview", "test": "vitest run", @@ -11,18 +14,22 @@ "format:write": "biome format --write", "lint": "biome lint", "check": "biome check", - "check:write": "biome check", + "check:write": "biome check --write", "prepare": "husky", "email:dev": "email dev --dir=./src/emails --port=2999" }, "dependencies": { + "@bogeychan/elysia-logger": "^0.1.10", "@elysiajs/eden": "^1.4.5", "@elysiajs/openapi": "^1.4.11", + "@fontsource/space-grotesk": "^5.2.10", "@netlify/vite-plugin-tanstack-start": "^1.0.2", "@react-email/components": "1.0.2", "@t3-oss/env-core": "^0.13.8", + "@tailwindcss/vite": "^4.1.18", "@tanstack/react-devtools": "^0.7.0", "@tanstack/react-form": "^1.0.0", + "@tanstack/react-form-start": "^1.28.0", "@tanstack/react-query": "^5.66.5", "@tanstack/react-query-devtools": "^5.84.2", "@tanstack/react-router": "^1.132.0", @@ -30,10 +37,15 @@ "@tanstack/react-router-ssr-query": "^1.131.7", "@tanstack/react-start": "^1.132.0", "@tanstack/router-plugin": "^1.132.0", + "concurrently": "^9.2.1", + "dotenv": "^17.2.4", "elysia": "^1.4.19", "nodemailer": "^7.0.12", + "pino": "^10.3.1", + "pino-pretty": "^13.1.3", "react": "^19.2.0", "react-dom": "^19.2.0", + "tailwindcss": "^4.1.18", "vite-tsconfig-paths": "^5.1.4", "zod": "^4.1.11" }, @@ -55,7 +67,6 @@ "sass": "^1.94.0", "typescript": "^5.7.2", "vite": "^7.1.7", - "vite-plugin-sass": "^0.1.0", "vitest": "^3.0.5", "web-vitals": "^5.1.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 21a58e4..533580a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,27 +8,39 @@ importers: .: dependencies: + '@bogeychan/elysia-logger': + specifier: ^0.1.10 + version: 0.1.10(elysia@1.4.19(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3))(pino@10.3.1) '@elysiajs/eden': specifier: ^1.4.5 version: 1.4.5(elysia@1.4.19(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)) '@elysiajs/openapi': specifier: ^1.4.11 version: 1.4.11(elysia@1.4.19(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)) + '@fontsource/space-grotesk': + specifier: ^5.2.10 + version: 5.2.10 '@netlify/vite-plugin-tanstack-start': specifier: ^1.0.2 - version: 1.1.12(@netlify/api@14.0.10)(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.2)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.1.12(@netlify/api@14.0.10)(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.2)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) '@react-email/components': specifier: 1.0.2 version: 1.0.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@t3-oss/env-core': specifier: ^0.13.8 version: 0.13.8(typescript@5.9.3)(zod@4.1.12) + '@tailwindcss/vite': + specifier: ^4.1.18 + version: 4.1.18(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) '@tanstack/react-devtools': specifier: ^0.7.0 version: 0.7.11(@types/react-dom@19.2.3(@types/react@19.2.5))(@types/react@19.2.5)(csstype@3.2.3)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(solid-js@1.9.10) '@tanstack/react-form': specifier: ^1.0.0 - version: 1.25.0(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 1.25.0(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@tanstack/react-form-start': + specifier: ^1.28.0 + version: 1.28.0(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tanstack/react-query': specifier: ^5.66.5 version: 5.90.10(react@19.2.0) @@ -40,31 +52,46 @@ importers: version: 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tanstack/react-router-devtools': specifier: ^1.132.0 - version: 1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.136.8)(@types/node@22.19.1)(csstype@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass@1.94.0)(solid-js@1.9.10)(tsx@4.20.6)(yaml@2.8.1) + version: 1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.136.8)(@types/node@22.19.1)(csstype@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass-embedded@1.97.3)(sass@1.94.0)(solid-js@1.9.10)(tsx@4.20.6)(yaml@2.8.1) '@tanstack/react-router-ssr-query': specifier: ^1.131.7 version: 1.136.8(@tanstack/query-core@5.90.10)(@tanstack/react-query@5.90.10(react@19.2.0))(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.136.8)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tanstack/react-start': specifier: ^1.132.0 - version: 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) '@tanstack/router-plugin': specifier: ^1.132.0 - version: 1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + concurrently: + specifier: ^9.2.1 + version: 9.2.1 + dotenv: + specifier: ^17.2.4 + version: 17.2.4 elysia: specifier: ^1.4.19 version: 1.4.19(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3) nodemailer: specifier: ^7.0.12 version: 7.0.12 + pino: + specifier: ^10.3.1 + version: 10.3.1 + pino-pretty: + specifier: ^13.1.3 + version: 13.1.3 react: specifier: ^19.2.0 version: 19.2.0 react-dom: specifier: ^19.2.0 version: 19.2.0(react@19.2.0) + tailwindcss: + specifier: ^4.1.18 + version: 4.1.18 vite-tsconfig-paths: specifier: ^5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) zod: specifier: ^4.1.11 version: 4.1.12 @@ -77,7 +104,7 @@ importers: version: 5.1.0(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass@1.94.0) '@tanstack/devtools-vite': specifier: ^0.3.11 - version: 0.3.11(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 0.3.11(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) '@testing-library/dom': specifier: ^10.4.0 version: 10.4.1 @@ -98,7 +125,7 @@ importers: version: 19.2.3(@types/react@19.2.5) '@vitejs/plugin-react': specifier: ^5.0.4 - version: 5.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) babel-plugin-react-compiler: specifier: ^1.0.0 version: 1.0.0 @@ -119,13 +146,10 @@ importers: version: 5.9.3 vite: specifier: ^7.1.7 - version: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) - vite-plugin-sass: - specifier: ^0.1.0 - version: 0.1.0 + version: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) vitest: specifier: ^3.0.5 - version: 3.2.4(@types/node@22.19.1)(jiti@2.6.1)(jsdom@27.2.0)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + version: 3.2.4(@types/node@22.19.1)(jiti@2.6.1)(jsdom@27.2.0)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) web-vitals: specifier: ^5.1.0 version: 5.1.0 @@ -475,9 +499,18 @@ packages: cpu: [x64] os: [win32] + '@bogeychan/elysia-logger@0.1.10': + resolution: {integrity: sha512-wFp3KUCNIkCV4zcbo70gifHH99ch7e4LNrP5Xa5e2MRO2MDyPgM92SWQmrzkng6PsSZk13+UKJskGNQ+ZuDZkQ==} + peerDependencies: + elysia: '>= 1.2.10' + pino: '>= 9.6.0' + '@borewit/text-codec@0.1.1': resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} + '@bufbuild/protobuf@2.11.0': + resolution: {integrity: sha512-sBXGT13cpmPR5BMgHE6UEEfEaShh5Ror6rfN3yEK5si7QVrtZg8LEPQb0VVhiLRUslD2yLnXtnRzG035J/mZXQ==} + '@colors/colors@1.6.0': resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} engines: {node: '>=0.1.90'} @@ -856,6 +889,9 @@ packages: '@fastify/busboy@3.2.0': resolution: {integrity: sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==} + '@fontsource/space-grotesk@5.2.10': + resolution: {integrity: sha512-XNXEbT74OIITPqw2H6HXwPDp85fy43uxfBwFR5PU+9sLnjuLj12KlhVM9nZVN6q6dlKjkuN8JisW/OBxwxgUew==} + '@humanwhocodes/momoa@2.0.4': resolution: {integrity: sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==} engines: {node: '>=10.10.0'} @@ -1418,6 +1454,9 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} + '@pinojs/redact@0.4.0': + resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -1971,6 +2010,96 @@ packages: zod: optional: true + '@tailwindcss/node@4.1.18': + resolution: {integrity: sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==} + + '@tailwindcss/oxide-android-arm64@4.1.18': + resolution: {integrity: sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.1.18': + resolution: {integrity: sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.1.18': + resolution: {integrity: sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.1.18': + resolution: {integrity: sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + resolution: {integrity: sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + resolution: {integrity: sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + resolution: {integrity: sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + resolution: {integrity: sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.1.18': + resolution: {integrity: sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.1.18': + resolution: {integrity: sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + resolution: {integrity: sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + resolution: {integrity: sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.1.18': + resolution: {integrity: sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==} + engines: {node: '>= 10'} + + '@tailwindcss/vite@4.1.18': + resolution: {integrity: sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==} + peerDependencies: + vite: ^5.2.0 || ^6 || ^7 + '@tanstack/devtools-client@0.0.3': resolution: {integrity: sha512-kl0r6N5iIL3t9gGDRAv55VRM3UIyMKVH83esRGq7xBjYsRLe/BeCIN2HqrlJkObUXQMKhy7i8ejuGOn+bDqDBw==} engines: {node: '>=18'} @@ -1987,6 +2116,10 @@ packages: resolution: {integrity: sha512-RL1f5ZlfZMpghrCIdzl6mLOFLTuhqmPNblZgBaeKfdtk5rfbjykurv+VfYydOFXj0vxVIoA2d/zT7xfD7Ph8fw==} engines: {node: '>=18'} + '@tanstack/devtools-event-client@0.4.0': + resolution: {integrity: sha512-RPfGuk2bDZgcu9bAJodvO2lnZeHuz4/71HjZ0bGb/SPg8+lyTA+RLSKQvo7fSmPSi8/vcH3aKQ8EM9ywf1olaw==} + engines: {node: '>=18'} + '@tanstack/devtools-ui@0.4.4': resolution: {integrity: sha512-5xHXFyX3nom0UaNfiOM92o6ziaHjGo3mcSGe2HD5Xs8dWRZNpdZ0Smd0B9ddEhy0oB+gXyMzZgUJb9DmrZV0Mg==} engines: {node: '>=18'} @@ -2014,10 +2147,17 @@ packages: '@tanstack/form-core@1.25.0': resolution: {integrity: sha512-OEWW2uTOFMyRmHrVEiPOn+J27ekQ/vXwRAJt9kD8U8vCt8CmpClj989OOGGSBSVJtDNxGUcWyKF8gYznnqIyaw==} + '@tanstack/form-core@1.28.0': + resolution: {integrity: sha512-MX3YveB6SKHAJ2yUwp+Ca/PCguub8bVEnLcLUbFLwdkSRMkP0lMGdaZl+F0JuEgZw56c6iFoRyfILhS7OQpydA==} + '@tanstack/history@1.133.28': resolution: {integrity: sha512-B7+x7eP2FFvi3fgd3rNH9o/Eixt+pp0zCIdGhnQbAJjFrlwIKGjGnwyJjhWJ5fMQlGks/E2LdDTqEV4W9Plx7g==} engines: {node: '>=12'} + '@tanstack/pacer-lite@0.1.1': + resolution: {integrity: sha512-y/xtNPNt/YeyoVxE/JCx+T7yjEzpezmbb+toK8DDD1P4m7Kzs5YR956+7OKexG3f8aXgC3rLZl7b1V+yNUSy5w==} + engines: {node: '>=18'} + '@tanstack/pacer@0.15.4': resolution: {integrity: sha512-vGY+CWsFZeac3dELgB6UZ4c7OacwsLb8hvL2gLS6hTgy8Fl0Bm/aLokHaeDIP+q9F9HUZTnp360z9uv78eg8pg==} engines: {node: '>=18'} @@ -2037,6 +2177,15 @@ packages: react: '>=16.8' react-dom: '>=16.8' + '@tanstack/react-form-start@1.28.0': + resolution: {integrity: sha512-9DUHFeklJxI4MCt5YMEr1tdfWIvcEMOn0ZDTEb6TL9VnQk6HmZ3AUqO3OdBPOT+MtH2u6VZudqwtPd3SjYQDqQ==} + peerDependencies: + '@tanstack/react-start': ^1.134.9 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@tanstack/react-start': + optional: true + '@tanstack/react-form@1.25.0': resolution: {integrity: sha512-SjKpBkjegNVW9WU+qlO8+/+kSbSEwo2zwHnrQz/yOnnJRhtdgubUt50LfeUtdzkMsbbptQ5MSZrXH03kidQjyw==} peerDependencies: @@ -2046,6 +2195,15 @@ packages: '@tanstack/react-start': optional: true + '@tanstack/react-form@1.28.0': + resolution: {integrity: sha512-ibLcf5QkTogV0Ly944CuqGxWTpHyreNA4Cy8Wtky7zE9wtE3HVapQt4/hUuXo51zihfTkv5URiXpoTSKF5Xosg==} + peerDependencies: + '@tanstack/react-start': '*' + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@tanstack/react-start': + optional: true + '@tanstack/react-query-devtools@5.90.2': resolution: {integrity: sha512-vAXJzZuBXtCQtrY3F/yUNJCV4obT/A/n81kb3+YqLbro5Z2+phdAbceO+deU3ywPw8B42oyJlp4FhO0SoivDFQ==} peerDependencies: @@ -2485,6 +2643,10 @@ packages: async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + atomically@2.1.0: resolution: {integrity: sha512-+gDffFXRW6sl/HCwbta7zK4uNqbPjv4YJEAdz7Vu+FLQHe77eZ4bvbJGi4hE0QPeJlMYMA3piXEr1UL3dAwx7Q==} @@ -2671,6 +2833,12 @@ packages: resolution: {integrity: sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==} engines: {node: '>=18'} + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + colorjs.io@0.5.2: + resolution: {integrity: sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==} + commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} engines: {node: '>=14'} @@ -2697,6 +2865,11 @@ packages: resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} engines: {node: '>= 14'} + concurrently@9.2.1: + resolution: {integrity: sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==} + engines: {node: '>=18'} + hasBin: true + conf@15.0.2: resolution: {integrity: sha512-JBSrutapCafTrddF9dH3lc7+T2tBycGF4uPkI4Js+g4vLLEhG6RZcFi3aJd5zntdf5tQxAejJt8dihkoQ/eSJw==} engines: {node: '>=20'} @@ -2800,6 +2973,9 @@ packages: resolution: {integrity: sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA==} engines: {node: '>=20'} + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + debounce-fn@6.0.0: resolution: {integrity: sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==} engines: {node: '>=18'} @@ -2832,6 +3008,9 @@ packages: decimal.js@10.6.0: resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + decode-formdata@0.9.0: + resolution: {integrity: sha512-q5uwOjR3Um5YD+ZWPOF/1sGHVW9A5rCrRwITQChRXlmPkxDFBqCm4jNTIVdGHNH9OnR+V9MoZVgRhsFb+ARbUw==} + dedent@1.7.0: resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==} peerDependencies: @@ -2913,6 +3092,9 @@ packages: dettle@1.0.5: resolution: {integrity: sha512-ZVyjhAJ7sCe1PNXEGveObOH9AC8QvMga3HJIghHawtG7mE4K5pW9nz/vDGAr/U7a3LWgdOzEE7ac9MURnyfaTA==} + devalue@5.6.2: + resolution: {integrity: sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==} + diff@8.0.2: resolution: {integrity: sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==} engines: {node: '>=0.3.1'} @@ -2945,6 +3127,10 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + dotenv@17.2.4: + resolution: {integrity: sha512-mudtfb4zRB4bVvdj0xRo+e6duH1csJRM8IukBqfTRvHotn9+LBXB8ynAidP9zHqoRC/fsllXgk4kCKlR21fIhw==} + engines: {node: '>=12'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -2999,6 +3185,10 @@ packages: resolution: {integrity: sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==} engines: {node: '>=10.2.0'} + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} + engines: {node: '>=10.13.0'} + entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -3099,6 +3289,9 @@ packages: engines: {node: '>= 10.17.0'} hasBin: true + fast-copy@4.0.2: + resolution: {integrity: sha512-ybA6PDXIXOXivLJK/z9e+Otk7ve13I4ckBvGO5I2RRmBU1gMHLVDJYEuJYhGwez7YNlYji2M2DvVU+a9mSFDlw==} + fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} @@ -3276,6 +3469,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + help-me@5.0.0: + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + hosted-git-info@7.0.2: resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} engines: {node: ^16.14.0 || >=18.0.0} @@ -3475,6 +3671,10 @@ packages: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + jpeg-js@0.4.4: resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} @@ -3921,6 +4121,10 @@ packages: omit.js@2.0.2: resolution: {integrity: sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==} + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -4057,6 +4261,20 @@ packages: picoquery@2.5.0: resolution: {integrity: sha512-j1kgOFxtaCyoFCkpoYG2Oj3OdGakadO7HZ7o5CqyRazlmBekKhbDoUnNnXASE07xSY4nDImWZkrZv7toSxMi/g==} + pino-abstract-transport@3.0.0: + resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} + + pino-pretty@13.1.3: + resolution: {integrity: sha512-ttXRkkOz6WWC95KeY9+xxWL6AtImwbyMHrL1mSwqwW9u+vLp/WIElvHvCSDg0xO/Dzrggz1zv3rN5ovTRVowKg==} + hasBin: true + + pino-std-serializers@7.1.0: + resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + + pino@10.3.1: + resolution: {integrity: sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==} + hasBin: true + pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} @@ -4098,6 +4316,9 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -4120,6 +4341,9 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + quote-unquote@1.0.0: resolution: {integrity: sha512-twwRO/ilhlG/FIgYeKGFqyHhoEhqgnKVkcmqMKi2r524gz3ZbDTcyFt38E9xjJI2vT+KbRNHVbnJ/e0I25Azwg==} @@ -4177,6 +4401,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + recast@0.23.11: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} @@ -4238,6 +4466,9 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} @@ -4251,11 +4482,125 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + sass-embedded-all-unknown@1.97.3: + resolution: {integrity: sha512-t6N46NlPuXiY3rlmG6/+1nwebOBOaLFOOVqNQOC2cJhghOD4hh2kHNQQTorCsbY9S1Kir2la1/XLBwOJfui0xg==} + cpu: ['!arm', '!arm64', '!riscv64', '!x64'] + + sass-embedded-android-arm64@1.97.3: + resolution: {integrity: sha512-aiZ6iqiHsUsaDx0EFbbmmA0QgxicSxVVN3lnJJ0f1RStY0DthUkquGT5RJ4TPdaZ6ebeJWkboV4bra+CP766eA==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [android] + + sass-embedded-android-arm@1.97.3: + resolution: {integrity: sha512-cRTtf/KV/q0nzGZoUzVkeIVVFv3L/tS1w4WnlHapphsjTXF/duTxI8JOU1c/9GhRPiMdfeXH7vYNcMmtjwX7jg==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [android] + + sass-embedded-android-riscv64@1.97.3: + resolution: {integrity: sha512-zVEDgl9JJodofGHobaM/q6pNETG69uuBIGQHRo789jloESxxZe82lI3AWJQuPmYCOG5ElfRthqgv89h3gTeLYA==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [android] + + sass-embedded-android-x64@1.97.3: + resolution: {integrity: sha512-3ke0le7ZKepyXn/dKKspYkpBC0zUk/BMciyP5ajQUDy4qJwobd8zXdAq6kOkdiMB+d9UFJOmEkvgFJHl3lqwcw==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [android] + + sass-embedded-darwin-arm64@1.97.3: + resolution: {integrity: sha512-fuqMTqO4gbOmA/kC5b9y9xxNYw6zDEyfOtMgabS7Mz93wimSk2M1quQaTJnL98Mkcsl2j+7shNHxIS/qpcIDDA==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [darwin] + + sass-embedded-darwin-x64@1.97.3: + resolution: {integrity: sha512-b/2RBs/2bZpP8lMkyZ0Px0vkVkT8uBd0YXpOwK7iOwYkAT8SsO4+WdVwErsqC65vI5e1e5p1bb20tuwsoQBMVA==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [darwin] + + sass-embedded-linux-arm64@1.97.3: + resolution: {integrity: sha512-IP1+2otCT3DuV46ooxPaOKV1oL5rLjteRzf8ldZtfIEcwhSgSsHgA71CbjYgLEwMY9h4jeal8Jfv3QnedPvSjg==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + + sass-embedded-linux-arm@1.97.3: + resolution: {integrity: sha512-2lPQ7HQQg4CKsH18FTsj2hbw5GJa6sBQgDsls+cV7buXlHjqF8iTKhAQViT6nrpLK/e8nFCoaRgSqEC8xMnXuA==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + + sass-embedded-linux-musl-arm64@1.97.3: + resolution: {integrity: sha512-Lij0SdZCsr+mNRSyDZ7XtJpXEITrYsaGbOTz5e6uFLJ9bmzUbV7M8BXz2/cA7bhfpRPT7/lwRKPdV4+aR9Ozcw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + + sass-embedded-linux-musl-arm@1.97.3: + resolution: {integrity: sha512-cBTMU68X2opBpoYsSZnI321gnoaiMBEtc+60CKCclN6PCL3W3uXm8g4TLoil1hDD6mqU9YYNlVG6sJ+ZNef6Lg==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + + sass-embedded-linux-musl-riscv64@1.97.3: + resolution: {integrity: sha512-sBeLFIzMGshR4WmHAD4oIM7WJVkSoCIEwutzptFtGlSlwfNiijULp+J5hA2KteGvI6Gji35apR5aWj66wEn/iA==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [linux] + + sass-embedded-linux-musl-x64@1.97.3: + resolution: {integrity: sha512-/oWJ+OVrDg7ADDQxRLC/4g1+Nsz1g4mkYS2t6XmyMJKFTFK50FVI2t5sOdFH+zmMp+nXHKM036W94y9m4jjEcw==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + + sass-embedded-linux-riscv64@1.97.3: + resolution: {integrity: sha512-l3IfySApLVYdNx0Kjm7Zehte1CDPZVcldma3dZt+TfzvlAEerM6YDgsk5XEj3L8eHBCgHgF4A0MJspHEo2WNfA==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [linux] + + sass-embedded-linux-x64@1.97.3: + resolution: {integrity: sha512-Kwqwc/jSSlcpRjULAOVbndqEy2GBzo6OBmmuBVINWUaJLJ8Kczz3vIsDUWLfWz/kTEw9FHBSiL0WCtYLVAXSLg==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + + sass-embedded-unknown-all@1.97.3: + resolution: {integrity: sha512-/GHajyYJmvb0IABUQHbVHf1nuHPtIDo/ClMZ81IDr59wT5CNcMe7/dMNujXwWugtQVGI5UGmqXWZQCeoGnct8Q==} + os: ['!android', '!darwin', '!linux', '!win32'] + + sass-embedded-win32-arm64@1.97.3: + resolution: {integrity: sha512-RDGtRS1GVvQfMGAmVXNxYiUOvPzn9oO1zYB/XUM9fudDRnieYTcUytpNTQZLs6Y1KfJxgt5Y+giRceC92fT8Uw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [win32] + + sass-embedded-win32-x64@1.97.3: + resolution: {integrity: sha512-SFRa2lED9UEwV6vIGeBXeBOLKF+rowF3WmNfb/BzhxmdAsKofCXrJ8ePW7OcDVrvNEbTOGwhsReIsF5sH8fVaw==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [win32] + + sass-embedded@1.97.3: + resolution: {integrity: sha512-eKzFy13Nk+IRHhlAwP3sfuv+PzOrvzUkwJK2hdoCKYcWGSdmwFpeGpWmyewdw8EgBnsKaSBtgf/0b2K635ecSA==} + engines: {node: '>=16.0.0'} + hasBin: true + sass@1.94.0: resolution: {integrity: sha512-Dqh7SiYcaFtdv5Wvku6QgS5IGPm281L+ZtVD1U2FJa7Q0EFRlq8Z3sjYtz6gYObsYThUOz9ArwFqPZx+1azILQ==} engines: {node: '>=14.0.0'} hasBin: true + sass@1.97.3: + resolution: {integrity: sha512-fDz1zJpd5GycprAbu4Q2PV/RprsRtKC/0z82z0JLgdytmcq0+ujJbJ/09bPGDxCLkKY3Np5cRAOcWiVkLXJURg==} + engines: {node: '>=14.0.0'} + hasBin: true + sax@1.4.3: resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} @@ -4266,6 +4611,9 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + secure-json-parse@4.1.0: + resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} + selderee@0.11.0: resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} @@ -4341,6 +4689,9 @@ packages: solid-js@1.9.10: resolution: {integrity: sha512-Coz956cos/EPDlhs6+jsdTxKuJDPT7B5SVIWgABwROyxjY7Xbr8wkzD68Et+NxnV7DLJ3nJdAC2r9InuV/4Jew==} + sonic-boom@4.2.1: + resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -4368,6 +4719,10 @@ packages: spdx-license-ids@3.0.22: resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -4426,6 +4781,10 @@ packages: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} @@ -4459,6 +4818,10 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -4471,6 +4834,14 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + sync-child-process@1.0.2: + resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==} + engines: {node: '>=16.0.0'} + + sync-message-port@1.2.0: + resolution: {integrity: sha512-gAQ9qrUN/UCypHtGFbbe7Rc/f9bzO88IwrG8TDo/aMKAApKyD6E3W4Cm0EfhfBb6Z6SKt59tTCTfD+n1xmAvMg==} + engines: {node: '>=16.0.0'} + system-architecture@0.1.0: resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} engines: {node: '>=18'} @@ -4482,6 +4853,10 @@ packages: tailwindcss@4.1.18: resolution: {integrity: sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==} + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + tar-stream@3.1.7: resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} @@ -4495,6 +4870,10 @@ packages: text-hex@1.0.0: resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + thread-stream@4.0.0: + resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==} + engines: {node: '>=20'} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -4562,6 +4941,10 @@ packages: resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} engines: {node: '>=20'} + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + triple-beam@1.4.1: resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} engines: {node: '>= 14.0.0'} @@ -4740,6 +5123,9 @@ packages: resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + varint@6.0.0: + resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -4749,9 +5135,6 @@ packages: engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite-plugin-sass@0.1.0: - resolution: {integrity: sha512-gLwvs3ozfDAOZCqs+PepkTd4078m8tfq50IlmTW/OphlWsW95uP7lQ5A3NezfUfTZDTCOA4nFlYnOWRpsKYOqw==} - vite-tsconfig-paths@5.1.4: resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} peerDependencies: @@ -5652,8 +6035,16 @@ snapshots: '@biomejs/cli-win32-x64@2.2.4': optional: true + '@bogeychan/elysia-logger@0.1.10(elysia@1.4.19(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3))(pino@10.3.1)': + dependencies: + elysia: 1.4.19(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3) + pino: 10.3.1 + '@borewit/text-codec@0.1.1': {} + '@bufbuild/protobuf@2.11.0': + optional: true + '@colors/colors@1.6.0': {} '@csstools/color-helpers@5.1.0': {} @@ -5867,6 +6258,8 @@ snapshots: '@fastify/busboy@3.2.0': {} + '@fontsource/space-grotesk@5.2.10': {} + '@humanwhocodes/momoa@2.0.4': {} '@iarna/toml@2.2.5': {} @@ -6278,12 +6671,12 @@ snapshots: '@netlify/types@2.2.0': {} - '@netlify/vite-plugin-tanstack-start@1.1.12(@netlify/api@14.0.10)(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.2)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@netlify/vite-plugin-tanstack-start@1.1.12(@netlify/api@14.0.10)(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(rollup@4.53.2)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - '@netlify/vite-plugin': 2.7.12(@netlify/api@14.0.10)(rollup@4.53.2)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + '@netlify/vite-plugin': 2.7.12(@netlify/api@14.0.10)(rollup@4.53.2)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: - '@tanstack/react-start': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + '@tanstack/react-start': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6311,12 +6704,12 @@ snapshots: - supports-color - uploadthing - '@netlify/vite-plugin@2.7.12(@netlify/api@14.0.10)(rollup@4.53.2)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@netlify/vite-plugin@2.7.12(@netlify/api@14.0.10)(rollup@4.53.2)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@netlify/dev': 4.8.0(@netlify/api@14.0.10)(rollup@4.53.2) '@netlify/dev-utils': 4.3.1 dedent: 1.7.0 - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -6592,6 +6985,8 @@ snapshots: '@parcel/watcher-win32-ia32': 2.5.1 '@parcel/watcher-win32-x64': 2.5.1 + '@pinojs/redact@0.4.0': {} + '@pkgjs/parseargs@0.11.0': optional: true @@ -6755,83 +7150,492 @@ snapshots: dependencies: react: 19.2.0 - '@rolldown/pluginutils@1.0.0-beta.40': {} - - '@rolldown/pluginutils@1.0.0-beta.47': {} - - '@rollup/pluginutils@5.3.0(rollup@4.53.2)': + '@react-email/body@0.2.0(react@19.2.0)': dependencies: - '@types/estree': 1.0.8 - estree-walker: 2.0.2 - picomatch: 4.0.3 - optionalDependencies: - rollup: 4.53.2 - - '@rollup/rollup-android-arm-eabi@4.53.2': - optional: true - - '@rollup/rollup-android-arm64@4.53.2': - optional: true - - '@rollup/rollup-darwin-arm64@4.53.2': - optional: true - - '@rollup/rollup-darwin-x64@4.53.2': - optional: true - - '@rollup/rollup-freebsd-arm64@4.53.2': - optional: true - - '@rollup/rollup-freebsd-x64@4.53.2': - optional: true + react: 19.2.0 - '@rollup/rollup-linux-arm-gnueabihf@4.53.2': - optional: true + '@react-email/button@0.2.0(react@19.2.0)': + dependencies: + react: 19.2.0 - '@rollup/rollup-linux-arm-musleabihf@4.53.2': - optional: true + '@react-email/code-block@0.2.0(react@19.2.0)': + dependencies: + prismjs: 1.30.0 + react: 19.2.0 - '@rollup/rollup-linux-arm64-gnu@4.53.2': - optional: true + '@react-email/code-inline@0.0.5(react@19.2.0)': + dependencies: + react: 19.2.0 - '@rollup/rollup-linux-arm64-musl@4.53.2': - optional: true + '@react-email/column@0.0.13(react@19.2.0)': + dependencies: + react: 19.2.0 - '@rollup/rollup-linux-loong64-gnu@4.53.2': - optional: true + '@react-email/components@1.0.2(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@react-email/body': 0.2.0(react@19.2.0) + '@react-email/button': 0.2.0(react@19.2.0) + '@react-email/code-block': 0.2.0(react@19.2.0) + '@react-email/code-inline': 0.0.5(react@19.2.0) + '@react-email/column': 0.0.13(react@19.2.0) + '@react-email/container': 0.0.15(react@19.2.0) + '@react-email/font': 0.0.9(react@19.2.0) + '@react-email/head': 0.0.12(react@19.2.0) + '@react-email/heading': 0.0.15(react@19.2.0) + '@react-email/hr': 0.0.11(react@19.2.0) + '@react-email/html': 0.0.11(react@19.2.0) + '@react-email/img': 0.0.11(react@19.2.0) + '@react-email/link': 0.0.12(react@19.2.0) + '@react-email/markdown': 0.0.17(react@19.2.0) + '@react-email/preview': 0.0.13(react@19.2.0) + '@react-email/render': 2.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@react-email/row': 0.0.12(react@19.2.0) + '@react-email/section': 0.0.16(react@19.2.0) + '@react-email/tailwind': 2.0.2(@react-email/body@0.2.0(react@19.2.0))(@react-email/button@0.2.0(react@19.2.0))(@react-email/code-block@0.2.0(react@19.2.0))(@react-email/code-inline@0.0.5(react@19.2.0))(@react-email/container@0.0.15(react@19.2.0))(@react-email/heading@0.0.15(react@19.2.0))(@react-email/hr@0.0.11(react@19.2.0))(@react-email/img@0.0.11(react@19.2.0))(@react-email/link@0.0.12(react@19.2.0))(@react-email/preview@0.0.13(react@19.2.0))(@react-email/text@0.1.5(react@19.2.0))(react@19.2.0) + '@react-email/text': 0.1.5(react@19.2.0) + react: 19.2.0 + transitivePeerDependencies: + - react-dom + + '@react-email/container@0.0.15(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/font@0.0.9(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/head@0.0.12(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/heading@0.0.15(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/hr@0.0.11(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/html@0.0.11(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/img@0.0.11(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/link@0.0.12(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/markdown@0.0.17(react@19.2.0)': + dependencies: + marked: 15.0.12 + react: 19.2.0 + + '@react-email/preview-server@5.1.0(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass@1.94.0)': + dependencies: + next: 16.0.10(@babel/core@7.28.5)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass@1.94.0) + transitivePeerDependencies: + - '@babel/core' + - '@opentelemetry/api' + - '@playwright/test' + - babel-plugin-macros + - babel-plugin-react-compiler + - react + - react-dom + - sass + + '@react-email/preview@0.0.13(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/render@2.0.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + html-to-text: 9.0.5 + prettier: 3.6.2 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + + '@react-email/row@0.0.12(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/section@0.0.16(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@react-email/tailwind@2.0.2(@react-email/body@0.2.0(react@19.2.0))(@react-email/button@0.2.0(react@19.2.0))(@react-email/code-block@0.2.0(react@19.2.0))(@react-email/code-inline@0.0.5(react@19.2.0))(@react-email/container@0.0.15(react@19.2.0))(@react-email/heading@0.0.15(react@19.2.0))(@react-email/hr@0.0.11(react@19.2.0))(@react-email/img@0.0.11(react@19.2.0))(@react-email/link@0.0.12(react@19.2.0))(@react-email/preview@0.0.13(react@19.2.0))(@react-email/text@0.1.5(react@19.2.0))(react@19.2.0)': + dependencies: + '@react-email/text': 0.1.5(react@19.2.0) + react: 19.2.0 + tailwindcss: 4.1.18 + optionalDependencies: + '@react-email/body': 0.2.0(react@19.2.0) + '@react-email/button': 0.2.0(react@19.2.0) + '@react-email/code-block': 0.2.0(react@19.2.0) + '@react-email/code-inline': 0.0.5(react@19.2.0) + '@react-email/container': 0.0.15(react@19.2.0) + '@react-email/heading': 0.0.15(react@19.2.0) + '@react-email/hr': 0.0.11(react@19.2.0) + '@react-email/img': 0.0.11(react@19.2.0) + '@react-email/link': 0.0.12(react@19.2.0) + '@react-email/preview': 0.0.13(react@19.2.0) + + '@react-email/text@0.1.5(react@19.2.0)': + dependencies: + react: 19.2.0 + + '@rolldown/pluginutils@1.0.0-beta.40': {} + + '@rolldown/pluginutils@1.0.0-beta.47': {} + + '@rollup/pluginutils@5.3.0(rollup@4.53.2)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 4.0.3 + optionalDependencies: + rollup: 4.53.2 + + '@rollup/rollup-android-arm-eabi@4.53.2': + optional: true + + '@rollup/rollup-android-arm64@4.53.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.53.2': + optional: true + + '@rollup/rollup-darwin-x64@4.53.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.53.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.53.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.53.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.53.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.53.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.53.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.53.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.53.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.53.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.53.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.53.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.53.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.53.2': + optional: true + + '@selderee/plugin-htmlparser2@0.11.0': + dependencies: + domhandler: 5.0.3 + selderee: 0.11.0 + + '@sinclair/typebox@0.34.41': {} + + '@smithy/abort-controller@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/config-resolver@4.4.5': + dependencies: + '@smithy/node-config-provider': 4.3.7 + '@smithy/types': 4.11.0 + '@smithy/util-config-provider': 4.2.0 + '@smithy/util-endpoints': 3.2.7 + '@smithy/util-middleware': 4.2.7 + tslib: 2.8.1 + + '@smithy/core@3.20.0': + dependencies: + '@smithy/middleware-serde': 4.2.8 + '@smithy/protocol-http': 5.3.7 + '@smithy/types': 4.11.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-body-length-browser': 4.2.0 + '@smithy/util-middleware': 4.2.7 + '@smithy/util-stream': 4.5.8 + '@smithy/util-utf8': 4.2.0 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.2.7': + dependencies: + '@smithy/node-config-provider': 4.3.7 + '@smithy/property-provider': 4.2.7 + '@smithy/types': 4.11.0 + '@smithy/url-parser': 4.2.7 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.3.8': + dependencies: + '@smithy/protocol-http': 5.3.7 + '@smithy/querystring-builder': 4.2.7 + '@smithy/types': 4.11.0 + '@smithy/util-base64': 4.3.0 + tslib: 2.8.1 + + '@smithy/hash-node@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@smithy/invalid-dependency@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/is-array-buffer@4.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/middleware-content-length@4.2.7': + dependencies: + '@smithy/protocol-http': 5.3.7 + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/middleware-endpoint@4.4.1': + dependencies: + '@smithy/core': 3.20.0 + '@smithy/middleware-serde': 4.2.8 + '@smithy/node-config-provider': 4.3.7 + '@smithy/shared-ini-file-loader': 4.4.2 + '@smithy/types': 4.11.0 + '@smithy/url-parser': 4.2.7 + '@smithy/util-middleware': 4.2.7 + tslib: 2.8.1 + + '@smithy/middleware-retry@4.4.17': + dependencies: + '@smithy/node-config-provider': 4.3.7 + '@smithy/protocol-http': 5.3.7 + '@smithy/service-error-classification': 4.2.7 + '@smithy/smithy-client': 4.10.2 + '@smithy/types': 4.11.0 + '@smithy/util-middleware': 4.2.7 + '@smithy/util-retry': 4.2.7 + '@smithy/uuid': 1.1.0 + tslib: 2.8.1 + + '@smithy/middleware-serde@4.2.8': + dependencies: + '@smithy/protocol-http': 5.3.7 + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/middleware-stack@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/node-config-provider@4.3.7': + dependencies: + '@smithy/property-provider': 4.2.7 + '@smithy/shared-ini-file-loader': 4.4.2 + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.4.7': + dependencies: + '@smithy/abort-controller': 4.2.7 + '@smithy/protocol-http': 5.3.7 + '@smithy/querystring-builder': 4.2.7 + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/property-provider@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/protocol-http@5.3.7': + dependencies: + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/querystring-builder@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + '@smithy/util-uri-escape': 4.2.0 + tslib: 2.8.1 + + '@smithy/querystring-parser@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/service-error-classification@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + + '@smithy/shared-ini-file-loader@4.4.2': + dependencies: + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/signature-v4@5.3.7': + dependencies: + '@smithy/is-array-buffer': 4.2.0 + '@smithy/protocol-http': 5.3.7 + '@smithy/types': 4.11.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-middleware': 4.2.7 + '@smithy/util-uri-escape': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@smithy/smithy-client@4.10.2': + dependencies: + '@smithy/core': 3.20.0 + '@smithy/middleware-endpoint': 4.4.1 + '@smithy/middleware-stack': 4.2.7 + '@smithy/protocol-http': 5.3.7 + '@smithy/types': 4.11.0 + '@smithy/util-stream': 4.5.8 + tslib: 2.8.1 + + '@smithy/types@4.11.0': + dependencies: + tslib: 2.8.1 + + '@smithy/url-parser@4.2.7': + dependencies: + '@smithy/querystring-parser': 4.2.7 + '@smithy/types': 4.11.0 + tslib: 2.8.1 + + '@smithy/util-base64@4.3.0': + dependencies: + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@smithy/util-body-length-browser@4.2.0': + dependencies: + tslib: 2.8.1 - '@rollup/rollup-linux-ppc64-gnu@4.53.2': - optional: true + '@smithy/util-body-length-node@4.2.1': + dependencies: + tslib: 2.8.1 - '@rollup/rollup-linux-riscv64-gnu@4.53.2': - optional: true + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.8.1 - '@rollup/rollup-linux-riscv64-musl@4.53.2': - optional: true + '@smithy/util-buffer-from@4.2.0': + dependencies: + '@smithy/is-array-buffer': 4.2.0 + tslib: 2.8.1 - '@rollup/rollup-linux-s390x-gnu@4.53.2': - optional: true + '@smithy/util-config-provider@4.2.0': + dependencies: + tslib: 2.8.1 - '@rollup/rollup-linux-x64-gnu@4.53.2': - optional: true + '@smithy/util-defaults-mode-browser@4.3.16': + dependencies: + '@smithy/property-provider': 4.2.7 + '@smithy/smithy-client': 4.10.2 + '@smithy/types': 4.11.0 + tslib: 2.8.1 - '@rollup/rollup-linux-x64-musl@4.53.2': - optional: true + '@smithy/util-defaults-mode-node@4.2.19': + dependencies: + '@smithy/config-resolver': 4.4.5 + '@smithy/credential-provider-imds': 4.2.7 + '@smithy/node-config-provider': 4.3.7 + '@smithy/property-provider': 4.2.7 + '@smithy/smithy-client': 4.10.2 + '@smithy/types': 4.11.0 + tslib: 2.8.1 - '@rollup/rollup-openharmony-arm64@4.53.2': - optional: true + '@smithy/util-endpoints@3.2.7': + dependencies: + '@smithy/node-config-provider': 4.3.7 + '@smithy/types': 4.11.0 + tslib: 2.8.1 - '@rollup/rollup-win32-arm64-msvc@4.53.2': - optional: true + '@smithy/util-hex-encoding@4.2.0': + dependencies: + tslib: 2.8.1 - '@rollup/rollup-win32-ia32-msvc@4.53.2': - optional: true + '@smithy/util-middleware@4.2.7': + dependencies: + '@smithy/types': 4.11.0 + tslib: 2.8.1 - '@rollup/rollup-win32-x64-gnu@4.53.2': - optional: true + '@smithy/util-retry@4.2.7': + dependencies: + '@smithy/service-error-classification': 4.2.7 + '@smithy/types': 4.11.0 + tslib: 2.8.1 - '@rollup/rollup-win32-x64-msvc@4.53.2': - optional: true + '@smithy/util-stream@4.5.8': + dependencies: + '@smithy/fetch-http-handler': 5.3.8 + '@smithy/node-http-handler': 4.4.7 + '@smithy/types': 4.11.0 + '@smithy/util-base64': 4.3.0 + '@smithy/util-buffer-from': 4.2.0 + '@smithy/util-hex-encoding': 4.2.0 + '@smithy/util-utf8': 4.2.0 + tslib: 2.8.1 + + '@smithy/util-uri-escape@4.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.8.1 '@selderee/plugin-htmlparser2@0.11.0': dependencies: @@ -7164,6 +7968,74 @@ snapshots: typescript: 5.9.3 zod: 4.1.12 + '@tailwindcss/node@4.1.18': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.19.0 + jiti: 2.6.1 + lightningcss: 1.30.2 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.1.18 + + '@tailwindcss/oxide-android-arm64@4.1.18': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.1.18': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.1.18': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.1.18': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.1.18': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.1.18': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.1.18': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.1.18': + optional: true + + '@tailwindcss/oxide@4.1.18': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.1.18 + '@tailwindcss/oxide-darwin-arm64': 4.1.18 + '@tailwindcss/oxide-darwin-x64': 4.1.18 + '@tailwindcss/oxide-freebsd-x64': 4.1.18 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.18 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.18 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.18 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.18 + '@tailwindcss/oxide-linux-x64-musl': 4.1.18 + '@tailwindcss/oxide-wasm32-wasi': 4.1.18 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.18 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.18 + + '@tailwindcss/vite@4.1.18(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + dependencies: + '@tailwindcss/node': 4.1.18 + '@tailwindcss/oxide': 4.1.18 + tailwindcss: 4.1.18 + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + '@tanstack/devtools-client@0.0.3': dependencies: '@tanstack/devtools-event-client': 0.3.5 @@ -7181,6 +8053,8 @@ snapshots: '@tanstack/devtools-event-client@0.3.5': {} + '@tanstack/devtools-event-client@0.4.0': {} + '@tanstack/devtools-ui@0.4.4(csstype@3.2.3)(solid-js@1.9.10)': dependencies: clsx: 2.1.1 @@ -7189,7 +8063,7 @@ snapshots: transitivePeerDependencies: - csstype - '@tanstack/devtools-vite@0.3.11(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tanstack/devtools-vite@0.3.11(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 '@babel/generator': 7.28.5 @@ -7201,7 +8075,7 @@ snapshots: chalk: 5.6.2 launch-editor: 2.12.0 picomatch: 4.0.3 - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - bufferutil - supports-color @@ -7223,7 +8097,7 @@ snapshots: - csstype - utf-8-validate - '@tanstack/directive-functions-plugin@1.134.5(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tanstack/directive-functions-plugin@1.134.5(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.28.5 @@ -7233,7 +8107,7 @@ snapshots: babel-dead-code-elimination: 1.0.10 pathe: 2.0.3 tiny-invariant: 1.3.3 - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -7243,8 +8117,16 @@ snapshots: '@tanstack/pacer': 0.15.4 '@tanstack/store': 0.7.7 + '@tanstack/form-core@1.28.0': + dependencies: + '@tanstack/devtools-event-client': 0.4.0 + '@tanstack/pacer-lite': 0.1.1 + '@tanstack/store': 0.7.7 + '@tanstack/history@1.133.28': {} + '@tanstack/pacer-lite@0.1.1': {} + '@tanstack/pacer@0.15.4': dependencies: '@tanstack/devtools-event-client': 0.3.5 @@ -7267,13 +8149,34 @@ snapshots: - solid-js - utf-8-validate - '@tanstack/react-form@1.25.0(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@tanstack/react-form-start@1.28.0(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/react-form': 1.28.0(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + decode-formdata: 0.9.0 + devalue: 5.6.2 + react: 19.2.0 + optionalDependencies: + '@tanstack/react-start': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + transitivePeerDependencies: + - react-dom + + '@tanstack/react-form@1.25.0(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@tanstack/form-core': 1.25.0 '@tanstack/react-store': 0.7.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 optionalDependencies: - '@tanstack/react-start': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + '@tanstack/react-start': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + transitivePeerDependencies: + - react-dom + + '@tanstack/react-form@1.28.0(@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@tanstack/form-core': 1.28.0 + '@tanstack/react-store': 0.8.0(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + optionalDependencies: + '@tanstack/react-start': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) transitivePeerDependencies: - react-dom @@ -7288,13 +8191,13 @@ snapshots: '@tanstack/query-core': 5.90.10 react: 19.2.0 - '@tanstack/react-router-devtools@1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.136.8)(@types/node@22.19.1)(csstype@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass@1.94.0)(solid-js@1.9.10)(tsx@4.20.6)(yaml@2.8.1)': + '@tanstack/react-router-devtools@1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.136.8)(@types/node@22.19.1)(csstype@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass-embedded@1.97.3)(sass@1.94.0)(solid-js@1.9.10)(tsx@4.20.6)(yaml@2.8.1)': dependencies: '@tanstack/react-router': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@tanstack/router-devtools-core': 1.136.8(@tanstack/router-core@1.136.8)(@types/node@22.19.1)(csstype@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(solid-js@1.9.10)(tsx@4.20.6)(yaml@2.8.1) + '@tanstack/router-devtools-core': 1.136.8(@tanstack/router-core@1.136.8)(@types/node@22.19.1)(csstype@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(solid-js@1.9.10)(tsx@4.20.6)(yaml@2.8.1) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: '@tanstack/router-core': 1.136.8 transitivePeerDependencies: @@ -7356,19 +8259,19 @@ snapshots: transitivePeerDependencies: - crossws - '@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tanstack/react-start@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@tanstack/react-router': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tanstack/react-start-client': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tanstack/react-start-server': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tanstack/router-utils': 1.133.19 '@tanstack/start-client-core': 1.136.8 - '@tanstack/start-plugin-core': 1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + '@tanstack/start-plugin-core': 1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) '@tanstack/start-server-core': 1.136.8 pathe: 2.0.3 react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@rsbuild/core' - crossws @@ -7400,14 +8303,14 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/router-devtools-core@1.136.8(@tanstack/router-core@1.136.8)(@types/node@22.19.1)(csstype@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(solid-js@1.9.10)(tsx@4.20.6)(yaml@2.8.1)': + '@tanstack/router-devtools-core@1.136.8(@tanstack/router-core@1.136.8)(@types/node@22.19.1)(csstype@3.2.3)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(solid-js@1.9.10)(tsx@4.20.6)(yaml@2.8.1)': dependencies: '@tanstack/router-core': 1.136.8 clsx: 2.1.1 goober: 2.1.18(csstype@3.2.3) solid-js: 1.9.10 tiny-invariant: 1.3.3 - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: csstype: 3.2.3 transitivePeerDependencies: @@ -7436,7 +8339,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tanstack/router-plugin@1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) @@ -7454,7 +8357,7 @@ snapshots: zod: 3.25.76 optionalDependencies: '@tanstack/react-router': 1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -7476,7 +8379,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@tanstack/server-functions-plugin@1.134.5(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tanstack/server-functions-plugin@1.134.5(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/code-frame': 7.27.1 '@babel/core': 7.28.5 @@ -7485,7 +8388,7 @@ snapshots: '@babel/template': 7.27.2 '@babel/traverse': 7.28.5 '@babel/types': 7.28.5 - '@tanstack/directive-functions-plugin': 1.134.5(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + '@tanstack/directive-functions-plugin': 1.134.5(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) babel-dead-code-elimination: 1.0.10 tiny-invariant: 1.3.3 transitivePeerDependencies: @@ -7500,7 +8403,7 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/start-plugin-core@1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tanstack/start-plugin-core@1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/code-frame': 7.26.2 '@babel/core': 7.28.5 @@ -7508,9 +8411,9 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.40 '@tanstack/router-core': 1.136.8 '@tanstack/router-generator': 1.136.8 - '@tanstack/router-plugin': 1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + '@tanstack/router-plugin': 1.136.8(@tanstack/react-router@1.136.8(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) '@tanstack/router-utils': 1.133.19 - '@tanstack/server-functions-plugin': 1.134.5(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + '@tanstack/server-functions-plugin': 1.134.5(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) '@tanstack/start-client-core': 1.136.8 '@tanstack/start-server-core': 1.136.8 babel-dead-code-elimination: 1.0.10 @@ -7520,8 +8423,8 @@ snapshots: srvx: 0.8.16 tinyglobby: 0.2.15 ufo: 1.6.1 - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) - vitefu: 1.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vitefu: 1.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) xmlbuilder2: 3.1.1 zod: 3.25.76 transitivePeerDependencies: @@ -7705,7 +8608,7 @@ snapshots: - rollup - supports-color - '@vitejs/plugin-react@5.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-react@5.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -7713,7 +8616,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.47 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -7725,13 +8628,13 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -7916,6 +8819,8 @@ snapshots: async@3.2.6: {} + atomic-sleep@1.0.0: {} + atomically@2.1.0: dependencies: stubborn-fs: 2.0.0 @@ -8111,6 +9016,11 @@ snapshots: color-convert: 3.1.3 color-string: 2.1.4 + colorette@2.0.20: {} + + colorjs.io@0.5.2: + optional: true + commander@10.0.1: {} commander@11.1.0: {} @@ -8131,6 +9041,15 @@ snapshots: normalize-path: 3.0.0 readable-stream: 4.7.0 + concurrently@9.2.1: + dependencies: + chalk: 4.1.2 + rxjs: 7.8.2 + shell-quote: 1.8.3 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + conf@15.0.2: dependencies: ajv: 8.17.1 @@ -8235,6 +9154,18 @@ snapshots: whatwg-mimetype: 4.0.0 whatwg-url: 15.1.0 + dateformat@4.6.3: {} + + debounce-fn@6.0.0: + dependencies: + mimic-function: 5.0.1 + + debounce@2.2.0: {} + + debug@4.3.7: + dependencies: + ms: 2.1.3 + debounce-fn@6.0.0: dependencies: mimic-function: 5.0.1 @@ -8255,6 +9186,8 @@ snapshots: decimal.js@10.6.0: {} + decode-formdata@0.9.0: {} + dedent@1.7.0: {} deep-eql@5.0.2: {} @@ -8329,6 +9262,8 @@ snapshots: dettle@1.0.5: {} + devalue@5.6.2: {} + diff@8.0.2: {} dom-accessibility-api@0.5.16: {} @@ -8361,6 +9296,8 @@ snapshots: dotenv@16.6.1: {} + dotenv@17.2.4: {} + eastasianwidth@0.2.0: {} ecdsa-sig-formatter@1.0.11: @@ -8418,6 +9355,11 @@ snapshots: - supports-color - utf-8-validate + enhanced-resolve@5.19.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + entities@4.5.0: {} entities@6.0.1: {} @@ -8552,6 +9494,8 @@ snapshots: transitivePeerDependencies: - supports-color + fast-copy@4.0.2: {} + fast-decode-uri-component@1.0.1: {} fast-deep-equal@3.1.3: {} @@ -8724,6 +9668,8 @@ snapshots: dependencies: function-bind: 1.1.2 + help-me@5.0.0: {} + hosted-git-info@7.0.2: dependencies: lru-cache: 10.4.3 @@ -8920,6 +9866,8 @@ snapshots: jiti@2.6.1: {} + joycon@3.1.1: {} + jpeg-js@0.4.4: {} js-image-generator@1.0.4: @@ -9071,7 +10019,6 @@ snapshots: lightningcss-linux-x64-musl: 1.30.2 lightningcss-win32-arm64-msvc: 1.30.2 lightningcss-win32-x64-msvc: 1.30.2 - optional: true listhen@1.9.0: dependencies: @@ -9334,6 +10281,8 @@ snapshots: omit.js@2.0.2: {} + on-exit-leak-free@2.1.2: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -9465,6 +10414,42 @@ snapshots: picoquery@2.5.0: {} + pino-abstract-transport@3.0.0: + dependencies: + split2: 4.2.0 + + pino-pretty@13.1.3: + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 4.0.2 + fast-safe-stringify: 2.1.1 + help-me: 5.0.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 3.0.0 + pump: 3.0.3 + secure-json-parse: 4.1.0 + sonic-boom: 4.2.1 + strip-json-comments: 5.0.3 + + pino-std-serializers@7.1.0: {} + + pino@10.3.1: + dependencies: + '@pinojs/redact': 0.4.0 + atomic-sleep: 1.0.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 3.0.0 + pino-std-serializers: 7.1.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.1 + thread-stream: 4.0.0 + pkg-types@1.3.1: dependencies: confbox: 0.1.8 @@ -9528,6 +10513,8 @@ snapshots: process-nextick-args@2.0.1: {} + process-warning@5.0.0: {} + process@0.11.10: {} prompts@2.4.2: @@ -9559,6 +10546,8 @@ snapshots: queue-microtask@1.2.3: {} + quick-format-unescaped@4.0.4: {} + quote-unquote@1.0.0: {} radix3@1.1.2: {} @@ -9646,6 +10635,8 @@ snapshots: readdirp@4.1.2: {} + real-require@0.2.0: {} + recast@0.23.11: dependencies: ast-types: 0.16.1 @@ -9729,6 +10720,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} @@ -9737,6 +10732,94 @@ snapshots: safer-buffer@2.1.2: {} + sass-embedded-all-unknown@1.97.3: + dependencies: + sass: 1.97.3 + optional: true + + sass-embedded-android-arm64@1.97.3: + optional: true + + sass-embedded-android-arm@1.97.3: + optional: true + + sass-embedded-android-riscv64@1.97.3: + optional: true + + sass-embedded-android-x64@1.97.3: + optional: true + + sass-embedded-darwin-arm64@1.97.3: + optional: true + + sass-embedded-darwin-x64@1.97.3: + optional: true + + sass-embedded-linux-arm64@1.97.3: + optional: true + + sass-embedded-linux-arm@1.97.3: + optional: true + + sass-embedded-linux-musl-arm64@1.97.3: + optional: true + + sass-embedded-linux-musl-arm@1.97.3: + optional: true + + sass-embedded-linux-musl-riscv64@1.97.3: + optional: true + + sass-embedded-linux-musl-x64@1.97.3: + optional: true + + sass-embedded-linux-riscv64@1.97.3: + optional: true + + sass-embedded-linux-x64@1.97.3: + optional: true + + sass-embedded-unknown-all@1.97.3: + dependencies: + sass: 1.97.3 + optional: true + + sass-embedded-win32-arm64@1.97.3: + optional: true + + sass-embedded-win32-x64@1.97.3: + optional: true + + sass-embedded@1.97.3: + dependencies: + '@bufbuild/protobuf': 2.11.0 + colorjs.io: 0.5.2 + immutable: 5.1.4 + rxjs: 7.8.2 + supports-color: 8.1.1 + sync-child-process: 1.0.2 + varint: 6.0.0 + optionalDependencies: + sass-embedded-all-unknown: 1.97.3 + sass-embedded-android-arm: 1.97.3 + sass-embedded-android-arm64: 1.97.3 + sass-embedded-android-riscv64: 1.97.3 + sass-embedded-android-x64: 1.97.3 + sass-embedded-darwin-arm64: 1.97.3 + sass-embedded-darwin-x64: 1.97.3 + sass-embedded-linux-arm: 1.97.3 + sass-embedded-linux-arm64: 1.97.3 + sass-embedded-linux-musl-arm: 1.97.3 + sass-embedded-linux-musl-arm64: 1.97.3 + sass-embedded-linux-musl-riscv64: 1.97.3 + sass-embedded-linux-musl-x64: 1.97.3 + sass-embedded-linux-riscv64: 1.97.3 + sass-embedded-linux-x64: 1.97.3 + sass-embedded-unknown-all: 1.97.3 + sass-embedded-win32-arm64: 1.97.3 + sass-embedded-win32-x64: 1.97.3 + optional: true + sass@1.94.0: dependencies: chokidar: 4.0.3 @@ -9745,6 +10828,15 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.1 + sass@1.97.3: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.4 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.1 + optional: true + sax@1.4.3: {} saxes@6.0.0: @@ -9753,6 +10845,8 @@ snapshots: scheduler@0.27.0: {} + secure-json-parse@4.1.0: {} + selderee@0.11.0: dependencies: parseley: 0.12.1 @@ -9856,6 +10950,10 @@ snapshots: seroval: 1.3.2 seroval-plugins: 1.3.3(seroval@1.3.2) + sonic-boom@4.2.1: + dependencies: + atomic-sleep: 1.0.0 + source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -9881,6 +10979,8 @@ snapshots: spdx-license-ids@3.0.22: {} + split2@4.2.0: {} + sprintf-js@1.0.3: {} srvx@0.8.16: {} @@ -9940,6 +11040,8 @@ snapshots: strip-final-newline@3.0.0: {} + strip-json-comments@5.0.3: {} + strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 @@ -9967,6 +11069,10 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} svgo@4.0.0: @@ -9981,12 +11087,22 @@ snapshots: symbol-tree@3.2.4: {} + sync-child-process@1.0.2: + dependencies: + sync-message-port: 1.2.0 + optional: true + + sync-message-port@1.2.0: + optional: true + system-architecture@0.1.0: {} tagged-tag@1.0.0: {} tailwindcss@4.1.18: {} + tapable@2.3.0: {} + tar-stream@3.1.7: dependencies: b4a: 1.7.3 @@ -10012,6 +11128,10 @@ snapshots: text-hex@1.0.0: {} + thread-stream@4.0.0: + dependencies: + real-require: 0.2.0 + tiny-invariant@1.3.3: {} tiny-warning@1.0.3: {} @@ -10067,6 +11187,8 @@ snapshots: dependencies: punycode: 2.3.1 + tree-kill@1.2.2: {} + triple-beam@1.4.1: {} ts-api-utils@2.1.0(typescript@5.9.3): @@ -10171,15 +11293,18 @@ snapshots: validate-npm-package-name@5.0.1: {} + varint@6.0.0: + optional: true + vary@1.1.2: {} - vite-node@3.2.4(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1): + vite-node@3.2.4(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -10194,20 +11319,18 @@ snapshots: - tsx - yaml - vite-plugin-sass@0.1.0: {} - - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)): dependencies: debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.3) optionalDependencies: - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1): + vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -10221,18 +11344,19 @@ snapshots: jiti: 2.6.1 lightningcss: 1.30.2 sass: 1.94.0 + sass-embedded: 1.97.3 tsx: 4.20.6 yaml: 2.8.1 - vitefu@1.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)): + vitefu@1.1.1(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)): optionalDependencies: - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) - vitest@3.2.4(@types/node@22.19.1)(jiti@2.6.1)(jsdom@27.2.0)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1): + vitest@3.2.4(@types/node@22.19.1)(jiti@2.6.1)(jsdom@27.2.0)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 @@ -10250,8 +11374,8 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@22.19.1)(jiti@2.6.1)(lightningcss@1.30.2)(sass-embedded@1.97.3)(sass@1.94.0)(tsx@4.20.6)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.19.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..922a57f --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,5 @@ +onlyBuiltDependencies: + - '@parcel/watcher' + - esbuild + - protobufjs + - sharp diff --git a/src/lib/api/handlers/auth.ts b/src/lib/api/handlers/auth.ts index ee13120..6394eee 100644 --- a/src/lib/api/handlers/auth.ts +++ b/src/lib/api/handlers/auth.ts @@ -3,29 +3,27 @@ import Elysia from "elysia"; import nodemailer from "nodemailer"; import z from "zod"; -import VerifyEmail from "$emails/verify"; -import { env } from "$env/server"; import { API_URL } from "$lib/constants/api"; import { BRANCH_NAMES } from "$lib/constants/org"; +import { decodeJWTPayload } from "$lib/utils"; + +import VerifyEmail from "$emails/verify"; +import env from "$env/server"; import { isErrorResponse } from "../types"; -import { APIUserSchema, UserSchema } from "../types/schemas"; +import { + APILoginResponseSchema, + AuthenticatedUserSchema, + UserSchema, +} from "../types/schemas"; import { createErrorResponse, createResponseSchema, toSuccessResponse, } from "../utils/helpers"; - -const LoginResponseSchema = z.object({ - token: z.string(), - user: UserSchema, -}); - -const APILoginResponseSchema = z.object({ - jwtToken: z.string(), - user: APIUserSchema, -}); +import { requireAuth } from "../utils/macros"; export const api = new Elysia({ prefix: "/auth" }) + .use(requireAuth) .model({ error: z.object({ success: z.literal(false), @@ -36,7 +34,7 @@ export const api = new Elysia({ prefix: "/auth" }) }) .post( "/sign-in", - async ({ body, set }) => { + async ({ body, status, cookie: { session, user: userCookie } }) => { const res = await fetch(API_URL.V1.USER.LOGIN, { method: "POST", body: JSON.stringify(body), @@ -53,17 +51,43 @@ export const api = new Elysia({ prefix: "/auth" }) }); } - const validatedRes = APILoginResponseSchema.parse(response); + const validated = APILoginResponseSchema.parse(response); + const claims = decodeJWTPayload(validated.jwtToken); + if (!claims) + return status(500, { + success: false, + error: "InternalServerError", + message: "Upstream returned invalid JWT", + timestamp: new Date().toISOString(), + }); - set.headers.authorization = `Bearer ${validatedRes.jwtToken}`; + const cookieBase = { + httpOnly: true, + sameSite: "lax", + secure: process.env.NODE_ENV === "production", + path: "/", + expires: new Date(claims.exp * 1000), + } as const; + + session.set({ value: validated.jwtToken, ...cookieBase }); + + const userData = { + id: validated.user.id, + name: validated.user.name, + email: validated.user.email, + batch: validated.user.batch, + sid: validated.user.sid, + designation: validated.user.designation, + profile: validated.user.dp ?? null, + experience: validated.user.xp, + verified: validated.user.verified, + }; + + userCookie.set({ value: userData, ...cookieBase }); return toSuccessResponse({ - token: validatedRes.jwtToken, - user: { - ...validatedRes.user, - profile: validatedRes.user.dp, - experience: validatedRes.user.xp, - }, + token: validated.jwtToken, + user: userData, }); }, { @@ -71,7 +95,7 @@ export const api = new Elysia({ prefix: "/auth" }) email: z.email("you need to enter a email to login"), password: z.string("you need to enter a password to login"), }), - response: createResponseSchema(LoginResponseSchema, { + response: createResponseSchema(AuthenticatedUserSchema, { errorCodes: [401, 404, 500], }), detail: { @@ -89,6 +113,11 @@ On successful authentication, returns a JWT token for subsequent authenticated r }, }, ) + .post("/sign-out", ({ cookie: { session, user } }) => { + session.remove(); + user.remove(); + return toSuccessResponse({ message: "Signed out successfully." }); + }) .get( "/verify-email/:token", async ({ params }) => { @@ -112,7 +141,6 @@ On successful authentication, returns a JWT token for subsequent authenticated r } } - // TODO: It's more ideal to redirect the user to confirmation page, instead of showing a bland json response. return toSuccessResponse({ message: "Your Email was sucessfully verified.", }); @@ -244,4 +272,8 @@ The user must verify their email before logging in. tags: ["Authentication"], }, }, - ); + ) + .get("/me", async ({ user }) => toSuccessResponse(user), { + requireAuth: true, + response: createResponseSchema(UserSchema, { errorCodes: [401, 500] }), + }); diff --git a/src/lib/api/handlers/events.ts b/src/lib/api/handlers/events.ts index 473dc4c..fb58cee 100644 --- a/src/lib/api/handlers/events.ts +++ b/src/lib/api/handlers/events.ts @@ -3,6 +3,7 @@ import z from "zod"; import { API_URL } from "$lib/constants/api"; import { ACM_BRANCHES } from "$lib/constants/org"; + import { isErrorResponse } from "../types"; import { BaseEventSchema, diff --git a/src/lib/api/handlers/user.ts b/src/lib/api/handlers/user.ts index 0d60c84..5521372 100644 --- a/src/lib/api/handlers/user.ts +++ b/src/lib/api/handlers/user.ts @@ -2,6 +2,7 @@ import Elysia from "elysia"; import z from "zod"; import { API_URL } from "$lib/constants/api"; + import { isErrorResponse } from "../types"; import { createErrorResponse, diff --git a/src/lib/api/types/index.ts b/src/lib/api/types/index.ts index b2cef58..6ef6951 100644 --- a/src/lib/api/types/index.ts +++ b/src/lib/api/types/index.ts @@ -1,3 +1,6 @@ +import type * as z from "zod"; +import type { UserSchema } from "./schemas"; + export interface APIErrorResponse { code: string; message: string; @@ -10,6 +13,8 @@ export interface ErrorResponse { timestamp: string; } +export type SessionUser = z.infer; + export function isErrorResponse(res: unknown): res is APIErrorResponse { return ( res !== null && diff --git a/src/lib/api/types/schemas.ts b/src/lib/api/types/schemas.ts index 7eafbf7..6c6830c 100644 --- a/src/lib/api/types/schemas.ts +++ b/src/lib/api/types/schemas.ts @@ -1,9 +1,9 @@ import z from "zod"; -import { ACM_BRANCHES, DESIGNATIONS } from "$lib/constants/org"; -export const BranchEnum = z.enum(ACM_BRANCHES); +import { ACM_BRANCHES } from "$lib/constants/org"; +import { DesignationEnum } from "$lib/types"; -export const DesignationEnum = z.enum(DESIGNATIONS); +export const BranchEnum = z.enum(ACM_BRANCHES); export const BaseUserSchema = z.object({ id: z.number(), @@ -26,6 +26,16 @@ export const APIUserSchema = BaseUserSchema.extend({ xp: z.number(), }); +export const AuthenticatedUserSchema = z.object({ + token: z.string(), + user: UserSchema, +}); + +export const APILoginResponseSchema = z.object({ + jwtToken: z.string(), + user: APIUserSchema, +}); + // everything can be made optional to support => export const BaseEventSchema = z.object({ id: z.number().optional(), diff --git a/src/lib/api/utils/helpers.ts b/src/lib/api/utils/helpers.ts index 31c3d15..85e0045 100644 --- a/src/lib/api/utils/helpers.ts +++ b/src/lib/api/utils/helpers.ts @@ -1,6 +1,7 @@ +import type { APIErrorResponse, ErrorStatusCode } from "../types"; + import { StatusMap, status } from "elysia"; import z from "zod"; -import type { APIErrorResponse, ErrorStatusCode } from "../types"; /** * Creates a standardized error response object from an API error payload. diff --git a/src/lib/api/utils/macros.ts b/src/lib/api/utils/macros.ts index 2c0f7de..f93e4b7 100644 --- a/src/lib/api/utils/macros.ts +++ b/src/lib/api/utils/macros.ts @@ -1,20 +1,65 @@ -import { Elysia } from "elysia"; - -export const requireAuth = new Elysia().macro({ - requireAuth: { - resolve({ headers, status }) { - if (!headers.authorization) { - return status(403, { - message: "you need to be signed in to perform this operation.", - error: "Unauthorized", - }); +import type { Designation } from "$lib/types"; +import type { SessionUser } from "../types"; + +import { Elysia, status } from "elysia"; + +import { hasRole } from "$lib/types"; +import { decodeJWTPayload } from "$lib/utils"; + +const unauthorized = (message: string) => + status(401, { + success: false as const, + error: "Unauthorized", + message, + timestamp: new Date().toISOString(), + }); + +const forbidden = (message: string) => + status(403, { + success: false as const, + error: "Forbidden", + message, + timestamp: new Date().toISOString(), + }); + +export const requireAuth = new Elysia({ name: "require-auth" }).macro({ + requireAuth: (enabled: true | Designation) => ({ + resolve({ headers, cookie: { session, user: userCookie } }) { + const token = + (session.value as string | undefined) ?? + headers.authorization?.split(" ")[1]; + + if (!token) return unauthorized("You need to be signed in."); + + const claims = decodeJWTPayload(token); + + if (!claims) return unauthorized("Malformed token."); + + if (Date.now() >= claims.exp * 1000) { + session.remove(); + userCookie.remove(); + return unauthorized("Your session has expired. Please sign in again."); + } + + const userData = userCookie.value as SessionUser | undefined; + + if (!userData) { + session.remove(); + return unauthorized("Session data missing. Please sign in again."); } - const token = headers.authorization.split(" ")[1]; + if (enabled !== true) { + if (!hasRole(userData.designation, enabled)) { + return forbidden( + `This action requires the '${enabled}' role or above. Your current role is '${userData.designation}'.`, + ); + } + } return { token, + user: userData, }; }, - }, + }), }); diff --git a/src/lib/constants/api.ts b/src/lib/constants/api.ts index 336286e..cfe5ffc 100644 --- a/src/lib/constants/api.ts +++ b/src/lib/constants/api.ts @@ -1,4 +1,4 @@ -import { env } from "$env/server"; +import env from "$env/server"; const BASE_URL = env.BACKEND_BASE_URL; diff --git a/src/lib/env/server.ts b/src/lib/env/server.ts index 1625f8f..b366abf 100644 --- a/src/lib/env/server.ts +++ b/src/lib/env/server.ts @@ -1,7 +1,7 @@ import { createEnv } from "@t3-oss/env-core"; import { z } from "zod"; -export const env = createEnv({ +const env = createEnv({ server: { BACKEND_BASE_URL: z.url(), SMTP_HOST: z.string(), @@ -15,3 +15,5 @@ export const env = createEnv({ runtimeEnv: process.env, emptyStringAsUndefined: true, }); + +export default env; diff --git a/src/lib/server/fns.ts b/src/lib/server/fns.ts new file mode 100644 index 0000000..2eea80e --- /dev/null +++ b/src/lib/server/fns.ts @@ -0,0 +1,52 @@ +import type { SessionUser } from "$lib/api/types"; + +import { createServerFn } from "@tanstack/react-start"; +import { deleteCookie, setCookie } from "@tanstack/react-start/server"; +import { getTreaty } from "src/routes/api.$"; + +import { readSession } from "./session"; + +export const fetchUserFn = createServerFn({ method: "GET" }).handler( + async (): Promise => { + const session = readSession(); + if (!session.authenticated) return null; + return session.user; + }, +); + +export const signinFn = createServerFn({ method: "POST" }) + .inputValidator((data: { email: string; password: string }) => data) + .handler(async ({ data }) => { + const api = getTreaty(); + + const { data: res, error } = await api.auth["sign-in"].post({ + email: data.email, + password: data.password, + }); + + if (error) return { error: error.value.message }; + + const cookieBase = { + httpOnly: true, + sameSite: "lax" as const, + path: "/", + secure: process.env.NODE_ENV === "production", + }; + + setCookie("session", res.data.token, cookieBase); + setCookie("user", JSON.stringify(res.data.user), cookieBase); + + return { success: true }; + }); + +export const signoutFn = createServerFn({ method: "POST" }).handler( + async () => { + const api = getTreaty(); + + await api.auth["sign-out"].post(); + deleteCookie("session"); + deleteCookie("user"); + + return { success: true }; + }, +); diff --git a/src/lib/server/session.ts b/src/lib/server/session.ts new file mode 100644 index 0000000..48e10ac --- /dev/null +++ b/src/lib/server/session.ts @@ -0,0 +1,27 @@ +import type { SessionUser } from "$lib/api/types"; + +import { getCookie } from "@tanstack/react-start/server"; + +import { decodeJWTPayload } from "$lib/utils"; + +type Session = + | { authenticated: true; user: SessionUser; token: string } + | { authenticated: false }; + +export function readSession(): Session { + const token = getCookie("session"); + const userRaw = getCookie("user"); + + if (!token || !userRaw) return { authenticated: false }; + + const claims = decodeJWTPayload(token); + if (!claims || Date.now() >= claims.exp * 1000) + return { authenticated: false }; + + try { + const user = JSON.parse(userRaw) as SessionUser; + return { authenticated: true, user, token }; + } catch { + return { authenticated: false }; + } +} diff --git a/src/lib/types.ts b/src/lib/types.ts new file mode 100644 index 0000000..8d2b36e --- /dev/null +++ b/src/lib/types.ts @@ -0,0 +1,19 @@ +import z from "zod"; + +import { DESIGNATIONS } from "./constants/org"; + +export type Designation = (typeof DESIGNATIONS)[number]; + +export const DesignationEnum = z.enum(DESIGNATIONS); + +const DESIGNATION_RANK: Record = { + Member: 0, + ImplementationBody: 1, + ExecutiveBody: 2, + Core: 3, + Admin: 4, +}; + +export function hasRole(actual: Designation, required: Designation): boolean { + return DESIGNATION_RANK[actual] >= DESIGNATION_RANK[required]; +} diff --git a/src/lib/utils.ts b/src/lib/utils.ts new file mode 100644 index 0000000..15af225 --- /dev/null +++ b/src/lib/utils.ts @@ -0,0 +1,14 @@ +type JWTPayload = { + sub: string; + exp: number; + iat: number; +}; + +export function decodeJWTPayload(token: string): JWTPayload | null { + try { + const [, payload] = token.split("."); + return JSON.parse(atob(payload.replace(/-/g, "+").replace(/_/g, "/"))); + } catch { + return null; + } +} diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index 7869899..bfc476c 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -9,9 +9,16 @@ // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. import { Route as rootRouteImport } from './routes/__root' +import { Route as AuthedRouteImport } from './routes/_authed' import { Route as IndexRouteImport } from './routes/index' import { Route as ApiSplatRouteImport } from './routes/api.$' +import { Route as authSignInRouteImport } from './routes/(auth)/sign-in' +import { Route as AuthedDashboardIndexRouteImport } from './routes/_authed/dashboard/index' +const AuthedRoute = AuthedRouteImport.update({ + id: '/_authed', + getParentRoute: () => rootRouteImport, +} as any) const IndexRoute = IndexRouteImport.update({ id: '/', path: '/', @@ -22,35 +29,67 @@ const ApiSplatRoute = ApiSplatRouteImport.update({ path: '/api/$', getParentRoute: () => rootRouteImport, } as any) +const authSignInRoute = authSignInRouteImport.update({ + id: '/(auth)/sign-in', + path: '/sign-in', + getParentRoute: () => rootRouteImport, +} as any) +const AuthedDashboardIndexRoute = AuthedDashboardIndexRouteImport.update({ + id: '/dashboard/', + path: '/dashboard/', + getParentRoute: () => AuthedRoute, +} as any) export interface FileRoutesByFullPath { '/': typeof IndexRoute + '/sign-in': typeof authSignInRoute '/api/$': typeof ApiSplatRoute + '/dashboard': typeof AuthedDashboardIndexRoute } export interface FileRoutesByTo { '/': typeof IndexRoute + '/sign-in': typeof authSignInRoute '/api/$': typeof ApiSplatRoute + '/dashboard': typeof AuthedDashboardIndexRoute } export interface FileRoutesById { __root__: typeof rootRouteImport '/': typeof IndexRoute + '/_authed': typeof AuthedRouteWithChildren + '/(auth)/sign-in': typeof authSignInRoute '/api/$': typeof ApiSplatRoute + '/_authed/dashboard/': typeof AuthedDashboardIndexRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: '/' | '/api/$' + fullPaths: '/' | '/sign-in' | '/api/$' | '/dashboard' fileRoutesByTo: FileRoutesByTo - to: '/' | '/api/$' - id: '__root__' | '/' | '/api/$' + to: '/' | '/sign-in' | '/api/$' | '/dashboard' + id: + | '__root__' + | '/' + | '/_authed' + | '/(auth)/sign-in' + | '/api/$' + | '/_authed/dashboard/' fileRoutesById: FileRoutesById } export interface RootRouteChildren { IndexRoute: typeof IndexRoute + AuthedRoute: typeof AuthedRouteWithChildren + authSignInRoute: typeof authSignInRoute ApiSplatRoute: typeof ApiSplatRoute } declare module '@tanstack/react-router' { interface FileRoutesByPath { + '/_authed': { + id: '/_authed' + path: '' + fullPath: '' + preLoaderRoute: typeof AuthedRouteImport + parentRoute: typeof rootRouteImport + } '/': { id: '/' path: '/' @@ -65,11 +104,38 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof ApiSplatRouteImport parentRoute: typeof rootRouteImport } + '/(auth)/sign-in': { + id: '/(auth)/sign-in' + path: '/sign-in' + fullPath: '/sign-in' + preLoaderRoute: typeof authSignInRouteImport + parentRoute: typeof rootRouteImport + } + '/_authed/dashboard/': { + id: '/_authed/dashboard/' + path: '/dashboard' + fullPath: '/dashboard' + preLoaderRoute: typeof AuthedDashboardIndexRouteImport + parentRoute: typeof AuthedRoute + } } } +interface AuthedRouteChildren { + AuthedDashboardIndexRoute: typeof AuthedDashboardIndexRoute +} + +const AuthedRouteChildren: AuthedRouteChildren = { + AuthedDashboardIndexRoute: AuthedDashboardIndexRoute, +} + +const AuthedRouteWithChildren = + AuthedRoute._addFileChildren(AuthedRouteChildren) + const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, + AuthedRoute: AuthedRouteWithChildren, + authSignInRoute: authSignInRoute, ApiSplatRoute: ApiSplatRoute, } export const routeTree = rootRouteImport diff --git a/src/router.tsx b/src/router.tsx index 186c65a..168f0c7 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -1,7 +1,7 @@ import { createRouter } from "@tanstack/react-router"; import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query"; -import * as TanstackQuery from "./integrations/tanstack-query/root-provider"; +import * as TanstackQuery from "./integrations/tanstack-query/root-provider"; // Import the generated route tree import { routeTree } from "./routeTree.gen"; diff --git a/src/routes/(auth)/sign-in.tsx b/src/routes/(auth)/sign-in.tsx new file mode 100644 index 0000000..3dcadd4 --- /dev/null +++ b/src/routes/(auth)/sign-in.tsx @@ -0,0 +1,149 @@ +import { useForm } from "@tanstack/react-form"; +import { + createFileRoute, + Link, + redirect, + useRouter, +} from "@tanstack/react-router"; +import { useState } from "react"; + +import { signinFn } from "$lib/server/fns"; + +export const Route = createFileRoute("/(auth)/sign-in")({ + head: () => ({ + meta: [{ title: "Sign In | PEC ACM" }], + }), + validateSearch: search => ({ + redirect: (search.redirect as string) || "/dashboard", + }), + beforeLoad: ({ context, search }) => { + if (context.user) { + throw redirect({ to: search.redirect }); + } + }, + component: RouteComponent, +}); + +function RouteComponent() { + const router = useRouter(); + const { redirect: redirectTo } = Route.useSearch(); + + const [serverError, setServerError] = useState(null); + + const form = useForm({ + defaultValues: { + email: "", + password: "", + }, + onSubmit: async ({ value }) => { + setServerError(null); + const result = await signinFn({ data: value }); + + if (result.error) { + setServerError(result.error); + return; + } + + await router.invalidate(); + await router.navigate({ to: redirectTo }); + }, + }); + + return ( +
+ + +
+
{ + e.preventDefault(); + form.handleSubmit(); + }} + > + + {field => ( +
+ + field.handleChange(e.target.value)} + placeholder="Email address" + autoComplete="email" + /> +
+ )} +
+ + + {field => ( +
+ + field.handleChange(e.target.value)} + placeholder="Password" + autoComplete="current-password" + /> +
+ )} +
+ + {serverError && ( +

{serverError}

+ )} + +
+ ({ + isSubmitting: state.isSubmitting, + canSubmit: state.canSubmit, + })} + > + {({ isSubmitting, canSubmit }) => ( + + )} + + + + Back + +
+
+
+
+ ); +} diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index f71474e..f8fd58f 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -1,15 +1,17 @@ -import { TanStackDevtools } from "@tanstack/react-devtools"; import type { QueryClient } from "@tanstack/react-query"; + +import { TanStackDevtools } from "@tanstack/react-devtools"; import { createRootRouteWithContext, HeadContent, Scripts, } from "@tanstack/react-router"; - import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools"; -import TanStackQueryDevtools from "../integrations/tanstack-query/devtools"; -import appCss from "../styles.css?url"; +import { fetchUserFn } from "$lib/server/fns"; + +import appCss from "$styles/app.css?url"; +import TanStackQueryDevtools from "../integrations/tanstack-query/devtools"; interface MyRouterContext { queryClient: QueryClient; @@ -40,8 +42,12 @@ export const Route = createRootRouteWithContext()({ }, ], }), - + beforeLoad: async () => { + const user = await fetchUserFn(); + return { user }; + }, shellComponent: RootDocument, + notFoundComponent: () =>
Not Found
, }); function RootDocument({ children }: { children: React.ReactNode }) { @@ -50,7 +56,7 @@ function RootDocument({ children }: { children: React.ReactNode }) { - + {children} { + if (!context.user) { + throw redirect({ + to: "/sign-in", + search: { redirect: location.href }, + }); + } + + return { user: context.user }; + }, + component: () => , +}); diff --git a/src/routes/_authed/dashboard/index.tsx b/src/routes/_authed/dashboard/index.tsx new file mode 100644 index 0000000..1a973c6 --- /dev/null +++ b/src/routes/_authed/dashboard/index.tsx @@ -0,0 +1,30 @@ +import { createFileRoute, useRouter } from "@tanstack/react-router"; + +import { signoutFn } from "$lib/server/fns"; + +export const Route = createFileRoute("/_authed/dashboard/")({ + component: RouteComponent, +}); + +function RouteComponent() { + const { user } = Route.useRouteContext(); + const router = useRouter(); + + async function handleSignOut() { + await signoutFn(); + await router.invalidate(); + await router.navigate({ to: "/" }); + } + + return ( +
+

Welcome, {user.name}

+ +
+ ); +} diff --git a/src/routes/api.$.ts b/src/routes/api.$.ts index 225cf77..fef2b18 100644 --- a/src/routes/api.$.ts +++ b/src/routes/api.$.ts @@ -1,3 +1,4 @@ +import { createPinoLogger } from "@bogeychan/elysia-logger"; import { treaty } from "@elysiajs/eden"; import { openapi } from "@elysiajs/openapi"; import { createFileRoute } from "@tanstack/react-router"; @@ -7,9 +8,39 @@ import * as z from "zod"; import { auth, events, user } from "$lib/api"; +const log = createPinoLogger({ + level: "debug", + transport: { + target: "pino-pretty", + options: { + colorize: true, + translateTime: "mm/dd/yyyy HH:MM:ss", + ignore: "pid,hostname,req,request,responseTime", + messageFormat: "{req.method} {req.url} - {responseTime}ms", + }, + }, +}); + const app = new Elysia({ prefix: "/api", }) + .use( + log.into({ + autoLogging: { + ignore() { + return false; + }, + }, + customProps(ctx) { + return { + req: { + method: ctx.request.method, + url: new URL(ctx.request.url).pathname, + }, + }; + }, + }), + ) .use( openapi({ path: "/docs", diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 3cc1b13..e8ec39c 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -1,7 +1,12 @@ -import { createFileRoute } from "@tanstack/react-router"; +import { createFileRoute, Link } from "@tanstack/react-router"; export const Route = createFileRoute("/")({ component: App }); function App() { - return

PEC ACM

; + return ( + <> +

PEC ACM

+ Sign In + + ); } diff --git a/src/styles.css b/src/styles.css deleted file mode 100644 index 3e1f253..0000000 --- a/src/styles.css +++ /dev/null @@ -1,12 +0,0 @@ -body { - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; -} diff --git a/src/styles/app.css b/src/styles/app.css new file mode 100644 index 0000000..88f9e24 --- /dev/null +++ b/src/styles/app.css @@ -0,0 +1,14 @@ +@import "tailwindcss"; + +body { + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", + "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: + source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace; +} diff --git a/tsconfig.json b/tsconfig.json index 8e98554..ce3bc7f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,7 +27,8 @@ "$env/*": ["./src/lib/env/*"], "$emails/*": ["./src/emails/*"], "$hooks/*": ["./src/hooks/*"], - "$lib/*": ["./src/lib/*"] + "$lib/*": ["./src/lib/*"], + "$styles/*": ["./src/styles/*"] } } } diff --git a/vite.config.ts b/vite.config.ts index 486c40f..9b90187 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,11 +1,14 @@ +import "dotenv/config"; + import { defineConfig } from 'vite' import { devtools } from '@tanstack/devtools-vite' import { tanstackStart } from '@tanstack/react-start/plugin/vite' +import tailwind from "@tailwindcss/vite"; import viteReact from '@vitejs/plugin-react' import viteTsConfigPaths from 'vite-tsconfig-paths' -import sass from "vite-plugin-sass"; import netlify from '@netlify/vite-plugin-tanstack-start' + const config = defineConfig({ plugins: [ devtools(), @@ -14,7 +17,7 @@ const config = defineConfig({ viteTsConfigPaths({ projects: ['./tsconfig.json'], }), - sass(), + tailwind(), tanstackStart(), viteReact({ babel: { @@ -22,6 +25,9 @@ const config = defineConfig({ }, }), ], + server: { + port: 3000, + } }) export default config