diff --git a/README.md b/README.md index 29367df..ded8f13 100644 --- a/README.md +++ b/README.md @@ -71,23 +71,23 @@ > 状态说明:`[x]` 已完成,`[ ]` 进行中/未开始(请随开发进度更新) -| 顺序 | 功能实现项(用户视角) | 你会看到的效果 | 状态 | -|---|---|---|---| -| 1 | 明确产品能力与交互流程 | 确认 TodoList 的核心使用方式与页面路径 | [x] | -| 2 | 实现基础登录(邮箱验证码) | 可以注册/登录并进入主页面 | [ ] | -| 3 | 实现任务基础能力(增删改查) | 可以创建、编辑、删除、完成任务 | [ ] | -| 4 | 实现富文本与媒体内容 | 任务详情可插入图片、视频、链接等内容 | [ ] | -| 5 | 实现本地离线存储(Dexie) | 无网时仍可打开并编辑任务 | [ ] | -| 6 | 实现云端同步与冲突处理 | 恢复网络后自动同步,冲突按规则合并 | [ ] | -| 7 | 实现提醒系统(邮件) | DDL 临近时收到邮件提醒 | [ ] | -| 8 | 实现 AI 问答(用户自带 Key) | 可直接用自己的 AI API Key 获取建议 | [ ] | -| 9 | 实现 Astrbot Provider 接入 | 可复用 Astrbot 内配置的 AI 提供商 | [ ] | -| 10 | 实现公共 AI 通道(可开关) | 管理员开启后,用户可直接使用站点公共 AI | [ ] | -| 11 | 实现 Astrbot Skill 对接 | 可通过 QQ 机器人添加/修改任务与获取建议 | [ ] | -| 12 | 实现完整账号安全(2FA + OAuth) | 支持 2FA、QQ/微信/GitHub 登录 | [ ] | -| 13 | 实现 PWA 安装与离线体验优化 | 支持“添加到桌面”,像本地 App 一样使用 | [ ] | -| 14 | 实现管理后台(配额/日志/系统配置) | 管理员可管理用户配额、站点信息、日志 | [ ] | -| 15 | 上线前安全与性能收尾 | 使用更稳定、更安全,核心链路可观测 | [ ] | +| 顺序 | 功能实现项(用户视角) | 你会看到的效果 | 状态 | +| ---- | ---------------------------------- | --------------------------------------- | ---- | +| 1 | 明确产品能力与交互流程 | 确认 TodoList 的核心使用方式与页面路径 | [x] | +| 2 | 实现基础登录(邮箱验证码) | 可以注册/登录并进入主页面 | [ ] | +| 3 | 实现任务基础能力(增删改查) | 可以创建、编辑、删除、完成任务 | [ ] | +| 4 | 实现富文本与媒体内容 | 任务详情可插入图片、视频、链接等内容 | [ ] | +| 5 | 实现本地离线存储(Dexie) | 无网时仍可打开并编辑任务 | [ ] | +| 6 | 实现云端同步与冲突处理 | 恢复网络后自动同步,冲突按规则合并 | [ ] | +| 7 | 实现提醒系统(邮件) | DDL 临近时收到邮件提醒 | [ ] | +| 8 | 实现 AI 问答(用户自带 Key) | 可直接用自己的 AI API Key 获取建议 | [ ] | +| 9 | 实现 Astrbot Provider 接入 | 可复用 Astrbot 内配置的 AI 提供商 | [ ] | +| 10 | 实现公共 AI 通道(可开关) | 管理员开启后,用户可直接使用站点公共 AI | [ ] | +| 11 | 实现 Astrbot Skill 对接 | 可通过 QQ 机器人添加/修改任务与获取建议 | [ ] | +| 12 | 实现完整账号安全(2FA + OAuth) | 支持 2FA、QQ/微信/GitHub 登录 | [ ] | +| 13 | 实现 PWA 安装与离线体验优化 | 支持“添加到桌面”,像本地 App 一样使用 | [ ] | +| 14 | 实现管理后台(配额/日志/系统配置) | 管理员可管理用户配额、站点信息、日志 | [ ] | +| 15 | 上线前安全与性能收尾 | 使用更稳定、更安全,核心链路可观测 | [ ] | --- @@ -151,6 +151,97 @@ TodoList/ --- +## 部署与使用 + +### 1. 环境要求 + +- Node.js `20.x` +- pnpm `9.15.2` +- PostgreSQL `14+`(本地或远程都可) +- 可选:MinIO / S3(附件上传功能使用) + +### 2. 安装依赖 + +```bash +pnpm install +``` + +### 3. 后端环境变量配置 + +1. 复制环境变量示例文件: + +```bash +cp apps/api/.env.example apps/api/.env +# PowerShell: +# Copy-Item apps/api/.env.example apps/api/.env +``` + +2. 至少修改以下配置: + +- `DATABASE_URL`:你的 PostgreSQL 连接串 +- `AUTH_ACCESS_SECRET`:生产环境请改为高强度随机值 +- `MAIL_SMTP_*`:邮件服务器配置(验证码/提醒邮件) +- `OAUTH_*`:第三方登录配置(未接入可先保留示例值) +- `S3_*`:对象存储配置(未启用附件可后续再配) + +### 4. 初始化数据库 + +```bash +pnpm --filter @todolist/api exec prisma db push +``` + +### 5. 本地开发启动 + +1. 启动后端(默认端口 `3000`): + +```bash +pnpm --filter @todolist/api start:dev +``` + +2. 启动前端(默认端口 `5173`): + +```bash +pnpm --filter web dev +``` + +3. 若前端需连接非默认后端地址,可设置: + +```bash +VITE_API_BASE_URL=http://localhost:3000 +``` + +### 6. 生产构建与运行 + +1. 构建: + +```bash +pnpm run build +``` + +2. 运行 API(需先构建): + +```bash +pnpm --filter @todolist/api start +``` + +3. 发布 Web: + +- `apps/web/dist` 为静态资源产物,建议使用 Nginx/静态托管服务发布。 + +### 7. CI/CD 说明(当前仓库) + +- PR 质量检查:`.github/workflows/pr-quality.yml` +- Web 部署模板:`.github/workflows/deploy-web.yml` +- Admin 部署模板:`.github/workflows/deploy-admin.yml` +- API 镜像构建:`.github/workflows/api-docker-image.yml` + +说明: + +- Web/Admin 工作流通过 Webhook 触发真实部署,需在仓库 Secrets 配置: + - `WEB_DEPLOY_WEBHOOK_URL` + - `ADMIN_DEPLOY_WEBHOOK_URL` +- API 镜像工作流仅在存在 `apps/api/Dockerfile` 时执行镜像构建与推送。 + ## License 本项目遵循 [GNUv3](./LICENSE)。 diff --git a/apps/api/.env.example b/apps/api/.env.example index 68af79c..971b829 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -1,27 +1,65 @@ +# ----------------------------------------------------------------------------- +# TodoList API 环境变量示例 +# 用法: +# 1) 复制为 apps/api/.env +# 2) 按实际环境替换值(尤其是密钥、密码、令牌) +# ----------------------------------------------------------------------------- + +# [数据库] PostgreSQL 连接串 +# 格式:postgresql://:@:/?schema=public DATABASE_URL="postgresql://postgres:postgres@localhost:5432/todolist?schema=public" + +# [鉴权] Access Token 签名密钥(生产环境必须使用高强度随机值) AUTH_ACCESS_SECRET="dev-access-secret" +# [鉴权] Access Token 有效期(秒),默认 15 分钟 AUTH_ACCESS_EXPIRES_IN_SECONDS="900" +# [鉴权] Refresh Token 有效期(秒),默认 30 天 AUTH_REFRESH_EXPIRES_IN_SECONDS="2592000" +# [鉴权] 邮箱验证码有效期(秒),默认 5 分钟 AUTH_EMAIL_CODE_TTL_SECONDS="300" +# [2FA] TOTP 签发方名称(会显示在验证器 App 中) AUTH_TOTP_ISSUER="TodoList" + +# [OAuth - GitHub] 第三方登录配置 OAUTH_GITHUB_CLIENT_ID="github-client-id" OAUTH_GITHUB_CLIENT_SECRET="github-client-secret" OAUTH_GITHUB_CALLBACK_URL="http://localhost:3000/auth/oauth/github/callback" + +# [OAuth - QQ] 第三方登录配置 OAUTH_QQ_CLIENT_ID="qq-client-id" OAUTH_QQ_CLIENT_SECRET="qq-client-secret" OAUTH_QQ_CALLBACK_URL="http://localhost:3000/auth/oauth/qq/callback" OAUTH_QQ_AUTH_URL="https://graph.qq.com/oauth2.0/authorize" OAUTH_QQ_TOKEN_URL="https://graph.qq.com/oauth2.0/token" + +# [OAuth - 微信] 第三方登录配置 OAUTH_WECHAT_CLIENT_ID="wechat-client-id" OAUTH_WECHAT_CLIENT_SECRET="wechat-client-secret" OAUTH_WECHAT_CALLBACK_URL="http://localhost:3000/auth/oauth/wechat/callback" OAUTH_WECHAT_AUTH_URL="https://open.weixin.qq.com/connect/qrconnect" OAUTH_WECHAT_TOKEN_URL="https://api.weixin.qq.com/sns/oauth2/access_token" + +# [对象存储] S3/MinIO 配置(附件上传) +# 本地开发可使用 MinIO,生产可切换到云厂商 S3 兼容服务 S3_ENDPOINT="http://127.0.0.1:9000" S3_REGION="us-east-1" S3_BUCKET="todolist" S3_ACCESS_KEY_ID="minioadmin" S3_SECRET_ACCESS_KEY="minioadmin" +# MinIO 常用 true;AWS S3 常用 false S3_FORCE_PATH_STYLE="true" +# 预签名上传 URL 的有效期(秒) S3_PRESIGN_EXPIRES_SECONDS="900" +# 对外访问附件的基础地址(用于拼接公开 URL) S3_PUBLIC_BASE_URL="http://127.0.0.1:9000" + +# [邮件] SMTP 配置(验证码/DDL 提醒邮件) +MAIL_SMTP_HOST="smtp.example.com" +MAIL_SMTP_PORT="465" +# 465 通常为 true(SSL),587 通常为 false(STARTTLS) +MAIL_SMTP_SECURE="true" +MAIL_SMTP_USER="no-reply@example.com" +MAIL_SMTP_PASS="replace-with-smtp-password" +# 发件人显示名称与地址 +MAIL_FROM_NAME="TodoList" +MAIL_FROM_ADDRESS="no-reply@example.com" diff --git a/apps/api/package.json b/apps/api/package.json index 66837c0..f2d2dff 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -20,6 +20,7 @@ "@nestjs/testing": "^11.1.18", "@types/jest": "^30.0.0", "@types/node": "^25.5.2", + "@types/nodemailer": "^8.0.0", "@types/passport-github2": "^1.2.9", "@types/passport-oauth2": "^1.8.0", "@types/supertest": "^7.2.0", @@ -47,6 +48,7 @@ "@prisma/client": "^7.6.0", "class-transformer": "^0.5.1", "class-validator": "^0.15.1", + "nodemailer": "^8.0.4", "otplib": "^13.4.0", "passport": "^0.7.0", "passport-github2": "^0.1.12", diff --git a/apps/api/src/auth/auth-mail.service.ts b/apps/api/src/auth/auth-mail.service.ts new file mode 100644 index 0000000..b0944bb --- /dev/null +++ b/apps/api/src/auth/auth-mail.service.ts @@ -0,0 +1,131 @@ +import { + Injectable, + InternalServerErrorException, + Logger, + ServiceUnavailableException +} from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import { createTransport, type Transporter } from "nodemailer"; + +type MailRuntimeConfig = { + host: string; + port: number; + secure: boolean; + user: string; + pass: string; + fromName: string; + fromAddress: string; +}; + +@Injectable() +export class AuthMailService { + private readonly logger = new Logger(AuthMailService.name); + private cachedConfig: MailRuntimeConfig | null = null; + private transporter: Transporter | null = null; + + constructor(private readonly configService: ConfigService) {} + + async sendLoginCode(email: string, code: string, ttlSeconds: number): Promise { + const config = this.getRuntimeConfig(); + const transporter = this.getTransporter(config); + + try { + await transporter.sendMail({ + from: this.resolveFromField(config), + to: email, + subject: "TodoList 登录验证码", + text: `你的验证码是 ${code},${ttlSeconds} 秒内有效。`, + html: `

你的验证码是 ${code},${ttlSeconds} 秒内有效。

` + }); + } catch (error) { + this.logger.error( + `验证码邮件发送失败: ${email}`, + error instanceof Error ? error.stack : undefined + ); + throw new ServiceUnavailableException("验证码邮件发送失败,请稍后重试"); + } + } + + private getTransporter(config: MailRuntimeConfig): Transporter { + if (this.transporter) { + return this.transporter; + } + + this.transporter = createTransport({ + host: config.host, + port: config.port, + secure: config.secure, + auth: { + user: config.user, + pass: config.pass + } + }); + + return this.transporter; + } + + private getRuntimeConfig(): MailRuntimeConfig { + if (this.cachedConfig) { + return this.cachedConfig; + } + + const host = this.getRequiredString("MAIL_SMTP_HOST"); + const port = this.getRequiredNumber("MAIL_SMTP_PORT"); + const secure = this.getBoolean("MAIL_SMTP_SECURE", port === 465); + const user = this.getRequiredString("MAIL_SMTP_USER"); + const pass = this.getRequiredString("MAIL_SMTP_PASS"); + const fromName = this.configService.get("MAIL_FROM_NAME")?.trim() || "TodoList"; + const fromAddress = this.configService.get("MAIL_FROM_ADDRESS")?.trim() || user; + + const config: MailRuntimeConfig = { + host, + port, + secure, + user, + pass, + fromName, + fromAddress + }; + + this.cachedConfig = config; + return config; + } + + private getRequiredString(key: string): string { + const value = this.configService.get(key)?.trim(); + if (!value) { + throw new InternalServerErrorException(`邮件配置缺失: ${key}`); + } + + return value; + } + + private getRequiredNumber(key: string): number { + const rawValue = this.configService.get(key)?.trim(); + if (!rawValue) { + throw new InternalServerErrorException(`邮件配置缺失: ${key}`); + } + + const parsedValue = Number(rawValue); + if (!Number.isFinite(parsedValue)) { + throw new InternalServerErrorException(`邮件配置格式错误: ${key}`); + } + + return parsedValue; + } + + private getBoolean(key: string, fallback: boolean): boolean { + const rawValue = this.configService.get(key); + if (!rawValue) { + return fallback; + } + + const normalizedValue = rawValue.trim().toLowerCase(); + return normalizedValue === "true" || normalizedValue === "1"; + } + + private resolveFromField(config: MailRuntimeConfig): string { + const sanitizedName = config.fromName.replace(/"/g, ""); + return `"${sanitizedName}" <${config.fromAddress}>`; + } +} diff --git a/apps/api/src/auth/auth.controller.ts b/apps/api/src/auth/auth.controller.ts index 1641223..707399a 100644 --- a/apps/api/src/auth/auth.controller.ts +++ b/apps/api/src/auth/auth.controller.ts @@ -14,7 +14,7 @@ export class AuthController { @Post("email/send-code") async sendEmailCode( @Body() body: SendEmailCodeDto - ): Promise<{ success: boolean; expiresInSeconds: number; debugCode: string }> { + ): Promise<{ success: boolean; expiresInSeconds: number }> { return this.authService.sendEmailCode(body.email); } diff --git a/apps/api/src/auth/auth.module.ts b/apps/api/src/auth/auth.module.ts index e108ac3..ede59b7 100644 --- a/apps/api/src/auth/auth.module.ts +++ b/apps/api/src/auth/auth.module.ts @@ -3,6 +3,7 @@ import { ConfigModule, ConfigService } from "@nestjs/config"; import { JwtModule } from "@nestjs/jwt"; import { PassportModule } from "@nestjs/passport"; import { AuthController } from "./auth.controller"; +import { AuthMailService } from "./auth-mail.service"; import { AuthService } from "./auth.service"; import { GithubStrategy } from "./strategies/github.strategy"; import { QqStrategy } from "./strategies/qq.strategy"; @@ -27,6 +28,6 @@ import { WechatStrategy } from "./strategies/wechat.strategy"; }) ], controllers: [AuthController], - providers: [AuthService, GithubStrategy, QqStrategy, WechatStrategy] + providers: [AuthService, AuthMailService, GithubStrategy, QqStrategy, WechatStrategy] }) export class AuthModule {} diff --git a/apps/api/src/auth/auth.service.ts b/apps/api/src/auth/auth.service.ts index 4e25fa1..52bac56 100644 --- a/apps/api/src/auth/auth.service.ts +++ b/apps/api/src/auth/auth.service.ts @@ -3,6 +3,8 @@ import { ConfigService } from "@nestjs/config"; import { JwtService } from "@nestjs/jwt"; import { randomUUID } from "node:crypto"; import { authenticator } from "@otplib/preset-default"; +import { AuthMailService } from "./auth-mail.service"; +import { PrismaService } from "../prisma/prisma.service"; type EmailCodeEntry = { code: string; @@ -14,17 +16,6 @@ type AuthUser = { email: string; }; -type RefreshTokenEntry = { - userId: string; - expiresAt: number; - revokedAt?: number; -}; - -type TwoFactorEntry = { - secret: string; - enabled: boolean; -}; - type AuthTokenResult = { accessToken: string; tokenType: "Bearer"; @@ -37,29 +28,26 @@ type AuthTokenResult = { @Injectable() export class AuthService { private readonly emailCodeStore = new Map(); - private readonly userStoreByEmail = new Map(); - private readonly userStoreById = new Map(); - private readonly refreshTokenStore = new Map(); - private readonly twoFactorStore = new Map(); constructor( private readonly configService: ConfigService, - private readonly jwtService: JwtService + private readonly jwtService: JwtService, + private readonly authMailService: AuthMailService, + private readonly prismaService: PrismaService ) {} - async sendEmailCode( - email: string - ): Promise<{ success: boolean; expiresInSeconds: number; debugCode: string }> { + async sendEmailCode(email: string): Promise<{ success: boolean; expiresInSeconds: number }> { const ttlSeconds = Number(this.configService.get("AUTH_EMAIL_CODE_TTL_SECONDS") ?? 300); const code = this.generateCode(); const expiresAt = Date.now() + ttlSeconds * 1000; + const normalizedEmail = email.toLowerCase(); - this.emailCodeStore.set(email.toLowerCase(), { code, expiresAt }); + await this.authMailService.sendLoginCode(normalizedEmail, code, ttlSeconds); + this.emailCodeStore.set(normalizedEmail, { code, expiresAt }); return { success: true, - expiresInSeconds: ttlSeconds, - debugCode: code + expiresInSeconds: ttlSeconds }; } @@ -82,53 +70,92 @@ export class AuthService { this.emailCodeStore.delete(lowerEmail); - const user = this.getOrCreateUser(lowerEmail); + const user = await this.getOrCreateUser(lowerEmail); return this.issueTokens(user); } async refreshTokens(refreshToken: string): Promise { - const entry = this.refreshTokenStore.get(refreshToken); + const entry = await this.prismaService.refreshToken.findUnique({ + where: { + tokenHash: refreshToken + }, + include: { + user: { + select: { + id: true, + email: true + } + } + } + }); + if (!entry) { throw new UnauthorizedException("刷新令牌不存在"); } + if (entry.revokedAt) { throw new UnauthorizedException("刷新令牌已注销"); } - if (entry.expiresAt < Date.now()) { - this.refreshTokenStore.delete(refreshToken); + + if (entry.expiresAt.getTime() < Date.now()) { + await this.prismaService.refreshToken.update({ + where: { + id: entry.id + }, + data: { + revokedAt: new Date() + } + }); throw new UnauthorizedException("刷新令牌已过期"); } - const user = this.userStoreById.get(entry.userId); - if (!user) { - throw new UnauthorizedException("用户不存在"); - } + await this.prismaService.refreshToken.update({ + where: { + id: entry.id + }, + data: { + revokedAt: new Date() + } + }); - entry.revokedAt = Date.now(); - return this.issueTokens(user); + return this.issueTokens(entry.user); } async revokeRefreshToken(refreshToken: string): Promise<{ success: boolean }> { - const entry = this.refreshTokenStore.get(refreshToken); - if (!entry) { - return { success: true }; - } + await this.prismaService.refreshToken.updateMany({ + where: { + tokenHash: refreshToken, + revokedAt: null + }, + data: { + revokedAt: new Date() + } + }); - entry.revokedAt = Date.now(); return { success: true }; } async enrollTwoFactor( email: string ): Promise<{ userId: string; secret: string; otpauthUrl: string; enabled: boolean }> { - const user = this.getOrCreateUser(email.toLowerCase()); + const user = await this.getOrCreateUser(email.toLowerCase()); const secret = authenticator.generateSecret(); const issuer = this.configService.get("AUTH_TOTP_ISSUER") ?? "TodoList"; const otpauthUrl = authenticator.keyuri(user.email, issuer, secret); - this.twoFactorStore.set(user.id, { - secret, - enabled: false + await this.prismaService.userSecurity.upsert({ + where: { + userId: user.id + }, + update: { + twoFactorSecret: secret, + twoFactorEnabled: false + }, + create: { + userId: user.id, + twoFactorSecret: secret, + twoFactorEnabled: false + } }); return { @@ -143,38 +170,54 @@ export class AuthService { email: string, token: string ): Promise<{ success: boolean; enabled: boolean }> { - const user = this.getOrCreateUser(email.toLowerCase()); - const entry = this.twoFactorStore.get(user.id); - if (!entry) { + const user = await this.getOrCreateUser(email.toLowerCase()); + const security = await this.prismaService.userSecurity.findUnique({ + where: { + userId: user.id + }, + select: { + twoFactorSecret: true + } + }); + + if (!security?.twoFactorSecret) { throw new UnauthorizedException("尚未启用两步验证"); } - const valid = authenticator.check(token, entry.secret); + const valid = authenticator.check(token, security.twoFactorSecret); if (!valid) { throw new UnauthorizedException("两步验证码错误"); } - entry.enabled = true; + await this.prismaService.userSecurity.update({ + where: { + userId: user.id + }, + data: { + twoFactorEnabled: true + } + }); + return { success: true, enabled: true }; } - private getOrCreateUser(email: string): AuthUser { - const existingUser = this.userStoreByEmail.get(email); - if (existingUser) { - return existingUser; - } - - const newUser = { - id: randomUUID(), - email - }; - this.userStoreByEmail.set(email, newUser); - this.userStoreById.set(newUser.id, newUser); - - return newUser; + private async getOrCreateUser(email: string): Promise { + return this.prismaService.user.upsert({ + where: { + email + }, + update: {}, + create: { + email + }, + select: { + id: true, + email: true + } + }); } private generateCode(): string { @@ -194,9 +237,12 @@ export class AuthService { }); const refreshToken = `${randomUUID()}${randomUUID()}`; - this.refreshTokenStore.set(refreshToken, { - userId: user.id, - expiresAt: Date.now() + refreshExpiresInSeconds * 1000 + await this.prismaService.refreshToken.create({ + data: { + userId: user.id, + tokenHash: refreshToken, + expiresAt: new Date(Date.now() + refreshExpiresInSeconds * 1000) + } }); return { diff --git a/apps/api/src/main.ts b/apps/api/src/main.ts index c7aef94..3f891f4 100644 --- a/apps/api/src/main.ts +++ b/apps/api/src/main.ts @@ -5,6 +5,10 @@ import { AppModule } from "./app.module"; async function bootstrap(): Promise { const app = await NestFactory.create(AppModule); + app.enableCors({ + origin: true, + credentials: true + }); app.useGlobalPipes( new ValidationPipe({ transform: true, diff --git a/apps/web/.gitignore b/apps/web/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/apps/web/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/apps/web/.gitkeep b/apps/web/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/apps/web/README.md b/apps/web/README.md new file mode 100644 index 0000000..15e3b1d --- /dev/null +++ b/apps/web/README.md @@ -0,0 +1,57 @@ +# TodoList Web 前端 + +这是 TodoList 的用户端前端应用(SPA + PWA),基于 `React + TypeScript + Vite`。 + +## 技术栈 + +- React +- TypeScript +- Vite +- Tailwind CSS +- shadcn/ui + +## 本地开发 + +在仓库根目录执行: + +```bash +pnpm install +pnpm --filter web dev +``` + +默认开发地址: + +- `http://localhost:5173` + +## 后端接口地址 + +前端默认请求: + +- `http://localhost:3000` + +如需自定义,请在运行前设置环境变量: + +```bash +VITE_API_BASE_URL=http://localhost:3000 +``` + +## 构建与预览 + +```bash +pnpm --filter web build +pnpm --filter web preview +``` + +## 当前功能进度(阶段性) + +- 邮箱验证码登录页面 +- OAuth 回调页面 +- 会话本地缓存与启动恢复 +- 基础工作台页面骨架 + +## 目录说明 + +- `src/pages`:页面组件 +- `src/components`:通用 UI 组件 +- `src/services`:接口请求与会话处理 +- `src/lib`:工具函数 diff --git a/apps/web/components.json b/apps/web/components.json new file mode 100644 index 0000000..f5ebd86 --- /dev/null +++ b/apps/web/components.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "base-nova", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "iconLibrary": "lucide", + "rtl": false, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "menuColor": "default", + "menuAccent": "subtle", + "registries": {} +} diff --git a/apps/web/eslint.config.js b/apps/web/eslint.config.js new file mode 100644 index 0000000..99368a6 --- /dev/null +++ b/apps/web/eslint.config.js @@ -0,0 +1,23 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; +import { defineConfig, globalIgnores } from "eslint/config"; + +export default defineConfig([ + globalIgnores(["dist"]), + { + files: ["**/*.{ts,tsx}"], + extends: [ + js.configs.recommended, + tseslint.configs.recommended, + reactHooks.configs.flat.recommended, + reactRefresh.configs.vite + ], + languageOptions: { + ecmaVersion: 2020, + globals: globals.browser + } + } +]); diff --git a/apps/web/index.html b/apps/web/index.html new file mode 100644 index 0000000..5e3836a --- /dev/null +++ b/apps/web/index.html @@ -0,0 +1,13 @@ + + + + + + + web + + +
+ + + diff --git a/apps/web/package.json b/apps/web/package.json new file mode 100644 index 0000000..c83804f --- /dev/null +++ b/apps/web/package.json @@ -0,0 +1,42 @@ +{ + "name": "web", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "tsc -b && vite build", + "lint": "eslint .", + "preview": "vite preview" + }, + "dependencies": { + "@base-ui/react": "^1.3.0", + "@fontsource-variable/geist": "^5.2.8", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "lucide-react": "^1.7.0", + "react": "^19.2.4", + "react-dom": "^19.2.4", + "react-router-dom": "^7.14.0", + "shadcn": "^4.1.2", + "tailwind-merge": "^3.5.0", + "tw-animate-css": "^1.4.0" + }, + "devDependencies": { + "@eslint/js": "^9.39.4", + "@types/node": "^24.12.0", + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "@vitejs/plugin-react": "^6.0.1", + "autoprefixer": "^10.4.27", + "eslint": "^9.39.4", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.4.0", + "postcss": "^8.5.8", + "tailwindcss": "^3.4.17", + "typescript": "~5.9.3", + "typescript-eslint": "^8.57.0", + "vite": "^8.0.1" + } +} diff --git a/apps/web/postcss.config.js b/apps/web/postcss.config.js new file mode 100644 index 0000000..ba80730 --- /dev/null +++ b/apps/web/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +}; diff --git a/apps/web/public/favicon.svg b/apps/web/public/favicon.svg new file mode 100644 index 0000000..6893eb1 --- /dev/null +++ b/apps/web/public/favicon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/web/public/icons.svg b/apps/web/public/icons.svg new file mode 100644 index 0000000..e952219 --- /dev/null +++ b/apps/web/public/icons.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/web/src/App.css b/apps/web/src/App.css new file mode 100644 index 0000000..f90339d --- /dev/null +++ b/apps/web/src/App.css @@ -0,0 +1,184 @@ +.counter { + font-size: 16px; + padding: 5px 10px; + border-radius: 5px; + color: var(--accent); + background: var(--accent-bg); + border: 2px solid transparent; + transition: border-color 0.3s; + margin-bottom: 24px; + + &:hover { + border-color: var(--accent-border); + } + &:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; + } +} + +.hero { + position: relative; + + .base, + .framework, + .vite { + inset-inline: 0; + margin: 0 auto; + } + + .base { + width: 170px; + position: relative; + z-index: 0; + } + + .framework, + .vite { + position: absolute; + } + + .framework { + z-index: 1; + top: 34px; + height: 28px; + transform: perspective(2000px) rotateZ(300deg) rotateX(44deg) rotateY(39deg) + scale(1.4); + } + + .vite { + z-index: 0; + top: 107px; + height: 26px; + width: auto; + transform: perspective(2000px) rotateZ(300deg) rotateX(40deg) rotateY(39deg) + scale(0.8); + } +} + +#center { + display: flex; + flex-direction: column; + gap: 25px; + place-content: center; + place-items: center; + flex-grow: 1; + + @media (max-width: 1024px) { + padding: 32px 20px 24px; + gap: 18px; + } +} + +#next-steps { + display: flex; + border-top: 1px solid var(--border); + text-align: left; + + & > div { + flex: 1 1 0; + padding: 32px; + @media (max-width: 1024px) { + padding: 24px 20px; + } + } + + .icon { + margin-bottom: 16px; + width: 22px; + height: 22px; + } + + @media (max-width: 1024px) { + flex-direction: column; + text-align: center; + } +} + +#docs { + border-right: 1px solid var(--border); + + @media (max-width: 1024px) { + border-right: none; + border-bottom: 1px solid var(--border); + } +} + +#next-steps ul { + list-style: none; + padding: 0; + display: flex; + gap: 8px; + margin: 32px 0 0; + + .logo { + height: 18px; + } + + a { + color: var(--text-h); + font-size: 16px; + border-radius: 6px; + background: var(--social-bg); + display: flex; + padding: 6px 12px; + align-items: center; + gap: 8px; + text-decoration: none; + transition: box-shadow 0.3s; + + &:hover { + box-shadow: var(--shadow); + } + .button-icon { + height: 18px; + width: 18px; + } + } + + @media (max-width: 1024px) { + margin-top: 20px; + flex-wrap: wrap; + justify-content: center; + + li { + flex: 1 1 calc(50% - 8px); + } + + a { + width: 100%; + justify-content: center; + box-sizing: border-box; + } + } +} + +#spacer { + height: 88px; + border-top: 1px solid var(--border); + @media (max-width: 1024px) { + height: 48px; + } +} + +.ticks { + position: relative; + width: 100%; + + &::before, + &::after { + content: ''; + position: absolute; + top: -4.5px; + border: 5px solid transparent; + } + + &::before { + left: 0; + border-left-color: var(--border); + } + &::after { + right: 0; + border-right-color: var(--border); + } +} diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx new file mode 100644 index 0000000..233d2f5 --- /dev/null +++ b/apps/web/src/App.tsx @@ -0,0 +1,113 @@ +import { useState } from "react"; +import { Navigate, Route, Routes, useNavigate } from "react-router-dom"; +import { Button } from "@/components/ui/button"; +import { EmailLoginPage } from "@/pages/email-login-page"; +import { OAuthCallbackPage } from "@/pages/oauth-callback-page"; +import { TodoShellPage } from "@/pages/todo-shell-page"; +import { revokeRefreshToken, type EmailLoginResult } from "@/services/auth-api"; +import { + clearSession, + loadSession, + saveSession, + type WebSession +} from "@/services/session-storage"; + +function toWebSession(payload: EmailLoginResult): WebSession { + return { + accessToken: payload.accessToken, + refreshToken: payload.refreshToken, + user: { + id: payload.user.id, + email: payload.user.email + } + }; +} + +function App() { + const [session, setSession] = useState(() => loadSession()); + const [loggingOut, setLoggingOut] = useState(false); + const navigate = useNavigate(); + + async function handleLogout(): Promise { + if (!session || loggingOut) { + return; + } + + try { + setLoggingOut(true); + await revokeRefreshToken(session.refreshToken); + } catch { + // 登出流程以本地会话清理为最终兜底,避免页面卡在登录态。 + } finally { + clearSession(); + setSession(null); + setLoggingOut(false); + navigate("/login/email", { replace: true }); + } + } + + return ( +
+
+
+
+
+ TodoList +
+ {session ? ( +
+ {session.user.email} + +
+ ) : ( + 未登录 + )} +
+
+
+ + { + const nextSession = toWebSession(payload); + saveSession(nextSession); + setSession(nextSession); + navigate("/"); + }} + /> + } + /> + { + setSession(nextSession); + }} + /> + } + /> + : + } + /> + } /> + +
+
+ ); +} + +export default App; diff --git a/apps/web/src/assets/hero.png b/apps/web/src/assets/hero.png new file mode 100644 index 0000000..cc51a3d Binary files /dev/null and b/apps/web/src/assets/hero.png differ diff --git a/apps/web/src/assets/react.svg b/apps/web/src/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/apps/web/src/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/web/src/assets/vite.svg b/apps/web/src/assets/vite.svg new file mode 100644 index 0000000..5101b67 --- /dev/null +++ b/apps/web/src/assets/vite.svg @@ -0,0 +1 @@ +Vite diff --git a/apps/web/src/components/ui/button.tsx b/apps/web/src/components/ui/button.tsx new file mode 100644 index 0000000..509aa05 --- /dev/null +++ b/apps/web/src/components/ui/button.tsx @@ -0,0 +1,59 @@ +/* eslint-disable react-refresh/only-export-components */ +import { Button as ButtonPrimitive } from "@base-ui/react/button"; +import { cva, type VariantProps } from "class-variance-authority"; + +import { cn } from "@/lib/utils"; + +const buttonVariants = cva( + "group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80", + outline: + "border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground", + ghost: + "hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50", + destructive: + "bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40", + link: "text-primary underline-offset-4 hover:underline" + }, + size: { + default: + "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", + xs: "h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", + sm: "h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", + lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", + icon: "size-8", + "icon-xs": + "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3", + "icon-sm": + "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg", + "icon-lg": "size-9" + } + }, + defaultVariants: { + variant: "default", + size: "default" + } + } +); + +function Button({ + className, + variant = "default", + size = "default", + ...props +}: ButtonPrimitive.Props & VariantProps) { + return ( + + ); +} + +export { Button, buttonVariants }; diff --git a/apps/web/src/index.css b/apps/web/src/index.css new file mode 100644 index 0000000..3239bed --- /dev/null +++ b/apps/web/src/index.css @@ -0,0 +1,21 @@ +@import "@fontsource-variable/geist"; +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + --radius: 0.625rem; + --background: #f6f8f7; + --foreground: #122117; + --primary: #0a7a5a; + --primary-foreground: #ffffff; + --border: #d7e2db; + font-family: "Geist Variable", "Noto Sans SC", sans-serif; +} + +body { + margin: 0; + min-height: 100vh; + background: var(--background); + color: var(--foreground); +} diff --git a/apps/web/src/lib/utils.ts b/apps/web/src/lib/utils.ts new file mode 100644 index 0000000..a5ef193 --- /dev/null +++ b/apps/web/src/lib/utils.ts @@ -0,0 +1,6 @@ +import { clsx, type ClassValue } from "clsx"; +import { twMerge } from "tailwind-merge"; + +export function cn(...inputs: ClassValue[]) { + return twMerge(clsx(inputs)); +} diff --git a/apps/web/src/main.tsx b/apps/web/src/main.tsx new file mode 100644 index 0000000..85a16d5 --- /dev/null +++ b/apps/web/src/main.tsx @@ -0,0 +1,13 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import { BrowserRouter } from "react-router-dom"; +import "./index.css"; +import App from "./App.tsx"; + +createRoot(document.getElementById("root")!).render( + + + + + +); diff --git a/apps/web/src/pages/email-login-page.tsx b/apps/web/src/pages/email-login-page.tsx new file mode 100644 index 0000000..fe17509 --- /dev/null +++ b/apps/web/src/pages/email-login-page.tsx @@ -0,0 +1,155 @@ +import { useMemo, useState } from "react"; +import type { FormEvent } from "react"; +import { Button } from "@/components/ui/button"; +import { loginWithEmailCode, sendEmailCode, type EmailLoginResult } from "@/services/auth-api"; + +type EmailLoginPageProps = { + onLoginSuccess: (payload: EmailLoginResult) => void; +}; + +const DEFAULT_API_BASE_URL = "http://localhost:3000"; + +function resolveApiBaseUrl(): string { + const envBaseUrl = import.meta.env.VITE_API_BASE_URL as string | undefined; + if (!envBaseUrl) { + return DEFAULT_API_BASE_URL; + } + + return envBaseUrl.replace(/\/+$/, ""); +} + +export function EmailLoginPage({ onLoginSuccess }: EmailLoginPageProps) { + const [email, setEmail] = useState(""); + const [code, setCode] = useState(""); + const [sendingCode, setSendingCode] = useState(false); + const [loggingIn, setLoggingIn] = useState(false); + const [codeCooldown, setCodeCooldown] = useState(0); + const [message, setMessage] = useState(null); + const [error, setError] = useState(null); + + const canSendCode = useMemo(() => { + return email.trim().length > 0 && !sendingCode && codeCooldown <= 0; + }, [codeCooldown, email, sendingCode]); + + const canLogin = useMemo(() => { + return email.trim().length > 0 && code.trim().length === 6 && !loggingIn; + }, [code, email, loggingIn]); + + async function handleSendCode(event: FormEvent): Promise { + event.preventDefault(); + if (!canSendCode) { + return; + } + + try { + setSendingCode(true); + setError(null); + setMessage(null); + const result = await sendEmailCode(email.trim()); + setMessage(`验证码已发送,有效期 ${result.expiresInSeconds} 秒。`); + + let remain = 60; + setCodeCooldown(remain); + const timer = window.setInterval(() => { + remain -= 1; + setCodeCooldown(remain); + if (remain <= 0) { + window.clearInterval(timer); + } + }, 1000); + } catch (err) { + setError(err instanceof Error ? err.message : "发送验证码失败"); + } finally { + setSendingCode(false); + } + } + + async function handleLogin(event: FormEvent): Promise { + event.preventDefault(); + if (!canLogin) { + return; + } + + try { + setLoggingIn(true); + setError(null); + setMessage(null); + const result = await loginWithEmailCode(email.trim(), code.trim()); + onLoginSuccess(result); + } catch (err) { + setError(err instanceof Error ? err.message : "登录失败"); + } finally { + setLoggingIn(false); + } + } + + return ( +
+

邮箱验证码登录

+

+ 输入邮箱后获取验证码,再完成登录。你也可以直接使用第三方账号登录。 +

+ +
+ + setEmail(event.target.value)} + /> + +
+ +
+ + setCode(event.target.value)} + /> + +
+ + + + {message ?

{message}

: null} + {error ?

{error}

: null} +
+ ); +} diff --git a/apps/web/src/pages/oauth-callback-page.tsx b/apps/web/src/pages/oauth-callback-page.tsx new file mode 100644 index 0000000..f4ae5f3 --- /dev/null +++ b/apps/web/src/pages/oauth-callback-page.tsx @@ -0,0 +1,65 @@ +import { useMemo } from "react"; +import { useNavigate, useSearchParams } from "react-router-dom"; +import { Button } from "@/components/ui/button"; +import { saveSession, type WebSession } from "@/services/session-storage"; + +type OAuthCallbackPageProps = { + onBootstrapSession: (session: WebSession) => void; +}; + +export function OAuthCallbackPage({ onBootstrapSession }: OAuthCallbackPageProps) { + const [searchParams] = useSearchParams(); + const navigate = useNavigate(); + + const parseResult = useMemo(() => { + const accessToken = searchParams.get("accessToken"); + const refreshToken = searchParams.get("refreshToken"); + const userId = searchParams.get("userId"); + const email = searchParams.get("email"); + + if (!accessToken || !refreshToken || !userId || !email) { + return { + ok: false as const, + reason: "回调参数不完整,暂时无法建立会话。" + }; + } + + return { + ok: true as const, + session: { + accessToken, + refreshToken, + user: { + id: userId, + email + } + } + }; + }, [searchParams]); + + function handleContinue(): void { + if (!parseResult.ok) { + navigate("/login/email", { replace: true }); + return; + } + + saveSession(parseResult.session); + onBootstrapSession(parseResult.session); + navigate("/", { replace: true }); + } + + return ( +
+

OAuth 回调处理中

+

+ {parseResult.ok ? "已收到回调参数,点击继续进入工作台。" : parseResult.reason} +

+ +
+ ); +} diff --git a/apps/web/src/pages/todo-shell-page.tsx b/apps/web/src/pages/todo-shell-page.tsx new file mode 100644 index 0000000..737789c --- /dev/null +++ b/apps/web/src/pages/todo-shell-page.tsx @@ -0,0 +1,16 @@ +import type { WebSession } from "@/services/session-storage"; + +type TodoShellPageProps = { + session: WebSession | null; +}; + +export function TodoShellPage({ session }: TodoShellPageProps) { + return ( +
+

TodoList 工作台

+

+ {session ? `当前登录邮箱:${session.user.email}` : "当前未建立登录会话,请先完成登录。"} +

+
+ ); +} diff --git a/apps/web/src/services/auth-api.ts b/apps/web/src/services/auth-api.ts new file mode 100644 index 0000000..5f2919e --- /dev/null +++ b/apps/web/src/services/auth-api.ts @@ -0,0 +1,98 @@ +export type SendEmailCodeResult = { + success: boolean; + expiresInSeconds: number; +}; + +export type EmailLoginResult = { + accessToken: string; + tokenType: "Bearer"; + expiresInSeconds: number; + refreshToken: string; + refreshExpiresInSeconds: number; + user: { + id: string; + email: string; + }; +}; + +type RevokeRefreshTokenResult = { + success: boolean; +}; + +const DEFAULT_API_BASE_URL = "http://localhost:3000"; + +function resolveApiBaseUrl(): string { + const envBaseUrl = import.meta.env.VITE_API_BASE_URL as string | undefined; + if (!envBaseUrl) { + return DEFAULT_API_BASE_URL; + } + + return envBaseUrl.replace(/\/+$/, ""); +} + +async function parseErrorMessage(response: Response): Promise { + try { + const body = (await response.json()) as { message?: string | string[] }; + if (Array.isArray(body.message)) { + return body.message.join(","); + } + if (typeof body.message === "string" && body.message.trim()) { + return body.message; + } + } catch { + return `请求失败(${response.status})`; + } + + return `请求失败(${response.status})`; +} + +export async function sendEmailCode(email: string): Promise { + const response = await fetch(`${resolveApiBaseUrl()}/auth/email/send-code`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ email }) + }); + + if (!response.ok) { + throw new Error(await parseErrorMessage(response)); + } + + const body = (await response.json()) as SendEmailCodeResult; + return body; +} + +export async function loginWithEmailCode(email: string, code: string): Promise { + const response = await fetch(`${resolveApiBaseUrl()}/auth/email/login`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ email, code }) + }); + + if (!response.ok) { + throw new Error(await parseErrorMessage(response)); + } + + const body = (await response.json()) as EmailLoginResult; + return body; +} + +export async function revokeRefreshToken(refreshToken: string): Promise { + const response = await fetch(`${resolveApiBaseUrl()}/auth/token/revoke`, { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ refreshToken }) + }); + + if (!response.ok) { + throw new Error(await parseErrorMessage(response)); + } + + const body = (await response.json()) as RevokeRefreshTokenResult; + return body; +} diff --git a/apps/web/src/services/session-storage.ts b/apps/web/src/services/session-storage.ts new file mode 100644 index 0000000..99963ba --- /dev/null +++ b/apps/web/src/services/session-storage.ts @@ -0,0 +1,67 @@ +import type { EmailLoginResult } from "@/services/auth-api"; + +const SESSION_STORAGE_KEY = "todolist.web.session"; + +export type WebSession = { + accessToken: string; + refreshToken: string; + user: { + id: string; + email: string; + }; +}; + +function isValidSession(payload: unknown): payload is WebSession { + if (!payload || typeof payload !== "object") { + return false; + } + + const data = payload as { + accessToken?: unknown; + refreshToken?: unknown; + user?: { + id?: unknown; + email?: unknown; + }; + }; + + return ( + typeof data.accessToken === "string" && + typeof data.refreshToken === "string" && + typeof data.user?.id === "string" && + typeof data.user?.email === "string" + ); +} + +export function loadSession(): WebSession | null { + const raw = window.localStorage.getItem(SESSION_STORAGE_KEY); + if (!raw) { + return null; + } + + try { + const parsed = JSON.parse(raw) as unknown; + if (!isValidSession(parsed)) { + return null; + } + return parsed; + } catch { + return null; + } +} + +export function saveSession(payload: EmailLoginResult | WebSession): void { + const session: WebSession = { + accessToken: payload.accessToken, + refreshToken: payload.refreshToken, + user: { + id: payload.user.id, + email: payload.user.email + } + }; + window.localStorage.setItem(SESSION_STORAGE_KEY, JSON.stringify(session)); +} + +export function clearSession(): void { + window.localStorage.removeItem(SESSION_STORAGE_KEY); +} diff --git a/apps/web/tailwind.config.js b/apps/web/tailwind.config.js new file mode 100644 index 0000000..0ded70e --- /dev/null +++ b/apps/web/tailwind.config.js @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ["./index.html", "./src/**/*.{ts,tsx}"], + theme: { + extend: {} + }, + plugins: [] +}; diff --git a/apps/web/tsconfig.app.json b/apps/web/tsconfig.app.json new file mode 100644 index 0000000..c7f7832 --- /dev/null +++ b/apps/web/tsconfig.app.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + "target": "ES2023", + "useDefineForClassFields": true, + "lib": ["ES2023", "DOM", "DOM.Iterable"], + "module": "ESNext", + "types": ["vite/client"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["src"] +} diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json new file mode 100644 index 0000000..7036885 --- /dev/null +++ b/apps/web/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "files": [], + "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }] +} diff --git a/apps/web/tsconfig.node.json b/apps/web/tsconfig.node.json new file mode 100644 index 0000000..8a67f62 --- /dev/null +++ b/apps/web/tsconfig.node.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2023", + "lib": ["ES2023"], + "module": "ESNext", + "types": ["node"], + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "erasableSyntaxOnly": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts new file mode 100644 index 0000000..396a817 --- /dev/null +++ b/apps/web/vite.config.ts @@ -0,0 +1,13 @@ +import path from "node:path"; +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], + resolve: { + alias: { + "@": path.resolve(__dirname, "./src") + } + } +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 799a176..73e0ebc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,13 +63,16 @@ importers: version: 7.6.0 "@prisma/client": specifier: ^7.6.0 - version: 7.6.0(prisma@7.6.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) + version: 7.6.0(prisma@7.6.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) class-transformer: specifier: ^0.5.1 version: 0.5.1 class-validator: specifier: ^0.15.1 version: 0.15.1 + nodemailer: + specifier: ^8.0.4 + version: 8.0.4 otplib: specifier: ^13.4.0 version: 13.4.0 @@ -101,6 +104,9 @@ importers: "@types/node": specifier: ^25.5.2 version: 25.5.2 + "@types/nodemailer": + specifier: ^8.0.0 + version: 8.0.0 "@types/passport-github2": specifier: ^1.2.9 version: 1.2.9 @@ -118,7 +124,7 @@ importers: version: 30.3.0(@types/node@25.5.2)(ts-node@10.9.2(@types/node@25.5.2)(typescript@5.9.3)) prisma: specifier: ^7.6.0 - version: 7.6.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + version: 7.6.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) supertest: specifier: ^7.2.2 version: 7.2.2 @@ -135,11 +141,100 @@ importers: specifier: ^5.9.3 version: 5.9.3 + apps/web: + dependencies: + "@base-ui/react": + specifier: ^1.3.0 + version: 1.3.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + "@fontsource-variable/geist": + specifier: ^5.2.8 + version: 5.2.8 + class-variance-authority: + specifier: ^0.7.1 + version: 0.7.1 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + lucide-react: + specifier: ^1.7.0 + version: 1.7.0(react@19.2.4) + react: + specifier: ^19.2.4 + version: 19.2.4 + react-dom: + specifier: ^19.2.4 + version: 19.2.4(react@19.2.4) + react-router-dom: + specifier: ^7.14.0 + version: 7.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + shadcn: + specifier: ^4.1.2 + version: 4.1.2(@types/node@24.12.2)(typescript@5.9.3) + tailwind-merge: + specifier: ^3.5.0 + version: 3.5.0 + tw-animate-css: + specifier: ^1.4.0 + version: 1.4.0 + devDependencies: + "@eslint/js": + specifier: ^9.39.4 + version: 9.39.4 + "@types/node": + specifier: ^24.12.0 + version: 24.12.2 + "@types/react": + specifier: ^19.2.14 + version: 19.2.14 + "@types/react-dom": + specifier: ^19.2.3 + version: 19.2.3(@types/react@19.2.14) + "@vitejs/plugin-react": + specifier: ^6.0.1 + version: 6.0.1(vite@8.0.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.12.2)(jiti@2.6.1)(yaml@2.8.3)) + autoprefixer: + specifier: ^10.4.27 + version: 10.4.27(postcss@8.5.8) + eslint: + specifier: ^9.39.4 + version: 9.39.4(jiti@2.6.1) + eslint-plugin-react-hooks: + specifier: ^7.0.1 + version: 7.0.1(eslint@9.39.4(jiti@2.6.1)) + eslint-plugin-react-refresh: + specifier: ^0.5.2 + version: 0.5.2(eslint@9.39.4(jiti@2.6.1)) + globals: + specifier: ^17.4.0 + version: 17.4.0 + postcss: + specifier: ^8.5.8 + version: 8.5.8 + tailwindcss: + specifier: ^3.4.17 + version: 3.4.17(ts-node@10.9.2(@types/node@24.12.2)(typescript@5.9.3)) + typescript: + specifier: ~5.9.3 + version: 5.9.3 + typescript-eslint: + specifier: ^8.57.0 + version: 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + vite: + specifier: ^8.0.1 + version: 8.0.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.12.2)(jiti@2.6.1)(yaml@2.8.3) + packages/eslint-config: {} packages/tsconfig: {} packages: + "@alloc/quick-lru@5.2.0": + resolution: + { + integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + } + engines: { node: ">=10" } + "@aws-crypto/crc32@5.2.0": resolution: { @@ -461,6 +556,13 @@ packages: } engines: { node: ">=6.9.0" } + "@babel/helper-annotate-as-pure@7.27.3": + resolution: + { + integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg== + } + engines: { node: ">=6.9.0" } + "@babel/helper-compilation-targets@7.28.6": resolution: { @@ -468,6 +570,15 @@ packages: } engines: { node: ">=6.9.0" } + "@babel/helper-create-class-features-plugin@7.28.6": + resolution: + { + integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow== + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0 + "@babel/helper-globals@7.28.0": resolution: { @@ -475,6 +586,13 @@ packages: } engines: { node: ">=6.9.0" } + "@babel/helper-member-expression-to-functions@7.28.5": + resolution: + { + integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== + } + engines: { node: ">=6.9.0" } + "@babel/helper-module-imports@7.28.6": resolution: { @@ -491,6 +609,13 @@ packages: peerDependencies: "@babel/core": ^7.0.0 + "@babel/helper-optimise-call-expression@7.27.1": + resolution: + { + integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw== + } + engines: { node: ">=6.9.0" } + "@babel/helper-plugin-utils@7.28.6": resolution: { @@ -498,6 +623,22 @@ packages: } engines: { node: ">=6.9.0" } + "@babel/helper-replace-supers@7.28.6": + resolution: + { + integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg== + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0 + + "@babel/helper-skip-transparent-expression-wrappers@7.27.1": + resolution: + { + integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg== + } + engines: { node: ">=6.9.0" } + "@babel/helper-string-parser@7.27.1": resolution: { @@ -676,6 +817,40 @@ packages: peerDependencies: "@babel/core": ^7.0.0-0 + "@babel/plugin-transform-modules-commonjs@7.28.6": + resolution: + { + integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA== + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/plugin-transform-typescript@7.28.6": + resolution: + { + integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw== + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/preset-typescript@7.28.5": + resolution: + { + integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== + } + engines: { node: ">=6.9.0" } + peerDependencies: + "@babel/core": ^7.0.0-0 + + "@babel/runtime@7.29.2": + resolution: + { + integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g== + } + engines: { node: ">=6.9.0" } + "@babel/template@7.28.6": resolution: { @@ -697,6 +872,33 @@ packages: } engines: { node: ">=6.9.0" } + "@base-ui/react@1.3.0": + resolution: + { + integrity: sha512-FwpKqZbPz14AITp1CVgf4AjhKPe1OeeVKSBMdgD10zbFlj3QSWelmtCMLi2+/PFZZcIm3l87G7rwtCZJwHyXWA== + } + engines: { node: ">=14.0.0" } + peerDependencies: + "@types/react": ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + "@types/react": + optional: true + + "@base-ui/utils@0.2.6": + resolution: + { + integrity: sha512-yQ+qeuqohwhsNpoYDqqXaLllYAkPCP4vYdDrVo8FQXaAPfHWm1pG/Vm+jmGTA5JFS0BAIjookyapuJFY8F9PIw== + } + peerDependencies: + "@types/react": ^17 || ^18 || ^19 + react: ^17 || ^18 || ^19 + react-dom: ^17 || ^18 || ^19 + peerDependenciesMeta: + "@types/react": + optional: true + "@bcoe/v8-coverage@0.2.3": resolution: { @@ -728,6 +930,22 @@ packages: } engines: { node: ">=12" } + "@dotenvx/dotenvx@1.59.1": + resolution: + { + integrity: sha512-Qg+meC+XFxliuVSDlEPkKnaUjdaJKK6FNx/Wwl2UxhQR8pyPIuLhMavsF7ePdB9qFZUWV1jEK3ckbJir/WmF4w== + } + hasBin: true + + "@ecies/ciphers@0.2.6": + resolution: + { + integrity: sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g== + } + engines: { bun: ">=1", deno: ">=2.7.10", node: ">=16" } + peerDependencies: + "@noble/ciphers": ^1.0.0 + "@electric-sql/pglite-socket@0.1.1": resolution: { @@ -785,6 +1003,13 @@ packages: } engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } + "@eslint/config-array@0.21.2": + resolution: + { + integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + "@eslint/config-array@0.23.4": resolution: { @@ -792,6 +1017,13 @@ packages: } engines: { node: ^20.19.0 || ^22.13.0 || >=24 } + "@eslint/config-helpers@0.4.2": + resolution: + { + integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + "@eslint/config-helpers@0.5.4": resolution: { @@ -799,6 +1031,13 @@ packages: } engines: { node: ^20.19.0 || ^22.13.0 || >=24 } + "@eslint/core@0.17.0": + resolution: + { + integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + "@eslint/core@1.2.0": resolution: { @@ -806,6 +1045,13 @@ packages: } engines: { node: ^20.19.0 || ^22.13.0 || >=24 } + "@eslint/eslintrc@3.3.5": + resolution: + { + integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + "@eslint/js@10.0.1": resolution: { @@ -818,6 +1064,20 @@ packages: eslint: optional: true + "@eslint/js@9.39.4": + resolution: + { + integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@eslint/object-schema@2.1.7": + resolution: + { + integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + "@eslint/object-schema@3.0.4": resolution: { @@ -825,6 +1085,13 @@ packages: } engines: { node: ^20.19.0 || ^22.13.0 || >=24 } + "@eslint/plugin-kit@0.4.1": + resolution: + { + integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + "@eslint/plugin-kit@0.7.0": resolution: { @@ -832,6 +1099,39 @@ packages: } engines: { node: ^20.19.0 || ^22.13.0 || >=24 } + "@floating-ui/core@1.7.5": + resolution: + { + integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ== + } + + "@floating-ui/dom@1.7.6": + resolution: + { + integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ== + } + + "@floating-ui/react-dom@2.1.8": + resolution: + { + integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A== + } + peerDependencies: + react: ">=16.8.0" + react-dom: ">=16.8.0" + + "@floating-ui/utils@0.2.11": + resolution: + { + integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg== + } + + "@fontsource-variable/geist@5.2.8": + resolution: + { + integrity: sha512-cJ6m9e+8MQ5dCYJsLylfZrgBh6KkG4bOLckB35Tr9J/EqdkEM6QllH5PxqP1dhTvFup+HtMRPuz9xOjxXJggxw== + } + "@hono/node-server@1.19.11": resolution: { @@ -869,6 +1169,56 @@ packages: } engines: { node: ">=18.18" } + "@inquirer/ansi@1.0.2": + resolution: + { + integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ== + } + engines: { node: ">=18" } + + "@inquirer/confirm@5.1.21": + resolution: + { + integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ== + } + engines: { node: ">=18" } + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + + "@inquirer/core@10.3.2": + resolution: + { + integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A== + } + engines: { node: ">=18" } + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + + "@inquirer/figures@1.0.15": + resolution: + { + integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g== + } + engines: { node: ">=18" } + + "@inquirer/type@3.0.10": + resolution: + { + integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA== + } + engines: { node: ">=18" } + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + "@isaacs/cliui@8.0.2": resolution: { @@ -1076,12 +1426,41 @@ packages: } engines: { node: ">=8" } + "@modelcontextprotocol/sdk@1.29.0": + resolution: + { + integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ== + } + engines: { node: ">=18" } + peerDependencies: + "@cfworker/json-schema": ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + "@cfworker/json-schema": + optional: true + + "@mswjs/interceptors@0.41.3": + resolution: + { + integrity: sha512-cXu86tF4VQVfwz8W1SPbhoRyHJkti6mjH/XJIxp40jhO4j2k1m4KYrEykxqWPkFF3vrK4rgQppBh//AwyGSXPA== + } + engines: { node: ">=18" } + "@napi-rs/wasm-runtime@0.2.12": resolution: { integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== } + "@napi-rs/wasm-runtime@1.1.2": + resolution: + { + integrity: sha512-sNXv5oLJ7ob93xkZ1XnxisYhGYXfaG9f65/ZgYuAu3qt7b3NadcOEhLvx28hv31PgX8SZJRYrAIPQilQmFpLVw== + } + peerDependencies: + "@emnapi/core": ^1.7.1 + "@emnapi/runtime": ^1.7.1 + "@nestjs/common@11.1.18": resolution: { @@ -1170,6 +1549,20 @@ packages: "@nestjs/platform-express": optional: true + "@noble/ciphers@1.3.0": + resolution: + { + integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw== + } + engines: { node: ^14.21.3 || >=16 } + + "@noble/curves@1.9.7": + resolution: + { + integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw== + } + engines: { node: ^14.21.3 || >=16 } + "@noble/hashes@1.8.0": resolution: { @@ -1184,6 +1577,27 @@ packages: } engines: { node: ">= 20.19.0" } + "@nodelib/fs.scandir@2.1.5": + resolution: + { + integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + } + engines: { node: ">= 8" } + + "@nodelib/fs.stat@2.0.5": + resolution: + { + integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + } + engines: { node: ">= 8" } + + "@nodelib/fs.walk@1.2.8": + resolution: + { + integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + } + engines: { node: ">= 8" } + "@nuxt/opencollective@0.4.1": resolution: { @@ -1192,6 +1606,24 @@ packages: engines: { node: ^14.18.0 || >=16.10.0, npm: ">=5.10.0" } hasBin: true + "@open-draft/deferred-promise@2.2.0": + resolution: + { + integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA== + } + + "@open-draft/logger@0.3.0": + resolution: + { + integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ== + } + + "@open-draft/until@2.1.0": + resolution: + { + integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg== + } + "@otplib/core@12.0.1": resolution: { @@ -1255,6 +1687,12 @@ packages: integrity: sha512-x1ozBa5bPbdZCrrTL/HK21qchiK7jYElTu+0ft22abeEhiLYgH1+SIULvOcVk3CK8YwF4kdcidvkq4ciejucJA== } + "@oxc-project/types@0.122.0": + resolution: + { + integrity: sha512-oLAl5kBpV4w69UtFZ9xqcmTi+GENWOcPF7FCrczTiBbmC0ibXxCwyvZGbO39rCVEuLGAZM84DH0pUIyyv/YJzA== + } + "@paralleldrive/cuid2@2.3.1": resolution: { @@ -1484,18 +1922,177 @@ packages: "@types/react": optional: true + "@rolldown/binding-android-arm64@1.0.0-rc.12": + resolution: + { + integrity: sha512-pv1y2Fv0JybcykuiiD3qBOBdz6RteYojRFY1d+b95WVuzx211CRh+ytI/+9iVyWQ6koTh5dawe4S/yRfOFjgaA== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [android] + + "@rolldown/binding-darwin-arm64@1.0.0-rc.12": + resolution: + { + integrity: sha512-cFYr6zTG/3PXXF3pUO+umXxt1wkRK/0AYT8lDwuqvRC+LuKYWSAQAQZjCWDQpAH172ZV6ieYrNnFzVVcnSflAg== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [darwin] + + "@rolldown/binding-darwin-x64@1.0.0-rc.12": + resolution: + { + integrity: sha512-ZCsYknnHzeXYps0lGBz8JrF37GpE9bFVefrlmDrAQhOEi4IOIlcoU1+FwHEtyXGx2VkYAvhu7dyBf75EJQffBw== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [darwin] + + "@rolldown/binding-freebsd-x64@1.0.0-rc.12": + resolution: + { + integrity: sha512-dMLeprcVsyJsKolRXyoTH3NL6qtsT0Y2xeuEA8WQJquWFXkEC4bcu1rLZZSnZRMtAqwtrF/Ib9Ddtpa/Gkge9Q== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [freebsd] + + "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12": + resolution: + { + integrity: sha512-YqWjAgGC/9M1lz3GR1r1rP79nMgo3mQiiA+Hfo+pvKFK1fAJ1bCi0ZQVh8noOqNacuY1qIcfyVfP6HoyBRZ85Q== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm] + os: [linux] + + "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12": + resolution: + { + integrity: sha512-/I5AS4cIroLpslsmzXfwbe5OmWvSsrFuEw3mwvbQ1kDxJ822hFHIx+vsN/TAzNVyepI/j/GSzrtCIwQPeKCLIg== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [linux] + + "@rolldown/binding-linux-arm64-musl@1.0.0-rc.12": + resolution: + { + integrity: sha512-V6/wZztnBqlx5hJQqNWwFdxIKN0m38p8Jas+VoSfgH54HSj9tKTt1dZvG6JRHcjh6D7TvrJPWFGaY9UBVOaWPw== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [linux] + + "@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12": + resolution: + { + integrity: sha512-AP3E9BpcUYliZCxa3w5Kwj9OtEVDYK6sVoUzy4vTOJsjPOgdaJZKFmN4oOlX0Wp0RPV2ETfmIra9x1xuayFB7g== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [ppc64] + os: [linux] + + "@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12": + resolution: + { + integrity: sha512-nWwpvUSPkoFmZo0kQazZYOrT7J5DGOJ/+QHHzjvNlooDZED8oH82Yg67HvehPPLAg5fUff7TfWFHQS8IV1n3og== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [s390x] + os: [linux] + + "@rolldown/binding-linux-x64-gnu@1.0.0-rc.12": + resolution: + { + integrity: sha512-RNrafz5bcwRy+O9e6P8Z/OCAJW/A+qtBczIqVYwTs14pf4iV1/+eKEjdOUta93q2TsT/FI0XYDP3TCky38LMAg== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [linux] + + "@rolldown/binding-linux-x64-musl@1.0.0-rc.12": + resolution: + { + integrity: sha512-Jpw/0iwoKWx3LJ2rc1yjFrj+T7iHZn2JDg1Yny1ma0luviFS4mhAIcd1LFNxK3EYu3DHWCps0ydXQ5i/rrJ2ig== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [linux] + + "@rolldown/binding-openharmony-arm64@1.0.0-rc.12": + resolution: + { + integrity: sha512-vRugONE4yMfVn0+7lUKdKvN4D5YusEiPilaoO2sgUWpCvrncvWgPMzK00ZFFJuiPgLwgFNP5eSiUlv2tfc+lpA== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [openharmony] + + "@rolldown/binding-wasm32-wasi@1.0.0-rc.12": + resolution: + { + integrity: sha512-ykGiLr/6kkiHc0XnBfmFJuCjr5ZYKKofkx+chJWDjitX+KsJuAmrzWhwyOMSHzPhzOHOy7u9HlFoa5MoAOJ/Zg== + } + engines: { node: ">=14.0.0" } + cpu: [wasm32] + + "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12": + resolution: + { + integrity: sha512-5eOND4duWkwx1AzCxadcOrNeighiLwMInEADT0YM7xeEOOFcovWZCq8dadXgcRHSf3Ulh1kFo/qvzoFiCLOL1Q== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [arm64] + os: [win32] + + "@rolldown/binding-win32-x64-msvc@1.0.0-rc.12": + resolution: + { + integrity: sha512-PyqoipaswDLAZtot351MLhrlrh6lcZPo2LSYE+VDxbVk24LVKAGOuE4hb8xZQmrPAuEtTZW8E6D2zc5EUZX4Lw== + } + engines: { node: ^20.19.0 || >=22.12.0 } + cpu: [x64] + os: [win32] + + "@rolldown/pluginutils@1.0.0-rc.12": + resolution: + { + integrity: sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw== + } + + "@rolldown/pluginutils@1.0.0-rc.7": + resolution: + { + integrity: sha512-qujRfC8sFVInYSPPMLQByRh7zhwkGFS4+tyMQ83srV1qrxL4g8E2tyxVVyxd0+8QeBM1mIk9KbWxkegRr76XzA== + } + "@scure/base@2.0.0": resolution: { integrity: sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w== } + "@sec-ant/readable-stream@0.4.1": + resolution: + { + integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg== + } + "@sinclair/typebox@0.34.49": resolution: { integrity: sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A== } + "@sindresorhus/merge-streams@4.0.0": + resolution: + { + integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ== + } + engines: { node: ">=18" } + "@sinonjs/commons@3.0.1": resolution: { @@ -1898,6 +2495,12 @@ packages: integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== } + "@ts-morph/common@0.27.0": + resolution: + { + integrity: sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ== + } + "@tsconfig/node10@1.0.12": resolution: { @@ -2096,12 +2699,24 @@ packages: integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== } + "@types/node@24.12.2": + resolution: + { + integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g== + } + "@types/node@25.5.2": resolution: { integrity: sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg== } + "@types/nodemailer@8.0.0": + resolution: + { + integrity: sha512-fyf8jWULsCo0d0BuoQ75i6IeoHs47qcqxWc7yUdUcV0pOZGjUTTOvwdG1PRXUDqN/8A64yQdQdnA2pZgcdi+cA== + } + "@types/oauth@0.9.6": resolution: { @@ -2144,6 +2759,14 @@ packages: integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== } + "@types/react-dom@19.2.3": + resolution: + { + integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ== + } + peerDependencies: + "@types/react": ^19.2.0 + "@types/react@19.2.14": resolution: { @@ -2168,6 +2791,12 @@ packages: integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== } + "@types/statuses@2.0.6": + resolution: + { + integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA== + } + "@types/strip-bom@3.0.0": resolution: { @@ -2192,6 +2821,12 @@ packages: integrity: sha512-uh2Lv57xvggst6lCqNdFAmDSvoMG7M/HDtX4iUCquxQ5EGPtaPM5PL5Hmi7LCvOG8db7YaCPNJEeoI8s/WzIQw== } + "@types/validate-npm-package-name@4.0.2": + resolution: + { + integrity: sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw== + } + "@types/validator@13.15.10": resolution: { @@ -2210,6 +2845,95 @@ packages: integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg== } + "@typescript-eslint/eslint-plugin@8.58.0": + resolution: + { + integrity: sha512-RLkVSiNuUP1C2ROIWfqX+YcUfLaSnxGE/8M+Y57lopVwg9VTYYfhuz15Yf1IzCKgZj6/rIbYTmJCUSqr76r0Wg== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + "@typescript-eslint/parser": ^8.58.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + + "@typescript-eslint/parser@8.58.0": + resolution: + { + integrity: sha512-rLoGZIf9afaRBYsPUMtvkDWykwXwUPL60HebR4JgTI8mxfFe2cQTu3AGitANp4b9B2QlVru6WzjgB2IzJKiCSA== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + + "@typescript-eslint/project-service@8.58.0": + resolution: + { + integrity: sha512-8Q/wBPWLQP1j16NxoPNIKpDZFMaxl7yWIoqXWYeWO+Bbd2mjgvoF0dxP2jKZg5+x49rgKdf7Ck473M8PC3V9lg== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + + "@typescript-eslint/scope-manager@8.58.0": + resolution: + { + integrity: sha512-W1Lur1oF50FxSnNdGp3Vs6P+yBRSmZiw4IIjEeYxd8UQJwhUF0gDgDD/W/Tgmh73mxgEU3qX0Bzdl/NGuSPEpQ== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@typescript-eslint/tsconfig-utils@8.58.0": + resolution: + { + integrity: sha512-doNSZEVJsWEu4htiVC+PR6NpM+pa+a4ClH9INRWOWCUzMst/VA9c4gXq92F8GUD1rwhNvRLkgjfYtFXegXQF7A== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + + "@typescript-eslint/type-utils@8.58.0": + resolution: + { + integrity: sha512-aGsCQImkDIqMyx1u4PrVlbi/krmDsQUs4zAcCV6M7yPcPev+RqVlndsJy9kJ8TLihW9TZ0kbDAzctpLn5o+lOg== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + + "@typescript-eslint/types@8.58.0": + resolution: + { + integrity: sha512-O9CjxypDT89fbHxRfETNoAnHj/i6IpRK0CvbVN3qibxlLdo5p5hcLmUuCCrHMpxiWSwKyI8mCP7qRNYuOJ0Uww== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + + "@typescript-eslint/typescript-estree@8.58.0": + resolution: + { + integrity: sha512-7vv5UWbHqew/dvs+D3e1RvLv1v2eeZ9txRHPnEEBUgSNLx5ghdzjHa0sgLWYVKssH+lYmV0JaWdoubo0ncGYLA== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + + "@typescript-eslint/utils@8.58.0": + resolution: + { + integrity: sha512-RfeSqcFeHMHlAWzt4TBjWOAtoW9lnsAGiP3GbaX9uVgTYYrMbVnGONEfUCiSss+xMHFl+eHZiipmA8WkQ7FuNA== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + + "@typescript-eslint/visitor-keys@8.58.0": + resolution: + { + integrity: sha512-XJ9UD9+bbDo4a4epraTwG3TsNPeiB9aShrUneAVXy8q4LuwowN+qu89/6ByLMINqvIMeI9H9hOHQtg/ijrYXzQ== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + "@ungap/structured-clone@1.3.0": resolution: { @@ -2368,6 +3092,22 @@ packages: cpu: [x64] os: [win32] + "@vitejs/plugin-react@6.0.1": + resolution: + { + integrity: sha512-l9X/E3cDb+xY3SWzlG1MOGt2usfEHGMNIaegaUGFsLkb3RCn/k8/TOXBcab+OndDI4TBtktT8/9BwwW8Vi9KUQ== + } + engines: { node: ^20.19.0 || >=22.12.0 } + peerDependencies: + "@rolldown/plugin-babel": ^0.1.7 || ^0.2.0 + babel-plugin-react-compiler: ^1.0.0 + vite: ^8.0.0 + peerDependenciesMeta: + "@rolldown/plugin-babel": + optional: true + babel-plugin-react-compiler: + optional: true + accepts@2.0.0: resolution: { @@ -2398,6 +3138,24 @@ packages: engines: { node: ">=0.4.0" } hasBin: true + agent-base@7.1.4: + resolution: + { + integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== + } + engines: { node: ">= 14" } + + ajv-formats@3.0.1: + resolution: + { + integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ== + } + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv@6.14.0: resolution: { @@ -2459,6 +3217,12 @@ packages: } engines: { node: ">=12" } + any-promise@1.3.0: + resolution: + { + integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + } + anymatch@3.1.3: resolution: { @@ -2478,24 +3242,53 @@ packages: integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== } + arg@5.0.2: + resolution: + { + integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + } + argparse@1.0.10: resolution: { integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== } + argparse@2.0.1: + resolution: + { + integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + } + asap@2.0.6: resolution: { integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== } + ast-types@0.16.1: + resolution: + { + integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg== + } + engines: { node: ">=4" } + asynckit@0.4.0: resolution: { integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== } + autoprefixer@10.4.27: + resolution: + { + integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA== + } + engines: { node: ^10 || ^12 || >=14 } + hasBin: true + peerDependencies: + postcss: ^8.1.0 + aws-ssl-profiles@1.1.2: resolution: { @@ -2657,6 +3450,13 @@ packages: integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== } + bundle-name@4.1.0: + resolution: + { + integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q== + } + engines: { node: ">=18" } + busboy@1.6.0: resolution: { @@ -2703,6 +3503,13 @@ packages: } engines: { node: ">=6" } + camelcase-css@2.0.1: + resolution: + { + integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + } + engines: { node: ">= 6" } + camelcase@5.3.1: resolution: { @@ -2730,6 +3537,13 @@ packages: } engines: { node: ">=10" } + chalk@5.6.2: + resolution: + { + integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA== + } + engines: { node: ^12.17.0 || ^14.13 || >=16.0.0 } + char-regex@1.0.2: resolution: { @@ -2795,6 +3609,12 @@ packages: integrity: sha512-LqoS80HBBSCVhz/3KloUly0ovokxpdOLR++Al3J3+dHXWt9sTKlKd4eYtoxhxyUjoe5+UcIM+5k9MIxyBWnRTw== } + class-variance-authority@0.7.1: + resolution: + { + integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg== + } + cli-cursor@5.0.0: resolution: { @@ -2802,6 +3622,13 @@ packages: } engines: { node: ">=18" } + cli-spinners@2.9.2: + resolution: + { + integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== + } + engines: { node: ">=6" } + cli-truncate@5.2.0: resolution: { @@ -2809,6 +3636,13 @@ packages: } engines: { node: ">=20" } + cli-width@4.1.0: + resolution: + { + integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + } + engines: { node: ">= 12" } + cliui@8.0.1: resolution: { @@ -2816,6 +3650,13 @@ packages: } engines: { node: ">=12" } + clsx@2.1.1: + resolution: + { + integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + } + engines: { node: ">=6" } + co@4.6.0: resolution: { @@ -2823,6 +3664,12 @@ packages: } engines: { iojs: ">= 1.0.0", node: ">= 0.12.0" } + code-block-writer@13.0.3: + resolution: + { + integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg== + } + collect-v8-coverage@1.0.3: resolution: { @@ -2855,6 +3702,13 @@ packages: } engines: { node: ">= 0.8" } + commander@11.1.0: + resolution: + { + integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== + } + engines: { node: ">=16" } + commander@14.0.3: resolution: { @@ -2862,6 +3716,13 @@ packages: } engines: { node: ">=20" } + commander@4.1.1: + resolution: + { + integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + } + engines: { node: ">= 6" } + component-emitter@1.3.1: resolution: { @@ -2928,6 +3789,13 @@ packages: } engines: { node: ">= 0.6" } + cookie@1.1.1: + resolution: + { + integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ== + } + engines: { node: ">=18" } + cookiejar@2.1.4: resolution: { @@ -2941,6 +3809,18 @@ packages: } engines: { node: ">= 0.10" } + cosmiconfig@9.0.1: + resolution: + { + integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ== + } + engines: { node: ">=14" } + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + create-require@1.1.1: resolution: { @@ -2954,12 +3834,27 @@ packages: } engines: { node: ">= 8" } + cssesc@3.0.0: + resolution: + { + integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + } + engines: { node: ">=4" } + hasBin: true + csstype@3.2.3: resolution: { integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== } + data-uri-to-buffer@4.0.1: + resolution: + { + integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + } + engines: { node: ">= 12" } + debug@4.4.3: resolution: { @@ -3003,6 +3898,27 @@ packages: } engines: { node: ">=0.10.0" } + default-browser-id@5.0.1: + resolution: + { + integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q== + } + engines: { node: ">=18" } + + default-browser@5.5.0: + resolution: + { + integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw== + } + engines: { node: ">=18" } + + define-lazy-prop@3.0.0: + resolution: + { + integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + } + engines: { node: ">=12" } + defu@6.1.6: resolution: { @@ -3036,6 +3952,13 @@ packages: integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA== } + detect-libc@2.1.2: + resolution: + { + integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== + } + engines: { node: ">=8" } + detect-newline@3.1.0: resolution: { @@ -3049,6 +3972,12 @@ packages: integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig== } + didyoumean@1.2.2: + resolution: + { + integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + } + diff@4.0.4: resolution: { @@ -3056,6 +3985,19 @@ packages: } engines: { node: ">=0.3.1" } + diff@8.0.4: + resolution: + { + integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw== + } + engines: { node: ">=0.3.1" } + + dlv@1.1.3: + resolution: + { + integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + } + dotenv-expand@12.0.3: resolution: { @@ -3102,6 +4044,13 @@ packages: integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== } + eciesjs@0.4.18: + resolution: + { + integrity: sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ== + } + engines: { bun: ">=1", deno: ">=2", node: ">=16" } + ee-first@1.1.1: resolution: { @@ -3159,6 +4108,13 @@ packages: } engines: { node: ">= 0.8" } + env-paths@2.2.1: + resolution: + { + integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + } + engines: { node: ">=6" } + env-paths@3.0.0: resolution: { @@ -3234,6 +4190,30 @@ packages: } engines: { node: ">=10" } + eslint-plugin-react-hooks@7.0.1: + resolution: + { + integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA== + } + engines: { node: ">=18" } + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.5.2: + resolution: + { + integrity: sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA== + } + peerDependencies: + eslint: ^9 || ^10 + + eslint-scope@8.4.0: + resolution: + { + integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + eslint-scope@9.1.2: resolution: { @@ -3248,6 +4228,13 @@ packages: } engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } + eslint-visitor-keys@4.2.1: + resolution: + { + integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + eslint-visitor-keys@5.0.1: resolution: { @@ -3268,6 +4255,26 @@ packages: jiti: optional: true + eslint@9.39.4: + resolution: + { + integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + hasBin: true + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: + { + integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + espree@11.2.0: resolution: { @@ -3324,6 +4331,20 @@ packages: integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw== } + eventsource-parser@3.0.6: + resolution: + { + integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg== + } + engines: { node: ">=18.0.0" } + + eventsource@3.0.7: + resolution: + { + integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA== + } + engines: { node: ">=18.0.0" } + execa@5.1.1: resolution: { @@ -3331,6 +4352,13 @@ packages: } engines: { node: ">=10" } + execa@9.6.1: + resolution: + { + integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA== + } + engines: { node: ^18.19.0 || >=20.5.0 } + exit-x@0.2.2: resolution: { @@ -3345,6 +4373,15 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + express-rate-limit@8.3.2: + resolution: + { + integrity: sha512-77VmFeJkO0/rvimEDuUC5H30oqUC4EyOhyGccfqoLebB0oiEYfM7nwPrsDsBL1gsTpwfzX8SFy2MT3TDyRq+bg== + } + engines: { node: ">= 16" } + peerDependencies: + express: ">= 4.11" + express@5.2.1: resolution: { @@ -3371,6 +4408,13 @@ packages: integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== } + fast-glob@3.3.3: + resolution: + { + integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== + } + engines: { node: ">=8.6.0" } + fast-json-stable-stringify@2.1.0: resolution: { @@ -3408,12 +4452,44 @@ packages: } hasBin: true + fastq@1.20.1: + resolution: + { + integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw== + } + fb-watchman@2.0.2: resolution: { integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== } + fdir@6.5.0: + resolution: + { + integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== + } + engines: { node: ">=12.0.0" } + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-blob@3.2.0: + resolution: + { + integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + } + engines: { node: ^12.20 || >= 14.13 } + + figures@6.1.0: + resolution: + { + integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg== + } + engines: { node: ">=18" } + file-entry-cache@8.0.0: resolution: { @@ -3483,6 +4559,13 @@ packages: } engines: { node: ">= 6" } + formdata-polyfill@4.0.10: + resolution: + { + integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + } + engines: { node: ">=12.20.0" } + formidable@3.5.4: resolution: { @@ -3497,6 +4580,12 @@ packages: } engines: { node: ">= 0.6" } + fraction.js@5.3.4: + resolution: + { + integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ== + } + fresh@2.0.0: resolution: { @@ -3504,6 +4593,13 @@ packages: } engines: { node: ">= 0.8" } + fs-extra@11.3.4: + resolution: + { + integrity: sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA== + } + engines: { node: ">=14.14" } + fs.realpath@1.0.0: resolution: { @@ -3524,6 +4620,12 @@ packages: integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== } + fuzzysort@3.1.0: + resolution: + { + integrity: sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ== + } + generate-function@2.3.1: resolution: { @@ -3558,6 +4660,13 @@ packages: } engines: { node: ">= 0.4" } + get-own-enumerable-keys@1.0.0: + resolution: + { + integrity: sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA== + } + engines: { node: ">=14.16" } + get-package-type@0.1.0: resolution: { @@ -3585,6 +4694,13 @@ packages: } engines: { node: ">=10" } + get-stream@9.0.1: + resolution: + { + integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA== + } + engines: { node: ">=18" } + giget@2.0.0: resolution: { @@ -3621,6 +4737,13 @@ packages: } deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + globals@14.0.0: + resolution: + { + integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== + } + engines: { node: ">=18" } + globals@17.4.0: resolution: { @@ -3653,6 +4776,13 @@ packages: integrity: sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg== } + graphql@16.13.2: + resolution: + { + integrity: sha512-5bJ+nf/UCpAjHM8i06fl7eLyVC9iuNAjm9qzkiu2ZGhM0VscSvS6WDPfAwkdkBuoXGM9FJSbKl6wylMwP9Ktig== + } + engines: { node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0 } + handlebars@4.7.9: resolution: { @@ -3689,6 +4819,24 @@ packages: } engines: { node: ">= 0.4" } + headers-polyfill@4.0.3: + resolution: + { + integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ== + } + + hermes-estree@0.25.1: + resolution: + { + integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw== + } + + hermes-parser@0.25.1: + resolution: + { + integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA== + } + hono@4.12.10: resolution: { @@ -3715,6 +4863,13 @@ packages: integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA== } + https-proxy-agent@7.0.6: + resolution: + { + integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== + } + engines: { node: ">= 14" } + human-signals@2.1.0: resolution: { @@ -3722,6 +4877,13 @@ packages: } engines: { node: ">=10.17.0" } + human-signals@8.0.1: + resolution: + { + integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ== + } + engines: { node: ">=18.18.0" } + husky@9.1.7: resolution: { @@ -3750,6 +4912,20 @@ packages: } engines: { node: ">= 4" } + ignore@7.0.5: + resolution: + { + integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== + } + engines: { node: ">= 4" } + + import-fresh@3.3.1: + resolution: + { + integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== + } + engines: { node: ">=6" } + import-local@3.2.0: resolution: { @@ -3778,6 +4954,13 @@ packages: integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== } + ip-address@10.1.0: + resolution: + { + integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q== + } + engines: { node: ">= 12" } + ipaddr.js@1.9.1: resolution: { @@ -3805,6 +4988,14 @@ packages: } engines: { node: ">= 0.4" } + is-docker@3.0.0: + resolution: + { + integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + hasBin: true + is-extglob@2.1.1: resolution: { @@ -3840,6 +5031,34 @@ packages: } engines: { node: ">=0.10.0" } + is-in-ssh@1.0.0: + resolution: + { + integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw== + } + engines: { node: ">=20" } + + is-inside-container@1.0.0: + resolution: + { + integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + } + engines: { node: ">=14.16" } + hasBin: true + + is-interactive@2.0.0: + resolution: + { + integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ== + } + engines: { node: ">=12" } + + is-node-process@1.2.0: + resolution: + { + integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw== + } + is-number@7.0.0: resolution: { @@ -3847,6 +5066,20 @@ packages: } engines: { node: ">=0.12.0" } + is-obj@3.0.0: + resolution: + { + integrity: sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ== + } + engines: { node: ">=12" } + + is-plain-obj@4.1.0: + resolution: + { + integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + } + engines: { node: ">=12" } + is-promise@4.0.0: resolution: { @@ -3859,6 +5092,13 @@ packages: integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== } + is-regexp@3.1.0: + resolution: + { + integrity: sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA== + } + engines: { node: ">=12" } + is-stream@2.0.1: resolution: { @@ -3866,12 +5106,47 @@ packages: } engines: { node: ">=8" } + is-stream@4.0.1: + resolution: + { + integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A== + } + engines: { node: ">=18" } + + is-unicode-supported@1.3.0: + resolution: + { + integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ== + } + engines: { node: ">=12" } + + is-unicode-supported@2.1.0: + resolution: + { + integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ== + } + engines: { node: ">=18" } + + is-wsl@3.1.1: + resolution: + { + integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw== + } + engines: { node: ">=16" } + isexe@2.0.0: resolution: { integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== } + isexe@3.1.5: + resolution: + { + integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w== + } + engines: { node: ">=18" } + istanbul-lib-coverage@3.2.2: resolution: { @@ -4123,6 +5398,13 @@ packages: node-notifier: optional: true + jiti@1.21.7: + resolution: + { + integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A== + } + hasBin: true + jiti@2.6.1: resolution: { @@ -4130,6 +5412,12 @@ packages: } hasBin: true + jose@6.2.2: + resolution: + { + integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ== + } + js-tokens@4.0.0: resolution: { @@ -4143,6 +5431,13 @@ packages: } hasBin: true + js-yaml@4.1.1: + resolution: + { + integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + } + hasBin: true + jsesc@3.1.0: resolution: { @@ -4175,6 +5470,12 @@ packages: integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== } + json-schema-typed@8.0.2: + resolution: + { + integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA== + } + json-stable-stringify-without-jsonify@1.0.1: resolution: { @@ -4189,6 +5490,12 @@ packages: engines: { node: ">=6" } hasBin: true + jsonfile@6.2.0: + resolution: + { + integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg== + } + jsonwebtoken@9.0.3: resolution: { @@ -4214,6 +5521,20 @@ packages: integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== } + kleur@3.0.3: + resolution: + { + integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + } + engines: { node: ">=6" } + + kleur@4.1.5: + resolution: + { + integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + } + engines: { node: ">=6" } + leven@3.1.0: resolution: { @@ -4234,6 +5555,119 @@ packages: integrity: sha512-lsmMmGXBxXIK/VMLEj0kL6MtUs1kBGj1nTCzi6zgQoG1DEwqwt2DQyHxcLykceIxAnfE3hya7NuIh6PpC6S3fA== } + lightningcss-android-arm64@1.32.0: + resolution: + { + integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg== + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: + { + integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ== + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: + { + integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w== + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: + { + integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig== + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: + { + integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw== + } + engines: { node: ">= 12.0.0" } + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: + { + integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ== + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: + { + integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg== + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: + { + integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA== + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.32.0: + resolution: + { + integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg== + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: + { + integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw== + } + engines: { node: ">= 12.0.0" } + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: + { + integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q== + } + engines: { node: ">= 12.0.0" } + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: + { + integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ== + } + engines: { node: ">= 12.0.0" } + + lilconfig@3.1.3: + resolution: + { + integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== + } + engines: { node: ">=14" } + lines-and-columns@1.2.4: resolution: { @@ -4318,6 +5752,12 @@ packages: integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== } + lodash.merge@4.6.2: + resolution: + { + integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + } + lodash.once@4.1.1: resolution: { @@ -4330,6 +5770,13 @@ packages: integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== } + log-symbols@6.0.0: + resolution: + { + integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw== + } + engines: { node: ">=18" } + log-update@6.1.0: resolution: { @@ -4362,6 +5809,14 @@ packages: } engines: { bun: ">=1.0.0", deno: ">=1.30.0", node: ">=8.0.0" } + lucide-react@1.7.0: + resolution: + { + integrity: sha512-yI7BeItCLZJTXikmK4KNUGCKoGzSvbKlfCvw44bU4fXAL6v3gYS4uHD1jzsLkfwODYwI6Drw5Tu9Z5ulDe0TSg== + } + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 + make-dir@4.0.0: resolution: { @@ -4415,6 +5870,13 @@ packages: integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== } + merge2@1.4.1: + resolution: + { + integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + } + engines: { node: ">= 8" } + methods@1.1.2: resolution: { @@ -4422,6 +5884,13 @@ packages: } engines: { node: ">= 0.6" } + micromatch@4.0.8: + resolution: + { + integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + } + engines: { node: ">=8.6" } + mime-db@1.52.0: resolution: { @@ -4519,6 +5988,19 @@ packages: integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== } + msw@2.12.14: + resolution: + { + integrity: sha512-4KXa4nVBIBjbDbd7vfQNuQ25eFxug0aropCQFoI0JdOBuJWamkT1yLVIWReFI8SiTRc+H1hKzaNk+cLk2N9rtQ== + } + engines: { node: ">=18" } + hasBin: true + peerDependencies: + typescript: ">= 4.8.x" + peerDependenciesMeta: + typescript: + optional: true + multer@2.1.1: resolution: { @@ -4526,6 +6008,13 @@ packages: } engines: { node: ">= 10.16.0" } + mute-stream@2.0.0: + resolution: + { + integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== + } + engines: { node: ^18.17.0 || >=20.5.0 } + mysql2@3.15.3: resolution: { @@ -4533,6 +6022,12 @@ packages: } engines: { node: ">= 8.0" } + mz@2.7.0: + resolution: + { + integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + } + named-placeholders@1.1.6: resolution: { @@ -4540,6 +6035,14 @@ packages: } engines: { node: ">=8.0.0" } + nanoid@3.3.11: + resolution: + { + integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + } + engines: { node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 } + hasBin: true + napi-postinstall@0.3.4: resolution: { @@ -4567,12 +6070,27 @@ packages: integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== } + node-domexception@1.0.0: + resolution: + { + integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + } + engines: { node: ">=10.5.0" } + deprecated: Use your platform's native DOMException instead + node-fetch-native@1.6.7: resolution: { integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q== } + node-fetch@3.3.2: + resolution: + { + integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== + } + engines: { node: ^12.20.0 || ^14.13.1 || >=16.0.0 } + node-int64@0.4.0: resolution: { @@ -4585,6 +6103,13 @@ packages: integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg== } + nodemailer@8.0.4: + resolution: + { + integrity: sha512-k+jf6N8PfQJ0Fe8ZhJlgqU5qJU44Lpvp2yvidH3vp1lPnVQMgi4yEEMPXg5eJS1gFIJTVq1NHBk7Ia9ARdSBdQ== + } + engines: { node: ">=6.0.0" } + normalize-path@3.0.0: resolution: { @@ -4599,6 +6124,13 @@ packages: } engines: { node: ">=8" } + npm-run-path@6.0.0: + resolution: + { + integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA== + } + engines: { node: ">=18" } + nypm@0.6.5: resolution: { @@ -4620,6 +6152,13 @@ packages: } engines: { node: ">=0.10.0" } + object-hash@3.0.0: + resolution: + { + integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + } + engines: { node: ">= 6" } + object-inspect@1.13.4: resolution: { @@ -4627,6 +6166,13 @@ packages: } engines: { node: ">= 0.4" } + object-treeify@1.1.33: + resolution: + { + integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A== + } + engines: { node: ">= 10" } + ohash@2.0.11: resolution: { @@ -4660,6 +6206,13 @@ packages: } engines: { node: ">=18" } + open@11.0.0: + resolution: + { + integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw== + } + engines: { node: ">=20" } + optionator@0.9.4: resolution: { @@ -4667,12 +6220,25 @@ packages: } engines: { node: ">= 0.8.0" } + ora@8.2.0: + resolution: + { + integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw== + } + engines: { node: ">=18" } + otplib@13.4.0: resolution: { integrity: sha512-RUcYcRMCgRWhUE/XabRppXpUwCwaWBNHe5iPXhdvP8wwDGpGpsIf/kxX/ec3zFsOaM1Oq8lEhUqDwk6W7DHkwg== } + outvariant@1.4.3: + resolution: + { + integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA== + } + p-limit@2.3.0: resolution: { @@ -4714,6 +6280,13 @@ packages: integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== } + parent-module@1.0.1: + resolution: + { + integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + } + engines: { node: ">=6" } + parse-json@5.2.0: resolution: { @@ -4721,6 +6294,13 @@ packages: } engines: { node: ">=8" } + parse-ms@4.0.0: + resolution: + { + integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw== + } + engines: { node: ">=18" } + parseurl@1.3.3: resolution: { @@ -4756,6 +6336,12 @@ packages: } engines: { node: ">= 0.4.0" } + path-browserify@1.0.1: + resolution: + { + integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + } + path-exists@4.0.0: resolution: { @@ -4784,6 +6370,13 @@ packages: } engines: { node: ">=8" } + path-key@4.0.0: + resolution: + { + integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + } + engines: { node: ">=12" } + path-parse@1.0.7: resolution: { @@ -4797,6 +6390,12 @@ packages: } engines: { node: ">=16 || 14 >=14.18" } + path-to-regexp@6.3.0: + resolution: + { + integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== + } + path-to-regexp@8.4.2: resolution: { @@ -4899,6 +6498,13 @@ packages: } engines: { node: ">=12" } + pify@2.3.0: + resolution: + { + integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + } + engines: { node: ">=0.10.0" } + pirates@4.0.7: resolution: { @@ -4906,6 +6512,13 @@ packages: } engines: { node: ">= 6" } + pkce-challenge@5.0.1: + resolution: + { + integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ== + } + engines: { node: ">=16.20.0" } + pkg-dir@4.2.0: resolution: { @@ -4919,6 +6532,75 @@ packages: integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig== } + postcss-import@15.1.0: + resolution: + { + integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + } + engines: { node: ">=14.0.0" } + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: + { + integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw== + } + engines: { node: ^12 || ^14 || >= 16 } + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@4.0.2: + resolution: + { + integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ== + } + engines: { node: ">= 14" } + peerDependencies: + postcss: ">=8.0.9" + ts-node: ">=9.0.0" + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-nested@6.2.0: + resolution: + { + integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ== + } + engines: { node: ">=12.0" } + peerDependencies: + postcss: ^8.2.14 + + postcss-selector-parser@6.1.2: + resolution: + { + integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== + } + engines: { node: ">=4" } + + postcss-selector-parser@7.1.1: + resolution: + { + integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg== + } + engines: { node: ">=4" } + + postcss-value-parser@4.2.0: + resolution: + { + integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + } + + postcss@8.5.8: + resolution: + { + integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg== + } + engines: { node: ^10 || ^12 || >=14 } + postgres-array@2.0.0: resolution: { @@ -4961,6 +6643,13 @@ packages: } engines: { node: ">=12" } + powershell-utils@0.1.0: + resolution: + { + integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A== + } + engines: { node: ">=20" } + prelude-ls@1.2.1: resolution: { @@ -4983,6 +6672,13 @@ packages: } engines: { node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0 } + pretty-ms@9.3.0: + resolution: + { + integrity: sha512-gjVS5hOP+M3wMm5nmNOucbIrqudzs9v/57bWRHQWLYklXqoXKrVfYW2W9+glfGsqtPgpiz5WwyEEB+ksXIx3gQ== + } + engines: { node: ">=18" } + prisma@7.6.0: resolution: { @@ -4999,6 +6695,13 @@ packages: typescript: optional: true + prompts@2.4.2: + resolution: + { + integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + } + engines: { node: ">= 6" } + proper-lockfile@4.1.2: resolution: { @@ -5038,6 +6741,12 @@ packages: } engines: { node: ">=0.6" } + queue-microtask@1.2.3: + resolution: + { + integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + } + range-parser@1.2.1: resolution: { @@ -5072,6 +6781,29 @@ packages: integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== } + react-router-dom@7.14.0: + resolution: + { + integrity: sha512-2G3ajSVSZMEtmTjIklRWlNvo8wICEpLihfD/0YMDxbWK2UyP5EGfnoIn9AIQGnF3G/FX0MRbHXdFcD+rL1ZreQ== + } + engines: { node: ">=20.0.0" } + peerDependencies: + react: ">=18" + react-dom: ">=18" + + react-router@7.14.0: + resolution: + { + integrity: sha512-m/xR9N4LQLmAS0ZhkY2nkPA1N7gQ5TUVa5n8TgANuDTARbn1gt+zLPXEm7W0XDTbrQ2AJSJKhoa6yx1D8BcpxQ== + } + engines: { node: ">=20.0.0" } + peerDependencies: + react: ">=18" + react-dom: ">=18" + peerDependenciesMeta: + react-dom: + optional: true + react@19.2.4: resolution: { @@ -5079,6 +6811,12 @@ packages: } engines: { node: ">=0.10.0" } + read-cache@1.0.0: + resolution: + { + integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + } + readable-stream@3.6.2: resolution: { @@ -5100,6 +6838,13 @@ packages: } engines: { node: ">= 14.18.0" } + recast@0.23.11: + resolution: + { + integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA== + } + engines: { node: ">= 4" } + reflect-metadata@0.2.2: resolution: { @@ -5126,6 +6871,12 @@ packages: } engines: { node: ">=0.10.0" } + reselect@5.1.1: + resolution: + { + integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w== + } + resolve-cwd@3.0.0: resolution: { @@ -5133,6 +6884,13 @@ packages: } engines: { node: ">=8" } + resolve-from@4.0.0: + resolution: + { + integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + } + engines: { node: ">=4" } + resolve-from@5.0.0: resolution: { @@ -5162,6 +6920,19 @@ packages: } engines: { node: ">= 4" } + rettime@0.10.1: + resolution: + { + integrity: sha512-uyDrIlUEH37cinabq0AX4QbgV4HbFZ/gqoiunWQ1UqBtRvTTytwhNYjE++pO/MjPTZL5KQCf2bEoJ/BJNVQ5Kw== + } + + reusify@1.1.0: + resolution: + { + integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== + } + engines: { iojs: ">=1.0.0", node: ">=0.10.0" } + rfdc@1.4.1: resolution: { @@ -5176,6 +6947,14 @@ packages: deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true + rolldown@1.0.0-rc.12: + resolution: + { + integrity: sha512-yP4USLIMYrwpPHEFB5JGH1uxhcslv6/hL0OyvTuY+3qlOSJvZ7ntYnoWpehBxufkgN0cvXxppuTu5hHa/zPh+A== + } + engines: { node: ^20.19.0 || >=22.12.0 } + hasBin: true + router@2.2.0: resolution: { @@ -5183,6 +6962,19 @@ packages: } engines: { node: ">= 18" } + run-applescript@7.1.0: + resolution: + { + integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q== + } + engines: { node: ">=18" } + + run-parallel@1.2.0: + resolution: + { + integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + } + rxjs@7.8.2: resolution: { @@ -5242,12 +7034,25 @@ packages: } engines: { node: ">= 18" } + set-cookie-parser@2.7.2: + resolution: + { + integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw== + } + setprototypeof@1.2.0: resolution: { integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== } + shadcn@4.1.2: + resolution: + { + integrity: sha512-qNQcCavkbYsgBj+X09tF2bTcwRd8abR880bsFkDU2kMqceMCLAm5c+cLg7kWDhfh1H9g08knpQ5ZEf6y/co16g== + } + hasBin: true + shebang-command@2.0.0: resolution: { @@ -5330,6 +7135,13 @@ packages: } engines: { node: ">=20" } + source-map-js@1.2.1: + resolution: + { + integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + } + engines: { node: ">=0.10.0" } + source-map-support@0.5.13: resolution: { @@ -5389,6 +7201,13 @@ packages: integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg== } + stdin-discarder@0.2.2: + resolution: + { + integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ== + } + engines: { node: ">=18" } + streamsearch@1.1.0: resolution: { @@ -5396,6 +7215,12 @@ packages: } engines: { node: ">=10.0.0" } + strict-event-emitter@0.5.1: + resolution: + { + integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ== + } + string-argv@0.3.2: resolution: { @@ -5444,6 +7269,13 @@ packages: integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== } + stringify-object@5.0.0: + resolution: + { + integrity: sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg== + } + engines: { node: ">=14.16" } + strip-ansi@6.0.1: resolution: { @@ -5479,6 +7311,13 @@ packages: } engines: { node: ">=6" } + strip-final-newline@4.0.0: + resolution: + { + integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw== + } + engines: { node: ">=18" } + strip-json-comments@2.0.1: resolution: { @@ -5506,6 +7345,14 @@ packages: } engines: { node: ">=18" } + sucrase@3.35.1: + resolution: + { + integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw== + } + engines: { node: ">=16 || 14 >=14.17" } + hasBin: true + superagent@10.3.0: resolution: { @@ -5548,6 +7395,33 @@ packages: } engines: { node: ^14.18.0 || >=16.0.0 } + tabbable@6.4.0: + resolution: + { + integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg== + } + + tagged-tag@1.0.0: + resolution: + { + integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng== + } + engines: { node: ">=20" } + + tailwind-merge@3.5.0: + resolution: + { + integrity: sha512-I8K9wewnVDkL1NTGoqWmVEIlUcB9gFriAEkXkfCjX5ib8ezGxtR3xD7iZIxrfArjEsH7F1CHD4RFUtxefdqV/A== + } + + tailwindcss@3.4.17: + resolution: + { + integrity: sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og== + } + engines: { node: ">=14.0.0" } + hasBin: true + test-exclude@6.0.0: resolution: { @@ -5555,6 +7429,19 @@ packages: } engines: { node: ">=8" } + thenify-all@1.6.0: + resolution: + { + integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + } + engines: { node: ">=0.8" } + + thenify@3.3.1: + resolution: + { + integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + } + thirty-two@1.0.2: resolution: { @@ -5562,6 +7449,12 @@ packages: } engines: { node: ">=0.2.6" } + tiny-invariant@1.3.3: + resolution: + { + integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== + } + tinyexec@1.0.4: resolution: { @@ -5569,6 +7462,26 @@ packages: } engines: { node: ">=18" } + tinyglobby@0.2.15: + resolution: + { + integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== + } + engines: { node: ">=12.0.0" } + + tldts-core@7.0.27: + resolution: + { + integrity: sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg== + } + + tldts@7.0.27: + resolution: + { + integrity: sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg== + } + hasBin: true + tmpl@1.0.5: resolution: { @@ -5596,6 +7509,13 @@ packages: } engines: { node: ">=14.16" } + tough-cookie@6.0.1: + resolution: + { + integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw== + } + engines: { node: ">=16" } + tree-kill@1.2.2: resolution: { @@ -5603,6 +7523,21 @@ packages: } hasBin: true + ts-api-utils@2.5.0: + resolution: + { + integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA== + } + engines: { node: ">=18.12" } + peerDependencies: + typescript: ">=4.8.4" + + ts-interface-checker@0.1.13: + resolution: + { + integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + } + ts-jest@29.4.9: resolution: { @@ -5633,6 +7568,12 @@ packages: jest-util: optional: true + ts-morph@26.0.0: + resolution: + { + integrity: sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug== + } + ts-node-dev@2.0.0: resolution: { @@ -5664,6 +7605,13 @@ packages: "@swc/wasm": optional: true + tsconfig-paths@4.2.0: + resolution: + { + integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + } + engines: { node: ">=6" } + tsconfig@7.0.0: resolution: { @@ -5683,6 +7631,12 @@ packages: } hasBin: true + tw-animate-css@1.4.0: + resolution: + { + integrity: sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ== + } + type-check@0.4.0: resolution: { @@ -5711,6 +7665,13 @@ packages: } engines: { node: ">=16" } + type-fest@5.5.0: + resolution: + { + integrity: sha512-PlBfpQwiUvGViBNX84Yxwjsdhd1TUlXr6zjX7eoirtCPIr08NAmxwa+fcYBTeRQxHo9YC9wwF3m9i700sHma8g== + } + engines: { node: ">=20" } + type-is@1.6.18: resolution: { @@ -5731,6 +7692,16 @@ packages: integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== } + typescript-eslint@8.58.0: + resolution: + { + integrity: sha512-e2TQzKfaI85fO+F3QywtX+tCTsu/D3WW5LVU6nz8hTFKFZ8yBJ6mSYRpXqdR3mFjPWmO0eWsTa5f+UpAOe/FMA== + } + engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + typescript@5.9.3: resolution: { @@ -5767,12 +7738,32 @@ packages: } engines: { node: ">=18" } + undici-types@7.16.0: + resolution: + { + integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== + } + undici-types@7.18.2: resolution: { integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w== } + unicorn-magic@0.3.0: + resolution: + { + integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA== + } + engines: { node: ">=18" } + + universalify@2.0.1: + resolution: + { + integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + } + engines: { node: ">= 10.0.0" } + unpipe@1.0.0: resolution: { @@ -5786,6 +7777,12 @@ packages: integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg== } + until-async@3.0.2: + resolution: + { + integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw== + } + update-browserslist-db@1.2.3: resolution: { @@ -5801,6 +7798,14 @@ packages: integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== } + use-sync-external-store@1.6.0: + resolution: + { + integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== + } + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + util-deprecate@1.0.2: resolution: { @@ -5838,6 +7843,13 @@ packages: typescript: optional: true + validate-npm-package-name@7.0.2: + resolution: + { + integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A== + } + engines: { node: ^20.17.0 || >=22.9.0 } + validator@13.15.35: resolution: { @@ -5852,12 +7864,65 @@ packages: } engines: { node: ">= 0.8" } + vite@8.0.3: + resolution: + { + integrity: sha512-B9ifbFudT1TFhfltfaIPgjo9Z3mDynBTJSUYxTjOQruf/zHH+ezCQKcoqO+h7a9Pw9Nm/OtlXAiGT1axBgwqrQ== + } + engines: { node: ^20.19.0 || >=22.12.0 } + hasBin: true + peerDependencies: + "@types/node": ^20.19.0 || >=22.12.0 + "@vitejs/devtools": ^0.1.0 + esbuild: ^0.27.0 + jiti: ">=1.21.0" + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: ">=0.54.8" + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + "@types/node": + optional: true + "@vitejs/devtools": + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + walker@1.0.8: resolution: { integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== } + web-streams-polyfill@3.3.3: + resolution: + { + integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== + } + engines: { node: ">= 8" } + which@2.0.2: resolution: { @@ -5866,6 +7931,14 @@ packages: engines: { node: ">= 8" } hasBin: true + which@4.0.0: + resolution: + { + integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg== + } + engines: { node: ^16.13.0 || >=18.0.0 } + hasBin: true + word-wrap@1.2.5: resolution: { @@ -5879,6 +7952,13 @@ packages: integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== } + wrap-ansi@6.2.0: + resolution: + { + integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + } + engines: { node: ">=8" } + wrap-ansi@7.0.0: resolution: { @@ -5913,6 +7993,13 @@ packages: } engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } + wsl-utils@0.3.1: + resolution: + { + integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg== + } + engines: { node: ">=20" } + xtend@4.0.2: resolution: { @@ -5969,13 +8056,58 @@ packages: } engines: { node: ">=10" } + yoctocolors-cjs@2.1.3: + resolution: + { + integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw== + } + engines: { node: ">=18" } + + yoctocolors@2.1.2: + resolution: + { + integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug== + } + engines: { node: ">=18" } + zeptomatch@2.1.0: resolution: { integrity: sha512-KiGErG2J0G82LSpniV0CtIzjlJ10E04j02VOudJsPyPwNZgGnRKQy7I1R7GMyg/QswnE4l7ohSGrQbQbjXPPDA== } + zod-to-json-schema@3.25.2: + resolution: + { + integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA== + } + peerDependencies: + zod: ^3.25.28 || ^4 + + zod-validation-error@4.0.2: + resolution: + { + integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ== + } + engines: { node: ">=18.0.0" } + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@3.25.76: + resolution: + { + integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ== + } + + zod@4.3.6: + resolution: + { + integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg== + } + snapshots: + "@alloc/quick-lru@5.2.0": {} + "@aws-crypto/crc32@5.2.0": dependencies: "@aws-crypto/util": 5.2.0 @@ -6474,6 +8606,10 @@ snapshots: "@jridgewell/trace-mapping": 0.3.31 jsesc: 3.1.0 + "@babel/helper-annotate-as-pure@7.27.3": + dependencies: + "@babel/types": 7.29.0 + "@babel/helper-compilation-targets@7.28.6": dependencies: "@babel/compat-data": 7.29.0 @@ -6482,8 +8618,28 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 + "@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)": + dependencies: + "@babel/core": 7.29.0 + "@babel/helper-annotate-as-pure": 7.27.3 + "@babel/helper-member-expression-to-functions": 7.28.5 + "@babel/helper-optimise-call-expression": 7.27.1 + "@babel/helper-replace-supers": 7.28.6(@babel/core@7.29.0) + "@babel/helper-skip-transparent-expression-wrappers": 7.27.1 + "@babel/traverse": 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + "@babel/helper-globals@7.28.0": {} + "@babel/helper-member-expression-to-functions@7.28.5": + dependencies: + "@babel/traverse": 7.29.0 + "@babel/types": 7.29.0 + transitivePeerDependencies: + - supports-color + "@babel/helper-module-imports@7.28.6": dependencies: "@babel/traverse": 7.29.0 @@ -6500,8 +8656,28 @@ snapshots: transitivePeerDependencies: - supports-color + "@babel/helper-optimise-call-expression@7.27.1": + dependencies: + "@babel/types": 7.29.0 + "@babel/helper-plugin-utils@7.28.6": {} + "@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)": + dependencies: + "@babel/core": 7.29.0 + "@babel/helper-member-expression-to-functions": 7.28.5 + "@babel/helper-optimise-call-expression": 7.27.1 + "@babel/traverse": 7.29.0 + transitivePeerDependencies: + - supports-color + + "@babel/helper-skip-transparent-expression-wrappers@7.27.1": + dependencies: + "@babel/traverse": 7.29.0 + "@babel/types": 7.29.0 + transitivePeerDependencies: + - supports-color + "@babel/helper-string-parser@7.27.1": {} "@babel/helper-validator-identifier@7.28.5": {} @@ -6602,6 +8778,38 @@ snapshots: "@babel/core": 7.29.0 "@babel/helper-plugin-utils": 7.28.6 + "@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)": + dependencies: + "@babel/core": 7.29.0 + "@babel/helper-module-transforms": 7.28.6(@babel/core@7.29.0) + "@babel/helper-plugin-utils": 7.28.6 + transitivePeerDependencies: + - supports-color + + "@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)": + dependencies: + "@babel/core": 7.29.0 + "@babel/helper-annotate-as-pure": 7.27.3 + "@babel/helper-create-class-features-plugin": 7.28.6(@babel/core@7.29.0) + "@babel/helper-plugin-utils": 7.28.6 + "@babel/helper-skip-transparent-expression-wrappers": 7.27.1 + "@babel/plugin-syntax-typescript": 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + "@babel/preset-typescript@7.28.5(@babel/core@7.29.0)": + dependencies: + "@babel/core": 7.29.0 + "@babel/helper-plugin-utils": 7.28.6 + "@babel/helper-validator-option": 7.27.1 + "@babel/plugin-syntax-jsx": 7.28.6(@babel/core@7.29.0) + "@babel/plugin-transform-modules-commonjs": 7.28.6(@babel/core@7.29.0) + "@babel/plugin-transform-typescript": 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + "@babel/runtime@7.29.2": {} + "@babel/template@7.28.6": dependencies: "@babel/code-frame": 7.29.0 @@ -6625,6 +8833,30 @@ snapshots: "@babel/helper-string-parser": 7.27.1 "@babel/helper-validator-identifier": 7.28.5 + "@base-ui/react@1.3.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": + dependencies: + "@babel/runtime": 7.29.2 + "@base-ui/utils": 0.2.6(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + "@floating-ui/react-dom": 2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + "@floating-ui/utils": 0.2.11 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + tabbable: 6.4.0 + use-sync-external-store: 1.6.0(react@19.2.4) + optionalDependencies: + "@types/react": 19.2.14 + + "@base-ui/utils@0.2.6(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": + dependencies: + "@babel/runtime": 7.29.2 + "@floating-ui/utils": 0.2.11 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + reselect: 5.1.1 + use-sync-external-store: 1.6.0(react@19.2.4) + optionalDependencies: + "@types/react": 19.2.14 + "@bcoe/v8-coverage@0.2.3": {} "@borewit/text-codec@0.2.2": {} @@ -6644,6 +8876,22 @@ snapshots: dependencies: "@jridgewell/trace-mapping": 0.3.9 + "@dotenvx/dotenvx@1.59.1": + dependencies: + commander: 11.1.0 + dotenv: 17.2.3 + eciesjs: 0.4.18 + execa: 5.1.1 + fdir: 6.5.0(picomatch@4.0.4) + ignore: 5.3.2 + object-treeify: 1.1.33 + picomatch: 4.0.4 + which: 4.0.0 + + "@ecies/ciphers@0.2.6(@noble/ciphers@1.3.0)": + dependencies: + "@noble/ciphers": 1.3.0 + "@electric-sql/pglite-socket@0.1.1(@electric-sql/pglite@0.4.1)": dependencies: "@electric-sql/pglite": 0.4.1 @@ -6675,8 +8923,21 @@ snapshots: eslint: 10.2.0(jiti@2.6.1) eslint-visitor-keys: 3.4.3 + "@eslint-community/eslint-utils@4.9.1(eslint@9.39.4(jiti@2.6.1))": + dependencies: + eslint: 9.39.4(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + "@eslint-community/regexpp@4.12.2": {} + "@eslint/config-array@0.21.2": + dependencies: + "@eslint/object-schema": 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + "@eslint/config-array@0.23.4": dependencies: "@eslint/object-schema": 3.0.4 @@ -6685,25 +8946,75 @@ snapshots: transitivePeerDependencies: - supports-color + "@eslint/config-helpers@0.4.2": + dependencies: + "@eslint/core": 0.17.0 + "@eslint/config-helpers@0.5.4": dependencies: "@eslint/core": 1.2.0 + "@eslint/core@0.17.0": + dependencies: + "@types/json-schema": 7.0.15 + "@eslint/core@1.2.0": dependencies: "@types/json-schema": 7.0.15 + "@eslint/eslintrc@3.3.5": + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + "@eslint/js@10.0.1(eslint@10.2.0(jiti@2.6.1))": optionalDependencies: eslint: 10.2.0(jiti@2.6.1) + "@eslint/js@9.39.4": {} + + "@eslint/object-schema@2.1.7": {} + "@eslint/object-schema@3.0.4": {} + "@eslint/plugin-kit@0.4.1": + dependencies: + "@eslint/core": 0.17.0 + levn: 0.4.1 + "@eslint/plugin-kit@0.7.0": dependencies: "@eslint/core": 1.2.0 levn: 0.4.1 + "@floating-ui/core@1.7.5": + dependencies: + "@floating-ui/utils": 0.2.11 + + "@floating-ui/dom@1.7.6": + dependencies: + "@floating-ui/core": 1.7.5 + "@floating-ui/utils": 0.2.11 + + "@floating-ui/react-dom@2.1.8(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": + dependencies: + "@floating-ui/dom": 1.7.6 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + + "@floating-ui/utils@0.2.11": {} + + "@fontsource-variable/geist@5.2.8": {} + "@hono/node-server@1.19.11(hono@4.12.10)": dependencies: hono: 4.12.10 @@ -6719,6 +9030,34 @@ snapshots: "@humanwhocodes/retry@0.4.3": {} + "@inquirer/ansi@1.0.2": {} + + "@inquirer/confirm@5.1.21(@types/node@24.12.2)": + dependencies: + "@inquirer/core": 10.3.2(@types/node@24.12.2) + "@inquirer/type": 3.0.10(@types/node@24.12.2) + optionalDependencies: + "@types/node": 24.12.2 + + "@inquirer/core@10.3.2(@types/node@24.12.2)": + dependencies: + "@inquirer/ansi": 1.0.2 + "@inquirer/figures": 1.0.15 + "@inquirer/type": 3.0.10(@types/node@24.12.2) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + "@types/node": 24.12.2 + + "@inquirer/figures@1.0.15": {} + + "@inquirer/type@3.0.10(@types/node@24.12.2)": + optionalDependencies: + "@types/node": 24.12.2 + "@isaacs/cliui@8.0.2": dependencies: string-width: 5.1.2 @@ -6943,6 +9282,37 @@ snapshots: "@lukeed/csprng@1.1.0": {} + "@modelcontextprotocol/sdk@1.29.0(zod@3.25.76)": + dependencies: + "@hono/node-server": 1.19.11(hono@4.12.10) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.3.2(express@5.2.1) + hono: 4.12.10 + jose: 6.2.2 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 3.25.76 + zod-to-json-schema: 3.25.2(zod@3.25.76) + transitivePeerDependencies: + - supports-color + + "@mswjs/interceptors@0.41.3": + dependencies: + "@open-draft/deferred-promise": 2.2.0 + "@open-draft/logger": 0.3.0 + "@open-draft/until": 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + "@napi-rs/wasm-runtime@0.2.12": dependencies: "@emnapi/core": 1.9.2 @@ -6950,6 +9320,13 @@ snapshots: "@tybys/wasm-util": 0.10.1 optional: true + "@napi-rs/wasm-runtime@1.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)": + dependencies: + "@emnapi/core": 1.9.2 + "@emnapi/runtime": 1.9.2 + "@tybys/wasm-util": 0.10.1 + optional: true + "@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)": dependencies: file-type: 21.3.4 @@ -7018,14 +9395,41 @@ snapshots: optionalDependencies: "@nestjs/platform-express": 11.1.18(@nestjs/common@11.1.18(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.18) + "@noble/ciphers@1.3.0": {} + + "@noble/curves@1.9.7": + dependencies: + "@noble/hashes": 1.8.0 + "@noble/hashes@1.8.0": {} "@noble/hashes@2.0.1": {} + "@nodelib/fs.scandir@2.1.5": + dependencies: + "@nodelib/fs.stat": 2.0.5 + run-parallel: 1.2.0 + + "@nodelib/fs.stat@2.0.5": {} + + "@nodelib/fs.walk@1.2.8": + dependencies: + "@nodelib/fs.scandir": 2.1.5 + fastq: 1.20.1 + "@nuxt/opencollective@0.4.1": dependencies: consola: 3.4.2 + "@open-draft/deferred-promise@2.2.0": {} + + "@open-draft/logger@0.3.0": + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + "@open-draft/until@2.1.0": {} + "@otplib/core@12.0.1": {} "@otplib/core@13.4.0": {} @@ -7070,6 +9474,8 @@ snapshots: dependencies: "@otplib/core": 13.4.0 + "@oxc-project/types@0.122.0": {} + "@paralleldrive/cuid2@2.3.1": dependencies: "@noble/hashes": 1.8.0 @@ -7090,11 +9496,11 @@ snapshots: "@prisma/client-runtime-utils@7.6.0": {} - "@prisma/client@7.6.0(prisma@7.6.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3)": + "@prisma/client@7.6.0(prisma@7.6.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3)": dependencies: "@prisma/client-runtime-utils": 7.6.0 optionalDependencies: - prisma: 7.6.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) + prisma: 7.6.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) typescript: 5.9.3 "@prisma/config@7.6.0": @@ -7168,9 +9574,9 @@ snapshots: env-paths: 3.0.0 proper-lockfile: 4.1.2 - "@prisma/studio-core@0.27.3(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": + "@prisma/studio-core@0.27.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": dependencies: - "@radix-ui/react-toggle": 1.1.10(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + "@radix-ui/react-toggle": 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) "@types/react": 19.2.14 chart.js: 4.5.1 react: 19.2.4 @@ -7186,13 +9592,14 @@ snapshots: optionalDependencies: "@types/react": 19.2.14 - "@radix-ui/react-primitive@2.1.3(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": + "@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": dependencies: "@radix-ui/react-slot": 1.2.3(@types/react@19.2.14)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: "@types/react": 19.2.14 + "@types/react-dom": 19.2.3(@types/react@19.2.14) "@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.4)": dependencies: @@ -7201,15 +9608,16 @@ snapshots: optionalDependencies: "@types/react": 19.2.14 - "@radix-ui/react-toggle@1.1.10(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": + "@radix-ui/react-toggle@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)": dependencies: "@radix-ui/primitive": 1.1.3 - "@radix-ui/react-primitive": 2.1.3(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + "@radix-ui/react-primitive": 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) "@radix-ui/react-use-controllable-state": 1.2.2(@types/react@19.2.14)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) optionalDependencies: "@types/react": 19.2.14 + "@types/react-dom": 19.2.3(@types/react@19.2.14) "@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.4)": dependencies: @@ -7232,10 +9640,68 @@ snapshots: optionalDependencies: "@types/react": 19.2.14 + "@rolldown/binding-android-arm64@1.0.0-rc.12": + optional: true + + "@rolldown/binding-darwin-arm64@1.0.0-rc.12": + optional: true + + "@rolldown/binding-darwin-x64@1.0.0-rc.12": + optional: true + + "@rolldown/binding-freebsd-x64@1.0.0-rc.12": + optional: true + + "@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.12": + optional: true + + "@rolldown/binding-linux-arm64-gnu@1.0.0-rc.12": + optional: true + + "@rolldown/binding-linux-arm64-musl@1.0.0-rc.12": + optional: true + + "@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.12": + optional: true + + "@rolldown/binding-linux-s390x-gnu@1.0.0-rc.12": + optional: true + + "@rolldown/binding-linux-x64-gnu@1.0.0-rc.12": + optional: true + + "@rolldown/binding-linux-x64-musl@1.0.0-rc.12": + optional: true + + "@rolldown/binding-openharmony-arm64@1.0.0-rc.12": + optional: true + + "@rolldown/binding-wasm32-wasi@1.0.0-rc.12(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)": + dependencies: + "@napi-rs/wasm-runtime": 1.1.2(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + transitivePeerDependencies: + - "@emnapi/core" + - "@emnapi/runtime" + optional: true + + "@rolldown/binding-win32-arm64-msvc@1.0.0-rc.12": + optional: true + + "@rolldown/binding-win32-x64-msvc@1.0.0-rc.12": + optional: true + + "@rolldown/pluginutils@1.0.0-rc.12": {} + + "@rolldown/pluginutils@1.0.0-rc.7": {} + "@scure/base@2.0.0": {} + "@sec-ant/readable-stream@0.4.1": {} + "@sinclair/typebox@0.34.49": {} + "@sindresorhus/merge-streams@4.0.0": {} + "@sinonjs/commons@3.0.1": dependencies: type-detect: 4.0.8 @@ -7587,6 +10053,12 @@ snapshots: "@tokenizer/token@0.3.0": {} + "@ts-morph/common@0.27.0": + dependencies: + fast-glob: 3.3.3 + minimatch: 10.2.5 + path-browserify: 1.0.1 + "@tsconfig/node10@1.0.12": {} "@tsconfig/node12@1.0.11": {} @@ -7695,10 +10167,18 @@ snapshots: "@types/ms@2.1.0": {} + "@types/node@24.12.2": + dependencies: + undici-types: 7.16.0 + "@types/node@25.5.2": dependencies: undici-types: 7.18.2 + "@types/nodemailer@8.0.0": + dependencies: + "@types/node": 25.5.2 + "@types/oauth@0.9.6": dependencies: "@types/node": 25.5.2 @@ -7729,6 +10209,10 @@ snapshots: "@types/range-parser@1.2.7": {} + "@types/react-dom@19.2.3(@types/react@19.2.14)": + dependencies: + "@types/react": 19.2.14 + "@types/react@19.2.14": dependencies: csstype: 3.2.3 @@ -7744,6 +10228,8 @@ snapshots: "@types/stack-utils@2.0.3": {} + "@types/statuses@2.0.6": {} + "@types/strip-bom@3.0.0": {} "@types/strip-json-comments@0.0.30": {} @@ -7760,6 +10246,8 @@ snapshots: "@types/methods": 1.1.4 "@types/superagent": 8.1.9 + "@types/validate-npm-package-name@4.0.2": {} + "@types/validator@13.15.10": {} "@types/yargs-parser@21.0.3": {} @@ -7768,6 +10256,97 @@ snapshots: dependencies: "@types/yargs-parser": 21.0.3 + "@typescript-eslint/eslint-plugin@8.58.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)": + dependencies: + "@eslint-community/regexpp": 4.12.2 + "@typescript-eslint/parser": 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + "@typescript-eslint/scope-manager": 8.58.0 + "@typescript-eslint/type-utils": 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + "@typescript-eslint/utils": 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + "@typescript-eslint/visitor-keys": 8.58.0 + eslint: 9.39.4(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)": + dependencies: + "@typescript-eslint/scope-manager": 8.58.0 + "@typescript-eslint/types": 8.58.0 + "@typescript-eslint/typescript-estree": 8.58.0(typescript@5.9.3) + "@typescript-eslint/visitor-keys": 8.58.0 + debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/project-service@8.58.0(typescript@5.9.3)": + dependencies: + "@typescript-eslint/tsconfig-utils": 8.58.0(typescript@5.9.3) + "@typescript-eslint/types": 8.58.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/scope-manager@8.58.0": + dependencies: + "@typescript-eslint/types": 8.58.0 + "@typescript-eslint/visitor-keys": 8.58.0 + + "@typescript-eslint/tsconfig-utils@8.58.0(typescript@5.9.3)": + dependencies: + typescript: 5.9.3 + + "@typescript-eslint/type-utils@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)": + dependencies: + "@typescript-eslint/types": 8.58.0 + "@typescript-eslint/typescript-estree": 8.58.0(typescript@5.9.3) + "@typescript-eslint/utils": 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/types@8.58.0": {} + + "@typescript-eslint/typescript-estree@8.58.0(typescript@5.9.3)": + dependencies: + "@typescript-eslint/project-service": 8.58.0(typescript@5.9.3) + "@typescript-eslint/tsconfig-utils": 8.58.0(typescript@5.9.3) + "@typescript-eslint/types": 8.58.0 + "@typescript-eslint/visitor-keys": 8.58.0 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.7.4 + tinyglobby: 0.2.15 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/utils@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3)": + dependencies: + "@eslint-community/eslint-utils": 4.9.1(eslint@9.39.4(jiti@2.6.1)) + "@typescript-eslint/scope-manager": 8.58.0 + "@typescript-eslint/types": 8.58.0 + "@typescript-eslint/typescript-estree": 8.58.0(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + "@typescript-eslint/visitor-keys@8.58.0": + dependencies: + "@typescript-eslint/types": 8.58.0 + eslint-visitor-keys: 5.0.1 + "@ungap/structured-clone@1.3.0": {} "@unrs/resolver-binding-android-arm-eabi@1.11.1": @@ -7829,6 +10408,11 @@ snapshots: "@unrs/resolver-binding-win32-x64-msvc@1.11.1": optional: true + "@vitejs/plugin-react@6.0.1(vite@8.0.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.12.2)(jiti@2.6.1)(yaml@2.8.3))": + dependencies: + "@rolldown/pluginutils": 1.0.0-rc.7 + vite: 8.0.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.12.2)(jiti@2.6.1)(yaml@2.8.3) + accepts@2.0.0: dependencies: mime-types: 3.0.2 @@ -7844,6 +10428,12 @@ snapshots: acorn@8.16.0: {} + agent-base@7.1.4: {} + + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + ajv@6.14.0: dependencies: fast-deep-equal: 3.1.3 @@ -7878,6 +10468,8 @@ snapshots: ansi-styles@6.2.3: {} + any-promise@1.3.0: {} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 @@ -7887,14 +10479,31 @@ snapshots: arg@4.1.3: {} + arg@5.0.2: {} + argparse@1.0.10: dependencies: sprintf-js: 1.0.3 + argparse@2.0.1: {} + asap@2.0.6: {} + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + asynckit@0.4.0: {} + autoprefixer@10.4.27(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001785 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + aws-ssl-profiles@1.1.2: {} babel-jest@30.3.0(@babel/core@7.29.0): @@ -8016,6 +10625,10 @@ snapshots: buffer-from@1.1.2: {} + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 @@ -8049,6 +10662,8 @@ snapshots: callsites@3.1.0: {} + camelcase-css@2.0.1: {} + camelcase@5.3.1: {} camelcase@6.3.0: {} @@ -8060,6 +10675,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.6.2: {} + char-regex@1.0.2: {} chart.js@4.5.1: @@ -8100,23 +10717,35 @@ snapshots: libphonenumber-js: 1.12.41 validator: 13.15.35 + class-variance-authority@0.7.1: + dependencies: + clsx: 2.1.1 + cli-cursor@5.0.0: dependencies: restore-cursor: 5.1.0 + cli-spinners@2.9.2: {} + cli-truncate@5.2.0: dependencies: slice-ansi: 8.0.0 string-width: 8.2.0 + cli-width@4.1.0: {} + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + clsx@2.1.1: {} + co@4.6.0: {} + code-block-writer@13.0.3: {} + collect-v8-coverage@1.0.3: {} color-convert@2.0.1: @@ -8131,8 +10760,12 @@ snapshots: dependencies: delayed-stream: 1.0.0 + commander@11.1.0: {} + commander@14.0.3: {} + commander@4.1.1: {} + component-emitter@1.3.1: {} concat-map@0.0.1: {} @@ -8158,6 +10791,8 @@ snapshots: cookie@0.7.2: {} + cookie@1.1.1: {} + cookiejar@2.1.4: {} cors@2.8.6: @@ -8165,6 +10800,15 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 + cosmiconfig@9.0.1(typescript@5.9.3): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + optionalDependencies: + typescript: 5.9.3 + create-require@1.1.1: {} cross-spawn@7.0.6: @@ -8173,8 +10817,12 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + cssesc@3.0.0: {} + csstype@3.2.3: {} + data-uri-to-buffer@4.0.1: {} + debug@4.4.3: dependencies: ms: 2.1.3 @@ -8187,6 +10835,15 @@ snapshots: deepmerge@4.3.1: {} + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@3.0.0: {} + defu@6.1.6: {} delayed-stream@1.0.0: {} @@ -8197,6 +10854,8 @@ snapshots: destr@2.0.5: {} + detect-libc@2.1.2: {} + detect-newline@3.1.0: {} dezalgo@1.0.4: @@ -8204,8 +10863,14 @@ snapshots: asap: 2.0.6 wrappy: 1.0.2 + didyoumean@1.2.2: {} + diff@4.0.4: {} + diff@8.0.4: {} + + dlv@1.1.3: {} + dotenv-expand@12.0.3: dependencies: dotenv: 16.6.1 @@ -8230,6 +10895,13 @@ snapshots: dependencies: safe-buffer: 5.2.1 + eciesjs@0.4.18: + dependencies: + "@ecies/ciphers": 0.2.6(@noble/ciphers@1.3.0) + "@noble/ciphers": 1.3.0 + "@noble/curves": 1.9.7 + "@noble/hashes": 1.8.0 + ee-first@1.1.1: {} effect@3.20.0: @@ -8251,6 +10923,8 @@ snapshots: encodeurl@2.0.0: {} + env-paths@2.2.1: {} + env-paths@3.0.0: {} environment@1.1.0: {} @@ -8282,6 +10956,26 @@ snapshots: escape-string-regexp@4.0.0: {} + eslint-plugin-react-hooks@7.0.1(eslint@9.39.4(jiti@2.6.1)): + dependencies: + "@babel/core": 7.29.0 + "@babel/parser": 7.29.2 + eslint: 9.39.4(jiti@2.6.1) + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-refresh@0.5.2(eslint@9.39.4(jiti@2.6.1)): + dependencies: + eslint: 9.39.4(jiti@2.6.1) + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + eslint-scope@9.1.2: dependencies: "@types/esrecurse": 4.3.1 @@ -8291,6 +10985,8 @@ snapshots: eslint-visitor-keys@3.4.3: {} + eslint-visitor-keys@4.2.1: {} + eslint-visitor-keys@5.0.1: {} eslint@10.2.0(jiti@2.6.1): @@ -8330,6 +11026,53 @@ snapshots: transitivePeerDependencies: - supports-color + eslint@9.39.4(jiti@2.6.1): + dependencies: + "@eslint-community/eslint-utils": 4.9.1(eslint@9.39.4(jiti@2.6.1)) + "@eslint-community/regexpp": 4.12.2 + "@eslint/config-array": 0.21.2 + "@eslint/config-helpers": 0.4.2 + "@eslint/core": 0.17.0 + "@eslint/eslintrc": 3.3.5 + "@eslint/js": 9.39.4 + "@eslint/plugin-kit": 0.4.1 + "@humanfs/node": 0.16.7 + "@humanwhocodes/module-importer": 1.0.1 + "@humanwhocodes/retry": 0.4.3 + "@types/estree": 1.0.8 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + espree@11.2.0: dependencies: acorn: 8.16.0 @@ -8354,6 +11097,12 @@ snapshots: eventemitter3@5.0.4: {} + eventsource-parser@3.0.6: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.6 + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -8366,6 +11115,21 @@ snapshots: signal-exit: 3.0.7 strip-final-newline: 2.0.0 + execa@9.6.1: + dependencies: + "@sindresorhus/merge-streams": 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.1.2 + exit-x@0.2.2: {} expect@30.3.0: @@ -8377,6 +11141,11 @@ snapshots: jest-mock: 30.3.0 jest-util: 30.3.0 + express-rate-limit@8.3.2(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.1.0 + express@5.2.1: dependencies: accepts: 2.0.0 @@ -8418,6 +11187,14 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: + dependencies: + "@nodelib/fs.stat": 2.0.5 + "@nodelib/fs.walk": 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + fast-json-stable-stringify@2.1.0: {} fast-levenshtein@2.0.6: {} @@ -8436,10 +11213,27 @@ snapshots: path-expression-matcher: 1.2.1 strnum: 2.2.2 + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + fb-watchman@2.0.2: dependencies: bser: 2.1.1 + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -8498,6 +11292,10 @@ snapshots: hasown: 2.0.2 mime-types: 2.1.35 + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + formidable@3.5.4: dependencies: "@paralleldrive/cuid2": 2.3.1 @@ -8506,8 +11304,16 @@ snapshots: forwarded@0.2.0: {} + fraction.js@5.3.4: {} + fresh@2.0.0: {} + fs-extra@11.3.4: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -8515,6 +11321,8 @@ snapshots: function-bind@1.1.2: {} + fuzzysort@3.1.0: {} + generate-function@2.3.1: dependencies: is-property: 1.0.2 @@ -8538,6 +11346,8 @@ snapshots: hasown: 2.0.2 math-intrinsics: 1.1.0 + get-own-enumerable-keys@1.0.0: {} + get-package-type@0.1.0: {} get-port-please@3.2.0: {} @@ -8549,6 +11359,11 @@ snapshots: get-stream@6.0.1: {} + get-stream@9.0.1: + dependencies: + "@sec-ant/readable-stream": 0.4.1 + is-stream: 4.0.1 + giget@2.0.0: dependencies: citty: 0.1.6 @@ -8584,6 +11399,8 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 + globals@14.0.0: {} + globals@17.4.0: {} gopd@1.2.0: {} @@ -8594,6 +11411,8 @@ snapshots: graphmatch@1.1.1: {} + graphql@16.13.2: {} + handlebars@4.7.9: dependencies: minimist: 1.2.8 @@ -8615,6 +11434,14 @@ snapshots: dependencies: function-bind: 1.1.2 + headers-polyfill@4.0.3: {} + + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + hono@4.12.10: {} html-escaper@2.0.2: {} @@ -8629,8 +11456,17 @@ snapshots: http-status-codes@2.3.0: {} + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + human-signals@2.1.0: {} + human-signals@8.0.1: {} + husky@9.1.7: {} iconv-lite@0.7.2: @@ -8641,6 +11477,13 @@ snapshots: ignore@5.3.2: {} + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + import-local@3.2.0: dependencies: pkg-dir: 4.2.0 @@ -8655,6 +11498,8 @@ snapshots: inherits@2.0.4: {} + ip-address@10.1.0: {} + ipaddr.js@1.9.1: {} is-arrayish@0.2.1: {} @@ -8667,6 +11512,8 @@ snapshots: dependencies: hasown: 2.0.2 + is-docker@3.0.0: {} + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -8681,16 +11528,44 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-in-ssh@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-interactive@2.0.0: {} + + is-node-process@1.2.0: {} + is-number@7.0.0: {} + is-obj@3.0.0: {} + + is-plain-obj@4.1.0: {} + is-promise@4.0.0: {} is-property@1.0.2: {} + is-regexp@3.1.0: {} + is-stream@2.0.1: {} + is-stream@4.0.1: {} + + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.1.0: {} + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + isexe@2.0.0: {} + isexe@3.1.5: {} + istanbul-lib-coverage@3.2.2: {} istanbul-lib-instrument@6.0.3: @@ -9041,8 +11916,12 @@ snapshots: - supports-color - ts-node + jiti@1.21.7: {} + jiti@2.6.1: {} + jose@6.2.2: {} + js-tokens@4.0.0: {} js-yaml@3.14.2: @@ -9050,6 +11929,10 @@ snapshots: argparse: 1.0.10 esprima: 4.0.1 + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -9060,10 +11943,18 @@ snapshots: json-schema-traverse@1.0.0: {} + json-schema-typed@8.0.2: {} + json-stable-stringify-without-jsonify@1.0.1: {} json5@2.2.3: {} + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + jsonwebtoken@9.0.3: dependencies: jws: 4.0.1 @@ -9092,6 +11983,10 @@ snapshots: dependencies: json-buffer: 3.0.1 + kleur@3.0.3: {} + + kleur@4.1.5: {} + leven@3.1.0: {} levn@0.4.1: @@ -9101,6 +11996,57 @@ snapshots: libphonenumber-js@1.12.41: {} + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + lilconfig@3.1.3: {} + lines-and-columns@1.2.4: {} lint-staged@16.4.0: @@ -9145,10 +12091,17 @@ snapshots: lodash.memoize@4.1.2: {} + lodash.merge@4.6.2: {} + lodash.once@4.1.1: {} lodash@4.17.23: {} + log-symbols@6.0.0: + dependencies: + chalk: 5.6.2 + is-unicode-supported: 1.3.0 + log-update@6.1.0: dependencies: ansi-escapes: 7.3.0 @@ -9167,6 +12120,10 @@ snapshots: lru.min@1.1.4: {} + lucide-react@1.7.0(react@19.2.4): + dependencies: + react: 19.2.4 + make-dir@4.0.0: dependencies: semver: 7.7.4 @@ -9187,8 +12144,15 @@ snapshots: merge-stream@2.0.0: {} + merge2@1.4.1: {} + methods@1.1.2: {} + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + mime-db@1.52.0: {} mime-db@1.54.0: {} @@ -9227,6 +12191,31 @@ snapshots: ms@2.1.3: {} + msw@2.12.14(@types/node@24.12.2)(typescript@5.9.3): + dependencies: + "@inquirer/confirm": 5.1.21(@types/node@24.12.2) + "@mswjs/interceptors": 0.41.3 + "@open-draft/deferred-promise": 2.2.0 + "@types/statuses": 2.0.6 + cookie: 1.1.1 + graphql: 16.13.2 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + rettime: 0.10.1 + statuses: 2.0.2 + strict-event-emitter: 0.5.1 + tough-cookie: 6.0.1 + type-fest: 5.5.0 + until-async: 3.0.2 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - "@types/node" + multer@2.1.1: dependencies: append-field: 1.0.0 @@ -9234,6 +12223,8 @@ snapshots: concat-stream: 2.0.0 type-is: 1.6.18 + mute-stream@2.0.0: {} + mysql2@3.15.3: dependencies: aws-ssl-profiles: 1.1.2 @@ -9246,10 +12237,18 @@ snapshots: seq-queue: 0.0.5 sqlstring: 2.3.3 + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + named-placeholders@1.1.6: dependencies: lru.min: 1.1.4 + nanoid@3.3.11: {} + napi-postinstall@0.3.4: {} natural-compare@1.4.0: {} @@ -9258,18 +12257,33 @@ snapshots: neo-async@2.6.2: {} + node-domexception@1.0.0: {} + node-fetch-native@1.6.7: {} + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-int64@0.4.0: {} node-releases@2.0.37: {} + nodemailer@8.0.4: {} + normalize-path@3.0.0: {} npm-run-path@4.0.1: dependencies: path-key: 3.1.1 + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + nypm@0.6.5: dependencies: citty: 0.2.2 @@ -9280,8 +12294,12 @@ snapshots: object-assign@4.1.1: {} + object-hash@3.0.0: {} + object-inspect@1.13.4: {} + object-treeify@1.1.33: {} + ohash@2.0.11: {} on-finished@2.4.1: @@ -9300,6 +12318,15 @@ snapshots: dependencies: mimic-function: 5.0.1 + open@11.0.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.1.0 + wsl-utils: 0.3.1 + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -9309,6 +12336,18 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + ora@8.2.0: + dependencies: + chalk: 5.6.2 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.2.0 + otplib@13.4.0: dependencies: "@otplib/core": 13.4.0 @@ -9318,6 +12357,8 @@ snapshots: "@otplib/totp": 13.4.0 "@otplib/uri": 13.4.0 + outvariant@1.4.3: {} + p-limit@2.3.0: dependencies: p-try: 2.2.0 @@ -9338,6 +12379,10 @@ snapshots: package-json-from-dist@1.0.1: {} + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + parse-json@5.2.0: dependencies: "@babel/code-frame": 7.29.0 @@ -9345,6 +12390,8 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-ms@4.0.0: {} + parseurl@1.3.3: {} passport-github2@0.1.12: @@ -9367,6 +12414,8 @@ snapshots: pause: 0.0.1 utils-merge: 1.0.1 + path-browserify@1.0.1: {} + path-exists@4.0.0: {} path-expression-matcher@1.2.1: {} @@ -9375,6 +12424,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-scurry@1.11.1: @@ -9382,6 +12433,8 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.3 + path-to-regexp@6.3.0: {} + path-to-regexp@8.4.2: {} pathe@2.0.3: {} @@ -9431,8 +12484,12 @@ snapshots: picomatch@4.0.4: {} + pify@2.3.0: {} + pirates@4.0.7: {} + pkce-challenge@5.0.1: {} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -9443,6 +12500,49 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 + postcss-import@15.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 + + postcss-js@4.1.0(postcss@8.5.8): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.8 + + postcss-load-config@4.0.2(postcss@8.5.8)(ts-node@10.9.2(@types/node@24.12.2)(typescript@5.9.3)): + dependencies: + lilconfig: 3.1.3 + yaml: 2.8.3 + optionalDependencies: + postcss: 8.5.8 + ts-node: 10.9.2(@types/node@24.12.2)(typescript@5.9.3) + + postcss-nested@6.2.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + postgres-array@2.0.0: {} postgres-array@3.0.4: {} @@ -9457,6 +12557,8 @@ snapshots: postgres@3.4.7: {} + powershell-utils@0.1.0: {} + prelude-ls@1.2.1: {} prettier@3.8.1: {} @@ -9467,12 +12569,16 @@ snapshots: ansi-styles: 5.2.0 react-is: 18.3.1 - prisma@7.6.0(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + pretty-ms@9.3.0: + dependencies: + parse-ms: 4.0.0 + + prisma@7.6.0(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3): dependencies: "@prisma/config": 7.6.0 "@prisma/dev": 0.24.3(typescript@5.9.3) "@prisma/engines": 7.6.0 - "@prisma/studio-core": 0.27.3(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + "@prisma/studio-core": 0.27.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) mysql2: 3.15.3 postgres: 3.4.7 optionalDependencies: @@ -9484,6 +12590,11 @@ snapshots: - react - react-dom + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + proper-lockfile@4.1.2: dependencies: graceful-fs: 4.2.11 @@ -9505,6 +12616,8 @@ snapshots: dependencies: side-channel: 1.1.0 + queue-microtask@1.2.3: {} + range-parser@1.2.1: {} raw-body@3.0.2: @@ -9526,8 +12639,26 @@ snapshots: react-is@18.3.1: {} + react-router-dom@7.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + react-router: 7.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + + react-router@7.14.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + cookie: 1.1.1 + react: 19.2.4 + set-cookie-parser: 2.7.2 + optionalDependencies: + react-dom: 19.2.4(react@19.2.4) + react@19.2.4: {} + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -9540,6 +12671,14 @@ snapshots: readdirp@4.1.2: {} + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + reflect-metadata@0.2.2: {} remeda@2.33.4: {} @@ -9548,10 +12687,14 @@ snapshots: require-from-string@2.0.2: {} + reselect@5.1.1: {} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 + resolve-from@4.0.0: {} + resolve-from@5.0.0: {} resolve@1.22.11: @@ -9567,12 +12710,40 @@ snapshots: retry@0.12.0: {} + rettime@0.10.1: {} + + reusify@1.1.0: {} + rfdc@1.4.1: {} rimraf@2.7.1: dependencies: glob: 7.2.3 + rolldown@1.0.0-rc.12(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2): + dependencies: + "@oxc-project/types": 0.122.0 + "@rolldown/pluginutils": 1.0.0-rc.12 + optionalDependencies: + "@rolldown/binding-android-arm64": 1.0.0-rc.12 + "@rolldown/binding-darwin-arm64": 1.0.0-rc.12 + "@rolldown/binding-darwin-x64": 1.0.0-rc.12 + "@rolldown/binding-freebsd-x64": 1.0.0-rc.12 + "@rolldown/binding-linux-arm-gnueabihf": 1.0.0-rc.12 + "@rolldown/binding-linux-arm64-gnu": 1.0.0-rc.12 + "@rolldown/binding-linux-arm64-musl": 1.0.0-rc.12 + "@rolldown/binding-linux-ppc64-gnu": 1.0.0-rc.12 + "@rolldown/binding-linux-s390x-gnu": 1.0.0-rc.12 + "@rolldown/binding-linux-x64-gnu": 1.0.0-rc.12 + "@rolldown/binding-linux-x64-musl": 1.0.0-rc.12 + "@rolldown/binding-openharmony-arm64": 1.0.0-rc.12 + "@rolldown/binding-wasm32-wasi": 1.0.0-rc.12(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + "@rolldown/binding-win32-arm64-msvc": 1.0.0-rc.12 + "@rolldown/binding-win32-x64-msvc": 1.0.0-rc.12 + transitivePeerDependencies: + - "@emnapi/core" + - "@emnapi/runtime" + router@2.2.0: dependencies: debug: 4.4.3 @@ -9583,6 +12754,12 @@ snapshots: transitivePeerDependencies: - supports-color + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + rxjs@7.8.2: dependencies: tslib: 2.8.1 @@ -9624,8 +12801,53 @@ snapshots: transitivePeerDependencies: - supports-color + set-cookie-parser@2.7.2: {} + setprototypeof@1.2.0: {} + shadcn@4.1.2(@types/node@24.12.2)(typescript@5.9.3): + dependencies: + "@babel/core": 7.29.0 + "@babel/parser": 7.29.2 + "@babel/plugin-transform-typescript": 7.28.6(@babel/core@7.29.0) + "@babel/preset-typescript": 7.28.5(@babel/core@7.29.0) + "@dotenvx/dotenvx": 1.59.1 + "@modelcontextprotocol/sdk": 1.29.0(zod@3.25.76) + "@types/validate-npm-package-name": 4.0.2 + browserslist: 4.28.2 + commander: 14.0.3 + cosmiconfig: 9.0.1(typescript@5.9.3) + dedent: 1.7.2 + deepmerge: 4.3.1 + diff: 8.0.4 + execa: 9.6.1 + fast-glob: 3.3.3 + fs-extra: 11.3.4 + fuzzysort: 3.1.0 + https-proxy-agent: 7.0.6 + kleur: 4.1.5 + msw: 2.12.14(@types/node@24.12.2)(typescript@5.9.3) + node-fetch: 3.3.2 + open: 11.0.0 + ora: 8.2.0 + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + prompts: 2.4.2 + recast: 0.23.11 + stringify-object: 5.0.0 + tailwind-merge: 3.5.0 + ts-morph: 26.0.0 + tsconfig-paths: 4.2.0 + validate-npm-package-name: 7.0.2 + zod: 3.25.76 + zod-to-json-schema: 3.25.2(zod@3.25.76) + transitivePeerDependencies: + - "@cfworker/json-schema" + - "@types/node" + - babel-plugin-macros + - supports-color + - typescript + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -9678,6 +12900,8 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 + source-map-js@1.2.1: {} + source-map-support@0.5.13: dependencies: buffer-from: 1.1.2 @@ -9704,8 +12928,12 @@ snapshots: std-env@3.10.0: {} + stdin-discarder@0.2.2: {} + streamsearch@1.1.0: {} + strict-event-emitter@0.5.1: {} + string-argv@0.3.2: {} string-length@4.0.2: @@ -9740,6 +12968,12 @@ snapshots: dependencies: safe-buffer: 5.2.1 + stringify-object@5.0.0: + dependencies: + get-own-enumerable-keys: 1.0.0 + is-obj: 3.0.0 + is-regexp: 3.1.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -9754,6 +12988,8 @@ snapshots: strip-final-newline@2.0.0: {} + strip-final-newline@4.0.0: {} + strip-json-comments@2.0.1: {} strip-json-comments@3.1.1: {} @@ -9764,6 +13000,16 @@ snapshots: dependencies: "@tokenizer/token": 0.3.0 + sucrase@3.35.1: + dependencies: + "@jridgewell/gen-mapping": 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + superagent@10.3.0: dependencies: component-emitter: 1.3.1 @@ -9800,16 +13046,70 @@ snapshots: dependencies: "@pkgr/core": 0.2.9 + tabbable@6.4.0: {} + + tagged-tag@1.0.0: {} + + tailwind-merge@3.5.0: {} + + tailwindcss@3.4.17(ts-node@10.9.2(@types/node@24.12.2)(typescript@5.9.3)): + dependencies: + "@alloc/quick-lru": 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.8 + postcss-import: 15.1.0(postcss@8.5.8) + postcss-js: 4.1.0(postcss@8.5.8) + postcss-load-config: 4.0.2(postcss@8.5.8)(ts-node@10.9.2(@types/node@24.12.2)(typescript@5.9.3)) + postcss-nested: 6.2.0(postcss@8.5.8) + postcss-selector-parser: 6.1.2 + resolve: 1.22.11 + sucrase: 3.35.1 + transitivePeerDependencies: + - ts-node + test-exclude@6.0.0: dependencies: "@istanbuljs/schema": 0.1.3 glob: 7.2.3 minimatch: 3.1.5 + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + thirty-two@1.0.2: {} + tiny-invariant@1.3.3: {} + tinyexec@1.0.4: {} + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tldts-core@7.0.27: {} + + tldts@7.0.27: + dependencies: + tldts-core: 7.0.27 + tmpl@1.0.5: {} to-regex-range@5.0.1: @@ -9824,8 +13124,18 @@ snapshots: "@tokenizer/token": 0.3.0 ieee754: 1.2.1 + tough-cookie@6.0.1: + dependencies: + tldts: 7.0.27 + tree-kill@1.2.2: {} + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-interface-checker@0.1.13: {} + ts-jest@29.4.9(@babel/core@7.29.0)(@jest/transform@30.3.0)(@jest/types@30.3.0)(babel-jest@30.3.0(@babel/core@7.29.0))(jest-util@30.3.0)(jest@30.3.0(@types/node@25.5.2)(ts-node@10.9.2(@types/node@25.5.2)(typescript@5.9.3)))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 @@ -9846,6 +13156,11 @@ snapshots: babel-jest: 30.3.0(@babel/core@7.29.0) jest-util: 30.3.0 + ts-morph@26.0.0: + dependencies: + "@ts-morph/common": 0.27.0 + code-block-writer: 13.0.3 + ts-node-dev@2.0.0(@types/node@25.5.2)(typescript@5.9.3): dependencies: chokidar: 3.6.0 @@ -9864,6 +13179,25 @@ snapshots: - "@swc/wasm" - "@types/node" + ts-node@10.9.2(@types/node@24.12.2)(typescript@5.9.3): + dependencies: + "@cspotcode/source-map-support": 0.8.1 + "@tsconfig/node10": 1.0.12 + "@tsconfig/node12": 1.0.11 + "@tsconfig/node14": 1.0.3 + "@tsconfig/node16": 1.0.4 + "@types/node": 24.12.2 + acorn: 8.16.0 + acorn-walk: 8.3.5 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.4 + make-error: 1.3.6 + typescript: 5.9.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + ts-node@10.9.2(@types/node@25.5.2)(typescript@5.9.3): dependencies: "@cspotcode/source-map-support": 0.8.1 @@ -9882,6 +13216,12 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + tsconfig@7.0.0: dependencies: "@types/strip-bom": 3.0.0 @@ -9900,6 +13240,8 @@ snapshots: "@turbo/windows-64": 2.9.3 "@turbo/windows-arm64": 2.9.3 + tw-animate-css@1.4.0: {} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 @@ -9910,6 +13252,10 @@ snapshots: type-fest@4.41.0: {} + type-fest@5.5.0: + dependencies: + tagged-tag: 1.0.0 + type-is@1.6.18: dependencies: media-typer: 0.3.0 @@ -9923,6 +13269,17 @@ snapshots: typedarray@0.0.6: {} + typescript-eslint@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3): + dependencies: + "@typescript-eslint/eslint-plugin": 8.58.0(@typescript-eslint/parser@8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + "@typescript-eslint/parser": 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + "@typescript-eslint/typescript-estree": 8.58.0(typescript@5.9.3) + "@typescript-eslint/utils": 8.58.0(eslint@9.39.4(jiti@2.6.1))(typescript@5.9.3) + eslint: 9.39.4(jiti@2.6.1) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + typescript@5.9.3: {} uglify-js@3.19.3: @@ -9936,8 +13293,14 @@ snapshots: uint8array-extras@1.5.0: {} + undici-types@7.16.0: {} + undici-types@7.18.2: {} + unicorn-magic@0.3.0: {} + + universalify@2.0.1: {} + unpipe@1.0.0: {} unrs-resolver@1.11.1: @@ -9964,6 +13327,8 @@ snapshots: "@unrs/resolver-binding-win32-ia32-msvc": 1.11.1 "@unrs/resolver-binding-win32-x64-msvc": 1.11.1 + until-async@3.0.2: {} + update-browserslist-db@1.2.3(browserslist@4.28.2): dependencies: browserslist: 4.28.2 @@ -9974,6 +13339,10 @@ snapshots: dependencies: punycode: 2.3.1 + use-sync-external-store@1.6.0(react@19.2.4): + dependencies: + react: 19.2.4 + util-deprecate@1.0.2: {} utils-merge@1.0.1: {} @@ -9990,22 +13359,52 @@ snapshots: optionalDependencies: typescript: 5.9.3 + validate-npm-package-name@7.0.2: {} + validator@13.15.35: {} vary@1.1.2: {} + vite@8.0.3(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2)(@types/node@24.12.2)(jiti@2.6.1)(yaml@2.8.3): + dependencies: + lightningcss: 1.32.0 + picomatch: 4.0.4 + postcss: 8.5.8 + rolldown: 1.0.0-rc.12(@emnapi/core@1.9.2)(@emnapi/runtime@1.9.2) + tinyglobby: 0.2.15 + optionalDependencies: + "@types/node": 24.12.2 + fsevents: 2.3.3 + jiti: 2.6.1 + yaml: 2.8.3 + transitivePeerDependencies: + - "@emnapi/core" + - "@emnapi/runtime" + walker@1.0.8: dependencies: makeerror: 1.0.12 + web-streams-polyfill@3.3.3: {} + which@2.0.2: dependencies: isexe: 2.0.0 + which@4.0.0: + dependencies: + isexe: 3.1.5 + word-wrap@1.2.5: {} wordwrap@1.0.0: {} + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -10031,6 +13430,11 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 4.1.0 + wsl-utils@0.3.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.1.0 + xtend@4.0.2: {} y18n@5.0.8: {} @@ -10055,7 +13459,23 @@ snapshots: yocto-queue@0.1.0: {} + yoctocolors-cjs@2.1.3: {} + + yoctocolors@2.1.2: {} + zeptomatch@2.1.0: dependencies: grammex: 3.1.12 graphmatch: 1.1.1 + + zod-to-json-schema@3.25.2(zod@3.25.76): + dependencies: + zod: 3.25.76 + + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@3.25.76: {} + + zod@4.3.6: {}