diff --git a/.circleci/config.yml b/.circleci/config.yml index b0dd89b..7f67e8d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -65,7 +65,7 @@ workflows: only: - develop - PM-4931 - - PM-4704 + - skill-statistics tags: only: /^dev-.*/ diff --git a/.nvmrc b/.nvmrc index 9446372..0a2925f 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.13.1 \ No newline at end of file +26.5.1 diff --git a/Dockerfile b/Dockerfile index 905bed2..d5fd044 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,15 @@ -# ---- Base Stage ---- -FROM node:22-alpine AS base +ARG NODE_VERSION=26.5.1 +ARG PNPM_VERSION=11.15.1 + +# ---- Build Base Stage ---- +FROM node:${NODE_VERSION}-alpine AS base WORKDIR /usr/src/app # ---- Package Manager Stage ---- FROM base AS package-manager # Pin pnpm so clean builds do not change behaviour when a new major is released. -RUN npm install --global pnpm@11.15.0 +ARG PNPM_VERSION +RUN npm install --global pnpm@${PNPM_VERSION} # ---- Dependencies Stage ---- FROM package-manager AS deps @@ -22,17 +26,31 @@ COPY . . RUN pnpm build # ---- Production Stage ---- -FROM base AS production +FROM alpine:3.24 AS production +ARG NODE_VERSION ENV NODE_ENV=production +WORKDIR /usr/src/app + +# Use Alpine's dynamically linked Node runtime so patched system OpenSSL packages +# can be upgraded independently. The final image intentionally contains no npm or +# pnpm executable and runs as a dedicated unprivileged account. +RUN apk upgrade --no-cache \ + && apk add --no-cache ca-certificates nodejs-current=${NODE_VERSION}-r0 \ + && addgroup -S -g 10001 app \ + && adduser -S -D -u 10001 -G app -h /home/app app + # Copy built application from the build stage -COPY --from=build /usr/src/app/dist ./dist -COPY --from=build /usr/src/app/sql ./sql -COPY --from=build /usr/src/app/data ./data +COPY --from=build --chown=app:app /usr/src/app/dist ./dist +COPY --from=build --chown=app:app /usr/src/app/sql ./sql +COPY --from=build --chown=app:app /usr/src/app/data ./data # Copy production dependencies from the deps stage -COPY --from=deps /usr/src/app/node_modules ./node_modules +COPY --from=deps --chown=app:app /usr/src/app/node_modules ./node_modules # Expose the application port EXPOSE 3000 +# Do not grant report execution or database access through the container user. +USER app + # The command to run the application CMD ["node", "dist/main.js"] diff --git a/README.md b/README.md index ac64014..c18259f 100644 --- a/README.md +++ b/README.md @@ -69,12 +69,12 @@ Each report will be a separate SQL query, potentially with a few parameters (lik - **Language**: TypeScript - **Database**: PostgreSQL - **ORM**: Prisma -- **Package Manager**: pnpm +- **Package Manager**: pnpm 11.15.1 ## Prerequisites -- Node.js (v22 or later recommended) -- pnpm +- Node.js 26.5.1 (run `nvm use` to select the repository version) +- pnpm 11.15.1 ## Getting Started @@ -110,6 +110,18 @@ ENGAGEMENTS_DB_URL="postgresql://user:password@localhost:5432/engagements" # DATABASE_URL connection, including members.member, members.memberAddress, # members.memberPhone, identity.country, lookups.Country, and projects.projects. +# --------------------------------------------------- +# General statistics exclusions +# --------------------------------------------------- + +# Challenge type names excluded from the general statistics win counts. +# JSON array or comma-separated. Defaults to '["Task","First2Finish"]'. +REPORTS_EXCLUDED_CHALLENGE_TYPES='["Task","First2Finish"]' + +# Member user IDs excluded from the general statistics (country member details +# and top winners by country). JSON array or comma-separated; defaults to empty. +REPORTS_EXCLUDED_USER_IDS='["8547899","251280"]' + # Old tc-payments database URL (used by member-tax CSV export script) OLD_PAYMENTS_DATABASE_URL="postgresql://user:password@localhost:5432/tc_payments?schema=public" @@ -178,3 +190,11 @@ The following read-only endpoints are available without authentication to suppor - `GET /v6/reports/statistics/mm/competitions-count` — Marathon Match number of competitions (static JSON) Static datasets are stored under `data/statistics/srm` and `data/statistics/mm` and are packaged into the ECS image in the Dockerfile. + +## Container Runtime + +The production image uses Alpine 3.24's dynamically linked Node.js 26.5.1 +package and upgrades Alpine packages during the build so system security fixes, +including OpenSSL updates, are applied. The runtime runs as the unprivileged +`app` account (UID 10001) and intentionally excludes npm and pnpm; package +installation and application compilation happen only in builder stages. diff --git a/package.json b/package.json index 02ed013..c0f1e56 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "reports-api-v6", "version": "0.0.1", "private": true, - "packageManager": "pnpm@11.15.0", + "packageManager": "pnpm@11.15.1", "scripts": { "build": "nest build", "deploy:dev": "BRANCH=$(git rev-parse --abbrev-ref HEAD) && TAG=\"dev-${BRANCH}\" && git tag -d \"$TAG\" 2>/dev/null; git push origin \":refs/tags/$TAG\" 2>/dev/null; git tag \"$TAG\" && git push origin \"$TAG\"", @@ -23,8 +23,8 @@ "@nestjs/cli": "^11.0.12", "@nestjs/common": "^11.1.9", "@nestjs/config": "^4.0.2", - "@nestjs/core": "^11.1.9", - "@nestjs/platform-express": "^11.1.9", + "@nestjs/core": "^11.1.18", + "@nestjs/platform-express": "^11.1.18", "@nestjs/swagger": "^11.2.3", "@prisma/client": "^7.0.1", "@types/express": "^5.0.5", @@ -39,7 +39,7 @@ "tc-core-library-js": "github:topcoder-platform/tc-core-library-js#master", "@nestjs/schematics": "^11.0.9", "@types/jest": "^29.5.8", - "@nestjs/testing": "^11.1.9" + "@nestjs/testing": "^11.1.18" }, "devDependencies": { "@eslint/eslintrc": "^3.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f5070c..90e40a5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,34 +4,73 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@hono/node-server': 2.0.10 + '@isaacs/brace-expansion': 5.0.1 + '@nestjs/core': 11.1.18 + ajv@^6.0.0: 6.14.0 + ajv@>=7: 8.18.0 + axios: 1.18.1 + body-parser: 2.3.0 + brace-expansion@^1.0.0: 1.1.18 + brace-expansion@^2.0.0: 2.1.4 + brace-expansion@>=3: 5.0.9 + deepmerge-ts: 8.0.0 + defu: 6.1.5 + effect@^3.0.0: 3.22.0 + fast-uri@^3.0.0: 3.1.5 + file-type@>=13.0.0 <21.3.2: 21.3.2 + flatted: 3.4.2 + follow-redirects: 1.16.0 + form-data: 4.0.6 + handlebars: 4.7.9 + hono: 4.12.34 + ip-address: 10.3.1 + js-yaml@^3: 3.15.1 + js-yaml@^4.0.0: 4.3.1 + js-yaml@^5.0.0: 5.2.2 + jws@^3.0.0: 3.2.3 + lodash: 4.18.1 + minimatch@^3.0.0: 3.1.4 + minimatch@^9.0.0: 9.0.7 + minimatch@>=10: 10.2.3 + multer: 2.2.0 + path-to-regexp: 8.4.0 + picomatch@^2.0.0: 2.3.2 + picomatch@^4.0.0: 4.0.5 + qs: 6.15.2 + serialize-javascript: 7.0.5 + tar: 7.5.21 + valibot: 1.4.2 + importers: .: dependencies: '@nestjs/cli': specifier: ^11.0.12 - version: 11.0.12(@types/node@20.19.11) + version: 11.0.12(@types/node@20.19.11)(uglify-js@3.19.3) '@nestjs/common': specifier: ^11.1.9 - version: 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) + version: 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1) '@nestjs/config': specifier: ^4.0.2 - version: 4.0.2(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(rxjs@7.8.2) + version: 4.0.2(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(rxjs@7.8.2) '@nestjs/core': - specifier: ^11.1.9 - version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(reflect-metadata@0.1.14)(rxjs@7.8.2) + specifier: 11.1.18 + version: 11.1.18(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/platform-express@11.2.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) '@nestjs/platform-express': - specifier: ^11.1.9 - version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.1.9) + specifier: ^11.1.18 + version: 11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/core@11.1.18)(supports-color@8.1.1) '@nestjs/schematics': specifier: ^11.0.9 version: 11.0.9(chokidar@4.0.3)(typescript@5.9.2) '@nestjs/swagger': specifier: ^11.2.3 - version: 11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.1.9)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14) + version: 11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14) '@nestjs/testing': - specifier: ^11.1.9 - version: 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-express@11.1.9) + specifier: ^11.1.18 + version: 11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/core@11.1.18)(@nestjs/platform-express@11.2.3) '@prisma/client': specifier: ^7.0.1 version: 7.0.1(prisma@7.0.1(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.2))(typescript@5.9.2) @@ -67,11 +106,11 @@ importers: version: 7.8.2 tc-core-library-js: specifier: github:topcoder-platform/tc-core-library-js#master - version: https://codeload.github.com/topcoder-platform/tc-core-library-js/tar.gz/1075136355e1e1c4779f2138a30f3ffbd718bfa4 + version: https://codeload.github.com/topcoder-platform/tc-core-library-js/tar.gz/1075136355e1e1c4779f2138a30f3ffbd718bfa4(debug@4.4.3(supports-color@8.1.1))(supports-color@8.1.1) devDependencies: '@eslint/eslintrc': specifier: ^3.2.0 - version: 3.3.1 + version: 3.3.1(supports-color@8.1.1) '@eslint/js': specifier: ^9.18.0 version: 9.33.0 @@ -83,25 +122,25 @@ importers: version: 8.15.5 '@typescript-eslint/eslint-plugin': specifier: ^7.13.0 - version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2))(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) '@typescript-eslint/parser': specifier: ^7.13.0 - version: 7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) + version: 7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) eslint: specifier: ^9.18.0 - version: 9.33.0(jiti@2.6.1) + version: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) eslint-config-prettier: specifier: ^10.0.1 - version: 10.1.8(eslint@9.33.0(jiti@2.6.1)) + version: 10.1.8(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.6.1)))(eslint@9.33.0(jiti@2.6.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1)))(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(prettier@3.6.2) globals: specifier: ^16.3.0 version: 16.3.0 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + version: 29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) prettier: specifier: ^3.2.5 version: 3.6.2 @@ -110,7 +149,7 @@ importers: version: 7.0.1(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.2) ts-jest: specifier: ^29.1.1 - version: 29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)))(typescript@5.9.2) + version: 29.4.5(@babel/core@7.28.5(supports-color@8.1.1))(@jest/transform@29.7.0(supports-color@8.1.1))(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5(supports-color@8.1.1))(supports-color@8.1.1))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)))(typescript@5.9.2) ts-node: specifier: ^10.9.2 version: 10.9.2(@types/node@20.19.11)(typescript@5.9.2) @@ -119,7 +158,7 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.38.0 - version: 8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) + version: 8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) packages: @@ -394,11 +433,11 @@ packages: resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@hono/node-server@1.14.2': - resolution: {integrity: sha512-GHjpOeHYbr9d1vkID2sNUYkl5IxumyhDrUJB7wBp7jvqYwPFt+oNKsAPBRcdSbV7kIrXhouLE199ks1QcK4r7A==} - engines: {node: '>=18.14.1'} + '@hono/node-server@2.0.10': + resolution: {integrity: sha512-ZcnNVhKTmyDJeg0UlnZjvM73JBsTAuhrH/J4fjwGOw59PwOW51r4J+p6CsKZWXdKSme4MFqU62CZMOsdDrU4CA==} + engines: {node: '>=20'} peerDependencies: - hono: ^4 + hono: 4.12.34 '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} @@ -563,14 +602,6 @@ packages: '@types/node': optional: true - '@isaacs/balanced-match@4.0.1': - resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} - engines: {node: 20 || >=22} - - '@isaacs/brace-expansion@5.0.0': - resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} - engines: {node: 20 || >=22} - '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -714,8 +745,8 @@ packages: '@nestjs/common': ^10.0.0 || ^11.0.0 rxjs: ^7.1.0 - '@nestjs/core@11.1.9': - resolution: {integrity: sha512-a00B0BM4X+9z+t3UxJqIZlemIwCQdYoPKrMcM+ky4z3pkqqG1eTWexjs+YXpGObnLnjtMPVKWlcZHp3adDYvUw==} + '@nestjs/core@11.1.18': + resolution: {integrity: sha512-wR3DtGyk/LUAiPtbXDuWJJwVkWElKBY0sqnTzf9d4uM3+X18FRZhK7WFc47czsIGOdWuRsMeLYV+1Z9dO4zDEQ==} engines: {node: '>= 20'} peerDependencies: '@nestjs/common': ^11.0.0 @@ -745,11 +776,11 @@ packages: class-validator: optional: true - '@nestjs/platform-express@11.1.9': - resolution: {integrity: sha512-GVd3+0lO0mJq2m1kl9hDDnVrX3Nd4oH3oDfklz0pZEVEVS0KVSp63ufHq2Lu9cyPdSBuelJr9iPm2QQ1yX+Kmw==} + '@nestjs/platform-express@11.2.3': + resolution: {integrity: sha512-YFQvRXT2de1qNL9LJPUBQ31+RsfI4cJ+sbpU9ENM/hDCgoHSEhm7oxUuGGKmhTZBNZEYm8mDYdfoTFmAH1LIJg==} peerDependencies: '@nestjs/common': ^11.0.0 - '@nestjs/core': ^11.0.0 + '@nestjs/core': 11.1.18 '@nestjs/schematics@11.0.9': resolution: {integrity: sha512-0NfPbPlEaGwIT8/TCThxLzrlz3yzDNkfRNpbL7FiplKq3w4qXpJg0JYwqgMEJnLQZm3L/L/5XjoyfJHUO3qX9g==} @@ -761,7 +792,7 @@ packages: peerDependencies: '@fastify/static': ^8.0.0 '@nestjs/common': ^11.0.1 - '@nestjs/core': ^11.0.1 + '@nestjs/core': 11.1.18 class-transformer: '*' class-validator: '*' reflect-metadata: ^0.1.12 || ^0.2.0 @@ -773,11 +804,11 @@ packages: class-validator: optional: true - '@nestjs/testing@11.1.9': - resolution: {integrity: sha512-UFxerBDdb0RUNxQNj25pvkvNE7/vxKhXYWBt3QuwBFnYISzRIzhVlyIqLfoV5YI3zV0m0Nn4QAn1KM0zzwfEng==} + '@nestjs/testing@11.2.3': + resolution: {integrity: sha512-7ANDWlkm8Xw4CYIhCNZhtBzANsQUKqjteA2yx/6sjqGyWhekeBKz8wgCJykm0vo+ltrg6U34dZlm2NgiRcNHPQ==} peerDependencies: '@nestjs/common': ^11.0.0 - '@nestjs/core': ^11.0.0 + '@nestjs/core': 11.1.18 '@nestjs/microservices': ^11.0.0 '@nestjs/platform-express': ^11.0.0 peerDependenciesMeta: @@ -874,8 +905,8 @@ packages: '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - '@tokenizer/inflate@0.3.1': - resolution: {integrity: sha512-4oeoZEBQdLdt5WmP/hx1KZ6D3/Oid/0cUb2nk4F0pTDAWy+KCH3/EnAkZF/bvckWo8I33EqBm01lIPgmgc8rCA==} + '@tokenizer/inflate@0.4.1': + resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} engines: {node: '>=18'} '@tokenizer/token@0.3.0': @@ -1187,10 +1218,14 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: - ajv: ^8.0.0 + ajv: 8.18.0 peerDependenciesMeta: ajv: optional: true @@ -1198,7 +1233,7 @@ packages: ajv-formats@3.0.1: resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} peerDependencies: - ajv: ^8.0.0 + ajv: 8.18.0 peerDependenciesMeta: ajv: optional: true @@ -1206,18 +1241,18 @@ packages: ajv-keywords@3.5.2: resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} peerDependencies: - ajv: ^6.9.1 + ajv: 6.14.0 ajv-keywords@5.1.0: resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} peerDependencies: - ajv: ^8.8.2 + ajv: 8.18.0 - ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + 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==} ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} @@ -1281,8 +1316,8 @@ packages: resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} engines: {node: '>= 6.0.0'} - axios@0.30.2: - resolution: {integrity: sha512-0pE4RQ4UQi1jKY6p7u6i1Tkzqmu+d+/tHS7Q7rKunWLB9WyilBTpHHpXzPNMDj5hTbK0B0PTLSz07yqMBiF6xg==} + axios@1.18.1: + resolution: {integrity: sha512-3nTvFlvpn9Zu/RkHUqtc7/+al4UpRW5az71ap5zccp6e8RAYEzhMTecX8Dz1wWDYrPpUoB1HAQEGEAEvUr7S9g==} babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} @@ -1316,21 +1351,26 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - body-parser@2.2.1: - resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} + 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@1.1.18: + resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==} - brace-expansion@2.0.2: - resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} @@ -1517,6 +1557,10 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} + engines: {node: '>=18'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -1531,8 +1575,8 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - cors@2.8.5: - resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} cosmiconfig@8.3.6: @@ -1591,8 +1635,8 @@ packages: 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==} + deepmerge-ts@8.0.0: + resolution: {integrity: sha512-ICNjaP0ML+eSdEpJYQC46XiAn/UjAdwbEl0dE8p85ZTeNDinN4Kd4+9jS4OSAuH7st6eC7rQhsqTF5zIDaUm2g==} engines: {node: '>=16.0.0'} deepmerge@4.3.1: @@ -1602,8 +1646,8 @@ packages: defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - defu@6.1.4: - resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + defu@6.1.5: + resolution: {integrity: sha512-pwdBJxJuJXmqrLO6s0VBmfbRz+G7FUzkjldAsdi9Yrv86mPyzq0ll1o8+8gB4Gsr6GJHbK1Lh3ngllgTInDCjA==} delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} @@ -1665,8 +1709,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - effect@3.18.4: - resolution: {integrity: sha512-b1LXQJLe9D11wfnOKAk3PKxuqYshQ0Heez+y5pnkd3jLj1yx9QhM72zZ9uUrOQyNvrs2GZZd/3maL0ZV18YuDA==} + effect@3.22.0: + resolution: {integrity: sha512-jhYFe0zTlIRqYFrKTS+6luhmS/Tm0f+JLo0K9KUxvtFab1SUGEszQi2ehOP6QzAZvy831lDmTwwzvVDZSPNz3g==} electron-to-chromium@1.5.207: resolution: {integrity: sha512-mryFrrL/GXDTmAtIVMVf+eIXM09BBPlO5IQ7lUyKmK8d+A4VpRGG+M3ofoVef6qyF8s60rJei8ymlJxjUA8Faw==} @@ -1769,6 +1813,7 @@ packages: eslint@9.33.0: resolution: {integrity: sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true peerDependencies: jiti: '*' @@ -1825,8 +1870,8 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - express@5.1.0: - resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} exsolve@1.0.8: @@ -1855,8 +1900,8 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + fast-uri@3.1.5: + resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -1864,15 +1909,12 @@ packages: fb-watchman@2.0.2: resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} - 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@21.1.0: - resolution: {integrity: sha512-boU4EHmP3JXkwDo4uhyBhTt5pPstxB6eEXKJBu2yu2l7aAMMm7QQYQEzssJmKReZYrFdFOJS8koVo6bXIBGDqA==} + file-type@21.3.2: + resolution: {integrity: sha512-DLkUvGwep3poOV2wpzbHCOnSKGk1LzyXTv+aHFgN2VFl96wnp8YA9YjO2qPzg5PuL8q/SW9Pdi6WTkYOIh995w==} engines: {node: '>=20'} fill-range@7.1.1: @@ -1895,11 +1937,11 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.3.3: - resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} peerDependencies: debug: '*' @@ -1918,8 +1960,8 @@ packages: typescript: '>3.6.0' webpack: ^5.11.0 - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} forwarded@0.2.0: @@ -2000,11 +2042,11 @@ packages: glob@6.0.4: resolution: {integrity: sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==} - deprecated: Glob versions prior to v9 are no longer supported + 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 glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} @@ -2031,8 +2073,8 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - handlebars@4.7.8: - resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} engines: {node: '>=0.4.7'} hasBin: true @@ -2052,17 +2094,17 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} - hono@4.7.10: - resolution: {integrity: sha512-QkACju9MiN59CKSY5JsGZCYmPZkA6sIW6OFCUp7qDjZu6S6KHtJHhAc9Uy9mV9F8PJ1/HQ3ybZF2yjCa/73fvQ==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hono@4.12.34: + resolution: {integrity: sha512-GqXJqY/xJkJmuloTrnV1ZEXG3fqte+VjkUqoRNZXcrUidiUOP4fMSIHHY4tsqZBK++kVyWmt/AAfSUuy57/eSA==} engines: {node: '>=16.9.0'} html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - http-errors@2.0.1: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} @@ -2070,6 +2112,10 @@ packages: http-status-codes@2.3.0: resolution: {integrity: sha512-RJ8XvFvpPM/Dmc5SV+dC4y5PCeOhT3x1Hq0NU3rjGeg5a/CqlhZ7uudknPwZFz4aeAXDcbAyaeP7GAo9lvngtA==} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -2082,6 +2128,10 @@ packages: resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -2340,16 +2390,12 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + js-yaml@3.15.1: + resolution: {integrity: sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==} hasBin: true - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - - js-yaml@4.1.1: - resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} hasBin: true jsesc@3.1.0: @@ -2397,8 +2443,8 @@ packages: resolution: {integrity: sha512-PwchfHcQK/5PSydeKCs1ylNym0w/SSv8a62DgHJ//7x2ZclCoinlsjAfDxAAbpoTPybOum/Jgy+vkvMmKz89Ww==} engines: {node: '>=14'} - jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + jws@3.2.3: + resolution: {integrity: sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==} keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -2474,8 +2520,8 @@ packages: lodash.once@4.1.1: resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} - lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} log-symbols@4.1.0: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} @@ -2573,15 +2619,15 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - minimatch@10.1.1: - resolution: {integrity: sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==} - engines: {node: 20 || >=22} + minimatch@10.2.3: + resolution: {integrity: sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==} + engines: {node: 18 || 20 || >=22} - minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@3.1.4: + resolution: {integrity: sha512-twmL+S8+7yIsE9wsqgzU3E8/LumN3M3QELrBZ20OdmQ9jB2JvW5oZtBEmft84k/Gs5CG9mqtWc6Y9vW+JEzGxw==} - minimatch@9.0.5: - resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + minimatch@9.0.7: + resolution: {integrity: sha512-MOwgjc8tfrpn5QQEvjijjmDVtMw2oL88ugTevzxQnzRLm6l3fVEF2gzU0kYeYYKD8C66+IdGX6peJ4MyUlUnPg==} engines: {node: '>=16 || 14 >=14.17'} minimist@1.2.8: @@ -2601,8 +2647,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - multer@2.0.2: - resolution: {integrity: sha512-u7f2xaZ/UG8oLXHvtF/oWTRvT44p9ecwBBqTwgJVq0+4BW1g8OW01TyMEGWBHbyMOYVHXslaut7qEQ1meATXgw==} + multer@2.2.0: + resolution: {integrity: sha512-6rdyFg2kLrMh9Jee7/BMPuV9lEAd7lLW2YUpF9/YxR7njyoUwwQ0ZPh3TaIY50Sw6vlyD2HW3wGOkTS4P79xrQ==} engines: {node: '>= 10.16.0'} mute-stream@2.0.0: @@ -2750,8 +2796,8 @@ packages: resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-to-regexp@8.4.0: + resolution: {integrity: sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==} path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} @@ -2800,12 +2846,12 @@ packages: picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} - picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.2: - resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} pirates@4.0.7: @@ -2888,8 +2934,9 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} @@ -2898,8 +2945,8 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} - qs@6.14.0: - resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + qs@6.15.2: + resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -2909,9 +2956,6 @@ packages: resolution: {integrity: sha512-xx0kgFxSHWY9aG1109uv4w2b+JLwHseSowOWo1bzCTDBpUk3er2rZdtQ90mAjUYbkh6Hus9DAwWvmHsX5pHaIQ==} engines: {node: ^8.10.0 || ^10.13.0 || >=11.10.1} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} - range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -3059,8 +3103,9 @@ packages: seq-queue@0.0.5: resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==} - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + serialize-javascript@7.0.5: + resolution: {integrity: sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==} + engines: {node: '>=20.0.0'} serve-static@2.2.0: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} @@ -3136,10 +3181,6 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - statuses@2.0.2: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} @@ -3222,7 +3263,7 @@ packages: engines: {node: '>=6'} tc-core-library-js@https://codeload.github.com/topcoder-platform/tc-core-library-js/tar.gz/1075136355e1e1c4779f2138a30f3ffbd718bfa4: - resolution: {tarball: https://codeload.github.com/topcoder-platform/tc-core-library-js/tar.gz/1075136355e1e1c4779f2138a30f3ffbd718bfa4} + resolution: {gitHosted: true, tarball: https://codeload.github.com/topcoder-platform/tc-core-library-js/tar.gz/1075136355e1e1c4779f2138a30f3ffbd718bfa4} version: 3.0.1 engines: {node: '>= 14'} @@ -3358,6 +3399,10 @@ packages: resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} @@ -3421,8 +3466,8 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} - valibot@1.1.0: - resolution: {integrity: sha512-Nk8lX30Qhu+9txPYTwM0cFlWLdPFsFr6LblzqIySfbZph9+BFsAHsNvHOymEviUepeIW6KFHzpX8TKhbptBXXw==} + valibot@1.4.2: + resolution: {integrity: sha512-gjdCvJ6d3RyHAneqxMYMW9QMCwYMb3jpOO0IyHZV1bnRHFBHrX3VkIILt5XYR0WhwHiH7Mty8ovuPZ/O3gamrg==} peerDependencies: typescript: '>=5' peerDependenciesMeta: @@ -3537,10 +3582,10 @@ 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) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) jsonc-parser: 3.3.1 - picomatch: 4.0.2 + picomatch: 4.0.5 rxjs: 7.8.1 source-map: 0.7.4 optionalDependencies: @@ -3548,10 +3593,10 @@ snapshots: '@angular-devkit/core@19.2.19(chokidar@4.0.3)': dependencies: - ajv: 8.17.1 - ajv-formats: 3.0.1(ajv@8.17.1) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) jsonc-parser: 3.3.1 - picomatch: 4.0.2 + picomatch: 4.0.5 rxjs: 7.8.1 source-map: 0.7.4 optionalDependencies: @@ -3597,20 +3642,20 @@ snapshots: '@babel/compat-data@7.28.5': {} - '@babel/core@7.28.5': + '@babel/core@7.28.5(supports-color@8.1.1)': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.5 '@babel/helper-compilation-targets': 7.27.2 - '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5) + '@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5(supports-color@8.1.1))(supports-color@8.1.1) '@babel/helpers': 7.28.4 '@babel/parser': 7.28.5 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.5(supports-color@8.1.1) '@babel/types': 7.28.5 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.3(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -3635,19 +3680,19 @@ snapshots: '@babel/helper-globals@7.28.0': {} - '@babel/helper-module-imports@7.27.1': + '@babel/helper-module-imports@7.27.1(supports-color@8.1.1)': dependencies: - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.5(supports-color@8.1.1) '@babel/types': 7.28.5 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5)': + '@babel/helper-module-transforms@7.28.3(@babel/core@7.28.5(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: - '@babel/core': 7.28.5 - '@babel/helper-module-imports': 7.27.1 + '@babel/core': 7.28.5(supports-color@8.1.1) + '@babel/helper-module-imports': 7.27.1(supports-color@8.1.1) '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.5 + '@babel/traverse': 7.28.5(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -3668,89 +3713,89 @@ snapshots: dependencies: '@babel/types': 7.28.5 - '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.5)': + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.5)': + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.5)': + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5)': + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.5)': + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.5)': + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.5)': + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.5)': + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.5)': + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 - '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5)': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.5(supports-color@8.1.1))': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.27.1 '@babel/template@7.27.2': @@ -3759,7 +3804,7 @@ snapshots: '@babel/parser': 7.28.5 '@babel/types': 7.28.5 - '@babel/traverse@7.28.5': + '@babel/traverse@7.28.5(supports-color@8.1.1)': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.5 @@ -3767,7 +3812,7 @@ snapshots: '@babel/parser': 7.28.5 '@babel/template': 7.27.2 '@babel/types': 7.28.5 - debug: 4.4.1 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -3784,12 +3829,12 @@ snapshots: dependencies: '@chevrotain/gast': 10.5.0 '@chevrotain/types': 10.5.0 - lodash: 4.17.21 + lodash: 4.18.1 '@chevrotain/gast@10.5.0': dependencies: '@chevrotain/types': 10.5.0 - lodash: 4.17.21 + lodash: 4.18.1 '@chevrotain/types@10.5.0': {} @@ -3812,18 +3857,18 @@ snapshots: '@electric-sql/pglite@0.3.2': {} - '@eslint-community/eslint-utils@4.7.0(eslint@9.33.0(jiti@2.6.1))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))': dependencies: - eslint: 9.33.0(jiti@2.6.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/config-array@0.21.0': + '@eslint/config-array@0.21.0(supports-color@8.1.1)': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1 - minimatch: 3.1.2 + debug: 4.4.1(supports-color@8.1.1) + minimatch: 3.1.4 transitivePeerDependencies: - supports-color @@ -3833,16 +3878,16 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.1': + '@eslint/eslintrc@3.3.1(supports-color@8.1.1)': dependencies: - ajv: 6.12.6 - debug: 4.4.1 + ajv: 6.14.0 + debug: 4.4.1(supports-color@8.1.1) espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 + js-yaml: 4.3.1 + minimatch: 3.1.4 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color @@ -3856,9 +3901,9 @@ snapshots: '@eslint/core': 0.15.2 levn: 0.4.1 - '@hono/node-server@1.14.2(hono@4.7.10)': + '@hono/node-server@2.0.10(hono@4.12.34)': dependencies: - hono: 4.7.10 + hono: 4.12.34 '@humanfs/core@0.19.1': {} @@ -4013,12 +4058,6 @@ snapshots: optionalDependencies: '@types/node': 20.19.11 - '@isaacs/balanced-match@4.0.1': {} - - '@isaacs/brace-expansion@5.0.0': - dependencies: - '@isaacs/balanced-match': 4.0.1 - '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -4033,7 +4072,7 @@ snapshots: camelcase: 5.3.1 find-up: 4.1.0 get-package-type: 0.1.0 - js-yaml: 3.14.1 + js-yaml: 3.15.1 resolve-from: 5.0.0 '@istanbuljs/schema@0.1.3': {} @@ -4047,12 +4086,12 @@ snapshots: jest-util: 29.7.0 slash: 3.0.0 - '@jest/core@29.7.0(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2))': + '@jest/core@29.7.0(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2))': dependencies: '@jest/console': 29.7.0 - '@jest/reporters': 29.7.0 + '@jest/reporters': 29.7.0(supports-color@8.1.1) '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 '@types/node': 20.19.11 ansi-escapes: 4.3.2 @@ -4061,15 +4100,15 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + jest-config: 29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) 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-resolve-dependencies: 29.7.0(supports-color@8.1.1) + jest-runner: 29.7.0(supports-color@8.1.1) + jest-runtime: 29.7.0(supports-color@8.1.1) + jest-snapshot: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 jest-validate: 29.7.0 jest-watcher: 29.7.0 @@ -4093,10 +4132,10 @@ snapshots: dependencies: jest-get-type: 29.6.3 - '@jest/expect@29.7.0': + '@jest/expect@29.7.0(supports-color@8.1.1)': dependencies: expect: 29.7.0 - jest-snapshot: 29.7.0 + jest-snapshot: 29.7.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -4109,21 +4148,21 @@ snapshots: jest-mock: 29.7.0 jest-util: 29.7.0 - '@jest/globals@29.7.0': + '@jest/globals@29.7.0(supports-color@8.1.1)': dependencies: '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 + '@jest/expect': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 jest-mock: 29.7.0 transitivePeerDependencies: - supports-color - '@jest/reporters@29.7.0': + '@jest/reporters@29.7.0(supports-color@8.1.1)': dependencies: '@bcoe/v8-coverage': 0.2.3 '@jest/console': 29.7.0 '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.30 '@types/node': 20.19.11 @@ -4133,9 +4172,9 @@ snapshots: glob: 7.2.3 graceful-fs: 4.2.11 istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 + istanbul-lib-instrument: 6.0.3(supports-color@8.1.1) istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 + istanbul-lib-source-maps: 4.0.1(supports-color@8.1.1) istanbul-reports: 3.2.0 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -4171,12 +4210,12 @@ snapshots: jest-haste-map: 29.7.0 slash: 3.0.0 - '@jest/transform@29.7.0': + '@jest/transform@29.7.0(supports-color@8.1.1)': dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.30 - babel-plugin-istanbul: 6.1.1 + babel-plugin-istanbul: 6.1.1(supports-color@8.1.1) chalk: 4.1.2 convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 @@ -4238,7 +4277,7 @@ snapshots: chevrotain: 10.5.0 lilconfig: 2.1.0 - '@nestjs/cli@11.0.12(@types/node@20.19.11)': + '@nestjs/cli@11.0.12(@types/node@20.19.11)(uglify-js@3.19.3)': dependencies: '@angular-devkit/core': 19.2.19(chokidar@4.0.3) '@angular-devkit/schematics': 19.2.19(chokidar@4.0.3) @@ -4249,14 +4288,14 @@ snapshots: 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.100.2) + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.100.2(uglify-js@3.19.3)) glob: 12.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.100.2 + webpack: 5.100.2(uglify-js@3.19.3) webpack-node-externals: 3.0.0 transitivePeerDependencies: - '@types/node' @@ -4264,9 +4303,9 @@ snapshots: - uglify-js - webpack-cli - '@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)': + '@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1)': dependencies: - file-type: 21.1.0 + file-type: 21.3.2(supports-color@8.1.1) iterare: 1.2.1 load-esm: 1.0.3 reflect-metadata: 0.1.14 @@ -4279,44 +4318,44 @@ snapshots: transitivePeerDependencies: - supports-color - '@nestjs/config@4.0.2(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(rxjs@7.8.2)': + '@nestjs/config@4.0.2(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1) dotenv: 16.4.7 dotenv-expand: 12.0.1 - lodash: 4.17.21 + lodash: 4.18.1 rxjs: 7.8.2 - '@nestjs/core@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(reflect-metadata@0.1.14)(rxjs@7.8.2)': + '@nestjs/core@11.1.18(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/platform-express@11.2.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)': dependencies: - '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1) '@nuxt/opencollective': 0.4.1 fast-safe-stringify: 2.1.1 iterare: 1.2.1 - path-to-regexp: 8.3.0 + path-to-regexp: 8.4.0 reflect-metadata: 0.1.14 rxjs: 7.8.2 tslib: 2.8.1 uid: 2.0.2 optionalDependencies: - '@nestjs/platform-express': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.1.9) + '@nestjs/platform-express': 11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/core@11.1.18)(supports-color@8.1.1) - '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)': + '@nestjs/mapped-types@2.1.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)': dependencies: - '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1) reflect-metadata: 0.1.14 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.14.3 - '@nestjs/platform-express@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.1.9)': + '@nestjs/platform-express@11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/core@11.1.18)(supports-color@8.1.1)': dependencies: - '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) - '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(reflect-metadata@0.1.14)(rxjs@7.8.2) - cors: 2.8.5 - express: 5.1.0 - multer: 2.0.2 - path-to-regexp: 8.3.0 + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/platform-express@11.2.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) + cors: 2.8.6 + express: 5.2.1(supports-color@8.1.1) + multer: 2.2.0 + path-to-regexp: 8.4.0 tslib: 2.8.1 transitivePeerDependencies: - supports-color @@ -4343,28 +4382,28 @@ snapshots: transitivePeerDependencies: - chokidar - '@nestjs/swagger@11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.1.9)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)': + '@nestjs/swagger@11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/core@11.1.18)(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)': dependencies: '@microsoft/tsdoc': 0.16.0 - '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) - '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(reflect-metadata@0.1.14)(rxjs@7.8.2) - '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14) - js-yaml: 4.1.1 - lodash: 4.17.21 - path-to-regexp: 8.3.0 + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/platform-express@11.2.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14) + js-yaml: 4.3.1 + lodash: 4.18.1 + path-to-regexp: 8.4.0 reflect-metadata: 0.1.14 swagger-ui-dist: 5.30.2 optionalDependencies: class-transformer: 0.5.1 class-validator: 0.14.3 - '@nestjs/testing@11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.1.9)(@nestjs/platform-express@11.1.9)': + '@nestjs/testing@11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/core@11.1.18)(@nestjs/platform-express@11.2.3)': dependencies: - '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) - '@nestjs/core': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.1.9)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/common': 11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1) + '@nestjs/core': 11.1.18(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/platform-express@11.2.3)(reflect-metadata@0.1.14)(rxjs@7.8.2) tslib: 2.8.1 optionalDependencies: - '@nestjs/platform-express': 11.1.9(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.1.9) + '@nestjs/platform-express': 11.2.3(@nestjs/common@11.1.9(class-transformer@0.5.1)(class-validator@0.14.3)(reflect-metadata@0.1.14)(rxjs@7.8.2)(supports-color@8.1.1))(@nestjs/core@11.1.18)(supports-color@8.1.1) '@nodelib/fs.scandir@2.1.5': dependencies: @@ -4396,8 +4435,8 @@ snapshots: '@prisma/config@7.0.1': dependencies: c12: 3.1.0 - deepmerge-ts: 7.1.5 - effect: 3.18.4 + deepmerge-ts: 8.0.0 + effect: 3.22.0 empathic: 2.0.0 transitivePeerDependencies: - magicast @@ -4411,19 +4450,19 @@ snapshots: '@electric-sql/pglite': 0.3.2 '@electric-sql/pglite-socket': 0.0.6(@electric-sql/pglite@0.3.2) '@electric-sql/pglite-tools': 0.2.7(@electric-sql/pglite@0.3.2) - '@hono/node-server': 1.14.2(hono@4.7.10) + '@hono/node-server': 2.0.10(hono@4.12.34) '@mrleebo/prisma-ast': 0.12.1 '@prisma/get-platform': 6.8.2 '@prisma/query-plan-executor': 6.18.0 foreground-child: 3.3.1 get-port-please: 3.1.2 - hono: 4.7.10 + hono: 4.12.34 http-status-codes: 2.3.0 pathe: 2.0.3 proper-lockfile: 4.1.2 remeda: 2.21.3 std-env: 3.9.0 - valibot: 1.1.0(typescript@5.9.2) + valibot: 1.4.2(typescript@5.9.2) zeptomatch: 2.0.2 transitivePeerDependencies: - typescript @@ -4473,10 +4512,9 @@ snapshots: '@standard-schema/spec@1.0.0': {} - '@tokenizer/inflate@0.3.1': + '@tokenizer/inflate@0.4.1(supports-color@8.1.1)': dependencies: - debug: 4.4.1 - fflate: 0.8.2 + debug: 4.4.3(supports-color@8.1.1) token-types: 6.1.1 transitivePeerDependencies: - supports-color @@ -4631,15 +4669,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2))(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/parser': 7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) '@typescript-eslint/scope-manager': 7.18.0 - '@typescript-eslint/type-utils': 7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) - '@typescript-eslint/utils': 7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/type-utils': 7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) + '@typescript-eslint/utils': 7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) '@typescript-eslint/visitor-keys': 7.18.0 - eslint: 9.33.0(jiti@2.6.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 @@ -4649,15 +4687,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2))(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) '@typescript-eslint/scope-manager': 8.40.0 - '@typescript-eslint/type-utils': 8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) + '@typescript-eslint/type-utils': 8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.40.0 - eslint: 9.33.0(jiti@2.6.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -4666,36 +4704,36 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/parser@7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 7.18.0(supports-color@8.1.1)(typescript@5.9.2) '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.1 - eslint: 9.33.0(jiti@2.6.1) + debug: 4.4.1(supports-color@8.1.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2)': dependencies: '@typescript-eslint/scope-manager': 8.40.0 '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.40.0(supports-color@8.1.1)(typescript@5.9.2) '@typescript-eslint/visitor-keys': 8.40.0 - debug: 4.4.1 - eslint: 9.33.0(jiti@2.6.1) + debug: 4.4.1(supports-color@8.1.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.40.0(typescript@5.9.2)': + '@typescript-eslint/project-service@8.40.0(supports-color@8.1.1)(typescript@5.9.2)': dependencies: '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.9.2) '@typescript-eslint/types': 8.40.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@8.1.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -4714,25 +4752,25 @@ snapshots: dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/type-utils@7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2)': dependencies: - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.2) - '@typescript-eslint/utils': 7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) - debug: 4.4.1 - eslint: 9.33.0(jiti@2.6.1) + '@typescript-eslint/typescript-estree': 7.18.0(supports-color@8.1.1)(typescript@5.9.2) + '@typescript-eslint/utils': 7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) + debug: 4.4.1(supports-color@8.1.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) ts-api-utils: 1.4.3(typescript@5.9.2) optionalDependencies: typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/type-utils@8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) - debug: 4.4.1 - eslint: 9.33.0(jiti@2.6.1) + '@typescript-eslint/typescript-estree': 8.40.0(supports-color@8.1.1)(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) + debug: 4.4.1(supports-color@8.1.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: @@ -4742,14 +4780,14 @@ snapshots: '@typescript-eslint/types@8.40.0': {} - '@typescript-eslint/typescript-estree@7.18.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@7.18.0(supports-color@8.1.1)(typescript@5.9.2)': dependencies: '@typescript-eslint/types': 7.18.0 '@typescript-eslint/visitor-keys': 7.18.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 - minimatch: 9.0.5 + minimatch: 9.0.7 semver: 7.7.2 ts-api-utils: 1.4.3(typescript@5.9.2) optionalDependencies: @@ -4757,40 +4795,40 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.40.0(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.40.0(supports-color@8.1.1)(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.40.0(typescript@5.9.2) + '@typescript-eslint/project-service': 8.40.0(supports-color@8.1.1)(typescript@5.9.2) '@typescript-eslint/tsconfig-utils': 8.40.0(typescript@5.9.2) '@typescript-eslint/types': 8.40.0 '@typescript-eslint/visitor-keys': 8.40.0 - debug: 4.4.1 + debug: 4.4.1(supports-color@8.1.1) fast-glob: 3.3.3 is-glob: 4.0.3 - minimatch: 9.0.5 + minimatch: 9.0.7 semver: 7.7.2 ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.18.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/utils@7.18.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1)) '@typescript-eslint/scope-manager': 7.18.0 '@typescript-eslint/types': 7.18.0 - '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.9.2) - eslint: 9.33.0(jiti@2.6.1) + '@typescript-eslint/typescript-estree': 7.18.0(supports-color@8.1.1)(typescript@5.9.2) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) transitivePeerDependencies: - supports-color - typescript - '@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2)': + '@typescript-eslint/utils@8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1)) '@typescript-eslint/scope-manager': 8.40.0 '@typescript-eslint/types': 8.40.0 - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - eslint: 9.33.0(jiti@2.6.1) + '@typescript-eslint/typescript-estree': 8.40.0(supports-color@8.1.1)(typescript@5.9.2) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -4904,34 +4942,40 @@ snapshots: acorn@8.15.0: {} - ajv-formats@2.1.1(ajv@8.17.1): + agent-base@6.0.2(supports-color@8.1.1): + dependencies: + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + ajv-formats@2.1.1(ajv@8.18.0): optionalDependencies: - ajv: 8.17.1 + ajv: 8.18.0 - ajv-formats@3.0.1(ajv@8.17.1): + ajv-formats@3.0.1(ajv@8.18.0): optionalDependencies: - ajv: 8.17.1 + ajv: 8.18.0 - ajv-keywords@3.5.2(ajv@6.12.6): + ajv-keywords@3.5.2(ajv@6.14.0): dependencies: - ajv: 6.12.6 + ajv: 6.14.0 - ajv-keywords@5.1.0(ajv@8.17.1): + ajv-keywords@5.1.0(ajv@8.18.0): dependencies: - ajv: 8.17.1 + ajv: 8.18.0 fast-deep-equal: 3.1.3 - ajv@6.12.6: + 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: + ajv@8.18.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 + fast-uri: 3.1.5 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -4958,7 +5002,7 @@ snapshots: anymatch@3.1.3: dependencies: normalize-path: 3.0.0 - picomatch: 2.3.1 + picomatch: 2.3.2 append-field@1.0.0: {} @@ -4978,33 +5022,35 @@ snapshots: aws-ssl-profiles@1.1.2: {} - axios@0.30.2: + axios@1.18.1(debug@4.4.3(supports-color@8.1.1))(supports-color@8.1.1): dependencies: - follow-redirects: 1.15.11 - form-data: 4.0.5 - proxy-from-env: 1.1.0 + follow-redirects: 1.16.0(debug@4.4.3(supports-color@8.1.1)) + form-data: 4.0.6 + https-proxy-agent: 5.0.1(supports-color@8.1.1) + proxy-from-env: 2.1.0 transitivePeerDependencies: - debug + - supports-color - babel-jest@29.7.0(@babel/core@7.28.5): + babel-jest@29.7.0(@babel/core@7.28.5(supports-color@8.1.1))(supports-color@8.1.1): dependencies: - '@babel/core': 7.28.5 - '@jest/transform': 29.7.0 + '@babel/core': 7.28.5(supports-color@8.1.1) + '@jest/transform': 29.7.0(supports-color@8.1.1) '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.28.5) + babel-plugin-istanbul: 6.1.1(supports-color@8.1.1) + babel-preset-jest: 29.6.3(@babel/core@7.28.5(supports-color@8.1.1)) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color - babel-plugin-istanbul@6.1.1: + babel-plugin-istanbul@6.1.1(supports-color@8.1.1): dependencies: '@babel/helper-plugin-utils': 7.27.1 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 - istanbul-lib-instrument: 5.2.1 + istanbul-lib-instrument: 5.2.1(supports-color@8.1.1) test-exclude: 6.0.0 transitivePeerDependencies: - supports-color @@ -5016,30 +5062,30 @@ snapshots: '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.28.0 - babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.5): - dependencies: - '@babel/core': 7.28.5 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.5) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.5) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.5) - '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.5) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.5) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.5) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5) - - babel-preset-jest@29.6.3(@babel/core@7.28.5): - dependencies: - '@babel/core': 7.28.5 + babel-preset-current-node-syntax@1.2.0(@babel/core@7.28.5(supports-color@8.1.1)): + dependencies: + '@babel/core': 7.28.5(supports-color@8.1.1) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.28.5(supports-color@8.1.1)) + + babel-preset-jest@29.6.3(@babel/core@7.28.5(supports-color@8.1.1)): + dependencies: + '@babel/core': 7.28.5(supports-color@8.1.1) babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5(supports-color@8.1.1)) backoff@2.5.0: dependencies: @@ -5047,6 +5093,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-js@1.5.1: {} bl@4.1.0: @@ -5055,28 +5103,28 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - body-parser@2.2.1: + body-parser@2.3.0(supports-color@8.1.1): dependencies: bytes: 3.1.2 - content-type: 1.0.5 - debug: 4.4.3 - http-errors: 2.0.0 - iconv-lite: 0.7.0 + content-type: 2.1.0 + debug: 4.4.3(supports-color@8.1.1) + http-errors: 2.0.1 + iconv-lite: 0.7.3 on-finished: 2.4.1 - qs: 6.14.0 + qs: 6.15.2 raw-body: 3.0.2 - type-is: 2.0.1 + type-is: 2.1.0 transitivePeerDependencies: - supports-color - brace-expansion@1.1.12: + brace-expansion@1.1.18: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.2: + brace-expansion@5.0.9: dependencies: - balanced-match: 1.0.2 + balanced-match: 4.0.4 braces@3.0.3: dependencies: @@ -5123,7 +5171,7 @@ snapshots: dependencies: chokidar: 4.0.3 confbox: 0.2.2 - defu: 6.1.4 + defu: 6.1.5 dotenv: 16.6.1 exsolve: 1.0.8 giget: 2.0.0 @@ -5167,7 +5215,7 @@ snapshots: '@chevrotain/gast': 10.5.0 '@chevrotain/types': 10.5.0 '@chevrotain/utils': 10.5.0 - lodash: 4.17.21 + lodash: 4.18.1 regexp-to-ast: 0.5.0 chokidar@4.0.3: @@ -5259,6 +5307,8 @@ snapshots: content-type@1.0.5: {} + content-type@2.1.0: {} + convert-source-map@2.0.0: {} cookie-signature@1.2.2: {} @@ -5267,7 +5317,7 @@ snapshots: core-util-is@1.0.3: {} - cors@2.8.5: + cors@2.8.6: dependencies: object-assign: 4.1.1 vary: 1.1.2 @@ -5275,19 +5325,19 @@ snapshots: cosmiconfig@8.3.6(typescript@5.9.3): dependencies: import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.3.1 parse-json: 5.2.0 path-type: 4.0.0 optionalDependencies: typescript: 5.9.3 - create-jest@29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)): + create-jest@29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)): 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@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + jest-config: 29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -5308,19 +5358,23 @@ snapshots: date-fns@4.1.0: {} - debug@4.4.1: + debug@4.4.1(supports-color@8.1.1): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 - debug@4.4.3: + debug@4.4.3(supports-color@8.1.1): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 dedent@1.7.0: {} deep-is@0.1.4: {} - deepmerge-ts@7.1.5: {} + deepmerge-ts@8.0.0: {} deepmerge@4.3.1: {} @@ -5328,7 +5382,7 @@ snapshots: dependencies: clone: 1.0.4 - defu@6.1.4: {} + defu@6.1.5: {} delayed-stream@1.0.0: {} @@ -5375,7 +5429,7 @@ snapshots: ee-first@1.1.1: {} - effect@3.18.4: + effect@3.22.0: dependencies: '@standard-schema/spec': 1.0.0 fast-check: 3.23.2 @@ -5426,19 +5480,19 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.6.1)): + eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1)): dependencies: - eslint: 9.33.0(jiti@2.6.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) - eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.6.1)))(eslint@9.33.0(jiti@2.6.1))(prettier@3.6.2): + eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1)))(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(prettier@3.6.2): dependencies: - eslint: 9.33.0(jiti@2.6.1) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) prettier: 3.6.2 prettier-linter-helpers: 1.0.0 synckit: 0.11.11 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@9.33.0(jiti@2.6.1)) + eslint-config-prettier: 10.1.8(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1)) eslint-scope@5.1.1: dependencies: @@ -5454,14 +5508,14 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.33.0(jiti@2.6.1): + eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.6.1)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1)) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 + '@eslint/config-array': 0.21.0(supports-color@8.1.1) '@eslint/config-helpers': 0.3.1 '@eslint/core': 0.15.2 - '@eslint/eslintrc': 3.3.1 + '@eslint/eslintrc': 3.3.1(supports-color@8.1.1) '@eslint/js': 9.33.0 '@eslint/plugin-kit': 0.3.5 '@humanfs/node': 0.16.6 @@ -5469,10 +5523,10 @@ snapshots: '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 - ajv: 6.12.6 + ajv: 6.14.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.1(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -5488,7 +5542,7 @@ snapshots: is-glob: 4.0.3 json-stable-stringify-without-jsonify: 1.0.1 lodash.merge: 4.6.2 - minimatch: 3.1.2 + minimatch: 3.1.4 natural-compare: 1.4.0 optionator: 0.9.4 optionalDependencies: @@ -5544,33 +5598,34 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - express@5.1.0: + express@5.2.1(supports-color@8.1.1): dependencies: accepts: 2.0.0 - body-parser: 2.2.1 + body-parser: 2.3.0(supports-color@8.1.1) content-disposition: 1.0.1 content-type: 1.0.5 cookie: 0.7.1 cookie-signature: 1.2.2 - debug: 4.4.1 + debug: 4.4.3(supports-color@8.1.1) + depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.0 + finalhandler: 2.1.0(supports-color@8.1.1) fresh: 2.0.0 - http-errors: 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.14.0 + qs: 6.15.2 range-parser: 1.2.1 - router: 2.2.0 - send: 1.2.0 - serve-static: 2.2.0 - statuses: 2.0.1 + router: 2.2.0(supports-color@8.1.1) + send: 1.2.0(supports-color@8.1.1) + serve-static: 2.2.0(supports-color@8.1.1) + statuses: 2.0.2 type-is: 2.0.1 vary: 1.1.2 transitivePeerDependencies: @@ -5600,7 +5655,7 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.0.6: {} + fast-uri@3.1.5: {} fastq@1.19.1: dependencies: @@ -5610,15 +5665,13 @@ snapshots: dependencies: bser: 2.1.1 - fflate@0.8.2: {} - file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 - file-type@21.1.0: + file-type@21.3.2(supports-color@8.1.1): dependencies: - '@tokenizer/inflate': 0.3.1 + '@tokenizer/inflate': 0.4.1(supports-color@8.1.1) strtok3: 10.3.4 token-types: 6.1.1 uint8array-extras: 1.4.1 @@ -5629,14 +5682,14 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@2.1.0: + finalhandler@2.1.0(supports-color@8.1.1): dependencies: - debug: 4.4.1 + debug: 4.4.3(supports-color@8.1.1) encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 parseurl: 1.3.3 - statuses: 2.0.1 + statuses: 2.0.2 transitivePeerDependencies: - supports-color @@ -5652,19 +5705,21 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.3.3 + flatted: 3.4.2 keyv: 4.5.4 - flatted@3.3.3: {} + flatted@3.4.2: {} - follow-redirects@1.15.11: {} + follow-redirects@1.16.0(debug@4.4.3(supports-color@8.1.1)): + optionalDependencies: + debug: 4.4.3(supports-color@8.1.1) foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.100.2): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.100.2(uglify-js@3.19.3)): dependencies: '@babel/code-frame': 7.27.1 chalk: 4.1.2 @@ -5673,20 +5728,20 @@ snapshots: deepmerge: 4.3.1 fs-extra: 10.1.0 memfs: 3.5.3 - minimatch: 3.1.2 + minimatch: 3.1.4 node-abort-controller: 3.1.1 schema-utils: 3.3.0 semver: 7.7.3 tapable: 2.2.2 typescript: 5.9.3 - webpack: 5.100.2 + webpack: 5.100.2(uglify-js@3.19.3) - form-data@4.0.5: + form-data@4.0.6: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.2 + hasown: 2.0.4 mime-types: 2.1.35 forwarded@0.2.0: {} @@ -5744,7 +5799,7 @@ snapshots: dependencies: citty: 0.1.6 consola: 3.4.2 - defu: 6.1.4 + defu: 6.1.5 node-fetch-native: 1.6.7 nypm: 0.6.2 pathe: 2.0.3 @@ -5763,7 +5818,7 @@ snapshots: dependencies: foreground-child: 3.3.1 jackspeak: 4.1.1 - minimatch: 10.1.1 + minimatch: 10.2.3 minipass: 7.1.2 package-json-from-dist: 1.0.1 path-scurry: 2.0.1 @@ -5772,7 +5827,7 @@ snapshots: dependencies: inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.4 once: 1.4.0 path-is-absolute: 1.0.1 optional: true @@ -5782,7 +5837,7 @@ snapshots: fs.realpath: 1.0.0 inflight: 1.0.6 inherits: 2.0.4 - minimatch: 3.1.2 + minimatch: 3.1.4 once: 1.4.0 path-is-absolute: 1.0.1 @@ -5807,7 +5862,7 @@ snapshots: graphemer@1.4.0: {} - handlebars@4.7.8: + handlebars@4.7.9: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -5828,17 +5883,13 @@ snapshots: dependencies: function-bind: 1.1.2 - hono@4.7.10: {} + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 - html-escaper@2.0.2: {} + hono@4.12.34: {} - http-errors@2.0.0: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.1 - toidentifier: 1.0.1 + html-escaper@2.0.2: {} http-errors@2.0.1: dependencies: @@ -5850,6 +5901,13 @@ snapshots: http-status-codes@2.3.0: {} + https-proxy-agent@5.0.1(supports-color@8.1.1): + dependencies: + agent-base: 6.0.2(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + human-signals@2.1.0: {} i18n-iso-countries@3.7.8: {} @@ -5858,6 +5916,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -5917,9 +5979,9 @@ snapshots: istanbul-lib-coverage@3.2.2: {} - istanbul-lib-instrument@5.2.1: + istanbul-lib-instrument@5.2.1(supports-color@8.1.1): dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/parser': 7.28.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -5927,9 +5989,9 @@ snapshots: transitivePeerDependencies: - supports-color - istanbul-lib-instrument@6.0.3: + istanbul-lib-instrument@6.0.3(supports-color@8.1.1): dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/parser': 7.28.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 @@ -5943,9 +6005,9 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1: + istanbul-lib-source-maps@4.0.1(supports-color@8.1.1): dependencies: - debug: 4.4.1 + debug: 4.4.3(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -5968,10 +6030,10 @@ snapshots: jest-util: 29.7.0 p-limit: 3.1.0 - jest-circus@29.7.0: + jest-circus@29.7.0(supports-color@8.1.1): dependencies: '@jest/environment': 29.7.0 - '@jest/expect': 29.7.0 + '@jest/expect': 29.7.0(supports-color@8.1.1) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 '@types/node': 20.19.11 @@ -5982,8 +6044,8 @@ snapshots: 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-runtime: 29.7.0(supports-color@8.1.1) + jest-snapshot: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 p-limit: 3.1.0 pretty-format: 29.7.0 @@ -5994,16 +6056,16 @@ snapshots: - babel-plugin-macros - supports-color - jest-cli@29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)): + jest-cli@29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + '@jest/core': 29.7.0(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + create-jest: 29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + jest-config: 29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -6013,23 +6075,23 @@ snapshots: - supports-color - ts-node - jest-config@29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)): + jest-config@29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)): dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.5) + babel-jest: 29.7.0(@babel/core@7.28.5(supports-color@8.1.1))(supports-color@8.1.1) 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-circus: 29.7.0(supports-color@8.1.1) 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-runner: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 jest-validate: 29.7.0 micromatch: 4.0.8 @@ -6126,10 +6188,10 @@ snapshots: jest-regex-util@29.6.3: {} - jest-resolve-dependencies@29.7.0: + jest-resolve-dependencies@29.7.0(supports-color@8.1.1): dependencies: jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 + jest-snapshot: 29.7.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -6145,12 +6207,12 @@ snapshots: resolve.exports: 2.0.3 slash: 3.0.0 - jest-runner@29.7.0: + jest-runner@29.7.0(supports-color@8.1.1): dependencies: '@jest/console': 29.7.0 '@jest/environment': 29.7.0 '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 '@types/node': 20.19.11 chalk: 4.1.2 @@ -6162,7 +6224,7 @@ snapshots: jest-leak-detector: 29.7.0 jest-message-util: 29.7.0 jest-resolve: 29.7.0 - jest-runtime: 29.7.0 + jest-runtime: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 jest-watcher: 29.7.0 jest-worker: 29.7.0 @@ -6171,14 +6233,14 @@ snapshots: transitivePeerDependencies: - supports-color - jest-runtime@29.7.0: + jest-runtime@29.7.0(supports-color@8.1.1): dependencies: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 - '@jest/globals': 29.7.0 + '@jest/globals': 29.7.0(supports-color@8.1.1) '@jest/source-map': 29.6.3 '@jest/test-result': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 '@types/node': 20.19.11 chalk: 4.1.2 @@ -6191,24 +6253,24 @@ snapshots: jest-mock: 29.7.0 jest-regex-util: 29.6.3 jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 + jest-snapshot: 29.7.0(supports-color@8.1.1) jest-util: 29.7.0 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: - supports-color - jest-snapshot@29.7.0: + jest-snapshot@29.7.0(supports-color@8.1.1): dependencies: - '@babel/core': 7.28.5 + '@babel/core': 7.28.5(supports-color@8.1.1) '@babel/generator': 7.28.5 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5) - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5) + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.5(supports-color@8.1.1)) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.5(supports-color@8.1.1)) '@babel/types': 7.28.5 '@jest/expect-utils': 29.7.0 - '@jest/transform': 29.7.0 + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5) + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.28.5(supports-color@8.1.1)) chalk: 4.1.2 expect: 29.7.0 graceful-fs: 4.2.11 @@ -6230,7 +6292,7 @@ snapshots: chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 - picomatch: 2.3.1 + picomatch: 2.3.2 jest-validate@29.7.0: dependencies: @@ -6265,12 +6327,12 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 - jest@29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)): + jest@29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + '@jest/core': 29.7.0(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + jest-cli: 29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -6283,16 +6345,12 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@3.14.1: + js-yaml@3.15.1: dependencies: argparse: 1.0.10 esprima: 4.0.1 - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - js-yaml@4.1.1: + js-yaml@4.3.1: dependencies: argparse: 2.0.1 @@ -6322,7 +6380,7 @@ snapshots: jsonwebtoken@9.0.2: dependencies: - jws: 3.2.2 + jws: 3.2.3 lodash.includes: 4.3.0 lodash.isboolean: 3.0.3 lodash.isinteger: 4.0.4 @@ -6339,18 +6397,18 @@ snapshots: ecdsa-sig-formatter: 1.0.11 safe-buffer: 5.2.1 - jwks-rsa@3.2.0: + jwks-rsa@3.2.0(supports-color@8.1.1): dependencies: '@types/express': 4.17.23 '@types/jsonwebtoken': 9.0.10 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) jose: 4.15.9 limiter: 1.1.5 lru-memoizer: 2.3.0 transitivePeerDependencies: - supports-color - jws@3.2.2: + jws@3.2.3: dependencies: jwa: 1.4.2 safe-buffer: 5.2.1 @@ -6408,7 +6466,7 @@ snapshots: lodash.once@4.1.1: {} - lodash@4.17.21: {} + lodash@4.18.1: {} log-symbols@4.1.0: dependencies: @@ -6469,7 +6527,7 @@ snapshots: micromatch@4.0.8: dependencies: braces: 3.0.3 - picomatch: 2.3.1 + picomatch: 2.3.2 millisecond@0.1.2: {} @@ -6487,17 +6545,17 @@ snapshots: mimic-fn@2.1.0: {} - minimatch@10.1.1: + minimatch@10.2.3: dependencies: - '@isaacs/brace-expansion': 5.0.0 + brace-expansion: 5.0.9 - minimatch@3.1.2: + minimatch@3.1.4: dependencies: - brace-expansion: 1.1.12 + brace-expansion: 1.1.18 - minimatch@9.0.5: + minimatch@9.0.7: dependencies: - brace-expansion: 2.0.2 + brace-expansion: 5.0.9 minimist@1.2.8: {} @@ -6506,21 +6564,19 @@ snapshots: mkdirp@0.5.6: dependencies: minimist: 1.2.8 + optional: true moment@2.30.1: optional: true ms@2.1.3: {} - multer@2.0.2: + multer@2.2.0: 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 mute-stream@2.0.0: {} @@ -6563,7 +6619,7 @@ snapshots: node-emoji@1.11.0: dependencies: - lodash: 4.17.21 + lodash: 4.18.1 node-fetch-native@1.6.7: {} @@ -6670,7 +6726,7 @@ snapshots: lru-cache: 11.2.2 minipass: 7.1.2 - path-to-regexp@8.3.0: {} + path-to-regexp@8.4.0: {} path-type@4.0.0: {} @@ -6715,9 +6771,9 @@ snapshots: picocolors@1.1.1: {} - picomatch@2.3.1: {} + picomatch@2.3.2: {} - picomatch@4.0.2: {} + picomatch@4.0.5: {} pirates@4.0.7: {} @@ -6793,13 +6849,13 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 - proxy-from-env@1.1.0: {} + proxy-from-env@2.1.0: {} punycode@2.3.1: {} pure-rand@6.1.0: {} - qs@6.14.0: + qs@6.15.2: dependencies: side-channel: 1.1.0 @@ -6809,13 +6865,9 @@ snapshots: dependencies: codependency: 2.1.0 json-stringify-safe: 5.0.1 - lodash: 4.17.21 + lodash: 4.18.1 reconnect-core: 1.3.0 - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - range-parser@1.2.1: {} raw-body@3.0.2: @@ -6827,7 +6879,7 @@ snapshots: rc9@2.1.2: dependencies: - defu: 6.1.4 + defu: 6.1.5 destr: 2.0.5 react-dom@19.2.0(react@19.2.0): @@ -6893,13 +6945,13 @@ snapshots: glob: 6.0.4 optional: true - router@2.2.0: + router@2.2.0(supports-color@8.1.1): dependencies: - debug: 4.4.1 + debug: 4.4.3(supports-color@8.1.1) depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.3.0 + path-to-regexp: 8.4.0 transitivePeerDependencies: - supports-color @@ -6927,15 +6979,15 @@ snapshots: schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 - ajv: 6.12.6 - ajv-keywords: 3.5.2(ajv@6.12.6) + ajv: 6.14.0 + ajv-keywords: 3.5.2(ajv@6.14.0) schema-utils@4.3.2: dependencies: '@types/json-schema': 7.0.15 - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - ajv-keywords: 5.1.0(ajv@8.17.1) + ajv: 8.18.0 + ajv-formats: 2.1.1(ajv@8.18.0) + ajv-keywords: 5.1.0(ajv@8.18.0) semver@5.7.2: {} @@ -6945,34 +6997,32 @@ snapshots: semver@7.7.3: {} - send@1.2.0: + send@1.2.0(supports-color@8.1.1): dependencies: - debug: 4.4.1 + debug: 4.4.3(supports-color@8.1.1) encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 fresh: 2.0.0 - http-errors: 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.2.1 - statuses: 2.0.1 + statuses: 2.0.2 transitivePeerDependencies: - supports-color seq-queue@0.0.5: {} - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 + serialize-javascript@7.0.5: {} - serve-static@2.2.0: + serve-static@2.2.0(supports-color@8.1.1): dependencies: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 1.2.0 + send: 1.2.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -7044,8 +7094,6 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 - statuses@2.0.1: {} - statuses@2.0.2: {} std-env@3.9.0: {} @@ -7115,27 +7163,29 @@ snapshots: tapable@2.2.2: {} - tc-core-library-js@https://codeload.github.com/topcoder-platform/tc-core-library-js/tar.gz/1075136355e1e1c4779f2138a30f3ffbd718bfa4: + tc-core-library-js@https://codeload.github.com/topcoder-platform/tc-core-library-js/tar.gz/1075136355e1e1c4779f2138a30f3ffbd718bfa4(debug@4.4.3(supports-color@8.1.1))(supports-color@8.1.1): dependencies: - axios: 0.30.2 + axios: 1.18.1(debug@4.4.3(supports-color@8.1.1))(supports-color@8.1.1) bunyan: 1.8.15 jsonwebtoken: 9.0.2 - jwks-rsa: 3.2.0 - lodash: 4.17.21 + jwks-rsa: 3.2.0(supports-color@8.1.1) + lodash: 4.18.1 millisecond: 0.1.2 r7insight_node: 2.1.1 transitivePeerDependencies: - debug - supports-color - terser-webpack-plugin@5.3.14(webpack@5.100.2): + terser-webpack-plugin@5.3.14(uglify-js@3.19.3)(webpack@5.100.2(uglify-js@3.19.3)): dependencies: '@jridgewell/trace-mapping': 0.3.30 jest-worker: 27.5.1 schema-utils: 4.3.2 - serialize-javascript: 6.0.2 + serialize-javascript: 7.0.5 terser: 5.43.1 - webpack: 5.100.2 + webpack: 5.100.2(uglify-js@3.19.3) + optionalDependencies: + uglify-js: 3.19.3 terser@5.43.1: dependencies: @@ -7148,7 +7198,7 @@ snapshots: dependencies: '@istanbuljs/schema': 0.1.3 glob: 7.2.3 - minimatch: 3.1.2 + minimatch: 3.1.4 tinyexec@1.0.2: {} @@ -7174,12 +7224,12 @@ snapshots: dependencies: typescript: 5.9.2 - ts-jest@29.4.5(@babel/core@7.28.5)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)))(typescript@5.9.2): + ts-jest@29.4.5(@babel/core@7.28.5(supports-color@8.1.1))(@jest/transform@29.7.0(supports-color@8.1.1))(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.5(supports-color@8.1.1))(supports-color@8.1.1))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)))(typescript@5.9.2): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - handlebars: 4.7.8 - jest: 29.7.0(@types/node@20.19.11)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) + handlebars: 4.7.9 + jest: 29.7.0(@types/node@20.19.11)(supports-color@8.1.1)(ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2)) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -7188,10 +7238,10 @@ snapshots: typescript: 5.9.2 yargs-parser: 21.1.1 optionalDependencies: - '@babel/core': 7.28.5 - '@jest/transform': 29.7.0 + '@babel/core': 7.28.5(supports-color@8.1.1) + '@jest/transform': 29.7.0(supports-color@8.1.1) '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.5) + babel-jest: 29.7.0(@babel/core@7.28.5(supports-color@8.1.1))(supports-color@8.1.1) jest-util: 29.7.0 ts-node@10.9.2(@types/node@20.19.11)(typescript@5.9.2): @@ -7248,15 +7298,21 @@ snapshots: media-typer: 1.1.0 mime-types: 3.0.2 + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.0 + mime-types: 3.0.2 + typedarray@0.0.6: {} - typescript-eslint@8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2): + typescript-eslint@8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2))(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) - '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) - '@typescript-eslint/typescript-estree': 8.40.0(typescript@5.9.2) - '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@2.6.1))(typescript@5.9.2) - eslint: 9.33.0(jiti@2.6.1) + '@typescript-eslint/eslint-plugin': 8.40.0(@typescript-eslint/parser@8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2))(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) + '@typescript-eslint/parser': 8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.40.0(supports-color@8.1.1)(typescript@5.9.2) + '@typescript-eslint/utils': 8.40.0(eslint@9.33.0(jiti@2.6.1)(supports-color@8.1.1))(supports-color@8.1.1)(typescript@5.9.2) + eslint: 9.33.0(jiti@2.6.1)(supports-color@8.1.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -7300,7 +7356,7 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 - valibot@1.1.0(typescript@5.9.2): + valibot@1.4.2(typescript@5.9.2): optionalDependencies: typescript: 5.9.2 @@ -7325,7 +7381,7 @@ snapshots: webpack-sources@3.3.3: {} - webpack@5.100.2: + webpack@5.100.2(uglify-js@3.19.3): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -7349,7 +7405,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.2 - terser-webpack-plugin: 5.3.14(webpack@5.100.2) + terser-webpack-plugin: 5.3.14(uglify-js@3.19.3)(webpack@5.100.2(uglify-js@3.19.3)) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index b4b439e..c9816d4 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,9 +1,50 @@ packages: - . +overrides: + '@hono/node-server': 2.0.10 + '@isaacs/brace-expansion': 5.0.1 + '@nestjs/core': 11.1.18 + 'ajv@^6.0.0': 6.14.0 + 'ajv@>=7': 8.18.0 + axios: 1.18.1 + body-parser: 2.3.0 + 'brace-expansion@^1.0.0': 1.1.18 + 'brace-expansion@^2.0.0': 2.1.4 + 'brace-expansion@>=3': 5.0.9 + deepmerge-ts: 8.0.0 + defu: 6.1.5 + 'effect@^3.0.0': 3.22.0 + 'fast-uri@^3.0.0': 3.1.5 + 'file-type@>=13.0.0 <21.3.2': 21.3.2 + flatted: 3.4.2 + follow-redirects: 1.16.0 + form-data: 4.0.6 + handlebars: 4.7.9 + hono: 4.12.34 + ip-address: 10.3.1 + 'js-yaml@^3': 3.15.1 + 'js-yaml@^4.0.0': 4.3.1 + 'js-yaml@^5.0.0': 5.2.2 + 'jws@^3.0.0': 3.2.3 + lodash: 4.18.1 + 'minimatch@^3.0.0': 3.1.4 + 'minimatch@^9.0.0': 9.0.7 + 'minimatch@>=10': 10.2.3 + multer: 2.2.0 + path-to-regexp: 8.4.0 + 'picomatch@^2.0.0': 2.3.2 + 'picomatch@^4.0.0': 4.0.5 + qs: 6.15.2 + serialize-javascript: 7.0.5 + tar: 7.5.21 + valibot: 1.4.2 + allowBuilds: - '@nestjs/core@11.1.9': false - '@prisma/engines@7.0.1': true - '@scarf/scarf@1.4.0': false - dtrace-provider@0.8.8: false - prisma@7.0.1: true + '@nestjs/core': false + '@prisma/client': true + '@prisma/engines': true + '@scarf/scarf': false + dtrace-provider: false + prisma: true + unrs-resolver: true diff --git a/sql/reports/statistics/general/country-member-details.sql b/sql/reports/statistics/general/country-member-details.sql index da4b1e9..bf2e73c 100644 --- a/sql/reports/statistics/general/country-member-details.sql +++ b/sql/reports/statistics/general/country-member-details.sql @@ -8,6 +8,7 @@ WITH member_profiles AS ( m.handle, m."photoURL" AS photo_url FROM members.member m + WHERE NOT (m."userId"::text = ANY($2)) ), country_members AS ( SELECT diff --git a/sql/reports/statistics/general/top-winners-by-country.sql b/sql/reports/statistics/general/top-winners-by-country.sql index 61ce573..bf65e3b 100644 --- a/sql/reports/statistics/general/top-winners-by-country.sql +++ b/sql/reports/statistics/general/top-winners-by-country.sql @@ -21,7 +21,8 @@ stats_wins AS ( ON track.id::text = stats."trackId" LEFT JOIN challenges."ChallengeType" ct ON ct.id::text = stats."typeId" - WHERE stats."isPrivate" = false + WHERE NOT (stats."userId"::text = ANY($2)) + AND stats."isPrivate" = false AND ( UPPER(COALESCE(track.name, stats."trackId")) LIKE '%DEVELOP%' OR UPPER(COALESCE(track.name, stats."trackId")) LIKE '%DESIGN%' diff --git a/src/reports/member/dto/member-search-response.dto.ts b/src/reports/member/dto/member-search-response.dto.ts index 0141341..d87c2f7 100644 --- a/src/reports/member/dto/member-search-response.dto.ts +++ b/src/reports/member/dto/member-search-response.dto.ts @@ -51,6 +51,11 @@ export class MemberResultDto { }) openToWork!: boolean; + @ApiProperty({ + description: "True when the member has the platform Copilot role.", + }) + isCopilot!: boolean; + @ApiProperty({ description: 'Member location in "city country" format.', example: "Sydney Australia", diff --git a/src/reports/member/dto/member-search.dto.ts b/src/reports/member/dto/member-search.dto.ts index a54d987..60c20cc 100644 --- a/src/reports/member/dto/member-search.dto.ts +++ b/src/reports/member/dto/member-search.dto.ts @@ -83,6 +83,14 @@ export class MemberSearchBodyDto { @IsBoolean() profileComplete?: boolean; + @ApiPropertyOptional({ + description: + "When true, only return members who have the platform Copilot role.", + }) + @IsOptional() + @IsBoolean() + copilot?: boolean; + @ApiPropertyOptional({ description: "Filter by multiple preferred role values from the member's open-to-work personalization trait.", diff --git a/src/reports/member/member-search.controller.spec.ts b/src/reports/member/member-search.controller.spec.ts index 75a0a15..c805f65 100644 --- a/src/reports/member/member-search.controller.spec.ts +++ b/src/reports/member/member-search.controller.spec.ts @@ -62,6 +62,7 @@ describe("MemberSearchController", () => { isRecentlyActive: true, isVerified: true, openToWork: false, + isCopilot: true, location: "Gomel Belarus", matchedSkills: [], matchIndex: 97, diff --git a/src/reports/member/member-search.service.spec.ts b/src/reports/member/member-search.service.spec.ts index 4c7504f..375d21e 100644 --- a/src/reports/member/member-search.service.spec.ts +++ b/src/reports/member/member-search.service.spec.ts @@ -171,6 +171,7 @@ describe("MemberSearchService", () => { isRecentlyActive: undefined, isVerified: undefined, openToWork: undefined, + isCopilot: undefined, location: "", matchedSkills: null, matchIndex: undefined, @@ -212,6 +213,7 @@ describe("MemberSearchService", () => { isRecentlyActive: false, isVerified: false, openToWork: false, + isCopilot: false, location: "", matchedSkills: [], matchIndex: 0, @@ -269,6 +271,7 @@ describe("MemberSearchService", () => { openToWork: false, recentlyActive: false, verifiedProfile: false, + copilot: false, }); const dataSql = mockDbService.query.mock.calls[0][0] as string; @@ -277,6 +280,61 @@ describe("MemberSearchService", () => { expect(dataSql).not.toContain( 'EXISTS (SELECT 1 FROM recently_active ra WHERE ra.user_id = m."userId")', ); + expect(dataSql).not.toContain( + 'EXISTS (SELECT 1 FROM copilot_members cm WHERE cm.user_id = m."userId")', + ); + }); + + it("restricts results to copilot role holders when copilot filter is enabled", async () => { + mockDbService.query + .mockResolvedValueOnce([]) + .mockResolvedValueOnce([{ total: 0 }]); + + await service.search({ copilot: true, countries: ["us"] }); + + const dataSql = mockDbService.query.mock.calls[0][0] as string; + const countSql = mockDbService.query.mock.calls[1][0] as string; + + expect(dataSql).toContain("copilot_members AS ("); + expect(dataSql).toContain("LOWER(r.name) = 'copilot'"); + expect(dataSql).toContain( + 'EXISTS (SELECT 1 FROM copilot_members cm WHERE cm.user_id = m."userId")', + ); + // Copilot filter lives in filtered_members, so the count query honours it too. + expect(countSql).toContain( + 'EXISTS (SELECT 1 FROM copilot_members cm WHERE cm.user_id = m."userId")', + ); + expect(dataSql).toContain('m."homeCountryCode" = ANY($1::text[])'); + }); + + it("always selects the copilot indicator for returned members", async () => { + mockDbService.query + .mockResolvedValueOnce([ + { + id: "123", + handle: "tourist", + name: "Tourist Member", + photoUrl: null, + isRecentlyActive: true, + isVerified: true, + openToWork: true, + isCopilot: true, + location: "Sydney Australia", + matchedSkills: [], + matchIndex: 42, + }, + ]) + .mockResolvedValueOnce([{ total: 1 }]); + + const result = await service.search({}); + + const dataSql = mockDbService.query.mock.calls[0][0] as string; + + expect(dataSql).toContain("(cm.user_id IS NOT NULL)"); + expect(dataSql).toContain( + 'LEFT JOIN copilot_members cm ON cm.user_id = m."userId"', + ); + expect(result.data[0].isCopilot).toBe(true); }); it("adds profileComplete CTE/join only when enabled and keeps count params free of pagination", async () => { diff --git a/src/reports/member/member-search.service.ts b/src/reports/member/member-search.service.ts index 8bde5f5..e74b459 100644 --- a/src/reports/member/member-search.service.ts +++ b/src/reports/member/member-search.service.ts @@ -22,6 +22,7 @@ type RawMemberRow = { isRecentlyActive: boolean; isVerified: boolean; openToWork: boolean; + isCopilot: boolean; location: string; matchedSkills: MatchedSkillDto[] | null; matchIndex: number; @@ -421,6 +422,7 @@ ORDER BY recentlyActive, verifiedProfile, profileComplete, + copilot, countries, preferredRoles, sortBy = "matchIndex", @@ -555,6 +557,14 @@ verified_via_trolley AS ( FROM finance.trolley_recipient tr INNER JOIN active_members am ON am.user_id = tr.user_id::bigint ), +copilot_members AS ( + SELECT DISTINCT ra.subject_id::bigint AS user_id + FROM identity.role_assignment ra + INNER JOIN identity.role r ON r.id = ra.role_id + INNER JOIN active_members am ON am.user_id = ra.subject_id::bigint + WHERE ra.subject_type = 1 + AND LOWER(r.name) = 'copilot' +), member_address AS ( SELECT DISTINCT ON ("userId") "userId", city @@ -584,6 +594,12 @@ member_address AS ( ); } + if (copilot === true) { + where.push( + `EXISTS (SELECT 1 FROM copilot_members cm WHERE cm.user_id = m."userId")`, + ); + } + const normalizedCountries = Array.isArray(countries) ? [ ...new Set( @@ -746,6 +762,7 @@ SELECT EXISTS (SELECT 1 FROM recently_active ra WHERE ra.user_id = m."userId") AS "isRecentlyActive", (COALESCE(m.verified, false) = true OR vt.user_id IS NOT NULL) AS "isVerified", COALESCE(m."availableForGigs", false) AS "openToWork", + (cm.user_id IS NOT NULL) AS "isCopilot", TRIM( COALESCE(maddr.city || ' ', '') || COALESCE(m."homeCountryCode", COALESCE(m.country, COALESCE(m."competitionCountryCode", ''))) @@ -757,6 +774,7 @@ INNER JOIN filtered_members fm ON fm.user_id = m."userId" ${profileCompleteJoin} ${deduped.length > 0 ? 'LEFT JOIN user_match_data umd ON umd.user_id = m."userId"' : ""} LEFT JOIN verified_via_trolley vt ON vt.user_id = m."userId" +LEFT JOIN copilot_members cm ON cm.user_id = m."userId" LEFT JOIN member_address maddr ON maddr."userId" = m."userId" ORDER BY ${orderByClause} LIMIT ${pLimit} OFFSET ${pOffset}`; @@ -784,6 +802,7 @@ LIMIT ${pLimit} OFFSET ${pOffset}`; isRecentlyActive: row.isRecentlyActive ?? false, isVerified: row.isVerified ?? false, openToWork: row.openToWork ?? false, + isCopilot: row.isCopilot ?? false, location: formatLocation(row.location), matchedSkills: row.matchedSkills ?? [], matchIndex: row.matchIndex ?? 0, diff --git a/src/reports/report-directory.data.spec.ts b/src/reports/report-directory.data.spec.ts index ce04977..ac93d29 100644 --- a/src/reports/report-directory.data.spec.ts +++ b/src/reports/report-directory.data.spec.ts @@ -52,6 +52,12 @@ describe("getAccessibleReportsDirectory", () => { expect(directory.identity).toBeUndefined(); expect(directory.sfdc).toBeUndefined(); expect(directory.topcoder).toBeUndefined(); + expect( + directory.statistics?.reports.map((report) => report.path), + ).not.toContain("/statistics/expert-skills/categories"); + expect( + directory.statistics?.reports.map((report) => report.path), + ).not.toContain("/statistics/expert-skills/category-members"); }); it("returns challenge, member, and role-mapped identity reports for talent managers", () => { @@ -74,6 +80,12 @@ describe("getAccessibleReportsDirectory", () => { "/member/recent-member-data", "/member/search", ]); + expect(directory.statistics?.reports.map((report) => report.path)).toEqual( + expect.arrayContaining([ + "/statistics/expert-skills/categories", + "/statistics/expert-skills/category-members", + ]), + ); }); it("returns bulk member lookup for topcoder project managers", () => { @@ -98,6 +110,12 @@ describe("getAccessibleReportsDirectory", () => { expect(directory.identity).toBeUndefined(); expect(directory.sfdc).toBeUndefined(); expect(directory.statistics?.reports.length).toBeGreaterThan(0); + expect( + directory.statistics?.reports.map((report) => report.path), + ).not.toContain("/statistics/expert-skills/categories"); + expect( + directory.statistics?.reports.map((report) => report.path), + ).not.toContain("/statistics/expert-skills/category-members"); expect(directory.topcoder).toBeUndefined(); }); @@ -119,6 +137,12 @@ describe("getAccessibleReportsDirectory", () => { "/member/recent-member-data", "/member/search", ]); + expect( + directory.statistics?.reports.map((report) => report.path), + ).not.toContain("/statistics/expert-skills/categories"); + expect( + directory.statistics?.reports.map((report) => report.path), + ).not.toContain("/statistics/expert-skills/category-members"); }); it("returns an empty directory when no JWT user is present", () => { diff --git a/src/reports/report-directory.data.ts b/src/reports/report-directory.data.ts index 1fc78c1..56f93e8 100644 --- a/src/reports/report-directory.data.ts +++ b/src/reports/report-directory.data.ts @@ -1,4 +1,4 @@ -import { Scopes as AppScopes } from "../app-constants"; +import { Scopes as AppScopes, UserRoles } from "../app-constants"; import { AuthUserLike, getNormalizedRoles, @@ -58,6 +58,7 @@ export type ReportsDirectory = Partial>; type RegisteredReport = AvailableReport & { requiredScopes: readonly string[]; adminOnly?: boolean; + allowedRoles?: readonly string[]; }; type RegisteredReportGroup = Omit & { @@ -169,6 +170,16 @@ const publicReport = ( parameters: ReportParameter[] = [], ): RegisteredReport => report(name, path, description, [], parameters); +const talentManagerReport = ( + name: string, + path: string, + description: string, + parameters: ReportParameter[] = [], +): RegisteredReport => ({ + ...publicReport(name, path, description, parameters), + allowedRoles: [UserRoles.TalentManager], +}); + const challengeStatusParam: ReportParameter = { name: "challengeStatus", type: "enum[]", @@ -684,15 +695,15 @@ const REGISTERED_REPORTS_DIRECTORY: RegisteredReportsDirectory = { "/statistics/qa/wins", "Quality Assurance challenge wins by member (desc)", ), - publicReport( + talentManagerReport( "Expert Skill Categories", "/statistics/expert-skills/categories", - "Skill categories from skills.skill_category with win-normalized bubble sizes", + "Skill categories from skills.skill_category with win-normalized bubble sizes. Accessible by Administrator and Talent Manager roles only.", ), - publicReport( + talentManagerReport( "Expert Skill Category Members", "/statistics/expert-skills/category-members", - "Top 100 members in a skill category, sorted by wins", + "Top 100 members in a skill category, sorted by wins. Accessible by Administrator and Talent Manager roles only.", [ { name: "selectedcategory", @@ -980,6 +991,18 @@ export function getAccessibleReportsDirectory( return false; } + if (reportDefinition.allowedRoles?.length) { + if (isAdmin) { + return true; + } + + const allowedRoles = new Set( + reportDefinition.allowedRoles.map((role) => role.toLowerCase()), + ); + + return normalizedRoles.some((role) => allowedRoles.has(role)); + } + return hasAccessToScopes(authUser, reportDefinition.requiredScopes); }); diff --git a/src/statistics/expert-skills-statistics.data.spec.ts b/src/statistics/expert-skills-statistics.data.spec.ts index c16903c..368861f 100644 --- a/src/statistics/expert-skills-statistics.data.spec.ts +++ b/src/statistics/expert-skills-statistics.data.spec.ts @@ -13,15 +13,82 @@ describe("expert-skills-statistics.data", () => { ); }); - it("assigns a stable color and icon from the category id", () => { - const first = getCategoryAppearance("481b5ebc-2fe6-45ed-a90c-736936d458d7"); + it("maps known category names to Figma icons regardless of id", () => { + expect( + getCategoryAppearance( + "481b5ebc-2fe6-45ed-a90c-736936d458d7", + "Programming & Development", + ), + ).toEqual({ + color: "#1B4F72", + icon: "terminal", + }); + expect(getCategoryAppearance("unused-id", "Web Development")).toEqual({ + color: "#7EB8C4", + icon: "language", + }); + expect( + getCategoryAppearance( + "unused-id", + "Software Development Lifecycle (SDLC)", + ).icon, + ).toBe("cloud_sync"); + expect( + getCategoryAppearance("unused-id", "DevOps and Automation").icon, + ).toBe("rule_settings"); + expect( + getCategoryAppearance("unused-id", "UX Design and Multimedia").icon, + ).toBe("design_services"); + expect(getCategoryAppearance("unused-id", "Project Management").icon).toBe( + "assignment", + ); + }); + + it("gives each known category a unique icon", () => { + const names = [ + "Programming and Development", + "Web Development", + "Networking and Telecommunications", + "Cybersecurity", + "Software Development Lifecycle (SDLC)", + "Cloud Computing", + "Operating Systems", + "DevOps and Automation", + "Data Analysis and Big Data", + "Virtualization", + "Databases and Data Warehousing", + "Mathematics and Statistics", + "Database Management", + "Geospatial Information Systems (GIS)", + "Machine Learning and AI", + "User Experience Design and Multimedia", + "Hardware and Systems Administration", + "Mobile App Development", + "Software Testing and Quality Assurance", + "Blockchain", + "IoT (Internet of Things)", + "Project Management", + "Scripting and Automation", + ]; + const icons = names.map( + (name) => getCategoryAppearance("unused-id", name).icon, + ); + + expect(new Set(icons).size).toBe(names.length); + }); + + it("hashes unknown categories by id so new catalog entries still render", () => { + const first = getCategoryAppearance( + "481b5ebc-2fe6-45ed-a90c-736936d458d7", + "Test Cat QA 1", + ); const second = getCategoryAppearance( "481b5ebc-2fe6-45ed-a90c-736936d458d7", ); expect(first).toEqual(second); expect(first.color).toMatch(/^#[0-9A-F]{6}$/i); - expect(first.icon).toMatch(/Icon$/); + expect(first.icon).toMatch(/^[a-z0-9_]+$/); }); it("normalizes sizes on sqrt(wins) into the bubble range", () => { diff --git a/src/statistics/expert-skills-statistics.data.ts b/src/statistics/expert-skills-statistics.data.ts index 33a090f..629e980 100644 --- a/src/statistics/expert-skills-statistics.data.ts +++ b/src/statistics/expert-skills-statistics.data.ts @@ -1,7 +1,8 @@ /** * Visual tokens for Skill Statistics bubbles. - * Category names/ids come from standardized-skills; these palettes are - * assigned by hashing the category id so new catalog entries still render. + * Category names/ids come from standardized-skills. Icons are Material Symbols + * Rounded ligatures (https://fonts.google.com/icons?icon.style=Rounded). + * Known catalog names map to Figma icons/colors; unknown entries still hash by id. */ const CATEGORY_COLORS = [ "#1B4F72", @@ -29,29 +30,29 @@ const CATEGORY_COLORS = [ ]; const CATEGORY_ICONS = [ - "TerminalIcon", - "RssIcon", - "GlobeAltIcon", - "ShieldCheckIcon", - "CloudIcon", - "RefreshIcon", - "DuplicateIcon", - "ChipIcon", - "ChartBarIcon", - "SparklesIcon", - "ServerIcon", - "PencilAltIcon", - "CalculatorIcon", - "CubeTransparentIcon", - "MapIcon", - "DesktopComputerIcon", - "ClipboardCheckIcon", - "DatabaseIcon", - "DeviceMobileIcon", - "ShareIcon", - "WifiIcon", - "ClipboardListIcon", - "CodeIcon", + "terminal", + "cell_tower", + "language", + "shield_lock", + "desktop_cloud_stack", + "cloud_sync", + "layers", + "memory", + "analytics", + "psychology", + "data_table", + "design_services", + "calculate", + "database", + "map", + "install_desktop", + "fact_check", + "mobile_gear", + "hub", + "devices_other", + "assignment", + "integration_instructions", + "rule_settings", ]; export type CategoryAppearance = { @@ -59,15 +60,6 @@ export type CategoryAppearance = { icon: string; }; -export function getCategoryAppearance(categoryId: string): CategoryAppearance { - const hash = hashString(categoryId); - - return { - color: CATEGORY_COLORS[hash % CATEGORY_COLORS.length], - icon: CATEGORY_ICONS[hash % CATEGORY_ICONS.length], - }; -} - export function normalizeCategoryName(value: string): string { return value .toLowerCase() @@ -76,6 +68,87 @@ export function normalizeCategoryName(value: string): string { .trim(); } +const NAMED_CATEGORY_APPEARANCE: Array<[string[], CategoryAppearance]> = [ + [["Programming and Development"], { color: "#1B4F72", icon: "terminal" }], + [["Web Development"], { color: "#7EB8C4", icon: "language" }], + [ + ["Networking and Telecommunications"], + { color: "#5EB3C4", icon: "cell_tower" }, + ], + [["Cybersecurity"], { color: "#5B9BD5", icon: "shield_lock" }], + [ + [ + "Software Development Lifecycle (SDLC)", + "Software Development Lifecycle", + "SDLC", + ], + { color: "#1A3D3D", icon: "cloud_sync" }, + ], + [["Cloud Computing"], { color: "#2C4A6E", icon: "desktop_cloud_stack" }], + [["Operating Systems"], { color: "#3D7EA6", icon: "memory" }], + [["DevOps and Automation"], { color: "#2D4A3E", icon: "rule_settings" }], + [["Data Analysis and Big Data"], { color: "#2C5F8A", icon: "analytics" }], + [["Virtualization"], { color: "#3D7EA6", icon: "layers" }], + [ + ["Databases and Data Warehousing"], + { color: "#1B4F72", icon: "data_table" }, + ], + [["Mathematics and Statistics"], { color: "#6B7C4A", icon: "calculate" }], + [["Database Management"], { color: "#7EB8C4", icon: "database" }], + [ + ["Geospatial Information Systems (GIS)", "Geospatial Information Systems"], + { color: "#3D6A8A", icon: "map" }, + ], + [["Machine Learning and AI"], { color: "#5EB8B0", icon: "psychology" }], + [ + ["User Experience Design and Multimedia", "UX Design and Multimedia"], + { color: "#3D5C5C", icon: "design_services" }, + ], + [ + ["Hardware and Systems Administration"], + { color: "#4EC4C4", icon: "install_desktop" }, + ], + [["Mobile App Development"], { color: "#5A8A8A", icon: "mobile_gear" }], + [ + ["Software Testing and Quality Assurance", "Software Testing and QA"], + { color: "#2C5F8A", icon: "fact_check" }, + ], + [["Blockchain"], { color: "#2C4A6E", icon: "hub" }], + [["IoT (Internet of Things)"], { color: "#3D8B8F", icon: "devices_other" }], + [["Project Management"], { color: "#3D7EA6", icon: "assignment" }], + [ + ["Scripting and Automation"], + { color: "#5B9BD5", icon: "integration_instructions" }, + ], +]; + +const CATEGORY_APPEARANCE_BY_NAME: Record = + Object.fromEntries( + NAMED_CATEGORY_APPEARANCE.flatMap(([names, appearance]) => + names.map((name) => [normalizeCategoryName(name), appearance]), + ), + ); + +export function getCategoryAppearance( + categoryId: string, + categoryName?: string, +): CategoryAppearance { + const mapped = categoryName + ? CATEGORY_APPEARANCE_BY_NAME[normalizeCategoryName(categoryName)] + : undefined; + + if (mapped) { + return mapped; + } + + const hash = hashString(categoryId); + + return { + color: CATEGORY_COLORS[hash % CATEGORY_COLORS.length], + icon: CATEGORY_ICONS[hash % CATEGORY_ICONS.length], + }; +} + export const MIN_CATEGORY_SIZE = 3; export const MAX_CATEGORY_SIZE = 10; diff --git a/src/statistics/expert-skills-statistics.service.spec.ts b/src/statistics/expert-skills-statistics.service.spec.ts index a508e8d..3cc8b1f 100644 --- a/src/statistics/expert-skills-statistics.service.spec.ts +++ b/src/statistics/expert-skills-statistics.service.spec.ts @@ -74,8 +74,10 @@ describe("ExpertSkillsStatisticsService", () => { totalSkills: 50, }), ); - expect(result[0].color).toMatch(/^#[0-9A-F]{6}$/i); + expect(result[0].color).toBe("#1B4F72"); + expect(result[0].icon).toBe("terminal"); expect(result[1].name).toBe("Scripting and Automation"); + expect(result[1].icon).toBe("integration_instructions"); expect(result[1].size).toBe(3); }); diff --git a/src/statistics/expert-skills-statistics.service.ts b/src/statistics/expert-skills-statistics.service.ts index b99f508..49f86ec 100644 --- a/src/statistics/expert-skills-statistics.service.ts +++ b/src/statistics/expert-skills-statistics.service.ts @@ -98,7 +98,7 @@ export class ExpertSkillsStatisticsService { return categories.map((category, index) => { const stats = statsById.get(category.id); - const appearance = getCategoryAppearance(category.id); + const appearance = getCategoryAppearance(category.id, category.name); return { id: category.id, diff --git a/src/statistics/general-statistics.service.spec.ts b/src/statistics/general-statistics.service.spec.ts index 235c9be..cabbe1c 100644 --- a/src/statistics/general-statistics.service.spec.ts +++ b/src/statistics/general-statistics.service.spec.ts @@ -11,7 +11,15 @@ describe("GeneralStatisticsService", () => { load: jest.fn().mockReturnValue("SELECT tooltip data"), }; const config = { - get: jest.fn().mockReturnValue('["Task","First2Finish"]'), + get: jest.fn((key: string, defaultValue?: string) => { + if (key === "REPORTS_EXCLUDED_CHALLENGE_TYPES") { + return '["Task","First2Finish"]'; + } + if (key === "REPORTS_EXCLUDED_USER_IDS") { + return '["8547899", 251280]'; + } + return defaultValue; + }), }; const service = new GeneralStatisticsService( db as unknown as DbService, @@ -70,10 +78,10 @@ describe("GeneralStatisticsService", () => { expect(sql.load).toHaveBeenCalledWith( "reports/statistics/general/top-winners-by-country.sql", ); - expect(db.query).toHaveBeenCalledWith( - "SELECT tooltip data", - [["Task", "First2Finish"]], - ); + expect(db.query).toHaveBeenCalledWith("SELECT tooltip data", [ + ["Task", "First2Finish"], + ["8547899", "251280"], + ]); }); it("uses safe defaults when winner details are absent", async () => { @@ -94,10 +102,29 @@ describe("GeneralStatisticsService", () => { topWinners: [], }, ]); - expect(db.query).toHaveBeenCalledWith( - "SELECT tooltip data", - [["Task", "First2Finish"]], + expect(db.query).toHaveBeenCalledWith("SELECT tooltip data", [ + ["Task", "First2Finish"], + ["8547899", "251280"], + ]); + }); + + it("passes no excluded users when the config is unset", async () => { + const emptyConfig = { + get: jest.fn((_key: string, defaultValue?: string) => defaultValue), + }; + const serviceWithDefaults = new GeneralStatisticsService( + db as unknown as DbService, + sql as unknown as SqlLoaderService, + emptyConfig as unknown as ConfigService, ); + db.query.mockResolvedValue([]); + + await serviceWithDefaults.getTopWinnersByCountry(); + + expect(db.query).toHaveBeenCalledWith("SELECT tooltip data", [ + ["Task", "First2Finish"], + [], + ]); }); it("normalizes country member, skill, and top-member details", async () => { @@ -191,9 +218,9 @@ describe("GeneralStatisticsService", () => { expect(sql.load).toHaveBeenCalledWith( "reports/statistics/general/country-member-details.sql", ); - expect(db.query).toHaveBeenCalledWith( - "SELECT tooltip data", - [["Task", "First2Finish"]], - ); + expect(db.query).toHaveBeenCalledWith("SELECT tooltip data", [ + ["Task", "First2Finish"], + ["8547899", "251280"], + ]); }); }); diff --git a/src/statistics/general-statistics.service.ts b/src/statistics/general-statistics.service.ts index da878db..2400e24 100644 --- a/src/statistics/general-statistics.service.ts +++ b/src/statistics/general-statistics.service.ts @@ -30,22 +30,26 @@ type CountryMemberDetailRow = { @Injectable() export class GeneralStatisticsService { private readonly excludedChallengeTypes: string[]; + private readonly excludedUserIds: string[]; constructor( private readonly db: DbService, private readonly sql: SqlLoaderService, private readonly config: ConfigService, ) { - this.excludedChallengeTypes = this.parseExcludedChallengeTypes(); + this.excludedChallengeTypes = this.parseListConfig( + "REPORTS_EXCLUDED_CHALLENGE_TYPES", + '["Task","First2Finish"]', + ); + this.excludedUserIds = this.parseListConfig( + "REPORTS_EXCLUDED_USER_IDS", + "[]", + ); } - private parseExcludedChallengeTypes(): string[] { - const raw = this.config - .get( - "REPORTS_EXCLUDED_CHALLENGE_TYPES", - '["Task","First2Finish"]', - ) - .trim(); + // Accepts either a JSON array string ('["1","2"]') or a comma-separated list. + private parseListConfig(key: string, defaultValue: string): string[] { + const raw = (this.config.get(key, defaultValue) ?? "").trim(); if (!raw) { return []; @@ -55,8 +59,10 @@ export class GeneralStatisticsService { const parsed = JSON.parse(raw); if (Array.isArray(parsed)) { return parsed - .filter((item) => typeof item === "string" && item.trim()) - .map((item) => item.trim()); + .map((item) => + typeof item === "number" ? String(item) : String(item ?? "").trim(), + ) + .filter(Boolean); } } catch { // ignore JSON parse failure and fall back to comma-separated values @@ -118,6 +124,7 @@ export class GeneralStatisticsService { ); const rows = await this.db.query(q, [ this.excludedChallengeTypes, + this.excludedUserIds, ]); const countries = new Map< string, @@ -272,7 +279,7 @@ export class GeneralStatisticsService { photoURL?: string | null; wins?: number | string | null; }> | null; - }>(q, [this.excludedChallengeTypes]); + }>(q, [this.excludedChallengeTypes, this.excludedUserIds]); return rows.map((row) => { const countryName = diff --git a/src/statistics/guards/expert-skills.guard.spec.ts b/src/statistics/guards/expert-skills.guard.spec.ts new file mode 100644 index 0000000..ac0e6c6 --- /dev/null +++ b/src/statistics/guards/expert-skills.guard.spec.ts @@ -0,0 +1,85 @@ +import { + ExecutionContext, + ForbiddenException, + UnauthorizedException, +} from "@nestjs/common"; +import { UserRoles } from "src/app-constants"; +import { ExpertSkillsGuard } from "./expert-skills.guard"; + +type AuthUserFixture = { + isMachine?: boolean; + roles?: string[]; + role?: string | string[]; + scopes?: string[]; +}; + +function createExecutionContext(authUser?: AuthUserFixture): ExecutionContext { + return { + switchToHttp: () => ({ + getRequest: () => ({ + authUser, + }), + }), + } as unknown as ExecutionContext; +} + +describe("ExpertSkillsGuard", () => { + const guard = new ExpertSkillsGuard(); + + it("throws when no auth user is present", () => { + expect(() => guard.canActivate(createExecutionContext())).toThrow( + UnauthorizedException, + ); + }); + + it("allows talent manager role access", () => { + expect( + guard.canActivate( + createExecutionContext({ + roles: [UserRoles.TalentManager], + }), + ), + ).toBe(true); + }); + + it("allows admin role access", () => { + expect( + guard.canActivate( + createExecutionContext({ + roles: ["Administrator"], + }), + ), + ).toBe(true); + }); + + it("allows role claim with topcoder talent manager prefix", () => { + expect( + guard.canActivate( + createExecutionContext({ + role: "Topcoder Talent Manager", + }), + ), + ).toBe(true); + }); + + it("denies machine clients even with report scopes", () => { + expect(() => + guard.canActivate( + createExecutionContext({ + isMachine: true, + scopes: ["reports:all"], + }), + ), + ).toThrow(ForbiddenException); + }); + + it("denies non-admin users without required role", () => { + expect(() => + guard.canActivate( + createExecutionContext({ + roles: [UserRoles.ProjectManager], + }), + ), + ).toThrow(ForbiddenException); + }); +}); diff --git a/src/statistics/guards/expert-skills.guard.ts b/src/statistics/guards/expert-skills.guard.ts new file mode 100644 index 0000000..28871ed --- /dev/null +++ b/src/statistics/guards/expert-skills.guard.ts @@ -0,0 +1,38 @@ +import { + CanActivate, + ExecutionContext, + ForbiddenException, + Injectable, + UnauthorizedException, +} from "@nestjs/common"; +import { + AuthUserLike, + getNormalizedRoles, + hasAdminRole, +} from "../../auth/permissions.util"; +import { UserRoles } from "src/app-constants"; + +const ALLOWED_ROLES = new Set([UserRoles.TalentManager.toLowerCase()]); + +@Injectable() +export class ExpertSkillsGuard implements CanActivate { + canActivate(context: ExecutionContext): boolean { + const authUser: AuthUserLike | undefined = context + .switchToHttp() + .getRequest().authUser; + + if (!authUser) { + throw new UnauthorizedException("You are not authenticated."); + } + + const roles = getNormalizedRoles(authUser); + + if (hasAdminRole(roles) || roles.some((role) => ALLOWED_ROLES.has(role))) { + return true; + } + + throw new ForbiddenException( + "You do not have the required permissions to access this resource.", + ); + } +} diff --git a/src/statistics/statistics-expert-skills.controller.ts b/src/statistics/statistics-expert-skills.controller.ts index 2dfc21f..10b090e 100644 --- a/src/statistics/statistics-expert-skills.controller.ts +++ b/src/statistics/statistics-expert-skills.controller.ts @@ -1,8 +1,17 @@ -import { Controller, Get, Query } from "@nestjs/common"; -import { ApiOperation, ApiQuery, ApiTags } from "@nestjs/swagger"; +import { Controller, Get, Query, UseGuards } from "@nestjs/common"; +import { + ApiBearerAuth, + ApiOperation, + ApiQuery, + ApiResponse, + ApiTags, +} from "@nestjs/swagger"; import { ExpertSkillsStatisticsService } from "./expert-skills-statistics.service"; +import { ExpertSkillsGuard } from "./guards/expert-skills.guard"; @ApiTags("Statistics") +@ApiBearerAuth() +@UseGuards(ExpertSkillsGuard) @Controller("/statistics/expert-skills") export class StatisticsExpertSkillsController { constructor(private readonly expertSkills: ExpertSkillsStatisticsService) {} @@ -11,7 +20,11 @@ export class StatisticsExpertSkillsController { @ApiOperation({ summary: "Skill categories from skills.skill_category with win-normalized bubble sizes", + description: + "Returns skill categories from the standardized-skills catalog, with win-normalized bubble sizes (3–10). Accessible by Administrator and Talent Manager roles only.", }) + @ApiResponse({ status: 401, description: "Unauthenticated" }) + @ApiResponse({ status: 403, description: "Forbidden – insufficient role" }) getCategories() { return this.expertSkills.getCategories(); } @@ -19,12 +32,17 @@ export class StatisticsExpertSkillsController { @Get("/category-members") @ApiOperation({ summary: "Top 100 members in a skill category, sorted by wins", + description: + "Returns up to 100 members with wins in the selected skill category, sorted by wins descending. selectedcategory is the standardized-skills category name or UUID. Accessible by Administrator and Talent Manager roles only.", }) @ApiQuery({ name: "selectedcategory", required: true, description: "Standardized-skills category name or UUID", }) + @ApiResponse({ status: 401, description: "Unauthenticated" }) + @ApiResponse({ status: 403, description: "Forbidden – insufficient role" }) + @ApiResponse({ status: 404, description: "Skill category not found" }) getCategoryMembers(@Query("selectedcategory") selectedcategory: string) { return this.expertSkills.getCategoryMembers(selectedcategory); } diff --git a/src/statistics/statistics-general.sql.spec.ts b/src/statistics/statistics-general.sql.spec.ts index ea46b2c..70f9593 100644 --- a/src/statistics/statistics-general.sql.spec.ts +++ b/src/statistics/statistics-general.sql.spec.ts @@ -27,6 +27,7 @@ describe("General statistics SQL", () => { expect(sql).toContain('members."memberMaxRating"'); expect(sql).toContain("'maxRating', max_rating"); expect(sql).toContain('first_place_count AS "challenge_stats.count"'); + expect(sql).toContain('NOT (stats."userId"::text = ANY($2))'); }); it("aggregates owned skills and three deterministic top members", () => { @@ -52,6 +53,7 @@ describe("General statistics SQL", () => { expect(sql).toContain("ORDER BY wins DESC, handle ASC, user_id ASC"); expect(sql).toContain("member_rank <= 3"); expect(sql).toContain('countries.members_count AS "user.count"'); + expect(sql).toContain('WHERE NOT (m."userId"::text = ANY($2))'); }); it("uses public member stats wins for country totals", () => { diff --git a/src/statistics/statistics.module.ts b/src/statistics/statistics.module.ts index 1eb7c17..e344a80 100644 --- a/src/statistics/statistics.module.ts +++ b/src/statistics/statistics.module.ts @@ -12,6 +12,7 @@ import { StatisticsQaController } from "./statistics-qa.controller"; import { QaStatisticsService } from "./qa-statistics.service"; import { StatisticsExpertSkillsController } from "./statistics-expert-skills.controller"; import { ExpertSkillsStatisticsService } from "./expert-skills-statistics.service"; +import { ExpertSkillsGuard } from "./guards/expert-skills.guard"; import { SqlLoaderService } from "../common/sql-loader.service"; @Module({ @@ -31,6 +32,7 @@ import { SqlLoaderService } from "../common/sql-loader.service"; DevelopmentStatisticsService, QaStatisticsService, ExpertSkillsStatisticsService, + ExpertSkillsGuard, SqlLoaderService, ], })