diff --git a/.github/workflows/backend-ci.yaml b/.github/workflows/backend-ci.yaml index 0ea6005..c15c10a 100644 --- a/.github/workflows/backend-ci.yaml +++ b/.github/workflows/backend-ci.yaml @@ -8,7 +8,6 @@ on: - "docker/backend.Dockerfile" - "secrets/backend/**" - "packages/backend/**" - - "packages/prisma-client/**" - ".github/workflows/backend-ci.yaml" pull_request: paths: *backend-paths @@ -43,13 +42,16 @@ jobs: run: pnpm --filter=@hallmaster/backend lint - name: Run format check - run: pnpm --filter=@hallmaster/backend format + run: pnpm --filter=@hallmaster/backend format:check - name: Test the build process run: pnpm --filter=@hallmaster/backend build - - name: Run the tests - run: pnpm --filter=@hallmaster/backend test:cov + - name: Run the unit tests + run: pnpm --filter=@hallmaster/backend test:unit + + - name: Run the integration tests + run: pnpm --filter=@hallmaster/backend test:integration build-and-push: name: Build and Push Images diff --git a/docker/backend.Dockerfile b/docker/backend.Dockerfile index 7fae537..d8798b5 100644 --- a/docker/backend.Dockerfile +++ b/docker/backend.Dockerfile @@ -16,15 +16,6 @@ COPY package.json \ # Required by pnpm-workspace.yaml `patchedDependencies` COPY patches/ patches/ -# Install packages for Prisma -COPY packages/prisma-client/package.json \ - packages/prisma-client/ -RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ - pnpm install \ - --filter=@hallmaster/prisma-client \ - --prefer-offline \ - --frozen-lockfile - # Install packages for the backend COPY packages/backend/package.json packages/backend/ RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ @@ -38,10 +29,9 @@ COPY packages/backend/prisma/ packages/backend/prisma/ COPY packages/backend/prisma.config.ts packages/backend/ RUN pnpm --filter=@hallmaster/backend prisma:generate -# Build NestJS application -COPY packages/backend/tsconfig.build.json \ - packages/backend/tsconfig.json \ - packages/backend/nest-cli.json \ +# Build Hono application +COPY packages/backend/tsconfig.json \ + packages/backend/tsdown.config.ts \ packages/backend/ COPY packages/backend/src/ packages/backend/src/ RUN pnpm --filter=@hallmaster/backend build @@ -49,8 +39,8 @@ RUN pnpm --filter=@hallmaster/backend build # Cleanup the application RUN rm -rf packages/backend/src \ packages/backend/tsconfig.json \ - packages/backend/tsconfig.build.json \ - packages/backend/nest-cli.json + packages/backend/tsdown.config.ts \ + packages/backend/prisma/generated # Create the application package RUN pnpm deploy --filter=@hallmaster/backend --prod --legacy /prod-app diff --git a/package.json b/package.json index a5b5f55..1297c83 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ }, "packageManager": { "name": "pnpm", - "version": "^12.6.0" + "version": "12.6.0" } }, "devDependencies": { diff --git a/packages/backend/.env.example b/packages/backend/.env.example index 862319d..25dd757 100644 --- a/packages/backend/.env.example +++ b/packages/backend/.env.example @@ -1,12 +1,6 @@ -DISCORD_BOT_TOKEN_ENV_NAME=DISCORD_BOT_TOKEN -TOTAL_SHARDS_ENV_NAME=TOTAL_SHARDS -SHARD_ID_LIST_ENV_NAME=SHARD_ID_LIST +DATABASE_URL="postgres://postgres:postgres@localhost:51214/template1?sslmode=disable&connection_limit=10&connect_timeout=0&max_idle_connection_lifetime=0&pool_timeout=0&socket_timeout=0" -DATABASE_URL=postgresql://pguser:pgpassword@hallmaster-postgres:5432/hallmaster +# openssl rand -base64 32 +SECRET="change_me" -# python3 -c "import random,string;print(''.join([random.choice(string.hexdigits[:16]) for _ in range(32)]))" -JWT_SECRET=XXX -JWT_EXPIRES_IN=12h # 15m, 1d, ... - -# This enables logging of all incoming requests -# LOG_REQUESTS=true +PORT=3000 diff --git a/packages/backend/.gitignore b/packages/backend/.gitignore index 00a9233..f5caa46 100644 --- a/packages/backend/.gitignore +++ b/packages/backend/.gitignore @@ -1,58 +1,34 @@ -# compiled output -/dist -/node_modules -/build +# dev +.yarn/ +!.yarn/releases +.vscode/* +!.vscode/launch.json +!.vscode/*.code-snippets +.idea/workspace.xml +.idea/usage.statistics.xml +.idea/shelf + +# deps +node_modules/ + +# env +.env +.env.production -# Logs -logs +# logs +logs/ *.log npm-debug.log* -pnpm-debug.log* yarn-debug.log* yarn-error.log* +pnpm-debug.log* lerna-debug.log* -# OS +# misc .DS_Store +dist/ +coverage/ +/.alchemy +/.prisma-composer -# Tests -/coverage -/.nyc_output - -# IDEs and editors -/.idea -.project -.classpath -.c9/ -*.launch -.settings/ -*.sublime-workspace - -# IDE - VSCode -.vscode/* -!.vscode/settings.json -!.vscode/tasks.json -!.vscode/launch.json -!.vscode/extensions.json - -# dotenv environment variable files -.env -.env.development.local -.env.test.local -.env.production.local -.env.local - -# temp directory -.temp -.tmp - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -/generated +prisma/generated/ diff --git a/packages/backend/.oxfmtrc.json b/packages/backend/.oxfmtrc.json new file mode 100644 index 0000000..98338d1 --- /dev/null +++ b/packages/backend/.oxfmtrc.json @@ -0,0 +1,5 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "ignorePatterns": [], + "sortImports": true +} diff --git a/packages/backend/.oxlintrc.json b/packages/backend/.oxlintrc.json new file mode 100644 index 0000000..ac776a7 --- /dev/null +++ b/packages/backend/.oxlintrc.json @@ -0,0 +1,29 @@ +{ + "$schema": "./node_modules/oxlint/configuration_schema.json", + "plugins": ["typescript", "unicorn", "oxc"], + "categories": { + "correctness": "error" + }, + "rules": { + "typescript/await-thenable": "error", + "typescript/no-floating-promises": "error", + "typescript/no-misused-promises": "error", + "typescript/no-unnecessary-condition": "error", + "typescript/require-await": "error" + }, + "env": { + "builtin": true + }, + "options": { + "typeAware": true, + "typeCheck": true + }, + "overrides": [ + { + "files": ["tests/**/*.ts"], + "rules": { + "typescript/unbound-method": "off" + } + } + ] +} diff --git a/packages/backend/.prettierrc b/packages/backend/.prettierrc deleted file mode 100644 index 0981b7c..0000000 --- a/packages/backend/.prettierrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "singleQuote": true, - "printWidth": 120 -} diff --git a/packages/backend/README.md b/packages/backend/README.md deleted file mode 100644 index 272f498..0000000 --- a/packages/backend/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Hallmaster backend - -NestJS application powered by Fastify for the Hallmaster backend. diff --git a/packages/backend/eslint.config.ts b/packages/backend/eslint.config.ts deleted file mode 100644 index a8bed08..0000000 --- a/packages/backend/eslint.config.ts +++ /dev/null @@ -1,67 +0,0 @@ -// @ts-check -import { defineConfig } from 'eslint/config'; -import eslint from '@eslint/js'; -import globals from 'globals'; -import tseslint from 'typescript-eslint'; -import eslintPluginJest from 'eslint-plugin-jest'; -import eslintPluginImport from 'eslint-plugin-import'; -import eslintPluginPrettier from 'eslint-plugin-prettier/recommended'; - -export default defineConfig( - eslint.configs.recommended, - ...tseslint.configs.recommendedTypeChecked, - eslintPluginImport.flatConfigs.recommended, - eslintPluginImport.flatConfigs.typescript, - eslintPluginPrettier, - eslintPluginJest.configs['flat/recommended'], - { - languageOptions: { - globals: { - ...globals.node, - ...globals.jest, - }, - ecmaVersion: 5, - sourceType: 'module', - parserOptions: { - projectService: true, - tsconfigRootDir: import.meta.dirname, - }, - }, - settings: { - 'import/resolver': { - typescript: { - project: './tsconfig.json', - }, - }, - }, - }, - { - rules: { - '@typescript-eslint/no-explicit-any': 'error', - '@typescript-eslint/no-floating-promises': 'error', - '@typescript-eslint/no-unsafe-argument': 'error', - '@typescript-eslint/consistent-type-imports': 'error', - '@typescript-eslint/no-unused-vars': [ - 'error', - { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }, - ], - 'no-console': ['error', { allow: ['warn', 'error'] }], - 'import/order': [ - 'error', - { - groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'], - 'newlines-between': 'always', - alphabetize: { order: 'asc', caseInsensitive: true }, - }, - ], - 'import/no-unresolved': 'off', - }, - }, - { - files: ['**/*.spec.ts'], - rules: { - '@typescript-eslint/unbound-method': 'off', - 'jest/unbound-method': 'error', - }, - }, -); diff --git a/packages/backend/jest.config.ts b/packages/backend/jest.config.ts deleted file mode 100644 index 86a40da..0000000 --- a/packages/backend/jest.config.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { JestConfigWithTsJest } from 'ts-jest'; - -const config: JestConfigWithTsJest = { - // Use the ts-jest preset for ESM - preset: 'ts-jest/presets/default-esm', - - // The test environment that will be used for testing - testEnvironment: 'node', - - // A list of paths to directories that Jest should use to search for files in - roots: ['/src'], - - // The glob patterns Jest uses to detect test files - testRegex: '.*\\.spec\\.ts$', - - // A map from regular expressions to paths to transformers - transform: { - '^.+\\.ts?$': [ - 'ts-jest', - { - useESM: true, - }, - ], - // '^.+\\.[tj]s$': 'ts-jest' // This is handled by the preset - }, - - // Helps Jest resolve TypeScript paths - moduleNameMapper: { - // This mapping is necessary to handle the .js extension in ESM imports - '^(\\.{1,2}/.*)\\.js$': '$1', - - // If you use path aliases in tsconfig.json, map them here - // Example: '@App/(.*)': '/src/$1' - }, - - // An array of file extensions your modules use - moduleFileExtensions: ['ts', 'js', 'json', 'node'], - - clearMocks: true, -}; - -export default config; diff --git a/packages/backend/nest-cli.json b/packages/backend/nest-cli.json deleted file mode 100644 index f9aa683..0000000 --- a/packages/backend/nest-cli.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/nest-cli", - "collection": "@nestjs/schematics", - "sourceRoot": "src", - "compilerOptions": { - "deleteOutDir": true - } -} diff --git a/packages/backend/package.json b/packages/backend/package.json index 083a654..9644006 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,93 +1,55 @@ { "name": "@hallmaster/backend", - "version": "0.0.1", - "description": "Hallmaster backend", - "private": true, - "license": "UNLICENSED", "type": "module", "exports": { - "./dto": "./src/index.dto.ts" + "./schemas": "./src/schemas/index.ts" }, "scripts": { - "build": "nest build", - "start": "dotenv -e .env -- nest start", - "start:dev": "dotenv -e .env -- nest start --watch", - "start:debug": "dotenv -e .env -- nest start --debug --watch", - "start:prod": "prisma migrate deploy && node dist/src/main", - "lint": "eslint \"src/**/*.ts\"", - "lint:fix": "eslint --fix \"src/**/*.ts\"", - "format": "prettier --check src/", - "format:fix": "prettier --write src/", - "pretest": "pnpm build", - "test": "NODE_OPTIONS=--experimental-vm-modules jest", - "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch", - "test:cov": "NODE_OPTIONS=--experimental-vm-modules jest --coverage", - "test:debug": "NODE_OPTIONS=--experimental-vm-modules node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", - "prisma:reset": "dotenv -e .env -- prisma migrate reset", - "prisma:migrate": "dotenv -e .env -- prisma migrate dev", - "prisma:generate": "DATABASE_URL=postgres://null:null@null:5432/null prisma generate", - "prisma:deploy": "dotenv -e .env -- prisma migrate deploy", - "prisma:studio": "dotenv -e .env -- prisma studio", - "prisma:format": "dotenv -e .env -- prisma format" + "dev": "tsx watch src/index.ts", + "build": "tsc && tsdown", + "start": "node dist/index.mjs", + "start:prod": "prisma migrate deploy && node dist/index.mjs", + "lint": "oxlint", + "lint:fix": "oxlint --fix", + "format": "oxfmt", + "format:check": "oxfmt --check", + "test": "vitest run", + "test:unit": "vitest run --project unit", + "test:integration": "vitest run --project integration", + "test:cov": "vitest run --coverage", + "prisma:dev": "prisma dev", + "prisma:migrate": "prisma migrate dev", + "prisma:deploy": "prisma migrate deploy", + "prisma:reset": "prisma migrate reset", + "prisma:generate": "prisma generate" }, "dependencies": { - "@fastify/compress": "8.3.1", - "@hallmaster/docker.js": "0.0.28", - "@hallmaster/prisma-client": "workspace:*", - "@nestjs/common": "11.1.14", - "@nestjs/config": "4.0.3", - "@nestjs/core": "11.1.14", - "@nestjs/jwt": "11.0.2", - "@nestjs/platform-fastify": "11.1.14", - "@nestjs/swagger": "11.2.6", - "@prisma/adapter-pg": "7.4.1", - "@prisma/client": "7.4.1", - "argon2": "0.44.0", - "fastify": "5.7.4", - "nest-winston": "1.10.2", - "nestjs-zod": "5.1.1", - "pg": "8.18.0", - "prisma": "7.4.1", - "reflect-metadata": "0.2.2", - "rxjs": "7.8.2", - "swagger-themes": "1.4.3", - "winston": "3.19.0", - "zod": "4.3.6" + "@hallmaster/docker.js": "^0.0.28", + "@hono/node-server": "^2.1.1", + "@hono/standard-validator": "^0.4.0", + "@prisma/adapter-pg": "^7.10.0", + "@prisma/client": "^7.4.1", + "@scalar/hono-api-reference": "^0.12.6", + "argon2": "^0.45.1", + "dotenv": "^18.0.4", + "hono": "^4.13.9", + "hono-openapi": "^1.3.3", + "pg": "^8.23.0", + "prisma": "^7.10.0", + "zod": "^4.6.5" }, "devDependencies": { - "@eslint/eslintrc": "3.3.3", - "@eslint/js": "9.39.3", - "@jest/globals": "30.2.0", - "@nestjs/cli": "11.0.16", - "@nestjs/schematics": "11.0.9", - "@nestjs/testing": "11.1.14", - "@swc/cli": "0.6.0", - "@swc/core": "1.15.11", - "@types/jest": "30.0.0", - "@types/mocha": "^10.0.10", - "@types/node": "22.19.11", - "@types/pg": "8.16.0", - "@types/supertest": "6.0.3", - "dotenv": "17.3.1", - "dotenv-cli": "10.0.0", - "eslint": "9.39.3", - "eslint-config-prettier": "10.1.8", - "eslint-import-resolver-typescript": "^4.4.4", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-jest": "29.15.0", - "eslint-plugin-prettier": "5.5.5", - "globals": "16.5.0", - "jest": "29.7.0", - "jest-esm-transformer": "1.0.0", - "jest-mock-extended": "4.0.0", - "prettier": "3.8.1", - "source-map-support": "0.5.21", - "supertest": "7.2.2", - "ts-jest": "29.4.6", - "ts-loader": "9.5.4", - "ts-node": "10.9.2", - "tsconfig-paths": "4.2.0", - "typescript": "5.9.3", - "typescript-eslint": "8.56.0" + "@testcontainers/postgresql": "^12.2.0", + "@types/node": "^26.1.1", + "@types/pg": "^8.23.1", + "@vitest/coverage-v8": "^5.0.3", + "oxfmt": "^0.70.0", + "oxlint": "^1.85.0", + "oxlint-tsgolint": "^7.0.2003", + "tsdown": "^0.23.1", + "tsx": "^4.23.0", + "typescript": "^7.0.2", + "vite-tsconfig-paths": "^6.1.1", + "vitest": "^5.0.3" } } diff --git a/packages/backend/prisma.config.ts b/packages/backend/prisma.config.ts index 8b89c80..69edbe9 100644 --- a/packages/backend/prisma.config.ts +++ b/packages/backend/prisma.config.ts @@ -1,12 +1,12 @@ -import { defineConfig, env } from 'prisma/config'; +import "dotenv/config"; +import { defineConfig } from "prisma/config"; export default defineConfig({ - schema: 'prisma/schema.prisma', + schema: "prisma/schema.prisma", migrations: { - path: 'prisma/migrations', - seed: 'tsx prisma/seed.ts', + path: "prisma/migrations", }, datasource: { - url: env('DATABASE_URL'), + url: process.env["DATABASE_URL"], }, }); diff --git a/packages/backend/prisma/migrations/20260120001931_init/migration.sql b/packages/backend/prisma/migrations/20260120001931_init/migration.sql deleted file mode 100644 index 6cd9a3f..0000000 --- a/packages/backend/prisma/migrations/20260120001931_init/migration.sql +++ /dev/null @@ -1,25 +0,0 @@ --- CreateEnum -CREATE TYPE "ClusterStatus" AS ENUM ('STARTING', 'RUNNING', 'STOPPED', 'ERROR'); - --- CreateTable -CREATE TABLE "Bot" ( - "id" TEXT NOT NULL, - "clusterNumber" INTEGER NOT NULL, - "shards" INTEGER NOT NULL, - - CONSTRAINT "Bot_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "Cluster" ( - "id" TEXT NOT NULL, - "botId" TEXT NOT NULL, - "containerId" TEXT, - "status" "ClusterStatus" NOT NULL, - "shardIds" INTEGER[], - - CONSTRAINT "Cluster_pkey" PRIMARY KEY ("id") -); - --- AddForeignKey -ALTER TABLE "Cluster" ADD CONSTRAINT "Cluster_botId_fkey" FOREIGN KEY ("botId") REFERENCES "Bot"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/backend/prisma/migrations/20260215181900_user_model/migration.sql b/packages/backend/prisma/migrations/20260215181900_user_model/migration.sql deleted file mode 100644 index ed994c0..0000000 --- a/packages/backend/prisma/migrations/20260215181900_user_model/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ --- CreateTable -CREATE TABLE "User" ( - "username" TEXT NOT NULL, - "password" TEXT NOT NULL -); - --- CreateIndex -CREATE UNIQUE INDEX "User_username_key" ON "User"("username"); diff --git a/packages/backend/prisma/migrations/20260220213440_adding_cluster_state/migration.sql b/packages/backend/prisma/migrations/20260220213440_adding_cluster_state/migration.sql deleted file mode 100644 index 18ab9fc..0000000 --- a/packages/backend/prisma/migrations/20260220213440_adding_cluster_state/migration.sql +++ /dev/null @@ -1,2 +0,0 @@ --- AlterEnum -ALTER TYPE "ClusterStatus" ADD VALUE 'UPDATING'; diff --git a/packages/backend/prisma/migrations/20260223052940_setup_docker_image/migration.sql b/packages/backend/prisma/migrations/20260223052940_setup_docker_image/migration.sql deleted file mode 100644 index 5dbea53..0000000 --- a/packages/backend/prisma/migrations/20260223052940_setup_docker_image/migration.sql +++ /dev/null @@ -1,26 +0,0 @@ -/* - Warnings: - - - Added the required column `dockerImageId` to the `Bot` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "Bot" ADD COLUMN "dockerImageId" TEXT NOT NULL; - --- CreateTable -CREATE TABLE "DockerImage" ( - "id" TEXT NOT NULL, - "servername" TEXT NOT NULL DEFAULT 'host.docker.internal:5000', - "image" TEXT NOT NULL, - "tag" TEXT NOT NULL DEFAULT 'latest', - "username" TEXT, - "password" TEXT, - - CONSTRAINT "DockerImage_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "DockerImage_servername_key" ON "DockerImage"("servername"); - --- AddForeignKey -ALTER TABLE "Bot" ADD CONSTRAINT "Bot_dockerImageId_fkey" FOREIGN KEY ("dockerImageId") REFERENCES "DockerImage"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/packages/backend/prisma/migrations/20260223053032_setup_bot_token/migration.sql b/packages/backend/prisma/migrations/20260223053032_setup_bot_token/migration.sql deleted file mode 100644 index b3db11a..0000000 --- a/packages/backend/prisma/migrations/20260223053032_setup_bot_token/migration.sql +++ /dev/null @@ -1,8 +0,0 @@ -/* - Warnings: - - - Added the required column `token` to the `Bot` table without a default value. This is not possible if the table is not empty. - -*/ --- AlterTable -ALTER TABLE "Bot" ADD COLUMN "token" TEXT NOT NULL; diff --git a/packages/backend/prisma/migrations/20260223054709_bot_table_simplification/migration.sql b/packages/backend/prisma/migrations/20260223054709_bot_table_simplification/migration.sql deleted file mode 100644 index 3db66c3..0000000 --- a/packages/backend/prisma/migrations/20260223054709_bot_table_simplification/migration.sql +++ /dev/null @@ -1,64 +0,0 @@ -/* - Warnings: - - - You are about to drop the `Bot` table. If the table is not empty, all the data it contains will be lost. - - You are about to drop the `Cluster` table. If the table is not empty, all the data it contains will be lost. - - You are about to drop the `DockerImage` table. If the table is not empty, all the data it contains will be lost. - -*/ --- DropForeignKey -ALTER TABLE "Bot" DROP CONSTRAINT "Bot_dockerImageId_fkey"; - --- DropForeignKey -ALTER TABLE "Cluster" DROP CONSTRAINT "Cluster_botId_fkey"; - --- DropTable -DROP TABLE "Bot"; - --- DropTable -DROP TABLE "Cluster"; - --- DropTable -DROP TABLE "DockerImage"; - --- CreateTable -CREATE TABLE "bot" ( - "id" TEXT NOT NULL, - "token" TEXT NOT NULL, - "total_shards" INTEGER NOT NULL, - "docker_image_id" TEXT NOT NULL, - - CONSTRAINT "bot_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "docker_image" ( - "id" TEXT NOT NULL, - "server_name" TEXT NOT NULL DEFAULT 'host.docker.internal:5000', - "image" TEXT NOT NULL, - "tag" TEXT NOT NULL DEFAULT 'latest', - "username" TEXT, - "password" TEXT, - - CONSTRAINT "docker_image_pkey" PRIMARY KEY ("id") -); - --- CreateTable -CREATE TABLE "cluster" ( - "id" TEXT NOT NULL, - "bot_id" TEXT NOT NULL, - "container_id" TEXT, - "status" "ClusterStatus" NOT NULL, - "shard_ids" INTEGER[], - - CONSTRAINT "cluster_pkey" PRIMARY KEY ("id") -); - --- CreateIndex -CREATE UNIQUE INDEX "docker_image_server_name_key" ON "docker_image"("server_name"); - --- AddForeignKey -ALTER TABLE "bot" ADD CONSTRAINT "bot_docker_image_id_fkey" FOREIGN KEY ("docker_image_id") REFERENCES "docker_image"("id") ON DELETE RESTRICT ON UPDATE CASCADE; - --- AddForeignKey -ALTER TABLE "cluster" ADD CONSTRAINT "cluster_bot_id_fkey" FOREIGN KEY ("bot_id") REFERENCES "bot"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/backend/prisma/migrations/20260403075738_docker_image_child_of_bot/migration.sql b/packages/backend/prisma/migrations/20260403075738_docker_image_child_of_bot/migration.sql deleted file mode 100644 index cf0d121..0000000 --- a/packages/backend/prisma/migrations/20260403075738_docker_image_child_of_bot/migration.sql +++ /dev/null @@ -1,22 +0,0 @@ -/* - Warnings: - - - You are about to drop the column `docker_image_id` on the `bot` table. All the data in the column will be lost. - - A unique constraint covering the columns `[bot_id]` on the table `docker_image` will be added. If there are existing duplicate values, this will fail. - - Added the required column `bot_id` to the `docker_image` table without a default value. This is not possible if the table is not empty. - -*/ --- DropForeignKey -ALTER TABLE "bot" DROP CONSTRAINT "bot_docker_image_id_fkey"; - --- AlterTable -ALTER TABLE "bot" DROP COLUMN "docker_image_id"; - --- AlterTable -ALTER TABLE "docker_image" ADD COLUMN "bot_id" TEXT NOT NULL; - --- CreateIndex -CREATE UNIQUE INDEX "docker_image_bot_id_key" ON "docker_image"("bot_id"); - --- AddForeignKey -ALTER TABLE "docker_image" ADD CONSTRAINT "docker_image_bot_id_fkey" FOREIGN KEY ("bot_id") REFERENCES "bot"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/backend/prisma/migrations/20260513054314_use_numeric_cluster_ids/migration.sql b/packages/backend/prisma/migrations/20260513054314_use_numeric_cluster_ids/migration.sql deleted file mode 100644 index 7982974..0000000 --- a/packages/backend/prisma/migrations/20260513054314_use_numeric_cluster_ids/migration.sql +++ /dev/null @@ -1,12 +0,0 @@ -/* - Warnings: - - - The primary key for the `cluster` table will be changed. If it partially fails, the table could be left without primary key constraint. - - Changed the type of `id` on the `cluster` table. No cast exists, the column would be dropped and recreated, which cannot be done if there is data, since the column is required. - -*/ --- AlterTable -ALTER TABLE "cluster" DROP CONSTRAINT "cluster_pkey", -DROP COLUMN "id", -ADD COLUMN "id" INTEGER NOT NULL, -ADD CONSTRAINT "cluster_pkey" PRIMARY KEY ("bot_id", "id"); diff --git a/packages/backend/prisma/migrations/20261007133401_init/migration.sql b/packages/backend/prisma/migrations/20261007133401_init/migration.sql new file mode 100644 index 0000000..af33f25 --- /dev/null +++ b/packages/backend/prisma/migrations/20261007133401_init/migration.sql @@ -0,0 +1,56 @@ +-- CreateEnum +CREATE TYPE "ClusterStatus" AS ENUM ('STARTING', 'RUNNING', 'STOPPED', 'UPDATING', 'ERROR'); + +-- CreateTable +CREATE TABLE "User" ( + "username" TEXT NOT NULL, + "password_hash" TEXT NOT NULL +); + +-- CreateTable +CREATE TABLE "bot" ( + "id" TEXT NOT NULL, + "token" TEXT NOT NULL, + "total_shards" INTEGER NOT NULL, + + CONSTRAINT "bot_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "container_image" ( + "id" TEXT NOT NULL, + "server_name" TEXT NOT NULL DEFAULT 'host.docker.internal:5000', + "image" TEXT NOT NULL, + "tag" TEXT NOT NULL DEFAULT 'latest', + "username" TEXT, + "password" TEXT, + "bot_id" TEXT NOT NULL, + + CONSTRAINT "container_image_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "cluster" ( + "id" INTEGER NOT NULL, + "bot_id" TEXT NOT NULL, + "container_id" TEXT NOT NULL, + "status" "ClusterStatus" NOT NULL, + "shard_ids" INTEGER[], + + CONSTRAINT "cluster_pkey" PRIMARY KEY ("bot_id","id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "User_username_key" ON "User"("username"); + +-- CreateIndex +CREATE UNIQUE INDEX "container_image_server_name_key" ON "container_image"("server_name"); + +-- CreateIndex +CREATE UNIQUE INDEX "container_image_bot_id_key" ON "container_image"("bot_id"); + +-- AddForeignKey +ALTER TABLE "container_image" ADD CONSTRAINT "container_image_bot_id_fkey" FOREIGN KEY ("bot_id") REFERENCES "bot"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "cluster" ADD CONSTRAINT "cluster_bot_id_fkey" FOREIGN KEY ("bot_id") REFERENCES "bot"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/packages/backend/prisma/migrations/20261011210742_cluster_desired_status/migration.sql b/packages/backend/prisma/migrations/20261011210742_cluster_desired_status/migration.sql new file mode 100644 index 0000000..9ccbe68 --- /dev/null +++ b/packages/backend/prisma/migrations/20261011210742_cluster_desired_status/migration.sql @@ -0,0 +1,14 @@ +-- CreateEnum +CREATE TYPE "ClusterDesiredStatus" AS ENUM ('RUNNING', 'STOPPED'); + +-- AlterTable +ALTER TABLE "cluster" ADD COLUMN "desired_status" "ClusterDesiredStatus"; + +UPDATE "cluster" +SET "desired_status" = CASE WHEN "status" = 'STOPPED' THEN 'STOPPED' ELSE 'RUNNING' END::"ClusterDesiredStatus"; + +ALTER TABLE "cluster" ALTER COLUMN "desired_status" SET NOT NULL, +DROP COLUMN "status"; + +-- DropEnum +DROP TYPE "ClusterStatus"; diff --git a/packages/backend/prisma/schema.prisma b/packages/backend/prisma/schema.prisma index c082878..b28f8d1 100644 --- a/packages/backend/prisma/schema.prisma +++ b/packages/backend/prisma/schema.prisma @@ -1,7 +1,6 @@ generator client { - provider = "prisma-client-js" - moduleFormat = "esm" - output = "../../prisma-client/generated" + provider = "prisma-client" + output = "generated/prisma" } datasource db { @@ -9,21 +8,21 @@ datasource db { } model User { - username String @unique - password String + username String @unique + passwordHash String @map("password_hash") } model Bot { - id String @id - token String - totalShards Int @map("total_shards") - clusters Cluster[] - dockerImage DockerImage? + id String @id + token String + totalShards Int @map("total_shards") + clusters Cluster[] + containerImage ContainerImage? @@map("bot") } -model DockerImage { +model ContainerImage { id String @id @default(uuid()) serverName String @unique @default("host.docker.internal:5000") @map("server_name") image String @@ -33,24 +32,21 @@ model DockerImage { botId String @unique @map("bot_id") bot Bot @relation(fields: [botId], references: [id], onDelete: Cascade) - @@map("docker_image") + @@map("container_image") } -enum ClusterStatus { - STARTING +enum ClusterDesiredStatus { RUNNING STOPPED - UPDATING - ERROR } model Cluster { - id Int - botId String @map("bot_id") - containerId String? @map("container_id") - status ClusterStatus - shardIds Int[] @map("shard_ids") - bot Bot @relation(fields: [botId], references: [id], onDelete: Cascade) + id Int + botId String @map("bot_id") + containerId String @map("container_id") + desiredStatus ClusterDesiredStatus @map("desired_status") + shardIds Int[] @map("shard_ids") + bot Bot @relation(fields: [botId], references: [id], onDelete: Cascade) @@id([botId, id]) @@map("cluster") diff --git a/packages/backend/src/app.module.ts b/packages/backend/src/app.module.ts deleted file mode 100644 index 32e0294..0000000 --- a/packages/backend/src/app.module.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ConfigModule } from '@nestjs/config'; - -import { AuthModule } from './auth/auth.module.js'; -import { BotModule } from './bot/bot.module.js'; -import { ClustersModule } from './clusters/clusters.module.js'; -import { DockerModule } from './docker/docker.module.js'; -import { LoggerModule } from './logger/logger.module.js'; -import { PrismaModule } from './prisma/prisma.module.js'; - -@Module({ - imports: [LoggerModule, ConfigModule, PrismaModule, BotModule, ClustersModule, DockerModule, AuthModule], -}) -export class AppModule {} diff --git a/packages/backend/src/app.ts b/packages/backend/src/app.ts new file mode 100644 index 0000000..11d2a4c --- /dev/null +++ b/packages/backend/src/app.ts @@ -0,0 +1,89 @@ +import { Scalar } from "@scalar/hono-api-reference"; +import { Hono } from "hono"; +import { openAPIRouteHandler } from "hono-openapi"; +import { cors } from "hono/cors"; +import { HTTPException } from "hono/http-exception"; +import { logger } from "hono/logger"; +import z from "zod"; + +import authController from "#controllers/auth.controller"; +import botController from "#controllers/bot.controller"; +import clusterController from "#controllers/cluster.controller"; +import { ValidationException } from "#exceptions/http-exceptions"; +import { ApiErrorSchema, type ApiError } from "#schemas/error.schema"; + +const app = new Hono(); + +app.use("/api/*", logger()); +app.use("/api/*", cors()); + +app.onError((error, c) => { + if (error instanceof ValidationException) { + return c.json( + { message: error.message, issues: error.issues } satisfies ApiError, + error.status, + ); + } + + if (error instanceof HTTPException) { + const authenticate = error.res?.headers.get("WWW-Authenticate"); + if (authenticate) { + c.header("WWW-Authenticate", authenticate); + } + + return c.json({ message: error.message } satisfies ApiError, error.status); + } + + console.error(error); + + return c.json({ message: "Internal Server Error" } satisfies ApiError, 500); +}); + +app.notFound((c) => c.json({ message: "Route not found" } satisfies ApiError, 404)); + +app.get( + "/openapi.json", + openAPIRouteHandler(app, { + defaultValidationErrorResponse: { + description: "Bad Request", + content: { + "application/json": { + schema: z.toJSONSchema(ApiErrorSchema) as Record, + }, + }, + }, + documentation: { + info: { + title: "Hallmaster API Documentation", + version: "1.0.0", + }, + components: { + securitySchemes: { + bearerAuth: { + type: "http", + scheme: "bearer", + bearerFormat: "JWT", + }, + }, + }, + }, + }), +); + +app.get( + "/docs", + Scalar({ + theme: "saturn", + url: "/openapi.json", + agent: { disabled: true }, + mcp: { disabled: true }, + }), +); + +const routes = app + .route("/api/auth", authController) + .route("/api/bot", botController) + .route("/api/clusters", clusterController); + +export default app; +export type AppType = typeof routes; diff --git a/packages/backend/src/auth/auth.controller.spec.ts b/packages/backend/src/auth/auth.controller.spec.ts deleted file mode 100644 index 17a2946..0000000 --- a/packages/backend/src/auth/auth.controller.spec.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; -import type { DeepMockProxy } from 'jest-mock-extended'; -import { mockDeep } from 'jest-mock-extended'; - -import { AuthController } from './auth.controller.js'; -import { AuthService } from './auth.service.js'; -import { AuthGuard } from './guards/jwt.guard.js'; - -describe('AuthController', () => { - let controller: AuthController; - const authGuard: DeepMockProxy = mockDeep(); - const authService: DeepMockProxy = mockDeep(); - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [AuthController], - providers: [ - { - provide: AuthService, - useValue: authService, - }, - ], - }) - .overrideGuard(AuthGuard) - .useValue(authGuard) - .compile(); - - controller = module.get(AuthController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/packages/backend/src/auth/auth.controller.ts b/packages/backend/src/auth/auth.controller.ts deleted file mode 100644 index a1758c6..0000000 --- a/packages/backend/src/auth/auth.controller.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Body, Controller, HttpCode, HttpStatus, Post } from '@nestjs/common'; -import { - ApiBadRequestResponse, - ApiConflictResponse, - ApiCreatedResponse, - ApiInternalServerErrorResponse, - ApiOkResponse, - ApiTags, - ApiUnauthorizedResponse, -} from '@nestjs/swagger'; - -import { ApiErrorZodDto } from '../common/dto/api-error.dto.js'; - -import { AuthService } from './auth.service.js'; -import { LoginDto } from './dto/login.dto.js'; -import { RegisterDto } from './dto/register.dto.js'; -import { UserTokenDto } from './entities/user-token.entity.js'; - -@Controller('auth') -@ApiTags('Authentication') -@ApiInternalServerErrorResponse({ - type: ApiErrorZodDto, - description: 'This service is temporary unavailable.', -}) -@ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'The body of the request is invalid.', -}) -export class AuthController { - constructor(private readonly authService: AuthService) {} - - @Post('register') - @HttpCode(HttpStatus.CREATED) - @ApiCreatedResponse({ - type: UserTokenDto, - description: 'The Bearer token (JWT) for the new user.', - }) - @ApiConflictResponse({ - type: ApiErrorZodDto, - description: 'A user is already registered.', - }) - async register(@Body() body: RegisterDto): Promise { - return await this.authService.register(body); - } - - @Post('login') - @HttpCode(HttpStatus.OK) - @ApiOkResponse({ - type: UserTokenDto, - description: 'The user token used to communicate with the API.', - }) - @ApiUnauthorizedResponse({ - type: ApiErrorZodDto, - description: 'Either the email or the password is invalid.', - }) - async login(@Body() body: LoginDto): Promise { - return await this.authService.login(body); - } -} diff --git a/packages/backend/src/auth/auth.module.ts b/packages/backend/src/auth/auth.module.ts deleted file mode 100644 index 3ef05fd..0000000 --- a/packages/backend/src/auth/auth.module.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ConfigModule, ConfigService } from '@nestjs/config'; -import { JwtModule, JwtSignOptions } from '@nestjs/jwt'; - -import { PrismaModule } from '../prisma/prisma.module.js'; - -import { AuthController } from './auth.controller.js'; -import { AuthService } from './auth.service.js'; -import { AuthGuard } from './guards/jwt.guard.js'; - -@Module({ - imports: [ - PrismaModule, - JwtModule.registerAsync({ - imports: [ConfigModule], - inject: [ConfigService], - useFactory: (config: ConfigService) => ({ - secret: config.getOrThrow('JWT_SECRET'), - signOptions: { - expiresIn: config.getOrThrow('JWT_EXPIRES_IN'), - }, - }), - }), - ], - controllers: [AuthController], - providers: [AuthService, AuthGuard], - exports: [AuthService, AuthGuard], -}) -export class AuthModule {} diff --git a/packages/backend/src/auth/auth.service.spec.ts b/packages/backend/src/auth/auth.service.spec.ts deleted file mode 100644 index bf0424a..0000000 --- a/packages/backend/src/auth/auth.service.spec.ts +++ /dev/null @@ -1,212 +0,0 @@ -import type { Prisma } from '@hallmaster/prisma-client'; -import { beforeEach, describe, expect, it, jest } from '@jest/globals'; -import { ConflictException, UnauthorizedException } from '@nestjs/common'; -import { JwtModule, JwtService } from '@nestjs/jwt'; -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; -import type { DeepMockProxy } from 'jest-mock-extended'; -import { mockDeep } from 'jest-mock-extended'; - -import { PrismaService } from '../prisma/prisma.service.js'; - -import { AuthService } from './auth.service.js'; -import type { RegisterDto } from './dto/register.dto.js'; - -describe('authService', () => { - let service: AuthService; - let jwtService: JwtService; - const prismaService: DeepMockProxy = mockDeep(); - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - imports: [ - JwtModule.register({ - secret: 'secret', - signOptions: { - expiresIn: '1m', - }, - }), - ], - providers: [ - AuthService, - { - provide: PrismaService, - useValue: prismaService, - }, - ], - }).compile(); - - service = module.get(AuthService); - jwtService = module.get(JwtService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); - - it('should create a user', async () => { - const credentials: RegisterDto = { - username: 'bob', - password: 'ilikealice', - }; - - prismaService.user.count.mockResolvedValueOnce(0); - - prismaService.user.create.mockResolvedValueOnce({ - username: credentials.username, - } as Prisma.UserGetPayload); - - const hashPasswordMock = jest - .spyOn(AuthService, 'hashPassword') - .mockImplementationOnce((password) => Promise.resolve(`${password}-hashed`)); - - const signAsyncMock = jest.spyOn(jwtService, 'signAsync'); - - const { token } = await service.register(credentials); - - expect(prismaService.user.count).toHaveBeenCalledTimes(1); - - expect(hashPasswordMock).toHaveBeenCalledWith(credentials.password); - expect(hashPasswordMock).toHaveBeenCalledTimes(1); - - expect(prismaService.user.create).toHaveBeenCalledWith({ - select: { - username: true, - }, - data: { - username: credentials.username, - password: `${credentials.password}-hashed`, - }, - }); - expect(prismaService.user.create).toHaveBeenCalledTimes(1); - - expect(signAsyncMock).toHaveBeenCalledWith({ - username: credentials.username, - }); - expect(signAsyncMock).toHaveBeenCalledTimes(1); - - const verifyAsyncMock = jest.spyOn(jwtService, 'verifyAsync'); - - const data = await service.verifyToken(token); - - expect(verifyAsyncMock).toHaveBeenCalledWith(token); - expect(verifyAsyncMock).toHaveBeenCalledTimes(1); - - expect(data.username).toStrictEqual(credentials.username); - }); - - it('should not create a user', async () => { - const credentials: RegisterDto = { - username: 'bob', - password: 'ilikealice', - }; - - prismaService.user.count.mockResolvedValueOnce(1); - - await expect(service.register(credentials)).rejects.toBeInstanceOf(ConflictException); - - expect(prismaService.user.count).toHaveBeenCalledTimes(1); - }); - - it('should sign in a user', async () => { - const credentials: RegisterDto = { - username: 'bob', - password: 'ilikealice', - }; - - prismaService.user.findFirst.mockResolvedValueOnce({ - username: credentials.username, - password: `${credentials.password}-hashed`, - } as Prisma.UserGetPayload); - - const verifyPasswordMock = jest - .spyOn(AuthService, 'verifyPassword') - .mockImplementationOnce((hash: string, password: string) => Promise.resolve(hash === `${password}-hashed`)); - - const signAsyncMock = jest.spyOn(jwtService, 'signAsync'); - - const { token } = await service.login(credentials); - - expect(prismaService.user.findFirst).toHaveBeenCalledWith({ - select: { - username: true, - password: true, - }, - where: { - username: credentials.username, - }, - }); - expect(prismaService.user.findFirst).toHaveBeenCalledTimes(1); - - expect(verifyPasswordMock).toHaveBeenCalledWith(`${credentials.password}-hashed`, credentials.password); - expect(verifyPasswordMock).toHaveBeenCalledTimes(1); - - expect(signAsyncMock).toHaveBeenCalledWith({ - username: credentials.username, - }); - expect(signAsyncMock).toHaveBeenCalledTimes(1); - - const verifyAsyncMock = jest.spyOn(jwtService, 'verifyAsync'); - - const data = await service.verifyToken(token); - - expect(verifyAsyncMock).toHaveBeenCalledWith(token); - expect(verifyAsyncMock).toHaveBeenCalledTimes(1); - - expect(data.username).toStrictEqual(credentials.username); - }); - - it('should sign in a user (user not found)', async () => { - const credentials: RegisterDto = { - username: 'bob', - password: 'ilikealice', - }; - - prismaService.user.findFirst.mockResolvedValueOnce(null); - - await expect(service.login(credentials)).rejects.toBeInstanceOf(UnauthorizedException); - - expect(prismaService.user.findFirst).toHaveBeenCalledWith({ - select: { - username: true, - password: true, - }, - where: { - username: credentials.username, - }, - }); - expect(prismaService.user.findFirst).toHaveBeenCalledTimes(1); - }); - - it('should sign in a user (passwords do not match)', async () => { - const credentials: RegisterDto = { - username: 'bob', - password: 'ilikealice', - }; - - prismaService.user.findFirst.mockResolvedValueOnce({ - username: credentials.username, - password: `not-${credentials.password}-hashed`, - } as Prisma.UserGetPayload); - - const verifyPasswordMock = jest - .spyOn(AuthService, 'verifyPassword') - .mockImplementationOnce((hash: string, password: string) => Promise.resolve(hash === `${password}-hashed`)); - - await expect(service.login(credentials)).rejects.toBeInstanceOf(UnauthorizedException); - - expect(prismaService.user.findFirst).toHaveBeenCalledWith({ - select: { - username: true, - password: true, - }, - where: { - username: credentials.username, - }, - }); - expect(prismaService.user.findFirst).toHaveBeenCalledTimes(1); - - expect(verifyPasswordMock).toHaveBeenCalledWith(`not-${credentials.password}-hashed`, credentials.password); - expect(verifyPasswordMock).toHaveBeenCalledTimes(1); - }); -}); diff --git a/packages/backend/src/auth/auth.service.ts b/packages/backend/src/auth/auth.service.ts deleted file mode 100644 index d0261a3..0000000 --- a/packages/backend/src/auth/auth.service.ts +++ /dev/null @@ -1,101 +0,0 @@ -import { randomBytes } from 'node:crypto'; - -import { ConflictException, Injectable, UnauthorizedException } from '@nestjs/common'; -import { JwtService } from '@nestjs/jwt'; -import { hash, argon2id, verify } from 'argon2'; - -import { PrismaService } from '../prisma/prisma.service.js'; - -import { LoginDto } from './dto/login.dto.js'; -import { RegisterDto } from './dto/register.dto.js'; -import { UserTokenDataDto } from './entities/user-token-data.entity.js'; -import { UserTokenDto } from './entities/user-token.entity.js'; - -/* https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id */ -const OWASP_CONFIGS = [ - { m: 47104, t: 1, p: 1 } /* DO NOT USE WITH ARGON2I */, - { m: 19456, t: 2, p: 1 } /* DO NOT USE WITH ARGON2I */, - { m: 12288, t: 3, p: 1 }, - { m: 9216, t: 4, p: 1 }, - { m: 7168, t: 5, p: 1 }, -]; - -@Injectable() -export class AuthService { - private static CONFIG = OWASP_CONFIGS[2]; - - constructor( - private readonly prismaService: PrismaService, - private readonly jwtService: JwtService, - ) {} - - static async hashPassword(password: string) { - return await hash(password, { - type: argon2id, - memoryCost: AuthService.CONFIG.m, - timeCost: AuthService.CONFIG.t, - parallelism: AuthService.CONFIG.p, - hashLength: 32, - salt: randomBytes(16), - }); - } - - static async verifyPassword(hash: string, password: string) { - return await verify(hash, password); - } - - async register(dto: RegisterDto): Promise { - const users = await this.prismaService.user.count(); - if (users > 0) { - throw new ConflictException(); - } - - const hashedPassword = await AuthService.hashPassword(dto.password); - - const { username } = await this.prismaService.user.create({ - select: { - username: true, - }, - data: { - username: dto.username, - password: hashedPassword, - }, - }); - - const token = await this.jwtService.signAsync({ - username: username, - }); - - return { token: token }; - } - - async login(dto: LoginDto): Promise { - const user = await this.prismaService.user.findFirst({ - select: { - username: true, - password: true, - }, - where: { - username: dto.username, - }, - }); - - if (null === user) { - throw new UnauthorizedException(); - } - - const passwordMatch = await AuthService.verifyPassword(user.password, dto.password); - if (!passwordMatch) { - throw new UnauthorizedException(); - } - - const token = await this.jwtService.signAsync({ - username: user.username, - }); - return { token }; - } - - async verifyToken(token: string): Promise { - return await this.jwtService.verifyAsync(token); - } -} diff --git a/packages/backend/src/auth/dto/login.dto.ts b/packages/backend/src/auth/dto/login.dto.ts deleted file mode 100644 index 3c2f806..0000000 --- a/packages/backend/src/auth/dto/login.dto.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; - -import { loginSchema } from '../schemas/login.schema.js'; - -export class LoginDto extends createZodDto(loginSchema) {} diff --git a/packages/backend/src/auth/dto/register.dto.ts b/packages/backend/src/auth/dto/register.dto.ts deleted file mode 100644 index 4f95994..0000000 --- a/packages/backend/src/auth/dto/register.dto.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; - -import { registerSchema } from '../schemas/register.schema.js'; - -export class RegisterDto extends createZodDto(registerSchema) {} diff --git a/packages/backend/src/auth/entities/user-token-data.entity.ts b/packages/backend/src/auth/entities/user-token-data.entity.ts deleted file mode 100644 index 9a6ea4e..0000000 --- a/packages/backend/src/auth/entities/user-token-data.entity.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; - -import { userTokenDataSchema } from '../schemas/user-token-data.schema.js'; - -export class UserTokenDataDto extends createZodDto(userTokenDataSchema) {} diff --git a/packages/backend/src/auth/entities/user-token.entity.ts b/packages/backend/src/auth/entities/user-token.entity.ts deleted file mode 100644 index 3f88a75..0000000 --- a/packages/backend/src/auth/entities/user-token.entity.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; - -import { userTokenSchema } from '../schemas/user-token.schema.js'; - -export class UserTokenDto extends createZodDto(userTokenSchema) {} diff --git a/packages/backend/src/auth/guards/jwt.guard.ts b/packages/backend/src/auth/guards/jwt.guard.ts deleted file mode 100644 index ec67cd9..0000000 --- a/packages/backend/src/auth/guards/jwt.guard.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from '@nestjs/common'; -import { FastifyRequest } from 'fastify'; - -import { AuthService } from '../auth.service.js'; - -@Injectable() -export class AuthGuard implements CanActivate { - constructor(private readonly authService: AuthService) {} - - private static extractBearerToken(request: FastifyRequest): string { - const authHeader = request.headers.authorization ?? ''; - const [bearer, token] = authHeader.split(' '); - - if (bearer !== 'Bearer' || !token) throw new UnauthorizedException(); - return token; - } - - async canActivate(context: ExecutionContext) { - const request = context.switchToHttp().getRequest(); - const token = AuthGuard.extractBearerToken(request); - - try { - const payload = await this.authService.verifyToken(token); - - Object.defineProperty(request, 'user', { - configurable: true, - value: payload, - }); - } catch { - throw new UnauthorizedException(); - } - return true; - } -} diff --git a/packages/backend/src/auth/schemas/login.schema.ts b/packages/backend/src/auth/schemas/login.schema.ts deleted file mode 100644 index 1290b3d..0000000 --- a/packages/backend/src/auth/schemas/login.schema.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { z } from 'zod'; - -export const loginSchema = z.object({ - username: z.string().min(1).meta({ - description: "The user's username.", - }), - password: z.string().min(8).meta({ - description: "The user's password.", - }), -}); - -export type Login = z.infer; diff --git a/packages/backend/src/auth/schemas/register.schema.ts b/packages/backend/src/auth/schemas/register.schema.ts deleted file mode 100644 index a4bd993..0000000 --- a/packages/backend/src/auth/schemas/register.schema.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { z } from 'zod'; - -export const registerSchema = z.object({ - username: z.string().min(1).meta({ - description: "The user's username.", - }), - password: z.string().min(8).meta({ - description: "The user's password.", - }), -}); - -export type Register = z.infer; diff --git a/packages/backend/src/auth/schemas/user-token-data.schema.ts b/packages/backend/src/auth/schemas/user-token-data.schema.ts deleted file mode 100644 index 1711ced..0000000 --- a/packages/backend/src/auth/schemas/user-token-data.schema.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { z } from 'zod'; - -export const userTokenDataSchema = z.object({ - username: z.string().meta({ description: "The authenticated user's username." }), -}); - -export type UserTokenData = z.infer; diff --git a/packages/backend/src/auth/schemas/user-token.schema.ts b/packages/backend/src/auth/schemas/user-token.schema.ts deleted file mode 100644 index 44839d6..0000000 --- a/packages/backend/src/auth/schemas/user-token.schema.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { z } from 'zod'; - -export const userTokenSchema = z.object({ - token: z.jwt().meta({ - description: 'The user session token.', - }), -}); - -export type UserToken = z.infer; diff --git a/packages/backend/src/bot/bot.controller.spec.ts b/packages/backend/src/bot/bot.controller.spec.ts deleted file mode 100644 index 60fba34..0000000 --- a/packages/backend/src/bot/bot.controller.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; -import type { DeepMockProxy } from 'jest-mock-extended'; -import { mockDeep } from 'jest-mock-extended'; - -import { AuthGuard } from '../auth/guards/jwt.guard.js'; - -import { BotController } from './bot.controller.js'; -import { BotService } from './bot.service.js'; - -describe('BotController', () => { - let controller: BotController; - const authGuard: DeepMockProxy = mockDeep(); - const botService: DeepMockProxy = mockDeep(); - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [BotController], - providers: [ - { - provide: BotService, - useValue: botService, - }, - ], - }) - .overrideGuard(AuthGuard) - .useValue(authGuard) - .compile(); - - controller = module.get(BotController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/packages/backend/src/bot/bot.controller.ts b/packages/backend/src/bot/bot.controller.ts deleted file mode 100644 index 58dd887..0000000 --- a/packages/backend/src/bot/bot.controller.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Patch, Post, UseGuards } from '@nestjs/common'; -import { - ApiAcceptedResponse, - ApiBadRequestResponse, - ApiBearerAuth, - ApiConflictResponse, - ApiCreatedResponse, - ApiFailedDependencyResponse, - ApiNoContentResponse, - ApiNotFoundResponse, - ApiOkResponse, - ApiTags, - ApiUnauthorizedResponse, -} from '@nestjs/swagger'; - -import { AuthGuard } from '../auth/guards/jwt.guard.js'; -import { ApiErrorZodDto } from '../common/dto/api-error.dto.js'; - -import { BotService } from './bot.service.js'; -import { CreateBotZodDto } from './dto/create-bot.dto.js'; -import { GetBotZodDto } from './dto/get-bot.dto.js'; -import { GetRecommendedShardsZodDto } from './dto/get-recommended-shards.dto.js'; -import { UpdateBotZodDto } from './dto/update-bot.dto.js'; - -@ApiTags('Bot') -@Controller('bot') -@ApiBearerAuth('jwt') -@UseGuards(AuthGuard) -@ApiUnauthorizedResponse({ - type: ApiErrorZodDto, - description: 'This route is protected by an Authorization header that is either not provided or invalid.', -}) -export class BotController { - constructor(private readonly botService: BotService) {} - - @Get('recommended-shards') - @ApiOkResponse({ - description: 'The recommended number of shards from the Discord API.', - type: GetRecommendedShardsZodDto, - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'No bot created beforehand.', - }) - @ApiFailedDependencyResponse({ - type: ApiErrorZodDto, - description: 'The Discord bot token is invalid or got an invalid response from the Discord API.', - }) - getRecommendedShards() { - return this.botService.getRecommendedShards(); - } - - @Post() - @HttpCode(HttpStatus.CREATED) - @ApiCreatedResponse({ - description: 'The bot informations have been retrieve correctly and it has been created in database successfully.', - type: GetBotZodDto, - }) - @ApiConflictResponse({ - type: ApiErrorZodDto, - description: 'The bot is already created.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'The request body is invalid, or the Docker image could not be pulled.', - }) - @ApiFailedDependencyResponse({ - type: ApiErrorZodDto, - description: 'The Discord bot token is invalid or got an invalid response from the Discord API.', - }) - create(@Body() createBotDto: CreateBotZodDto) { - return this.botService.create(createBotDto); - } - - @Get() - @ApiOkResponse({ - description: 'The registered bot.', - type: GetBotZodDto, - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'No bot created beforehand.', - }) - findOne() { - return this.botService.findOne(); - } - - @Patch() - @HttpCode(HttpStatus.ACCEPTED) - @ApiAcceptedResponse({ - description: 'Updated bot information.', - type: GetBotZodDto, - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'No bot to update.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'The request body or cluster layout is invalid, or the Docker image could not be pulled.', - }) - @ApiFailedDependencyResponse({ - type: ApiErrorZodDto, - description: 'The Discord bot token is invalid or got an invalid response from the Discord API.', - }) - update(@Body() updateBotDto: UpdateBotZodDto) { - return this.botService.update(updateBotDto); - } - - @Delete() - @HttpCode(HttpStatus.NO_CONTENT) - @ApiNoContentResponse({ - description: 'The bot is deleted.', - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'No bot to update.', - }) - async remove() { - await this.botService.remove(); - } -} diff --git a/packages/backend/src/bot/bot.module.ts b/packages/backend/src/bot/bot.module.ts deleted file mode 100644 index 4ba22a2..0000000 --- a/packages/backend/src/bot/bot.module.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { AuthModule } from '../auth/auth.module.js'; -import { ClustersModule } from '../clusters/clusters.module.js'; -import { DiscordModule } from '../discord/discord.module.js'; -import { DockerModule } from '../docker/docker.module.js'; -import { PrismaModule } from '../prisma/prisma.module.js'; - -import { BotController } from './bot.controller.js'; -import { BotService } from './bot.service.js'; - -@Module({ - imports: [AuthModule, PrismaModule, ClustersModule, DockerModule, DiscordModule], - controllers: [BotController], - providers: [BotService], -}) -export class BotModule {} diff --git a/packages/backend/src/bot/bot.service.spec.ts b/packages/backend/src/bot/bot.service.spec.ts deleted file mode 100644 index be61f46..0000000 --- a/packages/backend/src/bot/bot.service.spec.ts +++ /dev/null @@ -1,609 +0,0 @@ -import { jest } from '@jest/globals'; -import { BadRequestException, ConflictException, NotFoundException } from '@nestjs/common'; -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/client'; -import type { DeepMockProxy } from 'jest-mock-extended'; -import { mockDeep } from 'jest-mock-extended'; - -import { ClustersService } from '../clusters/clusters.service.js'; -import { DiscordService } from '../discord/discord.service.js'; -import { DockerService } from '../docker/docker.service.js'; -import type { CreateBotDto, UpdateBotDto } from '../index.dto.js'; -import { PrismaService } from '../prisma/prisma.service.js'; - -import { BotService } from './bot.service.js'; - -const HALLMASTER_BOT_ID = '1352006130926096504'; -const DISCORD_BOT_TOKEN = `${Buffer.from(HALLMASTER_BOT_ID).toString('base64')}.YYYYYY.ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ`; - -const MOCK_DOCKER_IMAGE = { - serverName: 'host.docker.internal:5000', - image: 'hallmaster/discord-bot', - tag: 'latest', - username: null, -}; - -const EXPECTED_DOCKER_IMAGE = { - image: 'host.docker.internal:5000/hallmaster/discord-bot:latest', - username: null, -}; - -const mockDiscordGatewayBotResponse = (status = 200, body: unknown = { shards: 1 }) => - ({ - ok: status >= 200 && status < 300, - status, - statusText: status === 401 ? 'Unauthorized' : 'OK', - json: () => Promise.resolve(body), - }) as Response; - -const DISCORD_USER = { - id: HALLMASTER_BOT_ID, - username: 'HallMaster', - global_name: 'HallMaster Bot', - discriminator: '0', - avatar: 'abc123', - banner: 'a_def456', - accent_color: 5793266, -}; - -const EXPECTED_DISCORD_PROFILE = { - name: 'HallMaster', - displayName: 'HallMaster Bot', - discriminator: '0', - avatarUrl: `https://cdn.discordapp.com/avatars/${HALLMASTER_BOT_ID}/abc123.png`, - bannerUrl: `https://cdn.discordapp.com/banners/${HALLMASTER_BOT_ID}/a_def456.gif`, - accentColor: 5793266, -}; - -const mockDiscordUserResponse = (body: unknown = DISCORD_USER) => - ({ ok: true, status: 200, statusText: 'OK', json: () => Promise.resolve(body) }) as Response; - -describe('BotService', () => { - let service: BotService; - const originalFetch = globalThis.fetch; - const fetchMock = jest.fn(); - - const prismaService: DeepMockProxy = mockDeep(); - const clustersService: DeepMockProxy = mockDeep(); - const dockerService: DeepMockProxy = mockDeep(); - - beforeAll(() => { - globalThis.fetch = fetchMock; - }); - - afterAll(() => { - globalThis.fetch = originalFetch; - }); - - beforeEach(async () => { - fetchMock.mockReset(); - fetchMock.mockResolvedValue(mockDiscordGatewayBotResponse()); - dockerService.verifyImage.mockResolvedValue(); - - const module: TestingModule = await Test.createTestingModule({ - providers: [ - BotService, - { provide: PrismaService, useValue: prismaService }, - { provide: ClustersService, useValue: clustersService }, - { provide: DockerService, useValue: dockerService }, - DiscordService, - ], - }).compile(); - - service = module.get(BotService); - }); - - it('should create the bot without layout', async () => { - const body: CreateBotDto = { - token: DISCORD_BOT_TOKEN, - dockerImage: { - image: 'host.docker.internal:5000/hallmaster/discord-bot:latest', - username: null, - password: null, - }, - }; - - (prismaService.bot.create as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - const result = await service.create(body); - - expect(result).toStrictEqual({ - id: HALLMASTER_BOT_ID, - shards: 0, - layout: [], - dockerImage: EXPECTED_DOCKER_IMAGE, - }); - }); - - it('should throw ConflictException when bot already exists', async () => { - const body: CreateBotDto = { - token: DISCORD_BOT_TOKEN, - dockerImage: { - image: 'host.docker.internal:5000/hallmaster/discord-bot:latest', - username: null, - password: null, - }, - }; - - prismaService.bot.create.mockRejectedValueOnce( - new PrismaClientKnownRequestError('Conflict', { - code: 'P2002', - clientVersion: '', - }), - ); - - await expect(service.create(body)).rejects.toBeInstanceOf(ConflictException); - }); - - it('should reject creation when Discord rejects the token', async () => { - const body: CreateBotDto = { - token: DISCORD_BOT_TOKEN, - dockerImage: { - image: 'host.docker.internal:5000/hallmaster/discord-bot:latest', - username: null, - password: null, - }, - }; - - fetchMock.mockResolvedValueOnce(mockDiscordGatewayBotResponse(401)); - - await expect(service.create(body)).rejects.toThrow('Invalid Discord bot token.'); - expect(prismaService.bot.create).not.toHaveBeenCalled(); - }); - - it('should reject creation when the Docker image cannot be pulled', async () => { - const body: CreateBotDto = { - token: DISCORD_BOT_TOKEN, - dockerImage: { - image: 'host.docker.internal:5000/hallmaster/discord-bot:latest', - username: null, - password: null, - }, - }; - - dockerService.verifyImage.mockRejectedValueOnce(new BadRequestException('Unable to pull the Docker image.')); - - await expect(service.create(body)).rejects.toBeInstanceOf(BadRequestException); - expect(prismaService.bot.create).not.toHaveBeenCalled(); - }); - - it('should find the bot with its Discord profile', async () => { - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 6, - token: DISCORD_BOT_TOKEN, - clusters: [ - { id: 0, status: 'RUNNING', shardIds: [0, 1, 2] }, - { id: 1, status: 'RUNNING', shardIds: [3, 4, 5] }, - ], - dockerImage: MOCK_DOCKER_IMAGE, - }); - fetchMock.mockResolvedValueOnce(mockDiscordUserResponse()); - - const data = await service.findOne(); - - expect(data).toStrictEqual({ - id: HALLMASTER_BOT_ID, - shards: 6, - layout: [ - { id: 0, shardIds: [0, 1, 2] }, - { id: 1, shardIds: [3, 4, 5] }, - ], - dockerImage: EXPECTED_DOCKER_IMAGE, - discord: EXPECTED_DISCORD_PROFILE, - }); - }); - - it('should find the bot without layout', async () => { - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - token: DISCORD_BOT_TOKEN, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - fetchMock.mockResolvedValueOnce(mockDiscordUserResponse()); - - const data = await service.findOne(); - - expect(data).toStrictEqual({ - id: HALLMASTER_BOT_ID, - shards: 0, - layout: [], - dockerImage: EXPECTED_DOCKER_IMAGE, - discord: EXPECTED_DISCORD_PROFILE, - }); - }); - - it('should return a null Discord profile when Discord is unreachable', async () => { - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - token: DISCORD_BOT_TOKEN, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - fetchMock.mockRejectedValueOnce(new Error('network down')); - - const data = await service.findOne(); - - expect(data.discord).toBeNull(); - }); - - it('should throw NotFoundException when no bot exists', async () => { - prismaService.bot.findFirst.mockResolvedValueOnce(null); - - await expect(service.findOne()).rejects.toBeInstanceOf(NotFoundException); - }); - - it('should update the bot layout (grow shards)', async () => { - const body: UpdateBotDto = { - layout: [ - { id: 0, shardIds: [0, 1, 2] }, - { id: 1, shardIds: [3, 4, 5] }, - { id: 2, shardIds: [6, 7, 8] }, - { shardIds: [9] }, - ], - }; - - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 7, - clusters: [ - { id: 0, status: 'RUNNING', shardIds: [0, 1, 2] }, - { id: 1, status: 'RUNNING', shardIds: [3, 4, 5] }, - { id: 2, status: 'RUNNING', shardIds: [6] }, - ], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - clustersService.remove.mockResolvedValue(); - - (prismaService.bot.update as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 10, - clusters: [ - { id: 0, status: 'UPDATING', shardIds: [0, 1, 2] }, - { id: 1, status: 'UPDATING', shardIds: [3, 4, 5] }, - { id: 2, status: 'UPDATING', shardIds: [6, 7, 8] }, - { id: 3, status: 'UPDATING', shardIds: [9] }, - ], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - clustersService.start.mockResolvedValue(); - - const data = await service.update(body); - - expect(clustersService.remove).toHaveBeenCalledWith(0); - expect(clustersService.remove).toHaveBeenCalledWith(1); - expect(clustersService.remove).toHaveBeenCalledWith(2); - expect(clustersService.remove).toHaveBeenCalledTimes(3); - - expect(clustersService.start).toHaveBeenCalledWith(0); - expect(clustersService.start).toHaveBeenCalledWith(1); - expect(clustersService.start).toHaveBeenCalledWith(2); - expect(clustersService.start).toHaveBeenCalledWith(3); - expect(clustersService.start).toHaveBeenCalledTimes(4); - - expect(data).toStrictEqual({ - id: HALLMASTER_BOT_ID, - shards: 10, - layout: [ - { id: 0, shardIds: [0, 1, 2] }, - { id: 1, shardIds: [3, 4, 5] }, - { id: 2, shardIds: [6, 7, 8] }, - { id: 3, shardIds: [9] }, - ], - dockerImage: EXPECTED_DOCKER_IMAGE, - }); - }); - - it('should set initial layout via update', async () => { - const body: UpdateBotDto = { - layout: [{ shardIds: [0, 1, 2] }, { shardIds: [3, 4, 5] }, { shardIds: [6] }], - }; - - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - (prismaService.bot.update as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 7, - clusters: [ - { id: 0, status: 'UPDATING', shardIds: [0, 1, 2] }, - { id: 1, status: 'UPDATING', shardIds: [3, 4, 5] }, - { id: 2, status: 'UPDATING', shardIds: [6] }, - ], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - clustersService.start.mockResolvedValue(); - - const data = await service.update(body); - - expect(clustersService.remove).not.toHaveBeenCalled(); - - expect(clustersService.start).toHaveBeenCalledWith(0); - expect(clustersService.start).toHaveBeenCalledWith(1); - expect(clustersService.start).toHaveBeenCalledWith(2); - expect(clustersService.start).toHaveBeenCalledTimes(3); - - expect(data).toStrictEqual({ - id: HALLMASTER_BOT_ID, - shards: 7, - layout: [ - { id: 0, shardIds: [0, 1, 2] }, - { id: 1, shardIds: [3, 4, 5] }, - { id: 2, shardIds: [6] }, - ], - dockerImage: EXPECTED_DOCKER_IMAGE, - }); - }); - - it('should update the bot layout only (same shards)', async () => { - const body: UpdateBotDto = { - layout: [ - { id: 0, shardIds: [0, 1, 2, 3, 4] }, - { id: 1, shardIds: [5, 6] }, - ], - }; - - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 7, - clusters: [ - { id: 0, status: 'STOPPED', shardIds: [0, 1, 2] }, - { id: 1, status: 'RUNNING', shardIds: [3, 4, 5] }, - { id: 2, status: 'RUNNING', shardIds: [6] }, - ], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - clustersService.remove.mockResolvedValue(); - - (prismaService.bot.update as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 7, - clusters: [ - { id: 0, status: 'UPDATING', shardIds: [0, 1, 2, 3, 4] }, - { id: 1, status: 'UPDATING', shardIds: [5, 6] }, - ], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - clustersService.start.mockResolvedValue(); - - const data = await service.update(body); - - expect(clustersService.remove).toHaveBeenCalledTimes(3); - - expect(clustersService.start).toHaveBeenCalledWith(0); - expect(clustersService.start).toHaveBeenCalledWith(1); - expect(clustersService.start).toHaveBeenCalledTimes(2); - - expect(data).toStrictEqual({ - id: HALLMASTER_BOT_ID, - shards: 7, - layout: [ - { id: 0, shardIds: [0, 1, 2, 3, 4] }, - { id: 1, shardIds: [5, 6] }, - ], - dockerImage: EXPECTED_DOCKER_IMAGE, - }); - }); - - it('should reject layout with duplicate shard IDs', async () => { - const body: UpdateBotDto = { - layout: [{ shardIds: [0, 1] }, { shardIds: [1, 2] }], - }; - - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - await expect(service.update(body)).rejects.toBeInstanceOf(BadRequestException); - }); - - it('should reject layout with out-of-range shard IDs', async () => { - const body: UpdateBotDto = { - layout: [{ shardIds: [0, 5] }], - }; - - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - await expect(service.update(body)).rejects.toBeInstanceOf(BadRequestException); - }); - - it('should reject layout with an empty cluster', async () => { - const body: UpdateBotDto = { - layout: [{ shardIds: [0, 1] }, { shardIds: [] }, { shardIds: [2] }], - }; - - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - await expect(service.update(body)).rejects.toBeInstanceOf(BadRequestException); - }); - - it('should reject layout referencing a non-existent cluster ID', async () => { - const body: UpdateBotDto = { - layout: [ - { id: 0, shardIds: [0, 1] }, - { id: 98, shardIds: [2] }, - ], - }; - - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 2, - clusters: [{ id: 0, status: 'RUNNING', shardIds: [0, 1] }], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - await expect(service.update(body)).rejects.toBeInstanceOf(BadRequestException); - }); - - it('should reject layout with duplicate cluster IDs', async () => { - const body: UpdateBotDto = { - layout: [ - { id: 0, shardIds: [0, 1] }, - { id: 0, shardIds: [2] }, - ], - }; - - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 2, - clusters: [{ id: 0, status: 'RUNNING', shardIds: [0, 1] }], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - await expect(service.update(body)).rejects.toBeInstanceOf(BadRequestException); - }); - - it('should throw NotFoundException when updating non-existent bot', async () => { - const body: UpdateBotDto = { - layout: [{ shardIds: [0, 1, 2] }, { shardIds: [3, 4] }], - }; - - prismaService.bot.findFirst.mockResolvedValueOnce(null); - - await expect(service.update(body)).rejects.toBeInstanceOf(NotFoundException); - }); - - it('should reject update when Discord rejects the new token', async () => { - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - token: DISCORD_BOT_TOKEN, - dockerImage: MOCK_DOCKER_IMAGE, - }); - - fetchMock.mockResolvedValueOnce(mockDiscordGatewayBotResponse(401)); - - await expect(service.update({ token: 'a-new-but-invalid-token' })).rejects.toThrow('Invalid Discord bot token.'); - expect(prismaService.bot.update).not.toHaveBeenCalled(); - }); - - it('should not call Discord when the token is unchanged in update', async () => { - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - token: DISCORD_BOT_TOKEN, - dockerImage: MOCK_DOCKER_IMAGE, - }); - - (prismaService.bot.update as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - await service.update({ token: DISCORD_BOT_TOKEN }); - - expect(fetchMock).not.toHaveBeenCalled(); - }); - - it('should reject update when the new Docker image cannot be pulled', async () => { - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - (prismaService.dockerImage.findUniqueOrThrow as jest.Mock).mockResolvedValueOnce({ - ...MOCK_DOCKER_IMAGE, - password: null, - }); - - dockerService.verifyImage.mockRejectedValueOnce(new BadRequestException('Unable to pull the Docker image.')); - - await expect( - service.update({ dockerImage: { image: 'host.docker.internal:5000/hallmaster/discord-bot:broken' } }), - ).rejects.toBeInstanceOf(BadRequestException); - expect(prismaService.bot.update).not.toHaveBeenCalled(); - }); - - it('should not verify Docker image when it is unchanged in update', async () => { - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - (prismaService.bot.update as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 0, - clusters: [], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - dockerService.verifyImage.mockClear(); - - await service.update({ layout: [] }); - - expect(dockerService.verifyImage).not.toHaveBeenCalled(); - }); - - it('should remove the bot and stop all clusters', async () => { - (prismaService.bot.findFirst as jest.Mock).mockResolvedValueOnce({ - id: HALLMASTER_BOT_ID, - totalShards: 5, - clusters: [ - { id: 0, status: 'STOPPED', shardIds: [0, 1, 2] }, - { id: 1, status: 'RUNNING', shardIds: [3, 4] }, - ], - dockerImage: MOCK_DOCKER_IMAGE, - }); - - prismaService.bot.delete.mockResolvedValueOnce({} as never); - clustersService.stopByCluster.mockResolvedValue(); - - const data = await service.remove(); - - expect(clustersService.stopByCluster).toHaveBeenCalledTimes(2); - - expect(data).toStrictEqual({ - id: HALLMASTER_BOT_ID, - shards: 5, - layout: [ - { id: 0, shardIds: [0, 1, 2] }, - { id: 1, shardIds: [3, 4] }, - ], - dockerImage: EXPECTED_DOCKER_IMAGE, - }); - }); - - it('should throw NotFoundException when removing non-existent bot', async () => { - prismaService.bot.findFirst.mockResolvedValueOnce(null); - - await expect(service.remove()).rejects.toBeInstanceOf(NotFoundException); - }); -}); diff --git a/packages/backend/src/bot/bot.service.ts b/packages/backend/src/bot/bot.service.ts deleted file mode 100644 index 08abb75..0000000 --- a/packages/backend/src/bot/bot.service.ts +++ /dev/null @@ -1,365 +0,0 @@ -import { BadRequestException, ConflictException, Injectable, NotFoundException } from '@nestjs/common'; -import { PrismaClientKnownRequestError } from '@prisma/client/runtime/client'; - -import { ClustersService } from '../clusters/clusters.service.js'; -import { DiscordService, type DiscordProfile } from '../discord/discord.service.js'; -import { DockerService } from '../docker/docker.service.js'; -import { PrismaService } from '../prisma/prisma.service.js'; - -import { formatDockerImage } from './bot.utils.js'; -import { CreateBotZodDto } from './dto/create-bot.dto.js'; -import { GetBotZodDto } from './dto/get-bot.dto.js'; -import { UpdateBotZodDto } from './dto/update-bot.dto.js'; - -type LayoutInput = NonNullable; - -@Injectable() -export class BotService { - constructor( - private readonly prismaService: PrismaService, - private readonly clustersService: ClustersService, - private readonly dockerService: DockerService, - private readonly discordService: DiscordService, - ) {} - - private parseDockerImage(image: string): { serverName: string; image: string; tag: string } { - const [serverName, ...path] = image.trim().split('/'); - const [imageName, tag] = path.join('/').split(':'); - return { serverName, image: imageName, tag }; - } - - private static readonly BOT_SELECT = { - id: true, - totalShards: true, - clusters: true, - dockerImage: { - select: { - serverName: true, - image: true, - tag: true, - username: true, - }, - }, - } as const; - - private getBotId(token: string): string { - return Buffer.from(token.split('.')[0], 'base64').toString('ascii'); - } - - private validateLayout(layout: LayoutInput, existingClusterIds: Set): void { - const providedIds = new Set(); - for (const [index, cluster] of layout.entries()) { - if (cluster.shardIds.length === 0) { - throw new BadRequestException(`Cluster at index ${index} is empty.`); - } - if (cluster.id !== undefined) { - if (providedIds.has(cluster.id)) { - throw new BadRequestException(`Duplicate cluster ID ${cluster.id} in layout.`); - } - if (!existingClusterIds.has(cluster.id)) { - throw new BadRequestException(`Cluster ID ${cluster.id} does not exist.`); - } - providedIds.add(cluster.id); - } - } - - const allShardIds = layout.flatMap((c) => c.shardIds); - const uniqueShardIds = new Set(allShardIds); - const totalShards = allShardIds.length; - - if (uniqueShardIds.size !== totalShards) { - throw new BadRequestException('Duplicate shard IDs found in layout.'); - } - - for (const shardId of allShardIds) { - if (shardId < 0 || shardId >= totalShards) { - throw new BadRequestException(`Shard ID ${shardId} is out of range [0, ${totalShards - 1}].`); - } - } - } - - private assignClusterIds(layout: LayoutInput): Array<{ id: number; shardIds: number[] }> { - const sorted = [...layout].sort((a, b) => Math.min(...a.shardIds) - Math.min(...b.shardIds)); - - const usedIds = new Set(); - for (const cluster of sorted) { - if (cluster.id !== undefined) usedIds.add(cluster.id); - } - - let candidate = 0; - return sorted.map((cluster) => { - if (cluster.id !== undefined) { - return { id: cluster.id, shardIds: cluster.shardIds }; - } - while (usedIds.has(candidate)) candidate++; - const id = candidate++; - usedIds.add(id); - return { id, shardIds: cluster.shardIds }; - }); - } - - private async fetchDiscordProfile(token: string): Promise { - try { - return await this.discordService.getCurrentUser(token); - } catch { - return null; - } - } - - async getRecommendedShards(): Promise<{ shards: number }> { - const bot = await this.prismaService.bot.findFirst({ - select: { token: true }, - }); - - if (bot === null) { - throw new NotFoundException('No bot created.'); - } - - return await this.discordService.getGatewayBot(bot.token); - } - - async create(createBotDto: CreateBotZodDto): Promise { - await this.discordService.getGatewayBot(createBotDto.token); - - const { serverName, image, tag } = this.parseDockerImage(createBotDto.dockerImage.image); - - await this.dockerService.verifyImage({ - serverName, - image, - tag, - username: createBotDto.dockerImage.username ?? null, - password: createBotDto.dockerImage.password ?? null, - }); - - try { - const bot = await this.prismaService.bot.create({ - data: { - id: this.getBotId(createBotDto.token), - totalShards: 0, - token: createBotDto.token, - dockerImage: { - create: { - image: image, - tag: tag, - serverName: serverName, - username: createBotDto.dockerImage.username, - password: createBotDto.dockerImage.password, - }, - }, - }, - select: BotService.BOT_SELECT, - }); - - return { - id: bot.id, - shards: bot.totalShards, - layout: bot.clusters.map((c) => ({ id: c.id, shardIds: c.shardIds })), - dockerImage: formatDockerImage(bot.dockerImage), - }; - } catch (e) { - if (e instanceof PrismaClientKnownRequestError && 'P2002' === e.code) { - throw new ConflictException(); - } - throw e; - } - } - - async findOne(): Promise { - const bot = await this.prismaService.bot.findFirst({ - select: { ...BotService.BOT_SELECT, token: true }, - }); - - if (null === bot) { - throw new NotFoundException(); - } - - return { - id: bot.id, - shards: bot.totalShards, - layout: bot.clusters.map((c) => ({ id: c.id, shardIds: c.shardIds })), - dockerImage: formatDockerImage(bot.dockerImage), - discord: await this.fetchDiscordProfile(bot.token), - }; - } - - private buildDockerImageUpdate( - input: UpdateBotZodDto['dockerImage'], - current: { - serverName: string; - image: string; - tag: string; - username: string | null; - } | null, - ): - | { - serverName?: string; - image?: string; - tag?: string; - username?: string | null; - password?: string | null; - } - | undefined { - if (!input) { - return undefined; - } - - const update: { - serverName?: string; - image?: string; - tag?: string; - username?: string | null; - password?: string | null; - } = {}; - - if (input.image !== undefined) { - const { serverName, image, tag } = this.parseDockerImage(input.image); - if (current === null || serverName !== current.serverName || image !== current.image || tag !== current.tag) { - update.serverName = serverName; - update.image = image; - update.tag = tag; - } - } - - if (input.username !== undefined && input.username !== current?.username) { - update.username = input.username; - } - - if (input.password !== undefined) { - update.password = input.password; - } - - return Object.keys(update).length > 0 ? update : undefined; - } - - async update(updateBotDto: UpdateBotZodDto): Promise { - const bot = await this.prismaService.bot.findFirst({ - select: { - ...BotService.BOT_SELECT, - token: true, - }, - }); - - if (null === bot) { - throw new NotFoundException(); - } - - const existingClusterIds = new Set(bot.clusters.map((c) => c.id)); - - const layoutInput: LayoutInput = - updateBotDto.layout ?? bot.clusters.map((c) => ({ id: c.id, shardIds: c.shardIds })); - - this.validateLayout(layoutInput, existingClusterIds); - - const resolvedLayout = this.assignClusterIds(layoutInput); - const totalShards = resolvedLayout.flatMap((c) => c.shardIds).length; - - const sortedLayout = resolvedLayout - .map((c) => ({ id: c.id, shardIds: [...c.shardIds].sort((a, b) => a - b) })) - .sort((a, b) => a.id - b.id); - const oldLayout = bot.clusters - .map((c) => ({ id: c.id, shardIds: [...c.shardIds].sort((a, b) => a - b) })) - .sort((a, b) => a.id - b.id); - const layoutChanged = JSON.stringify(sortedLayout) !== JSON.stringify(oldLayout); - - const newToken = updateBotDto.token !== undefined && updateBotDto.token !== bot.token ? updateBotDto.token : null; - const tokenChanged = newToken !== null; - - if (newToken !== null) { - await this.discordService.getGatewayBot(newToken); - } - - const dockerImageUpdate = this.buildDockerImageUpdate(updateBotDto.dockerImage, bot.dockerImage); - const dockerImageChanged = dockerImageUpdate !== undefined; - - if (dockerImageUpdate !== undefined) { - const currentImage = await this.prismaService.dockerImage.findUniqueOrThrow({ - where: { botId: bot.id }, - select: { serverName: true, image: true, tag: true, username: true, password: true }, - }); - await this.dockerService.verifyImage({ - serverName: dockerImageUpdate.serverName ?? currentImage.serverName, - image: dockerImageUpdate.image ?? currentImage.image, - tag: dockerImageUpdate.tag ?? currentImage.tag, - username: dockerImageUpdate.username !== undefined ? dockerImageUpdate.username : currentImage.username, - password: dockerImageUpdate.password !== undefined ? dockerImageUpdate.password : currentImage.password, - }); - } - - const shouldForceRestart = layoutChanged || tokenChanged || dockerImageChanged; - - const oldStatusById = new Map(bot.clusters.map((c) => [c.id, c.status])); - - for (const cluster of bot.clusters) { - await this.clustersService.remove(cluster.id); - } - - const newBot = await this.prismaService.bot.update({ - data: { - totalShards, - ...(newToken !== null && { token: newToken }), - ...(dockerImageChanged && { - dockerImage: { update: dockerImageUpdate }, - }), - clusters: { - createMany: { - data: resolvedLayout.map((cluster) => ({ - id: cluster.id, - status: shouldForceRestart || oldStatusById.get(cluster.id) !== 'STOPPED' ? 'UPDATING' : 'STOPPED', - shardIds: cluster.shardIds, - })), - }, - }, - }, - where: { - id: bot.id, - }, - select: BotService.BOT_SELECT, - }); - - for (const cluster of newBot.clusters) { - if (cluster.status !== 'STOPPED') { - await this.clustersService.start(cluster.id); - } - } - - return { - id: newBot.id, - shards: newBot.totalShards, - layout: newBot.clusters.map((c) => ({ id: c.id, shardIds: c.shardIds })), - dockerImage: formatDockerImage(newBot.dockerImage), - }; - } - - async remove(): Promise { - const bot = await this.prismaService.bot.findFirst({ - select: BotService.BOT_SELECT, - }); - if (null === bot) { - throw new NotFoundException(); - } - - try { - await this.prismaService.bot.delete({ - where: { - id: bot.id, - }, - }); - } catch (e) { - if (e instanceof PrismaClientKnownRequestError && 'P2025' === e.code) { - throw new NotFoundException(); - } - throw e; - } - - for (const cluster of bot.clusters) { - await this.clustersService.stopByCluster(cluster); - } - - return { - id: bot.id, - shards: bot.totalShards, - layout: bot.clusters.map((c) => ({ id: c.id, shardIds: c.shardIds })), - dockerImage: formatDockerImage(bot.dockerImage), - }; - } -} diff --git a/packages/backend/src/bot/bot.utils.ts b/packages/backend/src/bot/bot.utils.ts deleted file mode 100644 index 7250088..0000000 --- a/packages/backend/src/bot/bot.utils.ts +++ /dev/null @@ -1,17 +0,0 @@ -export function formatDockerImage( - dockerImage: { - serverName: string; - image: string; - tag: string; - username: string | null; - } | null, -) { - if (dockerImage === null) { - throw new Error('Docker image is required but was not found.'); - } - - return { - image: `${dockerImage.serverName}/${dockerImage.image}:${dockerImage.tag}`, - username: dockerImage.username, - }; -} diff --git a/packages/backend/src/bot/dto/create-bot.dto.ts b/packages/backend/src/bot/dto/create-bot.dto.ts deleted file mode 100644 index 9bf35c7..0000000 --- a/packages/backend/src/bot/dto/create-bot.dto.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const CreateBotDockerImageSchema = z.object({ - image: z.string().meta({ - description: - 'The Docker image to use, following this format: hostname/repo/image:tag. (example: hallmaster/discord-bot:tag)', - }), - username: z.string().optional().meta({ - description: 'The username used to authenticate to a remote Docker registry.', - }), - password: z.string().optional().meta({ - description: 'The password used to authenticate to a remote Docker registry.', - }), -}); - -export const CreateBotSchema = z.object({ - token: z.string().meta({ - description: 'The token of the Discord bot.', - }), - dockerImage: CreateBotDockerImageSchema.meta({ - description: 'The information required to pull the Discord bot Docker image.', - }), -}); - -export class CreateBotZodDto extends createZodDto(CreateBotSchema) {} - -export type CreateBotDto = z.infer; diff --git a/packages/backend/src/bot/dto/get-bot.dto.ts b/packages/backend/src/bot/dto/get-bot.dto.ts deleted file mode 100644 index efab6ca..0000000 --- a/packages/backend/src/bot/dto/get-bot.dto.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const GetBotDockerImageSchema = z.object({ - image: z.string().meta({ - description: 'The full Docker image URI (serverName/image:tag).', - }), - username: z.string().nullable().meta({ - description: 'The username used to authenticate to the Docker registry.', - }), -}); - -export const GetBotLayoutClusterSchema = z.object({ - id: z.number().int().nonnegative().meta({ - description: 'The cluster ID (sequential per bot).', - }), - shardIds: z.array(z.number().nonnegative()).meta({ - description: 'The shard IDs assigned to that cluster.', - }), -}); - -export const GetBotDiscordSchema = z.object({ - name: z.string().meta({ - description: 'The Discord username of the bot.', - }), - displayName: z.string().nullable().meta({ - description: 'The Discord display name (global name) of the bot, or null if none is set.', - }), - discriminator: z.string().meta({ - description: 'The Discord discriminator.', - }), - avatarUrl: z.string().nullable().meta({ - description: 'URL of the bot avatar on the Discord CDN, or null if none is set.', - }), - bannerUrl: z.string().nullable().meta({ - description: 'URL of the bot banner on the Discord CDN, or null if none is set.', - }), - accentColor: z.number().int().nullable().meta({ - description: 'The bot profile accent color as an integer (0xRRGGBB), usable as a fallback when no banner is set.', - }), -}); - -export const GetBotSchema = z.object({ - id: z.string().meta({ - description: 'The bot ID.', - }), - shards: z.number().nonnegative().meta({ - description: 'The total number of shards for the bot.', - }), - layout: z.array(GetBotLayoutClusterSchema).meta({ - description: 'The cluster layout. Each element is a cluster with its ID and assigned shard IDs.', - }), - dockerImage: GetBotDockerImageSchema.meta({ - description: 'The Docker image configuration associated with the bot.', - }), - discord: GetBotDiscordSchema.nullable().optional().meta({ - description: "The bot's Discord profile.", - }), -}); - -export class GetBotZodDto extends createZodDto(GetBotSchema) {} - -export type GetBotDto = z.infer; diff --git a/packages/backend/src/bot/dto/get-recommended-shards.dto.ts b/packages/backend/src/bot/dto/get-recommended-shards.dto.ts deleted file mode 100644 index 8b31ced..0000000 --- a/packages/backend/src/bot/dto/get-recommended-shards.dto.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const GetRecommendedShardsSchema = z.object({ - shards: z.int().positive().meta({ - description: 'The recommended number of shards for the bot.', - }), -}); - -export class GetRecommendedShardsZodDto extends createZodDto(GetRecommendedShardsSchema) {} - -export type GetRecommendedShardsDto = z.infer; diff --git a/packages/backend/src/bot/dto/update-bot.dto.ts b/packages/backend/src/bot/dto/update-bot.dto.ts deleted file mode 100644 index 57fca7a..0000000 --- a/packages/backend/src/bot/dto/update-bot.dto.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -import { CreateBotDockerImageSchema, CreateBotSchema } from './create-bot.dto.js'; - -export const LayoutClusterSchema = z.object({ - id: z.number().int().nonnegative().optional().meta({ - description: 'The cluster ID. Omit to create a new cluster (next available ID will be assigned).', - }), - shardIds: z.array(z.number().nonnegative()).min(1).meta({ - description: 'The shard IDs assigned to that cluster.', - }), -}); - -export const UpdateBotSchema = CreateBotSchema.extend({ - layout: z.array(LayoutClusterSchema).min(1).meta({ - description: - 'The cluster layout. Each element references an existing cluster by ID (or omits it to create a new one) along with its shard IDs.', - }), - dockerImage: CreateBotDockerImageSchema.partial().meta({ - description: 'Partial Docker image configuration. Any provided field will be updated.', - }), -}).partial(); - -export class UpdateBotZodDto extends createZodDto(UpdateBotSchema) {} - -export type UpdateBotDto = z.infer; diff --git a/packages/backend/src/clusters/clusters.controller.spec.ts b/packages/backend/src/clusters/clusters.controller.spec.ts deleted file mode 100644 index 0f1c854..0000000 --- a/packages/backend/src/clusters/clusters.controller.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; -import type { DeepMockProxy } from 'jest-mock-extended'; -import { mockDeep } from 'jest-mock-extended'; - -import { AuthGuard } from '../auth/guards/jwt.guard.js'; - -import { ClustersController } from './clusters.controller.js'; -import { ClustersService } from './clusters.service.js'; - -describe('ClustersController', () => { - let controller: ClustersController; - const authGuard: DeepMockProxy = mockDeep(); - const clusterService: DeepMockProxy = mockDeep(); - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - controllers: [ClustersController], - providers: [ - { - provide: ClustersService, - useValue: clusterService, - }, - ], - }) - .overrideGuard(AuthGuard) - .useValue(authGuard) - .compile(); - - controller = module.get(ClustersController); - }); - - it('should be defined', () => { - expect(controller).toBeDefined(); - }); -}); diff --git a/packages/backend/src/clusters/clusters.controller.ts b/packages/backend/src/clusters/clusters.controller.ts deleted file mode 100644 index ce60991..0000000 --- a/packages/backend/src/clusters/clusters.controller.ts +++ /dev/null @@ -1,320 +0,0 @@ -import { Readable } from 'node:stream'; - -import { - Controller, - Delete, - Get, - HttpCode, - HttpStatus, - MessageEvent, - Param, - Post, - Query, - Sse, - UseGuards, -} from '@nestjs/common'; -import { - ApiBadRequestResponse, - ApiBearerAuth, - ApiInternalServerErrorResponse, - ApiNoContentResponse, - ApiNotFoundResponse, - ApiOkResponse, - ApiProduces, - ApiTags, - ApiUnauthorizedResponse, -} from '@nestjs/swagger'; -import { Observable, timer, exhaustMap, map, from } from 'rxjs'; - -import { AuthGuard } from '../auth/guards/jwt.guard.js'; -import { ApiErrorZodDto } from '../common/dto/api-error.dto.js'; - -import { ClustersService } from './clusters.service.js'; -import { ClusterBulkActionResultZodDto } from './dto/cluster-bulk-action-result.dto.js'; -import { ClusterIdParamZodDto } from './dto/cluster-id-param.dto.js'; -import { GetAggregateStatsZodDto } from './dto/get-aggregate-stats.dto.js'; -import { GetClusterLogsQueryZodDto, GetClusterLogsZodDto } from './dto/get-cluster-logs.dto.js'; -import { GetClusterStatsDto, GetClusterStatsZodDto } from './dto/get-cluster-stats.dto.js'; -import { GetClusterZodDto } from './dto/get-cluster.dto.js'; -import { SseIntervalQueryZodDto } from './dto/sse-interval-query.dto.js'; - -@ApiTags('Clusters') -@Controller('clusters') -@ApiBearerAuth('jwt') -@UseGuards(AuthGuard) -@ApiUnauthorizedResponse({ - type: ApiErrorZodDto, - description: 'This route is protected by an Authorization header that is either not provided or invalid.', -}) -export class ClustersController { - constructor(private readonly clustersService: ClustersService) {} - - @Get() - @ApiOkResponse({ - description: 'The list of clusters.', - type: GetClusterZodDto, - isArray: true, - }) - findAll() { - return this.clustersService.findAll(); - } - - @Sse('stream') - @ApiOkResponse({ - description: 'SSE stream that emits the full list of clusters at a configurable interval (default 5s).', - type: GetClusterZodDto, - isArray: true, - }) - @ApiProduces('text/event-stream') - streamAll(@Query() query: SseIntervalQueryZodDto): Observable { - return timer(0, query.interval * 1000).pipe( - exhaustMap(() => from(this.clustersService.findAll())), - map((clusters) => ({ data: clusters }) as MessageEvent), - ); - } - - @Post('start') - @HttpCode(HttpStatus.OK) - @ApiOkResponse({ - type: ClusterBulkActionResultZodDto, - description: - 'Start every cluster in parallel. Already-running clusters are no-ops. The response lists clusters that succeeded and those that failed, with the failure reason.', - }) - async startAll() { - return await this.clustersService.startAll(); - } - - @Post('stop') - @HttpCode(HttpStatus.OK) - @ApiOkResponse({ - type: ClusterBulkActionResultZodDto, - description: - 'Stop every cluster in parallel. Already-stopped clusters are no-ops. The response lists clusters that succeeded and those that failed, with the failure reason.', - }) - async stopAll() { - return await this.clustersService.stopAll(); - } - - @Post('restart') - @HttpCode(HttpStatus.OK) - @ApiOkResponse({ - type: ClusterBulkActionResultZodDto, - description: - 'Restart every cluster in parallel (stop + start). Stopped clusters are simply started. The response lists clusters that succeeded and those that failed, with the failure reason.', - }) - async restartAll() { - return await this.clustersService.restartAll(); - } - - @Sse('stats/stream') - @ApiOkResponse({ - description: - 'SSE stream that emits the stats of every running cluster at a configurable interval (default 5s). Clusters whose stats failed to fetch are omitted.', - type: GetAggregateStatsZodDto, - }) - @ApiProduces('text/event-stream') - streamAggregateStats(@Query() query: SseIntervalQueryZodDto): Observable { - return this.clustersService - .streamAggregateStats(query.interval) - .pipe(map((stats) => ({ data: stats }) as MessageEvent)); - } - - @Get(':id') - @ApiOkResponse({ - description: 'The cluster based on the given ID.', - type: GetClusterZodDto, - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The ID points to an unresolved cluster.', - }) - findOne(@Param() { id }: ClusterIdParamZodDto) { - return this.clustersService.findOne(id); - } - - @Delete(':id') - @HttpCode(HttpStatus.NO_CONTENT) - @ApiNoContentResponse({ - description: 'The cluster with the given ID has been deleted.', - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The ID points to an unresolved cluster.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'Unable to stop or remove the cluster container.', - }) - async remove(@Param() { id }: ClusterIdParamZodDto) { - await this.clustersService.remove(id); - } - - @Post(':id/start') - @HttpCode(HttpStatus.NO_CONTENT) - @ApiNoContentResponse({ - description: 'The cluster with the given ID is starting.', - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The cluster ID is unresolved, or the bot has no Docker image configured.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'Unable to provision or start the cluster container.', - }) - @ApiInternalServerErrorResponse({ - type: ApiErrorZodDto, - description: 'An unexpected error occurred while starting the cluster.', - }) - async start(@Param() { id }: ClusterIdParamZodDto) { - await this.clustersService.start(id); - } - - @Post(':id/stop') - @HttpCode(HttpStatus.NO_CONTENT) - @ApiNoContentResponse({ - description: 'The cluster with the given ID has been stopped.', - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The ID points to an unresolved cluster.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'Unable to stop the cluster container.', - }) - async stop(@Param() { id }: ClusterIdParamZodDto) { - await this.clustersService.stop(id); - } - - @Post(':id/restart') - @HttpCode(HttpStatus.NO_CONTENT) - @ApiNoContentResponse({ - description: 'The cluster with the given ID is restarting.', - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The cluster ID is unresolved, or the bot has no Docker image configured.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'Unable to restart the cluster container.', - }) - @ApiInternalServerErrorResponse({ - type: ApiErrorZodDto, - description: 'An unexpected error occurred while restarting the cluster.', - }) - async restart(@Param() { id }: ClusterIdParamZodDto) { - await this.clustersService.restart(id); - } - - @Get(':id/logs') - @ApiProduces('text/plain') - @ApiOkResponse({ - type: GetClusterLogsZodDto, - description: 'The logs of the cluster.', - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The ID points to an unresolved cluster.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'The cluster has no bound container.', - }) - async getLogs(@Param() { id }: ClusterIdParamZodDto, @Query() query: GetClusterLogsQueryZodDto) { - return await this.clustersService.logs( - id, - query.since ? new Date(query.since) : undefined, - query.until ? new Date(query.until) : undefined, - query.tail, - ); - } - - @Sse(':id/logs/stream') - @ApiProduces('text/event-stream') - @UseGuards(AuthGuard) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The ID points to an unresolved cluster.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'The cluster has no bound container.', - }) - streamLogs(@Param() { id }: ClusterIdParamZodDto): Observable { - return new Observable((subscriber) => { - let stream: Readable | undefined; - - this.clustersService - .streamLogs(id) - .then((s) => { - stream = s; - - stream.on('data', (log: { content: string; stream: string; timestamp?: string }) => { - subscriber.next({ data: log } as MessageEvent); - }); - - stream.on('end', () => subscriber.complete()); - stream.on('error', (err) => subscriber.error(err)); - }) - .catch((err) => subscriber.error(err)); - - return () => { - stream?.destroy(); - }; - }); - } - - @Get(':id/stats') - @ApiOkResponse({ - type: GetClusterStatsZodDto, - description: 'The stats of the cluster.', - }) - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The ID points to an unresolved cluster.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'The requested cluster has no bound container or its not running.', - }) - async getStats(@Param() { id }: ClusterIdParamZodDto) { - return await this.clustersService.stats(id); - } - - @Sse(':id/stats/stream') - @ApiOkResponse({ - description: 'SSE stream that emits the stats of the cluster.', - type: GetClusterStatsZodDto, - }) - @ApiProduces('text/event-stream') - @ApiNotFoundResponse({ - type: ApiErrorZodDto, - description: 'The ID points to an unresolved cluster.', - }) - @ApiBadRequestResponse({ - type: ApiErrorZodDto, - description: 'The requested cluster has no bound container or its not running.', - }) - streamStats(@Param() { id }: ClusterIdParamZodDto): Observable { - return new Observable((subscriber) => { - let stream: Readable | undefined; - - this.clustersService - .streamStats(id) - .then((s) => { - stream = s; - - stream.on('data', (stats: GetClusterStatsDto) => subscriber.next({ data: stats } as MessageEvent)); - stream.on('end', () => subscriber.complete()); - stream.on('error', (err) => subscriber.error(err)); - }) - .catch((err) => subscriber.error(err)); - - return () => { - stream?.destroy(); - }; - }); - } -} diff --git a/packages/backend/src/clusters/clusters.module.ts b/packages/backend/src/clusters/clusters.module.ts deleted file mode 100644 index aacf456..0000000 --- a/packages/backend/src/clusters/clusters.module.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { AuthModule } from '../auth/auth.module.js'; -import { DockerModule } from '../docker/docker.module.js'; -import { PrismaModule } from '../prisma/prisma.module.js'; - -import { ClustersController } from './clusters.controller.js'; -import { ClustersService } from './clusters.service.js'; - -@Module({ - imports: [AuthModule, PrismaModule, DockerModule], - controllers: [ClustersController], - providers: [ClustersService], - exports: [ClustersService], -}) -export class ClustersModule {} diff --git a/packages/backend/src/clusters/clusters.service.spec.ts b/packages/backend/src/clusters/clusters.service.spec.ts deleted file mode 100644 index 1f38947..0000000 --- a/packages/backend/src/clusters/clusters.service.spec.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; -import type { DeepMockProxy } from 'jest-mock-extended'; -import { mockDeep } from 'jest-mock-extended'; - -import { DockerService } from '../docker/docker.service.js'; -import { PrismaService } from '../prisma/prisma.service.js'; - -import { ClustersService } from './clusters.service.js'; - -describe('ClustersService', () => { - let service: ClustersService; - const prismaService: DeepMockProxy = mockDeep(); - const dockerService: DeepMockProxy = mockDeep(); - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - ClustersService, - { - provide: PrismaService, - useValue: prismaService, - }, - { - provide: DockerService, - useValue: dockerService, - }, - ], - }).compile(); - - service = module.get(ClustersService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/packages/backend/src/clusters/clusters.service.ts b/packages/backend/src/clusters/clusters.service.ts deleted file mode 100644 index 3531cf8..0000000 --- a/packages/backend/src/clusters/clusters.service.ts +++ /dev/null @@ -1,328 +0,0 @@ -import type { Readable } from 'node:stream'; - -import type { Cluster } from '@hallmaster/prisma-client'; -import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common'; -import { Observable } from 'rxjs'; - -import { DockerService } from '../docker/docker.service.js'; -import { PrismaService } from '../prisma/prisma.service.js'; - -import { ClusterBulkActionResultDto } from './dto/cluster-bulk-action-result.dto.js'; -import { GetAggregateStatsDto } from './dto/get-aggregate-stats.dto.js'; -import { GetClusterStatsDto } from './dto/get-cluster-stats.dto.js'; - -@Injectable() -export class ClustersService { - constructor( - private readonly prismaService: PrismaService, - private readonly dockerService: DockerService, - ) {} - - private async getFullResource(id: number) { - const resource = await this.prismaService.cluster.findFirst({ - select: { - bot: true, - containerId: true, - id: true, - shardIds: true, - status: true, - botId: true, - }, - where: { id }, - }); - - if (null === resource) { - throw new NotFoundException(); - } - - return resource; - } - - async findAll() { - const clusters = await this.prismaService.cluster.findMany({ - select: { - id: true, - shardIds: true, - status: true, - botId: true, - containerId: true, - }, - orderBy: { id: 'asc' }, - }); - - return await Promise.all( - clusters.map(async (c) => ({ - id: c.id, - shardIds: c.shardIds, - status: await this.dockerService.reconcileClusterStatus(c), - })), - ); - } - - async findOne(id: number) { - const resource = await this.prismaService.cluster.findFirst({ - select: { - id: true, - shardIds: true, - status: true, - botId: true, - containerId: true, - }, - where: { id }, - }); - - if (null === resource) { - throw new NotFoundException(); - } - - return { - id: resource.id, - shardIds: resource.shardIds, - status: await this.dockerService.reconcileClusterStatus(resource), - }; - } - - async remove(id: number) { - const resource = await this.getFullResource(id); - - await this.dockerService.remove({ - id: resource.id, - containerId: resource.containerId, - botId: resource.botId, - shardIds: resource.shardIds, - status: resource.status, - }); - } - - async start(id: number) { - const resource = await this.getFullResource(id); - - await this.dockerService.start(resource.bot, { - id: resource.id, - containerId: resource.containerId, - botId: resource.botId, - shardIds: resource.shardIds, - status: resource.status, - }); - } - - async stop(id: number) { - const resource = await this.getFullResource(id); - - await this.dockerService.stop({ - id: resource.id, - containerId: resource.containerId, - botId: resource.botId, - shardIds: resource.shardIds, - status: resource.status, - }); - } - - async stopByCluster(cluster: Cluster) { - await this.dockerService.stop(cluster); - } - - async restart(id: number) { - const resource = await this.getFullResource(id); - - await this.dockerService.restart(resource.bot, { - id: resource.id, - containerId: resource.containerId, - botId: resource.botId, - shardIds: resource.shardIds, - status: resource.status, - }); - } - - async streamLogs(id: number, tail: number | 'all' = 0): Promise { - const resource = await this.getFullResource(id); - if (null === resource.containerId) { - throw new BadRequestException('The cluster has no container ID.'); - } - return await this.dockerService.streamContainerLogs(resource.containerId, tail); - } - - async logs(id: number, since?: Date, until?: Date, tail?: number | 'all') { - const resource = await this.getFullResource(id); - - if (null === resource.containerId) { - throw new BadRequestException('The cluster has no container ID.'); - } - - return await this.dockerService.getContainerLogs(resource.containerId, since, until, tail); - } - - async stats(id: number) { - const resource = await this.getFullResource(id); - - if (null === resource.containerId) { - throw new BadRequestException('The cluster has no container ID.'); - } - - if (resource.status !== 'RUNNING') { - throw new BadRequestException('Unable to gather stats on a non-running cluster.'); - } - - return await this.dockerService.getContainerStats(resource.containerId); - } - - async streamStats(id: number): Promise { - const resource = await this.getFullResource(id); - - if (null === resource.containerId) { - throw new BadRequestException('The cluster has no container ID.'); - } - - if (resource.status !== 'RUNNING') { - throw new BadRequestException('Unable to gather stats on a non-running cluster.'); - } - - return await this.dockerService.streamContainerStats(resource.containerId); - } - - async startAll(): Promise { - return await this.runBulkAction((id) => this.start(id)); - } - - async stopAll(): Promise { - return await this.runBulkAction((id) => this.stop(id)); - } - - async restartAll(): Promise { - return await this.runBulkAction((id) => this.restart(id)); - } - - private async runBulkAction(action: (id: number) => Promise): Promise { - const clusters = await this.prismaService.cluster.findMany({ - select: { id: true }, - orderBy: { id: 'asc' }, - }); - - const settled = await Promise.allSettled(clusters.map((c) => action(c.id))); - - const succeeded: number[] = []; - const failed: Array<{ id: number; reason: string }> = []; - - settled.forEach((result, index) => { - const id = clusters[index].id; - if (result.status === 'fulfilled') { - succeeded.push(id); - } else { - const reason = result.reason instanceof Error ? result.reason.message : String(result.reason); - failed.push({ id, reason }); - } - }); - - return { succeeded, failed }; - } - - async aggregateStats(): Promise { - const clusters = await this.prismaService.cluster.findMany({ - where: { status: 'RUNNING', containerId: { not: null } }, - select: { id: true, containerId: true }, - }); - - const runnable = clusters.filter((c): c is { id: number; containerId: string } => c.containerId !== null); - - const results = await Promise.allSettled( - runnable.map(async (c) => ({ - id: c.id, - stats: await this.dockerService.getContainerStats(c.containerId), - })), - ); - - const aggregate: GetAggregateStatsDto = {}; - for (const result of results) { - if (result.status === 'fulfilled') { - aggregate[result.value.id] = result.value.stats; - } - } - - return aggregate; - } - - streamAggregateStats(intervalSeconds: number): Observable { - return new Observable((subscriber) => { - const streams = new Map(); - const latest = new Map(); - let closed = false; - - const removeStream = (id: number) => { - streams.get(id)?.destroy(); - streams.delete(id); - latest.delete(id); - }; - - const addStream = async (id: number, containerId: string) => { - if (streams.has(id)) { - return; - } - - try { - const stream = await this.dockerService.streamContainerStats(containerId); - - if (closed) { - stream.destroy(); - return; - } - - streams.set(id, stream); - stream.on('data', (stats: GetClusterStatsDto) => latest.set(id, stats)); - stream.on('error', () => removeStream(id)); - stream.on('end', () => removeStream(id)); - } catch { - // the next reconcile tick will retry opening this stream - } - }; - - const reconcile = async () => { - let clusters: Array<{ id: number; containerId: string | null }>; - try { - clusters = await this.prismaService.cluster.findMany({ - where: { status: 'RUNNING', containerId: { not: null } }, - select: { id: true, containerId: true }, - }); - } catch { - return; - } - - const running = new Map( - clusters - .filter((c): c is { id: number; containerId: string } => c.containerId !== null) - .map((c) => [c.id, c.containerId] as const), - ); - - for (const id of [...streams.keys()]) { - if (!running.has(id)) { - removeStream(id); - } - } - - for (const [id, containerId] of running) { - void addStream(id, containerId); - } - }; - - const emit = () => { - const snapshot: GetAggregateStatsDto = {}; - for (const [id, stats] of latest) { - snapshot[id] = stats; - } - subscriber.next(snapshot); - }; - - void reconcile(); - const reconcileTimer = setInterval(() => void reconcile(), intervalSeconds * 1000); - const emitTimer = setInterval(emit, intervalSeconds * 1000); - - return () => { - closed = true; - clearInterval(reconcileTimer); - clearInterval(emitTimer); - for (const id of [...streams.keys()]) { - removeStream(id); - } - }; - }); - } -} diff --git a/packages/backend/src/clusters/dto/cluster-bulk-action-result.dto.ts b/packages/backend/src/clusters/dto/cluster-bulk-action-result.dto.ts deleted file mode 100644 index a8a300b..0000000 --- a/packages/backend/src/clusters/dto/cluster-bulk-action-result.dto.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const ClusterBulkActionResultSchema = z.object({ - succeeded: z.array(z.number().int().nonnegative()).meta({ - description: 'IDs of clusters where the action completed successfully.', - }), - failed: z - .array( - z.object({ - id: z.number().int().nonnegative(), - reason: z.string(), - }), - ) - .meta({ - description: 'Clusters where the action failed, along with the failure reason.', - }), -}); - -export class ClusterBulkActionResultZodDto extends createZodDto(ClusterBulkActionResultSchema) {} - -export type ClusterBulkActionResultDto = z.infer; diff --git a/packages/backend/src/clusters/dto/cluster-id-param.dto.ts b/packages/backend/src/clusters/dto/cluster-id-param.dto.ts deleted file mode 100644 index 7f0dc72..0000000 --- a/packages/backend/src/clusters/dto/cluster-id-param.dto.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const ClusterIdParamSchema = z.object({ - id: z.coerce.number().int().nonnegative().meta({ - description: 'The cluster ID (sequential per bot, starting at 0).', - }), -}); - -export class ClusterIdParamZodDto extends createZodDto(ClusterIdParamSchema) {} - -export type ClusterIdParamDto = z.infer; diff --git a/packages/backend/src/clusters/dto/get-aggregate-stats.dto.ts b/packages/backend/src/clusters/dto/get-aggregate-stats.dto.ts deleted file mode 100644 index 6ce1e14..0000000 --- a/packages/backend/src/clusters/dto/get-aggregate-stats.dto.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -import { GetClusterStatsSchema } from './get-cluster-stats.dto.js'; - -export const GetAggregateStatsSchema = z.record(z.coerce.number().int().nonnegative(), GetClusterStatsSchema).meta({ - description: 'Stats of every running cluster, keyed by cluster ID. Clusters whose stats failed to fetch are omitted.', -}); - -export class GetAggregateStatsZodDto extends createZodDto(GetAggregateStatsSchema) {} - -export type GetAggregateStatsDto = z.infer; diff --git a/packages/backend/src/clusters/dto/get-cluster-logs.dto.ts b/packages/backend/src/clusters/dto/get-cluster-logs.dto.ts deleted file mode 100644 index 8fc2b42..0000000 --- a/packages/backend/src/clusters/dto/get-cluster-logs.dto.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const GetClusterLogsQuerySchema = z.object({ - since: z.iso.datetime().optional().meta({ - description: 'At which point in time does the logs collection start.', - }), - until: z.iso.datetime().optional().meta({ - description: 'At which point in time does the logs collection end.', - }), - tail: z.coerce.number().positive().min(1).or(z.literal('all')).optional().default('all').meta({ - description: "How many logs to fetch, from latest to oldest. 'all' gets all the logs.", - }), -}); - -export class GetClusterLogsQueryZodDto extends createZodDto(GetClusterLogsQuerySchema) {} - -export type GetClusterLogsQueryDto = z.infer; - -export const GetClusterLogSchema = z.object({ - content: z.string().meta({ - description: 'The content of a log line.', - }), - stream: z.union([z.literal('STDOUT'), z.literal('STDERR')]).meta({ - description: 'The stream that the log was published into.', - }), - timestamp: z.string().optional().meta({ - description: 'RFC3339Nano timestamp emitted by the Docker daemon for that log line.', - }), -}); - -export const GetClusterLogsSchema = z.array(GetClusterLogSchema).meta({ - description: 'Logs (line by line) of a container.', -}); - -export class GetClusterLogsZodDto extends createZodDto(GetClusterLogsSchema) {} - -export type GetClusterLogsDto = z.infer; diff --git a/packages/backend/src/clusters/dto/get-cluster-stats.dto.ts b/packages/backend/src/clusters/dto/get-cluster-stats.dto.ts deleted file mode 100644 index 0f921dd..0000000 --- a/packages/backend/src/clusters/dto/get-cluster-stats.dto.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -const GetClusterStatsProcessesUsageSchema = z.object({ - usage: z.number().meta({ - description: 'The number of processes running in the cluster.', - }), - percentage: z.number().meta({ - description: 'The number of running processes in the cluster over the limit.', - }), -}); - -const GetClusterStatsMemoryUsageSchema = z.object({ - usage: z.number().meta({ - description: 'The number of bytes used in memory.', - }), - percentage: z.number().meta({ - description: 'The percentage of the available memory used by the cluster.', - }), -}); - -const GetClusterStatsNetworkSchema = z.object({ - interface: z.string().meta({ - description: 'The networking interface name.', - }), - transmitted: z.number().meta({ - description: 'The number of bytes transmitted by the interface.', - }), - received: z.number().meta({ - description: 'The number of bytes received by the interface.', - }), -}); - -const GetClusterStatsDiskSchema = z.object({ - read: z.number().nullable().meta({ - description: 'The number of bytes read from disk. The value is null if no disk interface is detected.', - }), - write: z.number().nullable().meta({ - description: 'The number of bytes written to disk. The value is null if no disk interface is detected.', - }), -}); - -export const GetClusterStatsSchema = z.object({ - cpuPercentage: z.number().meta({ - description: 'The percentage of CPU utilization.', - }), - processes: GetClusterStatsProcessesUsageSchema, - memory: GetClusterStatsMemoryUsageSchema, - disk: GetClusterStatsDiskSchema, - networks: z.array(GetClusterStatsNetworkSchema).meta({ - description: 'The usage of each detected networking interface in the cluster.', - }), -}); - -export class GetClusterStatsZodDto extends createZodDto(GetClusterStatsSchema) {} - -export type GetClusterStatsDto = z.infer; diff --git a/packages/backend/src/clusters/dto/get-cluster.dto.ts b/packages/backend/src/clusters/dto/get-cluster.dto.ts deleted file mode 100644 index ae5f4b0..0000000 --- a/packages/backend/src/clusters/dto/get-cluster.dto.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const GetClusterSchema = z.object({ - id: z.number().int().nonnegative().meta({ - description: 'The cluster ID (sequential per bot, starting at 0).', - }), - shardIds: z.array(z.number()).meta({ - description: 'The shard IDs associated to that cluster.', - }), - status: z.enum(['STARTING', 'RUNNING', 'STOPPED', 'ERROR']).meta({ - description: 'The current status of the cluster.', - }), -}); - -export class GetClusterZodDto extends createZodDto(GetClusterSchema) {} - -export type GetClusterDto = z.infer; diff --git a/packages/backend/src/clusters/dto/sse-interval-query.dto.ts b/packages/backend/src/clusters/dto/sse-interval-query.dto.ts deleted file mode 100644 index cfb88b6..0000000 --- a/packages/backend/src/clusters/dto/sse-interval-query.dto.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const SseIntervalQuerySchema = z.object({ - interval: z.coerce.number().positive().min(1).max(120).optional().default(5).meta({ - description: 'Refresh interval in seconds (1–120). Defaults to 5.', - }), -}); - -export class SseIntervalQueryZodDto extends createZodDto(SseIntervalQuerySchema) {} diff --git a/packages/backend/src/common/dto/api-error.dto.ts b/packages/backend/src/common/dto/api-error.dto.ts deleted file mode 100644 index 004fda2..0000000 --- a/packages/backend/src/common/dto/api-error.dto.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { createZodDto } from 'nestjs-zod'; -import { z } from 'zod'; - -export const ApiErrorIssueSchema = z.object({ - path: z.array(z.union([z.string(), z.number()])).meta({ - description: 'Path to the field that failed validation (e.g. ["interval"]).', - }), - message: z.string().meta({ - description: 'A human-readable reason the field is invalid (e.g. "Expected number").', - }), - code: z.string().meta({ - description: 'The Zod issue code (e.g. "invalid_type").', - }), -}); - -export const ApiErrorSchema = z.object({ - statusCode: z.number().int().meta({ - description: 'The HTTP status code of the error.', - }), - error: z.string().meta({ - description: 'The short reason phrase associated with the status code (e.g. "Bad Request").', - }), - message: z.string().meta({ - description: 'A human-readable description of what went wrong.', - }), - issues: z.array(ApiErrorIssueSchema).optional().meta({ - description: 'Field-level validation errors. Present only when the request failed schema validation.', - }), -}); - -export class ApiErrorZodDto extends createZodDto(ApiErrorSchema) {} - -export type ApiErrorDto = z.infer; diff --git a/packages/backend/src/common/filters/all-exceptions.filter.spec.ts b/packages/backend/src/common/filters/all-exceptions.filter.spec.ts deleted file mode 100644 index 7166007..0000000 --- a/packages/backend/src/common/filters/all-exceptions.filter.spec.ts +++ /dev/null @@ -1,78 +0,0 @@ -import type { ArgumentsHost } from '@nestjs/common'; -import { BadRequestException, NotFoundException } from '@nestjs/common'; - -import { AllExceptionsFilter } from './all-exceptions.filter.js'; - -describe('AllExceptionsFilter', () => { - const filter = new AllExceptionsFilter(); - - const capture = (exception: unknown): { status: number; body: unknown } => { - let status = 0; - let body: unknown; - const reply = { - status: (code: number) => { - status = code; - return { send: (payload: unknown) => (body = payload) }; - }, - }; - const host = { - switchToHttp: () => ({ getResponse: () => reply }), - } as unknown as ArgumentsHost; - - filter.catch(exception, host); - return { status, body }; - }; - - it('normalizes a standard HttpException to { statusCode, error, message }', () => { - const { status, body } = capture(new NotFoundException()); - - expect(status).toBe(404); - expect(body).toEqual({ statusCode: 404, error: 'Not Found', message: 'Not Found' }); - }); - - it('keeps the custom message of an HttpException thrown with a string', () => { - const { body } = capture(new BadRequestException('The cluster has no container ID.')); - - expect(body).toEqual({ - statusCode: 400, - error: 'Bad Request', - message: 'The cluster has no container ID.', - }); - }); - - it('exposes Zod validation issues under `issues`', () => { - // nestjs-zod throws a BadRequestException whose payload has `errors` and no `error`. - const exception = new BadRequestException({ - statusCode: 400, - message: 'Validation failed', - errors: [{ path: ['interval'], message: 'Expected number', code: 'invalid_type' }], - }); - - const { status, body } = capture(exception); - - expect(status).toBe(400); - expect(body).toEqual({ - statusCode: 400, - error: 'Bad Request', - message: 'Validation failed', - issues: [{ path: ['interval'], message: 'Expected number', code: 'invalid_type' }], - }); - }); - - it('omits `issues` entirely for non-validation errors', () => { - const { body } = capture(new NotFoundException()); - - expect(body).not.toHaveProperty('issues'); - }); - - it('maps an unknown (non-HTTP) error to a generic 500 without leaking internals', () => { - const { status, body } = capture(new Error('bimbamboom database exploded')); - - expect(status).toBe(500); - expect(body).toEqual({ - statusCode: 500, - error: 'Internal Server Error', - message: 'Internal server error', - }); - }); -}); diff --git a/packages/backend/src/common/filters/all-exceptions.filter.ts b/packages/backend/src/common/filters/all-exceptions.filter.ts deleted file mode 100644 index af94605..0000000 --- a/packages/backend/src/common/filters/all-exceptions.filter.ts +++ /dev/null @@ -1,112 +0,0 @@ -import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus, Logger } from '@nestjs/common'; -import { FastifyReply } from 'fastify'; - -import { ApiErrorDto } from '../dto/api-error.dto.js'; - -/** - * Normalizes every thrown exception into a single {@link ApiErrorDto} shape - * (`{ statusCode, error, message }`), so clients get one predictable, typed - * error body regardless of the source (Nest `HttpException`, Zod validation - * failures, or unexpected errors). - */ -@Catch() -export class AllExceptionsFilter implements ExceptionFilter { - private readonly logger = new Logger(AllExceptionsFilter.name); - - catch(exception: unknown, host: ArgumentsHost): void { - const reply = host.switchToHttp().getResponse(); - const body = AllExceptionsFilter.normalize(exception); - - if (body.statusCode >= 500) { - this.logger.error(`${body.statusCode} ${body.message}`, exception instanceof Error ? exception.stack : undefined); - } - - reply.status(body.statusCode).send(body); - } - - private static normalize(exception: unknown): ApiErrorDto { - if (exception instanceof HttpException) { - const statusCode = exception.getStatus(); - const response = exception.getResponse(); - const issues = AllExceptionsFilter.extractIssues(response); - - return { - statusCode, - error: AllExceptionsFilter.extractError(response, statusCode), - message: AllExceptionsFilter.extractMessage(response, exception.message), - ...(issues && { issues }), - }; - } - - return { - statusCode: HttpStatus.INTERNAL_SERVER_ERROR, - error: 'Internal Server Error', - message: 'Internal server error', - }; - } - - // Zod validation failures - private static extractIssues(response: string | object): ApiErrorDto['issues'] { - if (typeof response !== 'object') { - return undefined; - } - - const errors: unknown = (response as { errors?: unknown }).errors; - if (!Array.isArray(errors) || errors.length === 0) { - return undefined; - } - - const issues = (errors as unknown[]) - .filter((issue): issue is Record => typeof issue === 'object' && issue !== null) - .map((issue) => ({ - path: Array.isArray(issue.path) - ? (issue.path as unknown[]).filter( - (p): p is string | number => typeof p === 'string' || typeof p === 'number', - ) - : [], - message: typeof issue.message === 'string' ? issue.message : 'Invalid value', - code: typeof issue.code === 'string' ? issue.code : 'invalid', - })); - - return issues.length > 0 ? issues : undefined; - } - - private static extractMessage(response: string | object, fallback: string): string { - if (typeof response === 'string') { - return response; - } - - const message = (response as { message?: unknown }).message; - if (Array.isArray(message)) { - return message.join('; '); - } - if (typeof message === 'string') { - return message; - } - - return fallback; - } - - private static extractError(response: string | object, statusCode: number): string { - if (typeof response === 'object') { - const error = (response as { error?: unknown }).error; - if (typeof error === 'string') { - return error; - } - } - - return AllExceptionsFilter.reasonPhrase(statusCode); - } - - private static reasonPhrase(statusCode: number): string { - const name: unknown = (HttpStatus as Record)[statusCode]; - if (typeof name !== 'string') { - return 'Error'; - } - - return name - .split('_') - .map((word) => word.charAt(0) + word.slice(1).toLowerCase()) - .join(' '); - } -} diff --git a/packages/backend/src/controllers/auth.controller.ts b/packages/backend/src/controllers/auth.controller.ts new file mode 100644 index 0000000..beda30a --- /dev/null +++ b/packages/backend/src/controllers/auth.controller.ts @@ -0,0 +1,75 @@ +import { Hono } from "hono"; +import { describeRoute, resolver } from "hono-openapi"; + +import validator from "#middlewares/validator.middleware"; +import { UserSchema, UserTokenResponseSchema } from "#schemas/auth.schema"; +import { ApiErrorSchema } from "#schemas/error.schema"; +import { AuthService } from "#services/auth.service"; + +const tags = ["Authentication"]; + +const authController = new Hono() + .post( + "/register", + describeRoute({ + tags, + description: "Register a new account", + responses: { + 201: { + description: "Created", + content: { + "application/json": { schema: resolver(UserTokenResponseSchema) }, + }, + }, + 409: { + description: "Conflict", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "A user is already registered" }, + }, + }, + }, + }, + }), + validator("json", UserSchema), + async (c) => { + const data = c.req.valid("json"); + const token = await AuthService.register(data); + + return c.json(token, 201); + }, + ) + .post( + "/login", + describeRoute({ + tags, + description: "Log in the user", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(UserTokenResponseSchema) }, + }, + }, + 401: { + description: "Unauthorized", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Invalid username or password" }, + }, + }, + }, + }, + }), + validator("json", UserSchema), + async (c) => { + const data = c.req.valid("json"); + const token = await AuthService.login(data); + + return c.json(token); + }, + ); + +export default authController; diff --git a/packages/backend/src/controllers/bot.controller.ts b/packages/backend/src/controllers/bot.controller.ts new file mode 100644 index 0000000..887bddc --- /dev/null +++ b/packages/backend/src/controllers/bot.controller.ts @@ -0,0 +1,377 @@ +import { Hono } from "hono"; +import { describeRoute, resolver } from "hono-openapi"; + +import authMiddlewares from "#middlewares/auth.middlware"; +import validator from "#middlewares/validator.middleware"; +import { + BotDiscordProfileSchema, + BotSchema, + ContainerImageSchema, + CreateBotSchema, + RecommendedShardsSchema, +} from "#schemas/bot.schema"; +import { ApiErrorSchema } from "#schemas/error.schema"; +import BotService from "#services/bot.service"; + +const tags = ["Bot"]; + +const botController = new Hono() + .use(...authMiddlewares) + .post( + "/", + describeRoute({ + tags, + description: "Register a bot", + responses: { + 201: { + description: "Created", + content: { + "application/json": { schema: resolver(BotSchema) }, + }, + }, + 409: { + description: "Conflict", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "A bot is already registered" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + examples: { + "Unreachable or timed out": { + value: { message: "Discord API is unreachable or timed out" }, + }, + "Invalid token": { value: { message: "Invalid Discord bot token" } }, + Unexpected: { + value: { message: "Discord API returned an unexpected response body" }, + }, + }, + }, + }, + }, + }, + }), + validator("json", CreateBotSchema), + async (c) => { + const data = c.req.valid("json"); + const bot = await BotService.create(data); + + return c.json(bot, 201); + }, + ) + .get( + "/", + describeRoute({ + tags, + description: "Get the registered bot", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(BotSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Bot not found" }, + }, + }, + }, + }, + }), + async (c) => { + const bot = await BotService.get(); + + return c.json(bot); + }, + ) + .put( + "/", + describeRoute({ + tags, + description: "Update bot", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(BotSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Bot not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Invalid response from the Discord API" }, + }, + }, + }, + }, + }), + validator("json", CreateBotSchema), + async (c) => { + const data = c.req.valid("json"); + const bot = await BotService.update(data); + + return c.json(bot, 200); + }, + ) + .delete( + "/", + describeRoute({ + tags, + description: "Delete bot", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(BotSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Bot not found" }, + }, + }, + }, + }, + }), + async (c) => { + const bot = await BotService.delete(); + + return c.json(bot, 200); + }, + ) + .get( + "/profile", + describeRoute({ + tags, + description: "Get bot Discord profile", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(BotDiscordProfileSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Bot not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + examples: { + "Unreachable or timed out": { + value: { message: "Discord API is unreachable or timed out" }, + }, + "Invalid token": { value: { message: "Invalid Discord bot token" } }, + Unexpected: { + value: { message: "Discord API returned an unexpected response body" }, + }, + }, + }, + }, + }, + }, + }), + async (c) => { + const profile = await BotService.discordProfile(); + + return c.json(profile, 200); + }, + ) + .get( + "/recommended-shards", + describeRoute({ + tags, + description: "Get the number of shards recommended by Discord", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(RecommendedShardsSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Bot not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + examples: { + "Unreachable or timed out": { + value: { message: "Discord API is unreachable or timed out" }, + }, + "Invalid token": { value: { message: "Invalid Discord bot token" } }, + Unexpected: { + value: { message: "Discord API returned an unexpected response body" }, + }, + }, + }, + }, + }, + }, + }), + async (c) => { + const recommendedShards = await BotService.recommendedShards(); + + return c.json(recommendedShards, 200); + }, + ) + .get( + "/container-image", + describeRoute({ + tags, + description: "Get the registered container image", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(ContainerImageSchema.omit({ password: true })) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Container image not found" }, + }, + }, + }, + }, + }), + async (c) => { + const containerImage = await BotService.getContainerImage(); + + return c.json(containerImage, 200); + }, + ) + .post( + "/container-image", + describeRoute({ + tags, + description: "Register a container image", + responses: { + 201: { + description: "Created", + content: { + "application/json": { schema: resolver(ContainerImageSchema.omit({ password: true })) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Bot not found" }, + }, + }, + }, + 409: { + description: "Conflict", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "A container image is already registered" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("json", ContainerImageSchema), + async (c) => { + const data = c.req.valid("json"); + const containerImage = await BotService.createContainerImage(data); + + return c.json(containerImage, 201); + }, + ) + .put( + "/container-image", + describeRoute({ + tags, + description: "Update container image", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(ContainerImageSchema.omit({ password: true })) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Container image not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("json", ContainerImageSchema), + async (c) => { + const data = c.req.valid("json"); + const containerImage = await BotService.updateContainerImage(data); + + return c.json(containerImage, 200); + }, + ); + +export default botController; diff --git a/packages/backend/src/controllers/cluster.controller.ts b/packages/backend/src/controllers/cluster.controller.ts new file mode 100644 index 0000000..5510f49 --- /dev/null +++ b/packages/backend/src/controllers/cluster.controller.ts @@ -0,0 +1,498 @@ +import { Hono } from "hono"; +import { describeRoute, resolver } from "hono-openapi"; +import { streamSSE } from "hono/streaming"; + +import authMiddlewares from "#middlewares/auth.middlware"; +import validator from "#middlewares/validator.middleware"; +import { + ClusterActionParamSchema, + ClusterIdActionParamSchema, + ClusterIdParamSchema, + ClusterLogSchema, + ClusterLogsQuerySchema, + ClusterLogsSchema, + ClustersBulkActionResultSchema, + ClusterSchema, + ClustersSchema, + ClustersStatsSchema, + ClusterStatsSchema, + SseIntervalQuerySchema, + UpdateClustersSchema, +} from "#schemas/cluster.schema"; +import { ApiErrorSchema } from "#schemas/error.schema"; +import ClusterService from "#services/cluster.service"; + +const tags = ["Clusters"]; + +const clusterController = new Hono() + .use(...authMiddlewares) + .get( + "/", + describeRoute({ + tags, + description: "Get clusters", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(ClustersSchema) }, + }, + }, + }, + }), + async (c) => { + const clusters = await ClusterService.getAll(); + + return c.json(clusters, 200); + }, + ) + .put( + "/", + describeRoute({ + tags, + description: "Update cluster layout", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(ClustersSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + examples: { + "Bot not found": { value: { message: "Bot not found" } }, + "Container image not found": { value: { message: "Container image not found" } }, + }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("json", UpdateClustersSchema), + async (c) => { + const layout = c.req.valid("json"); + const clusters = await ClusterService.updateAll(layout); + + return c.json(clusters, 200); + }, + ) + .get( + "/sse", + describeRoute({ + tags, + description: "Steam clusters", + responses: { + 200: { + description: "Server-Sent Events listing clusters", + content: { + "text/event-stream": { schema: resolver(ClustersSchema) }, + }, + }, + }, + }), + validator("query", SseIntervalQuerySchema), + (c) => { + const query = c.req.valid("query"); + + return streamSSE(c, async (stream) => { + while (!stream.aborted) { + const clusters = await ClusterService.getAll(); + + await stream.writeSSE({ + data: JSON.stringify(clusters), + }); + + await stream.sleep(query.interval * 1000); + } + }); + }, + ) + .get( + "/stats/sse", + describeRoute({ + tags, + description: "Stream clusters stats", + responses: { + 200: { + description: "Server-Sent Events listing clusters stats", + content: { + "text/event-stream": { schema: resolver(ClustersStatsSchema) }, + }, + }, + }, + }), + validator("query", SseIntervalQuerySchema), + (c) => { + const query = c.req.valid("query"); + + return streamSSE(c, async (stream) => { + while (!stream.aborted) { + const stats = await ClusterService.getAllStats(); + + await stream.writeSSE({ + data: JSON.stringify(stats), + }); + + await stream.sleep(query.interval * 1000); + } + }); + }, + ) + .post( + "/:action{(?:start|stop|restart)}", + describeRoute({ + tags, + description: + "Start, stop or restart every cluster (clusters already in the requested state are ignored)", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(ClustersBulkActionResultSchema) }, + }, + }, + }, + }), + validator("param", ClusterActionParamSchema), + async (c) => { + const param = c.req.valid("param"); + const result = await ClusterService.runActionOnAll(param.action); + + return c.json(result, 200); + }, + ) + .get( + "/:id", + describeRoute({ + tags, + description: "Get a cluster", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(ClusterSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster not found" }, + }, + }, + }, + }, + }), + validator("param", ClusterIdParamSchema), + async (c) => { + const param = c.req.valid("param"); + const cluster = await ClusterService.get(param.id); + + return c.json(cluster, 200); + }, + ) + .delete( + "/:id", + describeRoute({ + tags, + description: "Delete a cluster", + responses: { + 200: { + description: "Deleted cluster", + content: { + "application/json": { schema: resolver(ClusterSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("param", ClusterIdParamSchema), + async (c) => { + const param = c.req.valid("param"); + const cluster = await ClusterService.remove(param.id); + + return c.json(cluster, 200); + }, + ) + .get( + "/:id/logs", + describeRoute({ + tags, + description: "Get a cluster logs", + responses: { + 200: { + description: "Logs of the cluster", + content: { + "application/json": { schema: resolver(ClusterLogsSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("param", ClusterIdParamSchema), + validator("query", ClusterLogsQuerySchema), + async (c) => { + const param = c.req.valid("param"); + const query = c.req.valid("query"); + + const logs = await ClusterService.logs(param.id, query); + + return c.json(logs, 200); + }, + ) + .get( + "/:id/logs/sse", + describeRoute({ + tags, + description: "Stream cluster logs", + responses: { + 200: { + description: "Server-Sent Events with cluster logs", + content: { + "text/event-stream": { schema: resolver(ClusterLogSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("param", ClusterIdParamSchema), + async (c) => { + const param = c.req.valid("param"); + const logs = await ClusterService.streamLogs(param.id); + + return streamSSE(c, async (stream) => { + stream.onAbort(() => { + logs.destroy(); + }); + + try { + for await (const log of logs) { + await stream.writeSSE({ data: JSON.stringify(log) }); + } + } catch (error) { + if (!stream.aborted) { + throw error; + } + } + }); + }, + ) + .get( + "/:id/stats", + describeRoute({ + tags, + description: "Get cluster stats", + responses: { + 200: { + description: "Cluster stats", + content: { + "application/json": { schema: resolver(ClusterStatsSchema) }, + }, + }, + 400: { + description: "Bad Request", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster 0 is not running" }, + }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("param", ClusterIdParamSchema), + async (c) => { + const param = c.req.valid("param"); + const stats = await ClusterService.stats(param.id); + + return c.json(stats, 200); + }, + ) + .get( + "/:id/stats/sse", + describeRoute({ + tags, + description: "Stream cluster stats", + responses: { + 200: { + description: "Server-Sent Events with cluster stats", + content: { + "text/event-stream": { schema: resolver(ClusterStatsSchema) }, + }, + }, + 400: { + description: "Bad Request", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster 0 is not running" }, + }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("param", ClusterIdParamSchema), + async (c) => { + const param = c.req.valid("param"); + const stats = await ClusterService.streamStats(param.id); + + return streamSSE(c, async (stream) => { + stream.onAbort(() => { + stats.destroy(); + }); + + try { + for await (const sample of stats) { + await stream.writeSSE({ data: JSON.stringify(sample) }); + } + } catch (error) { + if (!stream.aborted) { + throw error; + } + } + }); + }, + ) + .post( + "/:id/:action{(?:start|stop|restart)}", + describeRoute({ + tags, + description: "Start, stop or restart a cluster", + responses: { + 200: { + description: "OK", + content: { + "application/json": { schema: resolver(ClusterSchema) }, + }, + }, + 404: { + description: "Not Found", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Cluster not found" }, + }, + }, + }, + 424: { + description: "Failed Dependency", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Docker Engine API returned an unexpected response" }, + }, + }, + }, + }, + }), + validator("param", ClusterIdActionParamSchema), + async (c) => { + const param = c.req.valid("param"); + const cluster = await ClusterService.runAction(param.id, param.action); + + return c.json(cluster, 200); + }, + ); + +export default clusterController; diff --git a/packages/backend/src/discord/discord.module.ts b/packages/backend/src/discord/discord.module.ts deleted file mode 100644 index 8b71b7e..0000000 --- a/packages/backend/src/discord/discord.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { DiscordService } from './discord.service.js'; - -@Module({ - providers: [DiscordService], - exports: [DiscordService], -}) -export class DiscordModule {} diff --git a/packages/backend/src/discord/discord.service.spec.ts b/packages/backend/src/discord/discord.service.spec.ts deleted file mode 100644 index f5275ad..0000000 --- a/packages/backend/src/discord/discord.service.spec.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { jest } from '@jest/globals'; -import { HttpException, HttpStatus } from '@nestjs/common'; - -import { DiscordService } from './discord.service.js'; - -const TOKEN = 'a-bot-token'; -const BOT_ID = '1352006130926096504'; - -const jsonResponse = (status: number, body: unknown): Response => - ({ - ok: status >= 200 && status < 300, - status, - statusText: status === 401 ? 'Unauthorized' : 'OK', - json: () => Promise.resolve(body), - }) as Response; - -describe('DiscordService', () => { - const service = new DiscordService(); - const originalFetch = globalThis.fetch; - const fetchMock = jest.fn(); - - beforeAll(() => { - globalThis.fetch = fetchMock; - }); - - afterAll(() => { - globalThis.fetch = originalFetch; - }); - - beforeEach(() => { - fetchMock.mockReset(); - }); - - describe('getGatewayBot', () => { - it('returns the recommended shard count', async () => { - fetchMock.mockResolvedValueOnce(jsonResponse(200, { shards: 4 })); - - await expect(service.getGatewayBot(TOKEN)).resolves.toEqual({ shards: 4 }); - }); - - it('throws a 424 on a 401 (invalid token)', async () => { - fetchMock.mockResolvedValueOnce(jsonResponse(401, {})); - - await expect(service.getGatewayBot(TOKEN)).rejects.toMatchObject({ - status: HttpStatus.FAILED_DEPENDENCY, - message: 'Invalid Discord bot token.', - }); - }); - - it('throws a 424 when the Discord API errors', async () => { - fetchMock.mockResolvedValueOnce(jsonResponse(500, {})); - - await expect(service.getGatewayBot(TOKEN)).rejects.toMatchObject({ status: HttpStatus.FAILED_DEPENDENCY }); - }); - - it('throws a 424 when the shard count is missing', async () => { - fetchMock.mockResolvedValueOnce(jsonResponse(200, {})); - - await expect(service.getGatewayBot(TOKEN)).rejects.toBeInstanceOf(HttpException); - }); - - it('maps a network failure / timeout to a 424', async () => { - fetchMock.mockRejectedValueOnce(new Error('timeout')); - - await expect(service.getGatewayBot(TOKEN)).rejects.toMatchObject({ status: HttpStatus.FAILED_DEPENDENCY }); - }); - }); - - describe('getCurrentUser', () => { - it('maps the user and builds CDN URLs (png avatar, animated gif banner)', async () => { - fetchMock.mockResolvedValueOnce( - jsonResponse(200, { - id: BOT_ID, - username: 'HallMaster', - global_name: 'HallMaster Bot', - discriminator: '0', - avatar: 'abc123', - banner: 'a_def456', - accent_color: 5793266, - }), - ); - - await expect(service.getCurrentUser(TOKEN)).resolves.toEqual({ - name: 'HallMaster', - displayName: 'HallMaster Bot', - discriminator: '0', - avatarUrl: `https://cdn.discordapp.com/avatars/${BOT_ID}/abc123.png`, - bannerUrl: `https://cdn.discordapp.com/banners/${BOT_ID}/a_def456.gif`, - accentColor: 5793266, - }); - }); - - it('returns null URLs, displayName and accentColor when the bot has none', async () => { - fetchMock.mockResolvedValueOnce( - jsonResponse(200, { - id: BOT_ID, - username: 'HallMaster', - global_name: null, - discriminator: '0001', - avatar: null, - banner: null, - accent_color: null, - }), - ); - - await expect(service.getCurrentUser(TOKEN)).resolves.toEqual({ - name: 'HallMaster', - displayName: null, - discriminator: '0001', - avatarUrl: null, - bannerUrl: null, - accentColor: null, - }); - }); - }); -}); diff --git a/packages/backend/src/discord/discord.service.ts b/packages/backend/src/discord/discord.service.ts deleted file mode 100644 index e4d9e09..0000000 --- a/packages/backend/src/discord/discord.service.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; -import { z } from 'zod'; - -const DISCORD_API_VERSION = 'v10'; -const DISCORD_API_BASE_URL = `https://discord.com/api/${DISCORD_API_VERSION}`; -const DISCORD_CDN_BASE_URL = 'https://cdn.discordapp.com'; -const DISCORD_REQUEST_TIMEOUT_MS = 10_000; - -const DiscordGatewayBotSchema = z.object({ - shards: z.int().positive(), -}); - -const DiscordUserSchema = z.object({ - id: z.string(), - username: z.string(), - global_name: z.string().nullish(), - discriminator: z.string(), - avatar: z.string().nullish(), - banner: z.string().nullish(), - accent_color: z.number().int().nullish(), -}); - -export interface DiscordGatewayBot { - shards: number; -} - -export interface DiscordProfile { - name: string; - displayName: string | null; - discriminator: string; - avatarUrl: string | null; - bannerUrl: string | null; - accentColor: number | null; -} - -@Injectable() -export class DiscordService { - private async request(path: string, token: string, schema: S): Promise> { - let response: Response; - try { - response = await fetch(`${DISCORD_API_BASE_URL}${path}`, { - headers: { Authorization: `Bot ${token}` }, - signal: AbortSignal.timeout(DISCORD_REQUEST_TIMEOUT_MS), - }); - } catch { - throw new HttpException('The Discord API is unreachable or timed out.', HttpStatus.FAILED_DEPENDENCY); - } - - if (response.status === 401) { - throw new HttpException('Invalid Discord bot token.', HttpStatus.FAILED_DEPENDENCY); - } - - if (!response.ok) { - throw new HttpException( - `Discord API returned ${response.status}: ${response.statusText}`, - HttpStatus.FAILED_DEPENDENCY, - ); - } - - const payload: unknown = await response.json().catch(() => undefined); - const parsed = schema.safeParse(payload); - if (!parsed.success) { - throw new HttpException('The Discord API returned an unexpected response.', HttpStatus.FAILED_DEPENDENCY); - } - - return parsed.data; - } - - async getGatewayBot(token: string): Promise { - return await this.request('/gateway/bot', token, DiscordGatewayBotSchema); - } - - async getCurrentUser(token: string): Promise { - const user = await this.request('/users/@me', token, DiscordUserSchema); - - return { - name: user.username, - displayName: user.global_name ?? null, - discriminator: user.discriminator, - avatarUrl: DiscordService.buildCdnUrl('avatars', user.id, user.avatar ?? null), - bannerUrl: DiscordService.buildCdnUrl('banners', user.id, user.banner ?? null), - accentColor: user.accent_color ?? null, - }; - } - - private static buildCdnUrl(kind: 'avatars' | 'banners', id: string, hash: string | null): string | null { - if (!hash) { - return null; - } - - const extension = hash.startsWith('a_') ? 'gif' : 'png'; - return `${DISCORD_CDN_BASE_URL}/${kind}/${id}/${hash}.${extension}`; - } -} diff --git a/packages/backend/src/docker/docker.module.ts b/packages/backend/src/docker/docker.module.ts deleted file mode 100644 index 3d10b24..0000000 --- a/packages/backend/src/docker/docker.module.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { DockerSocket } from '@hallmaster/docker.js'; -import { Module } from '@nestjs/common'; -import { ConfigModule, ConfigService } from '@nestjs/config'; - -import { PrismaModule } from '../prisma/prisma.module.js'; -import { PrismaService } from '../prisma/prisma.service.js'; - -import { DockerService } from './docker.service.js'; - -@Module({ - imports: [ConfigModule, PrismaModule], - providers: [ - { - provide: DockerService, - inject: [ConfigService, PrismaService], - async useFactory(configService: ConfigService, prismaService: PrismaService) { - const dockerSocket = new DockerSocket(); - await dockerSocket.init(); - - return new DockerService(configService, prismaService, dockerSocket); - }, - }, - ], - exports: [DockerService], -}) -export class DockerModule {} diff --git a/packages/backend/src/docker/docker.service.spec.ts b/packages/backend/src/docker/docker.service.spec.ts deleted file mode 100644 index c2fedd2..0000000 --- a/packages/backend/src/docker/docker.service.spec.ts +++ /dev/null @@ -1,205 +0,0 @@ -import { DockerAPIHttpError, DockerSocket, type DockerContainerStats } from '@hallmaster/docker.js'; -import type { Bot, Cluster } from '@hallmaster/prisma-client'; -import { ConfigService } from '@nestjs/config'; -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; -import type { DeepMockProxy } from 'jest-mock-extended'; -import { mockDeep } from 'jest-mock-extended'; - -import { PrismaService } from '../prisma/prisma.service.js'; - -import { DockerService } from './docker.service.js'; - -describe('DockerService', () => { - let service: DockerService; - let prismaService: DeepMockProxy; - let configService: DeepMockProxy; - let dockerSocket: DeepMockProxy; - - beforeEach(async () => { - prismaService = mockDeep(); - configService = mockDeep(); - dockerSocket = mockDeep(); - - const module: TestingModule = await Test.createTestingModule({ - providers: [ - DockerService, - { provide: ConfigService, useValue: configService }, - { provide: PrismaService, useValue: prismaService }, - { provide: DockerSocket, useValue: dockerSocket }, - ], - }).compile(); - - service = module.get(DockerService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); - - describe('idempotent lifecycle ops when container was removed out-of-band', () => { - const cluster: Cluster = { - botId: 'bot-1', - id: 0, - containerId: 'vanished-container-id', - shardIds: [0], - status: 'RUNNING', - }; - - it('stop() marks the cluster STOPPED and clears containerId instead of throwing', async () => { - dockerSocket.apiCall.mockRejectedValueOnce(new DockerAPIHttpError(404, 'no such container')); - - await expect(service.stop(cluster)).resolves.not.toThrow(); - - expect(prismaService.cluster.update).toHaveBeenCalledWith({ - where: { botId_id: { botId: 'bot-1', id: 0 } }, - data: { status: 'STOPPED', containerId: null }, - }); - }); - - it('remove() deletes the DB row instead of throwing', async () => { - // First call inside stop(); second call inside remove(). Both 404. - dockerSocket.apiCall.mockRejectedValue(new DockerAPIHttpError(404, 'no such container')); - - await expect(service.remove(cluster)).resolves.not.toThrow(); - - expect(prismaService.cluster.delete).toHaveBeenCalledWith({ - where: { botId_id: { botId: 'bot-1', id: 0 } }, - }); - }); - }); - - describe('start() with name collision', () => { - const bot: Bot = { - id: 'bot-1', - token: 'discord-token', - totalShards: 1, - } as unknown as Bot; - - const cluster: Cluster = { - botId: 'bot-1', - id: 0, - containerId: null, - shardIds: [0], - status: 'STOPPED', - }; - - it('cleans up the stale container and retries when create returns 409', async () => { - configService.getOrThrow.mockReturnValue('ENV_NAME'); - prismaService.dockerImage.findUnique.mockResolvedValue({ - botId: 'bot-1', - serverName: 'docker.io', - image: 'foo/bar', - tag: 'latest', - username: null, - password: null, - }); - - // Image pull succeeds - // First create attempt fails with 409. Cleanup succeeds. - // Second create attempt succeeds. Then start succeeds. - dockerSocket.apiCall - .mockResolvedValueOnce(undefined) // pull - .mockRejectedValueOnce(new DockerAPIHttpError(409, 'name already in use')) // create #1 - .mockResolvedValueOnce(undefined) // stop the stale one - .mockResolvedValueOnce(undefined) // remove the stale one - .mockResolvedValueOnce({ Id: 'new-container-id' } as never) // create #2 - .mockResolvedValueOnce(undefined); // start - - await expect(service.start(bot, cluster)).resolves.toBe('new-container-id'); - }); - }); - - describe('reconcileClusterStatus', () => { - const baseCluster = { id: 0, botId: 'bot-1', containerId: 'container-id' }; - - it('flips DB RUNNING→STOPPED when the container has been stopped out-of-band', async () => { - dockerSocket.apiCall.mockResolvedValueOnce({ State: { Running: false } } as never); - - const status = await service.reconcileClusterStatus({ ...baseCluster, status: 'RUNNING' }); - - expect(status).toBe('STOPPED'); - expect(prismaService.cluster.update).toHaveBeenCalledWith({ - where: { botId_id: { botId: 'bot-1', id: 0 } }, - data: { status: 'STOPPED' }, - }); - }); - - it('clears containerId and marks STOPPED when the container has vanished (404)', async () => { - dockerSocket.apiCall.mockRejectedValueOnce(new DockerAPIHttpError(404, 'no such container')); - - const status = await service.reconcileClusterStatus({ ...baseCluster, status: 'RUNNING' }); - - expect(status).toBe('STOPPED'); - expect(prismaService.cluster.update).toHaveBeenCalledWith({ - where: { botId_id: { botId: 'bot-1', id: 0 } }, - data: { status: 'STOPPED', containerId: null }, - }); - }); - - it('does not touch DB when the actual state matches the stored one', async () => { - dockerSocket.apiCall.mockResolvedValueOnce({ State: { Running: true } } as never); - - const status = await service.reconcileClusterStatus({ ...baseCluster, status: 'RUNNING' }); - - expect(status).toBe('RUNNING'); - expect(prismaService.cluster.update).not.toHaveBeenCalled(); - }); - - it('skips transient states (STARTING/UPDATING/ERROR) without hitting Docker', async () => { - const status = await service.reconcileClusterStatus({ ...baseCluster, status: 'STARTING' }); - - expect(status).toBe('STARTING'); - expect(dockerSocket.apiCall).not.toHaveBeenCalled(); - expect(prismaService.cluster.update).not.toHaveBeenCalled(); - }); - - it('returns current status without throwing when Docker is unreachable', async () => { - dockerSocket.apiCall.mockRejectedValueOnce(new DockerAPIHttpError(500, 'socket error')); - - const status = await service.reconcileClusterStatus({ ...baseCluster, status: 'RUNNING' }); - - expect(status).toBe('RUNNING'); - expect(prismaService.cluster.update).not.toHaveBeenCalled(); - }); - }); - - describe('getContainerStats CPU percentage', () => { - const buildStats = (cpuTotal: number, precpuTotal: number) => - ({ - cpu_stats: { - cpu_usage: { total_usage: cpuTotal, percpu_usage: [0], usage_in_kernelmode: 0, usage_in_usermode: 0 }, - system_cpu_usage: 2_000_000, - online_cpus: 1, - throttling_data: { periods: 0, throttled_periods: 0, throttled_time: 0 }, - }, - precpu_stats: { - cpu_usage: { total_usage: precpuTotal, percpu_usage: [0], usage_in_kernelmode: 0, usage_in_usermode: 0 }, - system_cpu_usage: 1_000_000, - online_cpus: 1, - throttling_data: { periods: 0, throttled_periods: 0, throttled_time: 0 }, - }, - pids_stats: { current: 1, limit: 10 }, - memory_stats: { usage: 100, limit: 1000, stats: {} }, - blkio_stats: { io_service_bytes_recursive: [] }, - networks: {}, - }) as unknown as DockerContainerStats; - - it('clamps CPU to 0 when the delta is negative (counter reset on restart)', async () => { - dockerSocket.apiCall.mockResolvedValueOnce(buildStats(100, 1000)); - - const stats = await service.getContainerStats('container-1'); - - expect(stats.cpuPercentage).toBe(0); - }); - - it('computes the CPU percentage from a positive delta', async () => { - dockerSocket.apiCall.mockResolvedValueOnce(buildStats(1500, 1000)); - - const stats = await service.getContainerStats('container-1'); - - // cpuDelta 500 / systemDelta 1_000_000 * 1 online cpu * 100 - expect(stats.cpuPercentage).toBeCloseTo(0.05); - }); - }); -}); diff --git a/packages/backend/src/docker/docker.service.ts b/packages/backend/src/docker/docker.service.ts deleted file mode 100644 index fce7c45..0000000 --- a/packages/backend/src/docker/docker.service.ts +++ /dev/null @@ -1,496 +0,0 @@ -import { Readable, Transform } from 'node:stream'; - -import { - DockerContainersAPI, - DockerImagesAPI, - DockerSocket, - DockerAPIHttpError, - type DockerContainerCreated, - type DockerContainerCreationBody, - type DockerContainerStats, -} from '@hallmaster/docker.js'; -import { Bot, Cluster, ClusterStatus, DockerImage } from '@hallmaster/prisma-client'; -import { BadRequestException, Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; - -import { GetClusterStatsZodDto } from '../clusters/dto/get-cluster-stats.dto.js'; -import { PrismaService } from '../prisma/prisma.service.js'; - -@Injectable() -export class DockerService { - constructor( - private readonly configService: ConfigService, - private readonly prismaService: PrismaService, - private readonly dockerSocket: DockerSocket, - ) {} - - private isDockerApiError(error: unknown, status: number): boolean { - return error instanceof DockerAPIHttpError && error.status === status; - } - - private isContainerNotFound(error: unknown): boolean { - return this.isDockerApiError(error, 404); - } - - private async clearContainerId(cluster: Cluster): Promise { - await this.prismaService.cluster.update({ - where: { botId_id: { botId: cluster.botId, id: cluster.id } }, - data: { containerId: null }, - }); - } - - private async cleanupStaleContainerByName(name: string): Promise { - const api = new DockerContainersAPI(this.dockerSocket); - - try { - await api.stop(name); - } catch { - // proceed to remove even if stop fails - } - - try { - await api.remove(name); - } catch (e) { - // Any 404 is treated as success: the container is gone, which is the goal. - if (!this.isContainerNotFound(e)) throw e; - } - } - - private async createContainerOrCleanup( - api: DockerContainersAPI, - body: Partial, - name: string, - ): Promise { - try { - return await api.create(body, name); - } catch (e) { - if (!this.isDockerApiError(e, 409)) throw e; - await this.cleanupStaleContainerByName(name); - return await api.create(body, name); - } - } - - async reconcileClusterStatus(cluster: { - id: number; - botId: string; - containerId: string | null; - status: ClusterStatus; - }): Promise { - if (cluster.status !== 'RUNNING' && cluster.status !== 'STOPPED') { - return cluster.status; - } - if (cluster.containerId === null) { - return cluster.status; - } - - const api = new DockerContainersAPI(this.dockerSocket); - - try { - const container = await api.get(cluster.containerId); - const actual: ClusterStatus = container.State.Running ? 'RUNNING' : 'STOPPED'; - - if (actual !== cluster.status) { - await this.prismaService.cluster.update({ - where: { botId_id: { botId: cluster.botId, id: cluster.id } }, - data: { status: actual }, - }); - } - return actual; - } catch (e) { - if (this.isContainerNotFound(e)) { - await this.prismaService.cluster.update({ - where: { botId_id: { botId: cluster.botId, id: cluster.id } }, - data: { status: 'STOPPED', containerId: null }, - }); - return 'STOPPED'; - } - return cluster.status; - } - } - - async verifyImage(dockerImage: { - serverName: string; - image: string; - tag: string; - username: string | null; - password: string | null; - }): Promise { - const dockerImagesAPI = new DockerImagesAPI(this.dockerSocket); - - try { - await dockerImagesAPI.verify({ - fromImage: `${dockerImage.serverName}/${dockerImage.image}`, - tag: dockerImage.tag, - auth: { - serveraddress: dockerImage.serverName, - username: dockerImage.username ?? '', - password: dockerImage.password ?? '', - }, - }); - } catch (e) { - throw new BadRequestException('Unable to pull the Docker image.', { - description: `Failed to verify ${dockerImage.serverName}/${dockerImage.image}:${dockerImage.tag}: ${e instanceof Error ? e.message : String(e)}`, - cause: e, - }); - } - } - - private async pullDockerImage(cluster: Cluster, dockerImage: DockerImage) { - const dockerImagesAPI = new DockerImagesAPI(this.dockerSocket); - - try { - await dockerImagesAPI.create({ - fromImage: `${dockerImage.serverName}/${dockerImage.image}`, - tag: dockerImage.tag, - auth: { - serveraddress: dockerImage.serverName, - username: dockerImage.username ?? '', - password: dockerImage.password ?? '', - }, - }); - } catch (e) { - await this.prismaService.cluster.update({ - where: { - botId_id: { botId: cluster.botId, id: cluster.id }, - }, - data: { - status: 'ERROR', - }, - }); - - throw new BadRequestException('Unable to pull the Docker image.', { - description: `An error occurred while pulling the bot's Docker image from ${dockerImage.image}: ${e instanceof Error ? e.message : String(e)}`, - cause: e, - }); - } - } - - async start(bot: Bot, cluster: Cluster) { - if (cluster.status === 'RUNNING') { - return; - } - - const dockerImage = await this.prismaService.dockerImage.findUnique({ - where: { botId: bot.id }, - }); - if (null === dockerImage) { - throw new NotFoundException(); - } - - const discordBotTokenEnvName = this.configService.getOrThrow('DISCORD_BOT_TOKEN_ENV_NAME'); - - const totalShardsEnvName = this.configService.getOrThrow('TOTAL_SHARDS_ENV_NAME'); - - const shardIdListEnvName = this.configService.getOrThrow('SHARD_ID_LIST_ENV_NAME'); - - await this.prismaService.cluster.update({ - data: { - status: 'STARTING', - }, - where: { - botId_id: { botId: cluster.botId, id: cluster.id }, - }, - }); - - const dockerContainersAPI = new DockerContainersAPI(this.dockerSocket); - let containerId: null | string = cluster.containerId; - - // If we have a containerId in DB but Docker no longer knows about it - // (e.g. user removed it manually), clear the stale reference and fall - // through to the create path. - if (containerId !== null) { - try { - await dockerContainersAPI.get(containerId); - } catch (e) { - if (this.isContainerNotFound(e)) { - await this.clearContainerId(cluster); - containerId = null; - } else { - await this.prismaService.cluster.update({ - where: { botId_id: { botId: bot.id, id: cluster.id } }, - data: { status: 'ERROR' }, - }); - throw new BadRequestException('Unable to inspect the cluster container', { - description: `An error occurred while inspecting the Docker container: ${e instanceof Error ? e.message : String(e)}`, - cause: e, - }); - } - } - } - - if (null === containerId) { - await this.pullDockerImage(cluster, dockerImage); - try { - const container = await this.createContainerOrCleanup( - dockerContainersAPI, - { - Env: [ - `${discordBotTokenEnvName}=${bot.token}`, - `${totalShardsEnvName}=${bot.totalShards}`, - `${shardIdListEnvName}=${cluster.shardIds.join(',')}`, - ], - Image: `${dockerImage.serverName}/${dockerImage.image}:${dockerImage.tag}`, - Labels: { - kind: 'hallmaster', - 'cluster-id': String(cluster.id), - 'bot-id': bot.id, - }, - }, - `${bot.id}-${cluster.id}`, - ); - - containerId = container.Id; - - await this.prismaService.cluster.update({ - where: { - botId_id: { botId: bot.id, id: cluster.id }, - }, - data: { - status: 'RUNNING', - containerId: containerId, - }, - }); - } catch (e) { - await this.prismaService.cluster.update({ - where: { - botId_id: { botId: bot.id, id: cluster.id }, - }, - data: { - status: 'ERROR', - }, - }); - - throw new BadRequestException('Unable to create the cluster', { - description: `An error occurred while starting the Docker container project: ${e instanceof Error ? e.message : String(e)}`, - cause: e, - }); - } - } - - if (null === containerId) { - throw new InternalServerErrorException(); - } - - try { - await dockerContainersAPI.start(containerId); - - await this.prismaService.cluster.update({ - where: { - botId_id: { botId: bot.id, id: cluster.id }, - }, - data: { - status: 'RUNNING', - containerId: containerId, - }, - }); - - return containerId; - } catch (e) { - await this.prismaService.cluster.update({ - where: { - botId_id: { botId: bot.id, id: cluster.id }, - }, - data: { - status: 'ERROR', - }, - }); - - throw new BadRequestException('Unable to create the cluster', { - description: `An error occurred while starting the Docker container project: ${e instanceof Error ? e.message : String(e)}`, - cause: e, - }); - } - } - - async stop(cluster: Cluster) { - if (null === cluster.containerId) { - return; - } - - const dockerContainersAPI = new DockerContainersAPI(this.dockerSocket); - let containerVanished = false; - - try { - await dockerContainersAPI.stop(cluster.containerId); - } catch (e) { - if (this.isContainerNotFound(e)) { - // Container was removed out-of-band — treat stop as already done. - containerVanished = true; - } else { - await this.prismaService.cluster.update({ - where: { - botId_id: { botId: cluster.botId, id: cluster.id }, - }, - data: { - status: 'ERROR', - }, - }); - - throw new BadRequestException('Unable to stop the cluster', { - description: `An error occurred while stopping the Docker container: ${e instanceof Error ? e.message : String(e)}`, - cause: e, - }); - } - } - - await this.prismaService.cluster.update({ - where: { - botId_id: { botId: cluster.botId, id: cluster.id }, - }, - data: { - status: 'STOPPED', - ...(containerVanished && { containerId: null }), - }, - }); - } - - async remove(cluster: Cluster) { - if (cluster.status !== 'STOPPED' && cluster.status !== 'ERROR') { - await this.stop(cluster); - } - - if (null !== cluster.containerId) { - const dockerContainersAPI = new DockerContainersAPI(this.dockerSocket); - - try { - await dockerContainersAPI.remove(cluster.containerId); - } catch (e) { - if (!this.isContainerNotFound(e)) { - throw new BadRequestException('Unable to remove the cluster', { - description: `An error occurred while removing the Docker container: ${e instanceof Error ? e.message : String(e)}`, - cause: e, - }); - } - } - } - - await this.prismaService.cluster.delete({ - where: { - botId_id: { botId: cluster.botId, id: cluster.id }, - }, - }); - } - - async restart(bot: Bot, cluster: Cluster): Promise { - if (cluster.status === 'RUNNING') { - await this.stop(cluster); - cluster.status = 'STOPPED'; - } - - await this.start(bot, cluster); - } - - async streamContainerLogs(containerId: string, tail?: number | 'all'): Promise { - const dockerContainersAPI = new DockerContainersAPI(this.dockerSocket); - return await dockerContainersAPI.logs(containerId, { - follow: true, - stdout: true, - stderr: true, - timestamps: true, - tail: tail, - }); - } - - async getContainerLogs(containerId: string, since?: Date, until?: Date, tail?: number | 'all') { - const dockerContainersAPI = new DockerContainersAPI(this.dockerSocket); - - const sinceTimestamp = since ? since.getTime() / 1000 : undefined; - const untilTimestamp = until ? until.getTime() / 1000 : undefined; - - return await dockerContainersAPI.logs(containerId, { - stdout: true, - stderr: true, - timestamps: true, - follow: false, - since: sinceTimestamp, - until: untilTimestamp, - tail: tail, - }); - } - - async getContainerStats(id: string): Promise { - const dockerContainersAPI = new DockerContainersAPI(this.dockerSocket); - - const stats = await dockerContainersAPI.stats(id, { - oneShot: false, - stream: false, - }); - - return DockerService.toStatsDto(stats); - } - - async streamContainerStats(id: string): Promise { - const dockerContainersAPI = new DockerContainersAPI(this.dockerSocket); - - const raw = await dockerContainersAPI.stats(id, { stream: true }); - - const transform = new Transform({ - objectMode: true, - transform(stats: DockerContainerStats, _encoding, callback) { - if (stats.precpu_stats.system_cpu_usage === 0) { - callback(); - return; - } - - callback(null, DockerService.toStatsDto(stats)); - }, - }); - - raw.pipe(transform); - raw.on('error', (err) => transform.destroy(err)); - - return transform; - } - - private static toStatsDto(stats: DockerContainerStats): GetClusterStatsZodDto { - const cpuDelta = stats.cpu_stats.cpu_usage.total_usage - stats.precpu_stats.cpu_usage.total_usage; - - const systemDelta = stats.cpu_stats.system_cpu_usage - stats.precpu_stats.system_cpu_usage; - - const onlineCPUs = stats.cpu_stats.online_cpus ?? stats.cpu_stats.cpu_usage.percpu_usage?.length ?? 1; - - const cpuPercentage = systemDelta > 0 && cpuDelta > 0 ? (cpuDelta / systemDelta) * onlineCPUs * 100 : 0; - - const processesUsage = stats.pids_stats?.current ?? 0; - const processesLimit = stats.pids_stats?.limit ?? 0; - const processesPercentage = processesLimit > 0 ? (processesUsage / processesLimit) * 100 : 0; - - const memoryUsage = - (stats.memory_stats?.usage ?? 0) - - (stats.memory_stats?.stats?.inactive_file ?? 0) - - (stats.memory_stats?.stats?.slab_reclaimable ?? 0); - - const memoryLimit = stats.memory_stats?.limit ?? 0; - const memoryPercentage = memoryLimit > 0 ? (memoryUsage / memoryLimit) * 100 : 0; - - const diskRead = stats.blkio_stats?.io_service_bytes_recursive - ?.filter((service) => service.op === 'read') - ?.reduce((acc, cur) => acc + cur.value, 0); - const diskWrite = stats.blkio_stats?.io_service_bytes_recursive - ?.filter((service) => service.op === 'write') - ?.reduce((acc, cur) => acc + cur.value, 0); - - const networks = Object.entries(stats.networks ?? {}).map(([interfaceName, data]) => ({ - interface: interfaceName, - transmitted: data.tx_bytes, - received: data.rx_bytes, - })); - - return { - cpuPercentage: cpuPercentage, - processes: { - usage: processesUsage, - percentage: processesPercentage, - }, - memory: { - usage: memoryUsage, - percentage: memoryPercentage, - }, - disk: { - read: diskRead ?? null, - write: diskWrite ?? null, - }, - networks: networks, - }; - } -} diff --git a/packages/backend/src/exceptions/http-exceptions.ts b/packages/backend/src/exceptions/http-exceptions.ts new file mode 100644 index 0000000..cb481ef --- /dev/null +++ b/packages/backend/src/exceptions/http-exceptions.ts @@ -0,0 +1,47 @@ +import { HTTPException } from "hono/http-exception"; + +import type { ApiIssue } from "#schemas/error.schema"; + +type HTTPExceptionOptions = Omit< + NonNullable[1]>, + "res" +>; + +export class BadRequestException extends HTTPException { + constructor(options: HTTPExceptionOptions) { + super(400, options); + } +} + +export class UnauthorizedException extends HTTPException { + constructor(options: HTTPExceptionOptions) { + super(401, options); + } +} + +type NotFoundExceptionOptions = + | Omit + | { message?: `${string} not found` }; +export class NotFoundException extends HTTPException { + constructor(options: NotFoundExceptionOptions) { + super(404, options); + } +} + +export class ConflictException extends HTTPException { + constructor(options: HTTPExceptionOptions) { + super(409, options); + } +} + +export class FailedDependancyException extends HTTPException { + constructor(options: HTTPExceptionOptions) { + super(424, options); + } +} + +export class ValidationException extends BadRequestException { + constructor(public readonly issues: ApiIssue[]) { + super({ message: "Validation failed" }); + } +} diff --git a/packages/backend/src/index.dto.ts b/packages/backend/src/index.dto.ts deleted file mode 100644 index d18bedf..0000000 --- a/packages/backend/src/index.dto.ts +++ /dev/null @@ -1,22 +0,0 @@ -export { ApiErrorSchema, type ApiErrorDto } from './common/dto/api-error.dto.js'; - -export { registerSchema, type Register } from './auth/schemas/register.schema.js'; -export { loginSchema } from './auth/schemas/login.schema.js'; -export { type UserToken } from './auth/schemas/user-token.schema.js'; - -export { CreateBotSchema, type CreateBotDto } from './bot/dto/create-bot.dto.js'; -export { UpdateBotSchema, type UpdateBotDto } from './bot/dto/update-bot.dto.js'; -export { GetBotSchema, type GetBotDto } from './bot/dto/get-bot.dto.js'; -export { GetRecommendedShardsSchema, type GetRecommendedShardsDto } from './bot/dto/get-recommended-shards.dto.js'; - -export { SseIntervalQuerySchema } from './clusters/dto/sse-interval-query.dto.js'; -export { ClusterIdParamSchema, type ClusterIdParamDto } from './clusters/dto/cluster-id-param.dto.js'; -export { GetClusterSchema, type GetClusterDto } from './clusters/dto/get-cluster.dto.js'; -export { - GetClusterLogsQuerySchema, - GetClusterLogsSchema, - type GetClusterLogsQueryDto, - type GetClusterLogsDto, -} from './clusters/dto/get-cluster-logs.dto.js'; -export { GetClusterStatsSchema, type GetClusterStatsDto } from './clusters/dto/get-cluster-stats.dto.js'; -export { type GetAggregateStatsDto } from './clusters/dto/get-aggregate-stats.dto.js'; diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts new file mode 100644 index 0000000..d082160 --- /dev/null +++ b/packages/backend/src/index.ts @@ -0,0 +1,15 @@ +import { serve } from "@hono/node-server"; + +import env from "#lib/env"; + +import app from "./app"; + +serve( + { + fetch: app.fetch, + port: env.PORT, + }, + (info) => { + console.log(`Server is running on http://localhost:${info.port}`); + }, +); diff --git a/packages/backend/src/lib/database.ts b/packages/backend/src/lib/database.ts new file mode 100644 index 0000000..5662a14 --- /dev/null +++ b/packages/backend/src/lib/database.ts @@ -0,0 +1,9 @@ +import "dotenv/config"; +import { PrismaPg } from "@prisma/adapter-pg"; + +import { PrismaClient } from "#prisma/client"; + +const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }); +const prisma = new PrismaClient({ adapter }); + +export default prisma; diff --git a/packages/backend/src/lib/env.ts b/packages/backend/src/lib/env.ts new file mode 100644 index 0000000..6fbe807 --- /dev/null +++ b/packages/backend/src/lib/env.ts @@ -0,0 +1,10 @@ +import "dotenv/config"; +import z from "zod"; + +const EnvironmentSchema = z.object({ + SECRET: z.string(), + PORT: z.coerce.number().int().positive().default(3000), +}); + +const env = EnvironmentSchema.parse(process.env); +export default env; diff --git a/packages/backend/src/logger/logger.module.ts b/packages/backend/src/logger/logger.module.ts deleted file mode 100644 index d2adb67..0000000 --- a/packages/backend/src/logger/logger.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Module } from '@nestjs/common'; - -import { LoggerService } from './logger.service.js'; - -@Module({ - providers: [LoggerService], - exports: [LoggerService], -}) -export class LoggerModule {} diff --git a/packages/backend/src/logger/logger.service.spec.ts b/packages/backend/src/logger/logger.service.spec.ts deleted file mode 100644 index c42ab50..0000000 --- a/packages/backend/src/logger/logger.service.spec.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; - -import { LoggerService } from './logger.service.js'; - -describe('LoggerService', () => { - let service: LoggerService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [LoggerService], - }).compile(); - - service = module.get(LoggerService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/packages/backend/src/logger/logger.service.ts b/packages/backend/src/logger/logger.service.ts deleted file mode 100644 index 0f64689..0000000 --- a/packages/backend/src/logger/logger.service.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Injectable, LoggerService as NestLoggerService } from '@nestjs/common'; -import { utilities as nestWinstonModuleUtilities } from 'nest-winston'; -import * as winston from 'winston'; - -@Injectable() -export class LoggerService implements NestLoggerService { - private readonly logger: winston.Logger; - constructor() { - this.logger = winston.createLogger({ - level: 'debug', - transports: [ - new winston.transports.Console({ - format: winston.format.combine( - winston.format.timestamp(), - winston.format.ms(), - nestWinstonModuleUtilities.format.nestLike('Nest', { - colors: true, - prettyPrint: true, - processId: true, - appName: true, - }), - ), - }), - ], - }); - } - - log(message: string) { - this.logger.info(message); - } - - error(message: string, trace: string) { - this.logger.error(message, trace); - } - - warn(message: string) { - this.logger.warn(message); - } - - debug(message: string) { - this.logger.debug(message); - } - - verbose(message: string) { - this.logger.debug(message); - } -} diff --git a/packages/backend/src/logger/logging.interceptor.ts b/packages/backend/src/logger/logging.interceptor.ts deleted file mode 100644 index 95a7128..0000000 --- a/packages/backend/src/logger/logging.interceptor.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { CallHandler, ExecutionContext, HttpException, Injectable, NestInterceptor } from '@nestjs/common'; -import type { FastifyReply, FastifyRequest } from 'fastify'; -import { catchError, Observable, tap, throwError } from 'rxjs'; - -import { LoggerService } from './logger.service.js'; - -@Injectable() -export class LoggingInterceptor implements NestInterceptor { - constructor(private readonly logger: LoggerService) {} - - intercept(context: ExecutionContext, next: CallHandler): Observable { - const req = context.switchToHttp().getRequest(); - const method = req.method; - const url = req.url; - const start = Date.now(); - - return next.handle().pipe( - tap(() => { - const res = context.switchToHttp().getResponse(); - const statusCode = res.statusCode; - const duration = Date.now() - start; - - this.logger.log(`${method} ${url} ${statusCode} - ${duration}ms`); - }), - catchError((error: unknown) => { - const duration = Date.now() - start; - - if (error instanceof HttpException) { - const statusCode = error.getStatus(); - this.logger.error(`${method} ${url} ${statusCode} - ${duration}ms - ${error.message}`, error.stack ?? ''); - } else { - this.logger.error(`${method} ${url} 500 - ${duration}ms`, error instanceof Error ? (error.stack ?? '') : ''); - } - - return throwError(() => error); - }), - ); - } -} diff --git a/packages/backend/src/main.ts b/packages/backend/src/main.ts deleted file mode 100644 index 13b1546..0000000 --- a/packages/backend/src/main.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { constants } from 'node:zlib'; - -import fastifyCompress from '@fastify/compress'; -import { Logger } from '@nestjs/common'; -import { ConfigService } from '@nestjs/config'; -import { NestFactory } from '@nestjs/core'; -import type { NestFastifyApplication } from '@nestjs/platform-fastify'; -import { FastifyAdapter } from '@nestjs/platform-fastify'; -import type { OpenAPIObject, SwaggerCustomOptions } from '@nestjs/swagger'; -import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger'; -import { cleanupOpenApiDoc, ZodValidationPipe } from 'nestjs-zod'; -import { SwaggerTheme, SwaggerThemeNameEnum } from 'swagger-themes'; - -import { AppModule } from './app.module.js'; -import { AllExceptionsFilter } from './common/filters/all-exceptions.filter.js'; -import { LoggerService } from './logger/logger.service.js'; -import { LoggingInterceptor } from './logger/logging.interceptor.js'; - -const getSwaggerDocumentConfig = (): Omit => - new DocumentBuilder() - .setTitle('OpenAPI Documentation') - .setDescription( - 'This document indexes all the available routes, along with their params, queries, payloads and responses.', - ) - .addTag('Authentication', 'All the endpoints used to authenticate a user.') - .addTag('Bot', "All the endpoints used to manage the bot's configuration (shards, clusters, ...)") - .addTag('Clusters', 'All the endpoints to manage the clusters themselves (start, stop, restart, ...)') - .addBearerAuth( - { - type: 'http', - description: "A JWT returned by the 'login' auth endpoint.", - name: 'bearer', - }, - 'jwt', - ) - .setVersion('1.0') - .build(); - -async function bootstrap() { - const app = await NestFactory.create(AppModule, new FastifyAdapter()); - - const configService = app.get(ConfigService); - const port = configService.get('PORT', 3000); - const logRequests = configService.get('LOG_REQUESTS', false); - - const loggerService = app.get(LoggerService); - app.useLogger(loggerService); - Logger.overrideLogger(loggerService); - - app.useGlobalPipes(new ZodValidationPipe()); - app.useGlobalFilters(new AllExceptionsFilter()); - if (logRequests) { - app.useGlobalInterceptors(new LoggingInterceptor(loggerService)); - } - - app.enableCors({ - origin: '*', - }); - - await app.register(fastifyCompress, { - brotliOptions: { params: { [constants.BROTLI_PARAM_QUALITY]: 1 } }, - }); - - const swaggerDocumentationConfig = getSwaggerDocumentConfig(); - const document = SwaggerModule.createDocument(app, swaggerDocumentationConfig); - cleanupOpenApiDoc(document); - const theme = new SwaggerTheme(); - const swaggerConfig: SwaggerCustomOptions = { - explorer: true, - customSiteTitle: swaggerDocumentationConfig.info.title, - customCss: theme.getBuffer(SwaggerThemeNameEnum.DARK), - }; - SwaggerModule.setup('/openapi', app, document, swaggerConfig); - - await app.listen(port, '0.0.0.0'); -} - -bootstrap().catch(console.error); diff --git a/packages/backend/src/middlewares/auth.middlware.ts b/packages/backend/src/middlewares/auth.middlware.ts new file mode 100644 index 0000000..d82f675 --- /dev/null +++ b/packages/backend/src/middlewares/auth.middlware.ts @@ -0,0 +1,33 @@ +import { describeRoute, resolver } from "hono-openapi"; +import { jwt } from "hono/jwt"; + +import env from "#lib/env"; +import { ApiErrorSchema } from "#schemas/error.schema"; + +const authMiddlewares = [ + describeRoute({ + responses: { + 401: { + description: + "Route is protected by an Authorization header that is either not provided or invalid", + content: { + "application/json": { + schema: resolver(ApiErrorSchema), + example: { message: "Unauthorized" }, + }, + }, + }, + }, + security: [ + { + bearerAuth: [], + }, + ], + }), + jwt({ + secret: env.SECRET, + alg: "HS256", + }), +]; + +export default authMiddlewares; diff --git a/packages/backend/src/middlewares/validator.middleware.ts b/packages/backend/src/middlewares/validator.middleware.ts new file mode 100644 index 0000000..9227a6f --- /dev/null +++ b/packages/backend/src/middlewares/validator.middleware.ts @@ -0,0 +1,29 @@ +import type { ValidationTargets } from "hono"; +import { validator as openAPIValidator } from "hono-openapi"; + +import { ValidationException } from "#exceptions/http-exceptions"; + +type ValidatorSchema = Parameters[1]; +type ValidationResult = Parameters[2]>>[0]; + +function validationHook(result: ValidationResult) { + if (result.success) { + return; + } + + throw new ValidationException( + result.error.map((issue) => ({ + path: (issue.path ?? []) + .map((segment) => String(typeof segment === "object" ? segment.key : segment)) + .join("."), + message: issue.message, + })), + ); +} + +export default function validator< + Schema extends ValidatorSchema, + Target extends keyof ValidationTargets, +>(target: Target, schema: Schema) { + return openAPIValidator(target, schema, validationHook); +} diff --git a/packages/backend/src/prisma/prisma.module.ts b/packages/backend/src/prisma/prisma.module.ts deleted file mode 100644 index 2d18a8e..0000000 --- a/packages/backend/src/prisma/prisma.module.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { Module } from '@nestjs/common'; -import { ConfigModule, ConfigService } from '@nestjs/config'; - -import { PrismaService } from './prisma.service.js'; - -@Module({ - imports: [ConfigModule], - providers: [ - { - provide: PrismaService, - inject: [ConfigService], - useFactory(configService: ConfigService) { - const datasourceUrl = configService.getOrThrow('DATABASE_URL'); - - return new PrismaService(datasourceUrl); - }, - }, - ], - exports: [PrismaService], -}) -export class PrismaModule {} diff --git a/packages/backend/src/prisma/prisma.service.spec.ts b/packages/backend/src/prisma/prisma.service.spec.ts deleted file mode 100644 index a763246..0000000 --- a/packages/backend/src/prisma/prisma.service.spec.ts +++ /dev/null @@ -1,26 +0,0 @@ -import type { TestingModule } from '@nestjs/testing'; -import { Test } from '@nestjs/testing'; - -import { PrismaService } from './prisma.service.js'; - -describe('PrismaService', () => { - let service: PrismaService; - - beforeEach(async () => { - const module: TestingModule = await Test.createTestingModule({ - providers: [ - PrismaService, - { - provide: String, - useValue: 'postgres://username:password@localhost:5432/dbname', - }, - ], - }).compile(); - - service = module.get(PrismaService); - }); - - it('should be defined', () => { - expect(service).toBeDefined(); - }); -}); diff --git a/packages/backend/src/prisma/prisma.service.ts b/packages/backend/src/prisma/prisma.service.ts deleted file mode 100644 index 2e88644..0000000 --- a/packages/backend/src/prisma/prisma.service.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { PrismaClient } from '@hallmaster/prisma-client'; -import { Injectable, OnModuleDestroy, OnModuleInit } from '@nestjs/common'; -import { PrismaPg } from '@prisma/adapter-pg'; -import { Pool } from 'pg'; - -@Injectable() -export class PrismaService extends PrismaClient implements OnModuleInit, OnModuleDestroy { - constructor(databaseUrl: string) { - const pool = new Pool({ connectionString: databaseUrl }); - const adapter = new PrismaPg(pool); - super({ - adapter, - }); - } - - async onModuleInit() { - await this.$connect(); - } - - async onModuleDestroy() { - await this.$disconnect(); - } -} diff --git a/packages/backend/src/repositories/bot.repository.ts b/packages/backend/src/repositories/bot.repository.ts new file mode 100644 index 0000000..9ddda7a --- /dev/null +++ b/packages/backend/src/repositories/bot.repository.ts @@ -0,0 +1,123 @@ +import prisma from "#lib/database"; +import type { Bot } from "#prisma/client"; + +export default class BotRepository { + private static readonly DEFAULT_SELECT = { + id: true, + totalShards: true, + } as const; + + static async count() { + return prisma.bot.count(); + } + + public static async create(data: Omit) { + return prisma.bot.create({ + data: { + ...data, + totalShards: 0, + }, + select: this.DEFAULT_SELECT, + }); + } + + public static async delete() { + const bot = await this.findFirstId(); + if (bot === null) return null; + + return prisma.bot.delete({ where: { id: bot.id }, select: this.DEFAULT_SELECT }); + } + + public static async findFirst() { + return prisma.bot.findFirst({ select: this.DEFAULT_SELECT }); + } + + public static async findFirstId() { + return prisma.bot.findFirst({ select: { id: true } }); + } + + public static async findFirstIdContainerImageTotalShardsAndToken() { + return prisma.bot.findFirst({ + select: { + id: true, + token: true, + totalShards: true, + containerImage: { + select: { image: true, tag: true, serverName: true, username: true, password: true }, + }, + }, + }); + } + + public static async findFirstToken() { + return prisma.bot.findFirst({ select: { token: true } }); + } + + public static async findFirstIdAndToken() { + return prisma.bot.findFirst({ select: { id: true, token: true } }); + } + + public static async findFirstClusters() { + return prisma.bot.findFirst({ + select: { clusters: { select: { id: true, desiredStatus: true, shardIds: true } } }, + }); + } + + public static async updateToken(data: Pick) { + const bot = await this.findFirstId(); + if (bot === null) return null; + + return prisma.bot.update({ + data, + where: { + id: bot.id, + }, + select: this.DEFAULT_SELECT, + }); + } + + public static async updateTotalShards(data: Pick) { + const bot = await this.findFirstId(); + if (bot === null) { + return null; + } + + return prisma.bot.update({ + data, + where: { + id: bot.id, + }, + select: this.DEFAULT_SELECT, + }); + } + + // public static async createClusters(data: Pick[]) { + // const bot = await this.findFirstId(); + // if (bot === null) return null; + + // const { clusters } = await prisma.bot.update({ + // data: { + // totalShards: data.flatMap(({ shardIds }) => shardIds).length, + // clusters: { + // createMany: { + // data, + // }, + // }, + // }, + // where: { + // id: bot.id, + // }, + // select: { + // clusters: { + // select: { + // id: true, + // status: true, + // shardIds: true, + // }, + // }, + // }, + // }); + + // return clusters; + // } +} diff --git a/packages/backend/src/repositories/cluster.repository.ts b/packages/backend/src/repositories/cluster.repository.ts new file mode 100644 index 0000000..a31c3d5 --- /dev/null +++ b/packages/backend/src/repositories/cluster.repository.ts @@ -0,0 +1,106 @@ +import prisma from "#lib/database"; +import type { Cluster } from "#prisma/client"; + +export default class ClusterRepository { + private static readonly DEFAULT_SELECT = { + id: true, + shardIds: true, + desiredStatus: true, + } as const; + + public static async findFirstContainerIdById(id: Cluster["id"]) { + return prisma.cluster.findFirst({ + where: { id }, + select: { + containerId: true, + }, + }); + } + + public static async create( + data: Pick, + ) { + return prisma.cluster.create({ + data, + select: this.DEFAULT_SELECT, + }); + } + + public static async findFirstBotIdById(id: Cluster["id"]) { + return prisma.cluster.findFirst({ + where: { + id, + }, + select: { botId: true }, + }); + } + + public static async findFirstShardIdsById(id: Cluster["id"]) { + return prisma.cluster.findFirst({ + where: { id }, + select: { shardIds: true }, + }); + } + + public static async updateDesiredStatusById( + desiredStatus: Cluster["desiredStatus"], + id: Cluster["id"], + ) { + const cluster = await this.findFirstBotIdById(id); + if (cluster === null) return null; + + return prisma.cluster.update({ + data: { + desiredStatus, + }, + where: { botId_id: { botId: cluster.botId, id } }, + select: this.DEFAULT_SELECT, + }); + } + + public static async deleteById(id: Cluster["id"]) { + const cluster = await this.findFirstBotIdById(id); + if (cluster === null) return null; + + return prisma.cluster.delete({ + where: { botId_id: { botId: cluster.botId, id } }, + select: this.DEFAULT_SELECT, + }); + } + + public static async findMany() { + return prisma.cluster.findMany({ + select: this.DEFAULT_SELECT, + orderBy: { id: "asc" }, + }); + } + + public static async findManyWithContainerId() { + return prisma.cluster.findMany({ + select: { ...this.DEFAULT_SELECT, containerId: true }, + orderBy: { id: "asc" }, + }); + } + + public static async findManyId() { + return prisma.cluster.findMany({ select: { id: true }, orderBy: { id: "asc" } }); + } + + public static async findManyIdAndContainerId() { + return prisma.cluster.findMany({ select: { id: true, containerId: true } }); + } + + public static async updateManyDesiredStatusById( + desiredStatus: Cluster["desiredStatus"], + ids: Cluster["id"][], + ) { + return prisma.cluster.updateMany({ + data: { desiredStatus }, + where: { id: { in: ids } }, + }); + } + + public static async deleteManyById(ids: Cluster["id"][]) { + return prisma.cluster.deleteMany({ where: { id: { in: ids } } }); + } +} diff --git a/packages/backend/src/repositories/container-image.repository.ts b/packages/backend/src/repositories/container-image.repository.ts new file mode 100644 index 0000000..89c2418 --- /dev/null +++ b/packages/backend/src/repositories/container-image.repository.ts @@ -0,0 +1,67 @@ +import { ConflictException } from "#exceptions/http-exceptions"; +import prisma from "#lib/database"; +import type { ContainerImage } from "#prisma/client"; + +import BotRepository from "./bot.repository"; + +export default class ContainerImageRepository { + private static readonly DEFAULT_SELECT = { + serverName: true, + image: true, + tag: true, + username: true, + password: true, + } as const; + + public static async count() { + return prisma.containerImage.count(); + } + + public static async create( + data: Pick, + ) { + const bot = await BotRepository.findFirstId(); + if (bot === null) return null; + + if (await this.count()) + throw new ConflictException({ message: "A container image is already registered" }); + + return prisma.containerImage.create({ + data: { + ...data, + botId: bot.id, + }, + select: { + image: true, + serverName: true, + tag: true, + username: true, + }, + }); + } + + public static async findFirst() { + return prisma.containerImage.findFirst({ + select: this.DEFAULT_SELECT, + }); + } + + public static async findFirstId() { + return prisma.containerImage.findFirst({ select: { id: true } }); + } + + public static async update( + data: Pick, + ) { + const containerImage = await this.findFirstId(); + if (containerImage === null) return null; + + return prisma.containerImage.update({ + data, + where: { + id: containerImage.id, + }, + select: this.DEFAULT_SELECT, + }); + } +} diff --git a/packages/backend/src/repositories/user.repository.ts b/packages/backend/src/repositories/user.repository.ts new file mode 100644 index 0000000..360e3ae --- /dev/null +++ b/packages/backend/src/repositories/user.repository.ts @@ -0,0 +1,17 @@ +import prisma from "#lib/database"; +import type { User } from "#prisma/client"; + +export default class UserRepository { + static async create(data: User) { + return prisma.user.create({ select: { username: true }, data }); + } + + static async findFirstByUsername(username: User["username"]) { + return prisma.user.findFirst({ + select: { username: true, passwordHash: true }, + where: { + username, + }, + }); + } +} diff --git a/packages/backend/src/schemas/auth.schema.ts b/packages/backend/src/schemas/auth.schema.ts new file mode 100644 index 0000000..2123801 --- /dev/null +++ b/packages/backend/src/schemas/auth.schema.ts @@ -0,0 +1,12 @@ +import z from "zod"; + +export const UserSchema = z.object({ + username: z.string().min(1).meta({ description: "User username" }), + password: z.string().min(8).meta({ description: "User password" }), +}); +export type User = z.infer; + +export const UserTokenResponseSchema = z.object({ + token: z.jwt().meta({ description: "User session token" }), +}); +export type UserTokenResponse = z.infer; diff --git a/packages/backend/src/schemas/bot.schema.ts b/packages/backend/src/schemas/bot.schema.ts new file mode 100644 index 0000000..2143931 --- /dev/null +++ b/packages/backend/src/schemas/bot.schema.ts @@ -0,0 +1,79 @@ +import z from "zod"; + +import { ClusterSchema } from "./cluster.schema"; + +export const ContainerImageSchema = z.object({ + url: z.string().meta({ + description: "URL of the container image (example: ghcr.io/repo/image:tag)", + }), + username: z.string().optional().meta({ + description: "Username used to authenticate to the container registry", + }), + password: z.string().optional().meta({ + description: "Password used to authenticate to the container registry", + }), +}); +export type ContainerImage = z.infer; + +export const CreateBotSchema = z.object({ + token: z.string().meta({ + description: "Discord token of the bot", + }), +}); +export type CreateBot = z.infer; + +export const BotClusterLayoutSchema = z.array(ClusterSchema).meta({ + description: "Clusters layout", +}); +export type BotClusterLayout = z.infer; + +export const BotDiscordProfileSchema = z.object({ + name: z.string().meta({ + description: "Discord username of the bot", + }), + displayName: z.string().nullable().meta({ + description: "Discord display name (global name) of the bot, or null if none is set", + }), + discriminator: z.string().meta({ + description: "Discord discriminator", + }), + avatarUrl: z.string().nullable().meta({ + description: "URL of the bot avatar on the Discord CDN, or null if none is set", + }), + bannerUrl: z.string().nullable().meta({ + description: "URL of the bot banner on the Discord CDN, or null if none is set", + }), + accentColor: z.number().int().nullable().meta({ + description: "The bot profile accent color as an integer (0xRRGGBB)", + }), +}); +export type BotDiscordProfile = z.infer; + +export const BotSchema = z.object({ + id: z.string().meta({ + description: "Bot's ID", + }), + shards: z.number().nonnegative().meta({ + description: "Number of shards", + }), + // layout: z.array(BotClusterLayoutSchema).meta({ + // description: "Clusters layout", + // }), + // containerImage: ContainerImageSchema.omit({ password: true }).meta({ + // description: "Container image configuration associated to the bot", + // }), + // discordProfile: BotDiscordProfileSchema.nullable().optional().meta({ + // description: "Bot Discord profile", + // }), +}); +export type Bot = z.infer; + +export const RecommendedShardsSchema = BotSchema.pick({ shards: true }).meta({ + description: "Number of shards recommended by Discord", +}); +export type RecommendedShards = z.infer; + +// export const UpdateBotSchema = CreateBotSchema.extend({ +// layout: BotClusterLayoutSchema.meta({ description: "Cluster layout" }), +// }); +// export type UpdateBot = z.infer; diff --git a/packages/backend/src/schemas/cluster.schema.ts b/packages/backend/src/schemas/cluster.schema.ts new file mode 100644 index 0000000..762c920 --- /dev/null +++ b/packages/backend/src/schemas/cluster.schema.ts @@ -0,0 +1,133 @@ +import z from "zod"; + +export const ClusterIdSchema = z.coerce.number().int().nonnegative().meta({ + description: "Cluster ID", +}); +export type ClusterId = z.infer; + +export const ClusterStatusSchema = z + .enum(["STARTING", "RUNNING", "STOPPED", "ERROR", "UPDATING"]) + .meta({ description: "Status of the cluster" }); +export type ClusterStatus = z.infer; + +export const ClusterSchema = z.object({ + id: ClusterIdSchema, + shardIds: z.array(z.number().nonnegative()).meta({ + description: "Shard IDs associated to that cluster", + }), + status: ClusterStatusSchema, +}); +export type Cluster = z.infer; + +export const ClustersSchema = z.array(ClusterSchema); + +export const UpdateClustersSchema = z + .array(ClusterSchema.pick({ id: true, shardIds: true }).partial({ id: true })) + .min(1) + .meta({ description: "List of clusters to update or create (if id is not provided)" }); +export type UpdateClusters = z.infer; + +export const SseIntervalQuerySchema = z.object({ + interval: z.coerce.number().positive().min(1).max(120).optional().default(5).meta({ + description: "Refresh interval in seconds", + }), +}); + +export const ClusterActionSchema = z.enum(["start", "stop", "restart"]).meta({ + description: "Action to apply", +}); +export type ClusterAction = z.infer; + +export const ClusterStatsSchema = z.object({ + cpuPercentage: z.number().min(0).nonnegative().meta({ + description: "CPU usage percentage of the cluster", + }), + memory: z.object({ + usage: z.number().nonnegative().meta({ + description: "Number of bytes used in memory", + }), + percentage: z.number().min(0).nonnegative().meta({ + description: "Percentage of available memory used", + }), + }), + network: z.array( + z.object({ + interface: z.string().meta({ + description: "Networking interface name", + }), + transmitted: z.number().nonnegative().meta({ + description: "Number of bytes transmitted by the interface", + }), + received: z.number().nonnegative().meta({ + description: "Number of bytes received by the interface", + }), + }), + ), +}); +export type ClusterStats = z.infer; + +export const ClustersStatsSchema = z.record(ClusterIdSchema, ClusterStatsSchema).meta({ + description: + "Stats of every running clusters keyed by ID (clusters whose stats failed to fetch are omitted)", +}); +export type ClustersStats = z.infer; + +export const ClustersBulkActionResultSchema = z.object({ + succeeded: z.array(ClusterIdSchema).meta({ + description: "Successfull clusters IDs", + }), + failed: z + .array( + z.object({ + id: ClusterIdSchema, + reason: z.string(), + }), + ) + .meta({ + description: "Failed clusters IDs with the reason of failure", + }), +}); +export type ClustersBulkActionResult = z.infer; + +export const ClusterIdParamSchema = z.object({ + id: ClusterIdSchema, +}); + +export const ClusterActionParamSchema = z.object({ + action: ClusterActionSchema, +}); + +export const ClusterIdActionParamSchema = ClusterIdParamSchema.extend( + ClusterActionParamSchema.shape, +); + +export const ClusterLogsQuerySchema = z.object({ + since: z.coerce.date().optional().meta({ + description: "At which point in time does the logs collection start", + }), + until: z.coerce.date().optional().meta({ + description: "At which point in time does the logs collection end", + }), + tail: z.coerce.number().positive().min(1).or(z.literal("all")).optional().default("all").meta({ + description: "How many logs to fetch from latest to oldest ('all' gets all the logs)", + }), +}); +export type ClusterLogsQuery = z.infer; + +export const ClusterLogSchema = z.object({ + content: z.string().meta({ + description: "Content of a log line", + }), + stream: z.enum(["STDOUT", "STDERR"]).meta({ + description: "Stream that the log was published into", + }), + timestamp: z.string().optional().meta({ + description: "RFC3339Nano timestamp emitted by the Docker daemon for that log line", + }), +}); +export type ClusterLog = z.infer; + +export const ClusterLogsSchema = z.array(ClusterLogSchema).meta({ + description: "Logs (line by line) of a container", +}); +export type ClusterLogs = z.infer; diff --git a/packages/backend/src/schemas/discord.schema.ts b/packages/backend/src/schemas/discord.schema.ts new file mode 100644 index 0000000..41796e4 --- /dev/null +++ b/packages/backend/src/schemas/discord.schema.ts @@ -0,0 +1,16 @@ +import z from "zod"; + +import { BotSchema } from "./bot.schema"; + +export const DiscordGatewayBotSchema = BotSchema.pick({ shards: true }); +export type DiscordGatewayBot = z.infer; + +export const DiscordUserSchema = z.object({ + id: z.string(), + username: z.string(), + global_name: z.string().nullable(), + discriminator: z.string(), + avatar: z.string().nullable(), + banner: z.string().nullish(), + accent_color: z.number().int().nullish(), +}); diff --git a/packages/backend/src/schemas/docker.schema.ts b/packages/backend/src/schemas/docker.schema.ts new file mode 100644 index 0000000..ed46866 --- /dev/null +++ b/packages/backend/src/schemas/docker.schema.ts @@ -0,0 +1,26 @@ +import z from "zod"; + +const DockerCpuStatsSchema = z + .object({ + cpu_usage: z.object({ total_usage: z.number().default(0) }).prefault({}), + system_cpu_usage: z.number().default(0), + online_cpus: z.number().default(1), + }) + .prefault({}); +export type DockerCpuStats = z.infer; + +export const DockerContainerStatsSchema = z.object({ + cpu_stats: DockerCpuStatsSchema, + precpu_stats: DockerCpuStatsSchema, + memory_stats: z + .object({ + usage: z.number().default(0), + limit: z.number().default(0), + stats: z.object({ inactive_file: z.number().default(0) }).prefault({}), + }) + .prefault({}), + networks: z + .record(z.string(), z.object({ rx_bytes: z.number(), tx_bytes: z.number() })) + .default({}), +}); +export type DockerContainerStats = z.infer; diff --git a/packages/backend/src/schemas/error.schema.ts b/packages/backend/src/schemas/error.schema.ts new file mode 100644 index 0000000..20fa7ea --- /dev/null +++ b/packages/backend/src/schemas/error.schema.ts @@ -0,0 +1,15 @@ +import z from "zod"; + +export const ApiIssueSchema = z.object({ + path: z.string().meta({ description: "Dot-separated path of the invalid field" }), + message: z.string().meta({ description: "Reason why the field is invalid" }), +}); +export type ApiIssue = z.infer; + +export const ApiErrorSchema = z.object({ + message: z.string().meta({ description: "Error message" }), + issues: z.array(ApiIssueSchema).optional().meta({ + description: "Invalid fields, only present on validation errors", + }), +}); +export type ApiError = z.infer; diff --git a/packages/backend/src/schemas/index.ts b/packages/backend/src/schemas/index.ts new file mode 100644 index 0000000..fe54832 --- /dev/null +++ b/packages/backend/src/schemas/index.ts @@ -0,0 +1,4 @@ +export * from "./auth.schema"; +export * from "./bot.schema"; +export * from "./cluster.schema"; +export * from "./error.schema"; diff --git a/packages/backend/src/services/auth.service.ts b/packages/backend/src/services/auth.service.ts new file mode 100644 index 0000000..e2f6f27 --- /dev/null +++ b/packages/backend/src/services/auth.service.ts @@ -0,0 +1,38 @@ +import { hash, verify } from "argon2"; +import { sign } from "hono/jwt"; + +import { ConflictException, UnauthorizedException } from "#exceptions/http-exceptions"; +import prisma from "#lib/database"; +import env from "#lib/env"; +import UserRepository from "#repositories/user.repository"; +import type { User, UserTokenResponse } from "#schemas/auth.schema"; + +export class AuthService { + private static async sign(sub: string) { + return await sign( + { + sub, + exp: Math.floor(Date.now() / 1000) + 3600 * 12, // 12 hours + }, + env.SECRET, + ); + } + + public static async register({ username, password }: User): Promise { + const userCount = await prisma.user.count(); + if (userCount !== 0) throw new ConflictException({ message: "A user is already registered" }); + + const user = await UserRepository.create({ username, passwordHash: await hash(password) }); + + return { token: await this.sign(user.username) }; + } + + public static async login({ username, password }: User): Promise { + const user = await UserRepository.findFirstByUsername(username); + + if (user === null || !(await verify(user.passwordHash, password))) + throw new UnauthorizedException({ message: "Invalid username or password" }); + + return { token: await this.sign(user.username) }; + } +} diff --git a/packages/backend/src/services/bot.service.ts b/packages/backend/src/services/bot.service.ts new file mode 100644 index 0000000..58a96e0 --- /dev/null +++ b/packages/backend/src/services/bot.service.ts @@ -0,0 +1,169 @@ +import { ConflictException, NotFoundException } from "#exceptions/http-exceptions"; +import BotRepository from "#repositories/bot.repository"; +import ContainerImageRepository from "#repositories/container-image.repository"; +import type { Bot, ContainerImage, CreateBot } from "#schemas/bot.schema"; + +import ClusterService from "./cluster.service"; +import DiscordService from "./discord.service"; +import DockerService from "./docker.service"; + +export default class BotService { + private static parseContainerImage(url: ContainerImage["url"]) { + const [first, ...rest] = url.trim().split("/"); + const hasRegistry = + rest.length > 0 && (first.includes(".") || first.includes(":") || first === "localhost"); + const host = hasRegistry ? first : "docker.io"; + const path = hasRegistry ? rest : [first, ...rest]; + const repository = host === "docker.io" && path.length === 1 ? ["library", ...path] : path; + const [image, tag = "latest"] = repository.join("/").split(":"); + + return { host, image, tag }; + } + + public static async create({ token }: CreateBot): Promise { + await DiscordService.getGatewayBot(token); + + const botCount = await BotRepository.count(); + if (botCount !== 0) throw new ConflictException({ message: "A bot is already registered" }); + + const { id, totalShards } = await BotRepository.create({ + id: Buffer.from(token.split(".")[0], "base64").toString("ascii"), + token, + }); + + return { + id, + shards: totalShards, + }; + } + + public static async update({ token }: CreateBot): Promise { + const bot = await BotRepository.findFirstId(); + if (bot === null) throw new NotFoundException({ message: "Bot not found" }); + + await DiscordService.getGatewayBot(token); + + const updated = await BotRepository.updateToken({ token }); + if (updated === null) throw new NotFoundException({ message: "Bot not found" }); + + return { + id: updated.id, + shards: updated.totalShards, + }; + } + + public static async get(): Promise { + const bot = await BotRepository.findFirst(); + if (bot === null) throw new NotFoundException({ message: "Bot not found" }); + + return { + id: bot.id, + shards: bot.totalShards, + }; + } + + public static async delete(): Promise { + const bot = await BotRepository.findFirstId(); + if (bot === null) throw new NotFoundException({ message: "Bot not found" }); + + await ClusterService.stopAll(); + await ClusterService.removeAll(); + + const deleted = await BotRepository.delete(); + if (deleted === null) throw new NotFoundException({ message: "Bot not found" }); + + return { + id: deleted.id, + shards: deleted.totalShards, + }; + } + + public static async recommendedShards() { + const bot = await BotRepository.findFirstToken(); + if (bot === null) { + throw new NotFoundException({ message: "Bot not found" }); + } + + const { shards } = await DiscordService.getGatewayBot(bot.token); + + return { shards }; + } + + public static async discordProfile() { + const bot = await BotRepository.findFirstToken(); + if (bot === null) throw new NotFoundException({ message: "Bot not found" }); + + return DiscordService.getBotProfile(bot.token); + } + + public static async createContainerImage({ + url, + username, + password, + }: ContainerImage): Promise> { + const { host, image, tag } = this.parseContainerImage(url); + + await DockerService.ensureImage({ serverName: host, image, tag, username, password }); + + const containerImage = await ContainerImageRepository.create({ + image, + tag, + serverName: host, + username: username ?? null, + password: password ?? null, + }); + + if (containerImage === null) throw new NotFoundException({ message: "Bot not found" }); + + return { + url: `${containerImage.serverName}/${containerImage.image}:${containerImage.tag}`, + username: containerImage.username ?? undefined, + }; + } + + public static async getContainerImage() { + const containerImage = await ContainerImageRepository.findFirst(); + if (containerImage === null) + throw new NotFoundException({ message: "Container image not found" }); + + return { + url: `${containerImage.serverName}/${containerImage.image}:${containerImage.tag}`, + username: containerImage.username ?? undefined, + }; + } + + public static async updateContainerImage({ + url, + username, + password, + }: ContainerImage): Promise> { + const current = await ContainerImageRepository.findFirst(); + if (current === null) { + throw new NotFoundException({ message: "Container image not found" }); + } + + const { host, image, tag } = this.parseContainerImage(url); + const keepsCredentials = current.serverName === host && current.username === (username ?? null); + const credentials = { + username: username ?? null, + password: password ?? (keepsCredentials ? current.password : null), + }; + + await DockerService.ensureImage({ serverName: host, image, tag, ...credentials }); + + const containerImage = await ContainerImageRepository.update({ + image, + tag, + serverName: host, + ...credentials, + }); + + if (containerImage === null) + throw new NotFoundException({ message: "Container image not found" }); + + return { + url: `${containerImage.serverName}/${containerImage.image}:${containerImage.tag}`, + username: containerImage.username ?? undefined, + }; + } +} diff --git a/packages/backend/src/services/cluster.service.ts b/packages/backend/src/services/cluster.service.ts new file mode 100644 index 0000000..70490ea --- /dev/null +++ b/packages/backend/src/services/cluster.service.ts @@ -0,0 +1,373 @@ +import { BadRequestException, NotFoundException } from "#exceptions/http-exceptions"; +import type { Bot, Cluster as ClusterRow, ContainerImage } from "#prisma/client"; +import BotRepository from "#repositories/bot.repository"; +import ClusterRepository from "#repositories/cluster.repository"; +import ContainerImageRepository from "#repositories/container-image.repository"; +import type { + Cluster, + ClusterAction, + ClusterId, + ClusterLogsQuery, + ClustersBulkActionResult, + ClusterStatus, + UpdateClusters, +} from "#schemas/cluster.schema"; + +import DockerService from "./docker.service"; + +type PendingStatus = Extract; + +export default class ClusterService { + private static readonly pendingStatuses = new Map(); + + private static async track( + ids: ClusterId[], + status: PendingStatus, + operation: () => Promise, + ) { + for (const id of ids) { + this.pendingStatuses.set(id, status); + } + + try { + return await operation(); + } finally { + for (const id of ids) { + this.pendingStatuses.delete(id); + } + } + } + + private static status( + desiredStatus: ClusterRow["desiredStatus"], + containerState: string | undefined, + pendingStatus: PendingStatus | undefined, + ): ClusterStatus { + if (pendingStatus !== undefined) { + return pendingStatus; + } + + switch (containerState) { + case undefined: + return "ERROR"; + case "running": + return "RUNNING"; + case "restarting": + return "STARTING"; + default: + return desiredStatus === "RUNNING" ? "ERROR" : "STOPPED"; + } + } + + private static async findManyObserved() { + const clusters = await ClusterRepository.findManyWithContainerId(); + const containerStates = await DockerService.containerStates( + clusters.map(({ containerId }) => containerId), + ); + + return clusters.map(({ id, shardIds, desiredStatus, containerId }) => ({ + id, + shardIds, + containerId, + status: this.status( + desiredStatus, + containerStates.get(containerId), + this.pendingStatuses.get(id), + ), + })); + } + + private static async findObserved(id: ClusterId) { + const cluster = (await this.findManyObserved()).find((cluster) => cluster.id === id); + if (cluster === undefined) { + throw new NotFoundException({ message: `Cluster ${id} not found` }); + } + + return cluster; + } + + private static async create( + cluster: Pick, + bot: Pick, + containerImage: Pick, + ) { + const shards = cluster.shardIds.join(","); + + const container = await DockerService.create( + { + Image: `${containerImage.serverName}/${containerImage.image}:${containerImage.tag}`, + Env: [ + `DISCORD_BOT_TOKEN=${bot.token}`, + `TOTAL_SHARDS=${bot.totalShards}`, + `SHARD_ID_LIST=${shards}`, + ], + Labels: { + "dev.hallmaster.cluster": cluster.id.toString(), + "dev.hallmaster.shards": shards, + }, + }, + `${bot.id}-${cluster.id}`, + ); + + await ClusterRepository.create({ + id: cluster.id, + botId: bot.id, + containerId: container.Id, + shardIds: cluster.shardIds, + desiredStatus: cluster.desiredStatus, + }); + + return container.Id; + } + + private static async findRunningContainerId(id: ClusterId) { + const cluster = await this.findObserved(id); + if (cluster.status !== "RUNNING") { + throw new BadRequestException({ message: `Cluster ${id} is not running` }); + } + + return cluster.containerId; + } + + public static async get(id: ClusterId): Promise { + const { shardIds, status } = await this.findObserved(id); + + return { id, shardIds, status }; + } + + public static async logs(id: ClusterId, options: ClusterLogsQuery) { + const cluster = await ClusterRepository.findFirstContainerIdById(id); + if (cluster === null) throw new NotFoundException({ message: `Cluster ${id} not found` }); + + return DockerService.containerLogs(cluster.containerId, { + tail: options.tail, + since: options.since && Math.floor(options.since.getTime() / 1000), + until: options.until && Math.ceil(options.until.getTime() / 1000), + stdout: true, + stderr: true, + timestamps: true, + follow: false, + }); + } + + public static async streamLogs(id: ClusterId) { + const cluster = await ClusterRepository.findFirstContainerIdById(id); + if (cluster === null) throw new NotFoundException({ message: `Cluster ${id} not found` }); + + return DockerService.streamContainerLogs(cluster.containerId, { + tail: 0, + stdout: true, + stderr: true, + timestamps: true, + }); + } + + public static async stats(id: ClusterId) { + const containerId = await this.findRunningContainerId(id); + + return DockerService.containerStats(containerId); + } + + public static async getAllStats() { + const clusters = (await this.findManyObserved()).filter(({ status }) => status === "RUNNING"); + const results = await Promise.allSettled( + clusters.map( + async ({ id, containerId }) => + [id, await DockerService.containerStats(containerId)] as const, + ), + ); + + return Object.fromEntries( + results.flatMap((result) => (result.status === "fulfilled" ? [result.value] : [])), + ); + } + + public static async streamStats(id: ClusterId) { + const containerId = await this.findRunningContainerId(id); + + return DockerService.streamContainerStats(containerId); + } + + public static async start(id: ClusterId) { + const cluster = await ClusterRepository.findFirstContainerIdById(id); + if (cluster === null) throw new NotFoundException({ message: `Cluster ${id} not found` }); + + await this.track([id], "STARTING", async () => { + await ClusterRepository.updateDesiredStatusById("RUNNING", id); + await DockerService.startContainer(cluster.containerId); + }); + + return this.get(id); + } + + public static async stop(id: ClusterId) { + const cluster = await ClusterRepository.findFirstContainerIdById(id); + if (cluster === null) throw new NotFoundException({ message: `Cluster ${id} not found` }); + + await ClusterRepository.updateDesiredStatusById("STOPPED", id); + await DockerService.stopContainer(cluster.containerId); + + return this.get(id); + } + + public static async restart(id: ClusterId) { + const cluster = await ClusterRepository.findFirstContainerIdById(id); + if (cluster === null) throw new NotFoundException({ message: `Cluster ${id} not found` }); + + await this.track([id], "STARTING", async () => { + await ClusterRepository.updateDesiredStatusById("RUNNING", id); + await DockerService.restartContainer(cluster.containerId); + }); + + return this.get(id); + } + + public static async runAction(id: ClusterId, action: ClusterAction) { + const actions = { + start: () => this.start(id), + stop: () => this.stop(id), + restart: () => this.restart(id), + } satisfies Record Promise>; + + return actions[action](); + } + + public static async runActionOnAll(action: ClusterAction): Promise { + const clusters = await ClusterRepository.findManyId(); + const outcomes = await Promise.all( + clusters.map(({ id }) => + this.runAction(id, action).then( + () => ({ id, reason: null }), + (error: unknown) => ({ + id, + reason: error instanceof Error ? error.message : String(error), + }), + ), + ), + ); + + return { + succeeded: outcomes.filter(({ reason }) => reason === null).map(({ id }) => id), + failed: outcomes.flatMap(({ id, reason }) => (reason === null ? [] : [{ id, reason }])), + }; + } + + public static async remove(id: ClusterId): Promise { + const { shardIds, status, containerId } = await this.findObserved(id); + + await DockerService.stopContainer(containerId); + await DockerService.removeContainer(containerId); + await ClusterRepository.deleteById(id); + + return { id, shardIds, status }; + } + + public static async getAll(): Promise { + const clusters = await this.findManyObserved(); + + return clusters.map(({ id, shardIds, status }) => ({ id, shardIds, status })); + } + + public static async stopAll() { + const clusters = await ClusterRepository.findManyIdAndContainerId(); + if (clusters.length === 0) { + return; + } + + await Promise.all(clusters.map(({ containerId }) => DockerService.stopContainer(containerId))); + + return ClusterRepository.updateManyDesiredStatusById( + "STOPPED", + clusters.map(({ id }) => id), + ); + } + + public static async removeAll() { + const clusters = await ClusterRepository.findManyIdAndContainerId(); + if (clusters.length === 0) return; + + await Promise.all( + clusters.map(({ containerId }) => DockerService.removeContainer(containerId)), + ); + + return ClusterRepository.deleteManyById(clusters.map(({ id }) => id)); + } + + public static async updateAll(clusters: UpdateClusters) { + const bot = await BotRepository.findFirstIdAndToken(); + if (bot === null) throw new NotFoundException({ message: "Bot not found" }); + + const ids = new Set(); + const previous = await ClusterRepository.findMany(); + const previousIds = new Set(previous.map(({ id }) => id)); + + for (const [index, cluster] of clusters.entries()) { + if (cluster.shardIds.length === 0) + throw new BadRequestException({ message: `Cluster at index ${index} is empty` }); + + if (cluster.id === undefined) continue; + + if (ids.has(cluster.id)) + throw new BadRequestException({ message: `Duplicate cluster ${cluster.id}` }); + + if (!previousIds.has(cluster.id)) + throw new BadRequestException({ message: `Cluster ${cluster.id} does not exist` }); + + ids.add(cluster.id); + } + + const shards = clusters.flatMap(({ shardIds }) => shardIds).sort((a, b) => a - b); + for (let index = 0; index < shards.length; index++) { + const shard = shards[index]; + + if (shard !== index) { + throw new BadRequestException({ + message: `Non-contiguous shard IDs, expected ${index} but got ${shard}`, + }); + } + } + + let nextId = 0; + for (const cluster of clusters) { + if (cluster.id !== undefined) continue; + + while (ids.has(nextId)) nextId++; + cluster.id = nextId++; + } + + const containerImage = await ContainerImageRepository.findFirst(); + if (containerImage === null) + throw new NotFoundException({ message: "Container image not found" }); + + await DockerService.ensureImage(containerImage); + + const affectedIds = [...new Set([...previousIds, ...clusters.map(({ id }) => id!)])]; + await this.track(affectedIds, "UPDATING", async () => { + await this.stopAll(); + await this.removeAll(); + + const updatedBot = await BotRepository.updateTotalShards({ totalShards: shards.length }); + if (updatedBot === null) { + throw new NotFoundException({ message: "Bot not found" }); + } + + const desiredStatuses = new Map(previous.map(({ id, desiredStatus }) => [id, desiredStatus])); + await Promise.all( + clusters.map(async (cluster) => { + const desiredStatus = desiredStatuses.get(cluster.id!) ?? "RUNNING"; + const containerId = await this.create( + { id: cluster.id!, shardIds: cluster.shardIds, desiredStatus }, + { ...bot, totalShards: updatedBot.totalShards }, + containerImage, + ); + + if (desiredStatus === "RUNNING") { + await DockerService.startContainer(containerId); + } + }), + ); + }); + + return this.getAll(); + } +} diff --git a/packages/backend/src/services/discord.service.ts b/packages/backend/src/services/discord.service.ts new file mode 100644 index 0000000..f7d8a2b --- /dev/null +++ b/packages/backend/src/services/discord.service.ts @@ -0,0 +1,68 @@ +import type z from "zod"; + +import { FailedDependancyException } from "#exceptions/http-exceptions"; +import type { BotDiscordProfile } from "#schemas/bot.schema"; +import { + DiscordGatewayBotSchema, + DiscordUserSchema, + type DiscordGatewayBot, +} from "#schemas/discord.schema"; + +export default class DiscordService { + private static readonly DISCORD_API_BASE_URL = "https://discord.com/api/v10"; + private static readonly DISCORD_CDN_BASE_URL = "https://cdn.discordapp.com"; + + private static async request( + path: `/${string}`, + token: string, + schema: S, + ): Promise> { + const response = await fetch(`${DiscordService.DISCORD_API_BASE_URL}${path}`, { + headers: { Authorization: `Bot ${token}` }, + signal: AbortSignal.timeout(10_000), + }).catch(() => { + throw new FailedDependancyException({ message: "Discord API is unreachable or timed out" }); + }); + + if (response.status === 401) + throw new FailedDependancyException({ message: "Invalid Discord bot token" }); + + if (!response.ok) { + throw new FailedDependancyException({ + message: `Discord API returned a ${response.status} ${response.statusText}`, + }); + } + + try { + return schema.parse(await response.json()); + } catch (error) { + throw new FailedDependancyException({ + message: "Discord API returned an unexpected response body", + cause: error, + }); + } + } + + private static cdnUrl(kind: "avatars" | "banners", id: string, hash: string) { + const extension = hash.startsWith("a_") ? "gif" : "png"; + + return `${this.DISCORD_CDN_BASE_URL}/${kind}/${id}/${hash}.${extension}`; + } + + public static async getGatewayBot(token: string): Promise { + return await this.request("/gateway/bot", token, DiscordGatewayBotSchema); + } + + public static async getBotProfile(token: string): Promise { + const user = await this.request("/users/@me", token, DiscordUserSchema); + + return { + name: user.username, + displayName: user.global_name, + discriminator: user.discriminator, + avatarUrl: user.avatar ? this.cdnUrl("avatars", user.id, user.avatar) : null, + bannerUrl: user.banner ? this.cdnUrl("banners", user.id, user.banner) : null, + accentColor: user.accent_color ?? null, + }; + } +} diff --git a/packages/backend/src/services/docker.service.ts b/packages/backend/src/services/docker.service.ts new file mode 100644 index 0000000..d0b22ee --- /dev/null +++ b/packages/backend/src/services/docker.service.ts @@ -0,0 +1,237 @@ +import { Transform } from "node:stream"; + +import { + DockerAPIHttpError, + DockerContainersAPI, + DockerImagesAPI, + DockerSocket, +} from "@hallmaster/docker.js"; + +import { FailedDependancyException } from "#exceptions/http-exceptions"; +import { + DockerContainerStatsSchema, + type DockerContainerStats, + type DockerCpuStats, +} from "#schemas/docker.schema"; + +type MethodParameters< + C extends abstract new (...args: any[]) => any, + P extends keyof InstanceType, +> = Parameters[P], (...args: any[]) => any>>; + +type RegistryImage = { + serverName: string; + image: string; + tag: string; + username?: string | null; + password?: string | null; +}; + +const socket = new DockerSocket(); +await socket.init(); + +export default class DockerService { + private static readonly images = new DockerImagesAPI(socket); + private static readonly containers = new DockerContainersAPI(socket); + + private static async call(request: Promise): Promise; + private static async call( + request: Promise, + ignoredStatuses: number[], + ): Promise; + private static async call(request: Promise, ignoredStatuses: number[] = []) { + return request.catch((error: unknown) => { + if (!(error instanceof DockerAPIHttpError)) { + throw new FailedDependancyException({ + message: "Docker Engine API returned an unexpected response", + cause: error, + }); + } + + if (ignoredStatuses.includes(error.status)) { + return undefined; + } + + throw new FailedDependancyException({ + message: `Docker Engine API returned a ${error.status} ${error.message}`, + cause: error, + }); + }); + } + + private static percentage(value: number, total: number) { + return total > 0 ? (value / total) * 100 : 0; + } + + private static cpuPercentage(cpu: DockerCpuStats, precpu: DockerCpuStats) { + const cpuDelta = cpu.cpu_usage.total_usage - precpu.cpu_usage.total_usage; + const systemDelta = cpu.system_cpu_usage - precpu.system_cpu_usage; + if (precpu.system_cpu_usage === 0 || cpuDelta <= 0) { + return 0; + } + + return this.percentage(cpuDelta, systemDelta) * cpu.online_cpus; + } + + private static toContainerStats(stats: DockerContainerStats) { + const memoryUsage = Math.max( + stats.memory_stats.usage - stats.memory_stats.stats.inactive_file, + 0, + ); + + return { + cpuPercentage: this.cpuPercentage(stats.cpu_stats, stats.precpu_stats), + memory: { + usage: memoryUsage, + percentage: this.percentage(memoryUsage, stats.memory_stats.limit), + }, + network: Object.entries(stats.networks).map(([name, network]) => ({ + interface: name, + transmitted: network.tx_bytes, + received: network.rx_bytes, + })), + }; + } + + private static unexpectedContainerStats(cause: unknown) { + return new FailedDependancyException({ + message: "Docker Engine API returned unexpected container stats", + cause, + }); + } + + private static registryAuth({ serverName, username, password }: RegistryImage) { + if (!username || !password) { + return undefined; + } + + return { serveraddress: serverName, username, password }; + } + + private static familiarReference({ serverName, image, tag }: RegistryImage) { + if (serverName !== "docker.io") { + return `${serverName}/${image}:${tag}`; + } + + return `${image.replace(/^library\//, "")}:${tag}`; + } + + private static async pullImage(image: RegistryImage) { + return this.call( + this.images.create({ + fromImage: `${image.serverName}/${image.image}`, + tag: image.tag, + auth: this.registryAuth(image), + }), + ); + } + + private static async hasImage(image: RegistryImage) { + const images = await this.call( + this.images.list({ filters: { reference: [this.familiarReference(image)] } }), + ); + + return images.length > 0; + } + + public static async ensureImage(image: RegistryImage) { + if (await this.hasImage(image)) { + return; + } + + await this.pullImage(image); + } + + public static async containerStates(containerIds: string[]) { + if (containerIds.length === 0) { + return new Map(); + } + + const containers = await this.call( + this.containers.list({ all: true, filters: { id: containerIds } }), + ); + + return new Map(containers.map(({ Id, State }) => [Id, State])); + } + + public static async create(...options: MethodParameters) { + return this.call(this.containers.create(...options)); + } + + public static async startContainer( + ...options: MethodParameters + ) { + return this.call(this.containers.start(...options), [304]); + } + + public static async stopContainer( + ...options: MethodParameters + ) { + return this.call(this.containers.stop(...options), [304, 404]); + } + + public static async restartContainer( + ...options: MethodParameters + ) { + return this.call(this.containers.restart(...options)); + } + + public static async removeContainer( + ...options: MethodParameters + ) { + return this.call(this.containers.remove(...options), [404]); + } + + public static async containerLogs( + ...options: MethodParameters + ) { + return this.call(this.containers.logs(...options)); + } + + public static async streamContainerLogs( + containerId: string, + options: Omit[1]>, "follow">, + ) { + return this.call(this.containers.logs(containerId, { ...options, follow: true })); + } + + public static async containerStats(containerId: string) { + const sample = await this.call( + this.containers.stats(containerId, { stream: false, oneShot: false }), + ); + + const result = DockerContainerStatsSchema.safeParse(sample); + if (!result.success) { + throw this.unexpectedContainerStats(result.error); + } + + return this.toContainerStats(result.data); + } + + public static async streamContainerStats(containerId: string) { + const samples = await this.call(this.containers.stats(containerId, { stream: true })); + const stats = new Transform({ + objectMode: true, + transform: (sample: unknown, _encoding, callback) => { + const result = DockerContainerStatsSchema.safeParse(sample); + if (!result.success) { + callback(this.unexpectedContainerStats(result.error)); + return; + } + + if (result.data.precpu_stats.system_cpu_usage === 0) { + callback(); + return; + } + + callback(null, this.toContainerStats(result.data)); + }, + }); + + samples.pipe(stats); + samples.on("error", (error) => stats.destroy(error)); + stats.on("close", () => samples.destroy()); + + return stats; + } +} diff --git a/packages/backend/tests/integration/api.test.ts b/packages/backend/tests/integration/api.test.ts new file mode 100644 index 0000000..e4320f6 --- /dev/null +++ b/packages/backend/tests/integration/api.test.ts @@ -0,0 +1,83 @@ +import { beforeEach, describe, expect, it } from "vitest"; + +import { register, request, resetState } from "./helpers"; + +beforeEach(async () => { + await resetState(); +}); + +describe("authentication", () => { + it("registers a single user", async () => { + expect(await register()).toEqual(expect.any(String)); + + const second = await request("/auth/register", { + method: "POST", + body: { username: "other", password: "password123" }, + }); + + expect(second.status).toBe(409); + expect(await second.json()).toEqual({ message: "A user is already registered" }); + }); + + it("rejects a wrong password", async () => { + await register(); + + const response = await request("/auth/login", { + method: "POST", + body: { username: "admin", password: "wrong-password" }, + }); + + expect(response.status).toBe(401); + expect(await response.json()).toEqual({ message: "Invalid username or password" }); + }); + + it("rejects a request without a token", async () => { + const response = await request("/clusters"); + + expect(response.status).toBe(401); + expect(response.headers.get("WWW-Authenticate")).toContain("Bearer"); + expect(await response.json()).toEqual({ message: expect.any(String) }); + }); +}); + +describe("error responses", () => { + it("lists invalid fields without echoing the submitted values", async () => { + const response = await request("/auth/register", { + method: "POST", + body: { username: "admin", password: "short" }, + }); + const body = await response.text(); + + expect(response.status).toBe(400); + expect(JSON.parse(body)).toEqual({ + message: "Validation failed", + issues: [{ path: "password", message: expect.any(String) }], + }); + expect(body).not.toContain("short"); + }); + + it("reports invalid path parameters", async () => { + const token = await register(); + + const response = await request("/clusters/abc", { token }); + + expect(response.status).toBe(400); + expect(await response.json()).toMatchObject({ issues: [{ path: "id" }] }); + }); + + it("reports unknown routes as json", async () => { + const response = await request("/nope"); + + expect(response.status).toBe(404); + expect(await response.json()).toEqual({ message: "Route not found" }); + }); + + it("reports unknown clusters as json", async () => { + const token = await register(); + + const response = await request("/clusters/42", { token }); + + expect(response.status).toBe(404); + expect(await response.json()).toEqual({ message: "Cluster 42 not found" }); + }); +}); diff --git a/packages/backend/tests/integration/bot.test.ts b/packages/backend/tests/integration/bot.test.ts new file mode 100644 index 0000000..aa60bf2 --- /dev/null +++ b/packages/backend/tests/integration/bot.test.ts @@ -0,0 +1,137 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { FailedDependancyException } from "#exceptions/http-exceptions"; +import DiscordService from "#services/discord.service"; + +import { BOT_ID, register, request, resetState } from "./helpers"; + +vi.mock("#services/discord.service", () => ({ + default: { + getBotProfile: vi.fn(), + getGatewayBot: vi.fn(), + }, +})); + +const DISCORD_TOKEN = `${Buffer.from(BOT_ID).toString("base64")}.timestamp.signature`; + +let token: string; + +async function call(path: string, init: { method?: string; body?: unknown } = {}) { + const response = await request(path, { ...init, token }); + + return { status: response.status, body: (await response.json()) as unknown }; +} + +beforeEach(async () => { + vi.resetAllMocks(); + vi.mocked(DiscordService.getGatewayBot).mockResolvedValue({ shards: 2 }); + vi.mocked(DiscordService.getBotProfile).mockResolvedValue({ + name: "hallmaster", + displayName: "HallMaster", + discriminator: "0", + avatarUrl: null, + bannerUrl: null, + accentColor: null, + }); + + await resetState(); + token = await register(); +}); + +describe("bot registration", () => { + it("registers a single bot from its Discord token", async () => { + const created = await call("/bot", { method: "POST", body: { token: DISCORD_TOKEN } }); + + expect(created).toEqual({ status: 201, body: { id: BOT_ID, shards: 0 } }); + expect(await call("/bot")).toEqual({ status: 200, body: { id: BOT_ID, shards: 0 } }); + expect(await call("/bot", { method: "POST", body: { token: DISCORD_TOKEN } })).toEqual({ + status: 409, + body: { message: "A bot is already registered" }, + }); + }); + + it("rejects an invalid Discord token", async () => { + vi.mocked(DiscordService.getGatewayBot).mockRejectedValue( + new FailedDependancyException({ message: "Invalid Discord bot token" }), + ); + + expect(await call("/bot", { method: "POST", body: { token: "invalid" } })).toEqual({ + status: 424, + body: { message: "Invalid Discord bot token" }, + }); + }); + + it("updates the bot token", async () => { + await call("/bot", { method: "POST", body: { token: DISCORD_TOKEN } }); + + const updated = await call("/bot", { method: "PUT", body: { token: `${DISCORD_TOKEN}2` } }); + + expect(updated).toEqual({ status: 200, body: { id: BOT_ID, shards: 0 } }); + expect(DiscordService.getGatewayBot).toHaveBeenLastCalledWith(`${DISCORD_TOKEN}2`); + }); + + it("returns the Discord profile and the recommended shards", async () => { + await call("/bot", { method: "POST", body: { token: DISCORD_TOKEN } }); + + expect(await call("/bot/profile")).toMatchObject({ + status: 200, + body: { name: "hallmaster", displayName: "HallMaster" }, + }); + expect(await call("/bot/recommended-shards")).toEqual({ status: 200, body: { shards: 2 } }); + }); + + it("reports that no bot is registered", async () => { + expect(await call("/bot")).toEqual({ status: 404, body: { message: "Bot not found" } }); + }); +}); + +describe("container image", () => { + beforeEach(async () => { + await call("/bot", { method: "POST", body: { token: DISCORD_TOKEN } }); + }); + + it("registers a single container image", async () => { + expect(await call("/bot/container-image")).toEqual({ + status: 404, + body: { message: "Container image not found" }, + }); + + const created = await call("/bot/container-image", { + method: "POST", + body: { url: "nginx:alpine" }, + }); + + expect(created).toEqual({ status: 201, body: { url: "docker.io/library/nginx:alpine" } }); + expect((await call("/bot/container-image")).body).toEqual({ + url: "docker.io/library/nginx:alpine", + }); + expect( + (await call("/bot/container-image", { method: "POST", body: { url: "nginx:alpine" } })) + .status, + ).toBe(409); + }); + + it("updates the container image without exposing the password", async () => { + await call("/bot/container-image", { method: "POST", body: { url: "nginx:alpine" } }); + + const updated = await call("/bot/container-image", { + method: "PUT", + body: { url: "docker.io/library/nginx:alpine", username: "deployer", password: "secret" }, + }); + + expect(updated).toEqual({ + status: 200, + body: { url: "docker.io/library/nginx:alpine", username: "deployer" }, + }); + expect(JSON.stringify((await call("/bot/container-image")).body)).not.toContain("secret"); + }); + + it("refuses to update an image that was never registered", async () => { + const { status } = await call("/bot/container-image", { + method: "PUT", + body: { url: "nginx:alpine" }, + }); + + expect(status).toBe(404); + }); +}); diff --git a/packages/backend/tests/integration/clusters.test.ts b/packages/backend/tests/integration/clusters.test.ts new file mode 100644 index 0000000..07c7d02 --- /dev/null +++ b/packages/backend/tests/integration/clusters.test.ts @@ -0,0 +1,234 @@ +import { afterAll, beforeEach, describe, expect, it } from "vitest"; + +import { + containerState, + createBot, + openEvents, + register, + removeContainerOutsideHallMaster, + request, + resetState, + stopContainerOutsideHallMaster, +} from "./helpers"; + +type Cluster = { id: number; shardIds: number[]; status: string }; + +let token: string; + +async function call(path: string, init: { method?: string; body?: unknown } = {}) { + const response = await request(path, { ...init, token }); + + return { status: response.status, body: (await response.json()) as unknown }; +} + +async function applyLayout(layout: { id?: number; shardIds: number[] }[]) { + const { status, body } = await call("/clusters", { method: "PUT", body: layout }); + expect(status).toBe(200); + + return body as Cluster[]; +} + +afterAll(async () => { + await resetState(); +}); + +beforeEach(async () => { + await resetState(); + token = await register(); + await createBot(); + + const { status } = await call("/bot/container-image", { + method: "POST", + body: { url: "nginx:alpine" }, + }); + expect(status).toBe(201); +}); + +describe("cluster layout", () => { + it("starts every cluster of a new layout", async () => { + const clusters = await applyLayout([{ shardIds: [0] }, { shardIds: [1, 2] }]); + + expect(clusters).toEqual([ + { id: 0, shardIds: [0], status: "RUNNING" }, + { id: 1, shardIds: [1, 2], status: "RUNNING" }, + ]); + expect(await containerState(0)).toBe("running"); + expect(await containerState(1)).toBe("running"); + expect((await call("/bot")).body).toMatchObject({ shards: 3 }); + }); + + it("keeps a stopped cluster stopped when the layout changes", async () => { + await applyLayout([{ shardIds: [0] }]); + await call("/clusters/0/stop", { method: "POST" }); + + const clusters = await applyLayout([{ id: 0, shardIds: [0] }, { shardIds: [1] }]); + + expect(clusters).toEqual([ + { id: 0, shardIds: [0], status: "STOPPED" }, + { id: 1, shardIds: [1], status: "RUNNING" }, + ]); + }); + + it("recreates a cluster whose container was removed outside HallMaster", async () => { + await applyLayout([{ shardIds: [0] }]); + await removeContainerOutsideHallMaster(0); + + const clusters = await applyLayout([{ id: 0, shardIds: [0] }]); + + expect(clusters).toEqual([{ id: 0, shardIds: [0], status: "RUNNING" }]); + expect(await containerState(0)).toBe("running"); + }); +}); + +describe("cluster actions", () => { + beforeEach(async () => { + await applyLayout([{ shardIds: [0] }, { shardIds: [1] }]); + }); + + it("stops and starts a single cluster", async () => { + expect((await call("/clusters/0/stop", { method: "POST" })).body).toMatchObject({ + status: "STOPPED", + }); + expect(await containerState(0)).toBe("exited"); + expect(await containerState(1)).toBe("running"); + + expect((await call("/clusters/0/start", { method: "POST" })).body).toMatchObject({ + status: "RUNNING", + }); + expect(await containerState(0)).toBe("running"); + }); + + it("reports the failures of an action applied to every cluster", async () => { + await removeContainerOutsideHallMaster(1); + + const { body } = await call("/clusters/restart", { method: "POST" }); + + expect(body).toEqual({ + succeeded: [0], + failed: [{ id: 1, reason: expect.stringContaining("No such container") }], + }); + }); + + it("stops and starts every cluster", async () => { + expect((await call("/clusters/stop", { method: "POST" })).body).toEqual({ + succeeded: [0, 1], + failed: [], + }); + expect(await containerState(0)).toBe("exited"); + expect(await containerState(1)).toBe("exited"); + + expect((await call("/clusters/start", { method: "POST" })).body).toEqual({ + succeeded: [0, 1], + failed: [], + }); + expect(await containerState(0)).toBe("running"); + expect(await containerState(1)).toBe("running"); + }); + + it("removes a running cluster", async () => { + const { status } = await call("/clusters/0", { method: "DELETE" }); + + expect(status).toBe(200); + expect(await containerState(0)).toBeUndefined(); + expect((await call("/clusters")).body).toEqual([{ id: 1, shardIds: [1], status: "RUNNING" }]); + }); + + it("removes the bot and its containers", async () => { + const { status } = await call("/bot", { method: "DELETE" }); + + expect(status).toBe(200); + expect(await containerState(0)).toBeUndefined(); + expect(await containerState(1)).toBeUndefined(); + }); +}); + +describe("observed cluster status", () => { + beforeEach(async () => { + await applyLayout([{ shardIds: [0] }]); + }); + + it("reports a container stopped outside HallMaster as an error", async () => { + await stopContainerOutsideHallMaster(0); + + expect((await call("/clusters/0")).body).toMatchObject({ status: "ERROR" }); + }); + + it("reports a removed container as an error", async () => { + await removeContainerOutsideHallMaster(0); + + expect((await call("/clusters/0")).body).toMatchObject({ status: "ERROR" }); + }); +}); + +describe("cluster monitoring", () => { + beforeEach(async () => { + await applyLayout([{ shardIds: [0] }]); + }); + + it("returns the stats of a running cluster", async () => { + const { status, body } = await call("/clusters/0/stats"); + + expect(status).toBe(200); + expect(body).toMatchObject({ + cpuPercentage: expect.any(Number), + memory: { usage: expect.any(Number), percentage: expect.any(Number) }, + }); + }); + + it("refuses the stats of a stopped cluster", async () => { + await call("/clusters/0/stop", { method: "POST" }); + + const { status, body } = await call("/clusters/0/stats"); + + expect(status).toBe(400); + expect(body).toEqual({ message: "Cluster 0 is not running" }); + }); + + it("returns the logs of a cluster", async () => { + const { status, body } = await call("/clusters/0/logs"); + + expect(status).toBe(200); + expect(body).toEqual(expect.any(Array)); + }); +}); + +describe("cluster streams", () => { + beforeEach(async () => { + await applyLayout([{ shardIds: [0] }]); + }); + + it("streams the clusters", async () => { + const stream = await openEvents("/clusters/sse?interval=1", token); + + expect(stream.contentType).toContain("text/event-stream"); + expect(await stream.read(1)).toEqual([[{ id: 0, shardIds: [0], status: "RUNNING" }]]); + }); + + it("streams the stats of every running cluster", async () => { + const [stats] = await (await openEvents("/clusters/stats/sse?interval=1", token)).read(1); + + expect(stats).toMatchObject({ 0: { cpuPercentage: expect.any(Number) } }); + }); + + it("streams the stats of a cluster", async () => { + const events = await (await openEvents("/clusters/0/stats/sse", token)).read(2); + + expect(events).toHaveLength(2); + expect(events[0]).toMatchObject({ memory: { usage: expect.any(Number) } }); + }); + + it("streams the new log lines of a cluster", async () => { + const stream = await openEvents("/clusters/0/logs/sse", token); + await call("/clusters/0/restart", { method: "POST" }); + + const [log] = await stream.read(1); + + expect(log).toMatchObject({ content: expect.any(String), stream: expect.any(String) }); + }); + + it("refuses to stream an unknown cluster", async () => { + const response = await request("/clusters/42/stats/sse", { token }); + + expect(response.status).toBe(404); + }); +}); diff --git a/packages/backend/tests/integration/global-setup.ts b/packages/backend/tests/integration/global-setup.ts new file mode 100644 index 0000000..c7edb31 --- /dev/null +++ b/packages/backend/tests/integration/global-setup.ts @@ -0,0 +1,26 @@ +import { execFileSync } from "node:child_process"; + +import { PostgreSqlContainer } from "@testcontainers/postgresql"; +import type { TestProject } from "vitest/node"; + +declare module "vitest" { + export interface ProvidedContext { + databaseUrl: string; + } +} + +export default async function setup(project: TestProject) { + const database = await new PostgreSqlContainer("postgres:17-alpine").start(); + const databaseUrl = database.getConnectionUri(); + + execFileSync("pnpm", ["exec", "prisma", "migrate", "deploy"], { + env: { ...process.env, DATABASE_URL: databaseUrl }, + stdio: "ignore", + }); + + project.provide("databaseUrl", databaseUrl); + + return async () => { + await database.stop(); + }; +} diff --git a/packages/backend/tests/integration/helpers.ts b/packages/backend/tests/integration/helpers.ts new file mode 100644 index 0000000..2e357e0 --- /dev/null +++ b/packages/backend/tests/integration/helpers.ts @@ -0,0 +1,114 @@ +import { DockerContainersAPI, DockerSocket } from "@hallmaster/docker.js"; + +import prisma from "#lib/database"; + +import app from "../../src/app"; + +export const BOT_ID = "424242424242424242"; + +const socket = new DockerSocket(); +await socket.init(); +const containers = new DockerContainersAPI(socket); + +async function findContainer(clusterId: number) { + const name = `${BOT_ID}-${clusterId}`; + const matches = await containers.list({ all: true, filters: { name: [name] } }); + + return matches.find(({ Names }) => Names.includes(`/${name}`)); +} + +export async function containerState(clusterId: number) { + return (await findContainer(clusterId))?.State; +} + +export async function stopContainerOutsideHallMaster(clusterId: number) { + const container = await findContainer(clusterId); + if (container !== undefined) { + await containers.stop(container.Id); + } +} + +export async function removeContainerOutsideHallMaster(clusterId: number) { + const container = await findContainer(clusterId); + if (container !== undefined) { + await containers.stop(container.Id); + await containers.remove(container.Id); + } +} + +export async function resetState() { + await prisma.$executeRawUnsafe('TRUNCATE "User", "bot" CASCADE'); + + const leftovers = await containers.list({ all: true, filters: { name: [`${BOT_ID}-`] } }); + for (const container of leftovers) { + await containers.stop(container.Id); + await containers.remove(container.Id); + } +} + +export async function createBot() { + await prisma.bot.create({ data: { id: BOT_ID, token: "integration.token", totalShards: 0 } }); +} + +export function request( + path: string, + init: { method?: string; token?: string; body?: unknown } = {}, +) { + const headers = new Headers({ "Content-Type": "application/json" }); + if (init.token !== undefined) { + headers.set("Authorization", `Bearer ${init.token}`); + } + + return app.request(`/api${path}`, { + method: init.method ?? "GET", + headers, + body: init.body === undefined ? undefined : JSON.stringify(init.body), + }); +} + +export async function register() { + const response = await request("/auth/register", { + method: "POST", + body: { username: "admin", password: "password123" }, + }); + const { token } = (await response.json()) as { token: string }; + + return token; +} + +export async function openEvents(path: string, token: string) { + const response = await request(path, { token }); + if (response.body === null) { + throw new Error(`No body for ${path}`); + } + + const reader = response.body.pipeThrough(new TextDecoderStream()).getReader(); + let buffer = ""; + + async function read(count: number) { + const events: unknown[] = []; + + while (events.length < count) { + const { value, done } = await reader.read(); + if (done) { + break; + } + + buffer += value; + const blocks = buffer.split("\n\n"); + buffer = blocks.pop() ?? ""; + for (const block of blocks) { + const data = block.split("\n").find((line) => line.startsWith("data: ")); + if (data !== undefined) { + events.push(JSON.parse(data.slice("data: ".length))); + } + } + } + + await reader.cancel(); + + return events; + } + + return { status: response.status, contentType: response.headers.get("Content-Type"), read }; +} diff --git a/packages/backend/tests/integration/setup.ts b/packages/backend/tests/integration/setup.ts new file mode 100644 index 0000000..8b75fb5 --- /dev/null +++ b/packages/backend/tests/integration/setup.ts @@ -0,0 +1,4 @@ +import { inject } from "vitest"; + +process.env.DATABASE_URL = inject("databaseUrl"); +process.env.SECRET = "integration-secret"; diff --git a/packages/backend/tests/unit/bot.service.test.ts b/packages/backend/tests/unit/bot.service.test.ts new file mode 100644 index 0000000..342ec2c --- /dev/null +++ b/packages/backend/tests/unit/bot.service.test.ts @@ -0,0 +1,133 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import BotRepository from "#repositories/bot.repository"; +import ContainerImageRepository from "#repositories/container-image.repository"; +import BotService from "#services/bot.service"; +import DiscordService from "#services/discord.service"; +import DockerService from "#services/docker.service"; + +vi.mock("#repositories/bot.repository", () => ({ + default: { + findFirstToken: vi.fn(), + }, +})); +vi.mock("#repositories/cluster.repository", () => ({ default: {} })); + +vi.mock("#repositories/container-image.repository", () => ({ + default: { + create: vi.fn(), + findFirst: vi.fn(), + update: vi.fn(), + }, +})); + +vi.mock("#services/discord.service", () => ({ + default: { + getGatewayBot: vi.fn(), + }, +})); + +vi.mock("#services/docker.service", () => ({ + default: { + ensureImage: vi.fn(), + }, +})); + +beforeEach(() => { + vi.resetAllMocks(); + vi.mocked(ContainerImageRepository.create).mockImplementation((data) => Promise.resolve(data)); + vi.mocked(ContainerImageRepository.update).mockImplementation((data) => Promise.resolve(data)); +}); + +describe("container image registration", () => { + it.each([ + ["alpine", "docker.io", "library/alpine", "latest"], + ["hallmaster-bot:dev", "docker.io", "library/hallmaster-bot", "dev"], + ["user/app:1.0", "docker.io", "user/app", "1.0"], + ["ghcr.io/org/app:2", "ghcr.io", "org/app", "2"], + ["localhost:5000/app", "localhost:5000", "app", "latest"], + ["localhost/app:edge", "localhost", "app", "edge"], + ])("normalizes %s", async (url, serverName, image, tag) => { + const registered = await BotService.createContainerImage({ url }); + + expect(registered.url).toBe(`${serverName}/${image}:${tag}`); + expect(DockerService.ensureImage).toHaveBeenCalledWith( + expect.objectContaining({ serverName, image, tag }), + ); + }); +}); + +describe("container image update", () => { + beforeEach(() => { + vi.mocked(ContainerImageRepository.findFirst).mockResolvedValue({ + serverName: "registry.example.com", + image: "bot", + tag: "1.0", + username: "deployer", + password: "secret", + }); + }); + + it("keeps the password on the same registry and user", async () => { + await BotService.updateContainerImage({ + url: "registry.example.com/bot:2.0", + username: "deployer", + }); + + expect(DockerService.ensureImage).toHaveBeenCalledWith( + expect.objectContaining({ tag: "2.0", username: "deployer", password: "secret" }), + ); + expect(ContainerImageRepository.update).toHaveBeenCalledWith( + expect.objectContaining({ username: "deployer", password: "secret" }), + ); + }); + + it("uses the new password when one is provided", async () => { + await BotService.updateContainerImage({ + url: "registry.example.com/bot:2.0", + username: "deployer", + password: "rotated", + }); + + expect(ContainerImageRepository.update).toHaveBeenCalledWith( + expect.objectContaining({ password: "rotated" }), + ); + }); + + it.each([ + ["another user", { url: "registry.example.com/bot:2.0", username: "someone" }, "someone"], + ["another registry", { url: "ghcr.io/org/bot:2.0", username: "deployer" }, "deployer"], + ["no user", { url: "registry.example.com/bot:2.0" }, null], + ])("drops the password for %s", async (_case, image, username) => { + await BotService.updateContainerImage(image); + + expect(ContainerImageRepository.update).toHaveBeenCalledWith( + expect.objectContaining({ username, password: null }), + ); + }); + + it("rejects the update when no image is registered", async () => { + vi.mocked(ContainerImageRepository.findFirst).mockResolvedValue(null); + + await expect(BotService.updateContainerImage({ url: "alpine" })).rejects.toMatchObject({ + status: 404, + }); + expect(DockerService.ensureImage).not.toHaveBeenCalled(); + }); +}); + +describe("recommended shards", () => { + it("returns the number of shards recommended by Discord", async () => { + vi.mocked(BotRepository.findFirstToken).mockResolvedValue({ token: "token" }); + vi.mocked(DiscordService.getGatewayBot).mockResolvedValue({ shards: 4 }); + + expect(await BotService.recommendedShards()).toEqual({ shards: 4 }); + expect(DiscordService.getGatewayBot).toHaveBeenCalledWith("token"); + }); + + it("rejects the request when no bot is registered", async () => { + vi.mocked(BotRepository.findFirstToken).mockResolvedValue(null); + + await expect(BotService.recommendedShards()).rejects.toMatchObject({ status: 404 }); + }); +}); diff --git a/packages/backend/tests/unit/cluster.service.test.ts b/packages/backend/tests/unit/cluster.service.test.ts new file mode 100644 index 0000000..7135e18 --- /dev/null +++ b/packages/backend/tests/unit/cluster.service.test.ts @@ -0,0 +1,250 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import BotRepository from "#repositories/bot.repository"; +import ClusterRepository from "#repositories/cluster.repository"; +import ContainerImageRepository from "#repositories/container-image.repository"; +import ClusterService from "#services/cluster.service"; +import DockerService from "#services/docker.service"; + +vi.mock("#repositories/bot.repository", () => ({ + default: { + findFirstIdAndToken: vi.fn(), + updateTotalShards: vi.fn(), + }, +})); + +vi.mock("#repositories/cluster.repository", () => ({ + default: { + create: vi.fn(), + deleteManyById: vi.fn(), + findFirstContainerIdById: vi.fn(), + findMany: vi.fn(), + findManyId: vi.fn(), + findManyIdAndContainerId: vi.fn(), + findManyWithContainerId: vi.fn(), + updateDesiredStatusById: vi.fn(), + updateManyDesiredStatusById: vi.fn(), + }, +})); + +vi.mock("#repositories/container-image.repository", () => ({ + default: { + findFirst: vi.fn(), + }, +})); + +vi.mock("#services/docker.service", () => ({ + default: { + containerLogs: vi.fn(), + containerStates: vi.fn(), + create: vi.fn(), + ensureImage: vi.fn(), + removeContainer: vi.fn(), + startContainer: vi.fn(), + stopContainer: vi.fn(), + }, +})); + +type ObservedCluster = { + id: number; + desiredStatus: "RUNNING" | "STOPPED"; + containerState?: string; +}; + +function givenClusters(clusters: ObservedCluster[]) { + vi.mocked(ClusterRepository.findManyWithContainerId).mockResolvedValue( + clusters.map(({ id, desiredStatus }) => ({ + id, + shardIds: [id], + desiredStatus, + containerId: `container-${id}`, + })), + ); + vi.mocked(DockerService.containerStates).mockResolvedValue( + new Map( + clusters.flatMap(({ id, containerState }) => + containerState === undefined ? [] : [[`container-${id}`, containerState] as const], + ), + ), + ); + vi.mocked(ClusterRepository.findFirstContainerIdById).mockImplementation((id) => + Promise.resolve( + clusters.some((cluster) => cluster.id === id) ? { containerId: `container-${id}` } : null, + ), + ); +} + +beforeEach(() => { + vi.resetAllMocks(); +}); + +describe("cluster status", () => { + it.each([ + ["RUNNING", "running", "RUNNING"], + ["STOPPED", "running", "RUNNING"], + ["RUNNING", "restarting", "STARTING"], + ["RUNNING", "exited", "ERROR"], + ["STOPPED", "exited", "STOPPED"], + ["STOPPED", "created", "STOPPED"], + ["RUNNING", undefined, "ERROR"], + ["STOPPED", undefined, "ERROR"], + ] as const)( + "reports a cluster desired %s with a %s container as %s", + async (desiredStatus, containerState, expected) => { + givenClusters([{ id: 0, desiredStatus, containerState }]); + + const [cluster] = await ClusterService.getAll(); + + expect(cluster.status).toBe(expected); + }, + ); + + it("reports STARTING while a start is in progress", async () => { + givenClusters([{ id: 0, desiredStatus: "STOPPED", containerState: "exited" }]); + let finishStart = () => {}; + vi.mocked(DockerService.startContainer).mockReturnValue( + new Promise((resolve) => { + finishStart = () => resolve(undefined); + }), + ); + + const start = ClusterService.start(0); + await vi.waitFor(() => expect(DockerService.startContainer).toHaveBeenCalled()); + + expect((await ClusterService.get(0)).status).toBe("STARTING"); + + givenClusters([{ id: 0, desiredStatus: "RUNNING", containerState: "running" }]); + finishStart(); + + expect((await start).status).toBe("RUNNING"); + expect(ClusterRepository.updateDesiredStatusById).toHaveBeenCalledWith("RUNNING", 0); + }); + + it("rejects stats of a cluster that is not running", async () => { + givenClusters([{ id: 0, desiredStatus: "RUNNING", containerState: "exited" }]); + + await expect(ClusterService.stats(0)).rejects.toMatchObject({ status: 400 }); + }); + + it("rejects an unknown cluster", async () => { + givenClusters([]); + + await expect(ClusterService.get(42)).rejects.toMatchObject({ status: 404 }); + }); +}); + +describe("cluster actions on every cluster", () => { + it("reports which clusters succeeded and which failed", async () => { + givenClusters([ + { id: 0, desiredStatus: "RUNNING", containerState: "running" }, + { id: 1, desiredStatus: "RUNNING", containerState: "running" }, + ]); + vi.mocked(ClusterRepository.findManyId).mockResolvedValue([{ id: 0 }, { id: 1 }]); + vi.mocked(DockerService.startContainer).mockImplementation((containerId) => + containerId === "container-1" + ? Promise.reject(new Error("No such container")) + : Promise.resolve(), + ); + + const result = await ClusterService.runActionOnAll("start"); + + expect(result).toEqual({ + succeeded: [0], + failed: [{ id: 1, reason: "No such container" }], + }); + }); +}); + +describe("cluster logs", () => { + it("sends time bounds to docker in seconds", async () => { + givenClusters([{ id: 0, desiredStatus: "RUNNING", containerState: "running" }]); + + await ClusterService.logs(0, { + since: new Date("2026-01-01T00:00:00.400Z"), + until: new Date("2026-01-01T00:01:00.400Z"), + tail: "all", + }); + + expect(DockerService.containerLogs).toHaveBeenCalledWith( + "container-0", + expect.objectContaining({ since: 1767225600, until: 1767225661 }), + ); + }); +}); + +describe("cluster layout update", () => { + beforeEach(() => { + vi.mocked(BotRepository.findFirstIdAndToken).mockResolvedValue({ id: "bot", token: "token" }); + vi.mocked(BotRepository.updateTotalShards).mockImplementation(({ totalShards }) => + Promise.resolve({ id: "bot", totalShards }), + ); + vi.mocked(ContainerImageRepository.findFirst).mockResolvedValue({ + serverName: "docker.io", + image: "library/alpine", + tag: "latest", + username: null, + password: null, + }); + vi.mocked(DockerService.create).mockImplementation((_body, name) => + Promise.resolve({ Id: `container-${name}`, Warnings: [] }), + ); + vi.mocked(ClusterRepository.findMany).mockResolvedValue([ + { id: 0, shardIds: [0], desiredStatus: "STOPPED" }, + { id: 1, shardIds: [1], desiredStatus: "RUNNING" }, + ]); + vi.mocked(ClusterRepository.findManyIdAndContainerId).mockResolvedValue([ + { id: 0, containerId: "old-0" }, + { id: 1, containerId: "old-1" }, + ]); + givenClusters([]); + }); + + it.each([ + ["an empty cluster", [{ shardIds: [] }]], + [ + "a duplicated cluster", + [ + { id: 0, shardIds: [0] }, + { id: 0, shardIds: [1] }, + ], + ], + ["an unknown cluster", [{ id: 7, shardIds: [0] }]], + ["non-contiguous shards", [{ shardIds: [0] }, { shardIds: [2] }]], + ])("rejects %s", async (_case, layout) => { + await expect(ClusterService.updateAll(layout)).rejects.toMatchObject({ status: 400 }); + expect(DockerService.stopContainer).not.toHaveBeenCalled(); + }); + + it("keeps stopped clusters stopped and starts the others", async () => { + await ClusterService.updateAll([{ id: 0, shardIds: [0] }, { shardIds: [1, 2] }]); + + expect(ClusterRepository.create).toHaveBeenCalledWith( + expect.objectContaining({ id: 0, desiredStatus: "STOPPED", shardIds: [0] }), + ); + expect(ClusterRepository.create).toHaveBeenCalledWith( + expect.objectContaining({ id: 1, desiredStatus: "RUNNING", shardIds: [1, 2] }), + ); + expect(DockerService.startContainer).toHaveBeenCalledTimes(1); + expect(DockerService.startContainer).toHaveBeenCalledWith("container-bot-1"); + }); + + it("stores the total number of shards", async () => { + await ClusterService.updateAll([{ shardIds: [0, 1] }, { shardIds: [2] }]); + + expect(BotRepository.updateTotalShards).toHaveBeenCalledWith({ totalShards: 3 }); + expect(DockerService.create).toHaveBeenCalledWith( + expect.objectContaining({ Env: expect.arrayContaining(["TOTAL_SHARDS=3"]) }), + "bot-0", + ); + }); + + it("leaves the current clusters untouched when the image is unavailable", async () => { + vi.mocked(DockerService.ensureImage).mockRejectedValue(new Error("pull access denied")); + + await expect(ClusterService.updateAll([{ shardIds: [0] }])).rejects.toThrow( + "pull access denied", + ); + expect(DockerService.stopContainer).not.toHaveBeenCalled(); + expect(DockerService.removeContainer).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/backend/tests/unit/discord.service.test.ts b/packages/backend/tests/unit/discord.service.test.ts new file mode 100644 index 0000000..4285e3e --- /dev/null +++ b/packages/backend/tests/unit/discord.service.test.ts @@ -0,0 +1,103 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import DiscordService from "#services/discord.service"; + +const fetchMock = vi.fn(); + +function respond(status: number, body: unknown = {}) { + fetchMock.mockResolvedValue(new Response(JSON.stringify(body), { status })); +} + +beforeEach(() => { + vi.stubGlobal("fetch", fetchMock); +}); + +afterEach(() => { + fetchMock.mockReset(); + vi.unstubAllGlobals(); +}); + +describe("gateway bot", () => { + it("returns the recommended number of shards", async () => { + respond(200, { url: "wss://gateway.discord.gg", shards: 3 }); + + expect(await DiscordService.getGatewayBot("token")).toEqual({ shards: 3 }); + expect(fetchMock).toHaveBeenCalledWith( + "https://discord.com/api/v10/gateway/bot", + expect.objectContaining({ headers: { Authorization: "Bot token" } }), + ); + }); + + it("reports an invalid token", async () => { + respond(401); + + await expect(DiscordService.getGatewayBot("token")).rejects.toMatchObject({ + status: 424, + message: "Invalid Discord bot token", + }); + }); + + it("reports an unavailable Discord API", async () => { + respond(503); + + await expect(DiscordService.getGatewayBot("token")).rejects.toMatchObject({ status: 424 }); + }); + + it("reports an unreachable Discord API", async () => { + fetchMock.mockRejectedValue(new TypeError("fetch failed")); + + await expect(DiscordService.getGatewayBot("token")).rejects.toMatchObject({ + status: 424, + message: "Discord API is unreachable or timed out", + }); + }); + + it("reports an unexpected response body", async () => { + respond(200, { shards: "many" }); + + await expect(DiscordService.getGatewayBot("token")).rejects.toMatchObject({ + status: 424, + message: "Discord API returned an unexpected response body", + }); + }); +}); + +describe("bot profile", () => { + it("builds the profile with cdn urls", async () => { + respond(200, { + id: "42", + username: "hallmaster", + global_name: "HallMaster", + discriminator: "0", + avatar: "a_animated", + banner: "static", + accent_color: 16711680, + }); + + expect(await DiscordService.getBotProfile("token")).toEqual({ + name: "hallmaster", + displayName: "HallMaster", + discriminator: "0", + avatarUrl: "https://cdn.discordapp.com/avatars/42/a_animated.gif", + bannerUrl: "https://cdn.discordapp.com/banners/42/static.png", + accentColor: 16711680, + }); + }); + + it("accepts a profile without avatar, banner or accent color", async () => { + respond(200, { + id: "42", + username: "hallmaster", + global_name: null, + discriminator: "0", + avatar: null, + }); + + expect(await DiscordService.getBotProfile("token")).toMatchObject({ + displayName: null, + avatarUrl: null, + bannerUrl: null, + accentColor: null, + }); + }); +}); diff --git a/packages/backend/tests/unit/docker.service.test.ts b/packages/backend/tests/unit/docker.service.test.ts new file mode 100644 index 0000000..907e9dc --- /dev/null +++ b/packages/backend/tests/unit/docker.service.test.ts @@ -0,0 +1,171 @@ +import { Readable } from "node:stream"; + +import { DockerAPIHttpError } from "@hallmaster/docker.js"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import DockerService from "#services/docker.service"; + +const { containers, images } = vi.hoisted(() => ({ + containers: { + list: vi.fn(), + remove: vi.fn(), + stats: vi.fn(), + stop: vi.fn(), + }, + images: { + create: vi.fn(), + list: vi.fn(), + }, +})); + +vi.mock("@hallmaster/docker.js", () => ({ + DockerAPIHttpError: class extends Error { + constructor( + public readonly status: number, + public readonly reason?: string, + ) { + super(reason); + } + }, + DockerSocket: class { + async init() {} + }, + DockerContainersAPI: class { + constructor() { + return containers; + } + }, + DockerImagesAPI: class { + constructor() { + return images; + } + }, +})); + +function statsSample(overrides: { precpuSystem?: number } = {}) { + return { + cpu_stats: { + cpu_usage: { total_usage: 400 }, + system_cpu_usage: 2000, + online_cpus: 2, + }, + precpu_stats: { + cpu_usage: { total_usage: 200 }, + system_cpu_usage: overrides.precpuSystem ?? 1000, + online_cpus: 2, + }, + memory_stats: { usage: 1000, limit: 1600, stats: { inactive_file: 200 } }, + networks: { eth0: { rx_bytes: 10, tx_bytes: 20 } }, + }; +} + +beforeEach(() => { + vi.resetAllMocks(); +}); + +describe("container stats", () => { + it("computes cpu, memory and network usage", async () => { + containers.stats.mockResolvedValue(statsSample()); + + expect(await DockerService.containerStats("container")).toEqual({ + cpuPercentage: 40, + memory: { usage: 800, percentage: 50 }, + network: [{ interface: "eth0", transmitted: 20, received: 10 }], + }); + }); + + it("reports no cpu usage without a previous sample", async () => { + containers.stats.mockResolvedValue(statsSample({ precpuSystem: 0 })); + + expect((await DockerService.containerStats("container")).cpuPercentage).toBe(0); + }); + + it("accepts the empty stats of a stopped container", async () => { + containers.stats.mockResolvedValue({ memory_stats: {}, cpu_stats: {}, precpu_stats: {} }); + + expect(await DockerService.containerStats("container")).toEqual({ + cpuPercentage: 0, + memory: { usage: 0, percentage: 0 }, + network: [], + }); + }); + + it("rejects malformed stats", async () => { + containers.stats.mockResolvedValue({ memory_stats: { usage: "a lot" } }); + + await expect(DockerService.containerStats("container")).rejects.toMatchObject({ + status: 424, + }); + }); + + it("skips the first streamed sample, which has no previous cpu sample", async () => { + containers.stats.mockResolvedValue( + Readable.from([statsSample({ precpuSystem: 0 }), statsSample()]), + ); + + const stats = await (await DockerService.streamContainerStats("container")).toArray(); + + expect(stats).toHaveLength(1); + expect(stats[0]).toMatchObject({ cpuPercentage: 40 }); + }); +}); + +describe("docker engine errors", () => { + it.each([304, 404])("treats a %i on stop as already stopped", async (status) => { + containers.stop.mockRejectedValue(new DockerAPIHttpError(status)); + + await expect(DockerService.stopContainer("container")).resolves.toBeUndefined(); + }); + + it("reports other docker errors as a failed dependency", async () => { + containers.stop.mockRejectedValue(new DockerAPIHttpError(500, "boom")); + + await expect(DockerService.stopContainer("container")).rejects.toMatchObject({ + status: 424, + message: "Docker Engine API returned a 500 boom", + }); + }); + + it("reports unexpected failures as a failed dependency", async () => { + containers.remove.mockRejectedValue(new Error("socket hang up")); + + await expect(DockerService.removeContainer("container")).rejects.toMatchObject({ + status: 424, + }); + }); +}); + +describe("image availability", () => { + const image = { serverName: "docker.io", image: "library/alpine", tag: "3.20" }; + + it("does not pull an image that is already present", async () => { + images.list.mockResolvedValue([{ Id: "sha256:abc" }]); + + await DockerService.ensureImage(image); + + expect(images.list).toHaveBeenCalledWith({ filters: { reference: ["alpine:3.20"] } }); + expect(images.create).not.toHaveBeenCalled(); + }); + + it("pulls a missing image with the registry credentials", async () => { + images.list.mockResolvedValue([]); + images.create.mockResolvedValue(undefined); + + await DockerService.ensureImage({ + serverName: "registry.example.com", + image: "bot", + tag: "1.0", + username: "deployer", + password: "secret", + }); + + expect(images.list).toHaveBeenCalledWith({ + filters: { reference: ["registry.example.com/bot:1.0"] }, + }); + expect(images.create).toHaveBeenCalledWith({ + fromImage: "registry.example.com/bot", + tag: "1.0", + auth: { serveraddress: "registry.example.com", username: "deployer", password: "secret" }, + }); + }); +}); diff --git a/packages/backend/tsconfig.build.json b/packages/backend/tsconfig.build.json deleted file mode 100644 index 64f86c6..0000000 --- a/packages/backend/tsconfig.build.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "extends": "./tsconfig.json", - "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] -} diff --git a/packages/backend/tsconfig.json b/packages/backend/tsconfig.json index dc6ff8d..36402b1 100644 --- a/packages/backend/tsconfig.json +++ b/packages/backend/tsconfig.json @@ -1,38 +1,28 @@ { - "$schema": "https://json.schemastore.org/tsconfig.json", "compilerOptions": { - "strict": true, - "allowUnreachableCode": false, - "noFallthroughCasesInSwitch": true, - "noImplicitOverride": true, - "noImplicitReturns": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - - "module": "NodeNext", - "moduleResolution": "NodeNext", + "allowImportingTsExtensions": true, + "noEmit": true, + "target": "es2023", + "module": "esnext", + "moduleResolution": "bundler", "resolveJsonModule": true, - - "declaration": true, - "declarationMap": true, - "removeComments": true, - "sourceMap": true, - "newLine": "lf", - "outDir": "./dist", - "rootDir": "./", - - "allowSyntheticDefaultImports": true, + "verbatimModuleSyntax": true, + "strict": true, "esModuleInterop": true, + "skipLibCheck": true, "forceConsistentCasingInFileNames": true, - "isolatedModules": true, - - "target": "ES2023", - "lib": ["ES2023"], - "types": ["jest", "mocha"], - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - - "incremental": true, - "skipLibCheck": true + "outDir": "dist", + "rootDir": ".", + "types": ["node"], + "paths": { + "#controllers/*": ["./src/controllers/*"], + "#exceptions/*": ["./src/exceptions/*"], + "#lib/*": ["./src/lib/*"], + "#middlewares/*": ["./src/middlewares/*"], + "#prisma/client": ["./prisma/generated/prisma/client"], + "#repositories/*": ["./src/repositories/*"], + "#schemas/*": ["./src/schemas/*"], + "#services/*": ["./src/services/*"] + } } } diff --git a/packages/backend/tsdown.config.ts b/packages/backend/tsdown.config.ts new file mode 100644 index 0000000..1b1b3eb --- /dev/null +++ b/packages/backend/tsdown.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from "tsdown"; + +export default defineConfig({ + entry: "src/index.ts", + platform: "node", + target: "node24", +}); diff --git a/packages/backend/vitest.config.ts b/packages/backend/vitest.config.ts new file mode 100644 index 0000000..7118c7e --- /dev/null +++ b/packages/backend/vitest.config.ts @@ -0,0 +1,32 @@ +import tsconfigPaths from "vite-tsconfig-paths"; +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + plugins: [tsconfigPaths()], + test: { + coverage: { + include: ["src/**/*.ts"], + }, + projects: [ + { + extends: true, + test: { + name: "unit", + include: ["tests/unit/**/*.test.ts"], + }, + }, + { + extends: true, + test: { + name: "integration", + include: ["tests/integration/**/*.test.ts"], + globalSetup: ["tests/integration/global-setup.ts"], + setupFiles: ["tests/integration/setup.ts"], + fileParallelism: false, + testTimeout: 60_000, + hookTimeout: 180_000, + }, + }, + ], + }, +}); diff --git a/packages/frontend/.oxlintrc.json b/packages/frontend/.oxlintrc.json index dfe0c31..d4bceb0 100644 --- a/packages/frontend/.oxlintrc.json +++ b/packages/frontend/.oxlintrc.json @@ -2,6 +2,7 @@ "$schema": "./node_modules/oxlint/configuration_schema.json", "plugins": ["eslint", "typescript", "unicorn", "oxc", "import", "node", "promise", "vitest"], "options": { - "typeAware": true + "typeAware": true, + "typeCheck": true } } diff --git a/packages/frontend/README.md b/packages/frontend/README.md deleted file mode 100644 index 75842c4..0000000 --- a/packages/frontend/README.md +++ /dev/null @@ -1,38 +0,0 @@ -# sv - -Everything you need to build a Svelte project, powered by [`sv`](https://github.com/sveltejs/cli). - -## Creating a project - -If you're seeing this, you've probably already done this step. Congrats! - -```sh -# create a new project in the current directory -npx sv create - -# create a new project in my-app -npx sv create my-app -``` - -## Developing - -Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server: - -```sh -npm run dev - -# or start the server and open the app in a new browser tab -npm run dev -- --open -``` - -## Building - -To create a production version of your app: - -```sh -npm run build -``` - -You can preview the production build with `npm run preview`. - -> To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment. diff --git a/packages/frontend/src/lib/components/ClusterLogs.svelte b/packages/frontend/src/lib/components/ClusterLogs.svelte index 31d671b..551ad16 100644 --- a/packages/frontend/src/lib/components/ClusterLogs.svelte +++ b/packages/frontend/src/lib/components/ClusterLogs.svelte @@ -1,6 +1,6 @@
diff --git a/packages/frontend/src/routes/(app)/clusters/components/ActionRow.svelte b/packages/frontend/src/routes/(app)/clusters/components/ActionRow.svelte index b17a980..002a3f3 100644 --- a/packages/frontend/src/routes/(app)/clusters/components/ActionRow.svelte +++ b/packages/frontend/src/routes/(app)/clusters/components/ActionRow.svelte @@ -6,12 +6,12 @@ stopClusters, } from "$lib/remotes/clusters.remote"; import toaster from "$lib/utils/toaster"; - import type { GetClusterDto } from "@hallmaster/backend/dto"; + import type { Cluster } from "@hallmaster/backend/schemas"; import { PlayIcon, RotateCcwIcon, SquareIcon, XIcon } from "@lucide/svelte"; import { fade } from "svelte/transition"; interface Props { - group: GetClusterDto["id"][]; + group: Cluster["id"][]; } let { group = $bindable() }: Props = $props(); diff --git a/packages/frontend/src/routes/(app)/clusters/components/CollapsibleContent.svelte b/packages/frontend/src/routes/(app)/clusters/components/CollapsibleContent.svelte index 4a4a7c7..a5d6ebf 100644 --- a/packages/frontend/src/routes/(app)/clusters/components/CollapsibleContent.svelte +++ b/packages/frontend/src/routes/(app)/clusters/components/CollapsibleContent.svelte @@ -1,5 +1,5 @@ -{#snippet component(data?: GetBotDto["discord"])} +{#snippet component(data?: BotDiscordProfile)}
@@ -27,9 +27,9 @@ {/snippet} - {const { discord } = await getBot()} + {const profile = await getBotProfile()} - {@render component(discord)} + {@render component(profile)} {#snippet pending()} {@render component()} diff --git a/packages/frontend/src/routes/(app)/layout/components/Actions.svelte b/packages/frontend/src/routes/(app)/layout/components/Actions.svelte index 53a7311..b1f9737 100644 --- a/packages/frontend/src/routes/(app)/layout/components/Actions.svelte +++ b/packages/frontend/src/routes/(app)/layout/components/Actions.svelte @@ -21,7 +21,7 @@ class="preset-filled-primary-500 btn-sm" disabled={!changed || !!updateBotLayout.pending} onclick={() => { - toaster.promise(updateBotLayout({ layout: layout!.export() }), { + toaster.promise(updateBotLayout(layout!.export()), { loading: { title: "Updating layout.." }, success: { title: "Successfully applied layout" }, error: (error) => ({ diff --git a/packages/frontend/src/routes/(app)/settings/+page.svelte b/packages/frontend/src/routes/(app)/settings/+page.svelte index b717381..5b2d4d3 100644 --- a/packages/frontend/src/routes/(app)/settings/+page.svelte +++ b/packages/frontend/src/routes/(app)/settings/+page.svelte @@ -1,7 +1,7 @@ @@ -36,8 +36,8 @@ icon={ContainerIcon} placeholder="ghcr.io/image:tag" required - {...dockerImage.image.as("text")} - issues={dockerImage.image.issues()} + {...url.as("text")} + issues={url.issues()} />
{/if} diff --git a/packages/prisma-client/.gitignore b/packages/prisma-client/.gitignore deleted file mode 100644 index be6cbc1..0000000 --- a/packages/prisma-client/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/dist -/node_modules -/generated diff --git a/packages/prisma-client/package.json b/packages/prisma-client/package.json deleted file mode 100644 index 7beb092..0000000 --- a/packages/prisma-client/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "@hallmaster/prisma-client", - "version": "0.0.1", - "type": "module", - "main": "./generated/client.js", - "types": "./generated/client.d.ts", - "private": false, - "exports": { - ".": { - "types": "./generated/client.d.ts", - "import": "./generated/client.js" - } - }, - "files": [ - "generated", - "package.json" - ], - "dependencies": { - "@prisma/client-runtime-utils": "^7.4.0" - } -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d654b1..c72284f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,7 +7,7 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: ^12.6.0 + specifier: 12.6.0 version: 12.6.0 packages: @@ -171,10 +171,10 @@ importers: devDependencies: '@changesets/cli': specifier: ^2.29.8 - version: 2.29.8(@types/node@22.19.11) + version: 2.29.8(@types/node@26.6.3) '@commitlint/cli': specifier: ^20.4.2 - version: 20.4.2(@types/node@22.19.11)(typescript@5.9.3) + version: 20.4.2(@types/node@26.6.3)(typescript@7.0.2) '@commitlint/config-conventional': specifier: ^20.4.2 version: 20.4.2 @@ -184,175 +184,82 @@ importers: packages/backend: dependencies: - '@fastify/compress': - specifier: 8.3.1 - version: 8.3.1 '@hallmaster/docker.js': - specifier: 0.0.28 + specifier: ^0.0.28 version: 0.0.28 - '@hallmaster/prisma-client': - specifier: workspace:* - version: link:../prisma-client - '@nestjs/common': - specifier: 11.1.14 - version: 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/config': - specifier: 4.0.3 - version: 4.0.3(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2) - '@nestjs/core': - specifier: 11.1.14 - version: 11.1.14(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/jwt': - specifier: 11.0.2 - version: 11.0.2(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)) - '@nestjs/platform-fastify': - specifier: 11.1.14 - version: 11.1.14(@fastify/static@8.3.0)(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14) - '@nestjs/swagger': - specifier: 11.2.6 - version: 11.2.6(@fastify/static@8.3.0)(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2) + '@hono/node-server': + specifier: ^2.1.1 + version: 2.1.1(hono@4.13.9) + '@hono/standard-validator': + specifier: ^0.4.0 + version: 0.4.0(@standard-schema/spec@1.1.0)(hono@4.13.9) '@prisma/adapter-pg': - specifier: 7.4.1 - version: 7.4.1 + specifier: ^7.10.0 + version: 7.10.0 '@prisma/client': - specifier: 7.4.1 - version: 7.4.1(prisma@7.4.1(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) + specifier: ^7.4.1 + version: 7.4.1(prisma@7.10.0(@types/react@19.2.11)(magicast@0.5.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@7.0.2))(typescript@7.0.2) + '@scalar/hono-api-reference': + specifier: ^0.12.6 + version: 0.12.6(hono@4.13.9) argon2: - specifier: 0.44.0 - version: 0.44.0 - fastify: - specifier: 5.7.4 - version: 5.7.4 - nest-winston: - specifier: 1.10.2 - version: 1.10.2(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(winston@3.19.0) - nestjs-zod: - specifier: 5.1.1 - version: 5.1.1(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.2.6(@fastify/static@8.3.0)(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2))(rxjs@7.8.2)(zod@4.3.6) + specifier: ^0.45.1 + version: 0.45.1 + dotenv: + specifier: ^18.0.4 + version: 18.0.4 + hono: + specifier: ^4.13.9 + version: 4.13.9 + hono-openapi: + specifier: ^1.3.3 + version: 1.3.3(effect@3.20.0)(hono@4.13.9)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5) pg: - specifier: 8.18.0 - version: 8.18.0 + specifier: ^8.23.0 + version: 8.23.0 prisma: - specifier: 7.4.1 - version: 7.4.1(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - reflect-metadata: - specifier: 0.2.2 - version: 0.2.2 - rxjs: - specifier: 7.8.2 - version: 7.8.2 - swagger-themes: - specifier: 1.4.3 - version: 1.4.3 - winston: - specifier: 3.19.0 - version: 3.19.0 + specifier: ^7.10.0 + version: 7.10.0(@types/react@19.2.11)(magicast@0.5.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@7.0.2) zod: - specifier: 4.3.6 - version: 4.3.6 + specifier: ^4.6.5 + version: 4.6.5 devDependencies: - '@eslint/eslintrc': - specifier: 3.3.3 - version: 3.3.3 - '@eslint/js': - specifier: 9.39.3 - version: 9.39.3 - '@jest/globals': - specifier: 30.2.0 - version: 30.2.0 - '@nestjs/cli': - specifier: 11.0.16 - version: 11.0.16(@swc/cli@0.6.0(@swc/core@1.15.11(@swc/helpers@0.5.18))(chokidar@4.0.3))(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11) - '@nestjs/schematics': - specifier: 11.0.9 - version: 11.0.9(chokidar@4.0.3)(typescript@5.9.3) - '@nestjs/testing': - specifier: 11.1.14 - version: 11.1.14(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)(@nestjs/platform-express@11.1.13) - '@swc/cli': - specifier: 0.6.0 - version: 0.6.0(@swc/core@1.15.11(@swc/helpers@0.5.18))(chokidar@4.0.3) - '@swc/core': - specifier: 1.15.11 - version: 1.15.11(@swc/helpers@0.5.18) - '@types/jest': - specifier: 30.0.0 - version: 30.0.0 - '@types/mocha': - specifier: ^10.0.10 - version: 10.0.10 + '@testcontainers/postgresql': + specifier: ^12.2.0 + version: 12.2.0 '@types/node': - specifier: 22.19.11 - version: 22.19.11 + specifier: ^26.1.1 + version: 26.6.3 '@types/pg': - specifier: 8.16.0 - version: 8.16.0 - '@types/supertest': - specifier: 6.0.3 - version: 6.0.3 - dotenv: - specifier: 17.3.1 - version: 17.3.1 - dotenv-cli: - specifier: 10.0.0 - version: 10.0.0 - eslint: - specifier: 9.39.3 - version: 9.39.3(jiti@2.7.0) - eslint-config-prettier: - specifier: 10.1.8 - version: 10.1.8(eslint@9.39.3(jiti@2.7.0)) - eslint-import-resolver-typescript: - specifier: ^4.4.4 - version: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.7.0)) - eslint-plugin-import: - specifier: ^2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.7.0)) - eslint-plugin-jest: - specifier: 29.15.0 - version: 29.15.0(@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.3(jiti@2.7.0))(jest@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)))(typescript@5.9.3) - eslint-plugin-prettier: - specifier: 5.5.5 - version: 5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.3(jiti@2.7.0)))(eslint@9.39.3(jiti@2.7.0))(prettier@3.8.1) - globals: - specifier: 16.5.0 - version: 16.5.0 - jest: - specifier: 29.7.0 - version: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - jest-esm-transformer: - specifier: 1.0.0 - version: 1.0.0 - jest-mock-extended: - specifier: 4.0.0 - version: 4.0.0(@jest/globals@30.2.0)(jest@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)))(typescript@5.9.3) - prettier: - specifier: 3.8.1 - version: 3.8.1 - source-map-support: - specifier: 0.5.21 - version: 0.5.21 - supertest: - specifier: 7.2.2 - version: 7.2.2 - ts-jest: - specifier: 29.4.6 - version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)))(typescript@5.9.3) - ts-loader: - specifier: 9.5.4 - version: 9.5.4(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18))) - ts-node: - specifier: 10.9.2 - version: 10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3) - tsconfig-paths: - specifier: 4.2.0 - version: 4.2.0 + specifier: ^8.23.1 + version: 8.23.1 + '@vitest/coverage-v8': + specifier: ^5.0.3 + version: 5.0.3(vitest@5.0.3) + oxfmt: + specifier: ^0.70.0 + version: 0.70.0(svelte@5.56.4(@typescript-eslint/types@8.56.0)) + oxlint: + specifier: ^1.85.0 + version: 1.85.0(oxlint-tsgolint@7.0.2003) + oxlint-tsgolint: + specifier: ^7.0.2003 + version: 7.0.2003 + tsdown: + specifier: ^0.23.1 + version: 0.23.1(tsx@4.23.15)(typescript@7.0.2) + tsx: + specifier: ^4.23.0 + version: 4.23.15 typescript: - specifier: 5.9.3 - version: 5.9.3 - typescript-eslint: - specifier: 8.56.0 - version: 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) + specifier: ^7.0.2 + version: 7.0.2 + vite-tsconfig-paths: + specifier: ^6.1.1 + version: 6.1.1(typescript@7.0.2)(vite@7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) + vitest: + specifier: ^5.0.3 + version: 5.0.3(@types/node@26.6.3)(@vitest/coverage-v8@5.0.3)(vite@7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) packages/frontend: devDependencies: @@ -370,16 +277,16 @@ importers: version: 4.15.2(svelte@5.56.4(@typescript-eslint/types@8.56.0)) '@sveltejs/adapter-node': specifier: ^5.5.4 - version: 5.5.4(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0))) + version: 5.5.4(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0))) '@sveltejs/kit': specifier: ^2.69.2 - version: 2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + version: 2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) '@sveltejs/vite-plugin-svelte': specifier: ^6.2.4 - version: 6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + version: 6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) '@tailwindcss/vite': specifier: ^4.3.1 - version: 4.3.1(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + version: 4.3.1(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) '@types/d3-shape': specifier: ^3.1.8 version: 3.1.8 @@ -400,7 +307,7 @@ importers: version: 16.5.0 layerchart: specifier: 2.0.0-next.65 - version: 2.0.0-next.65(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(zod@4.3.6) + version: 2.0.0-next.65(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(zod@4.3.6) oxfmt: specifier: ^0.57.0 version: 0.57.0(svelte@5.56.4(@typescript-eslint/types@8.56.0)) @@ -427,224 +334,45 @@ importers: version: 0.49.2(patch_hash=2c0d482dc06ad381cab34a6d5581eefb4327fc24a8dd80dad7562bd8922f879c)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(svelte@5.56.4(@typescript-eslint/types@8.56.0)) vite: specifier: ^7.3.5 - version: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0) - - packages/prisma-client: - dependencies: - '@prisma/client-runtime-utils': - specifier: ^7.4.0 - version: 7.4.1 + version: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) packages: - '@angular-devkit/core@19.2.17': - resolution: {integrity: sha512-Ah008x2RJkd0F+NLKqIpA34/vUGwjlprRCkvddjDopAWRzYn6xCkz1Tqwuhn0nR1Dy47wTLKYD999TYl5ONOAQ==} - engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - peerDependencies: - chokidar: ^4.0.0 - peerDependenciesMeta: - chokidar: - optional: true - - '@angular-devkit/core@19.2.19': - resolution: {integrity: sha512-JbLL+4IMLMBgjLZlnPG4lYDfz4zGrJ/s6Aoon321NJKuw1Kb1k5KpFu9dUY0BqLIe8xPQ2UJBpI+xXdK5MXMHQ==} - engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - peerDependencies: - chokidar: ^4.0.0 - peerDependenciesMeta: - chokidar: - optional: true - - '@angular-devkit/schematics-cli@19.2.19': - resolution: {integrity: sha512-7q9UY6HK6sccL9F3cqGRUwKhM7b/XfD2YcVaZ2WD7VMaRlRm85v6mRjSrfKIAwxcQU0UK27kMc79NIIqaHjzxA==} - engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - hasBin: true - - '@angular-devkit/schematics@19.2.17': - resolution: {integrity: sha512-ADfbaBsrG8mBF6Mfs+crKA/2ykB8AJI50Cv9tKmZfwcUcyAdmTr+vVvhsBCfvUAEokigSsgqgpYxfkJVxhJYeg==} - engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - - '@angular-devkit/schematics@19.2.19': - resolution: {integrity: sha512-J4Jarr0SohdrHcb40gTL4wGPCQ952IMWF1G/MSAQfBAPvA9ZKApYhpxcY7PmehVePve+ujpus1dGsJ7dPxz8Kg==} - engines: {node: ^18.19.1 || ^20.11.1 || >=22.0.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'} - '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.29.0': - resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} - engines: {node: '>=6.9.0'} - - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} - engines: {node: '>=6.9.0'} - - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-compilation-targets@7.28.6': - resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-imports@7.28.6': - resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} - engines: {node: '>=6.9.0'} - - '@babel/helper-module-transforms@7.28.6': - resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - - '@babel/helper-plugin-utils@7.28.6': - resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} '@babel/helper-validator-identifier@7.28.5': resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.27.1': - resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} - engines: {node: '>=6.9.0'} - - '@babel/helpers@7.28.6': - resolution: {integrity: sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/parser@7.29.0': - resolution: {integrity: sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==} + '@babel/parser@7.29.9': + resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-async-generators@7.8.4': - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-bigint@7.8.3': - resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-properties@7.12.13': - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-class-static-block@7.14.5': - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-attributes@7.28.6': - resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-import-meta@7.10.4': - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-json-strings@7.8.3': - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-jsx@7.28.6': - resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4': - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-numeric-separator@7.10.4': - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-object-rest-spread@7.8.3': - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3': - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-optional-chaining@7.8.3': - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-private-property-in-object@7.14.5': - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-top-level-await@7.14.5': - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - - '@babel/plugin-syntax-typescript@7.28.6': - resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} - engines: {node: '>=6.9.0'} - 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/runtime@7.28.6': resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==} engines: {node: '>=6.9.0'} - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.29.0': - resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} - engines: {node: '>=6.9.0'} - - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@balena/dockerignore@1.0.2': + resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} - '@borewit/text-codec@0.2.1': - resolution: {integrity: sha512-k7vvKPbf7J2fZ5klGRD9AeKfUvojuZIQ3BT5u7Jfv+puwXkUBUT5PVyMDfJZpy30CBDXGMgw7fguK/lpOMBvgw==} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} '@changesets/apply-release-plan@7.0.14': resolution: {integrity: sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==} @@ -701,26 +429,6 @@ packages: '@changesets/write@0.4.0': resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} - '@chevrotain/cst-dts-gen@10.5.0': - resolution: {integrity: sha512-lhmC/FyqQ2o7pGK4Om+hzuDrm9rhFYIJ/AXoQBeongmn870Xeb0L6oGEiuR8nohFNL5sMaQEJWCxr1oIVIVXrw==} - - '@chevrotain/gast@10.5.0': - resolution: {integrity: sha512-pXdMJ9XeDAbgOWKuD1Fldz4ieCs6+nLNmyVhe2gZVqoO7v8HXuHYs5OV2EzUtbuai37TlOAQHrTDvxMnvMJz3A==} - - '@chevrotain/types@10.5.0': - resolution: {integrity: sha512-f1MAia0x/pAVPWH/T73BJVyO2XU5tI4/iE7cnxb7tqdNTNhQI3Uq3XkqcoteTmD4t1aM0LbHCJOhgIDn07kl2A==} - - '@chevrotain/utils@10.5.0': - resolution: {integrity: sha512-hBzuU5+JjB2cqNZyszkDHZgOSrUUT8V3dhgRl8Q9Gp6dAj/H5+KILGjbhDpc3Iy9qmqlm/akuOI2ut9VUtzJxQ==} - - '@colors/colors@1.5.0': - resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} - engines: {node: '>=0.1.90'} - - '@colors/colors@1.6.0': - resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} - engines: {node: '>=0.1.90'} - '@commitlint/cli@20.4.2': resolution: {integrity: sha512-YjYSX2yj/WsVoxh9mNiymfFS2ADbg2EK4+1WAsMuckwKMCqJ5PDG0CJU/8GvmHWcv4VRB2V02KqSiecRksWqZQ==} engines: {node: '>=v18'} @@ -790,41 +498,25 @@ packages: resolution: {integrity: sha512-aO5l99BQJ0X34ft8b0h7QFkQlqxC6e7ZPVmBKz13xM9O8obDaM1Cld4sQlJDXXU/VFuUzQ30mVtHjVz74TuStw==} engines: {node: '>=v18'} - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - - '@dabh/diagnostics@2.0.8': - resolution: {integrity: sha512-R4MSXTVnuMzGD7bzHdW2ZhhdPC/igELENcq5IjEverBvq5hn1SXCWcsi6eSsdWP0/Ur+SItRRjAktmdoX/8R/Q==} - '@dagrejs/dagre@2.0.4': resolution: {integrity: sha512-J6vCWTNpicHF4zFlZG1cS5DkGzMr9941gddYkakjrg3ZNev4bbqEgLHFTWiFrcJm7UCRu7olO3K6IRDd9gSGhA==} '@dagrejs/graphlib@3.0.4': resolution: {integrity: sha512-HxZ7fCvAwTLCWCO0WjDkzAFQze8LdC6iOpKbetDKHIuDfIgMlIzYzqZ4nxwLlclQX+3ZVeZ1K2OuaOE2WWcyOg==} - '@electric-sql/pglite-socket@0.0.20': - resolution: {integrity: sha512-J5nLGsicnD9wJHnno9r+DGxfcZWh+YJMCe0q/aCgtG6XOm9Z7fKeite8IZSNXgZeGltSigM9U/vAWZQWdgcSFg==} + '@electric-sql/pglite-socket@0.1.3': + resolution: {integrity: sha512-LAciWM0M1dCL8hlsxu2venbVZcdxema0BtDfpWYVqr+Y468UADw0pFWidhKw1M8sfJ8rdLT71tjMmnirf/IZRQ==} hasBin: true peerDependencies: - '@electric-sql/pglite': 0.3.15 + '@electric-sql/pglite': 0.4.3 - '@electric-sql/pglite-tools@0.2.20': - resolution: {integrity: sha512-BK50ZnYa3IG7ztXhtgYf0Q7zijV32Iw1cYS8C+ThdQlwx12V5VZ9KRJ42y82Hyb4PkTxZQklVQA9JHyUlex33A==} + '@electric-sql/pglite-tools@0.3.3': + resolution: {integrity: sha512-AlzLJTRJ8+UFgK8CmxIpyIpJ0+YaFw02IiOSdYrqxwPXdSyeIShz8aa9Tq+tYFXdPwcaMp/Fc80mQZ1dkOQ/wg==} peerDependencies: - '@electric-sql/pglite': 0.3.15 - - '@electric-sql/pglite@0.3.15': - resolution: {integrity: sha512-Cj++n1Mekf9ETfdc16TlDi+cDDQF0W7EcbyRHYOAeZdsAe8M/FJg18itDTSwyHfar2WIezawM9o0EKaRGVKygQ==} - - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@electric-sql/pglite': 0.4.3 - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@electric-sql/pglite@0.4.3': + resolution: {integrity: sha512-ichuWTgtd4mOM1G4SpyGJa5trT03lWbMypDV0fUXUCXg5hiHqVAz/bZyV68NqmkLB7WcYmj1RMJVSp8HV/v/ZQ==} '@epic-web/invariant@1.0.0': resolution: {integrity: sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==} @@ -835,229 +527,311 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.27.3': resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.27.3': resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.27.3': resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.27.3': resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.27.3': resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.27.3': resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.27.3': resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.27.3': resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.27.3': resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.27.3': resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.27.3': resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.27.3': resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.27.3': resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.27.3': resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.27.3': resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.27.3': resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.27.3': resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.27.3': resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.27.3': resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.27.3': resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.27.3': resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.27.3': resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.27.3': resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.27.3': resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.27.3': resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.9.1': - resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - '@eslint-community/regexpp@4.12.2': - resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - - '@eslint/config-array@0.21.1': - resolution: {integrity: sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/config-helpers@0.4.2': - resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/core@0.17.0': - resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/eslintrc@3.3.3': - resolution: {integrity: sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.39.3': - resolution: {integrity: sha512-1B1VkCq6FuUNlQvlBYb+1jDu/gV297TIs/OeiaSR9l1H27SVW55ONE1e1Vp16NqP683+xEGzxYtv4XCiDPaQiw==} - 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/plugin-kit@0.4.1': - resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@fastify/accept-negotiator@2.0.1': - resolution: {integrity: sha512-/c/TW2bO/v9JeEgoD/g1G5GxGeCF1Hafdf79WPmUlgYiBXummY0oX3VVq4yFkKKVBKDNlaDUYoab7g38RpPqCQ==} - - '@fastify/ajv-compiler@4.0.5': - resolution: {integrity: sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==} - - '@fastify/compress@8.3.1': - resolution: {integrity: sha512-BUpItLr6MUX9e9ukg5Y6xekyA/7pBFG8QWtFCrUDm9ctoBc3R2/nA16yOaOWtVoccpXGjdDEYA/MxAb5+8cxag==} - - '@fastify/cors@11.2.0': - resolution: {integrity: sha512-LbLHBuSAdGdSFZYTLVA3+Ch2t+sA6nq3Ejc6XLAKiQ6ViS2qFnvicpj0htsx03FyYeLs04HfRNBsz/a8SvbcUw==} - - '@fastify/error@4.2.0': - resolution: {integrity: sha512-RSo3sVDXfHskiBZKBPRgnQTtIqpi/7zhJOEmAxCiBcM7d0uwdGdxLlsCaLzGs8v8NnxIRlfG0N51p5yFaOentQ==} - - '@fastify/fast-json-stringify-compiler@5.0.3': - resolution: {integrity: sha512-uik7yYHkLr6fxd8hJSZ8c+xF4WafPK+XzneQDPU+D10r5X19GW8lJcom2YijX2+qtFF1ENJlHXKFM9ouXNJYgQ==} - - '@fastify/formbody@8.0.2': - resolution: {integrity: sha512-84v5J2KrkXzjgBpYnaNRPqwgMsmY7ZDjuj0YVuMR3NXCJRCgKEZy/taSP1wUYGn0onfxJpLyRGDLa+NMaDJtnA==} - - '@fastify/forwarded@3.0.1': - resolution: {integrity: sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==} - - '@fastify/merge-json-schemas@0.2.1': - resolution: {integrity: sha512-OA3KGBCy6KtIvLf8DINC5880o5iBlDX4SxzLQS8HorJAbqluzLRn80UXU0bxZn7UOFhFgpRJDasfwn9nG4FG4A==} - - '@fastify/proxy-addr@5.1.0': - resolution: {integrity: sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==} - - '@fastify/send@4.1.0': - resolution: {integrity: sha512-TMYeQLCBSy2TOFmV95hQWkiTYgC/SEx7vMdV+wnZVX4tt8VBLKzmH8vV9OzJehV0+XBfg+WxPMt5wp+JBUKsVw==} - - '@fastify/static@8.3.0': - resolution: {integrity: sha512-yKxviR5PH1OKNnisIzZKmgZSus0r2OZb8qCSbqmw34aolT4g3UlzYfeBRym+HJ1J471CR8e2ldNub4PubD1coA==} + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} @@ -1068,167 +842,37 @@ packages: '@floating-ui/utils@0.2.11': resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + '@grpc/grpc-js@1.14.6': + resolution: {integrity: sha512-SgC/B3/VZ8lTyOZ4Cwk6f1skWhmkNAaVfiX90qd5u1rRXGKk1//8FTUEN9GvOUq7rfWIqAYkA3CoyumYVpOS6g==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.7.15': + resolution: {integrity: sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==} + engines: {node: '>=6'} + hasBin: true + + '@grpc/proto-loader@0.8.1': + resolution: {integrity: sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==} + engines: {node: '>=6'} + hasBin: true + '@hallmaster/docker.js@0.0.28': resolution: {integrity: sha512-Nu3dALGsn3o6k4vcX7IRgFU/BXtZ+JZlBxEYuu2lbdaEoKL6Pu/Hq8BT3urSIVbl3usXNleXbiaHyCLCGxtJUA==} - '@hono/node-server@1.19.9': - resolution: {integrity: sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==} - engines: {node: '>=18.14.1'} + '@hono/node-server@2.1.1': + resolution: {integrity: sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==} + engines: {node: '>=20'} peerDependencies: hono: ^4 - '@humanfs/core@0.19.1': - resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} - engines: {node: '>=18.18.0'} - - '@humanfs/node@0.16.7': - resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} - engines: {node: '>=18.18.0'} - - '@humanwhocodes/module-importer@1.0.1': - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - - '@humanwhocodes/retry@0.4.3': - resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} - engines: {node: '>=18.18'} - - '@inquirer/ansi@1.0.2': - resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} - engines: {node: '>=18'} + '@hono/standard-validator@0.4.0': + resolution: {integrity: sha512-MxOm1asDh9j7c1D0KiWwppSbFgAQxTRO4YEhjMrJn3lF1BIcXenPdgjSGKDRfQmZdaTaMA8slQLETgVOKyJxFw==} + peerDependencies: + '@standard-schema/spec': ^1.0.0 + hono: '>=4.11.2' - '@inquirer/checkbox@4.3.2': - resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@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/editor@4.2.23': - resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/expand@4.0.23': - resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/external-editor@1.0.3': - resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} - 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/input@4.3.1': - resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/number@3.0.23': - resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/password@4.0.23': - resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/prompts@7.10.1': - resolution: {integrity: sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/prompts@7.3.2': - resolution: {integrity: sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/rawlist@4.1.11': - resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/search@3.2.2': - resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/select@4.4.2': - resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} - engines: {node: '>=18'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/type@3.0.10': - resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -1239,131 +883,9 @@ packages: '@internationalized/date@3.12.0': resolution: {integrity: sha512-/PyIMzK29jtXaGU23qTvNZxvBXRtKbNnGDFD+PY6CZw/Y8Ex8pFUzkuCJCG9aOqmShjqhS9mPqP6Dk5onQY8rQ==} - '@isaacs/cliui@9.0.0': - resolution: {integrity: sha512-AokJm4tuBHillT+FpMtxQ60n8ObyXBatq7jD2/JA9dxbDDokKQm8KMht5ibGzLVU9IJDIKK4TPKgMHEYMn3lMg==} - engines: {node: '>=18'} - - '@istanbuljs/load-nyc-config@1.1.0': - resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} - engines: {node: '>=8'} - - '@istanbuljs/schema@0.1.3': - resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} - engines: {node: '>=8'} - - '@jest/console@29.7.0': - resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/core@29.7.0': - resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/diff-sequences@30.0.1': - resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/environment@29.7.0': - resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/environment@30.2.0': - resolution: {integrity: sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/expect-utils@29.7.0': - resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect-utils@30.2.0': - resolution: {integrity: sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/expect@29.7.0': - resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/expect@30.2.0': - resolution: {integrity: sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/fake-timers@29.7.0': - resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/fake-timers@30.2.0': - resolution: {integrity: sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/get-type@30.1.0': - resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/globals@29.7.0': - resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/globals@30.2.0': - resolution: {integrity: sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/pattern@30.0.1': - resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/reporters@29.7.0': - resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - '@jest/schemas@29.6.3': - resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/schemas@30.0.5': - resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/snapshot-utils@30.2.0': - resolution: {integrity: sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/source-map@29.6.3': - resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-result@29.7.0': - resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/test-sequencer@29.7.0': - resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/transform@29.7.0': - resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/transform@30.2.0': - resolution: {integrity: sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - '@jest/types@29.6.3': - resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - '@jest/types@30.2.0': - resolution: {integrity: sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -1381,11 +903,17 @@ packages: '@jridgewell/sourcemap-codec@1.5.5': resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} + '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} '@layerstack/svelte-actions@1.0.1-next.18': resolution: {integrity: sha512-gxPzCnJ1c9LTfWtRqLUzefCx+k59ZpxDUQ2XB+LokveZQPe7IDSOwHaBOEMlaGoGrtwc3Ft8dSZq+2WT2o9u/g==} @@ -1404,372 +932,204 @@ packages: peerDependencies: svelte: ^5 - '@lukeed/csprng@1.1.0': - resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} - engines: {node: '>=8'} - - '@lukeed/ms@2.0.2': - resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} - engines: {node: '>=8'} - '@manypkg/find-root@1.1.0': resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} '@manypkg/get-packages@1.1.3': resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} - '@microsoft/tsdoc@0.16.0': - resolution: {integrity: sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==} + '@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'} - '@mrleebo/prisma-ast@0.13.1': - resolution: {integrity: sha512-XyroGQXcHrZdvmrGJvsA9KNeOOgGMg1Vg9OlheUsBOSKznLMDl+YChxbkboRHvtFYJEMRYmlV3uoo/njCw05iw==} - engines: {node: '>=16'} + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} - '@napi-rs/nice-android-arm-eabi@1.1.1': - resolution: {integrity: sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==} - engines: {node: '>= 10'} + '@oxc-project/types@0.153.0': + resolution: {integrity: sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==} + + '@oxfmt/binding-android-arm-eabi@0.57.0': + resolution: {integrity: sha512-qVBsEO+KugOsCmUHcO8iqNnqc65p7PCKpCs8M66mPZ+Ri+CWbcpoQOEJBg2OTu03+0qu++NK1jj6IzvQVs0Sig==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@napi-rs/nice-android-arm64@1.1.1': - resolution: {integrity: sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==} - engines: {node: '>= 10'} + '@oxfmt/binding-android-arm-eabi@0.70.0': + resolution: {integrity: sha512-Xd7YO4/T2axEj6FTLcj4Why3mTBqFMg+x24xtorT4Lb2+1g82090GH0a/4U1m0pABGYiix2bq1pqkYrmV3f0Sw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@oxfmt/binding-android-arm64@0.57.0': + resolution: {integrity: sha512-mp6PibWbao3aizijcheOeHQaYEhcUAt8pwLniYbtLfHxL/psFF0BykAwCj+s3c6qIpa8yN8keZICWrqtZ70w8g==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@napi-rs/nice-darwin-arm64@1.1.1': - resolution: {integrity: sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==} - engines: {node: '>= 10'} + '@oxfmt/binding-android-arm64@0.70.0': + resolution: {integrity: sha512-x9rlMYyKXdgKdYyUJzGsK1ZV8P4di/J32ipzcS6Jet6p9r9UAh28neXIMtdlSaJJycdi61Z4YkcLKLpk8ueFjg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@oxfmt/binding-darwin-arm64@0.57.0': + resolution: {integrity: sha512-T+0stuCBqmUVY+aMIvrgXhzGhHO3sD5tNiiEcYqgSdPsnukskQqn2u5qOVD0sv1l7RLdFS5Z/f5Wi9Ktyjr3Eg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@napi-rs/nice-darwin-x64@1.1.1': - resolution: {integrity: sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==} - engines: {node: '>= 10'} + '@oxfmt/binding-darwin-arm64@0.70.0': + resolution: {integrity: sha512-IUTUPvrBVYy7POh4stXzRdz4IVC/1QSaviCWoyenSlOhGu0X9j5K07vCTM9biLjAA2Zs31l0Rj5vvRpj9n95wA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@oxfmt/binding-darwin-x64@0.57.0': + resolution: {integrity: sha512-O+3JbqWs/mCI2oi4xfhRO2IVPFJNDDEBV8Odo+ZpmsUOeKJfjXoNH7nDmBEQcDgK7NfjDIyE7kRgYSZcTLDO0A==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@napi-rs/nice-freebsd-x64@1.1.1': - resolution: {integrity: sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==} - engines: {node: '>= 10'} + '@oxfmt/binding-darwin-x64@0.70.0': + resolution: {integrity: sha512-vw745q870oTd6J517O24asoX4/E+eK0nxYIFoedSLqgJ+nI5En7+ZS82iZSHZ69zevQrnOXiyHP01dA+t8xD8w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@oxfmt/binding-freebsd-x64@0.57.0': + resolution: {integrity: sha512-pxwhxVC+JkLX9twOQ/8C/vbuOQcMZyKIDmiRDZfO7yITuVcIdZCiLRqqf4QOxb2+8FWrRXzQpm+1DBKcMpHSSQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': - resolution: {integrity: sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==} - engines: {node: '>= 10'} + '@oxfmt/binding-freebsd-x64@0.70.0': + resolution: {integrity: sha512-NO14EgSM9dFkcg+MfGPxvsKqXYs9LKaxPrOKXpv1R0rLokGGFDcCq6dBMq18dE4wlpFOovX0UZY2uh1P30O7QA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@oxfmt/binding-linux-arm-gnueabihf@0.57.0': + resolution: {integrity: sha512-pxBU4zH2imB/MDBfth2rOMeVxXUMjRQLCazagwLARIFH3hVlxZJBlM4nSnHXaIHJK4/qezoFCIORN6AY8Mra4A==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@napi-rs/nice-linux-arm64-gnu@1.1.1': - resolution: {integrity: sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==} - engines: {node: '>= 10'} + '@oxfmt/binding-linux-arm-gnueabihf@0.70.0': + resolution: {integrity: sha512-139OEhHarj9CYoJ/i9gXlPv4KLBGtLj2toseOWYFf09QwlhklaZk+wW3aOvlqoeZtuayvkoSNVWra7WJ21s3VQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm-musleabihf@0.57.0': + resolution: {integrity: sha512-JAprOzt8tycYou36ZgEw14DlRHTiN8qdtKANdV3VZIRIvTI/lh/cX13c9pJ/EnDk2GT3FASH7KvCgQ2AufAifQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm-musleabihf@0.70.0': + resolution: {integrity: sha512-GEh2PY3IWTE0M24eNhTduountANSbWyDmMnzFSQE/nGg/bjPugbUgiGuFu+xdqcQSd/HKSwH80/F2yVVD48yhA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@oxfmt/binding-linux-arm64-gnu@0.57.0': + resolution: {integrity: sha512-ajtjaxSaj9xl4BW7REt+Cef/ttzbAq00Bq4z7JUDZEfgFXdwSjH8K9bF+IcIJzZB9lKqMfQ4eHuSFOvvlvtqOg==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@napi-rs/nice-linux-arm64-musl@1.1.1': - resolution: {integrity: sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==} - engines: {node: '>= 10'} + '@oxfmt/binding-linux-arm64-gnu@0.70.0': + resolution: {integrity: sha512-En5i+UJmZSPxuSf47F2Hl5YOzKB0bicQLnGQkeTCMQ35cWLtbrSwACJKfiLqRZrk05DwSnsJkhBRaM3OURtIaA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@oxfmt/binding-linux-arm64-musl@0.57.0': + resolution: {integrity: sha512-p4Y/+RYk9Bk5WO+zHSUXAClRmZ2fbJCejMuCAsU2HhyME4jqf6Ftt/mJYEwIah1wGCBDYOB7wEGV1x5bCEZ6hA==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@napi-rs/nice-linux-ppc64-gnu@1.1.1': - resolution: {integrity: sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==} - engines: {node: '>= 10'} + '@oxfmt/binding-linux-arm64-musl@0.70.0': + resolution: {integrity: sha512-WWOoV5W9Im3flVwOVrWn/2DUlOF8v5vcCip+kcNuaMpulRCh6nzzt1Su2vcL2F908YJIXNV3HvegbBHuyLwKHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@oxfmt/binding-linux-ppc64-gnu@0.57.0': + resolution: {integrity: sha512-By6tRALAZsno0F4zedmtG+wdMvJiJmJoXM4d3+A9zHE4HRXLqXITwRH8mgrlcXc5yJM2g2W3riRPwTYdgemZLQ==} + engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@napi-rs/nice-linux-riscv64-gnu@1.1.1': - resolution: {integrity: sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==} - engines: {node: '>= 10'} - cpu: [riscv64] + '@oxfmt/binding-linux-ppc64-gnu@0.70.0': + resolution: {integrity: sha512-YUouneIqW+5n7aE8xx/zeZ6/utr/KH7oykcGoFyd8Uz8uh591T1oKlnoWA3BsRq/ZR42oY1w4MUYvS/0e/MQOA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] os: [linux] libc: [glibc] - '@napi-rs/nice-linux-s390x-gnu@1.1.1': - resolution: {integrity: sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==} - engines: {node: '>= 10'} - cpu: [s390x] + '@oxfmt/binding-linux-riscv64-gnu@0.57.0': + resolution: {integrity: sha512-skYeG+RgvyzspqVEBsEprL90OYYZfoVNqB3HcCNR6QDJyXKOzfDRT3zncnHmUaFluIlBHuY23mU1b5WGgR98hA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] os: [linux] libc: [glibc] - '@napi-rs/nice-linux-x64-gnu@1.1.1': - resolution: {integrity: sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==} - engines: {node: '>= 10'} - cpu: [x64] + '@oxfmt/binding-linux-riscv64-gnu@0.70.0': + resolution: {integrity: sha512-iEnMf21S5aGVa4hViDGY8sAQ/AHyCu2JPyrQF8P06wtHhSkD1YJBeT4m/KiGewgf7+a5XCYSCRIPcRQa1xwEoQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] os: [linux] libc: [glibc] - '@napi-rs/nice-linux-x64-musl@1.1.1': - resolution: {integrity: sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==} - engines: {node: '>= 10'} - cpu: [x64] + '@oxfmt/binding-linux-riscv64-musl@0.57.0': + resolution: {integrity: sha512-FFgACrZOXAXUh5KQh2mt1CDOVOZmn+QzHP71wM9QobNwyQvoFfyAeefVUltW83g3sm7LTiH3yfFqLLVUpA5ZFQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] os: [linux] libc: [musl] - '@napi-rs/nice-openharmony-arm64@1.1.1': - resolution: {integrity: sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [openharmony] - - '@napi-rs/nice-win32-arm64-msvc@1.1.1': - resolution: {integrity: sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - - '@napi-rs/nice-win32-ia32-msvc@1.1.1': - resolution: {integrity: sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==} - engines: {node: '>= 10'} - cpu: [ia32] - os: [win32] - - '@napi-rs/nice-win32-x64-msvc@1.1.1': - resolution: {integrity: sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - - '@napi-rs/nice@1.1.1': - resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} - engines: {node: '>= 10'} - - '@napi-rs/wasm-runtime@0.2.12': - resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} - - '@nestjs/cli@11.0.16': - resolution: {integrity: sha512-P0H+Vcjki6P5160E5QnMt3Q0X5FTg4PZkP99Ig4lm/4JWqfw32j3EXv3YBTJ2DmxLwOQ/IS9F7dzKpMAgzKTGg==} - engines: {node: '>= 20.11'} - hasBin: true - peerDependencies: - '@swc/cli': ^0.1.62 || ^0.3.0 || ^0.4.0 || ^0.5.0 || ^0.6.0 || ^0.7.0 - '@swc/core': ^1.3.62 - peerDependenciesMeta: - '@swc/cli': - optional: true - '@swc/core': - optional: true - - '@nestjs/common@11.1.14': - resolution: {integrity: sha512-IN/tlqd7Nl9gl6f0jsWEuOrQDaCI9vHzxv0fisHysfBQzfQIkqlv5A7w4Qge02BUQyczXT9HHPgHtWHCxhjRng==} - peerDependencies: - class-transformer: '>=0.4.1' - class-validator: '>=0.13.2' - reflect-metadata: ^0.1.12 || ^0.2.0 - rxjs: ^7.1.0 - peerDependenciesMeta: - class-transformer: - optional: true - class-validator: - optional: true - - '@nestjs/config@4.0.3': - resolution: {integrity: sha512-FQ3M3Ohqfl+nHAn5tp7++wUQw0f2nAk+SFKe8EpNRnIifPqvfJP6JQxPKtFLMOHbyer4X646prFG4zSRYEssQQ==} - peerDependencies: - '@nestjs/common': ^10.0.0 || ^11.0.0 - rxjs: ^7.1.0 - - '@nestjs/core@11.1.14': - resolution: {integrity: sha512-7OXPPMoDr6z+5NkoQKu4hOhfjz/YYqM3bNilPqv1WVFWrzSmuNXxvhbX69YMmNmRYascPXiwESqf5jJdjKXEww==} - engines: {node: '>= 20'} - peerDependencies: - '@nestjs/common': ^11.0.0 - '@nestjs/microservices': ^11.0.0 - '@nestjs/platform-express': ^11.0.0 - '@nestjs/websockets': ^11.0.0 - reflect-metadata: ^0.1.12 || ^0.2.0 - rxjs: ^7.1.0 - peerDependenciesMeta: - '@nestjs/microservices': - optional: true - '@nestjs/platform-express': - optional: true - '@nestjs/websockets': - optional: true - - '@nestjs/jwt@11.0.2': - resolution: {integrity: sha512-rK8aE/3/Ma45gAWfCksAXUNbOoSOUudU0Kn3rT39htPF7wsYXtKfjALKeKKJbFrIWbLjsbqfXX5bIJNvgBugGA==} - peerDependencies: - '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 - - '@nestjs/mapped-types@2.1.0': - resolution: {integrity: sha512-W+n+rM69XsFdwORF11UqJahn4J3xi4g/ZEOlJNL6KoW5ygWSmBB2p0S2BZ4FQeS/NDH72e6xIcu35SfJnE8bXw==} - peerDependencies: - '@nestjs/common': ^10.0.0 || ^11.0.0 - class-transformer: ^0.4.0 || ^0.5.0 - class-validator: ^0.13.0 || ^0.14.0 - reflect-metadata: ^0.1.12 || ^0.2.0 - peerDependenciesMeta: - class-transformer: - optional: true - class-validator: - optional: true - - '@nestjs/platform-express@11.1.13': - resolution: {integrity: sha512-LYmi43BrAs1n74kLCUfXcHag7s1CmGETcFbf9IVyA/KWXAuAH95G3wEaZZiyabOLFNwq4ifnRGnIwUwW7cz3+w==} - peerDependencies: - '@nestjs/common': ^11.0.0 - '@nestjs/core': ^11.0.0 - - '@nestjs/platform-fastify@11.1.14': - resolution: {integrity: sha512-/hnKvPpeH+CTWus7L+F+qXkdbTRXudSQU3Z8tcs5kfvluoBLsxSDTTvjjySr7zrPs5bebaFbGIyG2fKMAWl++g==} - peerDependencies: - '@fastify/static': ^8.0.0 || ^9.0.0 - '@fastify/view': ^10.0.0 || ^11.0.0 - '@nestjs/common': ^11.0.0 - '@nestjs/core': ^11.0.0 - peerDependenciesMeta: - '@fastify/static': - optional: true - '@fastify/view': - optional: true - - '@nestjs/schematics@11.0.9': - resolution: {integrity: sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==} - peerDependencies: - typescript: '>=4.8.2' - - '@nestjs/swagger@11.2.6': - resolution: {integrity: sha512-oiXOxMQqDFyv1AKAqFzSo6JPvMEs4uA36Eyz/s2aloZLxUjcLfUMELSLSNQunr61xCPTpwEOShfmO7NIufKXdA==} - peerDependencies: - '@fastify/static': ^8.0.0 || ^9.0.0 - '@nestjs/common': ^11.0.1 - '@nestjs/core': ^11.0.1 - class-transformer: '*' - class-validator: '*' - reflect-metadata: ^0.1.12 || ^0.2.0 - peerDependenciesMeta: - '@fastify/static': - optional: true - class-transformer: - optional: true - class-validator: - optional: true - - '@nestjs/testing@11.1.14': - resolution: {integrity: sha512-cQxX0ronsTbpfHz8/LYOVWXxoTxv6VoxrnuZoQaVX7QV2PSMqxWE7/9jSQR0GcqAFUEmFP34c6EJqfkjfX/k4Q==} - peerDependencies: - '@nestjs/common': ^11.0.0 - '@nestjs/core': ^11.0.0 - '@nestjs/microservices': ^11.0.0 - '@nestjs/platform-express': ^11.0.0 - peerDependenciesMeta: - '@nestjs/microservices': - optional: true - '@nestjs/platform-express': - optional: true - - '@noble/hashes@1.8.0': - resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} - engines: {node: ^14.21.3 || >=16} - - '@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: {integrity: sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==} - engines: {node: ^14.18.0 || >=16.10.0, npm: '>=5.10.0'} - hasBin: true - - '@oxfmt/binding-android-arm-eabi@0.57.0': - resolution: {integrity: sha512-qVBsEO+KugOsCmUHcO8iqNnqc65p7PCKpCs8M66mPZ+Ri+CWbcpoQOEJBg2OTu03+0qu++NK1jj6IzvQVs0Sig==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - - '@oxfmt/binding-android-arm64@0.57.0': - resolution: {integrity: sha512-mp6PibWbao3aizijcheOeHQaYEhcUAt8pwLniYbtLfHxL/psFF0BykAwCj+s3c6qIpa8yN8keZICWrqtZ70w8g==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - - '@oxfmt/binding-darwin-arm64@0.57.0': - resolution: {integrity: sha512-T+0stuCBqmUVY+aMIvrgXhzGhHO3sD5tNiiEcYqgSdPsnukskQqn2u5qOVD0sv1l7RLdFS5Z/f5Wi9Ktyjr3Eg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - - '@oxfmt/binding-darwin-x64@0.57.0': - resolution: {integrity: sha512-O+3JbqWs/mCI2oi4xfhRO2IVPFJNDDEBV8Odo+ZpmsUOeKJfjXoNH7nDmBEQcDgK7NfjDIyE7kRgYSZcTLDO0A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - - '@oxfmt/binding-freebsd-x64@0.57.0': - resolution: {integrity: sha512-pxwhxVC+JkLX9twOQ/8C/vbuOQcMZyKIDmiRDZfO7yITuVcIdZCiLRqqf4QOxb2+8FWrRXzQpm+1DBKcMpHSSQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - - '@oxfmt/binding-linux-arm-gnueabihf@0.57.0': - resolution: {integrity: sha512-pxBU4zH2imB/MDBfth2rOMeVxXUMjRQLCazagwLARIFH3hVlxZJBlM4nSnHXaIHJK4/qezoFCIORN6AY8Mra4A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxfmt/binding-linux-arm-musleabihf@0.57.0': - resolution: {integrity: sha512-JAprOzt8tycYou36ZgEw14DlRHTiN8qdtKANdV3VZIRIvTI/lh/cX13c9pJ/EnDk2GT3FASH7KvCgQ2AufAifQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - - '@oxfmt/binding-linux-arm64-gnu@0.57.0': - resolution: {integrity: sha512-ajtjaxSaj9xl4BW7REt+Cef/ttzbAq00Bq4z7JUDZEfgFXdwSjH8K9bF+IcIJzZB9lKqMfQ4eHuSFOvvlvtqOg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@oxfmt/binding-linux-arm64-musl@0.57.0': - resolution: {integrity: sha512-p4Y/+RYk9Bk5WO+zHSUXAClRmZ2fbJCejMuCAsU2HhyME4jqf6Ftt/mJYEwIah1wGCBDYOB7wEGV1x5bCEZ6hA==} + '@oxfmt/binding-linux-riscv64-musl@0.70.0': + resolution: {integrity: sha512-91Sdniaj20fQzyMeCxMDzTP4c9s4RB8dGQ308xHhDR0n6U7+1Xq7N9klE7mfXq8iV3lRmIGSXi5X23Hn/0XX/g==} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] + cpu: [riscv64] os: [linux] libc: [musl] - '@oxfmt/binding-linux-ppc64-gnu@0.57.0': - resolution: {integrity: sha512-By6tRALAZsno0F4zedmtG+wdMvJiJmJoXM4d3+A9zHE4HRXLqXITwRH8mgrlcXc5yJM2g2W3riRPwTYdgemZLQ==} + '@oxfmt/binding-linux-s390x-gnu@0.57.0': + resolution: {integrity: sha512-Nm/BAOfQeFiiKd502mZn/GAVKJwtd0RdCg17G3Wz/WSOIQmDi3+7/SZH4BHn1Ye5KvTVH3ua8WvfwLLycNIuvA==} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] + cpu: [s390x] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-gnu@0.57.0': - resolution: {integrity: sha512-skYeG+RgvyzspqVEBsEprL90OYYZfoVNqB3HcCNR6QDJyXKOzfDRT3zncnHmUaFluIlBHuY23mU1b5WGgR98hA==} + '@oxfmt/binding-linux-s390x-gnu@0.70.0': + resolution: {integrity: sha512-uUV30M6E+2TKKGMaKiwfeL4RZrviHXlUxsrYJ/jFBb+1EZy+pnFT+hF73eeWdzh5NqPOAnw0iiMAIqjqiLZPFg==} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] + cpu: [s390x] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-riscv64-musl@0.57.0': - resolution: {integrity: sha512-FFgACrZOXAXUh5KQh2mt1CDOVOZmn+QzHP71wM9QobNwyQvoFfyAeefVUltW83g3sm7LTiH3yfFqLLVUpA5ZFQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [riscv64] - os: [linux] - libc: [musl] - - '@oxfmt/binding-linux-s390x-gnu@0.57.0': - resolution: {integrity: sha512-Nm/BAOfQeFiiKd502mZn/GAVKJwtd0RdCg17G3Wz/WSOIQmDi3+7/SZH4BHn1Ye5KvTVH3ua8WvfwLLycNIuvA==} + '@oxfmt/binding-linux-x64-gnu@0.57.0': + resolution: {integrity: sha512-BiSy5Ku3mQqyxS6YIqAJgd403wEUWvI7kerfzPxc2l/txZVmZM0pSj7oDM+4bGBExowxOi7o73jEam1W0EDTZg==} engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] + cpu: [x64] os: [linux] libc: [glibc] - '@oxfmt/binding-linux-x64-gnu@0.57.0': - resolution: {integrity: sha512-BiSy5Ku3mQqyxS6YIqAJgd403wEUWvI7kerfzPxc2l/txZVmZM0pSj7oDM+4bGBExowxOi7o73jEam1W0EDTZg==} + '@oxfmt/binding-linux-x64-gnu@0.70.0': + resolution: {integrity: sha512-ivMcX6kNDPhqtbOaBt/ItFlLlTlXNHLgRuNmxP6Na6UuYXRT10llpJcAPbGeRgjjb3Qzv4jwPp3fB0hui50WNQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -1782,102 +1142,205 @@ packages: os: [linux] libc: [musl] + '@oxfmt/binding-linux-x64-musl@0.70.0': + resolution: {integrity: sha512-w+S+fERxYmlZSyZlJK/U292FjyBoH8cCEj21/tYJX6atX5kNSn+HDkhlFQKT2zcMwUW0uAtUL/bOrlwJZwqRdA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@oxfmt/binding-openharmony-arm64@0.57.0': resolution: {integrity: sha512-4Oaxe1qrGgXfpCJ1C/ERJ2iCtV2rN1R79ga9fsfyVHfSQRu/hVW780u2KDqZWFZ/iGTHODJji0JemxqFZ63eIQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@oxfmt/binding-openharmony-arm64@0.70.0': + resolution: {integrity: sha512-Zlom1Xkx257R8bk4ZI4zJsrGno2opknz1+5v5baka3nn4FPyvNSdh8JUL4CdN1S1OWRMvJ9UJQ+RfIqGGCUEfA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@oxfmt/binding-win32-arm64-msvc@0.57.0': resolution: {integrity: sha512-MYLAsDnhdNsSGheLYhWgbk0vfIrlS84iQYun/y21fX6u0jj8iBtYtbpZMdiqYeuf8U12eVPUjVY2xE2NrCfJ0g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@oxfmt/binding-win32-arm64-msvc@0.70.0': + resolution: {integrity: sha512-FQgPW5R17vzt7cgrJ8eG/dqX00o2xHsqFeLfw4xzA9FRHpN/DjFo9YDonvIIXGxiEuS9F/jZPnGO+KHNKuCo4Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@oxfmt/binding-win32-ia32-msvc@0.57.0': resolution: {integrity: sha512-PBwdzZALJY/jcCx2E6is0yu+cuVXeySTDmwuseD+9j0mHqlRNxwlKgsyRTBed/woPeqfVfuXfWjoq4Cx2Zt3Eg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] + '@oxfmt/binding-win32-ia32-msvc@0.70.0': + resolution: {integrity: sha512-ZfZublNhZ+XBndMiXhkiLlPE+XyGRDa0CweeTL6t1fZypfCh1LTg7e5CvnOeTBunq15MskOcRempumSPGAaCQA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + '@oxfmt/binding-win32-x64-msvc@0.57.0': resolution: {integrity: sha512-bQJdH9i4RRfw55jm7+8/xS7GzHLLTbHx4huhrrDxQJaJtbSDbsyOnODvP1ftT7EG0KFKAYO2S+q6AcioXODx8w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] + '@oxfmt/binding-win32-x64-msvc@0.70.0': + resolution: {integrity: sha512-HlIZEn+WzLQL0DszNzldiRl/DPRCX5R0Vkt6qeUPR1YHwy52hZZo4x6HoTOVmKRP2wUiwPGtKsihNY/f8KRaBg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@oxlint-tsgolint/darwin-arm64@0.17.4': resolution: {integrity: sha512-XEA7vl/T1+wiVnMq2MR6u5OYr2pwKHiAPgklxpK8tPrjQ1ci/amNmwI8ECn6TPXSCsC8SJsSN5xvzXm5H3dTfw==} cpu: [arm64] os: [darwin] + '@oxlint-tsgolint/darwin-arm64@7.0.2003': + resolution: {integrity: sha512-TgV33rXr6ueXBwvc+0nssUkTBSXHJxv77I8p4RCjDjCnvexHtmoPiudVRDfj3S3puMDdeQdHW6jdUgUPy3nr/w==} + cpu: [arm64] + os: [darwin] + '@oxlint-tsgolint/darwin-x64@0.17.4': resolution: {integrity: sha512-EY2wmHWqkz72B0/ddMiAM564ZXpEuN1i7JqJJhLmDUQfiHX0/X0EqK3xlSScMCFcVicitOxbKO9oqbde3658yg==} cpu: [x64] os: [darwin] + '@oxlint-tsgolint/darwin-x64@7.0.2003': + resolution: {integrity: sha512-hY3FMAjIaPDdK3FNxyRXRfHPOFeoBn6dmnLyKZgQ2IbTTD1adXhl6PfCIqHhCPvurigv7nf7mYuWZZ19MmJzmg==} + cpu: [x64] + os: [darwin] + '@oxlint-tsgolint/linux-arm64@0.17.4': resolution: {integrity: sha512-XL2X8hgp3/TZWeHFLUnWrveTCBPxy1kNtpzfvVkLtBgyoaRyopPYL0Mnm+ypXKgGvUdcjDaiJhnRjFHWmqZkew==} cpu: [arm64] os: [linux] + '@oxlint-tsgolint/linux-arm64@7.0.2003': + resolution: {integrity: sha512-eAET4JpyfBbg8SO0K74o4R55tEjVC292pIyxGOw2XGf8x/HrPNyxwQ478jMYOM54FIVOHc8sJ6VRHxluy6lucw==} + cpu: [arm64] + os: [linux] + '@oxlint-tsgolint/linux-x64@0.17.4': resolution: {integrity: sha512-jT+aWtQuU8jefwfBLAZu16p4t8xUDjxL6KKlOeuwX3cS6NO60ITJ4Glm8eQYq5cGsOmYIKXNIe4ckPpL5LC+5g==} cpu: [x64] os: [linux] + '@oxlint-tsgolint/linux-x64@7.0.2003': + resolution: {integrity: sha512-GXdyO/XyqDJ3s/llR/oOktLsYNjZtWSQBy0JMc+/0gsNPvTcseKPhn9c6KcFyWmnr6H4vljYALbujonqSzzEGw==} + cpu: [x64] + os: [linux] + '@oxlint-tsgolint/win32-arm64@0.17.4': resolution: {integrity: sha512-pnnkBaI5tHBFhx+EhmpUHccBT3VOAXTgWK2eQBVLE4a/ywhpHN+8D6/QQN+ZTaA4LTkKowvlGD6vDOVP5KRPvw==} cpu: [arm64] os: [win32] + '@oxlint-tsgolint/win32-arm64@7.0.2003': + resolution: {integrity: sha512-TWauXnPfet0VgpmrstoAK58eJ4gbuwPUuUTQmYQAzE/RG1CpnxXtrKUJULf6lyerPE4KN3gM+DflIA1hOH+38Q==} + cpu: [arm64] + os: [win32] + '@oxlint-tsgolint/win32-x64@0.17.4': resolution: {integrity: sha512-JxT81aEUBNA/s01Ql2OQ2DLAsuM0M+mK9iLHunukOdPMhjA6NvFE/GtTablBYJKScK21d/xTvnoSLgQU3l22Cw==} cpu: [x64] os: [win32] + '@oxlint-tsgolint/win32-x64@7.0.2003': + resolution: {integrity: sha512-DoRmfe7j8VqNlukp8liRVW45GQDhzRccNenjD/pdzelgtffW47pCMd1xbJLkPaPbKnTwID3onn3VZlL7JbebEA==} + cpu: [x64] + os: [win32] + '@oxlint/binding-android-arm-eabi@1.72.0': resolution: {integrity: sha512-zhCmvn+1Mj3UchAc/90i99S0t7jJUsHmFVSPg4UWrjO8b8eaSGwscgO6QAUtvHBstkjQwBttQNswEnAF1mIQdA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] + '@oxlint/binding-android-arm-eabi@1.85.0': + resolution: {integrity: sha512-q2KO/Zso9UT+OMn0NF9ywn4E4t0MI3yxiDhNyhsQ7DyQJrC4FhFE4TXOi4bktFnOWXTMds8qZSbpv2XwRaNOBg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + '@oxlint/binding-android-arm64@1.72.0': resolution: {integrity: sha512-mtH+aY/ozv1eZoCUC2owjFAtyNBKHpJHygKeEu9zXXnQGW1Q2/qOpvx+I+Lf23+TvTz66F4iiXUbl2cGvoLPCQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] + '@oxlint/binding-android-arm64@1.85.0': + resolution: {integrity: sha512-SxLN3ALjoT9NNdvpjEevGeHvfzTAFrF0NBYB5tzK7/GtCKMze3j1e/m/X2ozqGj2U9hfGG/dg/OG8vpVK4PiDA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@oxlint/binding-darwin-arm64@1.72.0': resolution: {integrity: sha512-EvnajNPDtfknB3ZieeOOyDTwJn9QXDiwfnF4ZDQqART6RG6hjY4WigQcZdGoK2dkB3e1vrmEzN9aYbQCUkh/gQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@oxlint/binding-darwin-arm64@1.85.0': + resolution: {integrity: sha512-Y/Sup/J4f0f9UGsSd/xyCNTeWL+gepO63GBdEDAfue9nBsnk9zMmnIXx1O6b1V8C90vB5nucYNZ0pbMXAp8zJA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@oxlint/binding-darwin-x64@1.72.0': resolution: {integrity: sha512-ZkCdEa/G80A7vEHfeCDz/+L3m33DE73v32mDKhgOIgz8Uwf0DFcK7+uu6qC+7LEhmz5fpOe1osWKyjSNMydFIQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@oxlint/binding-darwin-x64@1.85.0': + resolution: {integrity: sha512-ApOSNC04ynpDTwvBD+//0wyfODRSbEzvRoKpX8teffmc27z8AockwSNeMXGJXn5KP85eahDgR/2llICWLkzcnw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@oxlint/binding-freebsd-x64@1.72.0': resolution: {integrity: sha512-NroXv2vh+sxVY1uya/rM5pjhx1hm8BzlYpx9q67QP0Xhw5MH2bf5GJylpvLEC+781p1Xli/317EoV9AlGwViag==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@oxlint/binding-freebsd-x64@1.85.0': + resolution: {integrity: sha512-bNrVrCOA/kHky3Tu79IXWXe5bhIgLXfUuUEDHlAGOHUk96MkvDZ1ecaQF19rwstrnaqfP1o9nBTqzIr9+ZHkUg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@oxlint/binding-linux-arm-gnueabihf@1.72.0': resolution: {integrity: sha512-0NDywYgfj279Ou/BcQuCYSj7NJwBfmWn5qc5uGO/Ny7fUWmXyIpvawqX/8acQlWG6IXelJsJhj+JAy6sjsKj0A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@oxlint/binding-linux-arm-gnueabihf@1.85.0': + resolution: {integrity: sha512-NUrzOJ1s/EqsVvfn2L/1D8Wro2LPIZUbihL8kOJLh5fEdGEN3rdOGUYq3HwnUIL8sjpoP+4N6RaGrgmMJnaMPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@oxlint/binding-linux-arm-musleabihf@1.72.0': resolution: {integrity: sha512-4vpXB06h65Ezsy4hRyrGjGrfa1SkVPii09yaajiYhmVpgsFiLD+KNxIx/BNAY+XiO+i1yqp9HHdwqM8VTqa5XQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@oxlint/binding-linux-arm-musleabihf@1.85.0': + resolution: {integrity: sha512-UJXrAT3E/RWkEqXLIs2ehETja1qfgkPb+5gwLIIS+o/6cf+grHvoOXTa5997a/YNQfcJS0DRBTOfZt95cvOI1g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@oxlint/binding-linux-arm64-gnu@1.72.0': resolution: {integrity: sha512-immaN4g2ZGFiOkKrvRX9LvzZdd2GkQM5wR+UyzYyUuyhUTXGQ4HKUJH18xp4G8OfhCVaVAJfKZxwE1r8+4hhaQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1885,6 +1348,13 @@ packages: os: [linux] libc: [glibc] + '@oxlint/binding-linux-arm64-gnu@1.85.0': + resolution: {integrity: sha512-lK40QLjI0HxigO7CjDDshEtfYIeiYS0020v5BHFPqN4uuQBQxd2K9LNom2dW15o9F1937quSCRVp4ZsVhdbYdg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@oxlint/binding-linux-arm64-musl@1.72.0': resolution: {integrity: sha512-JGHS9Mnr7iWyyLDxgCv1MhzVpAckgptg00F2gnxt/GD7lQ2SW1BRcxHqhSTaSdDpjWRrBkBxMMh4+Hn3aVtExg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1892,6 +1362,13 @@ packages: os: [linux] libc: [musl] + '@oxlint/binding-linux-arm64-musl@1.85.0': + resolution: {integrity: sha512-c2zbdBwGKreHXwRx3gWBuFGJxLhxgsg6YlZ+3H+RgRusU/UEV9jNwJ3HGYK+nRo0LvBa7mt6Kj86xoVotUo8cw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + '@oxlint/binding-linux-ppc64-gnu@1.72.0': resolution: {integrity: sha512-AOYgBZqxNshrg83P9v0RYv+m8s10Cqkj4/PxXFDhcS3k7FqsIG5+CxErshZCIN7G8iy4Y+VGfAsuEdar8AcbBg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1899,6 +1376,13 @@ packages: os: [linux] libc: [glibc] + '@oxlint/binding-linux-ppc64-gnu@1.85.0': + resolution: {integrity: sha512-tlt/Hy8lZ97/lCPmCgw/B3k/mwh+BzaIPbPkldZEly7TwLmx0xe2CQcaW2g/rR0dOgS9JNGCZsMEqLhUNMGvaw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@oxlint/binding-linux-riscv64-gnu@1.72.0': resolution: {integrity: sha512-QMybPS5ij3/vrKG67mqzHwW++91sYxK/PPUVi6SBtNCEzW4niS52fVBdXbQ6nou0wWbUPEpx8Sl/ZjtgE3clXA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1906,6 +1390,13 @@ packages: os: [linux] libc: [glibc] + '@oxlint/binding-linux-riscv64-gnu@1.85.0': + resolution: {integrity: sha512-3tNR9Xey82X0zKuY1d8hJ6Rc9gwRDurmqGLnQZa5xqOXy8/YyiqFXjAtugkKLY82obOlpK1eSiDRlgcNPuxtIg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@oxlint/binding-linux-riscv64-musl@1.72.0': resolution: {integrity: sha512-gOc3W7JV0PXRpIL7stUlLe3Wa9Gp0Kdlup87IT3gHDvPKck2xNgMIl/Gs2lldYY2lyXZDC4rWi3hmoLUobkgbQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1913,6 +1404,13 @@ packages: os: [linux] libc: [musl] + '@oxlint/binding-linux-riscv64-musl@1.85.0': + resolution: {integrity: sha512-wbGRd5PqCcjkJFHhZuZ2OBSUQY9czlQsoA/cQQB9JK/L9mC5MQgGoKAh+xd8QjA5V+0D3j+Qd1lAWn1I8zlelA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + '@oxlint/binding-linux-s390x-gnu@1.72.0': resolution: {integrity: sha512-rpGxph+FjjHcYI5q6uxB3Az+tnfmEnDbSA8+PK9ZE/VzyUAkvBOMeuY7ZQMhu5mpZH7YQDsTdW6Cx4kV/msc6w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1920,6 +1418,13 @@ packages: os: [linux] libc: [glibc] + '@oxlint/binding-linux-s390x-gnu@1.85.0': + resolution: {integrity: sha512-3Sn0kSrE4DPZCWV/8o+n4x3aFZxI9ulMnkYlwCbJ8eUVkwRK2IerohE/A/z3SNbCwoPFOCJmGE5Avrq0rrvdvQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@oxlint/binding-linux-x64-gnu@1.72.0': resolution: {integrity: sha512-WND+uhf/Ko13SLqQMWQUgsZuLvYYEvL0ZKgg0tgGYfLqxG7l8Ju123fHDMJyYSDl5E3bUbpFUuii/OvMreFQzw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1927,8 +1432,22 @@ packages: os: [linux] libc: [glibc] - '@oxlint/binding-linux-x64-musl@1.72.0': - resolution: {integrity: sha512-SrpbrUL70nG9vh6zP4/oKHWgLuHquwsr7MW9XOn0olBVgh10Uqr8qscKhQoBGEn6olK/IUpn5GSKcdQ5AjUhGA==} + '@oxlint/binding-linux-x64-gnu@1.85.0': + resolution: {integrity: sha512-JY2pxxYfB62bAGfejljVCqc44etItehPuAyaeSAdMuEMtwNA00ggMnS66lC1oIhos6oOXUkuU6mZ9bpFh3BqWg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@oxlint/binding-linux-x64-musl@1.72.0': + resolution: {integrity: sha512-SrpbrUL70nG9vh6zP4/oKHWgLuHquwsr7MW9XOn0olBVgh10Uqr8qscKhQoBGEn6olK/IUpn5GSKcdQ5AjUhGA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@oxlint/binding-linux-x64-musl@1.85.0': + resolution: {integrity: sha512-5k74vZ6qJBjBHEOlBk9B/iv68Yu0F1Afw/vvT2ar6OGCqEeXLaSjXz2n/IPCbhLG22UoKoYEJTzpYraRdcp6PA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -1940,43 +1459,61 @@ packages: cpu: [arm64] os: [openharmony] + '@oxlint/binding-openharmony-arm64@1.85.0': + resolution: {integrity: sha512-GbAl5qt5TCkPLXTaIISZJnugrcBhra6rodcXc9jYt620UtdsTt71NlNmJmm0frxzFpd54x/G+MkitEJA8I/BoA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@oxlint/binding-win32-arm64-msvc@1.72.0': resolution: {integrity: sha512-LWR6ZlFZph+KPjXv8opgZsXRDCdrdQe8VL8Cg9zxCoBS73h6znzZpydVgmdnwj8mB9AuSM5jxEgDJDpQkjboeg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@oxlint/binding-win32-arm64-msvc@1.85.0': + resolution: {integrity: sha512-kjmws5MK0et2swk4ND85D7NVQyDHw162i6whtZDLUA/lo6FQyBZDcmMRCMcVZcNrAhIaftVb00x9ChGDOjjNJA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@oxlint/binding-win32-ia32-msvc@1.72.0': resolution: {integrity: sha512-yt6HEh7IsHvtjRWtmeZRX134eaXKHq5Gnqlf1xBJdJl1JtdoRUEJw3nAxpZoUDS860cX/foKbztO441anVBtVQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] + '@oxlint/binding-win32-ia32-msvc@1.85.0': + resolution: {integrity: sha512-eSsIJx9n4yxvOqYTZyPEMyEXRmE60XH7xGAU7i0Qbsn1lf6Za3CWJ9aRd82oSFKXaxhp+sA6/yMJVRIpLpna6A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + '@oxlint/binding-win32-x64-msvc@1.72.0': resolution: {integrity: sha512-b2eKFD2hX7tIwmo/cyH6TDq8vzWRZ2qNHrzoGntUTmq0h3zQh/uX3eTSHCwI8OB/ADQfJCRelLItK8BsxuucDA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@paralleldrive/cuid2@2.3.1': - resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==} + '@oxlint/binding-win32-x64-msvc@1.85.0': + resolution: {integrity: sha512-pBebIPUpKKhWrhSMWhy8TdAZBewiXnfxmaAGxhzxM1068GagqFaTwgKlU6e+UyJ2sPR+VoHouhXuGJkQjsrDvA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] '@phc/format@1.0.0': resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==} engines: {node: '>=10'} - '@pinojs/redact@0.4.0': - resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} - - '@pkgr/core@0.2.9': - resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@prisma/adapter-pg@7.4.1': - resolution: {integrity: sha512-AH9XrqvSoBAaStn0Gm/sAnF97pDKz8uLpNmn51j1S9O9dhUva6LIxGdoDiiU9VXRIR89wAJXsvJSy+mK40m2xw==} + '@prisma/adapter-pg@7.10.0': + resolution: {integrity: sha512-N7nwSor0HO1Kz6xBv0TPAjAPysKK0fac6p4fVN3ensLOuzc/83Fgmln5k92eK/cvzqdkSR/2kkAqlbcdwVrwpw==} '@prisma/client-runtime-utils@7.4.1': resolution: {integrity: sha512-8fy74OMYC7mt9cJ2MncIDk1awPRgmtXVvwTN2FlW4JVhbck8Dgt0wTkhPG85myfj4ZeP2stjF9Sdg12n5HrpQg==} @@ -1993,46 +1530,254 @@ packages: typescript: optional: true - '@prisma/config@7.4.1': - resolution: {integrity: sha512-vteSXm8N46bo3FW9MhPGVHAj+KRgrR6TWtlSk6GqToCKjTnOexXdPZyiDyEsfVW38YhqEmVl6w/6iHN8uYVJcw==} + '@prisma/config@7.10.0': + resolution: {integrity: sha512-Rcg828gIRE3HOQ3pOATFjV5d/P0U9OIobxhd/IMxlfWjA4vru0eGwb0AIwFw0rmcLMVShohZYWPixVxkBHsxUA==} + + '@prisma/debug@7.10.0': + resolution: {integrity: sha512-caygJKtltmRIgdJ3jRpkOr7yM4DW6zxo5uOmojKWFb3asnxWoRkQOwZmXBgD8FZp4htrX+nMpcWqDwzlQ1+Y4g==} '@prisma/debug@7.2.0': resolution: {integrity: sha512-YSGTiSlBAVJPzX4ONZmMotL+ozJwQjRmZweQNIq/ER0tQJKJynNkRB3kyvt37eOfsbMCXk3gnLF6J9OJ4QWftw==} - '@prisma/debug@7.4.1': - resolution: {integrity: sha512-qEtzO8oLouRv18JDQUC3G3Gnv+fGVscHZm/x1DBB/WT+kOvPDQLM2woX6IGgWnSMYYlrxjuALshT7G/blvY0bQ==} + '@prisma/dev@0.24.17': + resolution: {integrity: sha512-UvdZzmpFwknnfreh6Jije84ekkYGPYEJhXG1tFzCsCfQyzJifrOo38eZc0qajzvaC6OLUOrN9ML5XfCnEZL9DA==} - '@prisma/dev@0.20.0': - resolution: {integrity: sha512-ovlBYwWor0OzG+yH4J3Ot+AneD818BttLA+Ii7wjbcLHUrnC4tbUPVGyNd3c/+71KETPKZfjhkTSpdS15dmXNQ==} + '@prisma/driver-adapter-utils@7.10.0': + resolution: {integrity: sha512-u8zkcRLlaryO652T4qavBg0HmzNW5tSKdsCn6hc1PhWAp/J6k0vrxLuUs+b9o+HcjsK7Dfa01o4OFSn0frauJA==} - '@prisma/driver-adapter-utils@7.4.1': - resolution: {integrity: sha512-gEZOC2tnlHaZNbHUdbK8YvQphq2tKq/Ovu1YixJ/hPSutDAvNzC3R+xUeBuJ4AJp236eELMzwxb7rgo3UbRkTg==} + '@prisma/engines-version@7.10.0-4.0edf323efd1d98336f3f0a68684b56f689b900d3': + resolution: {integrity: sha512-8OJ6RuZTZ06eFUOtBwxVmv8XMmOW6HWN5F+uxUbZkGxR0Bfab1dfAdXaHPmR5mb59E+fmUo8IOzXlbLY1SClbw==} - '@prisma/engines-version@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': - resolution: {integrity: sha512-fUxVd1TjOW8K4XsZ8dAm88sDW5Ry7AxWDfsYEWwScS6Fjo3caKC6hgNumUfsmsy0Il9LjDn5X0PpVXNt3iwayw==} + '@prisma/engines@7.10.0': + resolution: {integrity: sha512-KNumN6NHFwybvfdYzTee9pqwx5PvknpWAaHn6L5NsbrKdl+SQrsVZs9opKs6U6SAsvB26HDt3WybRjOhgoWOYQ==} - '@prisma/engines@7.4.1': - resolution: {integrity: sha512-BZEBdHvNJx5PzIG37EI/Zi5UUI5hGWjkYsQmKa7OIK6evAvebOTwutjS/VRI6cA6grmA52eLZR+oekGRMqkKxQ==} + '@prisma/fetch-engine@7.10.0': + resolution: {integrity: sha512-Zqyu8DY14t6W/xwmAxUYWCXtHrvQnSvT644EAZSsdM8NSmCS74vJJbBKdVsK3ucFpnUWkEpbO1a0CxJXrg130g==} - '@prisma/fetch-engine@7.4.1': - resolution: {integrity: sha512-Z9kbuxX2bvEsyeS3LZEiEnxG0lVtZbpYgaAnPj69N+A9f2De8Lta0EoFtld9zhfERVPIQWhSWUc8himky3qYdA==} + '@prisma/get-platform@7.10.0': + resolution: {integrity: sha512-0bra1LFYi8xNw0yqV62bHJNQk4BKleOngZiqPWIQc7a3+9q6rqsnqJ15BuepP8943PFMvtmgnP52juZsyYkA6w==} '@prisma/get-platform@7.2.0': resolution: {integrity: sha512-k1V0l0Td1732EHpAfi2eySTezyllok9dXb6UQanajkJQzPUGi3vO2z7jdkz67SypFTdmbnyGYxvEvYZdZsMAVA==} - '@prisma/get-platform@7.4.1': - resolution: {integrity: sha512-kN4tmkQzlgm/KtE+jTNSYjsDxxe/5i6GApPI32BN9T0tlgsgSBtDJbjGBICttkAIjsh73dXf8raPKxO/2n2UUg==} - '@prisma/query-plan-executor@7.2.0': resolution: {integrity: sha512-EOZmNzcV8uJ0mae3DhTsiHgoNCuu1J9mULQpGCh62zN3PxPTd+qI9tJvk5jOst8WHKQNwJWR3b39t0XvfBB0WQ==} - '@prisma/studio-core@0.13.1': - resolution: {integrity: sha512-agdqaPEePRHcQ7CexEfkX1RvSH9uWDb6pXrZnhCRykhDFAV0/0P3d07WtfiY8hZWb7oRU4v+NkT4cGFHkQJIPg==} + '@prisma/streams-local@0.1.11': + resolution: {integrity: sha512-0TcebL559MByKqTJ+SsrFIEg228iw8UCVRFckzgfRSiJqczhs+MuAgWOF9lnOIV/IVqvu+KMnFTH0eDeTQMpUg==} + engines: {bun: '>=1.2.0', node: '>=22.0.0'} + + '@prisma/studio-core@0.33.0': + resolution: {integrity: sha512-V2fX/nKEymNTrHXwfP26PGjoLStO35Ogu+ex7CFJbLrMYEcZxxZpiSNOs7px23Hk5mzLWvM5RsqG6Ka+rha+wg==} + engines: {node: ^20.19 || ^22.12 || >=24.0, pnpm: '8'} peerDependencies: '@types/react': ^18.0.0 || ^19.0.0 react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} + + '@protobufjs/eventemitter@1.1.1': + resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==} + + '@protobufjs/fetch@1.1.1': + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.2': + resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} + + '@quansync/fs@1.1.0': + resolution: {integrity: sha512-qAPG/t3HqML1TlN7sY/pTbEjzFVAKsMjNNMGheyDosro+kT4iw2KCUoHcVdmliwWjorm4elZbgNQyU2eD97eDg==} + + '@radix-ui/primitive@1.1.3': + resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==} + + '@radix-ui/react-compose-refs@1.1.2': + resolution: {integrity: sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-primitive@2.1.3': + resolution: {integrity: sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-slot@1.2.3': + resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-toggle@1.1.10': + resolution: {integrity: sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@radix-ui/react-use-controllable-state@1.2.2': + resolution: {integrity: sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-effect-event@0.0.2': + resolution: {integrity: sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@radix-ui/react-use-layout-effect@1.1.1': + resolution: {integrity: sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==} + peerDependencies: + '@types/react': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + + '@rolldown/binding-android-arm-eabi@1.2.13': + resolution: {integrity: sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.13': + resolution: {integrity: sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.13': + resolution: {integrity: sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.13': + resolution: {integrity: sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.13': + resolution: {integrity: sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + resolution: {integrity: sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.13': + resolution: {integrity: sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.13': + resolution: {integrity: sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.13': + resolution: {integrity: sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.13': + resolution: {integrity: sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.13': + resolution: {integrity: sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.13': + resolution: {integrity: sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.13': + resolution: {integrity: sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.13': + resolution: {integrity: sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.13': + resolution: {integrity: sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + '@rollup/plugin-commonjs@29.0.2': resolution: {integrity: sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==} engines: {node: '>=16.0.0 || 14 >= 14.17'} @@ -2207,30 +1952,31 @@ packages: cpu: [x64] os: [win32] - '@rtsao/scc@1.1.0': - resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@scalar/client-side-rendering@0.4.5': + resolution: {integrity: sha512-6dhBKaRecrrk2WyVLxrA8oyTiY+4zzhwf5OUjUyuyQXZHt/751QDf/TvW14p2osEaNELfY/gjtN8meX+UslFQw==} + engines: {node: '>=22'} - '@scarf/scarf@1.4.0': - resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} + '@scalar/helpers@0.15.0': + resolution: {integrity: sha512-eUnaVQ1EE2YFIVrPOQxVaUiVYZjM6Yg2Oh0yUI87pyI0ilH6jOLA6wIJVWP/AXLv5WnhsfJW33xlZcztozEZ2A==} + engines: {node: '>=22'} - '@sinclair/typebox@0.27.10': - resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} - - '@sinclair/typebox@0.34.48': - resolution: {integrity: sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==} - - '@sindresorhus/is@5.6.0': - resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} - engines: {node: '>=14.16'} + '@scalar/hono-api-reference@0.12.6': + resolution: {integrity: sha512-u5CXaHTz8K9OZP5Yk/HungHJc4sqtQ1Y4Hf3NdY1EYsrUrgtCKdDn8G2xLKP2u+8+FICeUHx6IjPjEn3BkCCKg==} + engines: {node: '>=22'} + peerDependencies: + hono: ^4.12.5 - '@sinonjs/commons@3.0.1': - resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + '@scalar/schemas@0.12.1': + resolution: {integrity: sha512-D/1h/ek2mCwZFOBHQQ8gqD/pQ6Dz5xwur3s6aCwA71AnDF8/Wh+nwUNyIz+H4iquYIq5AUQD02mRyhUE/nIqtg==} + engines: {node: '>=22'} - '@sinonjs/fake-timers@10.3.0': - resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@scalar/types@0.22.1': + resolution: {integrity: sha512-h8/oe1tG1UIPoAKETiOBtYpyoH7GW3mp4Yu3Znl1RWa2iYLWl7ZtnqJ2A+n5s7MvZEDAb33pt4W/eswB3VVr6Q==} + engines: {node: '>=22'} - '@sinonjs/fake-timers@13.0.5': - resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} + '@scalar/validation@0.6.5': + resolution: {integrity: sha512-t/dtbqesbOLsTusFI2kXfiFEQOiZC7+oAY+jZnE82Y64xLamo/1KrZpta8GkuAfIHyeOHOx5bDFid04eO13MIg==} + engines: {node: '>=20'} '@skeletonlabs/skeleton-common@4.15.2': resolution: {integrity: sha512-y7KZn++Av8UHdoeaaguQ7zIS1HlK7Y5jyPDnHy65wJ60iS97fMtQV0kGhqVoYCWhor+xrjbAFjWtaPOPPDEMYA==} @@ -2245,8 +1991,65 @@ packages: peerDependencies: tailwindcss: ^4.0.0 - '@so-ric/colorspace@1.1.6': - resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==} + '@standard-community/standard-json@0.3.6': + resolution: {integrity: sha512-tuXKz1Ps4al0W4xhfwii7v4lskKtOv3QE7mcouRVThrBdOR6JzY4Vea3nsxcEnte84bOJvMvXGmOMWE3IBbHyA==} + peerDependencies: + '@standard-schema/spec': ^1.0.0 + '@types/json-schema': ^7.0.15 + '@valibot/to-json-schema': ^1.3.0 + arktype: ^2.1.20 + effect: ^3.20.0 + sury: ^10.0.0 + typebox: ^1.0.17 + valibot: ^1.4.2 + zod: ^3.25.0 || ^4.0.0 + zod-to-json-schema: ^3.24.5 + peerDependenciesMeta: + '@valibot/to-json-schema': + optional: true + arktype: + optional: true + effect: + optional: true + sury: + optional: true + typebox: + optional: true + valibot: + optional: true + zod: + optional: true + zod-to-json-schema: + optional: true + + '@standard-community/standard-openapi@0.2.10': + resolution: {integrity: sha512-whaCN9eu5zv5gu6Kyeh5am/S3AyS1nqo57/wAxs/KPS7+94UhBUZmkIetmXzm22qIV0zMrHt3y+2VfjkbkYYTA==} + peerDependencies: + '@standard-community/standard-json': ^0.3.5 + '@standard-schema/spec': ^1.0.0 + arktype: ^2.1.20 + effect: ^3.20.0 + openapi-types: ^12.1.3 + sury: ^10.0.0 + typebox: ^1.0.0 + valibot: ^1.4.2 + zod: ^3.25.0 || ^4.0.0 + zod-openapi: ^4 + peerDependenciesMeta: + arktype: + optional: true + effect: + optional: true + sury: + optional: true + typebox: + optional: true + valibot: + optional: true + zod: + optional: true + zod-openapi: + optional: true '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -2301,103 +2104,9 @@ packages: svelte: ^5.0.0 vite: ^6.3.0 || ^7.0.0 - '@swc/cli@0.6.0': - resolution: {integrity: sha512-Q5FsI3Cw0fGMXhmsg7c08i4EmXCrcl+WnAxb6LYOLHw4JFFC3yzmx9LaXZ7QMbA+JZXbigU2TirI7RAfO0Qlnw==} - engines: {node: '>= 16.14.0'} - hasBin: true - peerDependencies: - '@swc/core': ^1.2.66 - chokidar: ^4.0.1 - peerDependenciesMeta: - chokidar: - optional: true - - '@swc/core-darwin-arm64@1.15.11': - resolution: {integrity: sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==} - engines: {node: '>=10'} - cpu: [arm64] - os: [darwin] - - '@swc/core-darwin-x64@1.15.11': - resolution: {integrity: sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==} - engines: {node: '>=10'} - cpu: [x64] - os: [darwin] - - '@swc/core-linux-arm-gnueabihf@1.15.11': - resolution: {integrity: sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==} - engines: {node: '>=10'} - cpu: [arm] - os: [linux] - - '@swc/core-linux-arm64-gnu@1.15.11': - resolution: {integrity: sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - libc: [glibc] - - '@swc/core-linux-arm64-musl@1.15.11': - resolution: {integrity: sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==} - engines: {node: '>=10'} - cpu: [arm64] - os: [linux] - libc: [musl] - - '@swc/core-linux-x64-gnu@1.15.11': - resolution: {integrity: sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - libc: [glibc] - - '@swc/core-linux-x64-musl@1.15.11': - resolution: {integrity: sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==} - engines: {node: '>=10'} - cpu: [x64] - os: [linux] - libc: [musl] - - '@swc/core-win32-arm64-msvc@1.15.11': - resolution: {integrity: sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==} - engines: {node: '>=10'} - cpu: [arm64] - os: [win32] - - '@swc/core-win32-ia32-msvc@1.15.11': - resolution: {integrity: sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==} - engines: {node: '>=10'} - cpu: [ia32] - os: [win32] - - '@swc/core-win32-x64-msvc@1.15.11': - resolution: {integrity: sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==} - engines: {node: '>=10'} - cpu: [x64] - os: [win32] - - '@swc/core@1.15.11': - resolution: {integrity: sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==} - engines: {node: '>=10'} - peerDependencies: - '@swc/helpers': '>=0.5.17' - peerDependenciesMeta: - '@swc/helpers': - optional: true - - '@swc/counter@0.1.3': - resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} - '@swc/helpers@0.5.18': resolution: {integrity: sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ==} - '@swc/types@0.1.25': - resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} - - '@szmarczak/http-timer@5.0.1': - resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} - engines: {node: '>=14.16'} - '@tailwindcss/node@4.3.1': resolution: {integrity: sha512-6NDaqRoAMSXD1mr/RXu0HBvNE9a2n5tHPsxu9XHLws8o4Twes5rBM2205SUUiJ9goAtadrN6xTGX0UDEwp/N4A==} @@ -2492,67 +2201,65 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 - '@tokenizer/inflate@0.2.7': - resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==} - engines: {node: '>=18'} - - '@tokenizer/inflate@0.4.1': - resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} - engines: {node: '>=18'} - - '@tokenizer/token@0.3.0': - resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - - '@tsconfig/node10@1.0.12': - resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} - - '@tsconfig/node12@1.0.11': - resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} - - '@tsconfig/node14@1.0.3': - resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} - - '@tsconfig/node16@1.0.4': - resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} - - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@testcontainers/postgresql@12.2.0': + resolution: {integrity: sha512-14oNBbKdqIkWTiw8XwP6YqWnuBebiij8m4fF03WTSHvNt5FfvQpGTLwIV3p07UpDnqWRFvY50YFzbiYdB+SWuA==} - '@types/babel__core@7.20.5': - resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} - - '@types/babel__generator@7.27.0': - resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} - - '@types/babel__template@7.4.4': - resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} - - '@types/babel__traverse@7.28.0': - resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} - '@types/cookiejar@2.1.5': - resolution: {integrity: sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q==} + '@types/d3-array@3.0.3': + resolution: {integrity: sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==} '@types/d3-array@3.2.2': resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + '@types/d3-color@3.1.0': + resolution: {integrity: sha512-HKuicPHJuvPgCD+np6Se9MQvS6OCbJmOjGvylzMJRlDwUXjKTTXs6Pwgk79O09Vj/ho3u1ofXnhFOaEWWPrlwA==} + '@types/d3-contour@3.0.6': resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + '@types/d3-delaunay@6.0.1': + resolution: {integrity: sha512-tLxQ2sfT0p6sxdG75c6f/ekqxjyYR0+LwPrsO1mbC9YDBzPJhs2HbJJRrn8Ez1DBoHRo2yx7YEATI+8V1nGMnQ==} + + '@types/d3-format@3.0.1': + resolution: {integrity: sha512-5KY70ifCCzorkLuIkDe0Z9YTf9RR2CjBX1iaJG+rgM/cPP+sO+q9YdQ9WdhQcgPj1EQiJ2/0+yUkkziTG6Lubg==} + + '@types/d3-geo@3.1.0': + resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==} + + '@types/d3-interpolate@3.0.1': + resolution: {integrity: sha512-jx5leotSeac3jr0RePOH1KdR9rISG91QIE4Q2PYTu4OymLTZfA3SrnURSLzKH48HmXVUru50b8nje4E79oQSQw==} + '@types/d3-path@3.1.1': resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + '@types/d3-scale@4.0.2': + resolution: {integrity: sha512-Yk4htunhPAwN0XGlIwArRomOjdoBFXC3+kCxK2Ubg7I9shQlVSJy/pG/Ht5ASN+gdMIalpk8TJ5xV74jFsetLA==} + + '@types/d3-shape@3.1.7': + resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==} + '@types/d3-shape@3.1.8': resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} - '@types/eslint-scope@3.7.7': - resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + '@types/d3-time-format@2.1.0': + resolution: {integrity: sha512-/myT3I7EwlukNOX2xVdMzb8FRgNzRMpsZddwst9Ld/VFe6LyJyRp0s32l/V9XoUzk+Gqu56F/oGk6507+8BxrA==} + + '@types/d3-time@3.0.0': + resolution: {integrity: sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - '@types/eslint@9.6.1': - resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + '@types/docker-modem@3.0.6': + resolution: {integrity: sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==} + + '@types/dockerode@4.0.2': + resolution: {integrity: sha512-hA4myZ0XzwHG/p/eCLElYsQS3y1XZfvi6AfLFKVp1SNpPkO6J3xLatacAFVkReTxXRoIa3eHJmhJi9w6I3+zNA==} '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -2560,50 +2267,26 @@ packages: '@types/geojson@7946.0.16': resolution: {integrity: sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==} - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - - '@types/http-cache-semantics@4.2.0': - resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} - - '@types/istanbul-lib-coverage@2.0.6': - resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - - '@types/istanbul-lib-report@3.0.3': - resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} - - '@types/istanbul-reports@3.0.4': - resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - - '@types/jest@30.0.0': - resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==} - '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/json5@0.0.29': - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - - '@types/jsonwebtoken@9.0.10': - resolution: {integrity: sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA==} - - '@types/methods@1.1.4': - resolution: {integrity: sha512-ymXWVrDiCxTBE3+RIrrP533E70eA+9qu7zdWoHuOmGujkYtzf4HQF96b8nwHLqhuf4ykX61IGRIB38CC6/sImQ==} - - '@types/mocha@10.0.10': - resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} - - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/lodash@4.17.25': + resolution: {integrity: sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==} '@types/node@12.20.55': resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + '@types/node@18.19.130': + resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + '@types/node@22.19.11': resolution: {integrity: sha512-BH7YwL6rA93ReqeQS1c4bsPpcfOmJasG+Fkr6Y59q83f9M1WcBRHR2vM+P9eOisYRcN3ujQoiZY8uk5W+1WL8w==} - '@types/pg@8.16.0': - resolution: {integrity: sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==} + '@types/node@26.6.3': + resolution: {integrity: sha512-dsqMQQoeTLqu9wynDD00q573mNzso3IdQOAfHRJqLCcmCFPoGo9A1bDpUcv/9tnKpErQWv9uKeGfl37EIS02Yg==} + + '@types/pg@8.23.1': + resolution: {integrity: sha512-fKVHpikPdg4GKks3JuLEhvwSyvwzF23hnabPy6DD8ljVbC7+6J5dQzdv4arV6jqq57djnMgs1HKBxX4P8aBI3A==} '@types/react@19.2.11': resolution: {integrity: sha512-tORuanb01iEzWvMGVGv2ZDhYZVeRMrw453DCSAIn/5yvcSVnMoUMTyf33nQJLahYEnv9xqrTNbgz4qY5EfSh0g==} @@ -2611,285 +2294,276 @@ packages: '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - '@types/stack-utils@2.0.3': - resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} - - '@types/superagent@8.1.9': - resolution: {integrity: sha512-pTVjI73witn+9ILmoJdajHGW2jkSaOzhiFYF1Rd3EQ94kymLqB9PjD9ISg7WaALC7+dCHT0FGe9T2LktLq/3GQ==} + '@types/ssh2-streams@0.1.13': + resolution: {integrity: sha512-faHyY3brO9oLEA0QlcO8N2wT7R0+1sHWZvQ+y3rMLwdY1ZyS1z0W3t65j9PqT4HmQ6ALzNe7RZlNuCNE0wBSWA==} - '@types/supertest@6.0.3': - resolution: {integrity: sha512-8WzXq62EXFhJ7QsH3Ocb/iKQ/Ty9ZVWnVzoTKc9tyyFRRF3a74Tk2+TLFgaFFw364Ere+npzHKEJ6ga2LzIL7w==} + '@types/ssh2@0.5.52': + resolution: {integrity: sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg==} - '@types/triple-beam@1.3.5': - resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + '@types/ssh2@1.15.6': + resolution: {integrity: sha512-oGdxhBqcRTwSTKFm+9EiKzkNVYRLEFkcW44lhguvBalGJbWfGnDt/ezwSUZc+SF9m9bMc3VyklNAtp7zICjS5w==} '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - '@types/validator@13.15.10': - resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} - - '@types/yargs-parser@21.0.3': - resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - - '@types/yargs@17.0.35': - resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} - - '@typescript-eslint/eslint-plugin@8.56.0': - resolution: {integrity: sha512-lRyPDLzNCuae71A3t9NEINBiTn7swyOhvUj3MyUOxb8x6g6vPEFoOU+ZRmGMusNC3X3YMhqMIX7i8ShqhT74Pw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - '@typescript-eslint/parser': ^8.56.0 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/parser@8.56.0': - resolution: {integrity: sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==} - 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.0.0' - - '@typescript-eslint/project-service@8.56.0': - resolution: {integrity: sha512-M3rnyL1vIQOMeWxTWIW096/TtVP+8W3p/XnaFflhmcFp+U4zlxUxWj4XwNs6HbDeTtN4yun0GNTTDBw/SvufKg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/scope-manager@8.56.0': - resolution: {integrity: sha512-7UiO/XwMHquH+ZzfVCfUNkIXlp/yQjjnlYUyYz7pfvlK3/EyyN6BK+emDmGNyQLBtLGaYrTAI6KOw8tFucWL2w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/tsconfig-utils@8.56.0': - resolution: {integrity: sha512-bSJoIIt4o3lKXD3xmDh9chZcjCz5Lk8xS7Rxn+6l5/pKrDpkCwtQNQQwZ2qRPk7TkUYhrq3WPIHXOXlbXP0itg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/type-utils@8.56.0': - resolution: {integrity: sha512-qX2L3HWOU2nuDs6GzglBeuFXviDODreS58tLY/BALPC7iu3Fa+J7EOTwnX9PdNBxUI7Uh0ntP0YWGnxCkXzmfA==} - 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.0.0' - '@typescript-eslint/types@8.56.0': resolution: {integrity: sha512-DBsLPs3GsWhX5HylbP9HNG15U0bnwut55Lx12bHB9MpXxQ+R5GC8MwQe+N1UFXxAeQDvEsEDY6ZYwX03K7Z6HQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.56.0': - resolution: {integrity: sha512-ex1nTUMWrseMltXUHmR2GAQ4d+WjkZCT4f+4bVsps8QEdh0vlBsaCokKTPlnqBFqqGaxilDNJG7b8dolW2m43Q==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/utils@8.56.0': - resolution: {integrity: sha512-RZ3Qsmi2nFGsS+n+kjLAYDPVlrzf7UhTffrDIKr+h2yzAlYP/y5ZulU0yeDEPItos2Ph46JAL5P/On3pe7kDIQ==} - 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.0.0' - - '@typescript-eslint/visitor-keys@8.56.0': - resolution: {integrity: sha512-q+SL+b+05Ud6LbEE35qe4A99P+htKTKVbyiNEe45eCbJFyh/HVK9QXwlrbz+Q4L8SOW4roxSVwXYj4DMBT7Ieg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@ungap/structured-clone@1.3.0': - resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} - - '@unrs/resolver-binding-android-arm-eabi@1.11.1': - resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} - cpu: [arm] - os: [android] - - '@unrs/resolver-binding-android-arm64@1.11.1': - resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} - cpu: [arm64] - os: [android] + '@typescript/typescript-aix-ppc64@7.0.2': + resolution: {integrity: sha512-MTKKkWB7p/0E9xi1d1tHtZ5PiLkGEMIq88pK2CubZjOsLtYTLqhgIgi6zepFa+9GHZ6h05NMCkQxGKiPXMxXtQ==} + engines: {node: '>=16.20.0'} + cpu: [ppc64] + os: [aix] - '@unrs/resolver-binding-darwin-arm64@1.11.1': - resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + '@typescript/typescript-darwin-arm64@7.0.2': + resolution: {integrity: sha512-gowzar9MwS/aRWp6f3a4KUqzRjAZjOsmGNCM6LcTgXum+dBfgsBVMN+AgvOCCbguXyick6LJhpBszxMebJ8syA==} + engines: {node: '>=16.20.0'} cpu: [arm64] os: [darwin] - '@unrs/resolver-binding-darwin-x64@1.11.1': - resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + '@typescript/typescript-darwin-x64@7.0.2': + resolution: {integrity: sha512-SZ9xZInqApNlNGc9s0W1VSsktYSOe9cFqNOIqmN1Gs8SmkjKZYFt017G4VwPxASInODuAdbTW7sXiFUf893RgA==} + engines: {node: '>=16.20.0'} cpu: [x64] os: [darwin] - '@unrs/resolver-binding-freebsd-x64@1.11.1': - resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + '@typescript/typescript-freebsd-arm64@7.0.2': + resolution: {integrity: sha512-W5NH4y/J0plIIS5b2xvTEkU7JFxyqdMAOgf+Ilhl0vHQXKO5dZoxd+C/jEtq56c4F3wk71RB4BMRQ2XdI+bwYQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [freebsd] + + '@typescript/typescript-freebsd-x64@7.0.2': + resolution: {integrity: sha512-UMGDx5sTpzNw3WiPebH7l90IWfJggEd+egHt/q6p7/Cm3zqoV7VxkGXt+3DxPIw8CcmvAB0j3sVVfbhX+M4Tpw==} + engines: {node: '>=16.20.0'} cpu: [x64] os: [freebsd] - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': - resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} - cpu: [arm] + '@typescript/typescript-linux-arm64@7.0.2': + resolution: {integrity: sha512-Qh4eU4/y3yDjnfjjyPYihMj5/ODIlmt+Bzu17OI+fiSRDW57QmU5SiN63exPRNJPKUzcc1INa1NXdrJ+MqHjUQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] os: [linux] - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': - resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + '@typescript/typescript-linux-arm@7.0.2': + resolution: {integrity: sha512-gffT3xPz9sR7j/YJExkyPntrI0P2EP9XbOyWzth2/Gs0RstK+90RBcO0ncXoXy/beYll1SXw846Nf2zdnEz0QQ==} + engines: {node: '>=16.20.0'} cpu: [arm] os: [linux] - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': - resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} - cpu: [arm64] + '@typescript/typescript-linux-loong64@7.0.2': + resolution: {integrity: sha512-uEHck9i8hoAzXPiYRib1O7miOnz23SxIeVl6F4LXox+qov1K35jHcEW6VHKvZI+pyvl7fZEP4MCU5LYvIq1GuQ==} + engines: {node: '>=16.20.0'} + cpu: [loong64] os: [linux] - libc: [glibc] - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': - resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} - cpu: [arm64] + '@typescript/typescript-linux-mips64el@7.0.2': + resolution: {integrity: sha512-R4KvAMnE43W5Qeqb0Ly56O3mWMWIAgsMyz36DCaycd5nbg/9kzm0liw3JocfRqyJY0KPmzFjbswozXyW0DnIYA==} + engines: {node: '>=16.20.0'} + cpu: [mips64el] os: [linux] - libc: [musl] - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': - resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + '@typescript/typescript-linux-ppc64@7.0.2': + resolution: {integrity: sha512-DORx5b3sd/4S7eayxm4FQv+A7CrkUIGRaHiwI8oiHTAI1fAPWhF4J0vAlkC8biAlHSVVwxMQ3tjZ2/DVbnQiiA==} + engines: {node: '>=16.20.0'} cpu: [ppc64] os: [linux] - libc: [glibc] - - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': - resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': - resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + '@typescript/typescript-linux-riscv64@7.0.2': + resolution: {integrity: sha512-wf0jqEDOjrPRnKwYRyyJDRo11KMbvMFrU+q4zqKyChODBzvlkbhNQfKvLxQCcwTpdDaXSHZTVuh0JoCrKCUMHQ==} + engines: {node: '>=16.20.0'} cpu: [riscv64] os: [linux] - libc: [musl] - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + '@typescript/typescript-linux-s390x@7.0.2': + resolution: {integrity: sha512-IkwJc3L7yhytWd/ewjyxNDfOmswCm9GWMJT/ue/dU4aZNbwZeYAetq42VyLmsmSjvoX7z74X6ZaYCtzAr0EuGw==} + engines: {node: '>=16.20.0'} cpu: [s390x] os: [linux] - libc: [glibc] - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + '@typescript/typescript-linux-x64@7.0.2': + resolution: {integrity: sha512-EYdf2cNg7rgCWJnxCdJ+F3V39O8ihb37eHAu1LK8oAFizgTQbPOK7zHHXbPt8rX24COqODXeI3sIf0fCXG7H/A==} + engines: {node: '>=16.20.0'} cpu: [x64] os: [linux] - libc: [glibc] - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} - cpu: [x64] - os: [linux] - libc: [musl] + '@typescript/typescript-netbsd-arm64@7.0.2': + resolution: {integrity: sha512-+polYF4MF04aPpO5FTkHran9yUQDSXqy5GiSDKpsll5jy3l3+g9QLhpf39T+ePtefhXLOGrLl0QIjkQP6VnelA==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [netbsd] - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] + '@typescript/typescript-netbsd-x64@7.0.2': + resolution: {integrity: sha512-8YIT0EHM/3dq10ZOVF/A7pc/YSMtbcecct4rWtexrnSCHOPcpC2KTLXfTCR6vDpnSiY12heNb1GiN/wu+T/FyA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [netbsd] - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + '@typescript/typescript-openbsd-arm64@7.0.2': + resolution: {integrity: sha512-APT8+ClYnuYm1u9+kgGXoMj2VzWzcymwh2gNSQVySHfkRDGOTVkoWLjCmOQSaO+PoqQ57B0flRp9SA+7GnnkzQ==} + engines: {node: '>=16.20.0'} cpu: [arm64] - os: [win32] + os: [openbsd] - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} - cpu: [ia32] + '@typescript/typescript-openbsd-x64@7.0.2': + resolution: {integrity: sha512-yX7s+Q0Dln0Dt9tEzZsAjXXR/+ytBM7AlglaqyeMPxQszJ1JhlJdZ6jLA+IzldHtflX81em7lDao1xXu+aRRkg==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [openbsd] + + '@typescript/typescript-sunos-x64@7.0.2': + resolution: {integrity: sha512-dLJDGaLZ1D4HPQn62u1n8mBDkJREwMsAkCdkwd4Ieqw+x3TUyTsqY0YiBCtE6H6OzzgGk3iuZ3vFWRS+E8/d1g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [sunos] + + '@typescript/typescript-win32-arm64@7.0.2': + resolution: {integrity: sha512-Gyl1Vy6OsWesLzmq+EP0Fb7b4Nid5232AvcA2SFcdYreldpNtYFFofPjnt62y9hQy7VTaZp65ICJjuAQRaVcIQ==} + engines: {node: '>=16.20.0'} + cpu: [arm64] os: [win32] - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + '@typescript/typescript-win32-x64@7.0.2': + resolution: {integrity: sha512-0BQ3HkAHHlKLSp1qRvf3SUhGpGsDuhB/jgFw75guyqbxJqEaS0Cw/VFO8i2nHglJUzQCRtMMR/IBAKE3ETMC4g==} + engines: {node: '>=16.20.0'} cpu: [x64] os: [win32] - '@webassemblyjs/ast@1.14.1': - resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + '@visx/curve@4.0.1-alpha.0': + resolution: {integrity: sha512-jRu61Uz274pV1zyioXmboyrLutYbnKsgjj4njSGCnhdXj5GkZvZbg+ThDb6oOzoAnJOBRLz4rzPlWvNJOzuVMg==} - '@webassemblyjs/floating-point-hex-parser@1.13.2': - resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + '@visx/event@4.0.1-alpha.0': + resolution: {integrity: sha512-EQqCMSv/s8NbFjo+hz3FKsvvYfP+2QslsFJ/24/O5l/W+7UC6J6aAvO0ujVwrTwdYbuQ+vhxKi1xdPdKR/qj1g==} - '@webassemblyjs/helper-api-error@1.13.2': - resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + '@visx/grid@4.0.1-alpha.0': + resolution: {integrity: sha512-rycutGmTHO+znNdPumheWMglm7YfpffvRwUkVy5zy4WoORIuKTMkDxwnOzHG2xMxU3EE/YCd37xFV5AxA30yeg==} + peerDependencies: + react: ^16.14.0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0 - '@webassemblyjs/helper-buffer@1.14.1': - resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + '@visx/group@4.0.1-alpha.0': + resolution: {integrity: sha512-V19l7iQ7jccBv8kao/EByuI6o4xtxzzLV9nqVI1hRvmdzTVsuLpqlwzYCZUXJaTVvUWf8s4D2SQFjGkj/Nw+0w==} + peerDependencies: + react: ^16.14.0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0 - '@webassemblyjs/helper-numbers@1.13.2': - resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + '@visx/point@4.0.1-alpha.0': + resolution: {integrity: sha512-ijTfr/Nx09f03vIj9nyTr3z4Xth4Y75427UaogJh6dnIRLMEFHQOwNu791sbfiNj0a+ZXuaE32h0vKrFe4/8Qg==} - '@webassemblyjs/helper-wasm-bytecode@1.13.2': - resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + '@visx/responsive@4.0.1-alpha.0': + resolution: {integrity: sha512-o+1zGywQZY0+yOx3Iw87wc4bbPJRr/HnIukTwfOz4UVyj9pB1OQNVHB7OORO1+LBHJceWpB31co/ZV9KHncKrA==} + peerDependencies: + react: ^16.14.0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0 - '@webassemblyjs/helper-wasm-section@1.14.1': - resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + '@visx/scale@4.0.1-alpha.0': + resolution: {integrity: sha512-nzjeE87vFSAXGWFiiNfBpNLAf0Q8Qmf6syvKLjqNi4kGZkdhbUll3E/59YsgWXmjM8+llPLWzGsP+JPvo5eq1A==} - '@webassemblyjs/ieee754@1.13.2': - resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + '@visx/shape@4.0.1-alpha.0': + resolution: {integrity: sha512-62QeiVNmPlterQGwhkEDcbq7M0MqY0lBsK5QKXtM9ZoPZWkuGV3aykA3+Xu20B2FAvyJq4LqJzBc7Sxr+EAdbA==} + peerDependencies: + react: ^16.14.0 || ^17.0.0-0 || ^18.0.0-0 || ^19.0.0-0 - '@webassemblyjs/leb128@1.13.2': - resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + '@visx/vendor@4.0.0-alpha.0': + resolution: {integrity: sha512-6I+MuqXBcv9jnlcVowHoHKSdk9gXTWkHLKyqBwRWg7LY6A3Ei8SHfubpqGV5rBUSppxMq2RszPJUS6w+H0YgmQ==} - '@webassemblyjs/utf8@1.13.2': - resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + '@vitest/coverage-v8@5.0.3': + resolution: {integrity: sha512-+klsyz7BvT1vCU28Zkfzms1Ia78XD0V41U3FUtRaa3S+vOr/EXvK1O6BvVD7l1RzEjm6SONR2aybOvDDf9u0mQ==} + peerDependencies: + '@vitest/browser': 5.0.3 + vitest: 5.0.3 + peerDependenciesMeta: + '@vitest/browser': + optional: true - '@webassemblyjs/wasm-edit@1.14.1': - resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + '@vitest/istanbul-lib-coverage@1.0.2': + resolution: {integrity: sha512-9J/JMwOf9AoJhAywhrn7ScKTL38hsWQP/qPG60OtaAFcQ5OXPwKsxZFlbnuCKmZ61m8/lGgHYnFpdyQZUvG/iA==} + engines: {node: '>=22'} - '@webassemblyjs/wasm-gen@1.14.1': - resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + '@vitest/istanbul-lib-report@1.0.2': + resolution: {integrity: sha512-gUsfXZJbzPamoIY5TvHFiMMoXESBrUMo+xqaj+rYrWI69+EnvRlYBlP96ZnHPY4vX8kyUpgAnFUCg5wZG/HkDQ==} + engines: {node: '>=22'} - '@webassemblyjs/wasm-opt@1.14.1': - resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + '@vitest/mocker@5.0.3': + resolution: {integrity: sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true - '@webassemblyjs/wasm-parser@1.14.1': - resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + '@vitest/spy@5.0.3': + resolution: {integrity: sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==} - '@webassemblyjs/wast-printer@1.14.1': - resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + '@yuku-core/binding-android-arm64@0.18.1': + resolution: {integrity: sha512-1XTUWTmnpwXNyPwRLSQDjvHu7WPgykzCniYtTk+5ppnriznVONWd9TRPcFxCR8dlZ7HFGtv8v1wzbQmtmVlHNQ==} + cpu: [arm64] + os: [android] - '@xhmikosr/archive-type@7.1.0': - resolution: {integrity: sha512-xZEpnGplg1sNPyEgFh0zbHxqlw5dtYg6viplmWSxUj12+QjU9SKu3U/2G73a15pEjLaOqTefNSZ1fOPUOT4Xgg==} - engines: {node: '>=18'} + '@yuku-core/binding-darwin-arm64@0.18.1': + resolution: {integrity: sha512-7A7IPB/kEzIlm9Lwj6qVQ3ZORUH96mpqDWgGxkjmaAWGAfV4roTZWN+o7bW22BzcW55xbUKcZRslSZ8WRyqdQw==} + cpu: [arm64] + os: [darwin] - '@xhmikosr/bin-check@7.1.0': - resolution: {integrity: sha512-y1O95J4mnl+6MpVmKfMYXec17hMEwE/yeCglFNdx+QvLLtP0yN4rSYcbkXnth+lElBuKKek2NbvOfOGPpUXCvw==} - engines: {node: '>=18'} + '@yuku-core/binding-darwin-x64@0.18.1': + resolution: {integrity: sha512-aBZgmsAf1u/ps042xE9pgH9zOY57Rn0K8BXOWjQ2dAIg4W5nyQ/Oo3U3+VAcaEeBt6Q/XCwnCUpshFpWQaOCrw==} + cpu: [x64] + os: [darwin] - '@xhmikosr/bin-wrapper@13.2.0': - resolution: {integrity: sha512-t9U9X0sDPRGDk5TGx4dv5xiOvniVJpXnfTuynVKwHgtib95NYEw4MkZdJqhoSiz820D9m0o6PCqOPMXz0N9fIw==} - engines: {node: '>=18'} + '@yuku-core/binding-freebsd-x64@0.18.1': + resolution: {integrity: sha512-yOEEjmEW2XQWpoa+4J3+eVMhXd/4kMTXoLJ9WkhXMMeRpKGBtFGjX2uxV6qKuoti3talOnmMdi2/kvqkX+O4wQ==} + cpu: [x64] + os: [freebsd] - '@xhmikosr/decompress-tar@8.1.0': - resolution: {integrity: sha512-m0q8x6lwxenh1CrsTby0Jrjq4vzW/QU1OLhTHMQLEdHpmjR1lgahGz++seZI0bXF3XcZw3U3xHfqZSz+JPP2Gg==} - engines: {node: '>=18'} + '@yuku-core/binding-linux-arm-gnu@0.18.1': + resolution: {integrity: sha512-klpvuNubx19bsox50+ioEYfvwUj/+O6ML9YBDjzsz9PULffyOYxkR+i63BYvg//jAcEE9oHIQphm2Wz3vmk1TA==} + cpu: [arm] + os: [linux] + libc: [glibc] - '@xhmikosr/decompress-tarbz2@8.1.0': - resolution: {integrity: sha512-aCLfr3A/FWZnOu5eqnJfme1Z1aumai/WRw55pCvBP+hCGnTFrcpsuiaVN5zmWTR53a8umxncY2JuYsD42QQEbw==} - engines: {node: '>=18'} + '@yuku-core/binding-linux-arm-musl@0.18.1': + resolution: {integrity: sha512-eUG20Eh3Ycrm2D5WvRIn7BJp1+iPiFL0zLDdavVM5B6ymYEEmgrs6mime/h2y4Is1GA9uGyBBJQHaqKTcRiEng==} + cpu: [arm] + os: [linux] + libc: [musl] - '@xhmikosr/decompress-targz@8.1.0': - resolution: {integrity: sha512-fhClQ2wTmzxzdz2OhSQNo9ExefrAagw93qaG1YggoIz/QpI7atSRa7eOHv4JZkpHWs91XNn8Hry3CwUlBQhfPA==} - engines: {node: '>=18'} + '@yuku-core/binding-linux-arm64-gnu@0.18.1': + resolution: {integrity: sha512-og2/svnJ2Awjz4INj2lQh0KQMwy4FrVCtD5SgfoZNxdv5knG6XdIyIvZycRCeyk15AkHdhwJqCsHJFcB3tjTxg==} + cpu: [arm64] + os: [linux] + libc: [glibc] - '@xhmikosr/decompress-unzip@7.1.0': - resolution: {integrity: sha512-oqTYAcObqTlg8owulxFTqiaJkfv2SHsxxxz9Wg4krJAHVzGWlZsU8tAB30R6ow+aHrfv4Kub6WQ8u04NWVPUpA==} - engines: {node: '>=18'} + '@yuku-core/binding-linux-arm64-musl@0.18.1': + resolution: {integrity: sha512-dmkidtxAY3iSUOFAOwnp7w8nVx1s9QdSdyiJPVw0TkBlLhQySuQer3Pir3tmhIhHC+Oc2Bn0f0QQpFNAMvzTPQ==} + cpu: [arm64] + os: [linux] + libc: [musl] - '@xhmikosr/decompress@10.2.0': - resolution: {integrity: sha512-MmDBvu0+GmADyQWHolcZuIWffgfnuTo4xpr2I/Qw5Ox0gt+e1Be7oYqJM4te5ylL6mzlcoicnHVDvP27zft8tg==} - engines: {node: '>=18'} + '@yuku-core/binding-linux-x64-gnu@0.18.1': + resolution: {integrity: sha512-eXAZacTOzJbzv6sT/4h03MBE4DNGObfuTg3L6+FGADFt8Sam7peyhaFAekQIwvLETX3WYXhMwTehKPB69sdmcA==} + cpu: [x64] + os: [linux] + libc: [glibc] - '@xhmikosr/downloader@15.2.0': - resolution: {integrity: sha512-lAqbig3uRGTt0sHNIM4vUG9HoM+mRl8K28WuYxyXLCUT6pyzl4Y4i0LZ3jMEsCYZ6zjPZbO9XkG91OSTd4si7g==} - engines: {node: '>=18'} + '@yuku-core/binding-linux-x64-musl@0.18.1': + resolution: {integrity: sha512-mdeItxbo5No5ht5XdHh0mCHDBne/STUuzphzGQQxVX+XSsBPbUHsZkmUAahycR6RoEP2UF/YBhg1M5f0phBO9A==} + cpu: [x64] + os: [linux] + libc: [musl] - '@xhmikosr/os-filter-obj@3.0.0': - resolution: {integrity: sha512-siPY6BD5dQ2SZPl3I0OZBHL27ZqZvLEosObsZRQ1NUB8qcxegwt0T9eKtV96JMFQpIz1elhkzqOg4c/Ri6Dp9A==} - engines: {node: ^14.14.0 || >=16.0.0} + '@yuku-core/binding-win32-arm64@0.18.1': + resolution: {integrity: sha512-0CyeB03Lr/QV9XHGyuChJ3V99X9M/6Q+3JB3ZRJWjqs13G1qIeIiHwsaCfqIJsqei9wxBtaKWZ1vBU7ApQfMEA==} + cpu: [arm64] + os: [win32] - '@xtuc/ieee754@1.2.0': - resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + '@yuku-core/binding-win32-x64@0.18.1': + resolution: {integrity: sha512-p0zG4bkR4++W011YbcP7Thg0UunaX9Lfg6U3nHEEwLrvTNy4P0+I5GO762tdjLozZpZwWLV/HmYNeecyOS2y5g==} + cpu: [x64] + os: [win32] - '@xtuc/long@4.2.2': - resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + '@yuku-toolchain/types@0.18.1': + resolution: {integrity: sha512-rWtqVdjA8O34nV/4mBFIdUm5Zj+FIzZDR7P2PEpqXXp53VEHabTROu7j2RjzzJbLMVYjW6gDKwOgPgiKRA+x4w==} '@zag-js/accordion@1.39.1': resolution: {integrity: sha512-GA3m7gRTm3weSe1eMlHIsTNztcjZ6joIaRgxxKil7q/UX0xIVVGDy0aCr6oo7FAuoMiOOBVurYXILpFZ30nOXA==} @@ -3042,65 +2716,11 @@ packages: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} - abstract-logging@2.0.1: - resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} - - accepts@2.0.0: - resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} - engines: {node: '>= 0.6'} - - acorn-import-phases@1.0.4: - resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} - engines: {node: '>=10.13.0'} - peerDependencies: - acorn: ^8.14.0 - - acorn-jsx@5.3.2: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn-walk@8.3.5: - resolution: {integrity: sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==} - engines: {node: '>=0.4.0'} - acorn@8.16.0: resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true - ajv-formats@2.1.1: - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - - ajv-formats@3.0.1: - resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - - ajv-keywords@3.5.2: - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 - - ajv-keywords@5.1.0: - resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} - peerDependencies: - ajv: ^8.8.2 - - ajv@6.14.0: - resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} - - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} @@ -3108,41 +2728,32 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} - ansi-escapes@4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + ansi-regex@6.4.0: + resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==} + engines: {node: '>=12'} + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - ansi-styles@5.2.0: - resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} - engines: {node: '>=10'} - - ansis@4.2.0: - resolution: {integrity: sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==} - engines: {node: '>=14'} - - anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} - - append-field@1.0.0: - resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} - arch@3.0.0: - resolution: {integrity: sha512-AmIAC+Wtm2AU8lGfTtHsw0Y9Qtftx2YXEEtiBP10xFUtMOA+sHHx6OAddyL52mUKh1vsXQ6/w1mVDptZCyUt4Q==} + archiver-utils@5.0.2: + resolution: {integrity: sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==} + engines: {node: '>= 14'} - arg@4.1.3: - resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + archiver@7.0.1: + resolution: {integrity: sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==} + engines: {node: '>= 14'} - argon2@0.44.0: - resolution: {integrity: sha512-zHPGN3S55sihSQo0dBbK0A5qpi2R31z7HZDZnry3ifOyj8bZZnpZND2gpmhnRGO1V/d555RwBqIK5W4Mrmv3ig==} + argon2@0.45.1: + resolution: {integrity: sha512-skm+/WCjkGqCQxF7FG1LuZXM5yvbFjgbfiCGsud2oLgaDhh6b6dbH0b1EkghbM+xx4Bj8Ape+KKgixoIlWZicQ==} engines: {node: '>=16.17.0'} argparse@1.0.10: @@ -3155,64 +2766,29 @@ packages: resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==} engines: {node: '>= 0.4'} - array-buffer-byte-length@1.0.2: - resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} - engines: {node: '>= 0.4'} - array-ify@1.0.0: resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - array-includes@3.1.9: - resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} - engines: {node: '>= 0.4'} - - array-timsort@1.0.3: - resolution: {integrity: sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==} - array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - array.prototype.findlastindex@1.2.6: - resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} - engines: {node: '>= 0.4'} - - array.prototype.flat@1.3.3: - resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} - engines: {node: '>= 0.4'} - - array.prototype.flatmap@1.3.3: - resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} - engines: {node: '>= 0.4'} + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - arraybuffer.prototype.slice@1.0.4: - resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} - engines: {node: '>= 0.4'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} - asap@2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + ast-v8-to-istanbul@1.0.7: + resolution: {integrity: sha512-kFL68AG6ajd8fg248zwM9GQrUWEp79gsmjum34OEXjs4yHuUMZfYKwOLW9GMmB4oNvVrj+EAGxsP7ye2UR9UlA==} - async-function@1.0.0: - resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} - engines: {node: '>= 0.4'} + async-lock@1.4.1: + resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - atomic-sleep@1.0.0: - resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} - engines: {node: '>=8.0.0'} - - available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} - - avvio@9.2.0: - resolution: {integrity: sha512-2t/sy01ArdHHE0vRH5Hsay+RtCZt3dLPji7W7/MMOCEgze5b7SNDC4j5H6FnVgPkI1MTNFGzHdHrVXDDl7QSSQ==} - aws-ssl-profiles@1.1.2: resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} engines: {node: '>= 6.0.0'} @@ -3221,124 +2797,80 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - b4a@1.8.0: - resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==} + b4a@1.9.0: + resolution: {integrity: sha512-dpfcF9fDNR6++cthXR67iyhgqWy9CBouAvIWhIntzBG6cvK/cnIPiZQjBwi/ZqjjBEDGfoNDtmB0kTjroOJ3pQ==} peerDependencies: react-native-b4a: '*' peerDependenciesMeta: react-native-b4a: optional: true - babel-jest@29.7.0: - resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@babel/core': ^7.8.0 - - babel-plugin-istanbul@6.1.1: - resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} - engines: {node: '>=8'} - - babel-plugin-istanbul@7.0.1: - resolution: {integrity: sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==} - engines: {node: '>=12'} - - babel-plugin-jest-hoist@29.6.3: - resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - babel-preset-current-node-syntax@1.2.0: - resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + bare-events@2.9.2: + resolution: {integrity: sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA==} peerDependencies: - '@babel/core': ^7.0.0 || ^8.0.0-0 + bare-abort-controller: '*' + peerDependenciesMeta: + bare-abort-controller: + optional: true - babel-preset-jest@29.6.3: - resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + bare-fs@4.8.4: + resolution: {integrity: sha512-MPC2eyrpbk3A873sK4y6rk+Iv4o2enxTjHZ8zH3HO0mjrpm5XjnguY2XmfidIsDV6vnjpbMBKUAJpV0ISD2SsQ==} + engines: {bare: '>=1.28.0'} peerDependencies: - '@babel/core': ^7.0.0 - - balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - - balanced-match@4.0.3: - resolution: {integrity: sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g==} - engines: {node: 20 || >=22} + bare-buffer: '*' + peerDependenciesMeta: + bare-buffer: + optional: true - balanced-match@4.0.4: - resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} - engines: {node: 18 || 20 || >=22} + bare-path@3.1.2: + resolution: {integrity: sha512-ZyKbsuuqK6Ag0K8pX6V5Txq6XeJRvY+wXucnFGRjiyVYP9YWDpIQugk/b+enRYrEYBJaqLzghRQpXPMR7341Nw==} - bare-events@2.8.2: - resolution: {integrity: sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==} + bare-stream@2.13.4: + resolution: {integrity: sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA==} peerDependencies: bare-abort-controller: '*' + bare-buffer: '*' + bare-events: '*' peerDependenciesMeta: bare-abort-controller: optional: true + bare-buffer: + optional: true + bare-events: + optional: true + + bare-url@2.5.4: + resolution: {integrity: sha512-Gxa7UVWBr0/edU1b+TJhn/AZvMQUj9OGspvYsaTYQrAbZA4BOTZGL3LiZxvD+CeMlDH4juwD84+eTAp/bLYW5g==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.0: - resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} - engines: {node: '>=6.0.0'} - hasBin: true + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} better-path-resolve@1.0.0: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} - bin-version-check@5.1.0: - resolution: {integrity: sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==} - engines: {node: '>=12'} - - bin-version@6.0.0: - resolution: {integrity: sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==} - engines: {node: '>=12'} + better-result@2.10.0: + resolution: {integrity: sha512-oQhh0y1qo2/ZKdAAEvHZAqKKiHOFU5k/bW96fE2ScgQOVkJRiHwB+nOS1SgFsYqRlxMDWvefXi9Q3px7QvgNDw==} bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - body-parser@2.3.0: - resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} - engines: {node: '>=18'} - - brace-expansion@1.1.12: - resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} - - brace-expansion@5.0.2: - resolution: {integrity: sha512-Pdk8c9poy+YhOgVWw1JNN22/HcivgKWwpxKq04M/jTmHyCZn12WPJebZxdjSa5TmBqISrUSgNYU3eRORljfCCw==} - engines: {node: 20 || >=22} - - brace-expansion@5.0.7: - resolution: {integrity: sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==} - engines: {node: 18 || 20 || >=22} + brace-expansion@2.1.7: + resolution: {integrity: sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.28.1: - resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - - bs-logger@0.2.6: - resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} - engines: {node: '>= 6'} - - bser@2.1.1: - resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} - - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - - buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + buffer-crc32@1.0.0: + resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==} + engines: {node: '>=8.0.0'} buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -3349,226 +2881,90 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} - busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} + buildcheck@0.0.7: + resolution: {integrity: sha512-lHblz4ahamxpTmnsk+MNTRWsjYKv965MwOrSJyeD588rR3Jcu7swE+0wN5F+PbL5cjgu/9ObkhfzEPuofEMwLA==} + engines: {node: '>=10.0.0'} - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} + byline@5.0.0: + resolution: {integrity: sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==} + engines: {node: '>=0.10.0'} - c12@3.1.0: - resolution: {integrity: sha512-uWoS8OU1MEIsOv8p/5a82c3H31LsWVR5qiyXVfBNOzfffjUWtPnhAb4BYI2uG2HfGmZmFjCtui5XNWaps+iFuw==} + c12@3.3.4: + resolution: {integrity: sha512-cM0ApFQSBXuourJejzwv/AuPRvAxordTyParRVcHjjtXirtkzM0uK2L9TTn9s0cXZbG7E55jCivRQzoxYmRAlA==} peerDependencies: - magicast: ^0.3.5 + magicast: '*' peerDependenciesMeta: magicast: optional: true - cacheable-lookup@7.0.0: - resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} - engines: {node: '>=14.16'} - - cacheable-request@10.2.14: - resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} - engines: {node: '>=14.16'} - - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - - call-bind@1.0.9: - resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} - engines: {node: '>= 0.4'} - - call-bound@1.0.4: - resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} - engines: {node: '>= 0.4'} + cac@7.0.1: + resolution: {integrity: sha512-86diuUyeeWM8CrqhpGCaDafrzjS1s++7sWy2AbAPoFNz/xKv7ID57CR4pZsMuGCh60PtsnEx4z68b+Vgt07VPw==} + engines: {node: '>=20.19.0'} callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - caniuse-lite@1.0.30001770: - resolution: {integrity: sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - - char-regex@1.0.2: - resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} - engines: {node: '>=10'} + chai@6.3.0: + resolution: {integrity: sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==} + engines: {node: '>=18'} chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} - chevrotain@10.5.0: - resolution: {integrity: sha512-Pkv5rBY3+CsHOYfV5g/Vs5JY9WTHHDEKOlohI2XeygaZhUeqhAlldZ8Hz9cRmxu709bvS08YzxHdTPHhffc13A==} - chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chrome-trace-event@1.0.4: - resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} - engines: {node: '>=6.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} - ci-info@4.4.0: - resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} - engines: {node: '>=8'} - - citty@0.1.6: - resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} - - citty@0.2.1: - resolution: {integrity: sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg==} - - cjs-module-lexer@1.4.3: - resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} - - class-transformer@0.5.1: - resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} - - class-validator@0.14.3: - resolution: {integrity: sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==} - - cli-cursor@3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - - cli-spinners@2.9.2: - resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} - engines: {node: '>=6'} - - cli-table3@0.6.5: - resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} - engines: {node: 10.* || >= 12.*} - - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} - clone@1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} - co@4.6.0: - resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} - engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} - - collect-v8-coverage@1.0.3: - resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==} - color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} - color-convert@3.1.3: - resolution: {integrity: sha512-fasDH2ont2GqF5HpyO4w0+BcewlhHEZOFn9c1ckZdHpJ56Qb7MHhH/IcJZbBGgvdtwdwNbLvxiBEdg336iA9Sg==} - engines: {node: '>=14.6'} - color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - color-name@2.1.0: - resolution: {integrity: sha512-1bPaDNFm0axzE4MEAzKPuqKWeRaT43U/hyxKPBdqTfmPF+d6n7FSoTFxLVULUJOmiLp01KjhIPPH+HrXZJN4Rg==} - engines: {node: '>=12.20'} - - color-string@2.1.4: - resolution: {integrity: sha512-Bb6Cq8oq0IjDOe8wJmi4JeNn763Xs9cfrBcaylK1tPypWzyoy2G3l90v9k64kjphl/ZJjPIShFztenRomi8WTg==} - engines: {node: '>=18'} - - color@5.0.3: - resolution: {integrity: sha512-ezmVcLR3xAVp8kYOm4GS45ZLLgIE6SPAFoduLr6hTDajwb3KZ2F46gulK3XpcwRFb5KKGCSezCBAY4Dw4HsyXA==} - engines: {node: '>=18'} - - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - commander@4.1.1: - resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} - engines: {node: '>= 6'} - - commander@6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} - commander@7.2.0: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} - - comment-json@4.4.1: - resolution: {integrity: sha512-r1To31BQD5060QdkC+Iheai7gHwoSZobzunqkf2/kQ6xIAfJyrKNAFUwdKvkK7Qgu7pVTKQEa7ok7Ed3ycAJgg==} - engines: {node: '>= 6'} - commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} compare-func@2.0.0: resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - component-emitter@1.3.1: - resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} - - concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - - concat-stream@2.0.0: - resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} - engines: {'0': node >= 6.0} + compress-commons@6.0.2: + resolution: {integrity: sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==} + engines: {node: '>= 14'} confbox@0.2.4: resolution: {integrity: sha512-ysOGlgTFbN2/Y6Cg3Iye8YKulHw+R2fNXHrgSmXISQdMnomY6eNDprVdW9R5xBguEqI954+S6709UyiO7B+6OQ==} - consola@3.4.2: - resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} - engines: {node: ^14.18.0 || >=16.10.0} - - content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} - - content-disposition@1.1.0: - resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} - engines: {node: '>=18'} - - content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - - content-type@2.0.0: - resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} - engines: {node: '>=18'} - conventional-changelog-angular@8.1.0: resolution: {integrity: sha512-GGf2Nipn1RUCAktxuVauVr1e3r8QrLP/B0lEUsFktmGqc3ddbQkhoJZHJctVU829U1c6mTSWftrVOCHaL85Q3w==} engines: {node: '>=18'} @@ -3582,35 +2978,13 @@ packages: engines: {node: '>=18'} hasBin: true - convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - - cookie-signature@1.2.2: - resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} - engines: {node: '>=6.6.0'} - cookie@0.6.0: resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} engines: {node: '>= 0.6'} - cookie@0.7.2: - resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} - engines: {node: '>= 0.6'} - - cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} - - cookiejar@2.1.4: - resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} - core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cors@2.8.6: - resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} - engines: {node: '>= 0.10'} - cosmiconfig-typescript-loader@6.2.0: resolution: {integrity: sha512-GEN39v7TgdxgIoNcdkRE3uiAzQt3UXLyHbRHD6YoL048XAeOomyxaP+Hh/+2C6C2wYjxJ2onhJcsQp+L4YEkVQ==} engines: {node: '>=v18'} @@ -3619,15 +2993,6 @@ packages: cosmiconfig: '>=9' typescript: '>=5' - cosmiconfig@8.3.6: - resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} - engines: {node: '>=14'} - peerDependencies: - typescript: '>=4.9.5' - peerDependenciesMeta: - typescript: - optional: true - cosmiconfig@9.0.0: resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} @@ -3637,13 +3002,18 @@ packages: typescript: optional: true - create-jest@29.7.0: - resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + cpu-features@0.0.10: + resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==} + engines: {node: '>=10.0.0'} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} hasBin: true - create-require@1.1.1: - resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + crc32-stream@6.0.0: + resolution: {integrity: sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==} + engines: {node: '>= 14'} cross-env@10.1.0: resolution: {integrity: sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==} @@ -3660,6 +3030,10 @@ packages: d3-array@2.12.1: resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + d3-array@3.2.1: + resolution: {integrity: sha512-gUY/qeHq/yNqqoCKNq4vtpFLdoCdvyNpWoC/KNjhGbhDuQpAM9sIQQKkXSNpXa9h5KySs/gzm7R88WkUutgwWQ==} + engines: {node: '>=12'} + d3-array@3.2.4: resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} engines: {node: '>=12'} @@ -3676,6 +3050,10 @@ packages: resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} engines: {node: '>=12'} + d3-delaunay@6.0.2: + resolution: {integrity: sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==} + engines: {node: '>=12'} + d3-delaunay@6.0.4: resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} engines: {node: '>=12'} @@ -3693,6 +3071,10 @@ packages: resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} engines: {node: '>=12'} + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + d3-format@3.1.2: resolution: {integrity: sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==} engines: {node: '>=12'} @@ -3701,6 +3083,10 @@ packages: resolution: {integrity: sha512-kqE4yYuOjPbKdBXG0xztCacPwkVSK2REF1opSNrnqqtXJmNcM++UbwQ8SxvwP6IQTj9RvIjjK4qeiVsEfj0Z2Q==} engines: {node: '>=12'} + d3-geo@3.1.0: + resolution: {integrity: sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==} + engines: {node: '>=12'} + d3-geo@3.1.1: resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} engines: {node: '>=12'} @@ -3772,26 +3158,6 @@ packages: resolution: {integrity: sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==} engines: {node: '>=12'} - data-view-buffer@1.0.2: - resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} - engines: {node: '>= 0.4'} - - data-view-byte-length@1.0.2: - resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} - engines: {node: '>= 0.4'} - - data-view-byte-offset@1.0.1: - resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} - engines: {node: '>= 0.4'} - - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -3801,21 +3167,6 @@ packages: supports-color: optional: true - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - - dedent@1.7.1: - resolution: {integrity: sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==} - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - - deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - deepmerge-ts@7.1.5: resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} engines: {node: '>=16.0.0'} @@ -3824,43 +3175,16 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - defaults@1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - - defaults@2.0.2: - resolution: {integrity: sha512-cuIw0PImdp76AOfgkjbW4VhQODRmNNcKR73vdCH5cLd/ifj7aamfoXvYgfGkEAjNJZ3ozMIy9Gu2LutUkGEPbA==} - engines: {node: '>=16'} - - defer-to-connect@2.0.1: - resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} - engines: {node: '>=10'} - - define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} - - define-properties@1.2.1: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} - - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} delaunator@5.1.0: resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - denque@2.1.0: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -3876,107 +3200,73 @@ packages: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} - detect-newline@3.1.0: - resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} - engines: {node: '>=8'} - devalue@5.8.1: resolution: {integrity: sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==} - dezalgo@1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - - diff-sequences@29.6.3: - resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - diff@4.0.4: - resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} - engines: {node: '>=0.3.1'} - dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} - doctrine@2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} + docker-compose@1.5.0: + resolution: {integrity: sha512-O+eD6c63+BJORUWddXA7uAlI6H1KLDPd/aS14k73nXYpFliM48C3xrrKB3sXsR1Fp/rHUZQe7+fJ+QA7+jepyw==} + engines: {node: '>= 6.0.0'} + + docker-modem@5.0.7: + resolution: {integrity: sha512-XJgGhoR/CLpqshm4d3L7rzH6t8NgDFUIIpztYlLHIApeJjMZKYJMz2zxPsYxnejq5h3ELYSw/RBsi3t5h7gNTA==} + engines: {node: '>= 8.0'} + + dockerode@5.0.1: + resolution: {integrity: sha512-avsq/xk4YPIrn0CgleX5bjT9Y8IT1p9PxrNQ++RBQ2WEyFfHCTDsT9kmyxz+H/axnjAwg8wJWEIuPGOUuNupiA==} + engines: {node: '>= 14.17'} dot-prop@5.3.0: resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} engines: {node: '>=8'} - dotenv-cli@10.0.0: - resolution: {integrity: sha512-lnOnttzfrzkRx2echxJHQRB6vOAMSCzzZg79IxpC00tU42wZPuZkQxNNrrwVAxaQZIIh001l4PxVlCrBxngBzA==} - hasBin: true - - dotenv-expand@11.0.7: - resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} - engines: {node: '>=12'} - - dotenv-expand@12.0.3: - resolution: {integrity: sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==} - engines: {node: '>=12'} - - dotenv@16.6.1: - resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} - engines: {node: '>=12'} - - dotenv@17.2.3: - resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} - engines: {node: '>=12'} - dotenv@17.3.1: resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} engines: {node: '>=12'} - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - - duplexify@3.7.1: - resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} - - duplexify@4.1.3: - resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} - - ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + dotenv@18.0.4: + resolution: {integrity: sha512-jGt9uI5BIxpVO15kvy+iEFqNAwxYClKWnkptLjSNPnFLC003Imd0ofr3aEVsbpHdSBdSsbcApNIlz4nbyGMwdA==} + engines: {node: '>=12'} + hasBin: true - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dts-resolver@3.0.0: + resolution: {integrity: sha512-1T1f+z+4tl9XD+m+0HBgWoL/nm0bOIffyWaUuUSBlFg/86IWvfx+wjNaO/ybU0AJzG9/Mi5hBUgGV6zCmWEN7Q==} + engines: {node: ^22.18.0 || >=24.0.0} + peerDependencies: + oxc-resolver: '>=11.0.0' + peerDependenciesMeta: + oxc-resolver: + optional: true - effect@3.18.4: - resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.302: - resolution: {integrity: sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==} + effect@3.20.0: + resolution: {integrity: sha512-qMLfDJscrNG8p/aw+IkT9W7fgj50Z4wG5bLBy0Txsxz8iUHjDIkOgO3SV0WZfnQbNG2VJYb0b+rDLMrhM4+Krw==} - emittery@0.13.1: - resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} - engines: {node: '>=12'} + elkjs@0.11.1: + resolution: {integrity: sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + empathic@2.0.0: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} engines: {node: '>=14'} - enabled@2.0.0: - resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} + empathic@2.1.0: + resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} + engines: {node: '>=14'} end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.19.0: - resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} - engines: {node: '>=10.13.0'} - enhanced-resolve@5.21.6: resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} engines: {node: '>=10.13.0'} @@ -3989,39 +3279,15 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} - es-abstract@1.24.2: - resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} - engines: {node: '>= 0.4'} - - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - - es-module-lexer@2.0.0: - resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} - - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - - es-shim-unscopables@1.1.0: - resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} - engines: {node: '>= 0.4'} - - es-to-primitive@1.3.0: - resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} - engines: {node: '>= 0.4'} + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} es-toolkit@1.49.0: resolution: {integrity: sha512-G5iZ6Pc/FNRY/soKZHC+TxGDD83rHUDXxzaWhGCX44vAv/tMs56WMusnm/KMNK+luUPsgA9U28cGr4RDlSzL2g==} @@ -4031,159 +3297,23 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - escape-string-regexp@2.0.0: - resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} - engines: {node: '>=8'} - - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - - eslint-config-prettier@10.1.8: - resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - - eslint-import-context@0.1.9: - resolution: {integrity: sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - peerDependencies: - unrs-resolver: ^1.0.0 - peerDependenciesMeta: - unrs-resolver: - optional: true - - eslint-import-resolver-node@0.3.10: - resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} - - eslint-import-resolver-typescript@4.4.4: - resolution: {integrity: sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==} - engines: {node: ^16.17.0 || >=18.6.0} - peerDependencies: - eslint: '*' - eslint-plugin-import: '*' - eslint-plugin-import-x: '*' - peerDependenciesMeta: - eslint-plugin-import: - optional: true - eslint-plugin-import-x: - optional: true - - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - - eslint-plugin-import@2.32.0: - resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - - eslint-plugin-jest@29.15.0: - resolution: {integrity: sha512-ZCGr7vTH2WSo2hrK5oM2RULFmMruQ7W3cX7YfwoTiPfzTGTFBMmrVIz45jZHd++cGKj/kWf02li/RhTGcANJSA==} - engines: {node: ^20.12.0 || ^22.0.0 || >=24.0.0} - peerDependencies: - '@typescript-eslint/eslint-plugin': ^8.0.0 - eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 - jest: '*' - typescript: '>=4.8.4 <6.0.0' - peerDependenciesMeta: - '@typescript-eslint/eslint-plugin': - optional: true - jest: - optional: true - typescript: - optional: true - - eslint-plugin-prettier@5.5.5: - resolution: {integrity: sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==} - engines: {node: ^14.18.0 || >=16.0.0} - peerDependencies: - '@types/eslint': '>=8.0.0' - eslint: '>=8.0.0' - eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0' - prettier: '>=3.0.0' - peerDependenciesMeta: - '@types/eslint': - optional: true - eslint-config-prettier: - optional: true - - eslint-scope@5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - - eslint-scope@8.4.0: - resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - eslint-visitor-keys@3.4.3: - resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} - 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: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} - engines: {node: ^20.19.0 || ^22.13.0 || >=24} - - eslint@9.39.3: - resolution: {integrity: sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - esm-env@1.2.2: resolution: {integrity: sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==} - espree@10.4.0: - resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - esprima@4.0.1: resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} engines: {node: '>=4'} hasBin: true - esquery@1.7.0: - resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} - engines: {node: '>=0.10'} - esrap@2.2.13: resolution: {integrity: sha512-m8jH5hZgJE2RRUK/jjkGPcJEDAV+dYnZYFkosQaPTcE+Yw4xynXHOo6FUdwaWBtdR3b1MMa7wEDTSHeR2VWsGA==} peerDependencies: @@ -4192,28 +3322,11 @@ packages: '@typescript-eslint/types': optional: true - esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - - estraverse@4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - - estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} @@ -4230,37 +3343,13 @@ packages: resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} engines: {node: '>=18.0.0'} - execa@5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - - exit@0.1.2: - resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} - engines: {node: '>= 0.8.0'} - - expect@29.7.0: - resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - expect@30.2.0: - resolution: {integrity: sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - express@5.2.1: - resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} - engines: {node: '>= 18'} + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} + engines: {node: '>=12.0.0'} exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} - ext-list@2.2.2: - resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} - engines: {node: '>=0.10.0'} - - ext-name@5.0.0: - resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} - engines: {node: '>=4'} - extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} @@ -4274,9 +3363,6 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - fast-fifo@1.3.2: resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} @@ -4284,36 +3370,15 @@ packages: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} - fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - - fast-json-stringify@6.3.0: - resolution: {integrity: sha512-oRCntNDY/329HJPlmdNLIdogNtt6Vyjb1WuT01Soss3slIdyUp8kAcDU3saQTOquEK8KFVfwIIF7FebxUAu+yA==} - - fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fast-querystring@1.1.2: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} - fast-safe-stringify@2.1.1: - resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} - fastify-plugin@5.1.0: - resolution: {integrity: sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==} - - fastify@5.7.4: - resolution: {integrity: sha512-e6l5NsRdaEP8rdD8VR0ErJASeyaRbzXYpmkrpr2SuvuMq6Si3lvsaVy5C+7gLanEkvjpMDzBXWE5HPeb/hgTxA==} - 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'} @@ -4323,119 +3388,33 @@ packages: picomatch: optional: true - fecha@4.2.3: - resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} - - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} - - file-entry-cache@8.0.0: - resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} - engines: {node: '>=16.0.0'} - - file-type@20.5.0: - resolution: {integrity: sha512-BfHZtG/l9iMm4Ecianu7P8HRD2tBHLtjXinm4X62XBOYzi7CYA7jyqfJzOvXHqzVrVPYqBo2/GvbARMaaJkKVg==} - engines: {node: '>=18'} - - file-type@21.3.0: - resolution: {integrity: sha512-8kPJMIGz1Yt/aPEwOsrR97ZyZaD1Iqm8PClb1nYFclUCkBi0Ma5IsYNQzvSFS9ib51lWyIw5mIT9rWzI/xjpzA==} - engines: {node: '>=20'} - - filename-reserved-regex@3.0.0: - resolution: {integrity: sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - filenamify@6.0.0: - resolution: {integrity: sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==} - engines: {node: '>=16'} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@2.1.1: - resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} - engines: {node: '>= 18.0.0'} - - find-my-way@9.4.0: - resolution: {integrity: sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==} + find-my-way@9.7.0: + resolution: {integrity: sha512-f2JHn75x2JlwUwLenZypgczR7YWMb/uO9BvUXtus+JMgkbIkLADd38cI4EiV+OQqrGo1Zlq6V8wnqMJ8e62wUQ==} engines: {node: '>=20'} find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} - find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - - find-versions@5.1.0: - resolution: {integrity: sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==} - engines: {node: '>=12'} - - flat-cache@4.0.1: - resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} - engines: {node: '>=16'} - - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} - - fn.name@1.1.0: - resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - - for-each@0.3.5: - resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} - engines: {node: '>= 0.4'} - foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - fork-ts-checker-webpack-plugin@9.1.0: - resolution: {integrity: sha512-mpafl89VFPJmhnJ1ssH+8wmM2b50n+Rew5x42NeI2U78aRWgtkEtGmctp7iT16UjquJTjorEmIfESj3DxdW84Q==} - engines: {node: '>=14.21.3'} - peerDependencies: - typescript: '>3.6.0' - webpack: ^5.11.0 + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - form-data-encoder@2.1.4: - resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} - engines: {node: '>= 14.17'} - - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} - - formidable@3.5.4: - resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} - engines: {node: '>=14.0.0'} - - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - - fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} - - fs-extra@7.0.1: - resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} - engines: {node: '>=6 <7 || >=8'} + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} - fs-monkey@1.1.0: - resolution: {integrity: sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==} - - fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -4444,56 +3423,26 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.8: - resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} - engines: {node: '>= 0.4'} - - functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - generate-function@2.3.1: resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} - generator-function@2.0.1: - resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} - engines: {node: '>= 0.4'} - - gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-package-type@0.1.0: - resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} - engines: {node: '>=8.0.0'} - get-port-please@3.2.0: resolution: {integrity: sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==} - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - - get-stream@6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - - get-symbol-description@1.1.0: - resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} - engines: {node: '>= 0.4'} + get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} - get-tsconfig@4.14.0: - resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + get-tsconfig@5.0.0-beta.6: + resolution: {integrity: sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw==} + engines: {node: '>=20.20.0'} - giget@2.0.0: - resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} + giget@3.3.1: + resolution: {integrity: sha512-r+mvuDjrjMpsdw46Kmeydb8bdHm7wOKw8wNBtTndkjbPjgAp5oUJUxRE76wZFknxIPokfWvep2qSXK37aXE6zg==} hasBin: true git-raw-commits@4.0.0: @@ -4505,54 +3454,25 @@ packages: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} - glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} - - glob-to-regexp@0.4.1: - resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - - glob@11.1.0: - resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==} - engines: {node: 20 || >=22} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} 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 hasBin: true - glob@13.0.0: - resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} - engines: {node: 20 || >=22} - - glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - 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 - global-directory@4.0.1: resolution: {integrity: sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==} engines: {node: '>=18'} - globals@14.0.0: - resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} - engines: {node: '>=18'} - globals@16.5.0: resolution: {integrity: sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==} engines: {node: '>=18'} - globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} - globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - - got@13.0.0: - resolution: {integrity: sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA==} - engines: {node: '>=16'} + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -4563,67 +3483,26 @@ packages: graphmatch@1.1.1: resolution: {integrity: sha512-5ykVn/EXM1hF0XCaWh05VbYvEiOL2lY1kBxZtaYsyvjp7cmWOU1XsAdfQBwClraEofXDT197lFbXOEVMHpvQOg==} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} - engines: {node: '>=0.4.7'} - hasBin: true - - has-bigints@1.1.0: - resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} - engines: {node: '>= 0.4'} - - has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - - has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} - - has-proto@1.2.0: - resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} - engines: {node: '>= 0.4'} - - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hono@4.11.4: - resolution: {integrity: sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==} - engines: {node: '>=16.9.0'} - - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - - http-cache-semantics@4.2.0: - resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} - - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} + hono-openapi@1.3.3: + resolution: {integrity: sha512-+LVFPQEc4eDrXr/Rd0QQkRh/DbEZRXnm1RZU4bVaoqmWiWgspT4nNHIQMgi44X+D9/8k1eGzHvR0KLNPJ/0xaQ==} + peerDependencies: + hono: ^4.11.2 - http-status-codes@2.3.0: - resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + hono@4.13.9: + resolution: {integrity: sha512-7dMkQmZoC4E6F7AtaQSPhlWAdnBti+j7rreMZl8QB4jFiEhP9TWbGWUMi8WYzBCgmgulxuvLQupKqo+Co6Omyg==} + engines: {node: '>=16.9.0'} - http2-wrapper@2.2.1: - resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} - engines: {node: '>=10.19.0'} + hookable@6.1.2: + resolution: {integrity: sha512-+abwxtiEA52GCVIsQqut3S/uKTbUwYIp4Pe/vv+6py5XiXBCqMZHg6pA6Y5qhgLSEys0/cYuPbO0z1QFj5ZCmg==} human-id@4.1.3: resolution: {integrity: sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==} hasBin: true - human-signals@2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - husky@9.1.7: resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} engines: {node: '>=18'} @@ -4648,29 +3527,16 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} 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: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} - engines: {node: '>=8'} - hasBin: true - import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} - imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - - inflight@1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + import-without-cache@0.4.1: + resolution: {integrity: sha512-vXoV9PjKHEednCUu01e98TkImxy67e3BJXbTIOmIq4Hyzw3IAwYRcuPkfeTzJzwyyts4kjuA73x+pWJLc4f86A==} + engines: {node: ^22.18.0 || >=24.0.0} inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -4679,13 +3545,6 @@ packages: resolution: {integrity: sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - inspect-with-kind@1.0.5: - resolution: {integrity: sha512-MAQUJuIo7Xqk8EVNP+6d3CKq9c80hi4tjIbIAT6lmGW9W6WzlHiu9PS8uSuUYU+Do+j1baiFp3H25XEVxDIG2g==} - - internal-slot@1.1.0: - resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} - engines: {node: '>= 0.4'} - internmap@1.0.1: resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} @@ -4693,95 +3552,28 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - - ipaddr.js@2.3.0: - resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} - engines: {node: '>= 10'} - - is-array-buffer@3.0.5: - resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} - engines: {node: '>= 0.4'} - is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-async-function@2.1.1: - resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} - engines: {node: '>= 0.4'} - - is-bigint@1.1.0: - resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} - engines: {node: '>= 0.4'} - - is-boolean-object@1.2.2: - resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} - engines: {node: '>= 0.4'} - - is-bun-module@2.0.0: - resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} - - is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - is-core-module@2.16.1: resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} engines: {node: '>= 0.4'} - is-data-view@1.0.2: - resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} - engines: {node: '>= 0.4'} - - is-date-object@1.1.0: - resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} - engines: {node: '>= 0.4'} - is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-finalizationregistry@1.1.1: - resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} - engines: {node: '>= 0.4'} - is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} - is-generator-fn@2.1.0: - resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} - engines: {node: '>=6'} - - is-generator-function@1.1.2: - resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} - engines: {node: '>= 0.4'} - is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} - is-interactive@1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - - is-map@2.0.3: - resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} - engines: {node: '>= 0.4'} - is-module@1.0.0: resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - - is-number-object@1.1.1: - resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} - engines: {node: '>= 0.4'} - is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -4790,17 +3582,10 @@ packages: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} engines: {node: '>=8'} - is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - is-plain-obj@4.1.0: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} - is-promise@4.0.0: - resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} - is-property@1.0.2: resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} @@ -4810,54 +3595,14 @@ packages: is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} - is-regex@1.2.1: - resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} - engines: {node: '>= 0.4'} - - is-set@2.0.3: - resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} - engines: {node: '>= 0.4'} - - is-shared-array-buffer@1.0.4: - resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} - engines: {node: '>= 0.4'} - is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - is-string@1.1.1: - resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} - engines: {node: '>= 0.4'} - is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} - is-symbol@1.1.1: - resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} - engines: {node: '>= 0.4'} - - is-typed-array@1.1.15: - resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} - engines: {node: '>= 0.4'} - - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - - is-weakmap@2.0.2: - resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} - engines: {node: '>= 0.4'} - - is-weakref@1.1.1: - resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} - engines: {node: '>= 0.4'} - - is-weakset@2.0.4: - resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} - engines: {node: '>= 0.4'} - is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} engines: {node: '>=0.10.0'} @@ -4865,222 +3610,11 @@ packages: isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-instrument@5.2.1: - resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} - engines: {node: '>=8'} - - istanbul-lib-instrument@6.0.3: - resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} - engines: {node: '>=10'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-lib-source-maps@4.0.1: - resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} - - iterare@1.2.1: - resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} - engines: {node: '>=6'} - - jackspeak@4.2.3: - resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} - engines: {node: 20 || >=22} - - jest-changed-files@29.7.0: - resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-circus@29.7.0: - resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-cli@29.7.0: - resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - jest-config@29.7.0: - resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - - jest-diff@29.7.0: - resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-diff@30.2.0: - resolution: {integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-docblock@29.7.0: - resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-each@29.7.0: - resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-environment-node@29.7.0: - resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-esm-transformer@1.0.0: - resolution: {integrity: sha512-FoPgeMMwy1/CEsc8tBI41i83CEO3x85RJuZi5iAMmWoARXhfgk6Jd7y+4d+z+HCkTKNVDvSWKGRhwjzU9PUbrw==} - - jest-get-type@29.6.3: - resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-haste-map@29.7.0: - resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-haste-map@30.2.0: - resolution: {integrity: sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-leak-detector@29.7.0: - resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-matcher-utils@29.7.0: - resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-matcher-utils@30.2.0: - resolution: {integrity: sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-message-util@29.7.0: - resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-message-util@30.2.0: - resolution: {integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-mock-extended@4.0.0: - resolution: {integrity: sha512-7BZpfuvLam+/HC+NxifIi9b+5VXj/utUDMPUqrDJehGWVuXPtLS9Jqlob2mJLrI/pg2k1S8DMfKDvEB88QNjaQ==} - peerDependencies: - '@jest/globals': ^28.0.0 || ^29.0.0 || ^30.0.0 - jest: ^24.0.0 || ^25.0.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0 || ^30.0.0 - typescript: ^3.0.0 || ^4.0.0 || ^5.0.0 - - jest-mock@29.7.0: - resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-mock@30.2.0: - resolution: {integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-pnp-resolver@1.2.3: - resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} - engines: {node: '>=6'} - peerDependencies: - jest-resolve: '*' - peerDependenciesMeta: - jest-resolve: - optional: true - - jest-regex-util@29.6.3: - resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-regex-util@30.0.1: - resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-resolve-dependencies@29.7.0: - resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-resolve@29.7.0: - resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runner@29.7.0: - resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-runtime@29.7.0: - resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-snapshot@29.7.0: - resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-snapshot@30.2.0: - resolution: {integrity: sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-util@29.7.0: - resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-util@30.2.0: - resolution: {integrity: sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest-validate@29.7.0: - resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-watcher@29.7.0: - resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-worker@27.5.1: - resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} - engines: {node: '>= 10.13.0'} - - jest-worker@29.7.0: - resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - jest-worker@30.2.0: - resolution: {integrity: sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - jest@29.7.0: - resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} @@ -5090,6 +3624,9 @@ packages: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -5101,93 +3638,27 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true - jsesc@3.1.0: - resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} - engines: {node: '>=6'} - hasBin: true - - json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} - json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-schema-ref-resolver@3.0.0: - resolution: {integrity: sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==} - - json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - - json5@1.0.2: - resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} - hasBin: true - - json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} - jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} - jsonfile@6.2.0: - resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} - - jsonwebtoken@9.0.3: - resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==} - engines: {node: '>=12', npm: '>=6'} - - jwa@2.0.1: - resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} - - jws@4.0.1: - resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} - - keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} - - kind-of@6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - - 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'} - kuler@2.0.0: - resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - layerchart@2.0.0-next.65: resolution: {integrity: sha512-pyIpQwSrUDz5de/Es8JwrDuEg6VhpFVMlR1RGSGhOYVnDeOUO04v4ZKPNXEltYXldQt9VM7W7rmpwUuR4l7DOg==} peerDependencies: svelte: ^5.0.0 - leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - - levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - - libphonenumber-js@1.13.8: - resolution: {integrity: sha512-80xal1m93rADejw2pMp2MSzFhHCPLEspjHxnH2UtqI+DgAmElsbmLMiqk9niwH9NWAfjsRtaJI+qBrOEmRx9nQ==} - - light-my-request@6.6.0: - resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==} + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} lightningcss-android-arm64@1.32.0: resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} @@ -5263,21 +3734,9 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} - lilconfig@2.1.0: - resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} - engines: {node: '>=10'} - lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - load-esm@1.0.3: - resolution: {integrity: sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==} - engines: {node: '>=13.2.0'} - - loader-runner@4.3.1: - resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} - engines: {node: '>=6.11.5'} - locate-character@3.0.0: resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} @@ -5285,46 +3744,15 @@ packages: resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} engines: {node: '>=8'} - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} - lodash.includes@4.3.0: - resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} - - lodash.isboolean@3.0.3: - resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} - - lodash.isinteger@4.0.4: - resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} - - lodash.isnumber@3.0.3: - resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} - - lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - - lodash.isstring@4.0.1: - resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} - lodash.kebabcase@4.1.1: resolution: {integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==} - lodash.memoize@4.1.2: - resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} - - lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - lodash.mergewith@4.6.2: resolution: {integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==} - lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - lodash.snakecase@4.1.1: resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} @@ -5334,33 +3762,14 @@ packages: lodash.upperfirst@4.3.1: resolution: {integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - lodash@4.17.23: resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==} - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - - logform@2.7.0: - resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} - engines: {node: '>= 12.0.0'} - long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} - lowercase-keys@3.0.0: - resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - lru-cache@11.2.6: - resolution: {integrity: sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==} - engines: {node: 20 || >=22} - - lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} lru.min@1.1.4: resolution: {integrity: sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==} @@ -5370,41 +3779,18 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.30.17: - resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} - magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} + magic-string@1.4.3: + resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==} - make-error@1.3.6: - resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + magicast@0.5.5: + resolution: {integrity: sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA==} - makeerror@1.0.12: - resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} - - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - - media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - - memfs@3.5.3: - resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} - engines: {node: '>= 4.0.0'} - - memoize@10.2.0: - resolution: {integrity: sha512-DeC6b7QBrZsRs3Y02A6A7lQyzFbsQbqgjI6UW0GigGWV+u1s25TycMr0XHZE4cJce7rY/vyw2ctMQqfDkIhUEA==} - engines: {node: '>=18'} + memoize@10.2.0: + resolution: {integrity: sha512-DeC6b7QBrZsRs3Y02A6A7lQyzFbsQbqgjI6UW0GigGWV+u1s25TycMr0XHZE4cJce7rY/vyw2ctMQqfDkIhUEA==} + engines: {node: '>=18'} meow@12.1.1: resolution: {integrity: sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==} @@ -5414,80 +3800,24 @@ packages: resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} engines: {node: '>=18'} - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - - merge-stream@2.0.0: - resolution: {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: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - - mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - - mime@3.0.0: - resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} - engines: {node: '>=10.0.0'} - hasBin: true - - mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - mimic-function@5.0.1: resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} engines: {node: '>=18'} - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} engines: {node: '>=10'} - mimic-response@4.0.0: - resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - minimatch@10.2.2: - resolution: {integrity: sha512-+G4CpNBxa5MprY+04MbgOw1v7So6n5JY166pFi9KfYwT78fxScCeSNQSNzp6dpPSW2rONOps6Ocam1wFhCgoVw==} - engines: {node: 18 || 20 || >=22} - - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} - - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: @@ -5497,8 +3827,12 @@ packages: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} - mkdirp@0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} hasBin: true mri@1.2.0: @@ -5512,14 +3846,6 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - multer@2.0.2: - resolution: {integrity: sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==} - 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: {integrity: sha512-FBrGau0IXmuqg4haEZRBfHNWB5mUARw6hNwPDXXGg0XzVJ50mr/9hb267lvpVMnhZ1FON3qNd4Xfcez1rbFwSg==} engines: {node: '>= 8.0'} @@ -5528,158 +3854,54 @@ packages: resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==} engines: {node: '>=8.0.0'} + nan@2.29.0: + resolution: {integrity: sha512-GlGk3HIvitbvs+LT3g6XUP1kpirKNvmDFwF/bmo6XNWSb/eYEs/O4bfgIEIXCZ+lIOTS5xNwDvSGMw6FJdAhtA==} + 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: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + nanoid@5.1.16: + resolution: {integrity: sha512-kVrnsrJqMR8+oLJnGEmSWw9BivK5mt7H3FZatVRjrc5wGqFYuBxX1yG7+A7Gi5AefkX6t/oCkizcQgpu0cY1dQ==} + engines: {node: ^18 || >=20} hasBin: true - natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} - - neo-async@2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - - nest-winston@1.10.2: - resolution: {integrity: sha512-Z9IzL/nekBOF/TEwBHUJDiDPMaXUcFquUQOFavIRet6xF0EbuWnOzslyN/ksgzG+fITNgXhMdrL/POp9SdaFxA==} - peerDependencies: - '@nestjs/common': ^5.0.0 || ^6.6.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 - winston: ^3.0.0 - - nestjs-zod@5.1.1: - resolution: {integrity: sha512-pXa9Jrdip7iedKvGxJTvvCFVRCoIcNENPCsHjpCefPH3PcFejRgkZkUcr3TYITRyxnUk7Zy5OsLpirZGLYBfBQ==} - peerDependencies: - '@nestjs/common': ^10.0.0 || ^11.0.0 - '@nestjs/swagger': ^7.4.2 || ^8.0.0 || ^11.0.0 - rxjs: ^7.0.0 - zod: ^3.25.0 || ^4.0.0 - peerDependenciesMeta: - '@nestjs/swagger': - optional: true - - node-abort-controller@3.1.1: - resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} - - node-addon-api@8.5.0: - resolution: {integrity: sha512-/bRZty2mXUIFY/xU5HLvveNHlswNJej+RnxBjOMkidWfwZzgTbPG1E3K5TOxRLOR+5hX7bSofy8yf1hZevMS8A==} + node-addon-api@8.9.2: + resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==} engines: {node: ^18 || ^20 || >= 21} - node-emoji@1.11.0: - resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} - - node-exports-info@1.6.0: - resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} - engines: {node: '>= 0.4'} - - node-fetch-native@1.6.7: - resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} - node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-int64@0.4.0: - resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - - node-releases@2.0.27: - resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - normalize-url@8.1.1: - resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} - engines: {node: '>=14.16'} - - npm-run-path@4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - - nypm@0.6.5: - resolution: {integrity: sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ==} - engines: {node: '>=18'} - hasBin: true - - object-assign@4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - - object-inspect@1.13.4: - resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} - engines: {node: '>= 0.4'} - - object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - - object.assign@4.1.7: - resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} - engines: {node: '>= 0.4'} - - object.entries@1.1.9: - resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} - engines: {node: '>= 0.4'} - - object.fromentries@2.0.8: - resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} - engines: {node: '>= 0.4'} - - object.groupby@1.0.3: - resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} - engines: {node: '>= 0.4'} - - object.values@1.2.1: - resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} - engines: {node: '>= 0.4'} - obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} - ohash@2.0.11: - resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} + obug@2.2.1: + resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} + engines: {node: '>=12.20.0'} - on-exit-leak-free@2.1.2: - resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} - engines: {node: '>=14.0.0'} + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - one-time@1.0.0: - resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} - - onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - - optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} - - ora@5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} - own-keys@1.0.1: - resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} - engines: {node: '>= 0.4'} - oxfmt@0.57.0: resolution: {integrity: sha512-ZB7Bi+rGDSqmVIo9jwcLyFgjxXvQhDdU+jx+ZrVy6VRiVXK2+CHc4hO3J4dUQjHe7V0ymHB+MDuv5z+NhK07HA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -5693,10 +3915,27 @@ packages: vite-plus: optional: true + oxfmt@0.70.0: + resolution: {integrity: sha512-IsHxZ4y0wQLLMhnrJblBJgZsLDzfULrJnAw5j/QqsTlMa/m3AqsbToi+W71uhBGaqlqq/PbbjvHc09TJwdv3Tw==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + svelte: ^5.0.0 + vite-plus: '*' + peerDependenciesMeta: + svelte: + optional: true + vite-plus: + optional: true + oxlint-tsgolint@0.17.4: resolution: {integrity: sha512-4F/NXJiK2KnK4LQiULUPXRzVq0LOfextGvwCVRW1VKQbF5epI3MDMEGVAl5XjAGL6IFc7xBc/eVA95wczPeEQg==} hasBin: true + oxlint-tsgolint@7.0.2003: + resolution: {integrity: sha512-VnK4zlqgmgq/7ZcjzCk/WpN8kKFsYGcB85Io9qT3wL4K8Un3RKmJkp793crNETieMusPMKOA4a+Mw2wbteI6TQ==} + hasBin: true + oxlint@1.72.0: resolution: {integrity: sha512-1rhdZIP/EvoI91ABIwNU5Q8+bWf8mjrS5UzIOZld4d4bXxJvtlUhlQvaoTogIGin/qdErMOrwaIJvCSIAKTLhA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -5710,9 +3949,18 @@ packages: vite-plus: optional: true - p-cancelable@3.0.0: - resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} - engines: {node: '>=12.20'} + oxlint@1.85.0: + resolution: {integrity: sha512-bc26s97nuvPj1ViyPsqmKecVkUWFMEdtayO8MaQ6oiLfs1pj94cQlZZhrh4BPNlr9HQosjhIlwgZKsfcwmcNgg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + oxlint-tsgolint: '>=7.0.2001' + vite-plus: '*' + peerDependenciesMeta: + oxlint-tsgolint: + optional: true + vite-plus: + optional: true p-filter@2.1.0: resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} @@ -5722,18 +3970,10 @@ packages: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} - p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - p-locate@4.1.0: resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} engines: {node: '>=8'} - p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - p-map@2.1.0: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} @@ -5756,18 +3996,10 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -5775,12 +4007,9 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@2.0.2: - resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} - engines: {node: 18 || 20 || >=22} - - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -5789,39 +4018,36 @@ packages: pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} - peek-stream@1.1.3: - resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} + perfect-debounce@2.1.0: + resolution: {integrity: sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==} - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + pg-cloudflare@1.4.0: + resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==} - perfect-debounce@1.0.0: - resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} - - pg-cloudflare@1.3.0: - resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} - - pg-connection-string@2.11.0: - resolution: {integrity: sha512-kecgoJwhOpxYU21rZjULrmrBJ698U2RxXofKVzOn5UDj61BPj/qMb7diYUR1nLScCDbrztQFl1TaQZT0t1EtzQ==} + pg-connection-string@2.14.0: + resolution: {integrity: sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==} pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-pool@3.11.0: - resolution: {integrity: sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==} + pg-pool@3.14.0: + resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==} peerDependencies: pg: '>=8.0' pg-protocol@1.11.0: resolution: {integrity: sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==} + pg-protocol@1.16.0: + resolution: {integrity: sha512-sILXutLVjCLjcDuOmvhX5e2Z4cS5qG/6Bu3VkpFwdf/633ElGLpEh9bgmuI5I4sqKqkifQiGyiCcx1HdtrK7tg==} + pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - pg@8.18.0: - resolution: {integrity: sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==} + pg@8.23.0: + resolution: {integrity: sha512-Ip2EQCngowJLGOfCwkFhPXU7/ljlhn6Rxlmy4XYfL2Y+vyRM59+8uR2xqRWKdYmbXmxCFOAmKxBuSUCdF34qLg==} engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' @@ -5839,50 +4065,21 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} - engines: {node: '>=12'} - picomatch@4.0.3: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pino-abstract-transport@3.0.0: - resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} - - pino-std-serializers@7.1.0: - resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} - - pino@10.3.1: - resolution: {integrity: sha512-r34yH/GlQpKZbU1BvFFqOjhISRo1MNx1tWYsYvmj6KIRHSPMT2+yHOEb1SG6NMvRoHRF0a07kCOox/9yakl1vg==} - hasBin: true - - pirates@4.0.7: - resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} - engines: {node: '>= 6'} - - piscina@4.9.2: - resolution: {integrity: sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ==} - - pkg-dir@4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - pluralize@8.0.0: - resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} - engines: {node: '>=4'} - - possible-typed-array-names@1.1.0: - resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} - engines: {node: '>= 0.4'} - postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -5911,34 +4108,13 @@ packages: resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} engines: {node: '>=12'} - prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - - prettier-linter-helpers@1.0.1: - resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} - engines: {node: '>=6.0.0'} - prettier@2.8.8: resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} engines: {node: '>=10.13.0'} hasBin: true - prettier@3.8.1: - resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==} - engines: {node: '>=14'} - hasBin: true - - pretty-format@29.7.0: - resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - - pretty-format@30.2.0: - resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} - engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} - - prisma@7.4.1: - resolution: {integrity: sha512-gDKOXwnPiMdB+uYMhMeN8jj4K7Cu3Q2wB/wUsITOoOk446HtVb8T9BZxFJ1Zop6alc89k6PMNdR2FZCpbXp/jw==} + prisma@7.10.0: + resolution: {integrity: sha512-o0ornyJOWgygVAzGCpr8PdXV8EJLHyVGDDUr/voBQt8Azzw8cYTByzzPGcA/m4tCkPcnJA8raEOv2CslsKhPEw==} engines: {node: ^20.19 || ^22.12 || >=24.0} hasBin: true peerDependencies: @@ -5953,86 +4129,47 @@ packages: process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - process-warning@4.0.1: - resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} - - process-warning@5.0.0: - resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} - process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - prompts@2.4.2: - resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} - engines: {node: '>= 6'} - proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} + properties-reader@3.0.1: + resolution: {integrity: sha512-WPn+h9RGEExOKdu4bsF4HksG/uzd3cFq3MFtq8PsFeExPse5Ha/VOjQNyHhjboBFwGXGev6muJYTSPAOkROq2g==} + engines: {node: '>=18'} + + protobufjs@7.6.6: + resolution: {integrity: sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==} + engines: {node: '>=12.0.0'} proxy-compare@3.0.1: resolution: {integrity: sha512-V9plBAt3qjMlS1+nC8771KNf6oJ12gExvaxnNzN/9yVRLdTv/lc+oJlnSzrdYDAvBfTStPCoiaCOTmTs0adv7Q==} - pump@3.0.3: - resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} - - pumpify@2.0.1: - resolution: {integrity: sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==} - - punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.15.0: - resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} - engines: {node: '>=0.6'} - - qs@6.15.3: - resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} - engines: {node: '>=0.6'} - quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + quansync@1.0.0: + resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - quick-format-unescaped@4.0.4: - resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - - quick-lru@5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} - - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - - range-parser@1.3.0: - resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} - engines: {node: '>= 0.6'} - - raw-body@3.0.2: - resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} - engines: {node: '>= 0.10'} - - rc9@2.1.2: - resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + rc9@3.1.0: + resolution: {integrity: sha512-ufjkNVzbRHKcCOmTahZkmVsyc3W+MSk3jY03m+a7tGHkIsdVMG9l10/3HvFbWkkKzY5VFp3pkRsIo/UYgmFL7Q==} react-dom@19.2.4: resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} peerDependencies: react: ^19.2.4 - react-is@18.3.1: - resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} - react@19.2.4: resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} engines: {node: '>=0.10.0'} @@ -6048,31 +4185,20 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + readable-stream@4.8.0: + resolution: {integrity: sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} - real-require@0.2.0: - resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} - engines: {node: '>= 12.13.0'} - - reflect-metadata@0.2.2: - resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - - reflect.getprototypeof@1.0.10: - resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} - engines: {node: '>= 0.4'} - - regexp-to-ast@0.5.0: - resolution: {integrity: sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==} - - regexp.prototype.flags@1.5.4: - resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} - engines: {node: '>= 0.4'} + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} remeda@2.33.4: resolution: {integrity: sha512-ygHswjlc/opg2VrtiYvUOPLjxjtdKvjGz1/plDhkG66hjNjFr1xmfrs2ClNFo/E6TyUFiwYNh53bKV26oBoMGQ==} @@ -6085,13 +4211,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - resolve-alpn@1.2.1: - resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} - - resolve-cwd@3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -6103,28 +4222,11 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve.exports@2.0.3: - resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} - engines: {node: '>=10'} - resolve@1.22.11: resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} engines: {node: '>= 0.4'} hasBin: true - resolve@2.0.0-next.6: - resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} - engines: {node: '>= 0.4'} - hasBin: true - - responselike@3.0.0: - resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} - engines: {node: '>=14.16'} - - restore-cursor@3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - ret@0.5.0: resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==} engines: {node: '>=10'} @@ -6137,21 +4239,41 @@ packages: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - rfdc@1.4.1: - resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - robust-predicates@3.0.3: resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + rolldown-plugin-dts@0.28.7: + resolution: {integrity: sha512-o0lA6/NPzBAhMFgnIVJgW4eMBbMBQ8sXEbq4GqEHloerWMLqLNatpFy5AlWpEKskFShWKNghMMI8naul9Lgo5Q==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} + peerDependencies: + '@typescript/native-preview': '*' + '@volar/typescript': ~2.4.0 + '@vue/language-core': ~3.2.0 || ~3.3.0 + rolldown: ^1.2.0 + typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 + vue-tsc: ~3.2.0 || ~3.3.0 + peerDependenciesMeta: + '@typescript/native-preview': + optional: true + '@volar/typescript': + optional: true + '@vue/language-core': + optional: true + typescript: + optional: true + vue-tsc: + optional: true + + rolldown@1.2.13: + resolution: {integrity: sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.60.0: resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} - run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -6170,114 +4292,36 @@ packages: rw@1.3.3: resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} - rxjs@7.8.1: - resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} - - rxjs@7.8.2: - resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} - sade@1.8.1: resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} engines: {node: '>=6'} - safe-array-concat@1.1.3: - resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} - engines: {node: '>=0.4'} - safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-push-apply@1.0.0: - resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} - engines: {node: '>= 0.4'} - - safe-regex-test@1.1.0: - resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} - engines: {node: '>= 0.4'} - safe-regex2@5.0.0: resolution: {integrity: sha512-YwJwe5a51WlK7KbOJREPdjNrpViQBI3p4T50lfwPuDhZnE3XGVTlGvi+aolc5+RvxDD6bnUmjVsU9n1eboLUYw==} - safe-stable-stringify@2.5.0: - resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} - engines: {node: '>=10'} - safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} - schema-utils@3.3.0: - resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} - engines: {node: '>= 10.13.0'} - - schema-utils@4.3.3: - resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} - engines: {node: '>= 10.13.0'} - - secure-json-parse@4.1.0: - resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==} - - seek-bzip@2.0.0: - resolution: {integrity: sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg==} - hasBin: true - - semver-regex@4.0.5: - resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} - engines: {node: '>=12'} - - semver-truncate@3.0.0: - resolution: {integrity: sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==} - engines: {node: '>=12'} - - semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true - semver@7.7.4: resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} engines: {node: '>=10'} hasBin: true - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} - seq-queue@0.0.5: resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - - serve-static@2.2.1: - resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} - engines: {node: '>= 18'} - - set-cookie-parser@2.7.2: - resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} - set-cookie-parser@3.0.1: resolution: {integrity: sha512-n7Z7dXZhJbwuAHhNzkTti6Aw9QDDjZtm3JTpTGATIdNzdQz5GuFs22w90BcvF4INfnrL5xrX3oGsuqO5Dx3A1Q==} - set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} - - set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - - set-proto@1.0.0: - resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} - engines: {node: '>= 0.4'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -6286,30 +4330,6 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - side-channel-list@1.0.0: - resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} - engines: {node: '>= 0.4'} - - side-channel-list@1.0.1: - resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} - engines: {node: '>= 0.4'} - - side-channel-map@1.0.1: - resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} - engines: {node: '>= 0.4'} - - side-channel-weakmap@1.0.2: - resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} - engines: {node: '>= 0.4'} - - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} - engines: {node: '>= 0.4'} - - side-channel@1.1.1: - resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} - engines: {node: '>= 0.4'} - signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -6321,31 +4341,14 @@ packages: resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} - sisteransi@1.0.5: - resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - sonic-boom@4.2.1: - resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} - - sort-keys-length@1.0.1: - resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} - engines: {node: '>=0.10.0'} - - sort-keys@1.1.2: - resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} - engines: {node: '>=0.10.0'} - 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: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} - source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -6353,17 +4356,12 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - - source-map@0.7.6: - resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} - engines: {node: '>= 12'} - spawndamnit@3.0.1: resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + split-ca@1.0.1: + resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -6375,57 +4373,29 @@ packages: resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==} engines: {node: '>= 0.6'} - stable-hash-x@0.2.0: - resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} - engines: {node: '>=12.0.0'} - - stack-trace@0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - - stack-utils@2.0.6: - resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} - engines: {node: '>=10'} + ssh-remote-port-forward@1.0.4: + resolution: {integrity: sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ==} - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} + ssh2@1.17.0: + resolution: {integrity: sha512-wPldCk3asibAjQ/kziWQQt1Wh3PgDFpC0XpwclzKcdT1vql6KeYxf5LIt4nlFkUeR8WuphYMKqUA56X4rjbfgQ==} + engines: {node: '>=10.16.0'} std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} - stop-iteration-iterator@1.1.0: - resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} - engines: {node: '>= 0.4'} - - stream-shift@1.0.3: - resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} - - streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - - streamx@2.23.0: - resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==} + std-env@4.3.0: + resolution: {integrity: sha512-OtU/EgQ1kIm5KwqQpBC6ZEMXrZRui11w8zgfTWp8cdO9B8OaPsbA8bTHO2P+HNo1VlUTGMVBwPhydu6poeXiag==} - string-length@4.0.2: - resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} - engines: {node: '>=10'} + streamx@2.28.1: + resolution: {integrity: sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} - engines: {node: '>= 0.4'} - - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} - engines: {node: '>= 0.4'} - - string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} @@ -6437,45 +4407,14 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} - strip-bom@4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - - strip-dirs@3.0.0: - resolution: {integrity: sha512-I0sdgcFTfKQlUPZyAqPJmSG3HLO9rWDFnxonnIbskYNM3DwFOeTNB5KzVq3dA1GdRAc/25b5Y7UO2TQfKWw4aQ==} - - strip-final-newline@2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - - strtok3@10.3.4: - resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} - engines: {node: '>=18'} - - superagent@10.3.0: - resolution: {integrity: sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==} - engines: {node: '>=14.18.0'} - - supertest@7.2.2: - resolution: {integrity: sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==} - engines: {node: '>=14.18.0'} - - supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} - supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -6492,19 +4431,9 @@ packages: resolution: {integrity: sha512-/d0QHehmRuJW8gVz395MTkPcPozxzdjBMBE8oEYGz8O3b9KTMzzQ9ZHJQLuFKOHOPQbU6kx/X4iid/EBBzH7iw==} engines: {node: '>=18'} - swagger-themes@1.4.3: - resolution: {integrity: sha512-1G0CqJC1IBbNxkAOyJoREd9hfwXH1R6+3GOFxLhQho2w2i+AbaJqkF4mTJhkce4yhaEMUXvv4KKu1YO/qpe6nQ==} - - swagger-ui-dist@5.31.0: - resolution: {integrity: sha512-zSUTIck02fSga6rc0RZP3b7J7wgHXwLea8ZjgLA3Vgnb8QeOl3Wou2/j5QkzSGeoz6HusP/coYuJl33aQxQZpg==} - - symbol-observable@4.0.0: - resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} - engines: {node: '>=0.10'} - - synckit@0.11.12: - resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} - engines: {node: ^14.18.0 || >=16.0.0} + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} tailwind-merge@3.6.0: resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} @@ -6512,304 +4441,194 @@ packages: tailwindcss@4.3.1: resolution: {integrity: sha512-hk+TB1m+K8CYNrP6rjQaq/Y+4Zylwpa87mLYBKCunwnnQ9p+fHb7kmSfGqyEJoxF/O6CDyABWVFEafNSYKll+Q==} - tapable@2.3.0: - resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} - engines: {node: '>=6'} - tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} + tar-fs@2.1.5: + resolution: {integrity: sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==} + + tar-fs@3.1.3: + resolution: {integrity: sha512-/hU4AXnIdZu+Gvl1pk0oI5f5HxWsCJRtY2aFaJdk9VvyL48DWU6iU5WAIPG+wIi1YvWA6eTJvIviP/tMAZZNwQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar-stream@3.2.2: + resolution: {integrity: sha512-+8NeqHRjQWH9nYlwo2gamAMImZCVzI4UoEgDpWorBt9OEfppiZn+uSkskzQKPWIZyji/C8fpWO7u69G0DX0tbg==} + + teex@1.0.1: + resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} term-size@2.2.1: resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} engines: {node: '>=8'} - terser-webpack-plugin@5.3.16: - resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} - engines: {node: '>= 10.13.0'} - peerDependencies: - '@swc/core': '*' - esbuild: '*' - uglify-js: '*' - webpack: ^5.1.0 - peerDependenciesMeta: - '@swc/core': - optional: true - esbuild: - optional: true - uglify-js: - optional: true - terser@5.46.0: resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} engines: {node: '>=10'} hasBin: true - test-exclude@6.0.0: - resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} - engines: {node: '>=8'} + testcontainers@12.2.0: + resolution: {integrity: sha512-Pd0c2eU0DdIuK+Pb3c+vmBUdKjDLgxZmPecQGESFAKyn5LTqSaSw8l7htfMlLwabb/QsUILe6XkxMJw8Ly/ThA==} + engines: {node: '>= 22.22'} text-decoder@1.2.7: resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} - text-hex@1.0.0: - resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} - - thread-stream@4.0.0: - resolution: {integrity: sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA==} - engines: {node: '>=20'} - - through2@2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - - through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tinybench@6.2.2: + resolution: {integrity: sha512-nIZ2N2dFpjBsg2hgitKu7mA+FvsIJuGJOwysRngmVRRmWgR/UyPjwJj8c/fT/dhm8EkHnF5EOogRf+0Z2qrimA==} + engines: {node: '>=20.0.0'} tinyexec@1.0.2: resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==} engines: {node: '>=18'} + tinyexec@1.3.1: + resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} + engines: {node: '>=18'} + tinyglobby@0.2.15: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + tinypool@2.1.0: resolution: {integrity: sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==} engines: {node: ^20.0.0 || >=22.0.0} - tmpl@1.0.5: - resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + tinypool@2.1.2: + resolution: {integrity: sha512-9YodfrxS9g9IbFr/KOjE5bAeJ0p61n3bW6mqvy0jtoeKd1kTW1Cxm0oulm6KX2lyM9Gl6WIe8nEbY7LWv5ZJww==} + engines: {node: ^20.0.0 || >=22.0.0} + + tinyrainbow@3.2.0: + resolution: {integrity: sha512-LgO3D9yZJjApUiuUfl9iFAwrtaX4+lok3wJIqttGoKCHlWUqHqbQpnxCf82L8FjgKsh4iGo78hqJwgL8F6To2A==} + engines: {node: '>=14.0.0'} + + tmp@0.2.7: + resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} + engines: {node: '>=14.14'} to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - toad-cache@3.7.0: - resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} - engines: {node: '>=12'} - - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - token-types@6.1.2: - resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} - engines: {node: '>=14.16'} - totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - triple-beam@1.4.1: - resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} - engines: {node: '>= 14.0.0'} - - ts-api-utils@2.4.0: - resolution: {integrity: sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA==} - engines: {node: '>=18.12'} - peerDependencies: - typescript: '>=4.8.4' + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true - ts-essentials@10.1.1: - resolution: {integrity: sha512-4aTB7KLHKmUvkjNj8V+EdnmuVTiECzn3K+zIbRthumvHu+j44x3w63xpfs0JL3NGIzGXqoQ7AV591xHO+XrOTw==} + tsconfck@3.1.6: + resolution: {integrity: sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==} + engines: {node: ^18 || >=20} + deprecated: unmaintained + hasBin: true peerDependencies: - typescript: '>=4.5.0' + typescript: ^5.0.0 peerDependenciesMeta: typescript: optional: true - ts-jest@29.4.6: - resolution: {integrity: sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==} - engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + tsdown@0.23.1: + resolution: {integrity: sha512-MSC2WSOts3in95J334/VIS7KPfor3eCSvndJ6KdoVj9Aak9Kh1aNfz9ws5owhdukuTNSXRdfkPEzA/ihpDD6SA==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} hasBin: true peerDependencies: - '@babel/core': '>=7.0.0-beta.0 <8' - '@jest/transform': ^29.0.0 || ^30.0.0 - '@jest/types': ^29.0.0 || ^30.0.0 - babel-jest: ^29.0.0 || ^30.0.0 - esbuild: '*' - jest: ^29.0.0 || ^30.0.0 - jest-util: ^29.0.0 || ^30.0.0 - typescript: '>=4.3 <6' + '@arethetypeswrong/core': ^0.18.1 + '@tsdown/css': 0.23.1 + '@tsdown/exe': 0.23.1 + '@vitejs/devtools': '*' + publint: ^0.3.8 + tsx: '*' + typescript: ^5.0.0 || ^6.0.0 || ^7.0.0 + unplugin-unused: '>=0.5.0' + unrun: '*' peerDependenciesMeta: - '@babel/core': + '@arethetypeswrong/core': + optional: true + '@tsdown/css': optional: true - '@jest/transform': + '@tsdown/exe': optional: true - '@jest/types': + '@vitejs/devtools': optional: true - babel-jest: + publint: optional: true - esbuild: + tsx: optional: true - jest-util: + typescript: optional: true - - ts-loader@9.5.4: - resolution: {integrity: sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==} - engines: {node: '>=12.0.0'} - peerDependencies: - typescript: '*' - webpack: ^5.0.0 - - ts-node@10.9.2: - resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} - hasBin: true - peerDependencies: - '@swc/core': '>=1.2.50' - '@swc/wasm': '>=1.2.50' - '@types/node': '*' - typescript: '>=2.7' - peerDependenciesMeta: - '@swc/core': + unplugin-unused: optional: true - '@swc/wasm': + unrun: optional: true - tsconfig-paths-webpack-plugin@4.2.0: - resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} - engines: {node: '>=10.13.0'} - - tsconfig-paths@3.15.0: - resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} - - tsconfig-paths@4.2.0: - resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} - engines: {node: '>=6'} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - - type-detect@4.0.8: - resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} - engines: {node: '>=4'} - - type-fest@0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - - type-fest@4.41.0: - resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} - engines: {node: '>=16'} - - type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} - - type-is@2.1.0: - resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} - engines: {node: '>= 18'} - - typed-array-buffer@1.0.3: - resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} - engines: {node: '>= 0.4'} - - typed-array-byte-length@1.0.3: - resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} - engines: {node: '>= 0.4'} - - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} - engines: {node: '>= 0.4'} - - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} - engines: {node: '>= 0.4'} + tsx@4.23.15: + resolution: {integrity: sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==} + engines: {node: '>=18.0.0'} + hasBin: true - typedarray@0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - typescript-eslint@8.56.0: - resolution: {integrity: sha512-c7toRLrotJ9oixgdW7liukZpsnq5CZ7PuKztubGYlNppuTqhIoWfhgHo/7EU0v06gS2l/x0i2NEFK1qMIf0rIg==} - 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.0.0' + type-fest@5.10.0: + resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==} + engines: {node: '>=20'} typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true - uglify-js@3.19.3: - resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} - engines: {node: '>=0.8.0'} + typescript@7.0.2: + resolution: {integrity: sha512-8FYau96o3NKOhbjKi/qNvG/W5jhzxkbdm5sj9AbZ/5T5sWqn3hJgLfGx27sRKZWTvyzCP8dLRBTf5tBTSRVUNA==} + engines: {node: '>=16.20.0'} hasBin: true - uid@2.0.2: - resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} - engines: {node: '>=8'} - - uint8array-extras@1.5.0: - resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} - engines: {node: '>=18'} - - unbox-primitive@1.1.0: - resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} - engines: {node: '>= 0.4'} + unconfig-core@7.5.0: + resolution: {integrity: sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==} - unbzip2-stream@1.4.3: - resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} + + undici@8.11.2: + resolution: {integrity: sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==} + engines: {node: '>=22.19.0'} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} - universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - - unrs-resolver@1.11.1: - resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} - - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - - uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - v8-compile-cache-lib@3.0.1: - resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} - - v8-to-istanbul@9.3.0: - resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} - engines: {node: '>=10.12.0'} - - valibot@1.2.0: - resolution: {integrity: sha512-mm1rxUsmOxzrwnX5arGS+U4T25RdvpPjPN4yR0u9pUBov9+zGVtO84tif1eY4r6zWxVxu3KzIyknJy3rxfRZZg==} + valibot@1.4.2: + resolution: {integrity: sha512-gjdCvJ6d3RyHAneqxMYMW9QMCwYMb3jpOO0IyHZV1bnRHFBHrX3VkIILt5XYR0WhwHiH7Mty8ovuPZ/O3gamrg==} peerDependencies: typescript: '>=5' peerDependenciesMeta: typescript: optional: true - validator@13.15.35: - resolution: {integrity: sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==} - engines: {node: '>= 0.10'} - - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} + verkit@0.5.0: + resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} + engines: {node: '>=18.12.0'} virtua@0.49.2: resolution: {integrity: sha512-aEp3+6cmIRjHUlQnWdgGXYMYtrIG26QnN9jJDZEE5LRhvo1Z9HzoJwLDgyVULUPWcSdCnZAroQm7raXJyTG0AA==} @@ -6831,6 +4650,11 @@ packages: vue: optional: true + vite-tsconfig-paths@6.1.1: + resolution: {integrity: sha512-2cihq7zliibCCZ8P9cKJrQBkfgdvcFkOOc3Y02o3GWUDLgqjWsZudaoiuOwO/gzTzy17cS5F7ZPo4bsnS4DGkg==} + peerDependencies: + vite: '*' + vite@7.3.5: resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6879,89 +4703,68 @@ packages: vite: optional: true - walker@1.0.8: - resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} - - watchpack@2.5.1: - resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} - engines: {node: '>=10.13.0'} - - wcwidth@1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - - webpack-node-externals@3.0.0: - resolution: {integrity: sha512-LnL6Z3GGDPht/AigwRh2dvL9PQPFQ8skEpVrWZXLWBYmqcaojHNN0onvHzie6rq7EWKrrBfPYqNEzTJgiwEQDQ==} - engines: {node: '>=6'} - - webpack-sources@3.3.4: - resolution: {integrity: sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==} - engines: {node: '>=10.13.0'} - - webpack@5.104.1: - resolution: {integrity: sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==} - engines: {node: '>=10.13.0'} + vitest@5.0.3: + resolution: {integrity: sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==} + engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} hasBin: true peerDependencies: - webpack-cli: '*' + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^22.0.0 || >=24.0.0 + '@vitest/browser-playwright': 5.0.3 + '@vitest/browser-preview': 5.0.3 + '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 + '@vitest/coverage-istanbul': 5.0.3 + '@vitest/coverage-v8': 5.0.3 + '@vitest/ui': 5.0.3 + happy-dom: '*' + jsdom: '*' + vite: ^6.4.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: - webpack-cli: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: optional: true - - which-boxed-primitive@1.1.1: - resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} - engines: {node: '>= 0.4'} - - which-builtin-type@1.2.1: - resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} - engines: {node: '>= 0.4'} - - which-collection@1.0.2: - resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} - engines: {node: '>= 0.4'} - - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} - engines: {node: '>= 0.4'} which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} hasBin: true - winston-transport@4.9.0: - resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} - engines: {node: '>= 12.0.0'} - - winston@3.19.0: - resolution: {integrity: sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==} - engines: {node: '>= 12.0.0'} - - word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - - wordwrap@1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - - wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} + why-is-node-running@3.2.1: + resolution: {integrity: sha512-Tb2FUhB4vUsGQlfSquQLYkApkuPAFQXGFzxWKHHumVz2dK+X1RUm/HnID4+TfIGYJ1kTcwOaCk/buYCEJr6YjQ==} + engines: {node: '>=20.11'} + hasBin: true wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - write-file-atomic@4.0.2: - resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} - engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} - - write-file-atomic@5.0.1: - resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -6970,9 +4773,6 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} - yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} @@ -6986,21 +4786,21 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yauzl@3.2.0: - resolution: {integrity: sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==} - engines: {node: '>=12'} + yuku-ast@0.18.1: + resolution: {integrity: sha512-Y9YgmYeExF+13IOm4r9pTgmQiCVJtrhq014st78eAckWlCkbjzNd2AVrQHng5uiLz9j31O4sGYhuP3znSKJv9w==} + engines: {node: '>=14.18.0'} - yn@3.1.1: - resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} - engines: {node: '>=6'} + yuku-codegen@0.18.1: + resolution: {integrity: sha512-0tNgBfNHW6+tEBGEf1N20C6tDsFR9Vj344Ey01wgAMeP+j0zR5WBF8dyzOu5oA/n6Yz6YqV1ZcASdi0cin+q8A==} + engines: {node: '>=14.18.0'} - yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} + yuku-core@0.18.1: + resolution: {integrity: sha512-8PEOCKEi7r3nPY5cF0ZtJJSQj0ftwd0GC4En8fDQIP3nxw5ysSDwM0RcEuyHBblowRb82ad9AsExpqnKXAtC1Q==} + engines: {node: '>=14.18.0'} - yoctocolors-cjs@2.1.3: - resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} - engines: {node: '>=18'} + yuku-parser@0.18.1: + resolution: {integrity: sha512-t5pANCF6k9rgJre7jk8DMAU4lEoI1oWWZgXk0fcvmCYQquFVWv0rf6Awwt56nnPiHb0E24dhtrpfgf9ChTCbrQ==} + engines: {node: '>=14.18.0'} zeptomatch@2.1.0: resolution: {integrity: sha512-KiGErG2J0G82LSpniV0CtIzjlJ10E04j02VOudJsPyPwNZgGnRKQy7I1R7GMyg/QswnE4l7ohSGrQbQbjXPPDA==} @@ -7008,64 +4808,17 @@ packages: zimmerframe@1.1.4: resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} + zip-stream@6.0.1: + resolution: {integrity: sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==} + engines: {node: '>= 14'} + zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} -snapshots: - - '@angular-devkit/core@19.2.17(chokidar@4.0.3)': - dependencies: - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) - jsonc-parser: 3.3.1 - picomatch: 4.0.2 - rxjs: 7.8.1 - source-map: 0.7.4 - optionalDependencies: - chokidar: 4.0.3 - - '@angular-devkit/core@19.2.19(chokidar@4.0.3)': - dependencies: - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) - jsonc-parser: 3.3.1 - picomatch: 4.0.2 - rxjs: 7.8.1 - source-map: 0.7.4 - optionalDependencies: - chokidar: 4.0.3 - - '@angular-devkit/schematics-cli@19.2.19(@types/node@22.19.11)(chokidar@4.0.3)': - dependencies: - '@angular-devkit/core': 19.2.19(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.19(chokidar@4.0.3) - '@inquirer/prompts': 7.3.2(@types/node@22.19.11) - ansi-colors: 4.1.3 - symbol-observable: 4.0.0 - yargs-parser: 21.1.1 - transitivePeerDependencies: - - '@types/node' - - chokidar - - '@angular-devkit/schematics@19.2.17(chokidar@4.0.3)': - dependencies: - '@angular-devkit/core': 19.2.17(chokidar@4.0.3) - jsonc-parser: 3.3.1 - magic-string: 0.30.17 - ora: 5.4.1 - rxjs: 7.8.1 - transitivePeerDependencies: - - chokidar + zod@4.6.5: + resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} - '@angular-devkit/schematics@19.2.19(chokidar@4.0.3)': - dependencies: - '@angular-devkit/core': 19.2.19(chokidar@4.0.3) - jsonc-parser: 3.3.1 - magic-string: 0.30.17 - ora: 5.4.1 - rxjs: 7.8.1 - transitivePeerDependencies: - - chokidar +snapshots: '@babel/code-frame@7.29.0': dependencies: @@ -7073,231 +4826,57 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.29.0': {} + '@babel/helper-string-parser@7.29.7': {} - '@babel/core@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) - '@babel/helpers': 7.28.6 - '@babel/parser': 7.29.0 - '@babel/template': 7.28.6 - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + '@babel/helper-validator-identifier@7.28.5': {} - '@babel/generator@7.29.1': - dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - jsesc: 3.1.0 + '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-compilation-targets@7.28.6': + '@babel/parser@7.29.9': dependencies: - '@babel/compat-data': 7.29.0 - '@babel/helper-validator-option': 7.27.1 - browserslist: 4.28.1 - lru-cache: 5.1.1 - semver: 6.3.1 + '@babel/types': 7.29.8 - '@babel/helper-globals@7.28.0': {} - - '@babel/helper-module-imports@7.28.6': - dependencies: - '@babel/traverse': 7.29.0 - '@babel/types': 7.29.0 - transitivePeerDependencies: - - supports-color + '@babel/runtime@7.28.6': {} - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + '@babel/types@7.29.8': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0 - transitivePeerDependencies: - - supports-color - - '@babel/helper-plugin-utils@7.28.6': {} - - '@babel/helper-string-parser@7.27.1': {} - - '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 - '@babel/helper-validator-option@7.27.1': {} + '@balena/dockerignore@1.0.2': {} - '@babel/helpers@7.28.6': - dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + '@bcoe/v8-coverage@1.0.2': {} - '@babel/parser@7.29.0': + '@changesets/apply-release-plan@7.0.14': dependencies: - '@babel/types': 7.29.0 + '@changesets/config': 3.1.2 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.4 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.4 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)': + '@changesets/assemble-release-plan@6.0.9': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.4 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)': + '@changesets/changelog-git@0.2.1': dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 + '@changesets/types': 6.1.0 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': - dependencies: - '@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/runtime@7.28.6': {} - - '@babel/template@7.28.6': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - - '@babel/traverse@7.29.0': - dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.29.0 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - debug: 4.4.3 - transitivePeerDependencies: - - supports-color - - '@babel/types@7.29.0': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - - '@bcoe/v8-coverage@0.2.3': {} - - '@borewit/text-codec@0.2.1': {} - - '@changesets/apply-release-plan@7.0.14': - dependencies: - '@changesets/config': 3.1.2 - '@changesets/get-version-range-type': 0.4.0 - '@changesets/git': 3.0.4 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - detect-indent: 6.1.0 - fs-extra: 7.0.1 - lodash.startcase: 4.4.0 - outdent: 0.5.0 - prettier: 2.8.8 - resolve-from: 5.0.0 - semver: 7.7.4 - - '@changesets/assemble-release-plan@6.0.9': - dependencies: - '@changesets/errors': 0.2.0 - '@changesets/get-dependents-graph': 2.1.3 - '@changesets/should-skip-package': 0.1.2 - '@changesets/types': 6.1.0 - '@manypkg/get-packages': 1.1.3 - semver: 7.7.4 - - '@changesets/changelog-git@0.2.1': - dependencies: - '@changesets/types': 6.1.0 - - '@changesets/cli@2.29.8(@types/node@22.19.11)': + '@changesets/cli@2.29.8(@types/node@26.6.3)': dependencies: '@changesets/apply-release-plan': 7.0.14 '@changesets/assemble-release-plan': 6.0.9 @@ -7313,7 +4892,7 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@changesets/write': 0.4.0 - '@inquirer/external-editor': 1.0.3(@types/node@22.19.11) + '@inquirer/external-editor': 1.0.3(@types/node@26.6.3) '@manypkg/get-packages': 1.1.3 ansi-colors: 4.1.3 ci-info: 3.9.0 @@ -7412,31 +4991,11 @@ snapshots: human-id: 4.1.3 prettier: 2.8.8 - '@chevrotain/cst-dts-gen@10.5.0': - dependencies: - '@chevrotain/gast': 10.5.0 - '@chevrotain/types': 10.5.0 - lodash: 4.17.21 - - '@chevrotain/gast@10.5.0': - dependencies: - '@chevrotain/types': 10.5.0 - lodash: 4.17.21 - - '@chevrotain/types@10.5.0': {} - - '@chevrotain/utils@10.5.0': {} - - '@colors/colors@1.5.0': - optional: true - - '@colors/colors@1.6.0': {} - - '@commitlint/cli@20.4.2(@types/node@22.19.11)(typescript@5.9.3)': + '@commitlint/cli@20.4.2(@types/node@26.6.3)(typescript@7.0.2)': dependencies: '@commitlint/format': 20.4.0 '@commitlint/lint': 20.4.2 - '@commitlint/load': 20.4.0(@types/node@22.19.11)(typescript@5.9.3) + '@commitlint/load': 20.4.0(@types/node@26.6.3)(typescript@7.0.2) '@commitlint/read': 20.4.0 '@commitlint/types': 20.4.0 tinyexec: 1.0.2 @@ -7483,14 +5042,14 @@ snapshots: '@commitlint/rules': 20.4.2 '@commitlint/types': 20.4.0 - '@commitlint/load@20.4.0(@types/node@22.19.11)(typescript@5.9.3)': + '@commitlint/load@20.4.0(@types/node@26.6.3)(typescript@7.0.2)': dependencies: '@commitlint/config-validator': 20.4.0 '@commitlint/execute-rule': 20.0.0 '@commitlint/resolve-extends': 20.4.0 '@commitlint/types': 20.4.0 - cosmiconfig: 9.0.0(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.2.0(@types/node@22.19.11)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) + cosmiconfig: 9.0.0(typescript@7.0.2) + cosmiconfig-typescript-loader: 6.2.0(@types/node@26.6.3)(cosmiconfig@9.0.0(typescript@7.0.2))(typescript@7.0.2) is-plain-obj: 4.1.0 lodash.mergewith: 4.6.2 picocolors: 1.1.1 @@ -7541,1228 +5100,834 @@ snapshots: conventional-commits-parser: 6.2.1 picocolors: 1.1.1 - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - - '@dabh/diagnostics@2.0.8': - dependencies: - '@so-ric/colorspace': 1.1.6 - enabled: 2.0.0 - kuler: 2.0.0 - '@dagrejs/dagre@2.0.4': dependencies: '@dagrejs/graphlib': 3.0.4 '@dagrejs/graphlib@3.0.4': {} - '@electric-sql/pglite-socket@0.0.20(@electric-sql/pglite@0.3.15)': + '@electric-sql/pglite-socket@0.1.3(@electric-sql/pglite@0.4.3)': dependencies: - '@electric-sql/pglite': 0.3.15 + '@electric-sql/pglite': 0.4.3 - '@electric-sql/pglite-tools@0.2.20(@electric-sql/pglite@0.3.15)': + '@electric-sql/pglite-tools@0.3.3(@electric-sql/pglite@0.4.3)': dependencies: - '@electric-sql/pglite': 0.3.15 + '@electric-sql/pglite': 0.4.3 - '@electric-sql/pglite@0.3.15': {} + '@electric-sql/pglite@0.4.3': {} - '@emnapi/core@1.10.0': - dependencies: - '@emnapi/wasi-threads': 1.2.1 - tslib: 2.8.1 - optional: true + '@epic-web/invariant@1.0.0': {} - '@emnapi/runtime@1.10.0': - dependencies: - tslib: 2.8.1 + '@esbuild/aix-ppc64@0.27.3': optional: true - '@emnapi/wasi-threads@1.2.1': - dependencies: - tslib: 2.8.1 + '@esbuild/aix-ppc64@0.28.2': optional: true - '@epic-web/invariant@1.0.0': {} - - '@esbuild/aix-ppc64@0.27.3': + '@esbuild/android-arm64@0.27.3': optional: true - '@esbuild/android-arm64@0.27.3': + '@esbuild/android-arm64@0.28.2': optional: true '@esbuild/android-arm@0.27.3': optional: true + '@esbuild/android-arm@0.28.2': + optional: true + '@esbuild/android-x64@0.27.3': optional: true + '@esbuild/android-x64@0.28.2': + optional: true + '@esbuild/darwin-arm64@0.27.3': optional: true + '@esbuild/darwin-arm64@0.28.2': + optional: true + '@esbuild/darwin-x64@0.27.3': optional: true + '@esbuild/darwin-x64@0.28.2': + optional: true + '@esbuild/freebsd-arm64@0.27.3': optional: true + '@esbuild/freebsd-arm64@0.28.2': + optional: true + '@esbuild/freebsd-x64@0.27.3': optional: true + '@esbuild/freebsd-x64@0.28.2': + optional: true + '@esbuild/linux-arm64@0.27.3': optional: true + '@esbuild/linux-arm64@0.28.2': + optional: true + '@esbuild/linux-arm@0.27.3': optional: true + '@esbuild/linux-arm@0.28.2': + optional: true + '@esbuild/linux-ia32@0.27.3': optional: true + '@esbuild/linux-ia32@0.28.2': + optional: true + '@esbuild/linux-loong64@0.27.3': optional: true + '@esbuild/linux-loong64@0.28.2': + optional: true + '@esbuild/linux-mips64el@0.27.3': optional: true + '@esbuild/linux-mips64el@0.28.2': + optional: true + '@esbuild/linux-ppc64@0.27.3': optional: true + '@esbuild/linux-ppc64@0.28.2': + optional: true + '@esbuild/linux-riscv64@0.27.3': optional: true + '@esbuild/linux-riscv64@0.28.2': + optional: true + '@esbuild/linux-s390x@0.27.3': optional: true + '@esbuild/linux-s390x@0.28.2': + optional: true + '@esbuild/linux-x64@0.27.3': optional: true + '@esbuild/linux-x64@0.28.2': + optional: true + '@esbuild/netbsd-arm64@0.27.3': optional: true + '@esbuild/netbsd-arm64@0.28.2': + optional: true + '@esbuild/netbsd-x64@0.27.3': optional: true + '@esbuild/netbsd-x64@0.28.2': + optional: true + '@esbuild/openbsd-arm64@0.27.3': optional: true + '@esbuild/openbsd-arm64@0.28.2': + optional: true + '@esbuild/openbsd-x64@0.27.3': optional: true + '@esbuild/openbsd-x64@0.28.2': + optional: true + '@esbuild/openharmony-arm64@0.27.3': optional: true + '@esbuild/openharmony-arm64@0.28.2': + optional: true + '@esbuild/sunos-x64@0.27.3': optional: true + '@esbuild/sunos-x64@0.28.2': + optional: true + '@esbuild/win32-arm64@0.27.3': optional: true + '@esbuild/win32-arm64@0.28.2': + optional: true + '@esbuild/win32-ia32@0.27.3': optional: true - '@esbuild/win32-x64@0.27.3': + '@esbuild/win32-ia32@0.28.2': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@9.39.3(jiti@2.7.0))': - dependencies: - eslint: 9.39.3(jiti@2.7.0) - eslint-visitor-keys: 3.4.3 + '@esbuild/win32-x64@0.27.3': + optional: true - '@eslint-community/regexpp@4.12.2': {} + '@esbuild/win32-x64@0.28.2': + optional: true - '@eslint/config-array@0.21.1': + '@floating-ui/core@1.7.5': dependencies: - '@eslint/object-schema': 2.1.7 - debug: 4.4.3 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color + '@floating-ui/utils': 0.2.11 - '@eslint/config-helpers@0.4.2': + '@floating-ui/dom@1.7.6': dependencies: - '@eslint/core': 0.17.0 + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 - '@eslint/core@0.17.0': - dependencies: - '@types/json-schema': 7.0.15 + '@floating-ui/utils@0.2.11': {} - '@eslint/eslintrc@3.3.3': + '@grpc/grpc-js@1.14.6': 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.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color + '@grpc/proto-loader': 0.8.1 + '@js-sdsl/ordered-map': 4.4.2 - '@eslint/js@9.39.3': {} - - '@eslint/object-schema@2.1.7': {} - - '@eslint/plugin-kit@0.4.1': + '@grpc/proto-loader@0.7.15': dependencies: - '@eslint/core': 0.17.0 - levn: 0.4.1 - - '@fastify/accept-negotiator@2.0.1': {} + lodash.camelcase: 4.3.0 + long: 5.3.2 + protobufjs: 7.6.6 + yargs: 17.7.2 - '@fastify/ajv-compiler@4.0.5': + '@grpc/proto-loader@0.8.1': dependencies: - ajv: 8.18.0 - ajv-formats: 3.0.1(ajv@8.18.0) - fast-uri: 3.1.0 + lodash.camelcase: 4.3.0 + long: 5.3.2 + protobufjs: 7.6.6 + yargs: 17.7.2 - '@fastify/compress@8.3.1': - dependencies: - '@fastify/accept-negotiator': 2.0.1 - fastify-plugin: 5.1.0 - mime-db: 1.54.0 - minipass: 7.1.3 - peek-stream: 1.1.3 - pump: 3.0.3 - pumpify: 2.0.1 - readable-stream: 4.7.0 + '@hallmaster/docker.js@0.0.28': {} - '@fastify/cors@11.2.0': + '@hono/node-server@2.1.1(hono@4.13.9)': dependencies: - fastify-plugin: 5.1.0 - toad-cache: 3.7.0 + hono: 4.13.9 - '@fastify/error@4.2.0': {} - - '@fastify/fast-json-stringify-compiler@5.0.3': + '@hono/standard-validator@0.4.0(@standard-schema/spec@1.1.0)(hono@4.13.9)': dependencies: - fast-json-stringify: 6.3.0 + '@standard-schema/spec': 1.1.0 + hono: 4.13.9 - '@fastify/formbody@8.0.2': + '@inquirer/external-editor@1.0.3(@types/node@26.6.3)': dependencies: - fast-querystring: 1.1.2 - fastify-plugin: 5.1.0 - - '@fastify/forwarded@3.0.1': {} + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 26.6.3 - '@fastify/merge-json-schemas@0.2.1': + '@internationalized/date@3.12.0': dependencies: - dequal: 2.0.3 + '@swc/helpers': 0.5.18 - '@fastify/proxy-addr@5.1.0': + '@isaacs/cliui@8.0.2': dependencies: - '@fastify/forwarded': 3.0.1 - ipaddr.js: 2.3.0 + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 - '@fastify/send@4.1.0': + '@jridgewell/gen-mapping@0.3.13': dependencies: - '@lukeed/ms': 2.0.2 - escape-html: 1.0.3 - fast-decode-uri-component: 1.0.1 - http-errors: 2.0.1 - mime: 3.0.0 - optional: true + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 - '@fastify/static@8.3.0': + '@jridgewell/remapping@2.3.5': dependencies: - '@fastify/accept-negotiator': 2.0.1 - '@fastify/send': 4.1.0 - content-disposition: 0.5.4 - fastify-plugin: 5.1.0 - fastq: 1.20.1 - glob: 11.1.0 - optional: true + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 - '@floating-ui/core@1.7.5': - dependencies: - '@floating-ui/utils': 0.2.11 + '@jridgewell/resolve-uri@3.1.2': {} - '@floating-ui/dom@1.7.6': + '@jridgewell/source-map@0.3.11': dependencies: - '@floating-ui/core': 1.7.5 - '@floating-ui/utils': 0.2.11 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + optional: true - '@floating-ui/utils@0.2.11': {} + '@jridgewell/sourcemap-codec@1.5.5': {} - '@hallmaster/docker.js@0.0.28': {} + '@jridgewell/sourcemap-codec@1.6.0': {} - '@hono/node-server@1.19.9(hono@4.11.4)': + '@jridgewell/trace-mapping@0.3.31': dependencies: - hono: 4.11.4 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 - '@humanfs/core@0.19.1': {} + '@js-sdsl/ordered-map@4.4.2': {} - '@humanfs/node@0.16.7': + '@kwsites/file-exists@1.1.1': dependencies: - '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.4.3 - - '@humanwhocodes/module-importer@1.0.1': {} - - '@humanwhocodes/retry@0.4.3': {} + debug: 4.4.3 + transitivePeerDependencies: + - supports-color - '@inquirer/ansi@1.0.2': {} + '@layerstack/svelte-actions@1.0.1-next.18': + dependencies: + '@floating-ui/dom': 1.7.6 + '@layerstack/utils': 2.0.0-next.18 + d3-scale: 4.0.2 - '@inquirer/checkbox@4.3.2(@types/node@22.19.11)': + '@layerstack/svelte-state@0.1.0-next.23': dependencies: - '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.19.11) - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.19.11 + '@layerstack/utils': 2.0.0-next.18 - '@inquirer/confirm@5.1.21(@types/node@22.19.11)': + '@layerstack/tailwind@2.0.0-next.21': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/type': 3.0.10(@types/node@22.19.11) - optionalDependencies: - '@types/node': 22.19.11 + '@layerstack/utils': 2.0.0-next.18 + clsx: 2.1.1 + d3-array: 3.2.4 + tailwind-merge: 3.6.0 - '@inquirer/core@10.3.2(@types/node@22.19.11)': + '@layerstack/utils@2.0.0-next.18': dependencies: - '@inquirer/ansi': 1.0.2 - '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.19.11) - 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': 22.19.11 + d3-array: 3.2.4 + d3-time: 3.1.0 + d3-time-format: 4.1.0 - '@inquirer/editor@4.2.23(@types/node@22.19.11)': + '@lucide/svelte@0.553.0(svelte@5.56.4(@typescript-eslint/types@8.56.0))': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/external-editor': 1.0.3(@types/node@22.19.11) - '@inquirer/type': 3.0.10(@types/node@22.19.11) - optionalDependencies: - '@types/node': 22.19.11 + svelte: 5.56.4(@typescript-eslint/types@8.56.0) - '@inquirer/expand@4.0.23(@types/node@22.19.11)': + '@manypkg/find-root@1.1.0': dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/type': 3.0.10(@types/node@22.19.11) - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/external-editor@1.0.3(@types/node@22.19.11)': - dependencies: - chardet: 2.1.1 - iconv-lite: 0.7.2 - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/figures@1.0.15': {} - - '@inquirer/input@4.3.1(@types/node@22.19.11)': - dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/type': 3.0.10(@types/node@22.19.11) - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/number@3.0.23(@types/node@22.19.11)': - dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/type': 3.0.10(@types/node@22.19.11) - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/password@4.0.23(@types/node@22.19.11)': - dependencies: - '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/type': 3.0.10(@types/node@22.19.11) - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/prompts@7.10.1(@types/node@22.19.11)': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@22.19.11) - '@inquirer/confirm': 5.1.21(@types/node@22.19.11) - '@inquirer/editor': 4.2.23(@types/node@22.19.11) - '@inquirer/expand': 4.0.23(@types/node@22.19.11) - '@inquirer/input': 4.3.1(@types/node@22.19.11) - '@inquirer/number': 3.0.23(@types/node@22.19.11) - '@inquirer/password': 4.0.23(@types/node@22.19.11) - '@inquirer/rawlist': 4.1.11(@types/node@22.19.11) - '@inquirer/search': 3.2.2(@types/node@22.19.11) - '@inquirer/select': 4.4.2(@types/node@22.19.11) - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/prompts@7.3.2(@types/node@22.19.11)': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@22.19.11) - '@inquirer/confirm': 5.1.21(@types/node@22.19.11) - '@inquirer/editor': 4.2.23(@types/node@22.19.11) - '@inquirer/expand': 4.0.23(@types/node@22.19.11) - '@inquirer/input': 4.3.1(@types/node@22.19.11) - '@inquirer/number': 3.0.23(@types/node@22.19.11) - '@inquirer/password': 4.0.23(@types/node@22.19.11) - '@inquirer/rawlist': 4.1.11(@types/node@22.19.11) - '@inquirer/search': 3.2.2(@types/node@22.19.11) - '@inquirer/select': 4.4.2(@types/node@22.19.11) - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/rawlist@4.1.11(@types/node@22.19.11)': - dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/type': 3.0.10(@types/node@22.19.11) - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/search@3.2.2(@types/node@22.19.11)': - dependencies: - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.19.11) - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/select@4.4.2(@types/node@22.19.11)': - dependencies: - '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@22.19.11) - '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@22.19.11) - yoctocolors-cjs: 2.1.3 - optionalDependencies: - '@types/node': 22.19.11 - - '@inquirer/type@3.0.10(@types/node@22.19.11)': - optionalDependencies: - '@types/node': 22.19.11 - - '@internationalized/date@3.12.0': - dependencies: - '@swc/helpers': 0.5.18 - - '@isaacs/cliui@9.0.0': - optional: true - - '@istanbuljs/load-nyc-config@1.1.0': - dependencies: - camelcase: 5.3.1 + '@babel/runtime': 7.28.6 + '@types/node': 12.20.55 find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.2 - resolve-from: 5.0.0 - - '@istanbuljs/schema@0.1.3': {} - - '@jest/console@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3))': - dependencies: - '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - - '@jest/diff-sequences@30.0.1': {} - - '@jest/environment@29.7.0': - dependencies: - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - jest-mock: 29.7.0 - - '@jest/environment@30.2.0': - dependencies: - '@jest/fake-timers': 30.2.0 - '@jest/types': 30.2.0 - '@types/node': 22.19.11 - jest-mock: 30.2.0 - - '@jest/expect-utils@29.7.0': - dependencies: - jest-get-type: 29.6.3 - - '@jest/expect-utils@30.2.0': - dependencies: - '@jest/get-type': 30.1.0 - - '@jest/expect@29.7.0': - dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/expect@30.2.0': - dependencies: - expect: 30.2.0 - jest-snapshot: 30.2.0 - transitivePeerDependencies: - - supports-color - - '@jest/fake-timers@29.7.0': - dependencies: - '@jest/types': 29.6.3 - '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.19.11 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - '@jest/fake-timers@30.2.0': - dependencies: - '@jest/types': 30.2.0 - '@sinonjs/fake-timers': 13.0.5 - '@types/node': 22.19.11 - jest-message-util: 30.2.0 - jest-mock: 30.2.0 - jest-util: 30.2.0 - - '@jest/get-type@30.1.0': {} - - '@jest/globals@29.7.0': - dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/types': 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color - - '@jest/globals@30.2.0': - dependencies: - '@jest/environment': 30.2.0 - '@jest/expect': 30.2.0 - '@jest/types': 30.2.0 - jest-mock: 30.2.0 - transitivePeerDependencies: - - supports-color - - '@jest/pattern@30.0.1': - dependencies: - '@types/node': 22.19.11 - jest-regex-util: 30.0.1 - - '@jest/reporters@29.7.0': - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@jest/console': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.31 - '@types/node': 22.19.11 - chalk: 4.1.2 - collect-v8-coverage: 1.0.3 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.2.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color - - '@jest/schemas@29.6.3': - dependencies: - '@sinclair/typebox': 0.27.10 - - '@jest/schemas@30.0.5': - dependencies: - '@sinclair/typebox': 0.34.48 + fs-extra: 8.1.0 - '@jest/snapshot-utils@30.2.0': + '@manypkg/get-packages@1.1.3': dependencies: - '@jest/types': 30.2.0 - chalk: 4.1.2 - graceful-fs: 4.2.11 - natural-compare: 1.4.0 + '@babel/runtime': 7.28.6 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 - '@jest/source-map@29.6.3': + '@nodelib/fs.scandir@2.1.5': dependencies: - '@jridgewell/trace-mapping': 0.3.31 - callsites: 3.1.0 - graceful-fs: 4.2.11 + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 - '@jest/test-result@29.7.0': - dependencies: - '@jest/console': 29.7.0 - '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - collect-v8-coverage: 1.0.3 + '@nodelib/fs.stat@2.0.5': {} - '@jest/test-sequencer@29.7.0': + '@nodelib/fs.walk@1.2.8': dependencies: - '@jest/test-result': 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 - '@jest/transform@29.7.0': - dependencies: - '@babel/core': 7.29.0 - '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.31 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color + '@oxc-project/types@0.153.0': {} - '@jest/transform@30.2.0': - dependencies: - '@babel/core': 7.29.0 - '@jest/types': 30.2.0 - '@jridgewell/trace-mapping': 0.3.31 - babel-plugin-istanbul: 7.0.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 30.2.0 - jest-regex-util: 30.0.1 - jest-util: 30.2.0 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 5.0.1 - transitivePeerDependencies: - - supports-color + '@oxfmt/binding-android-arm-eabi@0.57.0': + optional: true - '@jest/types@29.6.3': - dependencies: - '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 22.19.11 - '@types/yargs': 17.0.35 - chalk: 4.1.2 + '@oxfmt/binding-android-arm-eabi@0.70.0': + optional: true - '@jest/types@30.2.0': - dependencies: - '@jest/pattern': 30.0.1 - '@jest/schemas': 30.0.5 - '@types/istanbul-lib-coverage': 2.0.6 - '@types/istanbul-reports': 3.0.4 - '@types/node': 22.19.11 - '@types/yargs': 17.0.35 - chalk: 4.1.2 + '@oxfmt/binding-android-arm64@0.57.0': + optional: true - '@jridgewell/gen-mapping@0.3.13': - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping': 0.3.31 + '@oxfmt/binding-android-arm64@0.70.0': + optional: true - '@jridgewell/remapping@2.3.5': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@oxfmt/binding-darwin-arm64@0.57.0': + optional: true - '@jridgewell/resolve-uri@3.1.2': {} + '@oxfmt/binding-darwin-arm64@0.70.0': + optional: true - '@jridgewell/source-map@0.3.11': - dependencies: - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 + '@oxfmt/binding-darwin-x64@0.57.0': + optional: true - '@jridgewell/sourcemap-codec@1.5.5': {} + '@oxfmt/binding-darwin-x64@0.70.0': + optional: true - '@jridgewell/trace-mapping@0.3.31': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@oxfmt/binding-freebsd-x64@0.57.0': + optional: true - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@oxfmt/binding-freebsd-x64@0.70.0': + optional: true - '@layerstack/svelte-actions@1.0.1-next.18': - dependencies: - '@floating-ui/dom': 1.7.6 - '@layerstack/utils': 2.0.0-next.18 - d3-scale: 4.0.2 + '@oxfmt/binding-linux-arm-gnueabihf@0.57.0': + optional: true - '@layerstack/svelte-state@0.1.0-next.23': - dependencies: - '@layerstack/utils': 2.0.0-next.18 + '@oxfmt/binding-linux-arm-gnueabihf@0.70.0': + optional: true - '@layerstack/tailwind@2.0.0-next.21': - dependencies: - '@layerstack/utils': 2.0.0-next.18 - clsx: 2.1.1 - d3-array: 3.2.4 - tailwind-merge: 3.6.0 + '@oxfmt/binding-linux-arm-musleabihf@0.57.0': + optional: true - '@layerstack/utils@2.0.0-next.18': - dependencies: - d3-array: 3.2.4 - d3-time: 3.1.0 - d3-time-format: 4.1.0 + '@oxfmt/binding-linux-arm-musleabihf@0.70.0': + optional: true - '@lucide/svelte@0.553.0(svelte@5.56.4(@typescript-eslint/types@8.56.0))': - dependencies: - svelte: 5.56.4(@typescript-eslint/types@8.56.0) + '@oxfmt/binding-linux-arm64-gnu@0.57.0': + optional: true - '@lukeed/csprng@1.1.0': {} + '@oxfmt/binding-linux-arm64-gnu@0.70.0': + optional: true - '@lukeed/ms@2.0.2': + '@oxfmt/binding-linux-arm64-musl@0.57.0': optional: true - '@manypkg/find-root@1.1.0': - dependencies: - '@babel/runtime': 7.28.6 - '@types/node': 12.20.55 - find-up: 4.1.0 - fs-extra: 8.1.0 + '@oxfmt/binding-linux-arm64-musl@0.70.0': + optional: true - '@manypkg/get-packages@1.1.3': - dependencies: - '@babel/runtime': 7.28.6 - '@changesets/types': 4.1.0 - '@manypkg/find-root': 1.1.0 - fs-extra: 8.1.0 - globby: 11.1.0 - read-yaml-file: 1.1.0 + '@oxfmt/binding-linux-ppc64-gnu@0.57.0': + optional: true - '@microsoft/tsdoc@0.16.0': {} + '@oxfmt/binding-linux-ppc64-gnu@0.70.0': + optional: true - '@mrleebo/prisma-ast@0.13.1': - dependencies: - chevrotain: 10.5.0 - lilconfig: 2.1.0 + '@oxfmt/binding-linux-riscv64-gnu@0.57.0': + optional: true - '@napi-rs/nice-android-arm-eabi@1.1.1': + '@oxfmt/binding-linux-riscv64-gnu@0.70.0': optional: true - '@napi-rs/nice-android-arm64@1.1.1': + '@oxfmt/binding-linux-riscv64-musl@0.57.0': optional: true - '@napi-rs/nice-darwin-arm64@1.1.1': + '@oxfmt/binding-linux-riscv64-musl@0.70.0': optional: true - '@napi-rs/nice-darwin-x64@1.1.1': + '@oxfmt/binding-linux-s390x-gnu@0.57.0': optional: true - '@napi-rs/nice-freebsd-x64@1.1.1': + '@oxfmt/binding-linux-s390x-gnu@0.70.0': optional: true - '@napi-rs/nice-linux-arm-gnueabihf@1.1.1': + '@oxfmt/binding-linux-x64-gnu@0.57.0': optional: true - '@napi-rs/nice-linux-arm64-gnu@1.1.1': + '@oxfmt/binding-linux-x64-gnu@0.70.0': optional: true - '@napi-rs/nice-linux-arm64-musl@1.1.1': + '@oxfmt/binding-linux-x64-musl@0.57.0': optional: true - '@napi-rs/nice-linux-ppc64-gnu@1.1.1': + '@oxfmt/binding-linux-x64-musl@0.70.0': optional: true - '@napi-rs/nice-linux-riscv64-gnu@1.1.1': + '@oxfmt/binding-openharmony-arm64@0.57.0': optional: true - '@napi-rs/nice-linux-s390x-gnu@1.1.1': + '@oxfmt/binding-openharmony-arm64@0.70.0': optional: true - '@napi-rs/nice-linux-x64-gnu@1.1.1': + '@oxfmt/binding-win32-arm64-msvc@0.57.0': optional: true - '@napi-rs/nice-linux-x64-musl@1.1.1': + '@oxfmt/binding-win32-arm64-msvc@0.70.0': optional: true - '@napi-rs/nice-openharmony-arm64@1.1.1': + '@oxfmt/binding-win32-ia32-msvc@0.57.0': optional: true - '@napi-rs/nice-win32-arm64-msvc@1.1.1': + '@oxfmt/binding-win32-ia32-msvc@0.70.0': optional: true - '@napi-rs/nice-win32-ia32-msvc@1.1.1': + '@oxfmt/binding-win32-x64-msvc@0.57.0': optional: true - '@napi-rs/nice-win32-x64-msvc@1.1.1': + '@oxfmt/binding-win32-x64-msvc@0.70.0': optional: true - '@napi-rs/nice@1.1.1': - optionalDependencies: - '@napi-rs/nice-android-arm-eabi': 1.1.1 - '@napi-rs/nice-android-arm64': 1.1.1 - '@napi-rs/nice-darwin-arm64': 1.1.1 - '@napi-rs/nice-darwin-x64': 1.1.1 - '@napi-rs/nice-freebsd-x64': 1.1.1 - '@napi-rs/nice-linux-arm-gnueabihf': 1.1.1 - '@napi-rs/nice-linux-arm64-gnu': 1.1.1 - '@napi-rs/nice-linux-arm64-musl': 1.1.1 - '@napi-rs/nice-linux-ppc64-gnu': 1.1.1 - '@napi-rs/nice-linux-riscv64-gnu': 1.1.1 - '@napi-rs/nice-linux-s390x-gnu': 1.1.1 - '@napi-rs/nice-linux-x64-gnu': 1.1.1 - '@napi-rs/nice-linux-x64-musl': 1.1.1 - '@napi-rs/nice-openharmony-arm64': 1.1.1 - '@napi-rs/nice-win32-arm64-msvc': 1.1.1 - '@napi-rs/nice-win32-ia32-msvc': 1.1.1 - '@napi-rs/nice-win32-x64-msvc': 1.1.1 - optional: true - - '@napi-rs/wasm-runtime@0.2.12': - dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@nestjs/cli@11.0.16(@swc/cli@0.6.0(@swc/core@1.15.11(@swc/helpers@0.5.18))(chokidar@4.0.3))(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)': - dependencies: - '@angular-devkit/core': 19.2.19(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.19(chokidar@4.0.3) - '@angular-devkit/schematics-cli': 19.2.19(@types/node@22.19.11)(chokidar@4.0.3) - '@inquirer/prompts': 7.10.1(@types/node@22.19.11) - '@nestjs/schematics': 11.0.9(chokidar@4.0.3)(typescript@5.9.3) - ansis: 4.2.0 - chokidar: 4.0.3 - cli-table3: 0.6.5 - commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18))) - glob: 13.0.0 - node-emoji: 1.11.0 - ora: 5.4.1 - tsconfig-paths: 4.2.0 - tsconfig-paths-webpack-plugin: 4.2.0 - typescript: 5.9.3 - webpack: 5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18)) - webpack-node-externals: 3.0.0 - optionalDependencies: - '@swc/cli': 0.6.0(@swc/core@1.15.11(@swc/helpers@0.5.18))(chokidar@4.0.3) - '@swc/core': 1.15.11(@swc/helpers@0.5.18) - transitivePeerDependencies: - - '@types/node' - - esbuild - - uglify-js - - webpack-cli - - '@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2)': - dependencies: - file-type: 21.3.0 - iterare: 1.2.1 - load-esm: 1.0.3 - reflect-metadata: 0.2.2 - rxjs: 7.8.2 - tslib: 2.8.1 - uid: 2.0.2 - optionalDependencies: - class-transformer: 0.5.1 - class-validator: 0.14.3 - transitivePeerDependencies: - - supports-color - - '@nestjs/config@4.0.3(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(rxjs@7.8.2)': - dependencies: - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - dotenv: 17.2.3 - dotenv-expand: 12.0.3 - lodash: 4.17.23 - rxjs: 7.8.2 - - '@nestjs/core@11.1.14(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)': - dependencies: - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nuxt/opencollective': 0.4.1 - fast-safe-stringify: 2.1.1 - iterare: 1.2.1 - path-to-regexp: 8.3.0 - reflect-metadata: 0.2.2 - rxjs: 7.8.2 - tslib: 2.8.1 - uid: 2.0.2 - optionalDependencies: - '@nestjs/platform-express': 11.1.13(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14) - - '@nestjs/jwt@11.0.2(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))': - dependencies: - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@types/jsonwebtoken': 9.0.10 - jsonwebtoken: 9.0.3 - - '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)': - dependencies: - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - reflect-metadata: 0.2.2 - optionalDependencies: - class-transformer: 0.5.1 - class-validator: 0.14.3 - - '@nestjs/platform-express@11.1.13(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)': - dependencies: - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.14(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) - cors: 2.8.6 - express: 5.2.1 - multer: 2.0.2 - path-to-regexp: 8.3.0 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color + '@oxlint-tsgolint/darwin-arm64@0.17.4': optional: true - '@nestjs/platform-fastify@11.1.14(@fastify/static@8.3.0)(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)': - dependencies: - '@fastify/cors': 11.2.0 - '@fastify/formbody': 8.0.2 - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.14(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) - fast-querystring: 1.1.2 - fastify: 5.7.4 - fastify-plugin: 5.1.0 - find-my-way: 9.4.0 - light-my-request: 6.6.0 - path-to-regexp: 8.3.0 - reusify: 1.1.0 - tslib: 2.8.1 - optionalDependencies: - '@fastify/static': 8.3.0 - - '@nestjs/schematics@11.0.9(chokidar@4.0.3)(typescript@5.9.3)': - dependencies: - '@angular-devkit/core': 19.2.17(chokidar@4.0.3) - '@angular-devkit/schematics': 19.2.17(chokidar@4.0.3) - comment-json: 4.4.1 - jsonc-parser: 3.3.1 - pluralize: 8.0.0 - typescript: 5.9.3 - transitivePeerDependencies: - - chokidar - - '@nestjs/swagger@11.2.6(@fastify/static@8.3.0)(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)': - dependencies: - '@microsoft/tsdoc': 0.16.0 - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.14(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2) - js-yaml: 4.1.1 - lodash: 4.17.23 - path-to-regexp: 8.3.0 - reflect-metadata: 0.2.2 - swagger-ui-dist: 5.31.0 - optionalDependencies: - '@fastify/static': 8.3.0 - class-transformer: 0.5.1 - class-validator: 0.14.3 - - '@nestjs/testing@11.1.14(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)(@nestjs/platform-express@11.1.13)': - dependencies: - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - '@nestjs/core': 11.1.14(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) - tslib: 2.8.1 - optionalDependencies: - '@nestjs/platform-express': 11.1.13(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14) - - '@noble/hashes@1.8.0': {} - - '@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 - - '@oxfmt/binding-android-arm-eabi@0.57.0': + '@oxlint-tsgolint/darwin-arm64@7.0.2003': optional: true - '@oxfmt/binding-android-arm64@0.57.0': + '@oxlint-tsgolint/darwin-x64@0.17.4': optional: true - '@oxfmt/binding-darwin-arm64@0.57.0': + '@oxlint-tsgolint/darwin-x64@7.0.2003': optional: true - '@oxfmt/binding-darwin-x64@0.57.0': + '@oxlint-tsgolint/linux-arm64@0.17.4': optional: true - '@oxfmt/binding-freebsd-x64@0.57.0': + '@oxlint-tsgolint/linux-arm64@7.0.2003': optional: true - '@oxfmt/binding-linux-arm-gnueabihf@0.57.0': + '@oxlint-tsgolint/linux-x64@0.17.4': optional: true - '@oxfmt/binding-linux-arm-musleabihf@0.57.0': + '@oxlint-tsgolint/linux-x64@7.0.2003': optional: true - '@oxfmt/binding-linux-arm64-gnu@0.57.0': + '@oxlint-tsgolint/win32-arm64@0.17.4': optional: true - '@oxfmt/binding-linux-arm64-musl@0.57.0': + '@oxlint-tsgolint/win32-arm64@7.0.2003': optional: true - '@oxfmt/binding-linux-ppc64-gnu@0.57.0': + '@oxlint-tsgolint/win32-x64@0.17.4': optional: true - '@oxfmt/binding-linux-riscv64-gnu@0.57.0': + '@oxlint-tsgolint/win32-x64@7.0.2003': optional: true - '@oxfmt/binding-linux-riscv64-musl@0.57.0': + '@oxlint/binding-android-arm-eabi@1.72.0': optional: true - '@oxfmt/binding-linux-s390x-gnu@0.57.0': + '@oxlint/binding-android-arm-eabi@1.85.0': optional: true - '@oxfmt/binding-linux-x64-gnu@0.57.0': + '@oxlint/binding-android-arm64@1.72.0': optional: true - '@oxfmt/binding-linux-x64-musl@0.57.0': + '@oxlint/binding-android-arm64@1.85.0': optional: true - '@oxfmt/binding-openharmony-arm64@0.57.0': + '@oxlint/binding-darwin-arm64@1.72.0': optional: true - '@oxfmt/binding-win32-arm64-msvc@0.57.0': + '@oxlint/binding-darwin-arm64@1.85.0': optional: true - '@oxfmt/binding-win32-ia32-msvc@0.57.0': + '@oxlint/binding-darwin-x64@1.72.0': optional: true - '@oxfmt/binding-win32-x64-msvc@0.57.0': + '@oxlint/binding-darwin-x64@1.85.0': optional: true - '@oxlint-tsgolint/darwin-arm64@0.17.4': + '@oxlint/binding-freebsd-x64@1.72.0': optional: true - '@oxlint-tsgolint/darwin-x64@0.17.4': + '@oxlint/binding-freebsd-x64@1.85.0': optional: true - '@oxlint-tsgolint/linux-arm64@0.17.4': + '@oxlint/binding-linux-arm-gnueabihf@1.72.0': optional: true - '@oxlint-tsgolint/linux-x64@0.17.4': + '@oxlint/binding-linux-arm-gnueabihf@1.85.0': optional: true - '@oxlint-tsgolint/win32-arm64@0.17.4': + '@oxlint/binding-linux-arm-musleabihf@1.72.0': optional: true - '@oxlint-tsgolint/win32-x64@0.17.4': + '@oxlint/binding-linux-arm-musleabihf@1.85.0': optional: true - '@oxlint/binding-android-arm-eabi@1.72.0': + '@oxlint/binding-linux-arm64-gnu@1.72.0': optional: true - '@oxlint/binding-android-arm64@1.72.0': + '@oxlint/binding-linux-arm64-gnu@1.85.0': optional: true - '@oxlint/binding-darwin-arm64@1.72.0': + '@oxlint/binding-linux-arm64-musl@1.72.0': optional: true - '@oxlint/binding-darwin-x64@1.72.0': + '@oxlint/binding-linux-arm64-musl@1.85.0': optional: true - '@oxlint/binding-freebsd-x64@1.72.0': + '@oxlint/binding-linux-ppc64-gnu@1.72.0': optional: true - '@oxlint/binding-linux-arm-gnueabihf@1.72.0': + '@oxlint/binding-linux-ppc64-gnu@1.85.0': optional: true - '@oxlint/binding-linux-arm-musleabihf@1.72.0': + '@oxlint/binding-linux-riscv64-gnu@1.72.0': optional: true - '@oxlint/binding-linux-arm64-gnu@1.72.0': + '@oxlint/binding-linux-riscv64-gnu@1.85.0': optional: true - '@oxlint/binding-linux-arm64-musl@1.72.0': + '@oxlint/binding-linux-riscv64-musl@1.72.0': optional: true - '@oxlint/binding-linux-ppc64-gnu@1.72.0': + '@oxlint/binding-linux-riscv64-musl@1.85.0': optional: true - '@oxlint/binding-linux-riscv64-gnu@1.72.0': + '@oxlint/binding-linux-s390x-gnu@1.72.0': optional: true - '@oxlint/binding-linux-riscv64-musl@1.72.0': + '@oxlint/binding-linux-s390x-gnu@1.85.0': optional: true - '@oxlint/binding-linux-s390x-gnu@1.72.0': + '@oxlint/binding-linux-x64-gnu@1.72.0': optional: true - '@oxlint/binding-linux-x64-gnu@1.72.0': + '@oxlint/binding-linux-x64-gnu@1.85.0': optional: true '@oxlint/binding-linux-x64-musl@1.72.0': optional: true + '@oxlint/binding-linux-x64-musl@1.85.0': + optional: true + '@oxlint/binding-openharmony-arm64@1.72.0': optional: true + '@oxlint/binding-openharmony-arm64@1.85.0': + optional: true + '@oxlint/binding-win32-arm64-msvc@1.72.0': optional: true + '@oxlint/binding-win32-arm64-msvc@1.85.0': + optional: true + '@oxlint/binding-win32-ia32-msvc@1.72.0': optional: true + '@oxlint/binding-win32-ia32-msvc@1.85.0': + optional: true + '@oxlint/binding-win32-x64-msvc@1.72.0': optional: true - '@paralleldrive/cuid2@2.3.1': - dependencies: - '@noble/hashes': 1.8.0 + '@oxlint/binding-win32-x64-msvc@1.85.0': + optional: true '@phc/format@1.0.0': {} - '@pinojs/redact@0.4.0': {} - - '@pkgr/core@0.2.9': {} + '@pkgjs/parseargs@0.11.0': + optional: true '@polka/url@1.0.0-next.29': {} - '@prisma/adapter-pg@7.4.1': + '@prisma/adapter-pg@7.10.0': dependencies: - '@prisma/driver-adapter-utils': 7.4.1 - pg: 8.18.0 + '@prisma/driver-adapter-utils': 7.10.0 + '@types/pg': 8.23.1 + pg: 8.23.0 postgres-array: 3.0.4 transitivePeerDependencies: - pg-native '@prisma/client-runtime-utils@7.4.1': {} - '@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3)': + '@prisma/client@7.4.1(prisma@7.10.0(@types/react@19.2.11)(magicast@0.5.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@7.0.2))(typescript@7.0.2)': dependencies: '@prisma/client-runtime-utils': 7.4.1 optionalDependencies: - prisma: 7.4.1(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - typescript: 5.9.3 + prisma: 7.10.0(@types/react@19.2.11)(magicast@0.5.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@7.0.2) + typescript: 7.0.2 - '@prisma/config@7.4.1': + '@prisma/config@7.10.0(magicast@0.5.5)': dependencies: - c12: 3.1.0 + c12: 3.3.4(magicast@0.5.5) deepmerge-ts: 7.1.5 - effect: 3.18.4 + effect: 3.20.0 empathic: 2.0.0 transitivePeerDependencies: - magicast - '@prisma/debug@7.2.0': {} + '@prisma/debug@7.10.0': {} - '@prisma/debug@7.4.1': {} + '@prisma/debug@7.2.0': {} - '@prisma/dev@0.20.0(typescript@5.9.3)': + '@prisma/dev@0.24.17(typescript@7.0.2)': dependencies: - '@electric-sql/pglite': 0.3.15 - '@electric-sql/pglite-socket': 0.0.20(@electric-sql/pglite@0.3.15) - '@electric-sql/pglite-tools': 0.2.20(@electric-sql/pglite@0.3.15) - '@hono/node-server': 1.19.9(hono@4.11.4) - '@mrleebo/prisma-ast': 0.13.1 + '@electric-sql/pglite': 0.4.3 + '@electric-sql/pglite-socket': 0.1.3(@electric-sql/pglite@0.4.3) + '@electric-sql/pglite-tools': 0.3.3(@electric-sql/pglite@0.4.3) '@prisma/get-platform': 7.2.0 '@prisma/query-plan-executor': 7.2.0 + '@prisma/streams-local': 0.1.11 + find-my-way: 9.7.0 foreground-child: 3.3.1 get-port-please: 3.2.0 - hono: 4.11.4 - http-status-codes: 2.3.0 pathe: 2.0.3 proper-lockfile: 4.1.2 remeda: 2.33.4 std-env: 3.10.0 - valibot: 1.2.0(typescript@5.9.3) + valibot: 1.4.2(typescript@7.0.2) zeptomatch: 2.1.0 transitivePeerDependencies: - typescript - '@prisma/driver-adapter-utils@7.4.1': + '@prisma/driver-adapter-utils@7.10.0': dependencies: - '@prisma/debug': 7.4.1 + '@prisma/debug': 7.10.0 + + '@prisma/engines-version@7.10.0-4.0edf323efd1d98336f3f0a68684b56f689b900d3': {} - '@prisma/engines-version@7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3': {} + '@prisma/engines@7.10.0': + dependencies: + '@prisma/debug': 7.10.0 + '@prisma/engines-version': 7.10.0-4.0edf323efd1d98336f3f0a68684b56f689b900d3 + '@prisma/fetch-engine': 7.10.0 + '@prisma/get-platform': 7.10.0 - '@prisma/engines@7.4.1': + '@prisma/fetch-engine@7.10.0': dependencies: - '@prisma/debug': 7.4.1 - '@prisma/engines-version': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 - '@prisma/fetch-engine': 7.4.1 - '@prisma/get-platform': 7.4.1 + '@prisma/debug': 7.10.0 + '@prisma/engines-version': 7.10.0-4.0edf323efd1d98336f3f0a68684b56f689b900d3 + '@prisma/get-platform': 7.10.0 - '@prisma/fetch-engine@7.4.1': + '@prisma/get-platform@7.10.0': dependencies: - '@prisma/debug': 7.4.1 - '@prisma/engines-version': 7.5.0-4.55ae170b1ced7fc6ed07a15f110549408c501bb3 - '@prisma/get-platform': 7.4.1 + '@prisma/debug': 7.10.0 '@prisma/get-platform@7.2.0': dependencies: '@prisma/debug': 7.2.0 - '@prisma/get-platform@7.4.1': + '@prisma/query-plan-executor@7.2.0': {} + + '@prisma/streams-local@0.1.11': dependencies: - '@prisma/debug': 7.4.1 + ajv: 8.18.0 + better-result: 2.10.0 + env-paths: 3.0.0 + proper-lockfile: 4.1.2 - '@prisma/query-plan-executor@7.2.0': {} + '@prisma/studio-core@0.33.0(@types/react@19.2.11)(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.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@types/react': 19.2.11 + '@visx/curve': 4.0.1-alpha.0 + '@visx/event': 4.0.1-alpha.0 + '@visx/grid': 4.0.1-alpha.0(react@19.2.4) + '@visx/group': 4.0.1-alpha.0(react@19.2.4) + '@visx/responsive': 4.0.1-alpha.0(react@19.2.4) + '@visx/scale': 4.0.1-alpha.0 + '@visx/shape': 4.0.1-alpha.0(react@19.2.4) + d3-array: 3.2.4 + d3-shape: 3.2.0 + elkjs: 0.11.1 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + transitivePeerDependencies: + - '@types/react-dom' + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.5': {} + + '@protobufjs/eventemitter@1.1.1': {} + + '@protobufjs/fetch@1.1.1': + dependencies: + '@protobufjs/aspromise': 1.1.2 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} - '@prisma/studio-core@0.13.1(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + '@protobufjs/utf8@1.1.2': {} + + '@quansync/fs@1.1.0': + dependencies: + quansync: 1.0.0 + + '@radix-ui/primitive@1.1.3': {} + + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.11)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.11 + + '@radix-ui/react-primitive@2.1.3(@types/react@19.2.11)(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.11)(react@19.2.4) + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.11 + + '@radix-ui/react-slot@1.2.3(@types/react@19.2.11)(react@19.2.4)': dependencies: + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + optionalDependencies: '@types/react': 19.2.11 + + '@radix-ui/react-toggle@1.1.10(@types/react@19.2.11)(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.11)(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.11)(react@19.2.4) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.11 + + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.11)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.11)(react@19.2.4) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.11 + + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.11)(react@19.2.4)': + dependencies: + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.11)(react@19.2.4) + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.11 + + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.11)(react@19.2.4)': + dependencies: + react: 19.2.4 + optionalDependencies: + '@types/react': 19.2.11 + + '@rolldown/binding-android-arm-eabi@1.2.13': + optional: true + + '@rolldown/binding-android-arm64@1.2.13': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.13': + optional: true + + '@rolldown/binding-darwin-x64@1.2.13': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.13': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.13': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.13': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.13': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.13': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.13': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.13': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.13': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.13': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.13': + optional: true + + '@rolldown/pluginutils@1.0.1': {} '@rollup/plugin-commonjs@29.0.2(rollup@4.60.0)': dependencies: @@ -8875,27 +6040,33 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.60.0': optional: true - '@rtsao/scc@1.1.0': {} - - '@scarf/scarf@1.4.0': {} - - '@sinclair/typebox@0.27.10': {} - - '@sinclair/typebox@0.34.48': {} + '@scalar/client-side-rendering@0.4.5': + dependencies: + '@scalar/helpers': 0.15.0 + '@scalar/schemas': 0.12.1 + '@scalar/types': 0.22.1 + '@scalar/validation': 0.6.5 - '@sindresorhus/is@5.6.0': {} + '@scalar/helpers@0.15.0': {} - '@sinonjs/commons@3.0.1': + '@scalar/hono-api-reference@0.12.6(hono@4.13.9)': dependencies: - type-detect: 4.0.8 + '@scalar/client-side-rendering': 0.4.5 + hono: 4.13.9 - '@sinonjs/fake-timers@10.3.0': + '@scalar/schemas@0.12.1': dependencies: - '@sinonjs/commons': 3.0.1 + '@scalar/helpers': 0.15.0 + '@scalar/validation': 0.6.5 - '@sinonjs/fake-timers@13.0.5': + '@scalar/types@0.22.1': dependencies: - '@sinonjs/commons': 3.0.1 + '@scalar/helpers': 0.15.0 + nanoid: 5.1.16 + type-fest: 5.10.0 + zod: 4.6.5 + + '@scalar/validation@0.6.5': {} '@skeletonlabs/skeleton-common@4.15.2': {} @@ -8936,10 +6107,25 @@ snapshots: dependencies: tailwindcss: 4.3.1 - '@so-ric/colorspace@1.1.6': + '@standard-community/standard-json@0.3.6(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(effect@3.20.0)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5)': dependencies: - color: 5.0.3 - text-hex: 1.0.0 + '@standard-schema/spec': 1.1.0 + '@types/json-schema': 7.0.15 + quansync: 0.2.11 + optionalDependencies: + effect: 3.20.0 + valibot: 1.4.2(typescript@7.0.2) + zod: 4.6.5 + + '@standard-community/standard-openapi@0.2.10(@standard-community/standard-json@0.3.6(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(effect@3.20.0)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5))(@standard-schema/spec@1.1.0)(effect@3.20.0)(openapi-types@12.1.3)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5)': + dependencies: + '@standard-community/standard-json': 0.3.6(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(effect@3.20.0)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5) + '@standard-schema/spec': 1.1.0 + openapi-types: 12.1.3 + optionalDependencies: + effect: 3.20.0 + valibot: 1.4.2(typescript@7.0.2) + zod: 4.6.5 '@standard-schema/spec@1.1.0': {} @@ -8951,19 +6137,19 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/adapter-node@5.5.4(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))': + '@sveltejs/adapter-node@5.5.4(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))': dependencies: '@rollup/plugin-commonjs': 29.0.2(rollup@4.60.0) '@rollup/plugin-json': 6.1.0(rollup@4.60.0) '@rollup/plugin-node-resolve': 16.0.3(rollup@4.60.0) - '@sveltejs/kit': 2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + '@sveltejs/kit': 2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) rollup: 4.60.0 - '@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0))': + '@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0))': dependencies: '@standard-schema/spec': 1.1.0 '@sveltejs/acorn-typescript': 1.0.9(acorn@8.16.0) - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) '@types/cookie': 0.6.0 acorn: 8.16.0 cookie: 0.6.0 @@ -8975,108 +6161,32 @@ snapshots: set-cookie-parser: 3.0.1 sirv: 3.0.2 svelte: 5.56.4(@typescript-eslint/types@8.56.0) - vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0) + vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) optionalDependencies: typescript: 5.9.3 '@sveltejs/load-config@0.2.0': {} - '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + '@sveltejs/vite-plugin-svelte': 6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) obug: 2.1.1 svelte: 5.56.4(@typescript-eslint/types@8.56.0) - vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0) + vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) - '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0))': + '@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + '@sveltejs/vite-plugin-svelte-inspector': 5.0.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) deepmerge: 4.3.1 magic-string: 0.30.21 obug: 2.1.1 svelte: 5.56.4(@typescript-eslint/types@8.56.0) - vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0) - vitefu: 1.1.1(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) + vitefu: 1.1.1(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) - '@swc/cli@0.6.0(@swc/core@1.15.11(@swc/helpers@0.5.18))(chokidar@4.0.3)': + '@swc/helpers@0.5.18': dependencies: - '@swc/core': 1.15.11(@swc/helpers@0.5.18) - '@swc/counter': 0.1.3 - '@xhmikosr/bin-wrapper': 13.2.0 - commander: 8.3.0 - fast-glob: 3.3.3 - minimatch: 9.0.5 - piscina: 4.9.2 - semver: 7.7.4 - slash: 3.0.0 - source-map: 0.7.6 - optionalDependencies: - chokidar: 4.0.3 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - supports-color - - '@swc/core-darwin-arm64@1.15.11': - optional: true - - '@swc/core-darwin-x64@1.15.11': - optional: true - - '@swc/core-linux-arm-gnueabihf@1.15.11': - optional: true - - '@swc/core-linux-arm64-gnu@1.15.11': - optional: true - - '@swc/core-linux-arm64-musl@1.15.11': - optional: true - - '@swc/core-linux-x64-gnu@1.15.11': - optional: true - - '@swc/core-linux-x64-musl@1.15.11': - optional: true - - '@swc/core-win32-arm64-msvc@1.15.11': - optional: true - - '@swc/core-win32-ia32-msvc@1.15.11': - optional: true - - '@swc/core-win32-x64-msvc@1.15.11': - optional: true - - '@swc/core@1.15.11(@swc/helpers@0.5.18)': - dependencies: - '@swc/counter': 0.1.3 - '@swc/types': 0.1.25 - optionalDependencies: - '@swc/core-darwin-arm64': 1.15.11 - '@swc/core-darwin-x64': 1.15.11 - '@swc/core-linux-arm-gnueabihf': 1.15.11 - '@swc/core-linux-arm64-gnu': 1.15.11 - '@swc/core-linux-arm64-musl': 1.15.11 - '@swc/core-linux-x64-gnu': 1.15.11 - '@swc/core-linux-x64-musl': 1.15.11 - '@swc/core-win32-arm64-msvc': 1.15.11 - '@swc/core-win32-ia32-msvc': 1.15.11 - '@swc/core-win32-x64-msvc': 1.15.11 - '@swc/helpers': 0.5.18 - - '@swc/counter@0.1.3': {} - - '@swc/helpers@0.5.18': - dependencies: - tslib: 2.8.1 - - '@swc/types@0.1.25': - dependencies: - '@swc/counter': 0.1.3 - - '@szmarczak/http-timer@5.0.1': - dependencies: - defer-to-connect: 2.0.1 + tslib: 2.8.1 '@tailwindcss/node@4.3.1': dependencies: @@ -9139,138 +6249,106 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.3.1 '@tailwindcss/oxide-win32-x64-msvc': 4.3.1 - '@tailwindcss/vite@4.3.1(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0))': + '@tailwindcss/vite@4.3.1(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0))': dependencies: '@tailwindcss/node': 4.3.1 '@tailwindcss/oxide': 4.3.1 tailwindcss: 4.3.1 - vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0) + vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) - '@tokenizer/inflate@0.2.7': + '@testcontainers/postgresql@12.2.0': dependencies: - debug: 4.4.3 - fflate: 0.8.2 - token-types: 6.1.2 + testcontainers: 12.2.0 transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a - supports-color - '@tokenizer/inflate@0.4.1': + '@types/chai@5.2.3': dependencies: - debug: 4.4.3 - token-types: 6.1.2 - transitivePeerDependencies: - - supports-color + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 - '@tokenizer/token@0.3.0': {} - - '@tsconfig/node10@1.0.12': {} + '@types/cookie@0.6.0': {} - '@tsconfig/node12@1.0.11': {} + '@types/d3-array@3.0.3': {} - '@tsconfig/node14@1.0.3': {} + '@types/d3-array@3.2.2': {} - '@tsconfig/node16@1.0.4': {} + '@types/d3-color@3.1.0': {} - '@tybys/wasm-util@0.10.1': + '@types/d3-contour@3.0.6': dependencies: - tslib: 2.8.1 - optional: true + '@types/d3-array': 3.2.2 + '@types/geojson': 7946.0.16 - '@types/babel__core@7.20.5': - dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 - '@types/babel__generator': 7.27.0 - '@types/babel__template': 7.4.4 - '@types/babel__traverse': 7.28.0 + '@types/d3-delaunay@6.0.1': {} - '@types/babel__generator@7.27.0': - dependencies: - '@babel/types': 7.29.0 + '@types/d3-format@3.0.1': {} - '@types/babel__template@7.4.4': + '@types/d3-geo@3.1.0': dependencies: - '@babel/parser': 7.29.0 - '@babel/types': 7.29.0 + '@types/geojson': 7946.0.16 - '@types/babel__traverse@7.28.0': + '@types/d3-interpolate@3.0.1': dependencies: - '@babel/types': 7.29.0 - - '@types/cookie@0.6.0': {} - - '@types/cookiejar@2.1.5': {} + '@types/d3-color': 3.1.0 - '@types/d3-array@3.2.2': {} + '@types/d3-path@3.1.1': {} - '@types/d3-contour@3.0.6': + '@types/d3-scale@4.0.2': dependencies: - '@types/d3-array': 3.2.2 - '@types/geojson': 7946.0.16 - - '@types/d3-path@3.1.1': {} + '@types/d3-time': 3.0.0 - '@types/d3-shape@3.1.8': + '@types/d3-shape@3.1.7': dependencies: '@types/d3-path': 3.1.1 - '@types/eslint-scope@3.7.7': + '@types/d3-shape@3.1.8': dependencies: - '@types/eslint': 9.6.1 - '@types/estree': 1.0.8 + '@types/d3-path': 3.1.1 - '@types/eslint@9.6.1': - dependencies: - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 + '@types/d3-time-format@2.1.0': {} - '@types/estree@1.0.8': {} + '@types/d3-time@3.0.0': {} - '@types/geojson@7946.0.16': {} + '@types/deep-eql@4.0.2': {} - '@types/graceful-fs@4.1.9': + '@types/docker-modem@3.0.6': dependencies: - '@types/node': 22.19.11 - - '@types/http-cache-semantics@4.2.0': {} + '@types/node': 26.6.3 + '@types/ssh2': 1.15.6 - '@types/istanbul-lib-coverage@2.0.6': {} - - '@types/istanbul-lib-report@3.0.3': + '@types/dockerode@4.0.2': dependencies: - '@types/istanbul-lib-coverage': 2.0.6 + '@types/docker-modem': 3.0.6 + '@types/node': 26.6.3 + '@types/ssh2': 1.15.6 - '@types/istanbul-reports@3.0.4': - dependencies: - '@types/istanbul-lib-report': 3.0.3 + '@types/estree@1.0.8': {} - '@types/jest@30.0.0': - dependencies: - expect: 30.2.0 - pretty-format: 30.2.0 + '@types/geojson@7946.0.16': {} '@types/json-schema@7.0.15': {} - '@types/json5@0.0.29': {} - - '@types/jsonwebtoken@9.0.10': - dependencies: - '@types/ms': 2.1.0 - '@types/node': 22.19.11 - - '@types/methods@1.1.4': {} - - '@types/mocha@10.0.10': {} - - '@types/ms@2.1.0': {} + '@types/lodash@4.17.25': {} '@types/node@12.20.55': {} + '@types/node@18.19.130': + dependencies: + undici-types: 5.26.5 + '@types/node@22.19.11': dependencies: undici-types: 6.21.0 - '@types/pg@8.16.0': + '@types/node@26.6.3': + dependencies: + undici-types: 8.9.0 + + '@types/pg@8.23.1': dependencies: '@types/node': 22.19.11 pg-protocol: 1.11.0 @@ -9282,359 +6360,227 @@ snapshots: '@types/resolve@1.20.2': {} - '@types/stack-utils@2.0.3': {} - - '@types/superagent@8.1.9': + '@types/ssh2-streams@0.1.13': dependencies: - '@types/cookiejar': 2.1.5 - '@types/methods': 1.1.4 - '@types/node': 22.19.11 - form-data: 4.0.5 + '@types/node': 26.6.3 - '@types/supertest@6.0.3': + '@types/ssh2@0.5.52': dependencies: - '@types/methods': 1.1.4 - '@types/superagent': 8.1.9 + '@types/node': 26.6.3 + '@types/ssh2-streams': 0.1.13 - '@types/triple-beam@1.3.5': {} + '@types/ssh2@1.15.6': + dependencies: + '@types/node': 18.19.130 '@types/trusted-types@2.0.7': {} - '@types/validator@13.15.10': + '@typescript-eslint/types@8.56.0': optional: true - '@types/yargs-parser@21.0.3': {} - - '@types/yargs@17.0.35': - dependencies: - '@types/yargs-parser': 21.0.3 - - '@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3)': - dependencies: - '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.56.0 - '@typescript-eslint/type-utils': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.0 - eslint: 9.39.3(jiti@2.7.0) - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3)': - dependencies: - '@typescript-eslint/scope-manager': 8.56.0 - '@typescript-eslint/types': 8.56.0 - '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.56.0 - debug: 4.4.3 - eslint: 9.39.3(jiti@2.7.0) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/project-service@8.56.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.56.0(typescript@5.9.3) - '@typescript-eslint/types': 8.56.0 - debug: 4.4.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/scope-manager@8.56.0': - dependencies: - '@typescript-eslint/types': 8.56.0 - '@typescript-eslint/visitor-keys': 8.56.0 - - '@typescript-eslint/tsconfig-utils@8.56.0(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 - - '@typescript-eslint/type-utils@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3)': - dependencies: - '@typescript-eslint/types': 8.56.0 - '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - debug: 4.4.3 - eslint: 9.39.3(jiti@2.7.0) - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/types@8.56.0': {} - - '@typescript-eslint/typescript-estree@8.56.0(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.56.0(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.56.0(typescript@5.9.3) - '@typescript-eslint/types': 8.56.0 - '@typescript-eslint/visitor-keys': 8.56.0 - debug: 4.4.3 - minimatch: 9.0.5 - semver: 7.7.4 - tinyglobby: 0.2.15 - ts-api-utils: 2.4.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3)': - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.56.0 - '@typescript-eslint/types': 8.56.0 - '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) - eslint: 9.39.3(jiti@2.7.0) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/visitor-keys@8.56.0': - dependencies: - '@typescript-eslint/types': 8.56.0 - eslint-visitor-keys: 5.0.1 - - '@ungap/structured-clone@1.3.0': {} + '@typescript/typescript-aix-ppc64@7.0.2': + optional: true - '@unrs/resolver-binding-android-arm-eabi@1.11.1': + '@typescript/typescript-darwin-arm64@7.0.2': optional: true - '@unrs/resolver-binding-android-arm64@1.11.1': + '@typescript/typescript-darwin-x64@7.0.2': optional: true - '@unrs/resolver-binding-darwin-arm64@1.11.1': + '@typescript/typescript-freebsd-arm64@7.0.2': optional: true - '@unrs/resolver-binding-darwin-x64@1.11.1': + '@typescript/typescript-freebsd-x64@7.0.2': optional: true - '@unrs/resolver-binding-freebsd-x64@1.11.1': + '@typescript/typescript-linux-arm64@7.0.2': optional: true - '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + '@typescript/typescript-linux-arm@7.0.2': optional: true - '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + '@typescript/typescript-linux-loong64@7.0.2': optional: true - '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + '@typescript/typescript-linux-mips64el@7.0.2': optional: true - '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + '@typescript/typescript-linux-ppc64@7.0.2': optional: true - '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + '@typescript/typescript-linux-riscv64@7.0.2': optional: true - '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + '@typescript/typescript-linux-s390x@7.0.2': optional: true - '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + '@typescript/typescript-linux-x64@7.0.2': optional: true - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + '@typescript/typescript-netbsd-arm64@7.0.2': optional: true - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + '@typescript/typescript-netbsd-x64@7.0.2': optional: true - '@unrs/resolver-binding-linux-x64-musl@1.11.1': + '@typescript/typescript-openbsd-arm64@7.0.2': optional: true - '@unrs/resolver-binding-wasm32-wasi@1.11.1': - dependencies: - '@napi-rs/wasm-runtime': 0.2.12 + '@typescript/typescript-openbsd-x64@7.0.2': optional: true - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + '@typescript/typescript-sunos-x64@7.0.2': optional: true - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + '@typescript/typescript-win32-arm64@7.0.2': optional: true - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + '@typescript/typescript-win32-x64@7.0.2': optional: true - '@webassemblyjs/ast@1.14.1': + '@visx/curve@4.0.1-alpha.0': dependencies: - '@webassemblyjs/helper-numbers': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - - '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + '@visx/vendor': 4.0.0-alpha.0 - '@webassemblyjs/helper-api-error@1.13.2': {} + '@visx/event@4.0.1-alpha.0': + dependencies: + '@types/react': 19.2.11 + '@visx/point': 4.0.1-alpha.0 - '@webassemblyjs/helper-buffer@1.14.1': {} + '@visx/grid@4.0.1-alpha.0(react@19.2.4)': + dependencies: + '@types/react': 19.2.11 + '@visx/curve': 4.0.1-alpha.0 + '@visx/group': 4.0.1-alpha.0(react@19.2.4) + '@visx/point': 4.0.1-alpha.0 + '@visx/scale': 4.0.1-alpha.0 + '@visx/shape': 4.0.1-alpha.0(react@19.2.4) + classnames: 2.5.1 + react: 19.2.4 - '@webassemblyjs/helper-numbers@1.13.2': + '@visx/group@4.0.1-alpha.0(react@19.2.4)': dependencies: - '@webassemblyjs/floating-point-hex-parser': 1.13.2 - '@webassemblyjs/helper-api-error': 1.13.2 - '@xtuc/long': 4.2.2 + '@types/react': 19.2.11 + classnames: 2.5.1 + react: 19.2.4 - '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + '@visx/point@4.0.1-alpha.0': {} - '@webassemblyjs/helper-wasm-section@1.14.1': + '@visx/responsive@4.0.1-alpha.0(react@19.2.4)': dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/wasm-gen': 1.14.1 + '@types/lodash': 4.17.25 + '@types/react': 19.2.11 + lodash: 4.17.23 + react: 19.2.4 - '@webassemblyjs/ieee754@1.13.2': + '@visx/scale@4.0.1-alpha.0': dependencies: - '@xtuc/ieee754': 1.2.0 + '@visx/vendor': 4.0.0-alpha.0 - '@webassemblyjs/leb128@1.13.2': + '@visx/shape@4.0.1-alpha.0(react@19.2.4)': dependencies: - '@xtuc/long': 4.2.2 - - '@webassemblyjs/utf8@1.13.2': {} + '@types/lodash': 4.17.25 + '@types/react': 19.2.11 + '@visx/curve': 4.0.1-alpha.0 + '@visx/group': 4.0.1-alpha.0(react@19.2.4) + '@visx/scale': 4.0.1-alpha.0 + '@visx/vendor': 4.0.0-alpha.0 + classnames: 2.5.1 + lodash: 4.17.23 + react: 19.2.4 - '@webassemblyjs/wasm-edit@1.14.1': + '@visx/vendor@4.0.0-alpha.0': dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/helper-wasm-section': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-opt': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - '@webassemblyjs/wast-printer': 1.14.1 + '@types/d3-array': 3.0.3 + '@types/d3-color': 3.1.0 + '@types/d3-delaunay': 6.0.1 + '@types/d3-format': 3.0.1 + '@types/d3-geo': 3.1.0 + '@types/d3-interpolate': 3.0.1 + '@types/d3-path': 3.1.1 + '@types/d3-scale': 4.0.2 + '@types/d3-shape': 3.1.7 + '@types/d3-time': 3.0.0 + '@types/d3-time-format': 2.1.0 + d3-array: 3.2.1 + d3-color: 3.1.0 + d3-delaunay: 6.0.2 + d3-format: 3.1.0 + d3-geo: 3.1.0 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-scale: 4.0.2 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + internmap: 2.0.3 - '@webassemblyjs/wasm-gen@1.14.1': + '@vitest/coverage-v8@5.0.3(vitest@5.0.3)': dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 + '@bcoe/v8-coverage': 1.0.2 + '@vitest/istanbul-lib-coverage': 1.0.2 + '@vitest/istanbul-lib-report': 1.0.2 + ast-v8-to-istanbul: 1.0.7 + magicast: 0.5.5 + obug: 2.2.1 + std-env: 4.3.0 + tinyrainbow: 3.2.0 + vitest: 5.0.3(@types/node@26.6.3)(@vitest/coverage-v8@5.0.3)(vite@7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) - '@webassemblyjs/wasm-opt@1.14.1': - dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-buffer': 1.14.1 - '@webassemblyjs/wasm-gen': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 + '@vitest/istanbul-lib-coverage@1.0.2': {} - '@webassemblyjs/wasm-parser@1.14.1': + '@vitest/istanbul-lib-report@1.0.2': dependencies: - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/helper-api-error': 1.13.2 - '@webassemblyjs/helper-wasm-bytecode': 1.13.2 - '@webassemblyjs/ieee754': 1.13.2 - '@webassemblyjs/leb128': 1.13.2 - '@webassemblyjs/utf8': 1.13.2 + '@vitest/istanbul-lib-coverage': 1.0.2 - '@webassemblyjs/wast-printer@1.14.1': + '@vitest/mocker@5.0.3(vite@7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0))': dependencies: - '@webassemblyjs/ast': 1.14.1 - '@xtuc/long': 4.2.2 + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/spy': 5.0.3 + estree-walker: 3.0.3 + magic-string: 1.4.3 + optionalDependencies: + vite: 7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) - '@xhmikosr/archive-type@7.1.0': - dependencies: - file-type: 20.5.0 - transitivePeerDependencies: - - supports-color + '@vitest/spy@5.0.3': {} - '@xhmikosr/bin-check@7.1.0': - dependencies: - execa: 5.1.1 - isexe: 2.0.0 + '@yuku-core/binding-android-arm64@0.18.1': + optional: true - '@xhmikosr/bin-wrapper@13.2.0': - dependencies: - '@xhmikosr/bin-check': 7.1.0 - '@xhmikosr/downloader': 15.2.0 - '@xhmikosr/os-filter-obj': 3.0.0 - bin-version-check: 5.1.0 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - supports-color + '@yuku-core/binding-darwin-arm64@0.18.1': + optional: true - '@xhmikosr/decompress-tar@8.1.0': - dependencies: - file-type: 20.5.0 - is-stream: 2.0.1 - tar-stream: 3.1.7 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - supports-color + '@yuku-core/binding-darwin-x64@0.18.1': + optional: true - '@xhmikosr/decompress-tarbz2@8.1.0': - dependencies: - '@xhmikosr/decompress-tar': 8.1.0 - file-type: 20.5.0 - is-stream: 2.0.1 - seek-bzip: 2.0.0 - unbzip2-stream: 1.4.3 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - supports-color + '@yuku-core/binding-freebsd-x64@0.18.1': + optional: true - '@xhmikosr/decompress-targz@8.1.0': - dependencies: - '@xhmikosr/decompress-tar': 8.1.0 - file-type: 20.5.0 - is-stream: 2.0.1 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - supports-color + '@yuku-core/binding-linux-arm-gnu@0.18.1': + optional: true - '@xhmikosr/decompress-unzip@7.1.0': - dependencies: - file-type: 20.5.0 - get-stream: 6.0.1 - yauzl: 3.2.0 - transitivePeerDependencies: - - supports-color + '@yuku-core/binding-linux-arm-musl@0.18.1': + optional: true - '@xhmikosr/decompress@10.2.0': - dependencies: - '@xhmikosr/decompress-tar': 8.1.0 - '@xhmikosr/decompress-tarbz2': 8.1.0 - '@xhmikosr/decompress-targz': 8.1.0 - '@xhmikosr/decompress-unzip': 7.1.0 - graceful-fs: 4.2.11 - strip-dirs: 3.0.0 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - supports-color + '@yuku-core/binding-linux-arm64-gnu@0.18.1': + optional: true - '@xhmikosr/downloader@15.2.0': - dependencies: - '@xhmikosr/archive-type': 7.1.0 - '@xhmikosr/decompress': 10.2.0 - content-disposition: 0.5.4 - defaults: 2.0.2 - ext-name: 5.0.0 - file-type: 20.5.0 - filenamify: 6.0.0 - get-stream: 6.0.1 - got: 13.0.0 - transitivePeerDependencies: - - bare-abort-controller - - react-native-b4a - - supports-color + '@yuku-core/binding-linux-arm64-musl@0.18.1': + optional: true - '@xhmikosr/os-filter-obj@3.0.0': - dependencies: - arch: 3.0.0 + '@yuku-core/binding-linux-x64-gnu@0.18.1': + optional: true + + '@yuku-core/binding-linux-x64-musl@0.18.1': + optional: true + + '@yuku-core/binding-win32-arm64@0.18.1': + optional: true - '@xtuc/ieee754@1.2.0': {} + '@yuku-core/binding-win32-x64@0.18.1': + optional: true - '@xtuc/long@4.2.2': {} + '@yuku-toolchain/types@0.18.1': {} '@zag-js/accordion@1.39.1': dependencies: @@ -9969,103 +6915,56 @@ snapshots: dependencies: event-target-shim: 5.0.1 - abstract-logging@2.0.1: {} - - accepts@2.0.0: - dependencies: - mime-types: 3.0.2 - negotiator: 1.0.0 - optional: true - - acorn-import-phases@1.0.4(acorn@8.16.0): - dependencies: - acorn: 8.16.0 + acorn@8.16.0: {} - acorn-jsx@5.3.2(acorn@8.16.0): + ajv@8.18.0: dependencies: - acorn: 8.16.0 + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 - acorn-walk@8.3.5: - dependencies: - acorn: 8.16.0 + ansi-colors@4.1.3: {} - acorn@8.16.0: {} + ansi-regex@5.0.1: {} - ajv-formats@2.1.1(ajv@8.18.0): - optionalDependencies: - ajv: 8.18.0 + ansi-regex@6.4.0: {} - ajv-formats@3.0.1(ajv@8.17.1): - optionalDependencies: - ajv: 8.17.1 + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 - ajv-formats@3.0.1(ajv@8.18.0): - optionalDependencies: - ajv: 8.18.0 + ansi-styles@6.2.3: {} - ajv-keywords@3.5.2(ajv@6.14.0): + archiver-utils@5.0.2: dependencies: - ajv: 6.14.0 + glob: 10.5.0 + graceful-fs: 4.2.11 + is-stream: 2.0.1 + lazystream: 1.0.1 + lodash: 4.17.23 + normalize-path: 3.0.0 + readable-stream: 4.8.0 - ajv-keywords@5.1.0(ajv@8.18.0): + archiver@7.0.1: dependencies: - ajv: 8.18.0 - fast-deep-equal: 3.1.3 - - ajv@6.14.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ajv@8.17.1: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - ajv@8.18.0: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.1.0 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - ansi-colors@4.1.3: {} - - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - - ansi-regex@5.0.1: {} - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansis@4.2.0: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - append-field@1.0.0: - optional: true - - arch@3.0.0: {} - - arg@4.1.3: {} + archiver-utils: 5.0.2 + async: 3.2.6 + buffer-crc32: 1.0.0 + readable-stream: 4.8.0 + readdir-glob: 1.1.3 + tar-stream: 3.2.2 + zip-stream: 6.0.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a - argon2@0.44.0: + argon2@0.45.1: dependencies: '@phc/format': 1.0.0 cross-env: 10.1.0 - node-addon-api: 8.5.0 + node-addon-api: 8.9.2 node-gyp-build: 4.8.4 argparse@1.0.10: @@ -10076,2384 +6975,821 @@ snapshots: aria-query@5.3.1: {} - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - array-ify@1.0.0: {} - array-includes@3.1.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - is-string: 1.1.1 - math-intrinsics: 1.1.0 - - array-timsort@1.0.3: {} - array-union@2.1.0: {} - array.prototype.findlastindex@1.2.6: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-shim-unscopables: 1.1.0 - - array.prototype.flat@1.3.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-shim-unscopables: 1.1.0 - - array.prototype.flatmap@1.3.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-shim-unscopables: 1.1.0 - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - - asap@2.0.6: {} - - async-function@1.0.0: {} - - async@3.2.6: {} - - asynckit@0.4.0: {} - - atomic-sleep@1.0.0: {} - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - avvio@9.2.0: - dependencies: - '@fastify/error': 4.2.0 - fastq: 1.20.1 - - aws-ssl-profiles@1.1.2: {} - - axobject-query@4.1.0: {} - - b4a@1.8.0: {} - - babel-jest@29.7.0(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@jest/transform': 29.7.0 - '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.29.0) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-istanbul@6.1.1: - dependencies: - '@babel/helper-plugin-utils': 7.28.6 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-istanbul@7.0.1: - dependencies: - '@babel/helper-plugin-utils': 7.28.6 - '@istanbuljs/load-nyc-config': 1.1.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 6.0.3 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-jest-hoist@29.6.3: - dependencies: - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 - '@types/babel__core': 7.20.5 - '@types/babel__traverse': 7.28.0 - - babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0) - '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) - - babel-preset-jest@29.6.3(@babel/core@7.29.0): - dependencies: - '@babel/core': 7.29.0 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) - - balanced-match@1.0.2: {} - - balanced-match@4.0.3: {} - - balanced-match@4.0.4: - optional: true - - bare-events@2.8.2: {} - - base64-js@1.5.1: {} - - baseline-browser-mapping@2.10.0: {} - - better-path-resolve@1.0.0: - dependencies: - is-windows: 1.0.2 - - bin-version-check@5.1.0: - dependencies: - bin-version: 6.0.0 - semver: 7.7.4 - semver-truncate: 3.0.0 - - bin-version@6.0.0: - dependencies: - execa: 5.1.1 - find-versions: 5.1.0 - - bl@4.1.0: - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.2 - - body-parser@2.3.0: - dependencies: - bytes: 3.1.2 - content-type: 2.0.0 - debug: 4.4.3 - http-errors: 2.0.1 - iconv-lite: 0.7.3 - on-finished: 2.4.1 - qs: 6.15.3 - raw-body: 3.0.2 - type-is: 2.1.0 - transitivePeerDependencies: - - supports-color - optional: true - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - brace-expansion@5.0.2: - dependencies: - balanced-match: 4.0.3 - - brace-expansion@5.0.7: - dependencies: - balanced-match: 4.0.4 - optional: true - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.28.1: - dependencies: - baseline-browser-mapping: 2.10.0 - caniuse-lite: 1.0.30001770 - electron-to-chromium: 1.5.302 - node-releases: 2.0.27 - update-browserslist-db: 1.2.3(browserslist@4.28.1) - - bs-logger@0.2.6: - dependencies: - fast-json-stable-stringify: 2.1.0 - - bser@2.1.1: - dependencies: - node-int64: 0.4.0 - - buffer-crc32@0.2.13: {} - - buffer-equal-constant-time@1.0.1: {} - - buffer-from@1.1.2: {} - - buffer@5.7.1: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - busboy@1.6.0: - dependencies: - streamsearch: 1.1.0 - optional: true - - bytes@3.1.2: - optional: true - - c12@3.1.0: - dependencies: - chokidar: 4.0.3 - confbox: 0.2.4 - defu: 6.1.4 - dotenv: 16.6.1 - exsolve: 1.0.8 - giget: 2.0.0 - jiti: 2.6.1 - ohash: 2.0.11 - pathe: 2.0.3 - perfect-debounce: 1.0.0 - pkg-types: 2.3.0 - rc9: 2.1.2 - - cacheable-lookup@7.0.0: {} - - cacheable-request@10.2.14: - dependencies: - '@types/http-cache-semantics': 4.2.0 - get-stream: 6.0.1 - http-cache-semantics: 4.2.0 - keyv: 4.5.4 - mimic-response: 4.0.0 - normalize-url: 8.1.1 - responselike: 3.0.0 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.9: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - camelcase@5.3.1: {} - - camelcase@6.3.0: {} - - caniuse-lite@1.0.30001770: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - char-regex@1.0.2: {} - - chardet@2.1.1: {} - - chevrotain@10.5.0: - dependencies: - '@chevrotain/cst-dts-gen': 10.5.0 - '@chevrotain/gast': 10.5.0 - '@chevrotain/types': 10.5.0 - '@chevrotain/utils': 10.5.0 - lodash: 4.17.21 - regexp-to-ast: 0.5.0 - - chokidar@4.0.3: - dependencies: - readdirp: 4.1.2 - - chrome-trace-event@1.0.4: {} - - ci-info@3.9.0: {} - - ci-info@4.4.0: {} - - citty@0.1.6: - dependencies: - consola: 3.4.2 - - citty@0.2.1: {} - - cjs-module-lexer@1.4.3: {} - - class-transformer@0.5.1: - optional: true - - class-validator@0.14.3: - dependencies: - '@types/validator': 13.15.10 - libphonenumber-js: 1.13.8 - validator: 13.15.35 - optional: true - - cli-cursor@3.1.0: - dependencies: - restore-cursor: 3.1.0 - - cli-spinners@2.9.2: {} - - cli-table3@0.6.5: - dependencies: - string-width: 4.2.3 - optionalDependencies: - '@colors/colors': 1.5.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 - - clone@1.0.4: {} - - clsx@2.1.1: {} - - co@4.6.0: {} - - collect-v8-coverage@1.0.3: {} - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-convert@3.1.3: - dependencies: - color-name: 2.1.0 - - color-name@1.1.4: {} - - color-name@2.1.0: {} - - color-string@2.1.4: - dependencies: - color-name: 2.1.0 - - color@5.0.3: - dependencies: - color-convert: 3.1.3 - color-string: 2.1.4 - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - commander@2.20.3: {} - - commander@4.1.1: {} - - commander@6.2.1: {} - - commander@7.2.0: {} - - commander@8.3.0: {} - - comment-json@4.4.1: - dependencies: - array-timsort: 1.0.3 - core-util-is: 1.0.3 - esprima: 4.0.1 - - commondir@1.0.1: {} - - compare-func@2.0.0: - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - - component-emitter@1.3.1: {} - - concat-map@0.0.1: {} - - concat-stream@2.0.0: + asn1@0.2.6: dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 3.6.2 - typedarray: 0.0.6 - optional: true - - confbox@0.2.4: {} - - consola@3.4.2: {} - - content-disposition@0.5.4: - dependencies: - safe-buffer: 5.2.1 - - content-disposition@1.1.0: - optional: true - - content-type@1.0.5: - optional: true - - content-type@2.0.0: - optional: true - - conventional-changelog-angular@8.1.0: - dependencies: - compare-func: 2.0.0 - - conventional-changelog-conventionalcommits@9.1.0: - dependencies: - compare-func: 2.0.0 - - conventional-commits-parser@6.2.1: - dependencies: - meow: 13.2.0 - - convert-source-map@2.0.0: {} - - cookie-signature@1.2.2: {} - - cookie@0.6.0: {} - - cookie@0.7.2: - optional: true - - cookie@1.1.1: {} - - cookiejar@2.1.4: {} - - core-util-is@1.0.3: {} - - cors@2.8.6: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - optional: true - - cosmiconfig-typescript-loader@6.2.0(@types/node@22.19.11)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): - dependencies: - '@types/node': 22.19.11 - cosmiconfig: 9.0.0(typescript@5.9.3) - jiti: 2.6.1 - typescript: 5.9.3 - - cosmiconfig@8.3.6(typescript@5.9.3): - dependencies: - import-fresh: 3.3.1 - js-yaml: 4.1.1 - parse-json: 5.2.0 - path-type: 4.0.0 - optionalDependencies: - typescript: 5.9.3 - - cosmiconfig@9.0.0(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-jest@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)): - dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - create-require@1.1.1: {} - - cross-env@10.1.0: - dependencies: - '@epic-web/invariant': 1.0.0 - cross-spawn: 7.0.6 - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - csstype@3.2.3: {} - - d3-array@2.12.1: - dependencies: - internmap: 1.0.1 - - d3-array@3.2.4: - dependencies: - internmap: 2.0.3 - - d3-chord@3.0.1: - dependencies: - d3-path: 3.1.0 - - d3-color@3.1.0: {} - - d3-contour@4.0.2: - dependencies: - d3-array: 3.2.4 - - d3-delaunay@6.0.4: - dependencies: - delaunator: 5.1.0 - - d3-dispatch@3.0.1: {} - - d3-dsv@3.0.1: - dependencies: - commander: 7.2.0 - iconv-lite: 0.6.3 - rw: 1.3.3 - - d3-force@3.0.0: - dependencies: - d3-dispatch: 3.0.1 - d3-quadtree: 3.0.1 - d3-timer: 3.0.1 - - d3-format@3.1.2: {} - - d3-geo-voronoi@2.1.0: - dependencies: - d3-array: 3.2.4 - d3-delaunay: 6.0.4 - d3-geo: 3.1.1 - d3-tricontour: 1.1.0 - - d3-geo@3.1.1: - dependencies: - d3-array: 3.2.4 - - d3-hierarchy@3.1.2: {} - - d3-interpolate-path@2.3.0: {} - - d3-interpolate@3.0.1: - dependencies: - d3-color: 3.1.0 - - d3-path@1.0.9: {} - - d3-path@3.1.0: {} - - d3-quadtree@3.0.1: {} - - d3-random@3.0.1: {} - - d3-sankey@0.12.3: - dependencies: - d3-array: 2.12.1 - d3-shape: 1.3.7 - - d3-scale-chromatic@3.1.0: - dependencies: - d3-color: 3.1.0 - d3-interpolate: 3.0.1 - - d3-scale@4.0.2: - dependencies: - d3-array: 3.2.4 - d3-format: 3.1.2 - d3-interpolate: 3.0.1 - d3-time: 3.1.0 - d3-time-format: 4.1.0 - - d3-shape@1.3.7: - dependencies: - d3-path: 1.0.9 - - d3-shape@3.2.0: - dependencies: - d3-path: 3.1.0 - - d3-tile@1.0.0: {} - - d3-time-format@4.1.0: - dependencies: - d3-time: 3.1.0 - - d3-time@3.1.0: - dependencies: - d3-array: 3.2.4 - - d3-timer@3.0.1: {} - - d3-tricontour@1.1.0: - dependencies: - d3-delaunay: 6.0.4 - d3-scale: 4.0.2 - - dargs@8.1.0: {} - - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - debug@3.2.7: - dependencies: - ms: 2.1.3 - - debug@4.4.3: - dependencies: - ms: 2.1.3 - - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - - dedent@1.7.1: {} - - deep-is@0.1.4: {} - - deepmerge-ts@7.1.5: {} - - deepmerge@4.3.1: {} - - defaults@1.0.4: - dependencies: - clone: 1.0.4 - - defaults@2.0.2: {} - - defer-to-connect@2.0.1: {} - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - defu@6.1.4: {} - - delaunator@5.1.0: - dependencies: - robust-predicates: 3.0.3 - - delayed-stream@1.0.0: {} - - denque@2.1.0: {} - - depd@2.0.0: - optional: true - - dequal@2.0.3: {} - - destr@2.0.5: {} - - detect-indent@6.1.0: {} - - detect-libc@2.1.2: {} - - detect-newline@3.1.0: {} - - devalue@5.8.1: {} - - dezalgo@1.0.4: - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - - diff-sequences@29.6.3: {} - - diff@4.0.4: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@2.1.0: - dependencies: - esutils: 2.0.3 - - dot-prop@5.3.0: - dependencies: - is-obj: 2.0.0 - - dotenv-cli@10.0.0: - dependencies: - cross-spawn: 7.0.6 - dotenv: 17.3.1 - dotenv-expand: 11.0.7 - minimist: 1.2.8 - - dotenv-expand@11.0.7: - dependencies: - dotenv: 16.6.1 - - dotenv-expand@12.0.3: - dependencies: - dotenv: 16.6.1 - - dotenv@16.6.1: {} - - dotenv@17.2.3: {} - - dotenv@17.3.1: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - duplexify@3.7.1: - dependencies: - end-of-stream: 1.4.5 - inherits: 2.0.4 - readable-stream: 2.3.8 - stream-shift: 1.0.3 - - duplexify@4.1.3: - dependencies: - end-of-stream: 1.4.5 - inherits: 2.0.4 - readable-stream: 3.6.2 - stream-shift: 1.0.3 - - ecdsa-sig-formatter@1.0.11: - dependencies: - safe-buffer: 5.2.1 - - ee-first@1.1.1: - optional: true - - effect@3.18.4: - dependencies: - '@standard-schema/spec': 1.1.0 - fast-check: 3.23.2 - - electron-to-chromium@1.5.302: {} - - emittery@0.13.1: {} - - emoji-regex@8.0.0: {} - - empathic@2.0.0: {} - - enabled@2.0.0: {} - - encodeurl@2.0.0: - optional: true - - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - - enhanced-resolve@5.19.0: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.0 - - enhanced-resolve@5.21.6: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.3.3 - - enquirer@2.4.1: - dependencies: - ansi-colors: 4.1.3 - strip-ansi: 6.0.1 - - env-paths@2.2.1: {} - - error-ex@1.3.4: - dependencies: - is-arrayish: 0.2.1 - - es-abstract@1.24.2: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.20 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@2.0.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es-shim-unscopables@1.1.0: - dependencies: - hasown: 2.0.2 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - - es-toolkit@1.49.0: {} - - esbuild@0.27.3: - optionalDependencies: - '@esbuild/aix-ppc64': 0.27.3 - '@esbuild/android-arm': 0.27.3 - '@esbuild/android-arm64': 0.27.3 - '@esbuild/android-x64': 0.27.3 - '@esbuild/darwin-arm64': 0.27.3 - '@esbuild/darwin-x64': 0.27.3 - '@esbuild/freebsd-arm64': 0.27.3 - '@esbuild/freebsd-x64': 0.27.3 - '@esbuild/linux-arm': 0.27.3 - '@esbuild/linux-arm64': 0.27.3 - '@esbuild/linux-ia32': 0.27.3 - '@esbuild/linux-loong64': 0.27.3 - '@esbuild/linux-mips64el': 0.27.3 - '@esbuild/linux-ppc64': 0.27.3 - '@esbuild/linux-riscv64': 0.27.3 - '@esbuild/linux-s390x': 0.27.3 - '@esbuild/linux-x64': 0.27.3 - '@esbuild/netbsd-arm64': 0.27.3 - '@esbuild/netbsd-x64': 0.27.3 - '@esbuild/openbsd-arm64': 0.27.3 - '@esbuild/openbsd-x64': 0.27.3 - '@esbuild/openharmony-arm64': 0.27.3 - '@esbuild/sunos-x64': 0.27.3 - '@esbuild/win32-arm64': 0.27.3 - '@esbuild/win32-ia32': 0.27.3 - '@esbuild/win32-x64': 0.27.3 - - escalade@3.2.0: {} - - escape-html@1.0.3: - optional: true - - escape-string-regexp@2.0.0: {} - - escape-string-regexp@4.0.0: {} - - eslint-config-prettier@10.1.8(eslint@9.39.3(jiti@2.7.0)): - dependencies: - eslint: 9.39.3(jiti@2.7.0) - - eslint-import-context@0.1.9(unrs-resolver@1.11.1): - dependencies: - get-tsconfig: 4.14.0 - stable-hash-x: 0.2.0 - optionalDependencies: - unrs-resolver: 1.11.1 - - eslint-import-resolver-node@0.3.10: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.1 - resolve: 2.0.0-next.6 - transitivePeerDependencies: - - supports-color - - eslint-import-resolver-typescript@4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.7.0)): - dependencies: - debug: 4.4.3 - eslint: 9.39.3(jiti@2.7.0) - eslint-import-context: 0.1.9(unrs-resolver@1.11.1) - get-tsconfig: 4.14.0 - is-bun-module: 2.0.0 - stable-hash-x: 0.2.0 - tinyglobby: 0.2.15 - unrs-resolver: 1.11.1 - optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.7.0)) - transitivePeerDependencies: - - supports-color - - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.7.0)): - dependencies: - debug: 3.2.7 - optionalDependencies: - '@typescript-eslint/parser': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - eslint: 9.39.3(jiti@2.7.0) - eslint-import-resolver-node: 0.3.10 - eslint-import-resolver-typescript: 4.4.4(eslint-plugin-import@2.32.0)(eslint@9.39.3(jiti@2.7.0)) - transitivePeerDependencies: - - supports-color - - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.7.0)): - dependencies: - '@rtsao/scc': 1.1.0 - array-includes: 3.1.9 - array.prototype.findlastindex: 1.2.6 - array.prototype.flat: 1.3.3 - array.prototype.flatmap: 1.3.3 - debug: 3.2.7 - doctrine: 2.1.0 - eslint: 9.39.3(jiti@2.7.0) - eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@4.4.4)(eslint@9.39.3(jiti@2.7.0)) - hasown: 2.0.2 - is-core-module: 2.16.1 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.fromentries: 2.0.8 - object.groupby: 1.0.3 - object.values: 1.2.1 - semver: 6.3.1 - string.prototype.trimend: 1.0.9 - tsconfig-paths: 3.15.0 - optionalDependencies: - '@typescript-eslint/parser': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - eslint-plugin-jest@29.15.0(@typescript-eslint/eslint-plugin@8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.3(jiti@2.7.0))(jest@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)))(typescript@5.9.3): - dependencies: - '@typescript-eslint/utils': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - eslint: 9.39.3(jiti@2.7.0) - optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - jest: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - - eslint-plugin-prettier@5.5.5(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.39.3(jiti@2.7.0)))(eslint@9.39.3(jiti@2.7.0))(prettier@3.8.1): - dependencies: - eslint: 9.39.3(jiti@2.7.0) - prettier: 3.8.1 - prettier-linter-helpers: 1.0.1 - synckit: 0.11.12 - optionalDependencies: - '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@9.39.3(jiti@2.7.0)) - - eslint-scope@5.1.1: - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - eslint-scope@8.4.0: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint-visitor-keys@5.0.1: {} - - eslint@9.39.3(jiti@2.7.0): - dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.3(jiti@2.7.0)) - '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.21.1 - '@eslint/config-helpers': 0.4.2 - '@eslint/core': 0.17.0 - '@eslint/eslintrc': 3.3.3 - '@eslint/js': 9.39.3 - '@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.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - optionalDependencies: - jiti: 2.7.0 - transitivePeerDependencies: - - supports-color - - esm-env@1.2.2: {} - - espree@10.4.0: - dependencies: - acorn: 8.16.0 - acorn-jsx: 5.3.2(acorn@8.16.0) - eslint-visitor-keys: 4.2.1 - - esprima@4.0.1: {} - - esquery@1.7.0: - dependencies: - estraverse: 5.3.0 - - esrap@2.2.13(@typescript-eslint/types@8.56.0): - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - optionalDependencies: - '@typescript-eslint/types': 8.56.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@4.3.0: {} - - estraverse@5.3.0: {} - - estree-walker@2.0.2: {} - - esutils@2.0.3: {} - - etag@1.8.1: - optional: true - - event-target-shim@5.0.1: {} - - events-universal@1.0.1: - dependencies: - bare-events: 2.8.2 - transitivePeerDependencies: - - bare-abort-controller - - events@3.3.0: {} - - eventsource-parser@3.0.8: {} - - execa@5.1.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - exit@0.1.2: {} - - expect@29.7.0: - dependencies: - '@jest/expect-utils': 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - - expect@30.2.0: - dependencies: - '@jest/expect-utils': 30.2.0 - '@jest/get-type': 30.1.0 - jest-matcher-utils: 30.2.0 - jest-message-util: 30.2.0 - jest-mock: 30.2.0 - jest-util: 30.2.0 - - express@5.2.1: - dependencies: - accepts: 2.0.0 - body-parser: 2.3.0 - content-disposition: 1.1.0 - content-type: 1.0.5 - cookie: 0.7.2 - cookie-signature: 1.2.2 - debug: 4.4.3 - depd: 2.0.0 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 2.1.1 - fresh: 2.0.0 - http-errors: 2.0.1 - merge-descriptors: 2.0.0 - mime-types: 3.0.2 - on-finished: 2.4.1 - once: 1.4.0 - parseurl: 1.3.3 - proxy-addr: 2.0.7 - qs: 6.15.3 - range-parser: 1.3.0 - router: 2.2.0 - send: 1.2.1 - serve-static: 2.2.1 - statuses: 2.0.2 - type-is: 2.1.0 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - optional: true - - exsolve@1.0.8: {} - - ext-list@2.2.2: - dependencies: - mime-db: 1.54.0 - - ext-name@5.0.0: - dependencies: - ext-list: 2.2.2 - sort-keys-length: 1.0.1 - - extendable-error@0.1.7: {} - - fast-check@3.23.2: - dependencies: - pure-rand: 6.1.0 - - fast-decode-uri-component@1.0.1: {} - - fast-deep-equal@3.1.3: {} - - fast-diff@1.3.0: {} - - fast-fifo@1.3.2: {} - - 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-json-stringify@6.3.0: - dependencies: - '@fastify/merge-json-schemas': 0.2.1 - ajv: 8.18.0 - ajv-formats: 3.0.1(ajv@8.18.0) - fast-uri: 3.1.0 - json-schema-ref-resolver: 3.0.0 - rfdc: 1.4.1 + safer-buffer: 2.1.2 - fast-levenshtein@2.0.6: {} + assertion-error@2.0.1: {} - fast-querystring@1.1.2: + ast-v8-to-istanbul@1.0.7: dependencies: - fast-decode-uri-component: 1.0.1 - - fast-safe-stringify@2.1.1: {} + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 - fast-uri@3.1.0: {} + async-lock@1.4.1: {} - fastify-plugin@5.1.0: {} - - fastify@5.7.4: - dependencies: - '@fastify/ajv-compiler': 4.0.5 - '@fastify/error': 4.2.0 - '@fastify/fast-json-stringify-compiler': 5.0.3 - '@fastify/proxy-addr': 5.1.0 - abstract-logging: 2.0.1 - avvio: 9.2.0 - fast-json-stringify: 6.3.0 - find-my-way: 9.4.0 - light-my-request: 6.6.0 - pino: 10.3.1 - process-warning: 5.0.0 - rfdc: 1.4.1 - secure-json-parse: 4.1.0 - semver: 7.7.4 - toad-cache: 3.7.0 + async@3.2.6: {} - fastq@1.20.1: - dependencies: - reusify: 1.1.0 + aws-ssl-profiles@1.1.2: {} - fb-watchman@2.0.2: - dependencies: - bser: 2.1.1 + axobject-query@4.1.0: {} - fdir@6.5.0(picomatch@4.0.3): - optionalDependencies: - picomatch: 4.0.3 + b4a@1.9.0: {} - fecha@4.2.3: {} + balanced-match@1.0.2: {} - fflate@0.8.2: {} + bare-events@2.9.2: {} - file-entry-cache@8.0.0: + bare-fs@4.8.4: dependencies: - flat-cache: 4.0.1 + bare-events: 2.9.2 + bare-path: 3.1.2 + bare-stream: 2.13.4(bare-events@2.9.2) + bare-url: 2.5.4 + fast-fifo: 1.3.2 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + bare-path@3.1.2: {} - file-type@20.5.0: + bare-stream@2.13.4(bare-events@2.9.2): dependencies: - '@tokenizer/inflate': 0.2.7 - strtok3: 10.3.4 - token-types: 6.1.2 - uint8array-extras: 1.5.0 + b4a: 1.9.0 + streamx: 2.28.1 + teex: 1.0.1 + optionalDependencies: + bare-events: 2.9.2 transitivePeerDependencies: - - supports-color + - react-native-b4a - file-type@21.3.0: + bare-url@2.5.4: dependencies: - '@tokenizer/inflate': 0.4.1 - strtok3: 10.3.4 - token-types: 6.1.2 - uint8array-extras: 1.5.0 - transitivePeerDependencies: - - supports-color + bare-path: 3.1.2 - filename-reserved-regex@3.0.0: {} + base64-js@1.5.1: {} - filenamify@6.0.0: + bcrypt-pbkdf@1.0.2: dependencies: - filename-reserved-regex: 3.0.0 + tweetnacl: 0.14.5 - fill-range@7.1.1: + better-path-resolve@1.0.0: dependencies: - to-regex-range: 5.0.1 + is-windows: 1.0.2 - finalhandler@2.1.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - optional: true + better-result@2.10.0: {} - find-my-way@9.4.0: + bl@4.1.0: dependencies: - fast-deep-equal: 3.1.3 - fast-querystring: 1.1.2 - safe-regex2: 5.0.0 + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 - find-up@4.1.0: + brace-expansion@2.1.7: dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 + balanced-match: 1.0.2 - find-up@5.0.0: + braces@3.0.3: dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 + fill-range: 7.1.1 + + buffer-crc32@1.0.0: {} - find-versions@5.1.0: + buffer-from@1.1.2: + optional: true + + buffer@5.7.1: dependencies: - semver-regex: 4.0.5 + base64-js: 1.5.1 + ieee754: 1.2.1 - flat-cache@4.0.1: + buffer@6.0.3: dependencies: - flatted: 3.3.3 - keyv: 4.5.4 + base64-js: 1.5.1 + ieee754: 1.2.1 - flatted@3.3.3: {} + buildcheck@0.0.7: + optional: true - fn.name@1.1.0: {} + byline@5.0.0: {} - for-each@0.3.5: + c12@3.3.4(magicast@0.5.5): dependencies: - is-callable: 1.2.7 + chokidar: 5.0.0 + confbox: 0.2.4 + defu: 6.1.7 + dotenv: 17.3.1 + exsolve: 1.0.8 + giget: 3.3.1 + jiti: 2.7.0 + ohash: 2.0.11 + pathe: 2.0.3 + perfect-debounce: 2.1.0 + pkg-types: 2.3.0 + rc9: 3.1.0 + optionalDependencies: + magicast: 0.5.5 - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 + cac@7.0.1: {} - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18))): - dependencies: - '@babel/code-frame': 7.29.0 - chalk: 4.1.2 - chokidar: 4.0.3 - cosmiconfig: 8.3.6(typescript@5.9.3) - deepmerge: 4.3.1 - fs-extra: 10.1.0 - memfs: 3.5.3 - minimatch: 3.1.2 - node-abort-controller: 3.1.1 - schema-utils: 3.3.0 - semver: 7.7.4 - tapable: 2.3.0 - typescript: 5.9.3 - webpack: 5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18)) + callsites@3.1.0: {} + + chai@6.3.0: {} - form-data-encoder@2.1.4: {} + chardet@2.1.1: {} - form-data@4.0.5: + chokidar@4.0.3: dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 + readdirp: 4.1.2 - formidable@3.5.4: + chokidar@5.0.0: dependencies: - '@paralleldrive/cuid2': 2.3.1 - dezalgo: 1.0.4 - once: 1.4.0 + readdirp: 5.1.1 - forwarded@0.2.0: - optional: true + chownr@1.1.4: {} - fresh@2.0.0: - optional: true + ci-info@3.9.0: {} - fs-extra@10.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.2.0 - universalify: 2.0.1 + classnames@2.5.1: {} - fs-extra@7.0.1: + cliui@8.0.1: dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 - fs-extra@8.1.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 4.0.0 - universalify: 0.1.2 + clsx@2.1.1: {} - fs-monkey@1.1.0: {} + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 - fs.realpath@1.0.0: {} + color-name@1.1.4: {} - fsevents@2.3.3: + commander@2.20.3: optional: true - function-bind@1.1.2: {} + commander@7.2.0: {} - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 + commondir@1.0.1: {} - functions-have-names@1.2.3: {} + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 - generate-function@2.3.1: + compress-commons@6.0.2: dependencies: - is-property: 1.0.2 + crc-32: 1.2.2 + crc32-stream: 6.0.0 + is-stream: 2.0.1 + normalize-path: 3.0.0 + readable-stream: 4.8.0 - generator-function@2.0.1: {} + confbox@0.2.4: {} - gensync@1.0.0-beta.2: {} + conventional-changelog-angular@8.1.0: + dependencies: + compare-func: 2.0.0 - get-caller-file@2.0.5: {} + conventional-changelog-conventionalcommits@9.1.0: + dependencies: + compare-func: 2.0.0 - get-intrinsic@1.3.0: + conventional-commits-parser@6.2.1: dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 + meow: 13.2.0 - get-package-type@0.1.0: {} + cookie@0.6.0: {} - get-port-please@3.2.0: {} + core-util-is@1.0.3: {} - get-proto@1.0.1: + cosmiconfig-typescript-loader@6.2.0(@types/node@26.6.3)(cosmiconfig@9.0.0(typescript@7.0.2))(typescript@7.0.2): dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 + '@types/node': 26.6.3 + cosmiconfig: 9.0.0(typescript@7.0.2) + jiti: 2.6.1 + typescript: 7.0.2 - get-stream@6.0.1: {} + cosmiconfig@9.0.0(typescript@7.0.2): + dependencies: + env-paths: 2.2.1 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + optionalDependencies: + typescript: 7.0.2 - get-symbol-description@1.1.0: + cpu-features@0.0.10: dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 + buildcheck: 0.0.7 + nan: 2.29.0 + optional: true - get-tsconfig@4.14.0: + crc-32@1.2.2: {} + + crc32-stream@6.0.0: dependencies: - resolve-pkg-maps: 1.0.0 + crc-32: 1.2.2 + readable-stream: 4.8.0 - giget@2.0.0: + cross-env@10.1.0: dependencies: - citty: 0.1.6 - consola: 3.4.2 - defu: 6.1.4 - node-fetch-native: 1.6.7 - nypm: 0.6.5 - pathe: 2.0.3 + '@epic-web/invariant': 1.0.0 + cross-spawn: 7.0.6 - git-raw-commits@4.0.0: + cross-spawn@7.0.6: dependencies: - dargs: 8.1.0 - meow: 12.1.1 - split2: 4.2.0 + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 - glob-parent@5.1.2: + csstype@3.2.3: {} + + d3-array@2.12.1: dependencies: - is-glob: 4.0.3 + internmap: 1.0.1 - glob-parent@6.0.2: + d3-array@3.2.1: dependencies: - is-glob: 4.0.3 + internmap: 2.0.3 - glob-to-regexp@0.4.1: {} + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 - glob@11.1.0: + d3-chord@3.0.1: dependencies: - foreground-child: 3.3.1 - jackspeak: 4.2.3 - minimatch: 10.2.5 - minipass: 7.1.3 - package-json-from-dist: 1.0.1 - path-scurry: 2.0.2 - optional: true + d3-path: 3.1.0 + + d3-color@3.1.0: {} - glob@13.0.0: + d3-contour@4.0.2: dependencies: - minimatch: 10.2.2 - minipass: 7.1.3 - path-scurry: 2.0.2 + d3-array: 3.2.4 - glob@7.2.3: + d3-delaunay@6.0.2: dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 + delaunator: 5.1.0 - global-directory@4.0.1: + d3-delaunay@6.0.4: dependencies: - ini: 4.1.1 + delaunator: 5.1.0 + + d3-dispatch@3.0.1: {} - globals@14.0.0: {} + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 - globals@16.5.0: {} + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.0: {} + + d3-format@3.1.2: {} + + d3-geo-voronoi@2.1.0: + dependencies: + d3-array: 3.2.4 + d3-delaunay: 6.0.4 + d3-geo: 3.1.1 + d3-tricontour: 1.1.0 - globalthis@1.0.4: + d3-geo@3.1.0: dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 + d3-array: 3.2.4 - globby@11.1.0: + d3-geo@3.1.1: dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 + d3-array: 3.2.4 - gopd@1.2.0: {} + d3-hierarchy@3.1.2: {} + + d3-interpolate-path@2.3.0: {} - got@13.0.0: + d3-interpolate@3.0.1: dependencies: - '@sindresorhus/is': 5.6.0 - '@szmarczak/http-timer': 5.0.1 - cacheable-lookup: 7.0.0 - cacheable-request: 10.2.14 - decompress-response: 6.0.0 - form-data-encoder: 2.1.4 - get-stream: 6.0.1 - http2-wrapper: 2.2.1 - lowercase-keys: 3.0.0 - p-cancelable: 3.0.0 - responselike: 3.0.0 + d3-color: 3.1.0 - graceful-fs@4.2.11: {} + d3-path@1.0.9: {} - grammex@3.1.12: {} + d3-path@3.1.0: {} - graphmatch@1.1.1: {} + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} - handlebars@4.7.8: + d3-sankey@0.12.3: dependencies: - minimist: 1.2.8 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.19.3 + d3-array: 2.12.1 + d3-shape: 1.3.7 - has-bigints@1.1.0: {} + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 - has-flag@4.0.0: {} + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.2 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 - has-property-descriptors@1.0.2: + d3-shape@1.3.7: dependencies: - es-define-property: 1.0.1 + d3-path: 1.0.9 - has-proto@1.2.0: + d3-shape@3.2.0: dependencies: - dunder-proto: 1.0.1 + d3-path: 3.1.0 - has-symbols@1.1.0: {} + d3-tile@1.0.0: {} - has-tostringtag@1.0.2: + d3-time-format@4.1.0: dependencies: - has-symbols: 1.1.0 + d3-time: 3.1.0 - hasown@2.0.2: + d3-time@3.1.0: dependencies: - function-bind: 1.1.2 - - hono@4.11.4: {} - - html-escaper@2.0.2: {} + d3-array: 3.2.4 - http-cache-semantics@4.2.0: {} + d3-timer@3.0.1: {} - http-errors@2.0.1: + d3-tricontour@1.1.0: dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 - optional: true + d3-delaunay: 6.0.4 + d3-scale: 4.0.2 - http-status-codes@2.3.0: {} + dargs@8.1.0: {} - http2-wrapper@2.2.1: + debug@4.4.3: dependencies: - quick-lru: 5.1.1 - resolve-alpn: 1.2.1 + ms: 2.1.3 - human-id@4.1.3: {} + deepmerge-ts@7.1.5: {} - human-signals@2.1.0: {} + deepmerge@4.3.1: {} - husky@9.1.7: {} + defu@6.1.7: {} - iconv-lite@0.6.3: + delaunator@5.1.0: dependencies: - safer-buffer: 2.1.2 + robust-predicates: 3.0.3 - iconv-lite@0.7.2: - dependencies: - safer-buffer: 2.1.2 + denque@2.1.0: {} - iconv-lite@0.7.3: - dependencies: - safer-buffer: 2.1.2 - optional: true + dequal@2.0.3: {} - ieee754@1.2.1: {} + destr@2.0.5: {} - ignore@5.3.2: {} + detect-indent@6.1.0: {} - ignore@7.0.5: {} + detect-libc@2.1.2: {} - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 + devalue@5.8.1: {} - import-local@3.2.0: + dir-glob@3.0.1: dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - - import-meta-resolve@4.2.0: {} - - imurmurhash@0.1.4: {} + path-type: 4.0.0 - inflight@1.0.6: + docker-compose@1.5.0: dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - ini@4.1.1: {} + yaml: 2.9.0 - inspect-with-kind@1.0.5: + docker-modem@5.0.7: dependencies: - kind-of: 6.0.3 + debug: 4.4.3 + readable-stream: 3.6.2 + split-ca: 1.0.1 + ssh2: 1.17.0 + transitivePeerDependencies: + - supports-color - internal-slot@1.1.0: + dockerode@5.0.1: dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - - internmap@1.0.1: {} + '@balena/dockerignore': 1.0.2 + '@grpc/grpc-js': 1.14.6 + '@grpc/proto-loader': 0.7.15 + docker-modem: 5.0.7 + protobufjs: 7.6.6 + tar-fs: 2.1.5 + transitivePeerDependencies: + - supports-color - internmap@2.0.3: {} + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 - ipaddr.js@1.9.1: - optional: true + dotenv@17.3.1: {} - ipaddr.js@2.3.0: {} + dotenv@18.0.4: {} - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 + dts-resolver@3.0.0: {} - is-arrayish@0.2.1: {} + eastasianwidth@0.2.0: {} - is-async-function@2.1.1: + effect@3.20.0: dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 + '@standard-schema/spec': 1.1.0 + fast-check: 3.23.2 - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 + elkjs@0.11.1: {} - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 + emoji-regex@8.0.0: {} - is-bun-module@2.0.0: - dependencies: - semver: 7.7.4 + emoji-regex@9.2.2: {} - is-callable@1.2.7: {} + empathic@2.0.0: {} - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 + empathic@2.1.0: {} - is-data-view@1.0.2: + end-of-stream@1.4.5: dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 + once: 1.4.0 - is-date-object@1.1.0: + enhanced-resolve@5.21.6: dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-extglob@2.1.1: {} + graceful-fs: 4.2.11 + tapable: 2.3.3 - is-finalizationregistry@1.1.1: + enquirer@2.4.1: dependencies: - call-bound: 1.0.4 - - is-fullwidth-code-point@3.0.0: {} + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 - is-generator-fn@2.1.0: {} + env-paths@2.2.1: {} - is-generator-function@1.1.2: - dependencies: - call-bound: 1.0.4 - generator-function: 2.0.1 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 + env-paths@3.0.0: {} - is-glob@4.0.3: + error-ex@1.3.4: dependencies: - is-extglob: 2.1.1 - - is-interactive@1.0.0: {} - - is-map@2.0.3: {} + is-arrayish: 0.2.1 - is-module@1.0.0: {} + es-module-lexer@2.3.2: {} - is-negative-zero@2.0.3: {} + es-toolkit@1.49.0: {} - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 - is-number@7.0.0: {} + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 - is-obj@2.0.0: {} + escalade@3.2.0: {} - is-plain-obj@1.1.0: {} + esm-env@1.2.2: {} - is-plain-obj@4.1.0: {} + esprima@4.0.1: {} - is-promise@4.0.0: - optional: true + esrap@2.2.13(@typescript-eslint/types@8.56.0): + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + optionalDependencies: + '@typescript-eslint/types': 8.56.0 - is-property@1.0.2: {} + estree-walker@2.0.2: {} - is-reference@1.2.1: + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 - is-reference@3.0.3: - dependencies: - '@types/estree': 1.0.8 + event-target-shim@5.0.1: {} - is-regex@1.2.1: + events-universal@1.0.1: dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 + bare-events: 2.9.2 + transitivePeerDependencies: + - bare-abort-controller - is-set@2.0.3: {} + events@3.3.0: {} - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 + eventsource-parser@3.0.8: {} - is-stream@2.0.1: {} + expect-type@1.4.0: {} - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 + exsolve@1.0.8: {} - is-subdir@1.2.0: - dependencies: - better-path-resolve: 1.0.0 + extendable-error@0.1.7: {} - is-symbol@1.1.1: + fast-check@3.23.2: dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 + pure-rand: 6.1.0 - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.20 + fast-decode-uri-component@1.0.1: {} - is-unicode-supported@0.1.0: {} + fast-deep-equal@3.1.3: {} - is-weakmap@2.0.2: {} + fast-fifo@1.3.2: {} - is-weakref@1.1.1: + fast-glob@3.3.3: dependencies: - call-bound: 1.0.4 + '@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 - is-weakset@2.0.4: + fast-querystring@1.1.2: dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-windows@1.0.2: {} + fast-decode-uri-component: 1.0.1 - isarray@1.0.0: {} + fast-uri@3.1.0: {} - isarray@2.0.5: {} + fastq@1.20.1: + dependencies: + reusify: 1.1.0 - isexe@2.0.0: {} + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 - istanbul-lib-coverage@3.2.2: {} + fdir@6.5.0(picomatch@4.0.7): + optionalDependencies: + picomatch: 4.0.7 - istanbul-lib-instrument@5.2.1: + fill-range@7.1.1: dependencies: - '@babel/core': 7.29.0 - '@babel/parser': 7.29.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + to-regex-range: 5.0.1 - istanbul-lib-instrument@6.0.3: + find-my-way@9.7.0: dependencies: - '@babel/core': 7.29.0 - '@babel/parser': 7.29.0 - '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 7.7.4 - transitivePeerDependencies: - - supports-color + fast-deep-equal: 3.1.3 + fast-querystring: 1.1.2 + safe-regex2: 5.0.0 - istanbul-lib-report@3.0.1: + find-up@4.1.0: dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 + locate-path: 5.0.0 + path-exists: 4.0.0 - istanbul-lib-source-maps@4.0.1: + foreground-child@3.3.1: dependencies: - debug: 4.4.3 - istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color + cross-spawn: 7.0.6 + signal-exit: 4.1.0 - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 + fs-constants@1.0.0: {} - iterare@1.2.1: {} + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 - jackspeak@4.2.3: + fs-extra@8.1.0: dependencies: - '@isaacs/cliui': 9.0.0 + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fsevents@2.3.3: optional: true - jest-changed-files@29.7.0: - dependencies: - execa: 5.1.1 - jest-util: 29.7.0 - p-limit: 3.1.0 + function-bind@1.1.2: {} - jest-circus@29.7.0: + generate-function@2.3.1: dependencies: - '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - chalk: 4.1.2 - co: 4.6.0 - dedent: 1.7.1 - is-generator-fn: 2.1.0 - jest-each: 29.7.0 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.1.0 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color + is-property: 1.0.2 - jest-cli@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node + get-caller-file@2.0.5: {} - jest-config@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)): - dependencies: - '@babel/core': 7.29.0 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.29.0) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - '@types/node': 22.19.11 - ts-node: 10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color + get-port-please@3.2.0: {} - jest-diff@29.7.0: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + get-port@5.1.1: {} - jest-diff@30.2.0: + get-tsconfig@5.0.0-beta.6: dependencies: - '@jest/diff-sequences': 30.0.1 - '@jest/get-type': 30.1.0 - chalk: 4.1.2 - pretty-format: 30.2.0 + resolve-pkg-maps: 1.0.0 - jest-docblock@29.7.0: + giget@3.3.1: {} + + git-raw-commits@4.0.0: dependencies: - detect-newline: 3.1.0 + dargs: 8.1.0 + meow: 12.1.1 + split2: 4.2.0 - jest-each@29.7.0: + glob-parent@5.1.2: dependencies: - '@jest/types': 29.6.3 - chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 + is-glob: 4.0.3 - jest-environment-node@29.7.0: + glob@10.5.0: dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - jest-mock: 29.7.0 - jest-util: 29.7.0 + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 - jest-esm-transformer@1.0.0: + global-directory@4.0.1: dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) - transitivePeerDependencies: - - supports-color + ini: 4.1.1 - jest-get-type@29.6.3: {} + globals@16.5.0: {} - jest-haste-map@29.7.0: + globby@11.1.0: dependencies: - '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.9 - '@types/node': 22.19.11 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.7.0 - micromatch: 4.0.8 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 - jest-haste-map@30.2.0: - dependencies: - '@jest/types': 30.2.0 - '@types/node': 22.19.11 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 30.0.1 - jest-util: 30.2.0 - jest-worker: 30.2.0 - micromatch: 4.0.8 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 + globrex@0.1.2: {} - jest-leak-detector@29.7.0: - dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + graceful-fs@4.2.11: {} - jest-matcher-utils@29.7.0: - dependencies: - chalk: 4.1.2 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 + grammex@3.1.12: {} - jest-matcher-utils@30.2.0: + graphmatch@1.1.1: {} + + hasown@2.0.2: dependencies: - '@jest/get-type': 30.1.0 - chalk: 4.1.2 - jest-diff: 30.2.0 - pretty-format: 30.2.0 + function-bind: 1.1.2 - jest-message-util@29.7.0: + hono-openapi@1.3.3(effect@3.20.0)(hono@4.13.9)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5): dependencies: - '@babel/code-frame': 7.29.0 - '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - stack-utils: 2.0.6 + '@hono/standard-validator': 0.4.0(@standard-schema/spec@1.1.0)(hono@4.13.9) + '@standard-community/standard-json': 0.3.6(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(effect@3.20.0)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5) + '@standard-community/standard-openapi': 0.2.10(@standard-community/standard-json@0.3.6(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(effect@3.20.0)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5))(@standard-schema/spec@1.1.0)(effect@3.20.0)(openapi-types@12.1.3)(valibot@1.4.2(typescript@7.0.2))(zod@4.6.5) + '@standard-schema/spec': 1.1.0 + '@types/json-schema': 7.0.15 + hono: 4.13.9 + openapi-types: 12.1.3 + transitivePeerDependencies: + - '@valibot/to-json-schema' + - arktype + - effect + - sury + - typebox + - valibot + - zod + - zod-openapi + - zod-to-json-schema + + hono@4.13.9: {} + + hookable@6.1.2: {} + + human-id@4.1.3: {} - jest-message-util@30.2.0: + husky@9.1.7: {} + + iconv-lite@0.6.3: dependencies: - '@babel/code-frame': 7.29.0 - '@jest/types': 30.2.0 - '@types/stack-utils': 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 30.2.0 - slash: 3.0.0 - stack-utils: 2.0.6 + safer-buffer: 2.1.2 - jest-mock-extended@4.0.0(@jest/globals@30.2.0)(jest@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)))(typescript@5.9.3): + iconv-lite@0.7.2: dependencies: - '@jest/globals': 30.2.0 - jest: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - ts-essentials: 10.1.1(typescript@5.9.3) - typescript: 5.9.3 + safer-buffer: 2.1.2 - jest-mock@29.7.0: + iconv-lite@0.7.3: dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - jest-util: 29.7.0 + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} - jest-mock@30.2.0: + ignore@5.3.2: {} + + import-fresh@3.3.1: dependencies: - '@jest/types': 30.2.0 - '@types/node': 22.19.11 - jest-util: 30.2.0 + parent-module: 1.0.1 + resolve-from: 4.0.0 - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): - optionalDependencies: - jest-resolve: 29.7.0 + import-meta-resolve@4.2.0: {} - jest-regex-util@29.6.3: {} + import-without-cache@0.4.1: {} - jest-regex-util@30.0.1: {} + inherits@2.0.4: {} - jest-resolve-dependencies@29.7.0: - dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color + ini@4.1.1: {} - jest-resolve@29.7.0: - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.11 - resolve.exports: 2.0.3 - slash: 3.0.0 + internmap@1.0.1: {} - jest-runner@29.7.0: - dependencies: - '@jest/console': 29.7.0 - '@jest/environment': 29.7.0 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.7.0 - jest-environment-node: 29.7.0 - jest-haste-map: 29.7.0 - jest-leak-detector: 29.7.0 - jest-message-util: 29.7.0 - jest-resolve: 29.7.0 - jest-runtime: 29.7.0 - jest-util: 29.7.0 - jest-watcher: 29.7.0 - jest-worker: 29.7.0 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color + internmap@2.0.3: {} - jest-runtime@29.7.0: + is-arrayish@0.2.1: {} + + is-core-module@2.16.1: dependencies: - '@jest/environment': 29.7.0 - '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 - '@jest/source-map': 29.6.3 - '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - chalk: 4.1.2 - cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.3 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color + hasown: 2.0.2 - jest-snapshot@29.7.0: - dependencies: - '@babel/core': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) - '@babel/types': 7.29.0 - '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 - '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) - chalk: 4.1.2 - expect: 29.7.0 - graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.7.4 - transitivePeerDependencies: - - supports-color + is-extglob@2.1.1: {} - jest-snapshot@30.2.0: - dependencies: - '@babel/core': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) - '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) - '@babel/types': 7.29.0 - '@jest/expect-utils': 30.2.0 - '@jest/get-type': 30.1.0 - '@jest/snapshot-utils': 30.2.0 - '@jest/transform': 30.2.0 - '@jest/types': 30.2.0 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) - chalk: 4.1.2 - expect: 30.2.0 - graceful-fs: 4.2.11 - jest-diff: 30.2.0 - jest-matcher-utils: 30.2.0 - jest-message-util: 30.2.0 - jest-util: 30.2.0 - pretty-format: 30.2.0 - semver: 7.7.4 - synckit: 0.11.12 - transitivePeerDependencies: - - supports-color + is-fullwidth-code-point@3.0.0: {} - jest-util@29.7.0: + is-glob@4.0.3: dependencies: - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - chalk: 4.1.2 - ci-info: 3.9.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 + is-extglob: 2.1.1 - jest-util@30.2.0: - dependencies: - '@jest/types': 30.2.0 - '@types/node': 22.19.11 - chalk: 4.1.2 - ci-info: 4.4.0 - graceful-fs: 4.2.11 - picomatch: 4.0.3 + is-module@1.0.0: {} - jest-validate@29.7.0: - dependencies: - '@jest/types': 29.6.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.6.3 - leven: 3.1.0 - pretty-format: 29.7.0 + is-number@7.0.0: {} - jest-watcher@29.7.0: - dependencies: - '@jest/test-result': 29.7.0 - '@jest/types': 29.6.3 - '@types/node': 22.19.11 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.7.0 - string-length: 4.0.2 + is-obj@2.0.0: {} + + is-plain-obj@4.1.0: {} + + is-property@1.0.2: {} - jest-worker@27.5.1: + is-reference@1.2.1: dependencies: - '@types/node': 22.19.11 - merge-stream: 2.0.0 - supports-color: 8.1.1 + '@types/estree': 1.0.8 - jest-worker@29.7.0: + is-reference@3.0.3: dependencies: - '@types/node': 22.19.11 - jest-util: 29.7.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 + '@types/estree': 1.0.8 + + is-stream@2.0.1: {} - jest-worker@30.2.0: + is-subdir@1.2.0: dependencies: - '@types/node': 22.19.11 - '@ungap/structured-clone': 1.3.0 - jest-util: 30.2.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 + better-path-resolve: 1.0.0 + + is-windows@1.0.2: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} - jest@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)): + jackspeak@3.4.3: dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 jiti@2.6.1: {} jiti@2.7.0: {} + js-tokens@10.0.0: {} + js-tokens@4.0.0: {} js-yaml@3.14.2: @@ -12465,77 +7801,17 @@ snapshots: dependencies: argparse: 2.0.1 - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - json-parse-even-better-errors@2.3.1: {} - json-schema-ref-resolver@3.0.0: - dependencies: - dequal: 2.0.3 - - json-schema-traverse@0.4.1: {} - json-schema-traverse@1.0.0: {} - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@1.0.2: - dependencies: - minimist: 1.2.8 - - json5@2.2.3: {} - - jsonc-parser@3.3.1: {} - jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 - jsonfile@6.2.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - jsonwebtoken@9.0.3: - dependencies: - jws: 4.0.1 - lodash.includes: 4.3.0 - lodash.isboolean: 3.0.3 - lodash.isinteger: 4.0.4 - lodash.isnumber: 3.0.3 - lodash.isplainobject: 4.0.6 - lodash.isstring: 4.0.1 - lodash.once: 4.1.1 - ms: 2.1.3 - semver: 7.7.4 - - jwa@2.0.1: - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - - jws@4.0.1: - dependencies: - jwa: 2.0.1 - safe-buffer: 5.2.1 - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kind-of@6.0.3: {} - - kleur@3.0.3: {} - kleur@4.1.5: {} - kuler@2.0.0: {} - - layerchart@2.0.0-next.65(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(zod@4.3.6): + layerchart@2.0.0-next.65(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(zod@4.3.6): dependencies: '@dagrejs/dagre': 2.0.4 '@layerstack/svelte-actions': 1.0.1-next.18 @@ -12565,27 +7841,15 @@ snapshots: d3-tile: 1.0.0 d3-time: 3.1.0 memoize: 10.2.0 - runed: 0.37.1(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(zod@4.3.6) + runed: 0.37.1(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(zod@4.3.6) svelte: 5.56.4(@typescript-eslint/types@8.56.0) transitivePeerDependencies: - '@sveltejs/kit' - zod - leven@3.1.0: {} - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - libphonenumber-js@1.13.8: - optional: true - - light-my-request@6.6.0: + lazystream@1.0.1: dependencies: - cookie: 1.1.1 - process-warning: 4.0.1 - set-cookie-parser: 2.7.2 + readable-stream: 2.3.8 lightningcss-android-arm64@1.32.0: optional: true @@ -12636,115 +7900,49 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 - lilconfig@2.1.0: {} - lines-and-columns@1.2.4: {} - load-esm@1.0.3: {} - - loader-runner@4.3.1: {} - locate-character@3.0.0: {} locate-path@5.0.0: dependencies: p-locate: 4.1.0 - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - lodash.camelcase@4.3.0: {} - lodash.includes@4.3.0: {} - - lodash.isboolean@3.0.3: {} - - lodash.isinteger@4.0.4: {} - - lodash.isnumber@3.0.3: {} - - lodash.isplainobject@4.0.6: {} - - lodash.isstring@4.0.1: {} - lodash.kebabcase@4.1.1: {} - lodash.memoize@4.1.2: {} - - lodash.merge@4.6.2: {} - lodash.mergewith@4.6.2: {} - lodash.once@4.1.1: {} - lodash.snakecase@4.1.1: {} lodash.startcase@4.4.0: {} lodash.upperfirst@4.3.1: {} - lodash@4.17.21: {} - lodash@4.17.23: {} - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - - logform@2.7.0: - dependencies: - '@colors/colors': 1.6.0 - '@types/triple-beam': 1.3.5 - fecha: 4.2.3 - ms: 2.1.3 - safe-stable-stringify: 2.5.0 - triple-beam: 1.4.1 - long@5.3.2: {} - lowercase-keys@3.0.0: {} - - lru-cache@11.2.6: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 + lru-cache@10.4.3: {} lru.min@1.1.4: {} lz-string@1.5.0: {} - magic-string@0.30.17: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - make-dir@4.0.0: - dependencies: - semver: 7.7.4 - - make-error@1.3.6: {} - - makeerror@1.0.12: + magic-string@1.4.3: dependencies: - tmpl: 1.0.5 + '@jridgewell/sourcemap-codec': 1.6.0 - math-intrinsics@1.1.0: {} - - media-typer@0.3.0: - optional: true - - media-typer@1.1.0: - optional: true - - memfs@3.5.3: + magicast@0.5.5: dependencies: - fs-monkey: 1.1.0 + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + source-map-js: 1.2.1 memoize@10.2.0: dependencies: @@ -12754,97 +7952,43 @@ snapshots: meow@13.2.0: {} - merge-descriptors@2.0.0: - optional: true - - 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.1 - mime-db@1.52.0: {} - - mime-db@1.54.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 - optional: true - - mime@2.6.0: {} - - mime@3.0.0: - optional: true - - mimic-fn@2.1.0: {} - mimic-function@5.0.1: {} - mimic-response@3.1.0: {} - - mimic-response@4.0.0: {} - - minimatch@10.2.2: - dependencies: - brace-expansion: 5.0.2 - - minimatch@10.2.5: - dependencies: - brace-expansion: 5.0.7 - optional: true - - minimatch@3.1.2: + minimatch@5.1.9: dependencies: - brace-expansion: 1.1.12 + brace-expansion: 2.1.7 - minimatch@9.0.5: + minimatch@9.0.9: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 2.1.7 minimist@1.2.8: {} minipass@7.1.3: {} - mkdirp@0.5.6: - dependencies: - minimist: 1.2.8 - optional: true - + mkdirp-classic@0.5.3: {} + + mkdirp@3.0.1: {} + mri@1.2.0: {} mrmime@2.0.1: {} ms@2.1.3: {} - multer@2.0.2: - dependencies: - append-field: 1.0.0 - busboy: 1.6.0 - concat-stream: 2.0.0 - mkdirp: 0.5.6 - object-assign: 4.1.1 - type-is: 1.6.18 - xtend: 4.0.2 - optional: true - - mute-stream@2.0.0: {} - mysql2@3.15.3: dependencies: aws-ssl-profiles: 1.1.2 denque: 2.1.0 generate-function: 2.3.1 - iconv-lite: 0.7.2 + iconv-lite: 0.7.3 long: 5.3.2 lru.min: 1.1.4 named-placeholders: 1.1.6 @@ -12855,164 +7999,35 @@ snapshots: dependencies: lru.min: 1.1.4 - nanoid@3.3.11: {} - - napi-postinstall@0.3.4: {} - - natural-compare@1.4.0: {} - - negotiator@1.0.0: + nan@2.29.0: optional: true - neo-async@2.6.2: {} - - nest-winston@1.10.2(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(winston@3.19.0): - dependencies: - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - fast-safe-stringify: 2.1.1 - winston: 3.19.0 - - nestjs-zod@5.1.1(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/swagger@11.2.6(@fastify/static@8.3.0)(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2))(rxjs@7.8.2)(zod@4.3.6): - dependencies: - '@nestjs/common': 11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2) - deepmerge: 4.3.1 - rxjs: 7.8.2 - zod: 4.3.6 - optionalDependencies: - '@nestjs/swagger': 11.2.6(@fastify/static@8.3.0)(@nestjs/common@11.1.14(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.14)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.2.2) - - node-abort-controller@3.1.1: {} - - node-addon-api@8.5.0: {} - - node-emoji@1.11.0: - dependencies: - lodash: 4.17.23 + nanoid@3.3.11: {} - node-exports-info@1.6.0: - dependencies: - array.prototype.flatmap: 1.3.3 - es-errors: 1.3.0 - object.entries: 1.1.9 - semver: 6.3.1 + nanoid@5.1.16: {} - node-fetch-native@1.6.7: {} + node-addon-api@8.9.2: {} node-gyp-build@4.8.4: {} - node-int64@0.4.0: {} - - node-releases@2.0.27: {} - normalize-path@3.0.0: {} - normalize-url@8.1.1: {} - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - nypm@0.6.5: - dependencies: - citty: 0.2.1 - pathe: 2.0.3 - tinyexec: 1.0.2 - - object-assign@4.1.1: - optional: true - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - object.entries@1.1.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - object.fromentries@2.0.8: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - - object.groupby@1.0.3: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - - object.values@1.2.1: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - obug@2.1.1: {} - ohash@2.0.11: {} + obug@2.2.1: {} - on-exit-leak-free@2.1.2: {} + obug@3.0.0: {} - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - optional: true + ohash@2.0.11: {} once@1.4.0: dependencies: wrappy: 1.0.2 - one-time@1.0.0: - dependencies: - fn.name: 1.1.0 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - ora@5.4.1: - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.9.2 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 + openapi-types@12.1.3: {} outdent@0.5.0: {} - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - oxfmt@0.57.0(svelte@5.56.4(@typescript-eslint/types@8.56.0)): dependencies: tinypool: 2.1.0 @@ -13038,6 +8053,31 @@ snapshots: '@oxfmt/binding-win32-x64-msvc': 0.57.0 svelte: 5.56.4(@typescript-eslint/types@8.56.0) + oxfmt@0.70.0(svelte@5.56.4(@typescript-eslint/types@8.56.0)): + dependencies: + tinypool: 2.1.2 + optionalDependencies: + '@oxfmt/binding-android-arm-eabi': 0.70.0 + '@oxfmt/binding-android-arm64': 0.70.0 + '@oxfmt/binding-darwin-arm64': 0.70.0 + '@oxfmt/binding-darwin-x64': 0.70.0 + '@oxfmt/binding-freebsd-x64': 0.70.0 + '@oxfmt/binding-linux-arm-gnueabihf': 0.70.0 + '@oxfmt/binding-linux-arm-musleabihf': 0.70.0 + '@oxfmt/binding-linux-arm64-gnu': 0.70.0 + '@oxfmt/binding-linux-arm64-musl': 0.70.0 + '@oxfmt/binding-linux-ppc64-gnu': 0.70.0 + '@oxfmt/binding-linux-riscv64-gnu': 0.70.0 + '@oxfmt/binding-linux-riscv64-musl': 0.70.0 + '@oxfmt/binding-linux-s390x-gnu': 0.70.0 + '@oxfmt/binding-linux-x64-gnu': 0.70.0 + '@oxfmt/binding-linux-x64-musl': 0.70.0 + '@oxfmt/binding-openharmony-arm64': 0.70.0 + '@oxfmt/binding-win32-arm64-msvc': 0.70.0 + '@oxfmt/binding-win32-ia32-msvc': 0.70.0 + '@oxfmt/binding-win32-x64-msvc': 0.70.0 + svelte: 5.56.4(@typescript-eslint/types@8.56.0) + oxlint-tsgolint@0.17.4: optionalDependencies: '@oxlint-tsgolint/darwin-arm64': 0.17.4 @@ -13047,6 +8087,15 @@ snapshots: '@oxlint-tsgolint/win32-arm64': 0.17.4 '@oxlint-tsgolint/win32-x64': 0.17.4 + oxlint-tsgolint@7.0.2003: + optionalDependencies: + '@oxlint-tsgolint/darwin-arm64': 7.0.2003 + '@oxlint-tsgolint/darwin-x64': 7.0.2003 + '@oxlint-tsgolint/linux-arm64': 7.0.2003 + '@oxlint-tsgolint/linux-x64': 7.0.2003 + '@oxlint-tsgolint/win32-arm64': 7.0.2003 + '@oxlint-tsgolint/win32-x64': 7.0.2003 + oxlint@1.72.0(oxlint-tsgolint@0.17.4): optionalDependencies: '@oxlint/binding-android-arm-eabi': 1.72.0 @@ -13070,7 +8119,28 @@ snapshots: '@oxlint/binding-win32-x64-msvc': 1.72.0 oxlint-tsgolint: 0.17.4 - p-cancelable@3.0.0: {} + oxlint@1.85.0(oxlint-tsgolint@7.0.2003): + optionalDependencies: + '@oxlint/binding-android-arm-eabi': 1.85.0 + '@oxlint/binding-android-arm64': 1.85.0 + '@oxlint/binding-darwin-arm64': 1.85.0 + '@oxlint/binding-darwin-x64': 1.85.0 + '@oxlint/binding-freebsd-x64': 1.85.0 + '@oxlint/binding-linux-arm-gnueabihf': 1.85.0 + '@oxlint/binding-linux-arm-musleabihf': 1.85.0 + '@oxlint/binding-linux-arm64-gnu': 1.85.0 + '@oxlint/binding-linux-arm64-musl': 1.85.0 + '@oxlint/binding-linux-ppc64-gnu': 1.85.0 + '@oxlint/binding-linux-riscv64-gnu': 1.85.0 + '@oxlint/binding-linux-riscv64-musl': 1.85.0 + '@oxlint/binding-linux-s390x-gnu': 1.85.0 + '@oxlint/binding-linux-x64-gnu': 1.85.0 + '@oxlint/binding-linux-x64-musl': 1.85.0 + '@oxlint/binding-openharmony-arm64': 1.85.0 + '@oxlint/binding-win32-arm64-msvc': 1.85.0 + '@oxlint/binding-win32-ia32-msvc': 1.85.0 + '@oxlint/binding-win32-x64-msvc': 1.85.0 + oxlint-tsgolint: 7.0.2003 p-filter@2.1.0: dependencies: @@ -13080,24 +8150,15 @@ snapshots: dependencies: p-try: 2.2.0 - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - p-locate@4.1.0: dependencies: p-limit: 2.3.0 - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - p-map@2.1.0: {} p-try@2.2.0: {} - package-json-from-dist@1.0.1: - optional: true + package-json-from-dist@1.0.1: {} package-manager-detector@0.2.11: dependencies: @@ -13114,51 +8175,38 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parseurl@1.3.3: - optional: true - path-exists@4.0.0: {} - path-is-absolute@1.0.1: {} - path-key@3.1.1: {} path-parse@1.0.7: {} - path-scurry@2.0.2: + path-scurry@1.11.1: dependencies: - lru-cache: 11.2.6 + lru-cache: 10.4.3 minipass: 7.1.3 - path-to-regexp@8.3.0: {} - path-type@4.0.0: {} pathe@2.0.3: {} - peek-stream@1.1.3: - dependencies: - buffer-from: 1.1.2 - duplexify: 3.7.1 - through2: 2.0.5 - - pend@1.2.0: {} + perfect-debounce@2.1.0: {} - perfect-debounce@1.0.0: {} - - pg-cloudflare@1.3.0: + pg-cloudflare@1.4.0: optional: true - pg-connection-string@2.11.0: {} + pg-connection-string@2.14.0: {} pg-int8@1.0.1: {} - pg-pool@3.11.0(pg@8.18.0): + pg-pool@3.14.0(pg@8.23.0): dependencies: - pg: 8.18.0 + pg: 8.23.0 pg-protocol@1.11.0: {} + pg-protocol@1.16.0: {} + pg-types@2.2.0: dependencies: pg-int8: 1.0.1 @@ -13167,15 +8215,15 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg@8.18.0: + pg@8.23.0: dependencies: - pg-connection-string: 2.11.0 - pg-pool: 3.11.0(pg@8.18.0) - pg-protocol: 1.11.0 + pg-connection-string: 2.14.0 + pg-pool: 3.14.0(pg@8.23.0) + pg-protocol: 1.16.0 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: - pg-cloudflare: 1.3.0 + pg-cloudflare: 1.4.0 pgpass@1.0.5: dependencies: @@ -13185,41 +8233,11 @@ snapshots: picomatch@2.3.1: {} - picomatch@4.0.2: {} - picomatch@4.0.3: {} - pify@4.0.1: {} - - pino-abstract-transport@3.0.0: - dependencies: - split2: 4.2.0 - - pino-std-serializers@7.1.0: {} - - pino@10.3.1: - dependencies: - '@pinojs/redact': 0.4.0 - atomic-sleep: 1.0.0 - on-exit-leak-free: 2.1.2 - pino-abstract-transport: 3.0.0 - pino-std-serializers: 7.1.0 - process-warning: 5.0.0 - quick-format-unescaped: 4.0.4 - real-require: 0.2.0 - safe-stable-stringify: 2.5.0 - sonic-boom: 4.2.1 - thread-stream: 4.0.0 - - pirates@4.0.7: {} - - piscina@4.9.2: - optionalDependencies: - '@napi-rs/nice': 1.1.1 + picomatch@4.0.7: {} - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 + pify@4.0.1: {} pkg-types@2.3.0: dependencies: @@ -13227,10 +8245,6 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 - pluralize@8.0.0: {} - - possible-typed-array-names@1.1.0: {} - postcss@8.5.6: dependencies: nanoid: 3.3.11 @@ -13251,122 +8265,74 @@ snapshots: postgres@3.4.7: {} - prelude-ls@1.2.1: {} - - prettier-linter-helpers@1.0.1: - dependencies: - fast-diff: 1.3.0 - prettier@2.8.8: {} - prettier@3.8.1: {} - - pretty-format@29.7.0: - dependencies: - '@jest/schemas': 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - pretty-format@30.2.0: - dependencies: - '@jest/schemas': 30.0.5 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - prisma@7.4.1(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3): + prisma@7.10.0(@types/react@19.2.11)(magicast@0.5.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@7.0.2): dependencies: - '@prisma/config': 7.4.1 - '@prisma/dev': 0.20.0(typescript@5.9.3) - '@prisma/engines': 7.4.1 - '@prisma/studio-core': 0.13.1(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@prisma/config': 7.10.0(magicast@0.5.5) + '@prisma/dev': 0.24.17(typescript@7.0.2) + '@prisma/engines': 7.10.0 + '@prisma/studio-core': 0.33.0(@types/react@19.2.11)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) mysql2: 3.15.3 postgres: 3.4.7 optionalDependencies: - typescript: 5.9.3 + typescript: 7.0.2 transitivePeerDependencies: - '@types/react' + - '@types/react-dom' - magicast - react - react-dom process-nextick-args@2.0.1: {} - process-warning@4.0.1: {} - - process-warning@5.0.0: {} - process@0.11.10: {} - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - proper-lockfile@4.1.2: dependencies: graceful-fs: 4.2.11 retry: 0.12.0 signal-exit: 3.0.7 - proxy-addr@2.0.7: + properties-reader@3.0.1: dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - optional: true + '@kwsites/file-exists': 1.1.1 + mkdirp: 3.0.1 + transitivePeerDependencies: + - supports-color + + protobufjs@7.6.6: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.1 + '@protobufjs/fetch': 1.1.1 + '@protobufjs/float': 1.0.2 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.2 + '@types/node': 26.6.3 + long: 5.3.2 proxy-compare@3.0.1: {} - pump@3.0.3: + pump@3.0.4: dependencies: end-of-stream: 1.4.5 once: 1.4.0 - pumpify@2.0.1: - dependencies: - duplexify: 4.1.3 - inherits: 2.0.4 - pump: 3.0.3 - - punycode@2.3.1: {} - pure-rand@6.1.0: {} - qs@6.15.0: - dependencies: - side-channel: 1.1.0 - - qs@6.15.3: - dependencies: - es-define-property: 1.0.1 - side-channel: 1.1.1 - optional: true - quansync@0.2.11: {} - queue-microtask@1.2.3: {} - - quick-format-unescaped@4.0.4: {} - - quick-lru@5.1.1: {} - - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - range-parser@1.3.0: - optional: true + quansync@1.0.0: {} - raw-body@3.0.2: - dependencies: - bytes: 3.1.2 - http-errors: 2.0.1 - iconv-lite: 0.7.3 - unpipe: 1.0.0 - optional: true + queue-microtask@1.2.3: {} - rc9@2.1.2: + rc9@3.1.0: dependencies: - defu: 6.1.4 + defu: 6.1.7 destr: 2.0.5 react-dom@19.2.4(react@19.2.4): @@ -13374,8 +8340,6 @@ snapshots: react: 19.2.4 scheduler: 0.27.0 - react-is@18.3.1: {} - react@19.2.4: {} read-yaml-file@1.1.0: @@ -13401,7 +8365,7 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - readable-stream@4.7.0: + readable-stream@4.8.0: dependencies: abort-controller: 3.0.0 buffer: 6.0.3 @@ -13409,33 +8373,13 @@ snapshots: process: 0.11.10 string_decoder: 1.3.0 - readdirp@4.1.2: {} - - real-require@0.2.0: {} - - reflect-metadata@0.2.2: {} - - reflect.getprototypeof@1.0.10: + readdir-glob@1.1.3: dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 + minimatch: 5.1.9 - regexp-to-ast@0.5.0: {} + readdirp@4.1.2: {} - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 + readdirp@5.1.1: {} remeda@2.33.4: {} @@ -13443,54 +8387,61 @@ snapshots: require-from-string@2.0.2: {} - resolve-alpn@1.2.1: {} - - resolve-cwd@3.0.0: - dependencies: - resolve-from: 5.0.0 - resolve-from@4.0.0: {} resolve-from@5.0.0: {} resolve-pkg-maps@1.0.0: {} - resolve.exports@2.0.3: {} - resolve@1.22.11: dependencies: is-core-module: 2.16.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 - resolve@2.0.0-next.6: - dependencies: - es-errors: 1.3.0 - is-core-module: 2.16.1 - node-exports-info: 1.6.0 - object-keys: 1.1.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - responselike@3.0.0: - dependencies: - lowercase-keys: 3.0.0 - - restore-cursor@3.1.0: - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - ret@0.5.0: {} retry@0.12.0: {} reusify@1.1.0: {} - rfdc@1.4.1: {} - robust-predicates@3.0.3: {} + rolldown-plugin-dts@0.28.7(rolldown@1.2.13)(typescript@7.0.2): + dependencies: + dts-resolver: 3.0.0 + get-tsconfig: 5.0.0-beta.6 + obug: 3.0.0 + rolldown: 1.2.13 + yuku-ast: 0.18.1 + yuku-codegen: 0.18.1 + yuku-parser: 0.18.1 + optionalDependencies: + typescript: 7.0.2 + transitivePeerDependencies: + - oxc-resolver + + rolldown@1.2.13: + dependencies: + '@oxc-project/types': 0.153.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.13 + '@rolldown/binding-android-arm64': 1.2.13 + '@rolldown/binding-darwin-arm64': 1.2.13 + '@rolldown/binding-darwin-x64': 1.2.13 + '@rolldown/binding-freebsd-x64': 1.2.13 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.13 + '@rolldown/binding-linux-arm64-gnu': 1.2.13 + '@rolldown/binding-linux-arm64-musl': 1.2.13 + '@rolldown/binding-linux-ppc64-gnu': 1.2.13 + '@rolldown/binding-linux-s390x-gnu': 1.2.13 + '@rolldown/binding-linux-x64-gnu': 1.2.13 + '@rolldown/binding-linux-x64-musl': 1.2.13 + '@rolldown/binding-openharmony-arm64': 1.2.13 + '@rolldown/binding-win32-arm64-msvc': 1.2.13 + '@rolldown/binding-win32-x64-msvc': 1.2.13 + rollup@4.60.0: dependencies: '@types/estree': 1.0.8 @@ -13522,297 +8473,104 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.60.0 fsevents: 2.3.3 - router@2.2.0: - dependencies: - debug: 4.4.3 - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.3.0 - transitivePeerDependencies: - - supports-color - optional: true - run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - runed@0.37.1(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(zod@4.3.6): + runed@0.37.1(@sveltejs/kit@2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(zod@4.3.6): dependencies: dequal: 2.0.3 esm-env: 1.2.2 lz-string: 1.5.0 svelte: 5.56.4(@typescript-eslint/types@8.56.0) optionalDependencies: - '@sveltejs/kit': 2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)) + '@sveltejs/kit': 2.69.2(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.4(@typescript-eslint/types@8.56.0))(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)))(svelte@5.56.4(@typescript-eslint/types@8.56.0))(typescript@5.9.3)(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) zod: 4.3.6 rw@1.3.3: {} - rxjs@7.8.1: - dependencies: - tslib: 2.8.1 - - rxjs@7.8.2: - dependencies: - tslib: 2.8.1 - sade@1.8.1: dependencies: mri: 1.2.0 - safe-array-concat@1.1.3: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - safe-buffer@5.1.2: {} safe-buffer@5.2.1: {} - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - safe-regex2@5.0.0: dependencies: ret: 0.5.0 - safe-stable-stringify@2.5.0: {} - safer-buffer@2.1.2: {} scheduler@0.27.0: {} - schema-utils@3.3.0: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 6.14.0 - ajv-keywords: 3.5.2(ajv@6.14.0) - - schema-utils@4.3.3: - dependencies: - '@types/json-schema': 7.0.15 - ajv: 8.18.0 - ajv-formats: 2.1.1(ajv@8.18.0) - ajv-keywords: 5.1.0(ajv@8.18.0) - - secure-json-parse@4.1.0: {} - - seek-bzip@2.0.0: - dependencies: - commander: 6.2.1 - - semver-regex@4.0.5: {} - - semver-truncate@3.0.0: - dependencies: - semver: 7.7.4 - - semver@6.3.1: {} - semver@7.7.4: {} - send@1.2.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.1 - mime-types: 3.0.2 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.3.0 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - optional: true - seq-queue@0.0.5: {} - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 - - serve-static@2.2.1: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.1 - transitivePeerDependencies: - - supports-color - optional: true - - set-cookie-parser@2.7.2: {} - set-cookie-parser@3.0.1: {} - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - - setprototypeof@1.2.0: - optional: true - shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-list@1.0.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - optional: true - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - side-channel@1.1.1: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.1 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - optional: true - signal-exit@3.0.7: {} signal-exit@4.1.0: {} sirv@3.0.2: dependencies: - '@polka/url': 1.0.0-next.29 - mrmime: 2.0.1 - totalist: 3.0.1 - - sisteransi@1.0.5: {} - - slash@3.0.0: {} - - sonic-boom@4.2.1: - dependencies: - atomic-sleep: 1.0.0 - - sort-keys-length@1.0.1: - dependencies: - sort-keys: 1.1.2 + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 + totalist: 3.0.1 - sort-keys@1.1.2: - dependencies: - is-plain-obj: 1.1.0 + slash@3.0.0: {} source-map-js@1.2.1: {} - source-map-support@0.5.13: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 + optional: true - source-map@0.6.1: {} - - source-map@0.7.4: {} - - source-map@0.7.6: {} + source-map@0.6.1: + optional: true spawndamnit@3.0.1: dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 + split-ca@1.0.1: {} + split2@4.2.0: {} sprintf-js@1.0.3: {} sqlstring@2.3.3: {} - stable-hash-x@0.2.0: {} - - stack-trace@0.0.10: {} - - stack-utils@2.0.6: + ssh-remote-port-forward@1.0.4: dependencies: - escape-string-regexp: 2.0.0 - - statuses@2.0.2: - optional: true - - std-env@3.10.0: {} + '@types/ssh2': 0.5.52 + ssh2: 1.17.0 - stop-iteration-iterator@1.1.0: + ssh2@1.17.0: dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 + asn1: 0.2.6 + bcrypt-pbkdf: 1.0.2 + optionalDependencies: + cpu-features: 0.0.10 + nan: 2.29.0 - stream-shift@1.0.3: {} + std-env@3.10.0: {} - streamsearch@1.1.0: - optional: true + std-env@4.3.0: {} - streamx@2.23.0: + streamx@2.28.1: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -13821,39 +8579,17 @@ snapshots: - bare-abort-controller - react-native-b4a - string-length@4.0.2: - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.2 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.9 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: + string-width@5.1.2: dependencies: - call-bind: 1.0.9 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 string_decoder@1.1.1: dependencies: @@ -13867,52 +8603,11 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-bom@3.0.0: {} - - strip-bom@4.0.0: {} - - strip-dirs@3.0.0: - dependencies: - inspect-with-kind: 1.0.5 - is-plain-obj: 1.1.0 - - strip-final-newline@2.0.0: {} - - strip-json-comments@3.1.1: {} - - strtok3@10.3.4: - dependencies: - '@tokenizer/token': 0.3.0 - - superagent@10.3.0: - dependencies: - component-emitter: 1.3.1 - cookiejar: 2.1.4 - debug: 4.4.3 - fast-safe-stringify: 2.1.1 - form-data: 4.0.5 - formidable: 3.5.4 - methods: 1.1.2 - mime: 2.6.0 - qs: 6.15.0 - transitivePeerDependencies: - - supports-color - - supertest@7.2.2: - dependencies: - cookie-signature: 1.2.2 - methods: 1.1.2 - superagent: 10.3.0 - transitivePeerDependencies: - - supports-color - - supports-color@7.2.0: + strip-ansi@7.2.0: dependencies: - has-flag: 4.0.0 + ansi-regex: 6.4.0 - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 + strip-bom@3.0.0: {} supports-preserve-symlinks-flag@1.0.0: {} @@ -13950,47 +8645,60 @@ snapshots: transitivePeerDependencies: - '@typescript-eslint/types' - swagger-themes@1.4.3: {} - - swagger-ui-dist@5.31.0: - dependencies: - '@scarf/scarf': 1.4.0 - - symbol-observable@4.0.0: {} - - synckit@0.11.12: - dependencies: - '@pkgr/core': 0.2.9 + tagged-tag@1.0.0: {} tailwind-merge@3.6.0: {} tailwindcss@4.3.1: {} - tapable@2.3.0: {} - tapable@2.3.3: {} - tar-stream@3.1.7: + tar-fs@2.1.5: dependencies: - b4a: 1.8.0 - fast-fifo: 1.3.2 - streamx: 2.23.0 + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.4 + tar-stream: 2.2.0 + + tar-fs@3.1.3: + dependencies: + pump: 3.0.4 + tar-stream: 3.2.2 + optionalDependencies: + bare-fs: 4.8.4 + bare-path: 3.1.2 transitivePeerDependencies: - bare-abort-controller + - bare-buffer - react-native-b4a - term-size@2.2.1: {} + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 - terser-webpack-plugin@5.3.16(@swc/core@1.15.11(@swc/helpers@0.5.18))(webpack@5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18))): + tar-stream@3.2.2: dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - terser: 5.46.0 - webpack: 5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18)) - optionalDependencies: - '@swc/core': 1.15.11(@swc/helpers@0.5.18) + b4a: 1.9.0 + bare-fs: 4.8.4 + fast-fifo: 1.3.2 + streamx: 2.28.1 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + + teex@1.0.1: + dependencies: + streamx: 2.28.1 + transitivePeerDependencies: + - bare-abort-controller + - react-native-b4a + + term-size@2.2.1: {} terser@5.46.0: dependencies: @@ -13998,297 +8706,160 @@ snapshots: acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 + optional: true - test-exclude@6.0.0: + testcontainers@12.2.0: dependencies: - '@istanbuljs/schema': 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 + '@balena/dockerignore': 1.0.2 + '@types/dockerode': 4.0.2 + archiver: 7.0.1 + async-lock: 1.4.1 + byline: 5.0.0 + debug: 4.4.3 + docker-compose: 1.5.0 + dockerode: 5.0.1 + get-port: 5.1.1 + proper-lockfile: 4.1.2 + properties-reader: 3.0.1 + ssh-remote-port-forward: 1.0.4 + tar-fs: 3.1.3 + tmp: 0.2.7 + undici: 8.11.2 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + - supports-color text-decoder@1.2.7: dependencies: - b4a: 1.8.0 + b4a: 1.9.0 transitivePeerDependencies: - react-native-b4a - text-hex@1.0.0: {} - - thread-stream@4.0.0: - dependencies: - real-require: 0.2.0 - - through2@2.0.5: - dependencies: - readable-stream: 2.3.8 - xtend: 4.0.2 - - through@2.3.8: {} + tinybench@6.2.2: {} tinyexec@1.0.2: {} + tinyexec@1.3.1: {} + tinyglobby@0.2.15: dependencies: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 - tinypool@2.1.0: {} + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 - tmpl@1.0.5: {} + tinypool@2.1.0: {} - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 + tinypool@2.1.2: {} - toad-cache@3.7.0: {} + tinyrainbow@3.2.0: {} - toidentifier@1.0.1: - optional: true + tmp@0.2.7: {} - token-types@6.1.2: + to-regex-range@5.0.1: dependencies: - '@borewit/text-codec': 0.2.1 - '@tokenizer/token': 0.3.0 - ieee754: 1.2.1 + is-number: 7.0.0 totalist@3.0.1: {} - triple-beam@1.4.1: {} - - ts-api-utils@2.4.0(typescript@5.9.3): - dependencies: - typescript: 5.9.3 - - ts-essentials@10.1.1(typescript@5.9.3): - optionalDependencies: - typescript: 5.9.3 + tree-kill@1.2.2: {} - ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)))(typescript@5.9.3): - dependencies: - bs-logger: 0.2.6 - fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 - jest: 29.7.0(@types/node@22.19.11)(ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(typescript@5.9.3)) - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.4 - type-fest: 4.41.0 - typescript: 5.9.3 - yargs-parser: 21.1.1 + tsconfck@3.1.6(typescript@7.0.2): optionalDependencies: - '@babel/core': 7.29.0 - '@jest/transform': 30.2.0 - '@jest/types': 30.2.0 - babel-jest: 29.7.0(@babel/core@7.29.0) - jest-util: 30.2.0 - - ts-loader@9.5.4(typescript@5.9.3)(webpack@5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18))): - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.19.0 - micromatch: 4.0.8 - semver: 7.7.4 - source-map: 0.7.6 - typescript: 5.9.3 - webpack: 5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18)) - - ts-node@10.9.2(@swc/core@1.15.11(@swc/helpers@0.5.18))(@types/node@22.19.11)(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': 22.19.11 - 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 + typescript: 7.0.2 + + tsdown@0.23.1(tsx@4.23.15)(typescript@7.0.2): + dependencies: + cac: 7.0.1 + defu: 6.1.7 + empathic: 2.1.0 + hookable: 6.1.2 + import-without-cache: 0.4.1 + obug: 3.0.0 + picomatch: 4.0.7 + rolldown: 1.2.13 + rolldown-plugin-dts: 0.28.7(rolldown@1.2.13)(typescript@7.0.2) + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + tree-kill: 1.2.2 + unconfig-core: 7.5.0 + verkit: 0.5.0 optionalDependencies: - '@swc/core': 1.15.11(@swc/helpers@0.5.18) - - tsconfig-paths-webpack-plugin@4.2.0: - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.19.0 - tapable: 2.3.0 - tsconfig-paths: 4.2.0 - - tsconfig-paths@3.15.0: - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.2 - minimist: 1.2.8 - strip-bom: 3.0.0 - - tsconfig-paths@4.2.0: - dependencies: - json5: 2.2.3 - minimist: 1.2.8 - strip-bom: 3.0.0 + tsx: 4.23.15 + typescript: 7.0.2 + transitivePeerDependencies: + - '@typescript/native-preview' + - '@volar/typescript' + - '@vue/language-core' + - oxc-resolver + - vue-tsc tslib@2.8.1: {} - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-detect@4.0.8: {} - - type-fest@0.21.3: {} - - type-fest@4.41.0: {} - - type-is@1.6.18: - dependencies: - media-typer: 0.3.0 - mime-types: 2.1.35 - optional: true - - type-is@2.1.0: - dependencies: - content-type: 2.0.0 - media-typer: 1.1.0 - mime-types: 3.0.2 - optional: true - - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: + tsx@4.23.15: dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.9 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 + esbuild: 0.28.2 + optionalDependencies: + fsevents: 2.3.3 - typedarray@0.0.6: - optional: true + tweetnacl@0.14.5: {} - typescript-eslint@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3): + type-fest@5.10.0: dependencies: - '@typescript-eslint/eslint-plugin': 8.56.0(@typescript-eslint/parser@8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/parser': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.56.0(typescript@5.9.3) - '@typescript-eslint/utils': 8.56.0(eslint@9.39.3(jiti@2.7.0))(typescript@5.9.3) - eslint: 9.39.3(jiti@2.7.0) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color + tagged-tag: 1.0.0 typescript@5.9.3: {} - uglify-js@3.19.3: - optional: true - - uid@2.0.2: - dependencies: - '@lukeed/csprng': 1.1.0 - - uint8array-extras@1.5.0: {} - - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - - unbzip2-stream@1.4.3: - dependencies: - buffer: 5.7.1 - through: 2.3.8 + typescript@7.0.2: + optionalDependencies: + '@typescript/typescript-aix-ppc64': 7.0.2 + '@typescript/typescript-darwin-arm64': 7.0.2 + '@typescript/typescript-darwin-x64': 7.0.2 + '@typescript/typescript-freebsd-arm64': 7.0.2 + '@typescript/typescript-freebsd-x64': 7.0.2 + '@typescript/typescript-linux-arm': 7.0.2 + '@typescript/typescript-linux-arm64': 7.0.2 + '@typescript/typescript-linux-loong64': 7.0.2 + '@typescript/typescript-linux-mips64el': 7.0.2 + '@typescript/typescript-linux-ppc64': 7.0.2 + '@typescript/typescript-linux-riscv64': 7.0.2 + '@typescript/typescript-linux-s390x': 7.0.2 + '@typescript/typescript-linux-x64': 7.0.2 + '@typescript/typescript-netbsd-arm64': 7.0.2 + '@typescript/typescript-netbsd-x64': 7.0.2 + '@typescript/typescript-openbsd-arm64': 7.0.2 + '@typescript/typescript-openbsd-x64': 7.0.2 + '@typescript/typescript-sunos-x64': 7.0.2 + '@typescript/typescript-win32-arm64': 7.0.2 + '@typescript/typescript-win32-x64': 7.0.2 + + unconfig-core@7.5.0: + dependencies: + '@quansync/fs': 1.1.0 + quansync: 1.0.0 + + undici-types@5.26.5: {} undici-types@6.21.0: {} - universalify@0.1.2: {} - - universalify@2.0.1: {} + undici-types@8.9.0: {} - unpipe@1.0.0: - optional: true - - unrs-resolver@1.11.1: - dependencies: - napi-postinstall: 0.3.4 - optionalDependencies: - '@unrs/resolver-binding-android-arm-eabi': 1.11.1 - '@unrs/resolver-binding-android-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-arm64': 1.11.1 - '@unrs/resolver-binding-darwin-x64': 1.11.1 - '@unrs/resolver-binding-freebsd-x64': 1.11.1 - '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 - '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 - '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 - '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 - '@unrs/resolver-binding-linux-x64-musl': 1.11.1 - '@unrs/resolver-binding-wasm32-wasi': 1.11.1 - '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 - '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 - '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 - - update-browserslist-db@1.2.3(browserslist@4.28.1): - dependencies: - browserslist: 4.28.1 - escalade: 3.2.0 - picocolors: 1.1.1 + undici@8.11.2: {} - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 + universalify@0.1.2: {} util-deprecate@1.0.2: {} - v8-compile-cache-lib@3.0.1: {} - - v8-to-istanbul@9.3.0: - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - '@types/istanbul-lib-coverage': 2.0.6 - convert-source-map: 2.0.0 - - valibot@1.2.0(typescript@5.9.3): + valibot@1.4.2(typescript@7.0.2): optionalDependencies: - typescript: 5.9.3 - - validator@13.15.35: - optional: true + typescript: 7.0.2 - vary@1.1.2: - optional: true + verkit@0.5.0: {} virtua@0.49.2(patch_hash=2c0d482dc06ad381cab34a6d5581eefb4327fc24a8dd80dad7562bd8922f879c)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(svelte@5.56.4(@typescript-eslint/types@8.56.0)): optionalDependencies: @@ -14296,7 +8867,17 @@ snapshots: react-dom: 19.2.4(react@19.2.4) svelte: 5.56.4(@typescript-eslint/types@8.56.0) - vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0): + vite-tsconfig-paths@6.1.1(typescript@7.0.2)(vite@7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)): + dependencies: + debug: 4.4.3 + globrex: 0.1.2 + tsconfck: 3.1.6(typescript@7.0.2) + vite: 7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) + transitivePeerDependencies: + - supports-color + - typescript + + vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0): dependencies: esbuild: 0.27.3 fdir: 6.5.0(picomatch@4.0.3) @@ -14310,135 +8891,57 @@ snapshots: jiti: 2.7.0 lightningcss: 1.32.0 terser: 5.46.0 + tsx: 4.23.15 yaml: 2.9.0 - vitefu@1.1.1(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0)): - optionalDependencies: - vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(yaml@2.9.0) - - walker@1.0.8: - dependencies: - makeerror: 1.0.12 - - watchpack@2.5.1: - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - - wcwidth@1.0.1: + vite@7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0): dependencies: - defaults: 1.0.4 - - webpack-node-externals@3.0.0: {} - - webpack-sources@3.3.4: {} + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.60.0 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 26.6.3 + fsevents: 2.3.3 + jiti: 2.7.0 + lightningcss: 1.32.0 + terser: 5.46.0 + tsx: 4.23.15 + yaml: 2.9.0 - webpack@5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18)): - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.16.0 - acorn-import-phases: 1.0.4(acorn@8.16.0) - browserslist: 4.28.1 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.19.0 - es-module-lexer: 2.0.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.1 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 4.3.3 - tapable: 2.3.0 - terser-webpack-plugin: 5.3.16(@swc/core@1.15.11(@swc/helpers@0.5.18))(webpack@5.104.1(@swc/core@1.15.11(@swc/helpers@0.5.18))) - watchpack: 2.5.1 - webpack-sources: 3.3.4 + vitefu@1.1.1(vite@7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)): + optionalDependencies: + vite: 7.3.5(@types/node@22.19.11)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) + + vitest@5.0.3(@types/node@26.6.3)(@vitest/coverage-v8@5.0.3)(vite@7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)): + dependencies: + '@types/chai': 5.2.3 + '@vitest/mocker': 5.0.3(vite@7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0)) + chai: 6.3.0 + es-module-lexer: 2.3.2 + expect-type: 1.4.0 + magic-string: 1.4.3 + obug: 2.2.1 + picomatch: 4.0.7 + std-env: 4.3.0 + tinybench: 6.2.2 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + vite: 7.3.5(@types/node@26.6.3)(jiti@2.7.0)(lightningcss@1.32.0)(terser@5.46.0)(tsx@4.23.15)(yaml@2.9.0) + why-is-node-running: 3.2.1 + optionalDependencies: + '@types/node': 26.6.3 + '@vitest/coverage-v8': 5.0.3(vitest@5.0.3) transitivePeerDependencies: - - '@swc/core' - - esbuild - - uglify-js - - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.2 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.20 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-typed-array@1.1.20: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.9 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 + - msw which@2.0.2: dependencies: isexe: 2.0.0 - winston-transport@4.9.0: - dependencies: - logform: 2.7.0 - readable-stream: 3.6.2 - triple-beam: 1.4.1 - - winston@3.19.0: - dependencies: - '@colors/colors': 1.6.0 - '@dabh/diagnostics': 2.0.8 - async: 3.2.6 - is-stream: 2.0.1 - logform: 2.7.0 - one-time: 1.0.0 - readable-stream: 3.6.2 - safe-stable-stringify: 2.5.0 - stack-trace: 0.0.10 - triple-beam: 1.4.1 - winston-transport: 4.9.0 - - 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 + why-is-node-running@3.2.1: {} wrap-ansi@7.0.0: dependencies: @@ -14446,26 +8949,19 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrappy@1.0.2: {} - - write-file-atomic@4.0.2: + wrap-ansi@8.1.0: dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 - write-file-atomic@5.0.1: - dependencies: - imurmurhash: 0.1.4 - signal-exit: 4.1.0 + wrappy@1.0.2: {} xtend@4.0.2: {} y18n@5.0.8: {} - yallist@3.1.1: {} - - yaml@2.9.0: - optional: true + yaml@2.9.0: {} yargs-parser@21.1.1: {} @@ -14479,16 +8975,35 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yauzl@3.2.0: + yuku-ast@0.18.1: dependencies: - buffer-crc32: 0.2.13 - pend: 1.2.0 - - yn@3.1.1: {} + '@yuku-toolchain/types': 0.18.1 - yocto-queue@0.1.0: {} + yuku-codegen@0.18.1: + dependencies: + '@yuku-toolchain/types': 0.18.1 - yoctocolors-cjs@2.1.3: {} + yuku-core@0.18.1: + dependencies: + '@yuku-toolchain/types': 0.18.1 + optionalDependencies: + '@yuku-core/binding-android-arm64': 0.18.1 + '@yuku-core/binding-darwin-arm64': 0.18.1 + '@yuku-core/binding-darwin-x64': 0.18.1 + '@yuku-core/binding-freebsd-x64': 0.18.1 + '@yuku-core/binding-linux-arm-gnu': 0.18.1 + '@yuku-core/binding-linux-arm-musl': 0.18.1 + '@yuku-core/binding-linux-arm64-gnu': 0.18.1 + '@yuku-core/binding-linux-arm64-musl': 0.18.1 + '@yuku-core/binding-linux-x64-gnu': 0.18.1 + '@yuku-core/binding-linux-x64-musl': 0.18.1 + '@yuku-core/binding-win32-arm64': 0.18.1 + '@yuku-core/binding-win32-x64': 0.18.1 + + yuku-parser@0.18.1: + dependencies: + '@yuku-toolchain/types': 0.18.1 + yuku-core: 0.18.1 zeptomatch@2.1.0: dependencies: @@ -14497,4 +9012,13 @@ snapshots: zimmerframe@1.1.4: {} - zod@4.3.6: {} + zip-stream@6.0.1: + dependencies: + archiver-utils: 5.0.2 + compress-commons: 6.0.2 + readable-stream: 4.8.0 + + zod@4.3.6: + optional: true + + zod@4.6.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 5aa3abe..6ed682a 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -7,8 +7,11 @@ allowBuilds: '@scarf/scarf': true '@swc/core': true argon2: true + cpu-features: false esbuild: true prisma: true + protobufjs: false + ssh2: false unrs-resolver: false # virtua patch is frontend-only; unused when deploying the backend subset diff --git a/secrets/backend/.env.production.example b/secrets/backend/.env.production.example index 862319d..79f2a83 100644 --- a/secrets/backend/.env.production.example +++ b/secrets/backend/.env.production.example @@ -1,12 +1,6 @@ -DISCORD_BOT_TOKEN_ENV_NAME=DISCORD_BOT_TOKEN -TOTAL_SHARDS_ENV_NAME=TOTAL_SHARDS -SHARD_ID_LIST_ENV_NAME=SHARD_ID_LIST +DATABASE_URL=postgresql://pguser:pgpassword@hallmaster-database:5432/hallmaster -DATABASE_URL=postgresql://pguser:pgpassword@hallmaster-postgres:5432/hallmaster +# openssl rand -base64 32 +SECRET=XXX -# python3 -c "import random,string;print(''.join([random.choice(string.hexdigits[:16]) for _ in range(32)]))" -JWT_SECRET=XXX -JWT_EXPIRES_IN=12h # 15m, 1d, ... - -# This enables logging of all incoming requests -# LOG_REQUESTS=true +PORT=3000