diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index daaa842..f01c607 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,6 +10,14 @@ concurrency: group: ci-${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +# None of this workflow's jobs write to the repository, comment on PRs, or +# otherwise need more than read access to the checked-out code. Pin an +# explicit least-privilege ceiling here rather than inheriting the ambient +# repository/org default GITHUB_TOKEN grant (mirrors release.yml, which +# scopes itself to the single `contents: write` it actually needs). +permissions: + contents: read + env: DATABASE_URL: postgresql://fanilab:fanilab@localhost:5432/fanilab_backend?schema=public REDIS_URL: redis://localhost:6379 diff --git a/docs/SECURITY.md b/docs/SECURITY.md index 70377b4..3f6f302 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -46,7 +46,13 @@ Dependabot (`.github/dependabot.yml`) tracks npm, Docker base images, and GitHub Dependabot only proposes upgrades — it does not fail a build for a known-vulnerable dependency that hasn't been upgraded yet. To close that gap, the `audit` job in `.github/workflows/ci.yml` runs `pnpm audit --audit-level=high` on every PR and on `main`; a `high` or `critical` advisory anywhere in the dependency tree (direct or transitive) fails CI. Run it locally with `pnpm audit`. -**Accepted exceptions:** none currently. If an advisory has no available fix and must be temporarily tolerated, it must be listed here with the advisory id, the affected package, a rationale, and an owner — the audit threshold is never lowered globally to work around a single unfixable advisory. +**Accepted exceptions:** none currently at or above the `high` CI threshold. If an advisory has no available fix and must be temporarily tolerated, it must be listed here with the advisory id, the affected package, a rationale, and an owner — the audit threshold is never lowered globally to work around a single unfixable advisory. + +**Known residual advisories below the `high` threshold** (do not fail CI, recorded here for visibility): + +- `GHSA-w5hq-g745-h8pq` — `uuid` <11.1.1, missing buffer bounds check in v3/v5/v6 when a `buf` argument is supplied. Reached only via `autocannon > hyperid > uuid`; `autocannon` is a dev-only load-testing tool (`pnpm load-test`), never bundled or run in production, and this project never passes a `buf` argument. No override is applied because `hyperid` has not published a release depending on a patched `uuid`. + +The `pnpm.overrides` block in `package.json` pins forward-patched versions of `tar`, `handlebars`, `vite`, `esbuild`, `nanoid`, `js-yaml`, and `fast-uri` — all pulled in transitively through build/lint/test tooling (`bcrypt`'s native-build toolchain, `eslint-plugin-boundaries`, the Vitest/Vite stack) — to clear the `critical`/`high` advisories those chains carried. ## Reporting Timeline & Disclosure diff --git a/package.json b/package.json index d473502..3e58930 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@types/bcrypt": "^5.0.2", "@types/jsonwebtoken": "^9.0.7", "@types/node": "^22.9.0", - "@vitest/coverage-v8": "^2.1.4", + "@vitest/coverage-v8": "^3.2.7", "autocannon": "^8.0.0", "eslint": "^9.14.0", "eslint-config-prettier": "^9.1.0", @@ -75,7 +75,7 @@ "tsx": "^4.23.12", "typescript": "^5.6.3", "typescript-eslint": "^8.67.0", - "vitest": "^2.1.4" + "vitest": "^3.2.7" }, "lint-staged": { "*.{ts,js}": [ @@ -96,6 +96,16 @@ "esbuild", "msgpackr-extract", "prisma" - ] + ], + "overrides": { + "tar@<7.5.21": ">=7.5.21", + "handlebars@<4.7.9": ">=4.7.9", + "vite@<6.4.3": "^6.4.3", + "esbuild@<0.25.0": "^0.25.0", + "nanoid@<3.3.18": "^3.3.18", + "js-yaml@<4.3.1": "^4.3.1", + "fast-uri@<3.1.5": "^3.1.5", + "@fastify/static@<10.1.2": "^10.1.2" + } } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9c8b612..6af23b7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,16 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + tar@<7.5.21: '>=7.5.21' + handlebars@<4.7.9: '>=4.7.9' + vite@<6.4.3: ^6.4.3 + esbuild@<0.25.0: ^0.25.0 + nanoid@<3.3.18: ^3.3.18 + js-yaml@<4.3.1: ^4.3.1 + fast-uri@<3.1.5: ^3.1.5 + '@fastify/static@<10.1.2': ^10.1.2 + importers: .: @@ -82,8 +92,8 @@ importers: specifier: ^22.9.0 version: 22.20.1 '@vitest/coverage-v8': - specifier: ^2.1.4 - version: 2.1.9(vitest@2.1.9(@types/node@22.20.1)) + specifier: ^3.2.7 + version: 3.2.7(vitest@3.2.7(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0)) autocannon: specifier: ^8.0.0 version: 8.0.0 @@ -118,8 +128,8 @@ importers: specifier: ^8.67.0 version: 8.67.0(eslint@9.39.5)(typescript@5.9.3) vitest: - specifier: ^2.1.4 - version: 2.1.9(@types/node@22.20.1) + specifier: ^3.2.7 + version: 3.2.7(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0) packages: @@ -147,8 +157,9 @@ packages: resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} engines: {node: '>=6.9.0'} - '@bcoe/v8-coverage@0.2.3': - resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} '@boundaries/elements@1.2.0': resolution: {integrity: sha512-W65Gum02liMd3hmNrLmDBX1u5BmRMcunouFjLXyhxHnNY4YlK1kTxsgfflZ5XBGSnPnO0MkiUzAcoGzYrlx0RQ==} @@ -158,9 +169,9 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@esbuild/aix-ppc64@0.21.5': - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -170,9 +181,9 @@ packages: cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.21.5': - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -182,9 +193,9 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm@0.21.5': - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} cpu: [arm] os: [android] @@ -194,9 +205,9 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-x64@0.21.5': - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} cpu: [x64] os: [android] @@ -206,9 +217,9 @@ packages: cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.21.5': - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -218,9 +229,9 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.21.5': - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -230,9 +241,9 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.21.5': - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -242,9 +253,9 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.21.5': - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -254,9 +265,9 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.21.5': - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -266,9 +277,9 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.21.5': - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -278,9 +289,9 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.21.5': - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -290,9 +301,9 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.21.5': - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -302,9 +313,9 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.21.5': - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -314,9 +325,9 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.21.5': - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -326,9 +337,9 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.21.5': - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -338,9 +349,9 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.21.5': - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -350,9 +361,9 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.21.5': - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} cpu: [x64] os: [linux] @@ -362,15 +373,21 @@ packages: cpu: [x64] os: [linux] + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-arm64@0.28.2': resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.21.5': - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -380,15 +397,21 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-arm64@0.28.2': resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.21.5': - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -398,15 +421,21 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/openharmony-arm64@0.28.2': resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.21.5': - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -416,9 +445,9 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.21.5': - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -428,9 +457,9 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.21.5': - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -440,9 +469,9 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.21.5': - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} cpu: [x64] os: [win32] @@ -523,8 +552,8 @@ packages: '@fastify/send@4.1.0': resolution: {integrity: sha512-TMYeQLCBSy2TOFmV95hQWkiTYgC/SEx7vMdV+wnZVX4tt8VBLKzmH8vV9OzJehV0+XBfg+WxPMt5wp+JBUKsVw==} - '@fastify/static@9.3.0': - resolution: {integrity: sha512-9YMYRpCOtMBrqKYWcqiw7ykOrn4D0jogHpJrFS0KGeSuOwzKMM5/mjj7B0CFLVoQ6htqKYw//Zs7APn9DBq05w==} + '@fastify/static@10.1.3': + resolution: {integrity: sha512-W6jqajYS974XjPjB5hQWoxPM8NKM4+p8YmQT6G5IbCa4uhdWSVadZUv75siy1wEA/3ty8RYdpBydfWeu9AqAqQ==} '@fastify/swagger-ui@5.2.6': resolution: {integrity: sha512-OMnms0O5s9wb6wis/K5nlrAMLsgUbr1GA8uphM41IasWe3AFdgxz6r/3bA9HTxlDNUYc2FGGKeqMp3ntxmSiNA==} @@ -559,6 +588,10 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@istanbuljs/schema@0.1.6': resolution: {integrity: sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==} engines: {node: '>=8'} @@ -806,6 +839,12 @@ packages: '@types/bcrypt@5.0.2': resolution: {integrity: sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} @@ -880,43 +919,43 @@ packages: resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitest/coverage-v8@2.1.9': - resolution: {integrity: sha512-Z2cOr0ksM00MpEfyVE8KXIYPEcBFxdbLSs56L8PO0QQMxt/6bDj45uQfxoc96v05KW3clk7vvgP0qfDit9DmfQ==} + '@vitest/coverage-v8@3.2.7': + resolution: {integrity: sha512-NEGWJS2XNu2PfRLQwOO3CTKj1tTETxNBdk454vDxVBhxJYhPaA/eS0nAI0c+1El1P7a60z8+i+ZrQoGESweGKg==} peerDependencies: - '@vitest/browser': 2.1.9 - vitest: 2.1.9 + '@vitest/browser': 3.2.7 + vitest: 3.2.7 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@2.1.9': - resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + '@vitest/expect@3.2.7': + resolution: {integrity: sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==} - '@vitest/mocker@2.1.9': - resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + '@vitest/mocker@3.2.7': + resolution: {integrity: sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==} peerDependencies: msw: ^2.4.9 - vite: ^5.0.0 + vite: ^6.4.3 peerDependenciesMeta: msw: optional: true vite: optional: true - '@vitest/pretty-format@2.1.9': - resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + '@vitest/pretty-format@3.2.7': + resolution: {integrity: sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==} - '@vitest/runner@2.1.9': - resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + '@vitest/runner@3.2.7': + resolution: {integrity: sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==} - '@vitest/snapshot@2.1.9': - resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + '@vitest/snapshot@3.2.7': + resolution: {integrity: sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==} - '@vitest/spy@2.1.9': - resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + '@vitest/spy@3.2.7': + resolution: {integrity: sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==} - '@vitest/utils@2.1.9': - resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + '@vitest/utils@3.2.7': + resolution: {integrity: sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==} abbrev@1.1.1: resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} @@ -991,6 +1030,9 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + ast-v8-to-istanbul@0.3.12: + resolution: {integrity: sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==} + asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -1126,9 +1168,9 @@ packages: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} cli-cursor@5.0.0: resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} @@ -1177,8 +1219,8 @@ packages: console-control-strings@1.1.0: resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - content-disposition@1.1.0: - resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + content-disposition@2.0.1: + resolution: {integrity: sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==} engines: {node: '>=18'} cookie@1.1.1: @@ -1296,9 +1338,9 @@ packages: resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} hasBin: true esbuild@0.28.2: @@ -1445,9 +1487,6 @@ packages: fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} - fast-uri@3.1.4: - resolution: {integrity: sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==} - fast-uri@3.1.5: resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} @@ -1525,10 +1564,6 @@ packages: resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} engines: {node: '>= 6'} - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -1586,8 +1621,8 @@ packages: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} - 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 @@ -1763,8 +1798,14 @@ packages: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} - js-yaml@4.3.0: - resolution: {integrity: sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==} + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + js-yaml@4.3.2: + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} hasBin: true json-buffer@3.0.1: @@ -1937,26 +1978,13 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} mnemonist@0.40.0: resolution: {integrity: sha512-kdd8AFNig2AD5Rkih7EPCXhu/iMvwevQFX/uEiGhZyPZi7fHqOoF4V4kHLpCfysxXMgQ4B52kdPMCwARshKvEg==} @@ -1971,8 +1999,8 @@ packages: msgpackr@2.0.5: resolution: {integrity: sha512-cef05H/dSYpLpqp3sj/qyZh5vhUYCalnaLO7j1yOmpsR0y/XwLVtK7r5gn+U/F7CTEfMowcGhlUQJDLcLf7jcA==} - nanoid@3.3.16: - resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -2092,8 +2120,8 @@ packages: resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} engines: {node: 18 || 20 || >=22} - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} pathval@2.0.1: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} @@ -2394,6 +2422,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2402,10 +2433,9 @@ packages: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} - tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} - deprecated: Old versions of tar 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 + tar@7.5.22: + resolution: {integrity: sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==} + engines: {node: '>=18'} tdigest@0.1.2: resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==} @@ -2435,12 +2465,12 @@ packages: resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} engines: {node: ^18.0.0 || >=20.0.0} - tinyrainbow@1.2.0: - resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} engines: {node: '>=14.0.0'} - tinyspy@3.0.2: - resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} engines: {node: '>=14.0.0'} to-buffer@1.2.2: @@ -2527,27 +2557,32 @@ packages: deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true - vite-node@2.1.9: - resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} - engines: {node: ^18.0.0 || >=20.0.0} + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true - vite@5.4.21: - resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} - engines: {node: ^18.0.0 || >=20.0.0} + vite@6.4.3: + resolution: {integrity: sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || >=20.0.0 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' less: '*' lightningcss: ^1.21.0 sass: '*' sass-embedded: '*' stylus: '*' sugarss: '*' - terser: ^5.4.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 peerDependenciesMeta: '@types/node': optional: true + jiti: + optional: true less: optional: true lightningcss: @@ -2562,21 +2597,28 @@ packages: optional: true terser: optional: true + tsx: + optional: true + yaml: + optional: true - vitest@2.1.9: - resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} - engines: {node: ^18.0.0 || >=20.0.0} + vitest@3.2.7: + resolution: {integrity: sha512-KrxIJ62Fd89gfysR4WotlgZABiz2dqFPgqGzX7s+CwsqLFomRH7777ZcrOD6+WVAh7khPQP41A+BKbpcJFrdEg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@types/node': ^18.0.0 || >=20.0.0 - '@vitest/browser': 2.1.9 - '@vitest/ui': 2.1.9 + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.7 + '@vitest/ui': 3.2.7 happy-dom: '*' jsdom: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@types/debug': + optional: true '@types/node': optional: true '@vitest/browser': @@ -2633,8 +2675,9 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} @@ -2675,13 +2718,13 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@bcoe/v8-coverage@0.2.3': {} + '@bcoe/v8-coverage@1.0.2': {} '@boundaries/elements@1.2.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5)(typescript@5.9.3))(eslint@9.39.5)': dependencies: eslint-import-resolver-node: 0.3.9 eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.67.0(eslint@9.39.5)(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.39.5) - handlebars: 4.7.8 + handlebars: 4.7.9 is-core-module: 2.16.1 micromatch: 4.0.8 transitivePeerDependencies: @@ -2694,148 +2737,157 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@esbuild/aix-ppc64@0.21.5': + '@esbuild/aix-ppc64@0.25.12': optional: true '@esbuild/aix-ppc64@0.28.2': optional: true - '@esbuild/android-arm64@0.21.5': + '@esbuild/android-arm64@0.25.12': optional: true '@esbuild/android-arm64@0.28.2': optional: true - '@esbuild/android-arm@0.21.5': + '@esbuild/android-arm@0.25.12': optional: true '@esbuild/android-arm@0.28.2': optional: true - '@esbuild/android-x64@0.21.5': + '@esbuild/android-x64@0.25.12': optional: true '@esbuild/android-x64@0.28.2': optional: true - '@esbuild/darwin-arm64@0.21.5': + '@esbuild/darwin-arm64@0.25.12': optional: true '@esbuild/darwin-arm64@0.28.2': optional: true - '@esbuild/darwin-x64@0.21.5': + '@esbuild/darwin-x64@0.25.12': optional: true '@esbuild/darwin-x64@0.28.2': optional: true - '@esbuild/freebsd-arm64@0.21.5': + '@esbuild/freebsd-arm64@0.25.12': optional: true '@esbuild/freebsd-arm64@0.28.2': optional: true - '@esbuild/freebsd-x64@0.21.5': + '@esbuild/freebsd-x64@0.25.12': optional: true '@esbuild/freebsd-x64@0.28.2': optional: true - '@esbuild/linux-arm64@0.21.5': + '@esbuild/linux-arm64@0.25.12': optional: true '@esbuild/linux-arm64@0.28.2': optional: true - '@esbuild/linux-arm@0.21.5': + '@esbuild/linux-arm@0.25.12': optional: true '@esbuild/linux-arm@0.28.2': optional: true - '@esbuild/linux-ia32@0.21.5': + '@esbuild/linux-ia32@0.25.12': optional: true '@esbuild/linux-ia32@0.28.2': optional: true - '@esbuild/linux-loong64@0.21.5': + '@esbuild/linux-loong64@0.25.12': optional: true '@esbuild/linux-loong64@0.28.2': optional: true - '@esbuild/linux-mips64el@0.21.5': + '@esbuild/linux-mips64el@0.25.12': optional: true '@esbuild/linux-mips64el@0.28.2': optional: true - '@esbuild/linux-ppc64@0.21.5': + '@esbuild/linux-ppc64@0.25.12': optional: true '@esbuild/linux-ppc64@0.28.2': optional: true - '@esbuild/linux-riscv64@0.21.5': + '@esbuild/linux-riscv64@0.25.12': optional: true '@esbuild/linux-riscv64@0.28.2': optional: true - '@esbuild/linux-s390x@0.21.5': + '@esbuild/linux-s390x@0.25.12': optional: true '@esbuild/linux-s390x@0.28.2': optional: true - '@esbuild/linux-x64@0.21.5': + '@esbuild/linux-x64@0.25.12': optional: true '@esbuild/linux-x64@0.28.2': optional: true + '@esbuild/netbsd-arm64@0.25.12': + optional: true + '@esbuild/netbsd-arm64@0.28.2': optional: true - '@esbuild/netbsd-x64@0.21.5': + '@esbuild/netbsd-x64@0.25.12': optional: true '@esbuild/netbsd-x64@0.28.2': optional: true + '@esbuild/openbsd-arm64@0.25.12': + optional: true + '@esbuild/openbsd-arm64@0.28.2': optional: true - '@esbuild/openbsd-x64@0.21.5': + '@esbuild/openbsd-x64@0.25.12': optional: true '@esbuild/openbsd-x64@0.28.2': optional: true + '@esbuild/openharmony-arm64@0.25.12': + optional: true + '@esbuild/openharmony-arm64@0.28.2': optional: true - '@esbuild/sunos-x64@0.21.5': + '@esbuild/sunos-x64@0.25.12': optional: true '@esbuild/sunos-x64@0.28.2': optional: true - '@esbuild/win32-arm64@0.21.5': + '@esbuild/win32-arm64@0.25.12': optional: true '@esbuild/win32-arm64@0.28.2': optional: true - '@esbuild/win32-ia32@0.21.5': + '@esbuild/win32-ia32@0.25.12': optional: true '@esbuild/win32-ia32@0.28.2': optional: true - '@esbuild/win32-x64@0.21.5': + '@esbuild/win32-x64@0.25.12': optional: true '@esbuild/win32-x64@0.28.2': @@ -2872,7 +2924,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.3.0 + js-yaml: 4.3.2 minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -2936,18 +2988,19 @@ snapshots: http-errors: 2.0.1 mime: 3.0.0 - '@fastify/static@9.3.0': + '@fastify/static@10.1.3': dependencies: '@fastify/accept-negotiator': 2.0.1 + '@fastify/error': 4.2.0 '@fastify/send': 4.1.0 - content-disposition: 1.1.0 + content-disposition: 2.0.1 fastify-plugin: 6.0.0 fastq: 1.20.1 glob: 13.0.6 '@fastify/swagger-ui@5.2.6': dependencies: - '@fastify/static': 9.3.0 + '@fastify/static': 10.1.3 fastify-plugin: 5.1.0 openapi-types: 12.1.3 rfdc: 1.4.1 @@ -2990,6 +3043,10 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + '@istanbuljs/schema@0.1.6': {} '@jridgewell/gen-mapping@0.3.13': @@ -3018,7 +3075,7 @@ snapshots: npmlog: 5.0.1 rimraf: 3.0.2 semver: 7.8.5 - tar: 6.2.1 + tar: 7.5.22 transitivePeerDependencies: - encoding - supports-color @@ -3189,6 +3246,13 @@ snapshots: dependencies: '@types/node': 22.20.1 + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/deep-eql@4.0.2': {} + '@types/estree@1.0.9': {} '@types/json-schema@7.0.15': {} @@ -3295,10 +3359,11 @@ snapshots: '@typescript-eslint/types': 8.67.0 eslint-visitor-keys: 5.0.1 - '@vitest/coverage-v8@2.1.9(vitest@2.1.9(@types/node@22.20.1))': + '@vitest/coverage-v8@3.2.7(vitest@3.2.7(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@ampproject/remapping': 2.3.0 - '@bcoe/v8-coverage': 0.2.3 + '@bcoe/v8-coverage': 1.0.2 + ast-v8-to-istanbul: 0.3.12 debug: 4.4.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -3308,50 +3373,52 @@ snapshots: magicast: 0.3.5 std-env: 3.10.0 test-exclude: 7.0.2 - tinyrainbow: 1.2.0 - vitest: 2.1.9(@types/node@22.20.1) + tinyrainbow: 2.0.0 + vitest: 3.2.7(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - supports-color - '@vitest/expect@2.1.9': + '@vitest/expect@3.2.7': dependencies: - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.7 + '@vitest/utils': 3.2.7 chai: 5.3.3 - tinyrainbow: 1.2.0 + tinyrainbow: 2.0.0 - '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.20.1))': + '@vitest/mocker@3.2.7(vite@6.4.3(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@vitest/spy': 2.1.9 + '@vitest/spy': 3.2.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 5.4.21(@types/node@22.20.1) + vite: 6.4.3(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0) - '@vitest/pretty-format@2.1.9': + '@vitest/pretty-format@3.2.7': dependencies: - tinyrainbow: 1.2.0 + tinyrainbow: 2.0.0 - '@vitest/runner@2.1.9': + '@vitest/runner@3.2.7': dependencies: - '@vitest/utils': 2.1.9 - pathe: 1.1.2 + '@vitest/utils': 3.2.7 + pathe: 2.0.3 + strip-literal: 3.1.0 - '@vitest/snapshot@2.1.9': + '@vitest/snapshot@3.2.7': dependencies: - '@vitest/pretty-format': 2.1.9 + '@vitest/pretty-format': 3.2.7 magic-string: 0.30.21 - pathe: 1.1.2 + pathe: 2.0.3 - '@vitest/spy@2.1.9': + '@vitest/spy@3.2.7': dependencies: - tinyspy: 3.0.2 + tinyspy: 4.0.4 - '@vitest/utils@2.1.9': + '@vitest/utils@3.2.7': dependencies: - '@vitest/pretty-format': 2.1.9 + '@vitest/pretty-format': 3.2.7 loupe: 3.2.1 - tinyrainbow: 1.2.0 + tinyrainbow: 2.0.0 abbrev@1.1.1: {} @@ -3416,6 +3483,12 @@ snapshots: assertion-error@2.0.1: {} + ast-v8-to-istanbul@0.3.12: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + estree-walker: 3.0.3 + js-tokens: 10.0.0 + asynckit@0.4.0: {} atomic-sleep@1.0.0: {} @@ -3579,7 +3652,7 @@ snapshots: check-error@2.1.3: {} - chownr@2.0.0: {} + chownr@3.0.0: {} cli-cursor@5.0.0: dependencies: @@ -3620,7 +3693,7 @@ snapshots: console-control-strings@1.1.0: {} - content-disposition@1.1.0: {} + content-disposition@2.0.1: {} cookie@1.1.1: {} @@ -3709,31 +3782,34 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.4 - esbuild@0.21.5: + esbuild@0.25.12: optionalDependencies: - '@esbuild/aix-ppc64': 0.21.5 - '@esbuild/android-arm': 0.21.5 - '@esbuild/android-arm64': 0.21.5 - '@esbuild/android-x64': 0.21.5 - '@esbuild/darwin-arm64': 0.21.5 - '@esbuild/darwin-x64': 0.21.5 - '@esbuild/freebsd-arm64': 0.21.5 - '@esbuild/freebsd-x64': 0.21.5 - '@esbuild/linux-arm': 0.21.5 - '@esbuild/linux-arm64': 0.21.5 - '@esbuild/linux-ia32': 0.21.5 - '@esbuild/linux-loong64': 0.21.5 - '@esbuild/linux-mips64el': 0.21.5 - '@esbuild/linux-ppc64': 0.21.5 - '@esbuild/linux-riscv64': 0.21.5 - '@esbuild/linux-s390x': 0.21.5 - '@esbuild/linux-x64': 0.21.5 - '@esbuild/netbsd-x64': 0.21.5 - '@esbuild/openbsd-x64': 0.21.5 - '@esbuild/sunos-x64': 0.21.5 - '@esbuild/win32-arm64': 0.21.5 - '@esbuild/win32-ia32': 0.21.5 - '@esbuild/win32-x64': 0.21.5 + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 esbuild@0.28.2: optionalDependencies: @@ -3923,8 +3999,6 @@ snapshots: fast-safe-stringify@2.1.1: {} - fast-uri@3.1.4: {} - fast-uri@3.1.5: {} fast-uri@4.1.2: {} @@ -4011,10 +4085,6 @@ snapshots: hasown: 2.0.4 mime-types: 2.1.35 - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -4088,7 +4158,7 @@ snapshots: gopd@1.2.0: {} - handlebars@4.7.8: + handlebars@4.7.9: dependencies: minimist: 1.2.8 neo-async: 2.6.2 @@ -4257,7 +4327,11 @@ snapshots: joycon@3.1.1: {} - js-yaml@4.3.0: + js-tokens@10.0.0: {} + + js-tokens@9.0.1: {} + + js-yaml@4.3.2: dependencies: argparse: 2.0.1 @@ -4270,7 +4344,7 @@ snapshots: json-schema-resolver@3.0.0: dependencies: debug: 4.4.3 - fast-uri: 3.1.4 + fast-uri: 3.1.5 rfdc: 1.4.1 transitivePeerDependencies: - supports-color @@ -4443,20 +4517,11 @@ snapshots: minimist@1.2.8: {} - minipass@3.3.6: - dependencies: - yallist: 4.0.0 - - minipass@5.0.0: {} - minipass@7.1.3: {} - minizlib@2.1.2: + minizlib@3.1.0: dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - - mkdirp@1.0.4: {} + minipass: 7.1.3 mnemonist@0.40.0: dependencies: @@ -4480,7 +4545,7 @@ snapshots: optionalDependencies: msgpackr-extract: 3.0.4 - nanoid@3.3.16: {} + nanoid@3.3.18: {} natural-compare@1.4.0: {} @@ -4581,7 +4646,7 @@ snapshots: lru-cache: 11.5.2 minipass: 7.1.3 - pathe@1.1.2: {} + pathe@2.0.3: {} pathval@2.0.1: {} @@ -4634,7 +4699,7 @@ snapshots: postcss@8.5.25: dependencies: - nanoid: 3.3.16 + nanoid: 3.3.18 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -4888,20 +4953,23 @@ snapshots: strip-json-comments@3.1.1: {} + strip-literal@3.1.0: + dependencies: + js-tokens: 9.0.1 + supports-color@7.2.0: dependencies: has-flag: 4.0.0 supports-preserve-symlinks-flag@1.0.0: {} - tar@6.2.1: + tar@7.5.22: dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 tdigest@0.1.2: dependencies: @@ -4930,9 +4998,9 @@ snapshots: tinypool@1.1.1: {} - tinyrainbow@1.2.0: {} + tinyrainbow@2.0.0: {} - tinyspy@3.0.2: {} + tinyspy@4.0.4: {} to-buffer@1.2.2: dependencies: @@ -5006,15 +5074,16 @@ snapshots: uuid@8.3.2: {} - vite-node@2.1.9(@types/node@22.20.1): + vite-node@3.2.4(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 - pathe: 1.1.2 - vite: 5.4.21(@types/node@22.20.1) + pathe: 2.0.3 + vite: 6.4.3(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0) transitivePeerDependencies: - '@types/node' + - jiti - less - lightningcss - sass @@ -5023,41 +5092,52 @@ snapshots: - sugarss - supports-color - terser + - tsx + - yaml - vite@5.4.21(@types/node@22.20.1): + vite@6.4.3(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0): dependencies: - esbuild: 0.21.5 + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 postcss: 8.5.25 rollup: 4.62.3 + tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.1 fsevents: 2.3.3 + tsx: 4.23.12 + yaml: 2.9.0 - vitest@2.1.9(@types/node@22.20.1): + vitest@3.2.7(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0): dependencies: - '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.20.1)) - '@vitest/pretty-format': 2.1.9 - '@vitest/runner': 2.1.9 - '@vitest/snapshot': 2.1.9 - '@vitest/spy': 2.1.9 - '@vitest/utils': 2.1.9 + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.7 + '@vitest/mocker': 3.2.7(vite@6.4.3(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0)) + '@vitest/pretty-format': 3.2.7 + '@vitest/runner': 3.2.7 + '@vitest/snapshot': 3.2.7 + '@vitest/spy': 3.2.7 + '@vitest/utils': 3.2.7 chai: 5.3.3 debug: 4.4.3 expect-type: 1.4.0 magic-string: 0.30.21 - pathe: 1.1.2 + pathe: 2.0.3 + picomatch: 4.0.5 std-env: 3.10.0 tinybench: 2.9.0 tinyexec: 0.3.2 + tinyglobby: 0.2.17 tinypool: 1.1.1 - tinyrainbow: 1.2.0 - vite: 5.4.21(@types/node@22.20.1) - vite-node: 2.1.9(@types/node@22.20.1) + tinyrainbow: 2.0.0 + vite: 6.4.3(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0) + vite-node: 3.2.4(@types/node@22.20.1)(tsx@4.23.12)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.20.1 transitivePeerDependencies: + - jiti - less - lightningcss - msw @@ -5067,6 +5147,8 @@ snapshots: - sugarss - supports-color - terser + - tsx + - yaml webidl-conversions@3.0.1: {} @@ -5122,7 +5204,7 @@ snapshots: wrappy@1.0.2: {} - yallist@4.0.0: {} + yallist@5.0.0: {} yaml@2.9.0: {} diff --git a/src/modules/auth/interface/schemas.spec.ts b/src/modules/auth/interface/schemas.spec.ts new file mode 100644 index 0000000..bd13389 --- /dev/null +++ b/src/modules/auth/interface/schemas.spec.ts @@ -0,0 +1,40 @@ +import { describe, expect, it } from 'vitest'; + +import { registerBodySchema, resetPasswordBodySchema } from './schemas.js'; + +describe('auth password schema (byte-accurate max length)', () => { + it('accepts a 72-byte pure-ASCII password', () => { + const password = 'a'.repeat(72); + expect(Buffer.byteLength(password, 'utf8')).toBe(72); + + const result = registerBodySchema.safeParse({ email: 'user@example.com', password }); + expect(result.success).toBe(true); + }); + + it('rejects a password under 72 JS characters but over 72 UTF-8 bytes', () => { + // 20 emoji: 40 UTF-16 code units (well under a naive .max(72)) but + // 80 UTF-8 bytes — bcrypt would silently truncate this. + const password = '😀'.repeat(20); + expect(password.length).toBeLessThan(72); + expect(Buffer.byteLength(password, 'utf8')).toBeGreaterThan(72); + + const result = registerBodySchema.safeParse({ email: 'user@example.com', password }); + expect(result.success).toBe(false); + expect(result.success ? [] : result.error.issues.map((i) => i.message)).toContain( + 'Password must be at most 72 bytes long', + ); + }); + + it('applies the same byte-accurate bound to resetPasswordBodySchema.newPassword', () => { + const result = resetPasswordBodySchema.safeParse({ + token: 'reset-token', + newPassword: '😀'.repeat(20), + }); + expect(result.success).toBe(false); + }); + + it('still rejects passwords shorter than 8 characters', () => { + const result = registerBodySchema.safeParse({ email: 'user@example.com', password: 'short' }); + expect(result.success).toBe(false); + }); +}); diff --git a/src/modules/auth/interface/schemas.ts b/src/modules/auth/interface/schemas.ts index 6fa9180..12eca06 100644 --- a/src/modules/auth/interface/schemas.ts +++ b/src/modules/auth/interface/schemas.ts @@ -1,7 +1,17 @@ import { z } from 'zod'; const email = z.string().trim().toLowerCase().email(); -const password = z.string().min(8).max(72); // bcrypt silently truncates beyond 72 bytes +// bcrypt truncates silently beyond 72 *bytes* (not characters — see the +// bcrypt package README). Zod's `.max()` counts UTF-16 code units, so a +// password with multi-byte UTF-8 characters (emoji, many non-Latin scripts) +// can sit under a 72-character limit while still exceeding 72 bytes and +// being silently truncated. Enforce the real byte boundary instead. +const password = z + .string() + .min(8) + .refine((value) => Buffer.byteLength(value, 'utf8') <= 72, { + message: 'Password must be at most 72 bytes long', + }); export const registerBodySchema = z.object({ email, diff --git a/src/modules/deliveries/interface/schemas.ts b/src/modules/deliveries/interface/schemas.ts index 11021c9..2efd521 100644 --- a/src/modules/deliveries/interface/schemas.ts +++ b/src/modules/deliveries/interface/schemas.ts @@ -1,6 +1,10 @@ import { z } from 'zod'; +import { chainId } from '../../../shared/validation/chain-id.js'; import { stellarAddress } from '../../../shared/validation/stellar-address.js'; -const chainDeliveryId = z.string().regex(/^\d+$/, 'Must be a non-negative integer string'); + +export { transactionResponseSchema } from '../../../shared/validation/transaction-response.js'; + +const chainDeliveryId = chainId; const cargoCategory = z.enum(['DOCUMENTS', 'ELECTRONICS', 'PERISHABLES', 'CLOTHING', 'GENERAL']); const deliveryStatus = z.enum([ 'PENDING', @@ -39,8 +43,6 @@ export const listDeliveriesResponseSchema = z.object({ data: z.array(deliveryDto export const deliveryIdParamsSchema = z.object({ chainDeliveryId }); export const getDeliveryResponseSchema = z.object({ data: deliveryDto }); -export const transactionResponseSchema = z.object({ data: z.object({ xdr: z.string() }) }); - export const createDeliveryBodySchema = z.object({ senderAddress: stellarAddress, recipientAddress: stellarAddress, diff --git a/src/modules/disputes/interface/schemas.ts b/src/modules/disputes/interface/schemas.ts index 37bcee7..83cf230 100644 --- a/src/modules/disputes/interface/schemas.ts +++ b/src/modules/disputes/interface/schemas.ts @@ -1,6 +1,10 @@ import { z } from 'zod'; +import { chainId } from '../../../shared/validation/chain-id.js'; import { stellarAddress } from '../../../shared/validation/stellar-address.js'; -const chainDeliveryId = z.string().regex(/^\d+$/, 'Must be a non-negative integer string'); + +export { transactionResponseSchema } from '../../../shared/validation/transaction-response.js'; + +const chainDeliveryId = chainId; const evidenceHash = z.string().regex(/^[0-9a-f]{64}$/, 'Must be a 32-byte hex-encoded hash'); const disputeStatus = z.enum(['OPEN', 'RESOLVED_REFUND', 'RESOLVED_PAYOUT', 'SPLIT']); @@ -43,8 +47,6 @@ const disputeDto = z.object({ export const disputeIdParamsSchema = z.object({ chainDeliveryId }); export const getDisputeResponseSchema = z.object({ data: disputeDto }); -export const transactionResponseSchema = z.object({ data: z.object({ xdr: z.string() }) }); - export const raiseDisputeBodySchema = z.object({ callerAddress: stellarAddress, chainDeliveryId, diff --git a/src/modules/escrow/interface/schemas.ts b/src/modules/escrow/interface/schemas.ts index 01ae2d7..5d88ff9 100644 --- a/src/modules/escrow/interface/schemas.ts +++ b/src/modules/escrow/interface/schemas.ts @@ -1,6 +1,12 @@ import { z } from 'zod'; +import { chainId } from '../../../shared/validation/chain-id.js'; import { stellarAddress } from '../../../shared/validation/stellar-address.js'; -const chainDeliveryId = z.string().regex(/^\d+$/, 'Must be a non-negative integer string'); + +export { transactionResponseSchema } from '../../../shared/validation/transaction-response.js'; + +const chainDeliveryId = chainId; +// Module-specific: a token amount that happens to share the digit-string +// shape of `chainId` but is a distinct concept — kept local by design. const amount = z.string().regex(/^\d+$/, 'Must be a non-negative integer string'); const escrowStatus = z.enum(['LOCKED', 'RELEASED', 'REFUNDED', 'PAUSED']); @@ -24,8 +30,6 @@ const escrowDto = z.object({ export const escrowIdParamsSchema = z.object({ chainDeliveryId }); export const getEscrowResponseSchema = z.object({ data: escrowDto }); -export const transactionResponseSchema = z.object({ data: z.object({ xdr: z.string() }) }); - export const createEscrowBodySchema = z.object({ senderAddress: stellarAddress, recipientAddress: stellarAddress, diff --git a/src/modules/fleet/interface/schemas.ts b/src/modules/fleet/interface/schemas.ts index 360b7b4..52b5a4a 100644 --- a/src/modules/fleet/interface/schemas.ts +++ b/src/modules/fleet/interface/schemas.ts @@ -1,6 +1,10 @@ import { z } from 'zod'; +import { chainId } from '../../../shared/validation/chain-id.js'; import { stellarAddress } from '../../../shared/validation/stellar-address.js'; -const chainFleetId = z.string().regex(/^\d+$/, 'Must be a non-negative integer string'); + +export { transactionResponseSchema } from '../../../shared/validation/transaction-response.js'; + +const chainFleetId = chainId; const fleetDriverStatus = z.enum(['PENDING', 'ACTIVE']); const fleetDriverDto = z.object({ @@ -49,8 +53,6 @@ export const payoutAddressResponseSchema = z.object({ data: z.object({ payoutAddress: z.string() }), }); -export const transactionResponseSchema = z.object({ data: z.object({ xdr: z.string() }) }); - export const registerFleetBodySchema = z.object({ ownerAddress: stellarAddress, treasuryAddress: stellarAddress, diff --git a/src/modules/reputation/interface/schemas.ts b/src/modules/reputation/interface/schemas.ts index fd88ca0..ce85f48 100644 --- a/src/modules/reputation/interface/schemas.ts +++ b/src/modules/reputation/interface/schemas.ts @@ -1,6 +1,8 @@ import { z } from 'zod'; import { stellarAddress } from '../../../shared/validation/stellar-address.js'; +export { transactionResponseSchema } from '../../../shared/validation/transaction-response.js'; + const driverTier = z.enum(['BRONZE', 'SILVER', 'GOLD']); const driverProfileDto = z.object({ @@ -17,8 +19,6 @@ const driverProfileDto = z.object({ export const driverAddressParamsSchema = z.object({ address: stellarAddress }); export const getDriverProfileResponseSchema = z.object({ data: driverProfileDto }); -export const transactionResponseSchema = z.object({ data: z.object({ xdr: z.string() }) }); - export const registerDriverBodySchema = z.object({ driverAddress: stellarAddress, }); diff --git a/src/shared/validation/chain-id.ts b/src/shared/validation/chain-id.ts new file mode 100644 index 0000000..eb300cd --- /dev/null +++ b/src/shared/validation/chain-id.ts @@ -0,0 +1,13 @@ +import { z } from 'zod'; + +/** + * An on-chain numeric identifier as it arrives over HTTP: always a string, + * always a bare non-negative integer (no sign, leading `+`, decimal point or + * whitespace). + * + * Named generically because the identical shape backs `chainDeliveryId` + * (deliveries, disputes, escrow) and `chainFleetId` (fleet) — it was + * previously redefined character-for-character in each of those modules' + * `interface/schemas.ts`. + */ +export const chainId = z.string().regex(/^\d+$/, 'Must be a non-negative integer string'); diff --git a/src/shared/validation/transaction-response.ts b/src/shared/validation/transaction-response.ts new file mode 100644 index 0000000..548c50d --- /dev/null +++ b/src/shared/validation/transaction-response.ts @@ -0,0 +1,11 @@ +import { z } from 'zod'; + +/** + * Standard response envelope for every endpoint that returns an unsigned + * Soroban transaction for the client to sign: `{ data: { xdr } }`. + * + * Previously redefined verbatim in the deliveries, disputes, escrow, fleet + * and reputation modules' `interface/schemas.ts`; defined once here so a + * future change to the envelope applies everywhere at once. + */ +export const transactionResponseSchema = z.object({ data: z.object({ xdr: z.string() }) });