diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index de640c47..56141c94 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -209,7 +209,8 @@ jobs: set -euo pipefail export PATH="$GITHUB_WORKSPACE/tooling/node_modules/.bin:$PATH" - if [[ "$(vercel --version)" != "58.4.4" ]]; then + trusted_vercel="$(node -p 'require(process.argv[1]).devDependencies.vercel' "$GITHUB_WORKSPACE/tooling/package.json")" + if [[ "$(vercel --version)" != "$trusted_vercel" ]]; then echo "Trusted Vercel CLI version mismatch." >&2 exit 1 fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bbd0c68..1fa70d43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to BetterMan are documented here. ## Unreleased +- Supply chain: check the OSV `sandbox` exceptions against the advisories' `<1.0.0` range, the Vercel CLI dependency path, and a one-year expiry cap instead of a pinned Vercel CLI version, and read the production deploy guard's expected CLI version from the trusted tooling manifest that `deps:provenance` verifies. A Vercel CLI bump now needs only manifest changes once an attested release exists; the SLSA provenance gate is unchanged, and no Vercel CLI release after 58.4.4 has provenance yet. - Security: validate, rate-limit, and bound dynamic man-page share image inputs, and return 404 without rendering for missing pages. - Security: key public API rate limits on the Vercel-overwritten client address instead of spoofable `CF-Connecting-IP` / `X-Forwarded-For` headers, and share an anonymous bucket when no trusted identity is present. - Maintenance: add a manual `prune-releases` workflow that previews by default and deletes superseded inactive releases in bounded, retried batches, retaining the newest verified release per distro as a rollback target and sweeping orphaned content blobs; release pruning and the orphan sweep now also delete their stored payload files, and the inactive-release preview paginates and reports rollback eligibility. diff --git a/docs/runbooks/vercel-ops.md b/docs/runbooks/vercel-ops.md index eb6b8399..aae9a4c8 100644 --- a/docs/runbooks/vercel-ops.md +++ b/docs/runbooks/vercel-ops.md @@ -17,7 +17,7 @@ Also set the public `CONVEX_URL` GitHub environment variable to the production ` 2. `.github/workflows/ci.yml` runs the complete test/build/security matrix. 3. A non-cancelable `workflow_run` in `.github/workflows/deploy.yml` accepts only a successful `push` CI result for `main`, checks out its exact `head_sha`, and confirms that SHA is still current `main` before changing the backend. 4. Under the repository's Node 26 tooling contract, the workflow deploys that exact SHA's Convex schema/functions, then checks production release data, search, page content, and metadata functions. Convex changes must remain backward-compatible with the currently promoted frontend during this handoff. -5. The workflow switches to the Vercel project's Node 24 build/runtime contract, uses pinned Vercel CLI `58.4.4`, and runs `scripts/deploy-vercel.sh` from the repository root. Vercel applies the project's `nextjs` root directory exactly once. The script pulls production settings, builds the artifact, and creates a production-targeted deployment with `--skip-domain`, leaving the current site live. +5. The workflow switches to the Vercel project's Node 24 build/runtime contract, uses the exact Vercel CLI version pinned in the trusted tooling checkout's `package.json` (the version `pnpm deps:provenance` just verified), and runs `scripts/deploy-vercel.sh` from the repository root. Vercel applies the project's `nextjs` root directory exactly once. The script pulls production settings, builds the artifact, and creates a production-targeted deployment with `--skip-domain`, leaving the current site live. 6. It requires the staged deployment to pass all of the following: - deployment state is `READY`; - deployment metadata SHA equals the checked-out `main` SHA; @@ -79,20 +79,36 @@ passed to the CLI. Sigstore verification additionally requires the exact release workflow certificate identity on `main` and the GitHub Actions OIDC issuer. Missing attestations fail even if registry signatures pass. Operational contract tests also require the gate to run unconditionally after -installation and before deployment-secret exposure, using the exact trusted CLI -pin. Dependabot vulnerability alerts and weekly update PRs remain enabled; an -upgrade cannot silently bypass the same provenance and dependency-review gates. +installation and before deployment-secret exposure, and require the deploy step +to refuse any `vercel --version` other than the exact pin in the trusted tooling +`package.json` that the gate verified. Dependabot vulnerability alerts and weekly +update PRs remain enabled; an upgrade cannot silently bypass the same provenance +and dependency-review gates. -The CLI is pinned to 58.4.4, the newest attested stable release observed on -September 7, 2026. Its verified source commit is +58.4.4 is the newest attested stable release. Its verified source commit is `6331571e2fe14de31a01d00deead9e7a349e53a6`. Vercel moved later CLI publication to -private source; see https://github.com/vercel/vercel/issues/17408. Version 59.10.0 -had registry signatures but no provenance, and its vendor integrity endpoint -returned 404. That is not evidence of compromise, but does not meet this gate. +private source; see https://github.com/vercel/vercel/issues/17408. npm does not +generate provenance for publishes from a private repository, so every release +from 58.5.1 onward has registry signatures but no attestation (rechecked through +63.1.2 on October 10, 2026). Vercel's suggested substitute, comparing +`https://vercel.com/docs/cli/release-notes/npm//integrity` with npm's +`dist.integrity`, is an unsigned vendor assertion with no source binding, and it +lags releases (59.10.0 returned 404 on September 7; 63.1.1 and 63.1.2 returned +404 on October 10). That is not evidence of compromise, but does not meet this +gate. Do not remove the provenance gate to accept an automated upgrade. Re-evaluate the pin when attested releases become available, or explicitly review an alternative verification policy if security or compatibility fixes require it. +The Vercel CLI depends on Vercel's `sandbox` package, which osv-scanner matches +against two advisories for the unrelated legacy `sandbox` package below 1.0.0. +The exceptions in `osv-scanner.toml` are checked against that range, not the CLI +version: `scripts/check-osv-exceptions.mjs` fails if the lockfile gains a +`sandbox` release below 1.0.0 (or a prerelease), reaches `sandbox` through +anything other than the root Vercel CLI dependency, or no longer contains +`sandbox` at all. Each exception must expire between 30 days and one year out. +A CLI upgrade that keeps these conditions needs no exception edit. + ## Manual deployment or rollback Run `.github/workflows/deploy.yml` (`deploy-vercel`) from the default `main` workflow definition with a full lowercase 40-character commit SHA. The no-secret validation job requires that commit to be reachable from protected `main`. The deploy job checks out current trusted deployment tooling separately from the selected application revision. It does not roll Convex functions backward: the current production contract is checked first, then the historical app receives the same build, metadata, smoke, promotion, alias, and rollback gates. Only select revisions compatible with the current Convex API. diff --git a/osv-scanner.toml b/osv-scanner.toml index 6e3b02e5..5e8cf4c3 100644 --- a/osv-scanner.toml +++ b/osv-scanner.toml @@ -1,9 +1,9 @@ [[IgnoredVulns]] id = "GHSA-fm4j-4xhm-xpwx" ignoreUntil = 2027-08-03 -reason = "Rechecked 2026-09-07 for attested Vercel CLI 58.4.4: OSV has no fixed event for the legacy sandbox package, but GitHub bounds the affected range below 1.0.0; this lockfile contains Vercel's unrelated sandbox@3.4.0 package from vercel/sandbox. See https://github.com/advisories/GHSA-fm4j-4xhm-xpwx." +reason = "Rechecked 2026-10-10: GitHub bounds this advisory to the legacy sandbox package below 1.0.0, but OSV has no fixed event, so osv-scanner flags every version. The only sandbox in this lockfile is Vercel's unrelated vercel/sandbox package (1.0.0 and later), pulled in by the Vercel CLI; scripts/check-osv-exceptions.mjs fails if a sandbox release below 1.0.0 or any other dependency path appears. See https://github.com/advisories/GHSA-fm4j-4xhm-xpwx." [[IgnoredVulns]] id = "GHSA-gc25-3vc5-2jf9" ignoreUntil = 2027-08-03 -reason = "Rechecked 2026-09-07 for attested Vercel CLI 58.4.4: OSV has no fixed event for the legacy sandbox package, but GitHub bounds the affected range below 1.0.0; this lockfile contains Vercel's unrelated sandbox@3.4.0 package from vercel/sandbox. See https://github.com/advisories/GHSA-gc25-3vc5-2jf9." +reason = "Rechecked 2026-10-10: GitHub bounds this advisory to the legacy sandbox package below 1.0.0, but OSV has no fixed event, so osv-scanner flags every version. The only sandbox in this lockfile is Vercel's unrelated vercel/sandbox package (1.0.0 and later), pulled in by the Vercel CLI; scripts/check-osv-exceptions.mjs fails if a sandbox release below 1.0.0 or any other dependency path appears. See https://github.com/advisories/GHSA-gc25-3vc5-2jf9." diff --git a/package.json b/package.json index 014b1136..17ccd362 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "convex:prod-check": "node scripts/check-convex-production.mjs", "convex:related-check": "node scripts/check-related-metadata.mjs", "convex:prune-releases": "node scripts/prune-inactive-releases.mjs", - "ops:test": "node --test scripts/check-related-metadata.test.mjs scripts/check-vercel-provenance.test.mjs scripts/prune-inactive-releases.test.mjs", + "ops:test": "node --test scripts/check-osv-exceptions.test.mjs scripts/check-related-metadata.test.mjs scripts/check-vercel-provenance.test.mjs scripts/prune-inactive-releases.test.mjs", "deps:provenance": "node scripts/check-vercel-provenance.mjs", "next:dev": "convex dev --start \"pnpm -C nextjs dev\"", "next:build": "pnpm -C nextjs build", @@ -32,7 +32,7 @@ "convex-test": "0.0.60", "sigstore": "5.0.0", "typescript": "6.0.3", - "vercel": "58.4.4", + "vercel": "62.2.0", "vite": "8.3.2", "vitest": "5.0.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 71c6db71..17414612 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -58,8 +58,8 @@ importers: specifier: 6.0.3 version: 6.0.3 vercel: - specifier: 58.4.4 - version: 58.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5) + specifier: 62.2.0 + version: 62.2.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5) vite: specifier: 8.3.2 version: 8.3.2(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.21.0) @@ -846,6 +846,13 @@ packages: '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 + '@napi-rs/wasm-runtime@1.2.4': + resolution: {integrity: sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 + '@next/env@16.3.8': resolution: {integrity: sha512-Al9zqHVV7TJv0eFuOU4U7Lvv74PTih4Ch63sk2xCIpSTkE3udFnaOcnzP2lQVymiL7yS9Cj2iClUXlR3EQ5sEw==} @@ -936,48 +943,97 @@ packages: resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} + '@oxc-parser/binding-android-arm-eabi@0.121.0': + resolution: {integrity: sha512-n07FQcySwOlzap424/PLMtOkbS7xOu8nsJduKL8P3COGHKgKoDYXwoAHCbChfgFpHnviehrLWIPX0lKGtbEk/A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + '@oxc-parser/binding-android-arm-eabi@0.143.0': resolution: {integrity: sha512-n9uozULWflPqBtdmI8lAabLqGKNgLVNN0ZH8HfgCwpKGNtzRzauB76jTiW/3YLkcA7N1zskpi9GdVnZuu1SAvg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] + '@oxc-parser/binding-android-arm64@0.121.0': + resolution: {integrity: sha512-/Dd1xIXboYAicw+twT2utxPD7bL8qh7d3ej0qvaYIMj3/EgIrGR+tSnjCUkiCT6g6uTC0neSS4JY8LxhdSU/sA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@oxc-parser/binding-android-arm64@0.143.0': resolution: {integrity: sha512-9BbdjHETk6O3zH/DDid9IgBtF0GlpLabNKN231uraXpRDSfY+iiZxTP5bk1Z63GBownVdhdINFIeddmMz4MzpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] + '@oxc-parser/binding-darwin-arm64@0.121.0': + resolution: {integrity: sha512-A0jNEvv7QMtCO1yk205t3DWU9sWUjQ2KNF0hSVO5W9R9r/R1BIvzG01UQAfmtC0dQm7sCrs5puixurKSfr2bRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@oxc-parser/binding-darwin-arm64@0.143.0': resolution: {integrity: sha512-gh+6ecoHUy4/sUcolBl/1qPXKBbYNxFY0Pk0ujgQvINTMSftJY7o4yb8gOkDJPeZeB8+a+u7xTe6umoP8N5HFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@oxc-parser/binding-darwin-x64@0.121.0': + resolution: {integrity: sha512-SsHzipdxTKUs3I9EOAPmnIimEeJOemqRlRDOp9LIj+96wtxZejF51gNibmoGq8KoqbT1ssAI5po/E3J+vEtXGA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@oxc-parser/binding-darwin-x64@0.143.0': resolution: {integrity: sha512-qd1hl2d+lXgHv/VQ/M9qm8TrMC5T4RqDBwtOnl+1D0QMjwcz+8AaB4JSg8STgeag0GP6a6L74XEGAsrTSJWNzQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@oxc-parser/binding-freebsd-x64@0.121.0': + resolution: {integrity: sha512-v1APOTkCp+RWOIDAHRoaeW/UoaHF15a60E8eUL6kUQXh+i4K7PBwq2Wi7jm8p0ymID5/m/oC1w3W31Z/+r7HQw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@oxc-parser/binding-freebsd-x64@0.143.0': resolution: {integrity: sha512-M5XXcNa7aOqLPKTR41msfghKu2yQ4xWvCm11/gwU0JzOzHNk5sgW//rVEjJ+LO48+VDAMzXTSzurUVxIDKwozw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@oxc-parser/binding-linux-arm-gnueabihf@0.121.0': + resolution: {integrity: sha512-PmqPQuqHZyFVWA4ycr0eu4VnTMmq9laOHZd+8R359w6kzuNZPvmmunmNJ8ybkm769A0nCoVp3TJ6dUz7B3FYIQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@oxc-parser/binding-linux-arm-gnueabihf@0.143.0': resolution: {integrity: sha512-T/GXusuOkPNQhCQCSBbcU/N8j0rAypuDBl1IyFK+lyYT594XsVz80clPC/OtbSSpBGyJxj8uYEfctxVuxVYoww==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@oxc-parser/binding-linux-arm-musleabihf@0.121.0': + resolution: {integrity: sha512-vF24htj+MOH+Q7y9A8NuC6pUZu8t/C2Fr/kDOi2OcNf28oogr2xadBPXAbml802E8wRAVfbta6YLDQTearz+jw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@oxc-parser/binding-linux-arm-musleabihf@0.143.0': resolution: {integrity: sha512-oKu4RcBlXSqo3OC62dp6YTnQaZIurNDpCX3BnAM3+bJxt7s8J2TJKMnC0UYer1qhlRaDCg6wkTaTw+2IlsZ12w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@oxc-parser/binding-linux-arm64-gnu@0.121.0': + resolution: {integrity: sha512-wjH8cIG2Lu/3d64iZpbYr73hREMgKAfu7fqpXjgM2S16y2zhTfDIp8EQjxO8vlDtKP5Rc7waZW72lh8nZtWrpA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-arm64-gnu@0.143.0': resolution: {integrity: sha512-WJBbD186AZmMGaSIhlktC+rPl8L3peCTXAh88Ih9uEvK0en2mPojGyCGYiL6mHtV1RPV3JyfJW5t6n5hh0lXhA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -985,6 +1041,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-arm64-musl@0.121.0': + resolution: {integrity: sha512-qT663J/W8yQFw3dtscbEi9LKJevr20V7uWs2MPGTnvNZ3rm8anhhE16gXGpxDOHeg9raySaSHKhd4IGa3YZvuw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + '@oxc-parser/binding-linux-arm64-musl@0.143.0': resolution: {integrity: sha512-t1AcYOwEzgceadT4v5e+vaCCb0AncCA3v5AyzfBAz/tMq11qzVccXKzNHtkWdjBsgvTKwRkaUF3QvT4kot8vcQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -992,6 +1055,13 @@ packages: os: [linux] libc: [musl] + '@oxc-parser/binding-linux-ppc64-gnu@0.121.0': + resolution: {integrity: sha512-mYNe4NhVvDBbPkAP8JaVS8lC1dsoJZWH5WCjpw5E+sjhk1R08wt3NnXYUzum7tIiWPfgQxbCMcoxgeemFASbRw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-ppc64-gnu@0.143.0': resolution: {integrity: sha512-RsnO/NoD8376LMJq8JS8TwI0ieNaFRTuNe2GVJntQg6gwZNMENZsEbknHdVwjpOmxdGLGodcwaGSbAeRr5Bgjw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -999,6 +1069,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-riscv64-gnu@0.121.0': + resolution: {integrity: sha512-+QiFoGxhAbaI/amqX567784cDyyuZIpinBrJNxUzb+/L2aBRX67mN6Jv40pqduHf15yYByI+K5gUEygCuv0z9w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-riscv64-gnu@0.143.0': resolution: {integrity: sha512-48fSVfR9TZi5CASZFyv0VC6z6BCoeihFsX031mAD/oSH7d9PYsPgIqza7d9mjP7Z2KTEpTFyH6SIu0Ui6R1vdg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1006,6 +1083,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-riscv64-musl@0.121.0': + resolution: {integrity: sha512-9ykEgyTa5JD/Uhv2sttbKnCfl2PieUfOjyxJC/oDL2UO0qtXOtjPLl7H8Kaj5G7p3hIvFgu3YWvAxvE0sqY+hQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [riscv64] + os: [linux] + libc: [musl] + '@oxc-parser/binding-linux-riscv64-musl@0.143.0': resolution: {integrity: sha512-T8CpdD+SfE01DnIOD4HpVxu0ZJOfMJ/VhCvikKfaXAxkZ+9veyLM/D2hpi7Y2hFUyPmVQO3FNZHmYzV/WlVR4g==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1013,6 +1097,13 @@ packages: os: [linux] libc: [musl] + '@oxc-parser/binding-linux-s390x-gnu@0.121.0': + resolution: {integrity: sha512-DB1EW5VHZdc1lIRjOI3bW/wV6R6y0xlfvdVrqj6kKi7Ayu2U3UqUBdq9KviVkcUGd5Oq+dROqvUEEFRXGAM7EQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-s390x-gnu@0.143.0': resolution: {integrity: sha512-QLdeMsCcacenPEFsfxnBUDF1y6opyz5+fmOz9bfD5Y7fiGCMupUCuB3KTPQhNwshIG1P9fPqar9MHxuBDd4bwQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1020,6 +1111,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-x64-gnu@0.121.0': + resolution: {integrity: sha512-s4lfobX9p4kPTclvMiH3gcQUd88VlnkMTF6n2MTMDAyX5FPNRhhRSFZK05Ykhf8Zy5NibV4PbGR6DnK7FGNN6A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + '@oxc-parser/binding-linux-x64-gnu@0.143.0': resolution: {integrity: sha512-659ujfqLy6k7cuH3sbzhd8b+ztSq+i6E2E9pG78Q0BmHjAExfGIdgc8cGgMdwAozDXeZFHkJ+LXYJdWsaGdgyw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1027,6 +1125,13 @@ packages: os: [linux] libc: [glibc] + '@oxc-parser/binding-linux-x64-musl@0.121.0': + resolution: {integrity: sha512-P9KlyTpuBuMi3NRGpJO8MicuGZfOoqZVRP1WjOecwx8yk4L/+mrCRNc5egSi0byhuReblBF2oVoDSMgV9Bj4Hw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@oxc-parser/binding-linux-x64-musl@0.143.0': resolution: {integrity: sha512-/Mw/9j4TfZcnKphPrzOE6t4MMknXadcAAuVUlDRTF/ETWB5xOgQvOJV2Mh9We/bWxZdoxaGAdc+hy4GuYwQ2yQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1034,24 +1139,53 @@ packages: os: [linux] libc: [musl] + '@oxc-parser/binding-openharmony-arm64@0.121.0': + resolution: {integrity: sha512-R+4jrWOfF2OAPPhj3Eb3U5CaKNAH9/btMveMULIrcNW/hjfysFQlF8wE0GaVBr81dWz8JLgQlsxwctoL78JwXw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@oxc-parser/binding-openharmony-arm64@0.143.0': resolution: {integrity: sha512-8rIKWR2BFuifbIK/1XB9wTaSdtuJ25dlE7ZQYDnEwj/2xH2vHsxnvIjHT3ZjSVuLLwGGlSslIG/fbOJ8TV8rTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@oxc-parser/binding-wasm32-wasi@0.121.0': + resolution: {integrity: sha512-5TFISkPTymKvsmIlKasPVTPuWxzCcrT8pM+p77+mtQbIZDd1UC8zww4CJcRI46kolmgrEX6QpKO8AvWMVZ+ifw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@oxc-parser/binding-win32-arm64-msvc@0.121.0': + resolution: {integrity: sha512-V0pxh4mql4XTt3aiEtRNUeBAUFOw5jzZNxPABLaOKAWrVzSr9+XUaB095lY7jqMf5t8vkfh8NManGB28zanYKw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@oxc-parser/binding-win32-arm64-msvc@0.143.0': resolution: {integrity: sha512-5U9kQYMfRRI6Zq7KDxgbIP0RMnKrfn3gLepRMgJuRkPSUALTiRCk9d/uyhb4lGDjUdzwK7mBkKqhLgzBPCmLpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@oxc-parser/binding-win32-ia32-msvc@0.121.0': + resolution: {integrity: sha512-4Ob1qvYMPnlF2N9rdmKdkQFdrq16QVcQwBsO8yiPZXof0fHKFF+LmQV501XFbi7lHyrKm8rlJRfQ/M8bZZPVLw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ia32] + os: [win32] + '@oxc-parser/binding-win32-ia32-msvc@0.143.0': resolution: {integrity: sha512-25P7AaHk4R88Yv2XH4gToDVmh0cOu+bEURQU10CRrmvgabfRArSGAP5osmwUKeSUHj0VS50upbpbRWWW/m7mHA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] + '@oxc-parser/binding-win32-x64-msvc@0.121.0': + resolution: {integrity: sha512-BOp1KCzdboB1tPqoCPXgntgFs0jjeSyOXHzgxVFR7B/qfr3F8r4YDacHkTOUNXtDgM8YwKnkf3rE5gwALYX7NA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@oxc-parser/binding-win32-x64-msvc@0.143.0': resolution: {integrity: sha512-ORMh3JE1s6V7ySicdRK7vgaDQnn5o+UHg9ct989PlWHbel8O9ARrmWXM6kZjrBMtNucxNayQ8g69G0VfWzhANw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -1061,6 +1195,9 @@ packages: '@oxc-project/types@0.110.0': resolution: {integrity: sha512-6Ct21OIlrEnFEJk5LT4e63pk3btsI6/TusD/GStLi7wYlGJNOl1GI9qvXAnRAxQU9zqA2Oz+UwhfTOU2rPZVow==} + '@oxc-project/types@0.121.0': + resolution: {integrity: sha512-CGtOARQb9tyv7ECgdAlFxi0Fv7lmzvmlm2rpD/RdijOO9rfk/JvB1CjT8EnoD+tjna/IYgKKw3IV7objRb+aYw==} + '@oxc-project/types@0.143.0': resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==} @@ -1775,6 +1912,9 @@ packages: '@tybys/wasm-util@0.10.3': resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + '@tybys/wasm-util@0.10.4': + resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==} + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} @@ -2051,117 +2191,193 @@ packages: cpu: [x64] os: [win32] - '@vercel/backends@0.8.30': - resolution: {integrity: sha512-rCDufBDL3Y9eiKOKZLoiy350KMt/kP7YmcRgI1egfrUpaaGObDesxkK9IQdP7fnYrK+rc2+rK07qb21AdsoAHw==} + '@vercel/backends@13.0.0': + resolution: {integrity: sha512-Ca805KM3lTwv29V/XO4++8LvZpM0V3WQaoktpC1z8wK7rtQJvgwJbi9bG4yidX0iTp//4/4zL6B/D0ES2hdUAQ==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/blob@2.4.0': - resolution: {integrity: sha512-ncQ8CRb6XoEAYJwjOTRGpACRT6h/AeY+/33gLyeVxG5BIes27OPm1jmqreF+JHjcTmGhClTP+kBpmyLfbV0xew==} + '@vercel/blob@2.8.0': + resolution: {integrity: sha512-Nu+HWKpkgovCh/ezlG7wCVwF7RErTzLzZMbGKFBdGBCbTKyK+s5VXPLl+0+TpNEQPH8AVaGzOpIsXUOtkqylCQ==} engines: {node: '>=20.0.0'} - '@vercel/build-utils@13.36.3': - resolution: {integrity: sha512-2f6RhmPYLiQjAJltaq9WPsRNdnzos0bWShL/AbYLXoydBVszlX8H/5w9rJ23nqPmtGjbDfZ9kLLGuAdyftvcTA==} + '@vercel/build-utils@14.15.0': + resolution: {integrity: sha512-lDssSXvbUShIvh4A5syC29egbesD239a2Ggj/szzrzX8X5Mi6ZF1gpU20Efeq2j9a6ARqDB1Qm/bIcrTSMcu5Q==} - '@vercel/cervel@0.1.38': - resolution: {integrity: sha512-yxPU1m2sYAyjHI9uWW6XmQcvxobYPhI7YzCGH4Vb6/F/lHtaRqHfBn9IVxpVdIKTWRdp9GZeJgNEC2gRhgRlmw==} + '@vercel/cervel@0.1.73': + resolution: {integrity: sha512-lx2Pl/DzRXFXYNMrrpwnHWRDSlYSEmEHro74T2OmauxhRLSu7DdEv5dAk3wUryd211PeAHw+lxO4PoJQSJyKlg==} hasBin: true - '@vercel/cli-auth@0.3.1': - resolution: {integrity: sha512-TaMXMiPrwcLoLxu6ExcJ8yEw8b8Qss6UZkNYF4xIq+/VdvAk0l8JCpeAwzuHgKuJqmIDrOvtfjHO2+T/MBR3dg==} + '@vercel/cli-auth@0.3.10': + resolution: {integrity: sha512-uI8JzvaGOiZkSN9lnTkwERwNlsubiRnL8Y4oACtLq3CAEeJTplETjCknzkzkNvV7bz8KkNZC8YYrsPOMDrMHkQ==} - '@vercel/cli-config@0.2.1': - resolution: {integrity: sha512-RhfyXmRLHdbnry8RJqHDc+5rGxMZ0bu+fpysZjtv3bE+BubpuwxTancHOKiH5zKQREsdwFVr3mOI2kOvxlOyxA==} + '@vercel/cli-config@0.3.1': + resolution: {integrity: sha512-sISbygqlFXYb8qfPu/+2Cf/A8IjrlAuZePdag3EDQr2PRA455s7UZtl9Ro674CWsB/saBRmz3jEkw0YsQs8OoQ==} - '@vercel/container@0.1.0': - resolution: {integrity: sha512-m1Y3qT1JOUFKLXUI54hVHSkRTGrvI8LC7EPNsEE1MBME8gk8aoIB+lJWl59jd56MjTDcTc3NCzPdHIZ65grZkA==} + '@vercel/cli-exec@1.0.1': + resolution: {integrity: sha512-g9XerViJ/paZujufXYcu5XYI2vU2rtB4sgdpjUHde5RnOkdmpu0ngH46LCFGHoPXO/C+qDPSczIHIRN+8Q2YKQ==} + engines: {node: '>= 18'} + + '@vercel/container@13.0.0': + resolution: {integrity: sha512-gu1XugkRATqpw4NyZFzduHmxQ/6M2GjN/k8OiM4xdGa8t9vPtmeSiWtVBHzLrR2njscpCBG2qhd+L+g2KiNSlg==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/detect-agent@1.2.3': - resolution: {integrity: sha512-VYNCgUc0nOmC4WJmWw9GkrKdfr8Zl4/rxhC5SvgacBgxiW9W/9NRttUoHHXV8xdII3MaRgkZZVX8Ikzc/Jmjag==} + '@vercel/detect-agent@1.2.5': + resolution: {integrity: sha512-0krENrjuitlW8s6TJu0MlqCevyCU7K7JK63jZAf7xZ6n17tx+vUEwzHT3sTxawtwZxaW21hu+oFUpoOrm49FsQ==} engines: {node: '>=14'} - '@vercel/elysia@0.1.107': - resolution: {integrity: sha512-DMGyVHfDqLma8Su4DsQ0ZRtS06AMIbSsUKekf+IxKj/JgtGBjRxaYHunBxYaW6l0KDxvfGkghhDLYAaajM5Xfw==} + '@vercel/elysia@13.0.0': + resolution: {integrity: sha512-uvA3+r89TE/QWNefnnL+rqJduq5mzRYRVF2Xbf3L9NtaPgIMepiIZIaOU65pDoQriyo6Nebzsqtp7fylyDJPWg==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/error-utils@2.2.0': - resolution: {integrity: sha512-WFWiRxfPzoYWYifaj4thSKvAaZZwUOqD4k5GINRIgZgCiS2E3iAJbWbIsIZmkQdTecWFHcWGA6q48CjisgpOBA==} + '@vercel/error-utils@2.2.1': + resolution: {integrity: sha512-9DhP8jP7raLML4hGsBemxX5fXuQnu5xxMV+HjGygGbzEmVK/+KyJ3QP2Cw7PdF0uXdb9N0Qa4c3tRGH34ZX6vw==} - '@vercel/express@0.1.121': - resolution: {integrity: sha512-d7W6xuMrIkduKphq1BRvas1kZiQGT0fsHxvaRHKBIznx0R9BlUkYDhrvEeat4qleYXuVjKHYoHXyvbOO9z4ykA==} + '@vercel/express@13.0.0': + resolution: {integrity: sha512-7DNt5LoM7xr0xSoMyCOL4tREzy6d2iYxD9c9aEO+g0azLT95J/9cbkMX1RNkk78s+J38QsGclvOYz5ne73CJbw==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/fastify@0.1.110': - resolution: {integrity: sha512-8RukhVPXAJqZK5zJSS3uCdlVKdxNLjN0vzTfE+kyupieYgU3cmhJdXULKMI2beYLjG7VW6G1oz4AZTWU2ockzg==} + '@vercel/fastify@13.0.0': + resolution: {integrity: sha512-2JwvlX6JKWuxf3IcHcuAc4FLVcpJim17cIjn0f0OzxGtQ/liDB/QonHo7CKkkX1xaMHdqREajnU2XzSNKI6mww==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/fun@1.3.0': - resolution: {integrity: sha512-8erw9uPe0dFg45THkNxmjtvMX143SkZebmjgSVbcM3XCkXu3RIiBaJMcMNG8aaS+rnTuw8+d4De9HVT0M/r3wg==} - engines: {node: '>= 18'} + '@vercel/fun@1.3.6': + resolution: {integrity: sha512-c05ioJxn3ShXAPoQAX7UbLVaKw7HSMDfJt2yljfCsDqGHN+Iw6mK4AMor4vcA+zsGFPngmJO0kVWP4zF2Q9rTQ==} + engines: {node: '>= 20'} - '@vercel/gatsby-plugin-vercel-analytics@1.0.11': - resolution: {integrity: sha512-iTEA0vY6RBPuEzkwUTVzSHDATo1aF6bdLLspI68mQ/BTbi5UQEGjpjyzdKOVcSYApDtFU6M6vypZ1t4vIEnHvw==} + '@vercel/gatsby-plugin-vercel-analytics@1.0.12': + resolution: {integrity: sha512-Ejlhwxr7EBYJxtwYnlh6Vm6A2dPsUSPxMdYrfv0koZkgAzVwo7cG4aDQiy7iASMaGzwuI/PAnwlY2sJBF5b4OA==} - '@vercel/gatsby-plugin-vercel-builder@2.2.33': - resolution: {integrity: sha512-UAb+Vx5pX1Y/WrBepbZG+gZBtQfAYsJ5alyjPH5c83QoWc4D4ZLG9YKIkChRnMSSwPIpZOjt9J6PAsr+FxGVJw==} + '@vercel/gatsby-plugin-vercel-builder@2.2.65': + resolution: {integrity: sha512-OhLrQt7xOuc89EhL6hQUms93v8qHbQi3RBpOtXk0BEL/by/q77NTNrp//oitaPXozbDPZ2Nk9wJ3hdLxYX5qvA==} - '@vercel/go@3.10.2': - resolution: {integrity: sha512-ZJqx1GzD1qqMkI92jEHp04zCwbZ7tNwcgI58e7t8HiYvILwCZ4Rvq0hfjTjsk+0Zn8A369qs4eAHvCYu38uB5A==} + '@vercel/go@16.0.0': + resolution: {integrity: sha512-L5SZCq1goOAhOv/kwASDhrw4gM7Y/MwqgBti6NdKb9k3fPTwNu8lTQ9Ip1RqDsR/CBK/TN1bBxoZhlb5nZWJQg==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/h3@0.1.116': - resolution: {integrity: sha512-7IS5u3UYSFMS/0HSUjZflyLmR1r7233eJWEatJH9gMB37GOB9nW2Lk1TqU3ehRLJUvGwcT1FOlnEaQR+HDVljQ==} + '@vercel/h3@13.0.0': + resolution: {integrity: sha512-iUB8SXpAGsbDTWpt1ySWsd2wlb9WdT6nbs20yd0q+ZmLyGfDvzH5RB8maWLVsQAmsj5fg0C1H2/joYS7igvTzQ==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/hono@0.2.110': - resolution: {integrity: sha512-OsfUoX0DLbAUUSHzzqY8Rh+RizQtG+gfPwX3W0AJlD1r+JpyczxyiqTavbX2jd2rFnGNKJHdnvrUsjid4xpB8w==} + '@vercel/hono@13.0.0': + resolution: {integrity: sha512-2AnKYfMY+o6hiyZU17s+UBzyHwKmDxhWYNfI/h2kHxKBFYsLkt14Mu54ktkv77i+WczRAC0e0cCiUR67CWk14w==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/hydrogen@1.4.0': - resolution: {integrity: sha512-gf3ELmAjcia7WNGNHAB/rFWFU0l5fJ7mTMgGC5hvcCjSIE4kp8WWuGYiTQgQ8W6GF/1FJAxa2J3BhY/yxjY8tA==} + '@vercel/hydrogen@14.0.0': + resolution: {integrity: sha512-5g+wF1UFFTdlmfZrj5SjsGw2UaOHPOslYC2sik9hH9BwmF+g9Z/EKdvEOSAbis3wUoezbncYvYNUAxnrDOY3BA==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/koa@0.1.90': - resolution: {integrity: sha512-qZNfHLs81cwsLT1AlIO9aUpIK1YjiUtYHqtThXdIqkx9jQIfHIFONLz3TRaIke45HEfU6QKtplkxhPIzQ+x1IQ==} + '@vercel/koa@13.0.0': + resolution: {integrity: sha512-BetGigbv4n5dzLYHZgIDZrJu5HOK7H9iDAihRTMqAsqqiTpWbXdWR3MRqGIvD33BGzj1HmoYxskoS6lDDJTpyw==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/nestjs@0.2.111': - resolution: {integrity: sha512-3Bpp1KXkcvE5CMaUFRQsBXdK61JSoLdcLDKtpMVgUZ23gDjpeWRelEyBO523iy3WgN1+AWzcdtyGlGDarfOfmg==} + '@vercel/nestjs@13.0.0': + resolution: {integrity: sha512-u5Ui4qzbgzucloYVMnw6zu3240+bYn3uFyUQyBWFyK1fgk3Ya7VWstRI1LOTSmUAof5XGgC8RFqeTgUQfBeh0g==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/next@4.20.5': - resolution: {integrity: sha512-a8CyH+/0JlvGfqeeEiBqOeG3kvQVzJsRHqw3rkXiqwNQHyLHVBJcufAPx5VxyA/7SpdzJG6jFTD9sm8FIwPmgw==} + '@vercel/next@17.0.0': + resolution: {integrity: sha512-zxbiSA72FPlAXfHXNfupKdtOS5LZgJx64zG2SXqBaW5l+dkSseM2pATf43JgiI9/bz6iyjMVYY6z+qW0MZilXA==} + peerDependencies: + '@vercel/build-utils': 14.15.0 '@vercel/nft@1.10.0': resolution: {integrity: sha512-iLOW4fcsgkipfOh2Bw3wB38YDfxTlxr7+j4uFeui2OswkNT28jIitS/aMce7tS0mef1YPQ8zLIDYr3a0aahNrA==} engines: {node: '>=20'} hasBin: true - '@vercel/node@5.9.3': - resolution: {integrity: sha512-KkAYFVyrRVm9nYLdk5zVIbAra4H9ZUmLyjDnMNe3+yy5GUtC/jmBVp1fl9cf1CejMNMBu7apcrRN5nX0lhj2xw==} + '@vercel/node@18.0.0': + resolution: {integrity: sha512-K23Ej7u3siIdoWta+KYHFJWR8Obg/bp4YWA4IQgIztZmQL+ti9G9lWYk1jHdLcCshtkHYk0b0XTEgWN3lf/jIA==} + peerDependencies: + '@vercel/build-utils': 14.15.0 '@vercel/oidc@3.2.0': resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} engines: {node: '>= 20'} + '@vercel/oidc@3.8.10': + resolution: {integrity: sha512-sPw1kIfQEA6/2dB+zlAJHnhhNBRJ8t/t4HfFvKO+g0EPBA7NbCKyGovuhgAV6Mnl865ka7HqCEguIy596czdAw==} + engines: {node: '>= 20'} + '@vercel/prepare-flags-definitions@0.3.0': resolution: {integrity: sha512-/0nuDFwYje0nqZnVKSd2VfJy2wOPQwbkas1qO1JQgtb0sLl+EeSCW4O9hrvq55pN50PNlAZ/APSeWHIAT9ZGHg==} - '@vercel/python-analysis@0.12.0': - resolution: {integrity: sha512-T9YgtINVJfZmDhXe6ULKoLC1Zr3LU3Cl4CgC+m+S1KsNDPlfGfXdr93K7aOqkMaJEDLpUH8dqrPP3/TuZXTjRw==} + '@vercel/python-analysis@0.14.0': + resolution: {integrity: sha512-qyVxbaU14gAi/AsaR8syZLukUsOp69Jkm1xn80rZPy4k9+zRUTIfqs0AOk7L8wwBxDDB6LLjcBUAmafhbJQnUQ==} + + '@vercel/python@19.0.0': + resolution: {integrity: sha512-4pUYjsRR6lZETHLNGThDXvV+3EPKxoBmk267Cx8TZBGhBAoibUUrJrfDRr8qK8vxbkXsjLzkxKnzb91FAa6MHQ==} + peerDependencies: + '@vercel/build-utils': 14.15.0 + + '@vercel/redwood@15.0.0': + resolution: {integrity: sha512-HeIrl6hgtquV2SJvAMBXSaXN0R8/P/NXK0Z/qLtuNJTkecNZqAvbj1F9W2GGwCbriFk2M8PJBpFQUREC4itJ4Q==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/python@6.54.1': - resolution: {integrity: sha512-RnkRLcRB4GkoUNlZl1uSQyzADJGTgRqj1UzWA93rixKvobO2n0LU5rqztOYnhE1Jb8ZlF7Ncnr9dXhQHy9KNRg==} + '@vercel/remix-builder@18.0.0': + resolution: {integrity: sha512-pXdvra9Shn0kAfTkVzSUsh85UpCmAreGfPDlMTU6XTtk2ohRCqP/tghk7gdPUuVopC8rKffanTr62dxRHttHdA==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/redwood@2.5.0': - resolution: {integrity: sha512-LO24CbieV57rGAqrq5n5z/B+fMYeUqbE/Ge3qMeKRuS3Q9awgcBgB6WYLCe8crHM7XJd5AZjbuyoS/6k3r0X0w==} + '@vercel/ruby@15.0.0': + resolution: {integrity: sha512-kgNopHL/nVnhn/8dRi2iPTHMpCq0n3FCwIT1PLa/d5wc8LexCz6WNsfkFZG0yCSFaPyb3ofWBFFdh5b6g0imlQ==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/remix-builder@5.9.1': - resolution: {integrity: sha512-s0SpfV640nmQ1BsKCPMYugGrH/V+319onTo2ZILSmsy6NTBlmeN0zJU9nPcP8dBEotGqtp68NfOlOUUdrVBzkw==} + '@vercel/rust@14.0.0': + resolution: {integrity: sha512-pKAn2yCdrgv5V36Vp+7ZEfvrlGduYKKxksTtd9fLBhoWpQmqfSXh3lrvbJ7rTa3aIL1xxf39qY2rRkNM0CEvmQ==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/ruby@2.5.1': - resolution: {integrity: sha512-e23M7pfORQyyxSUmeQ8PqEnyLJ4swhtNrnyctU5E02UCaUYFm5YAdNfdPYRP4It874H4Wyvm+LV8u7CPBrfcPA==} + '@vercel/sandbox@3.3.0': + resolution: {integrity: sha512-TclqRD2joExyECTrrHsioi3Onw20X2YfpOYEzs3JpJUtAjOKYw2bMeXldKrUg+TB/TT7tPdDu8uKNxj9NE7QUg==} - '@vercel/rust@1.4.0': - resolution: {integrity: sha512-/zRJtaf3pvdxZ7+tShmIo8StdbkCSBDcY7Gy7LOwNTIxm6GU9vkS+BlCwJHkOu6qNkbcSRH6ZQIeo4vNmqzKdQ==} + '@vercel/static-build@15.0.0': + resolution: {integrity: sha512-N51FsE1hlQ5YDe/J5JiaLYixdxf9FA6vQ2NP6rLM3fYAb59tgDXtrPV5czJ5JjDGbeiMuYgFPOPxc/5sLQMiDw==} + peerDependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/sandbox@2.4.0': - resolution: {integrity: sha512-pifnr8hex/rgQ3EPyLYHYwHyf0Kwmc4Vbya9kHGk4aERFVGj44P+742S8/SDdt2guMxBriXBOMkMLq1Kaiyyeg==} + '@vercel/static-config@3.4.4': + resolution: {integrity: sha512-WppaPyEKQhO8qo5gVee3mSo1QSCgDZaUcUDHrqICSlt90oYeC/SHTmKCPWY1x1NB9hU+kR2oDzJwAeRKKv5NIw==} - '@vercel/static-build@2.11.13': - resolution: {integrity: sha512-FShOZZpebAcCJuF+XejFeSmw9htNFHne/iVtroXaZvj3PJ+SDbLN2VFIRFwFGg5CZgDsbSN9N5caDbOSgQ7m9Q==} + '@vercel/vc-native-darwin-arm64@62.2.0': + resolution: {integrity: sha512-K98cEQaLQVcAztwf1Keqa527nx7LYuQECb1Zu2yKOJoPeGq6ZPAzNsu3uNM2CqIFdMn/rICuyRCiuykJ9ysNYA==} + cpu: [arm64] + os: [darwin] - '@vercel/static-config@3.4.0': - resolution: {integrity: sha512-wCq90CMUB//ggnFh77NQO1xaLFsS4LigQIqKrH6ohnr9Br/KI1FhlErx62WfCOuueWaW+LVsbLOqNXIUjK8t6A==} + '@vercel/vc-native-darwin-x64@62.2.0': + resolution: {integrity: sha512-X3IQClF/INN1R8fQvmIBykcJ04dmRKqDMAKgiJmyfgEgyKHYwWjp+ie6fHUU2l4Iffnka28ca//uYtwsAV0pug==} + cpu: [x64] + os: [darwin] + + '@vercel/vc-native-linux-arm64@62.2.0': + resolution: {integrity: sha512-ECKTkzV9RPHdfGr/vbAe681vlCt89ya65P+ugyav7dgbR1ZKpBjPHetLxZtB90KZJTbiBRsDGCtSXgy37hwohg==} + cpu: [arm64] + os: [linux] + + '@vercel/vc-native-linux-x64@62.2.0': + resolution: {integrity: sha512-N9+Htq7+zdVpcx63q4yA2GbuuWadvhtFAdirwx7qK0r0C/fFOXK5yeNXWPoZ8iGvZ2SIyQ2sLITxyFaIOCE08A==} + cpu: [x64] + os: [linux] + + '@vercel/vc-native-win32-arm64@62.2.0': + resolution: {integrity: sha512-cWqMO5AXWJJDHwO8bQIcD+cv+wHwAHXFOaVBDlTK3/7swS7v9lXIn0bClMRjXgXuymy+Uz/8cbZT9kHzpihmyg==} + cpu: [arm64] + os: [win32] + + '@vercel/vc-native-win32-x64@62.2.0': + resolution: {integrity: sha512-UxAWkPBLuh+oiQjwrGsNsqAhEpWcs6IPe45bYAJ97S99++kP6zSP2RKnFgXN4RPGCuOu9iNJ4vsft3DLPDlVDw==} + cpu: [x64] + os: [win32] '@vitest/mocker@5.0.2': resolution: {integrity: sha512-Z5FS00Q1SJHkB35xATsmWGdQ5WA1/0MV3CDjqyv7GavHv1OfOj145MNfHOlHk7QLes21dKFDHr8EO2zvL+9WGA==} @@ -2283,9 +2499,6 @@ packages: ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} - any-promise@1.3.0: - resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} - arg@4.1.0: resolution: {integrity: sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==} @@ -2368,8 +2581,8 @@ packages: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} - b4a@1.8.1: - resolution: {integrity: sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==} + b4a@1.9.0: + resolution: {integrity: sha512-dpfcF9fDNR6++cthXR67iyhgqWy9CBouAvIWhIntzBG6cvK/cnIPiZQjBwi/ZqjjBEDGfoNDtmB0kTjroOJ3pQ==} peerDependencies: react-native-b4a: '*' peerDependenciesMeta: @@ -2644,9 +2857,6 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - end-of-stream@1.1.0: - resolution: {integrity: sha512-EoulkdKF/1xa92q25PbjuDcgJ9RDHYU2Rs3SCIvs2/dSQ3BpmxneNHmA/M7fe60M3PrV7nNGTTNbkK62l6vXiQ==} - end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -3540,6 +3750,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.2.4: resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==} engines: {node: 20 || >=22} @@ -3793,9 +4006,6 @@ packages: resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} engines: {node: '>=12.20.0'} - once@1.3.3: - resolution: {integrity: sha512-6vaNInhu+CHxtONf3zw3vq4SP2DOQhjBvIa3rNcG0+P7eKWlYH6Peu7rHizSloRU2EwMz6GraLieis9Ac9+p1w==} - once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -3819,6 +4029,10 @@ packages: resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} + oxc-parser@0.121.0: + resolution: {integrity: sha512-ek9o58+SCv6AV7nchiAcUJy1DNE2CC5WRdBcO0mF+W4oRjNQfPO7b3pLjTHSFECpHkKGOZSQxx3hk8viIL5YCg==} + engines: {node: ^20.19.0 || >=22.12.0} + oxc-parser@0.143.0: resolution: {integrity: sha512-ov0NzaDCOInknS7mP1cwKdJERt3utPW8ldjtdUXQ8Ty0GEFD08wk422vCUN0d7pST6kqtV7dxoI9w1Zi0l/9TA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3930,9 +4144,6 @@ packages: resolution: {integrity: sha512-FYgfaA69XZ93zaXLoMNQ+ViDXGGBgR8aLh03txzcFhV+9xOXx7+8DLCULrKKpR9+GsH9ZfHm82aSUPpozX0Ztg==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - promisepipe@3.0.0: - resolution: {integrity: sha512-V6TbZDJ/ZswevgkDNpGt/YqNCiZP9ASfgU+p83uJE6NrGtvSGoOcHLiDCqkMs2+yg7F5qHdLV8d0aS8O26G/KA==} - prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -4051,8 +4262,8 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sandbox@3.4.0: - resolution: {integrity: sha512-JPdADikobt6zFuuCRhl6whNrCJlLPxpUmT/hNxLij70mkpeejHKDN+HeVlrdHI8snDTzRIiF3Ye8KyMIyVWA+A==} + sandbox@4.4.0: + resolution: {integrity: sha512-8DlAEKlHbOQmz5R05dAYE+P1wNQ44nEvAnf1jnWtF0LZWHiu/F48USSMKyY8Ib8iE1MCfo3Yvhmky8bUppLaWA==} hasBin: true saxes@6.0.0: @@ -4205,13 +4416,6 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} - stream-to-array@2.3.0: - resolution: {integrity: sha512-UsZtOYEn4tWU2RGLOXr/o/xjRBftZRlG3dEWoaHr8j4GuypJ3isitGbVyjQKAuMu+xbiop8q224TjiZWc4XTZA==} - - stream-to-promise@2.2.0: - resolution: {integrity: sha512-HAGUASw8NT0k8JvIVutB2Y/9iBk7gpgEyAudXwNJmZERdMITGdajOa4VJfD/kNiA3TppQpTP4J+CtcHwdzKBAw==} - deprecated: Deprecated. Use node:stream/promises and node:stream/consumers instead. - streamx@2.28.1: resolution: {integrity: sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==} @@ -4446,8 +4650,8 @@ packages: resolution: {integrity: sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==} engines: {node: '>=18.17'} - undici@7.29.1: - resolution: {integrity: sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==} + undici@7.30.0: + resolution: {integrity: sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==} engines: {node: '>=20.18.1'} universalify@2.0.1: @@ -4476,9 +4680,13 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - vercel@58.4.4: - resolution: {integrity: sha512-Mv1807Ptxhy6cQne5xV/2dD+bUGYRtpV3sLVPXEW115RBN6K/ssuvOww8eNfdGucFH9C+p5ccQF07XSyAvBPLQ==} - engines: {node: '>= 18'} + uuid@14.0.1: + resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==} + hasBin: true + + vercel@62.2.0: + resolution: {integrity: sha512-hwet6qXoOfZEc6waIx1VgI2nLl83wwuZZnFqKSsKJ47UFi9waEezPmAV7uNOx8Fq+6JTJIi+lRnxFXr9YFW3Eg==} + engines: {node: '>= 20'} hasBin: true vite@8.3.2: @@ -4660,18 +4868,6 @@ packages: utf-8-validate: optional: true - ws@8.21.3: - resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: '>=5.0.2' - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - ws@8.22.0: resolution: {integrity: sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg==} engines: {node: '>=10.0.0'} @@ -4740,8 +4936,8 @@ packages: zod@4.1.11: resolution: {integrity: sha512-WPsqwxITS2tzx1bzhIKsEs19ABD5vmCVa4xBo2tq/SrV4RNZtfws1EnCWQXM6yh8bD08a1idvkB5MZSBiZsjwg==} - zod@4.5.4: - resolution: {integrity: sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==} + zod@4.6.5: + resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} snapshots: @@ -5336,11 +5532,11 @@ snapshots: '@tybys/wasm-util': 0.10.3 optional: true - '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': + '@napi-rs/wasm-runtime@1.2.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': dependencies: '@emnapi/core': 2.0.0-alpha.3 '@emnapi/runtime': 2.0.0-alpha.3 - '@tybys/wasm-util': 0.10.3 + '@tybys/wasm-util': 0.10.4 optional: true '@next/env@16.3.8': {} @@ -5409,65 +5605,132 @@ snapshots: '@opentelemetry/api@1.9.1': {} + '@oxc-parser/binding-android-arm-eabi@0.121.0': + optional: true + '@oxc-parser/binding-android-arm-eabi@0.143.0': optional: true + '@oxc-parser/binding-android-arm64@0.121.0': + optional: true + '@oxc-parser/binding-android-arm64@0.143.0': optional: true + '@oxc-parser/binding-darwin-arm64@0.121.0': + optional: true + '@oxc-parser/binding-darwin-arm64@0.143.0': optional: true + '@oxc-parser/binding-darwin-x64@0.121.0': + optional: true + '@oxc-parser/binding-darwin-x64@0.143.0': optional: true + '@oxc-parser/binding-freebsd-x64@0.121.0': + optional: true + '@oxc-parser/binding-freebsd-x64@0.143.0': optional: true + '@oxc-parser/binding-linux-arm-gnueabihf@0.121.0': + optional: true + '@oxc-parser/binding-linux-arm-gnueabihf@0.143.0': optional: true + '@oxc-parser/binding-linux-arm-musleabihf@0.121.0': + optional: true + '@oxc-parser/binding-linux-arm-musleabihf@0.143.0': optional: true + '@oxc-parser/binding-linux-arm64-gnu@0.121.0': + optional: true + '@oxc-parser/binding-linux-arm64-gnu@0.143.0': optional: true + '@oxc-parser/binding-linux-arm64-musl@0.121.0': + optional: true + '@oxc-parser/binding-linux-arm64-musl@0.143.0': optional: true + '@oxc-parser/binding-linux-ppc64-gnu@0.121.0': + optional: true + '@oxc-parser/binding-linux-ppc64-gnu@0.143.0': optional: true + '@oxc-parser/binding-linux-riscv64-gnu@0.121.0': + optional: true + '@oxc-parser/binding-linux-riscv64-gnu@0.143.0': optional: true + '@oxc-parser/binding-linux-riscv64-musl@0.121.0': + optional: true + '@oxc-parser/binding-linux-riscv64-musl@0.143.0': optional: true + '@oxc-parser/binding-linux-s390x-gnu@0.121.0': + optional: true + '@oxc-parser/binding-linux-s390x-gnu@0.143.0': optional: true + '@oxc-parser/binding-linux-x64-gnu@0.121.0': + optional: true + '@oxc-parser/binding-linux-x64-gnu@0.143.0': optional: true + '@oxc-parser/binding-linux-x64-musl@0.121.0': + optional: true + '@oxc-parser/binding-linux-x64-musl@0.143.0': optional: true + '@oxc-parser/binding-openharmony-arm64@0.121.0': + optional: true + '@oxc-parser/binding-openharmony-arm64@0.143.0': optional: true + '@oxc-parser/binding-wasm32-wasi@0.121.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': + dependencies: + '@napi-rs/wasm-runtime': 1.2.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + optional: true + + '@oxc-parser/binding-win32-arm64-msvc@0.121.0': + optional: true + '@oxc-parser/binding-win32-arm64-msvc@0.143.0': optional: true + '@oxc-parser/binding-win32-ia32-msvc@0.121.0': + optional: true + '@oxc-parser/binding-win32-ia32-msvc@0.143.0': optional: true + '@oxc-parser/binding-win32-x64-msvc@0.121.0': + optional: true + '@oxc-parser/binding-win32-x64-msvc@0.143.0': optional: true '@oxc-project/types@0.110.0': {} + '@oxc-project/types@0.121.0': {} + '@oxc-project/types@0.143.0': {} '@oxc-project/types@0.152.0': {} @@ -5522,7 +5785,7 @@ snapshots: '@oxc-transform/binding-wasm32-wasi@0.111.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': dependencies: - '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) + '@napi-rs/wasm-runtime': 1.2.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -5614,7 +5877,7 @@ snapshots: '@rolldown/binding-wasm32-wasi@1.0.0-rc.1(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': dependencies: - '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) + '@napi-rs/wasm-runtime': 1.2.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -5986,6 +6249,11 @@ snapshots: tslib: 2.8.1 optional: true + '@tybys/wasm-util@0.10.4': + dependencies: + tslib: 2.8.1 + optional: true + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 @@ -6281,11 +6549,11 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.12.2': optional: true - '@vercel/backends@0.8.30(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5)': + '@vercel/backends@13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/build-utils': 13.36.3 + '@vercel/build-utils': 14.15.0 '@vercel/nft': 1.10.0(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) execa: 3.2.0 fs-extra: 11.1.0 get-port: 5.1.1 @@ -6304,64 +6572,77 @@ snapshots: - rollup - supports-color - '@vercel/blob@2.4.0': + '@vercel/blob@2.8.0': dependencies: + '@vercel/oidc': 3.8.10 async-retry: 1.3.3 is-buffer: 2.0.5 is-node-process: 1.2.0 throttleit: 2.1.0 undici: 6.28.0 - '@vercel/build-utils@13.36.3': + '@vercel/build-utils@14.15.0': dependencies: - '@vercel/python-analysis': 0.12.0 cjs-module-lexer: 1.2.3 es-module-lexer: 1.5.0 - '@vercel/cervel@0.1.38(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5)': + '@vercel/cervel@0.1.73(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/backends': 0.8.30(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5) + '@vercel/backends': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' + - '@vercel/build-utils' - encoding - rollup - supports-color - '@vercel/cli-auth@0.3.1': + '@vercel/cli-auth@0.3.10': dependencies: '@napi-rs/keyring': 1.2.0 - '@vercel/cli-config': 0.2.1 + '@vercel/cli-config': 0.3.1 async-listen: 3.0.0 open: 8.4.0 zod: 4.1.11 - '@vercel/cli-config@0.2.1': + '@vercel/cli-config@0.3.1': dependencies: xdg-app-paths: 5.5.1 zod: 4.1.11 - '@vercel/container@0.1.0': {} + '@vercel/cli-exec@1.0.1': + dependencies: + execa: 5.1.1 + + '@vercel/container@13.0.0(@vercel/build-utils@14.15.0)': + dependencies: + '@vercel/build-utils': 14.15.0 + smol-toml: 1.9.0 + tar: 7.5.22 - '@vercel/detect-agent@1.2.3': {} + '@vercel/detect-agent@1.2.5': {} - '@vercel/elysia@0.1.107(rollup@4.63.5)': + '@vercel/elysia@13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/node': 5.9.3(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/build-utils': 14.15.0 + '@vercel/node': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color - '@vercel/error-utils@2.2.0': {} + '@vercel/error-utils@2.2.1': {} - '@vercel/express@0.1.121(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5)': + '@vercel/express@13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/cervel': 0.1.38(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5) + '@vercel/build-utils': 14.15.0 + '@vercel/cervel': 0.1.73(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) '@vercel/nft': 1.10.0(rollup@4.63.5) - '@vercel/node': 5.9.3(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/node': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) fs-extra: 11.1.0 path-to-regexp: 8.4.0 ts-morph: 12.0.0 @@ -6373,16 +6654,19 @@ snapshots: - rollup - supports-color - '@vercel/fastify@0.1.110(rollup@4.63.5)': + '@vercel/fastify@13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/node': 5.9.3(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/build-utils': 14.15.0 + '@vercel/node': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color - '@vercel/fun@1.3.0': + '@vercel/fun@1.3.6': dependencies: '@tootallnate/once': 2.0.1 async-listen: 1.2.0 @@ -6392,10 +6676,8 @@ snapshots: ms: 2.1.1 node-fetch: 2.6.7 path-to-regexp: 8.4.0 - promisepipe: 3.0.0 semver: 7.5.4 stat-mode: 0.3.0 - stream-to-promise: 2.2.0 tar: 7.5.22 tinyexec: 0.3.2 tree-kill: 1.2.2 @@ -6406,68 +6688,87 @@ snapshots: - encoding - supports-color - '@vercel/gatsby-plugin-vercel-analytics@1.0.11': + '@vercel/gatsby-plugin-vercel-analytics@1.0.12': dependencies: web-vitals: 0.2.4 - '@vercel/gatsby-plugin-vercel-builder@2.2.33': + '@vercel/gatsby-plugin-vercel-builder@2.2.65': dependencies: '@sinclair/typebox': 0.25.24 - '@vercel/build-utils': 13.36.3 + '@vercel/build-utils': 14.15.0 esbuild: 0.28.2 etag: 1.8.1 fs-extra: 11.1.0 - '@vercel/go@3.10.2': {} + '@vercel/go@16.0.0(@vercel/build-utils@14.15.0)': + dependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/h3@0.1.116(rollup@4.63.5)': + '@vercel/h3@13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/node': 5.9.3(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/build-utils': 14.15.0 + '@vercel/node': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color - '@vercel/hono@0.2.110(rollup@4.63.5)': + '@vercel/hono@13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: + '@vercel/build-utils': 14.15.0 '@vercel/nft': 1.10.0(rollup@4.63.5) - '@vercel/node': 5.9.3(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/node': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) fs-extra: 11.1.0 path-to-regexp: 8.4.0 ts-morph: 12.0.0 zod: 3.22.4 transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color - '@vercel/hydrogen@1.4.0': + '@vercel/hydrogen@14.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)': dependencies: - '@vercel/static-config': 3.4.0 + '@vercel/build-utils': 14.15.0 + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) ts-morph: 12.0.0 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - '@vercel/koa@0.1.90(rollup@4.63.5)': + '@vercel/koa@13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/node': 5.9.3(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/build-utils': 14.15.0 + '@vercel/node': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color - '@vercel/nestjs@0.2.111(rollup@4.63.5)': + '@vercel/nestjs@13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/node': 5.9.3(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/build-utils': 14.15.0 + '@vercel/node': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color - '@vercel/next@4.20.5(rollup@4.63.5)': + '@vercel/next@17.0.0(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: + '@vercel/build-utils': 14.15.0 '@vercel/nft': 1.10.0(rollup@4.63.5) transitivePeerDependencies: - encoding @@ -6493,16 +6794,16 @@ snapshots: - rollup - supports-color - '@vercel/node@5.9.3(rollup@4.63.5)': + '@vercel/node@18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: '@edge-runtime/node-utils': 2.3.0 '@edge-runtime/primitives': 4.1.0 '@edge-runtime/vm': 3.2.0 '@types/node': 20.11.0 - '@vercel/build-utils': 13.36.3 - '@vercel/error-utils': 2.2.0 + '@vercel/build-utils': 14.15.0 + '@vercel/error-utils': 2.2.1 '@vercel/nft': 1.10.0(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) async-listen: 3.0.0 cjs-module-lexer: 1.2.3 edge-runtime: 2.5.9 @@ -6518,15 +6819,23 @@ snapshots: typescript: 5.9.3 undici: 6.28.0 transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color '@vercel/oidc@3.2.0': {} + '@vercel/oidc@3.8.10': + dependencies: + '@vercel/cli-config': 0.3.1 + '@vercel/cli-exec': 1.0.1 + jose: 5.9.6 + '@vercel/prepare-flags-definitions@0.3.0': {} - '@vercel/python-analysis@0.12.0': + '@vercel/python-analysis@0.14.0': dependencies: '@bytecodealliance/preview2-shim': 0.17.6 '@renovatebot/pep440': 4.2.1 @@ -6536,71 +6845,108 @@ snapshots: smol-toml: 1.9.0 zod: 3.22.4 - '@vercel/python@6.54.1': + '@vercel/python@19.0.0(@vercel/build-utils@14.15.0)': dependencies: - '@vercel/python-analysis': 0.12.0 + '@vercel/build-utils': 14.15.0 + '@vercel/python-analysis': 0.14.0 - '@vercel/redwood@2.5.0(rollup@4.63.5)': + '@vercel/redwood@15.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: + '@vercel/build-utils': 14.15.0 '@vercel/nft': 1.10.0(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) semver: 6.3.1 ts-morph: 12.0.0 transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color - '@vercel/remix-builder@5.9.1(rollup@4.63.5)': + '@vercel/remix-builder@18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5)': dependencies: - '@vercel/error-utils': 2.2.0 + '@vercel/build-utils': 14.15.0 + '@vercel/error-utils': 2.2.1 '@vercel/nft': 1.10.0(rollup@4.63.5) - '@vercel/static-config': 3.4.0 + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) path-to-regexp: 6.3.0 path-to-regexp-updated: path-to-regexp@6.3.0 ts-morph: 12.0.0 transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - encoding - rollup - supports-color - '@vercel/ruby@2.5.1': {} + '@vercel/ruby@15.0.0(@vercel/build-utils@14.15.0)': + dependencies: + '@vercel/build-utils': 14.15.0 - '@vercel/rust@1.4.0': + '@vercel/rust@14.0.0(@vercel/build-utils@14.15.0)': dependencies: + '@vercel/build-utils': 14.15.0 execa: 5.1.1 get-port: 5.1.1 smol-toml: 1.9.0 - '@vercel/sandbox@2.4.0': + '@vercel/sandbox@3.3.0': dependencies: '@vercel/oidc': 3.2.0 '@workflow/serde': 4.1.0-beta.2 async-retry: 1.3.3 jose: 6.2.3 jsonlines: 0.1.1 + lru-cache: 10.4.3 ms: 2.1.3 picocolors: 1.1.1 tar-stream: 3.1.7 - undici: 7.29.1 + undici: 7.30.0 xdg-app-paths: 5.1.0 - zod: 4.1.11 + zod: 4.6.5 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - '@vercel/static-build@2.11.13': + '@vercel/static-build@15.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)': dependencies: - '@vercel/gatsby-plugin-vercel-analytics': 1.0.11 - '@vercel/gatsby-plugin-vercel-builder': 2.2.33 - '@vercel/static-config': 3.4.0 + '@vercel/build-utils': 14.15.0 + '@vercel/gatsby-plugin-vercel-analytics': 1.0.12 + '@vercel/gatsby-plugin-vercel-builder': 2.2.65 + '@vercel/static-config': 3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) ts-morph: 12.0.0 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' - '@vercel/static-config@3.4.0': + '@vercel/static-config@3.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': dependencies: ajv: 8.18.0 json-schema-to-ts: 1.6.4 + oxc-parser: 0.121.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) ts-morph: 12.0.0 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + + '@vercel/vc-native-darwin-arm64@62.2.0': + optional: true + + '@vercel/vc-native-darwin-x64@62.2.0': + optional: true + + '@vercel/vc-native-linux-arm64@62.2.0': + optional: true + + '@vercel/vc-native-linux-x64@62.2.0': + optional: true + + '@vercel/vc-native-win32-arm64@62.2.0': + optional: true + + '@vercel/vc-native-win32-x64@62.2.0': + optional: true '@vitest/mocker@5.0.2(vite@8.3.2(@types/node@26.6.4)(esbuild@0.28.2)(jiti@2.7.0)(terser@5.51.2)(tsx@4.21.0))': dependencies: @@ -6758,8 +7104,6 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - any-promise@1.3.0: {} - arg@4.1.0: {} argparse@2.0.1: {} @@ -6859,7 +7203,7 @@ snapshots: axobject-query@4.1.0: {} - b4a@1.8.1: {} + b4a@1.9.0: {} balanced-match@1.0.2: {} @@ -7118,10 +7462,6 @@ snapshots: emoji-regex@9.2.2: {} - end-of-stream@1.1.0: - dependencies: - once: 1.3.3 - end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -7398,8 +7738,8 @@ snapshots: '@babel/parser': 7.29.8 eslint: 10.11.0(jiti@2.7.0) hermes-parser: 0.25.1 - zod: 4.5.4 - zod-validation-error: 4.0.2(zod@4.5.4) + zod: 4.6.5 + zod-validation-error: 4.0.2(zod@4.6.5) transitivePeerDependencies: - supports-color @@ -8196,6 +8536,8 @@ snapshots: dependencies: js-tokens: 4.0.0 + lru-cache@10.4.3: {} + lru-cache@11.2.4: {} lru-cache@11.5.3: {} @@ -8436,10 +8778,6 @@ snapshots: obug@2.2.1: {} - once@1.3.3: - dependencies: - wrappy: 1.0.2 - once@1.4.0: dependencies: wrappy: 1.0.2 @@ -8472,6 +8810,34 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + oxc-parser@0.121.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3): + dependencies: + '@oxc-project/types': 0.121.0 + optionalDependencies: + '@oxc-parser/binding-android-arm-eabi': 0.121.0 + '@oxc-parser/binding-android-arm64': 0.121.0 + '@oxc-parser/binding-darwin-arm64': 0.121.0 + '@oxc-parser/binding-darwin-x64': 0.121.0 + '@oxc-parser/binding-freebsd-x64': 0.121.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.121.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.121.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.121.0 + '@oxc-parser/binding-linux-arm64-musl': 0.121.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.121.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.121.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.121.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.121.0 + '@oxc-parser/binding-linux-x64-gnu': 0.121.0 + '@oxc-parser/binding-linux-x64-musl': 0.121.0 + '@oxc-parser/binding-openharmony-arm64': 0.121.0 + '@oxc-parser/binding-wasm32-wasi': 0.121.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) + '@oxc-parser/binding-win32-arm64-msvc': 0.121.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.121.0 + '@oxc-parser/binding-win32-x64-msvc': 0.121.0 + transitivePeerDependencies: + - '@emnapi/core' + - '@emnapi/runtime' + oxc-parser@0.143.0: dependencies: '@oxc-project/types': 0.143.0 @@ -8598,8 +8964,6 @@ snapshots: proc-log@7.0.0: {} - promisepipe@3.0.0: {} - prop-types@15.8.1: dependencies: loose-envify: 1.4.0 @@ -8782,13 +9146,13 @@ snapshots: safer-buffer@2.1.2: {} - sandbox@3.4.0: + sandbox@4.4.0: dependencies: - '@vercel/sandbox': 2.4.0 + '@vercel/sandbox': 3.3.0 async-retry: 1.3.3 debug: 4.4.3 - ws: 8.21.3 - zod: 4.1.11 + ws: 8.22.0 + zod: 4.6.5 transitivePeerDependencies: - bare-abort-controller - bufferutil @@ -8982,16 +9346,6 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 - stream-to-array@2.3.0: - dependencies: - any-promise: 1.3.0 - - stream-to-promise@2.2.0: - dependencies: - any-promise: 1.3.0 - end-of-stream: 1.1.0 - stream-to-array: 2.3.0 - streamx@2.28.1: dependencies: events-universal: 1.0.1 @@ -9078,7 +9432,7 @@ snapshots: tar-stream@3.1.7: dependencies: - b4a: 1.8.1 + b4a: 1.9.0 fast-fifo: 1.3.2 streamx: 2.28.1 transitivePeerDependencies: @@ -9114,7 +9468,7 @@ snapshots: text-decoder@1.2.7: dependencies: - b4a: 1.8.1 + b4a: 1.9.0 transitivePeerDependencies: - react-native-b4a @@ -9267,7 +9621,7 @@ snapshots: undici@6.28.0: {} - undici@7.29.1: {} + undici@7.30.0: {} universalify@2.0.1: {} @@ -9317,43 +9671,54 @@ snapshots: dependencies: punycode: 2.3.1 - vercel@58.4.4(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5): - dependencies: - '@vercel/backends': 0.8.30(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5) - '@vercel/blob': 2.4.0 - '@vercel/build-utils': 13.36.3 - '@vercel/cli-auth': 0.3.1 - '@vercel/cli-config': 0.2.1 - '@vercel/container': 0.1.0 - '@vercel/detect-agent': 1.2.3 - '@vercel/elysia': 0.1.107(rollup@4.63.5) - '@vercel/express': 0.1.121(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5) - '@vercel/fastify': 0.1.110(rollup@4.63.5) - '@vercel/fun': 1.3.0 - '@vercel/go': 3.10.2 - '@vercel/h3': 0.1.116(rollup@4.63.5) - '@vercel/hono': 0.2.110(rollup@4.63.5) - '@vercel/hydrogen': 1.4.0 - '@vercel/koa': 0.1.90(rollup@4.63.5) - '@vercel/nestjs': 0.2.111(rollup@4.63.5) - '@vercel/next': 4.20.5(rollup@4.63.5) - '@vercel/node': 5.9.3(rollup@4.63.5) + uuid@14.0.1: {} + + vercel@62.2.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(rollup@4.63.5): + dependencies: + '@vercel/backends': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/blob': 2.8.0 + '@vercel/build-utils': 14.15.0 + '@vercel/cli-auth': 0.3.10 + '@vercel/cli-config': 0.3.1 + '@vercel/container': 13.0.0(@vercel/build-utils@14.15.0) + '@vercel/detect-agent': 1.2.5 + '@vercel/elysia': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/express': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/fastify': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/fun': 1.3.6 + '@vercel/go': 16.0.0(@vercel/build-utils@14.15.0) + '@vercel/h3': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/hono': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/hydrogen': 14.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0) + '@vercel/koa': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/nestjs': 13.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/next': 17.0.0(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/node': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) '@vercel/prepare-flags-definitions': 0.3.0 - '@vercel/python': 6.54.1 - '@vercel/redwood': 2.5.0(rollup@4.63.5) - '@vercel/remix-builder': 5.9.1(rollup@4.63.5) - '@vercel/ruby': 2.5.1 - '@vercel/rust': 1.4.0 - '@vercel/static-build': 2.11.13 + '@vercel/python': 19.0.0(@vercel/build-utils@14.15.0) + '@vercel/python-analysis': 0.14.0 + '@vercel/redwood': 15.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/remix-builder': 18.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0)(rollup@4.63.5) + '@vercel/ruby': 15.0.0(@vercel/build-utils@14.15.0) + '@vercel/rust': 14.0.0(@vercel/build-utils@14.15.0) + '@vercel/static-build': 15.0.0(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)(@vercel/build-utils@14.15.0) chokidar: 4.0.0 esbuild: 0.28.2 jose: 5.9.6 jsonc-parser: 3.3.1 luxon: 3.7.2 - sandbox: 3.4.0 + sandbox: 4.4.0 smol-toml: 1.9.0 undici: 6.28.0 + uuid: 14.0.1 zod: 4.1.11 + optionalDependencies: + '@vercel/vc-native-darwin-arm64': 62.2.0 + '@vercel/vc-native-darwin-x64': 62.2.0 + '@vercel/vc-native-linux-arm64': 62.2.0 + '@vercel/vc-native-linux-x64': 62.2.0 + '@vercel/vc-native-win32-arm64': 62.2.0 + '@vercel/vc-native-win32-x64': 62.2.0 transitivePeerDependencies: - '@emnapi/core' - '@emnapi/runtime' @@ -9529,10 +9894,7 @@ snapshots: ws@8.21.0: {} - ws@8.21.3: {} - - ws@8.22.0: - optional: true + ws@8.22.0: {} xdg-app-paths@5.1.0: dependencies: @@ -9575,12 +9937,12 @@ snapshots: yocto-queue@0.1.0: {} - zod-validation-error@4.0.2(zod@4.5.4): + zod-validation-error@4.0.2(zod@4.6.5): dependencies: - zod: 4.5.4 + zod: 4.6.5 zod@3.22.4: {} zod@4.1.11: {} - zod@4.5.4: {} + zod@4.6.5: {} diff --git a/scripts/check-osv-exceptions.mjs b/scripts/check-osv-exceptions.mjs index 7444d6de..41842abf 100644 --- a/scripts/check-osv-exceptions.mjs +++ b/scripts/check-osv-exceptions.mjs @@ -2,13 +2,19 @@ import fs from 'node:fs' import { execFileSync } from 'node:child_process' -import { fileURLToPath } from 'node:url' +import { fileURLToPath, pathToFileURL } from 'node:url' const configPath = new URL('../osv-scanner.toml', import.meta.url) const packagePath = new URL('../package.json', import.meta.url) +// GitHub bounds both advisories to the legacy `sandbox` package below 1.0.0. +// OSV records no fixed event, so osv-scanner flags every version, including +// Vercel's unrelated vercel/sandbox releases that took over the name at 1.0.0. +const exemptPackage = 'sandbox' const expectedIds = new Set(['GHSA-fm4j-4xhm-xpwx', 'GHSA-gc25-3vc5-2jf9']) -const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8')) +const dayMs = 24 * 60 * 60 * 1000 +const reviewLeadMs = 30 * dayMs +const maxHorizonMs = 366 * dayMs const tomlParser = ` import json @@ -37,79 +43,84 @@ for item in config.get("IgnoredVulns", []): print(json.dumps(entries)) ` -const entries = JSON.parse( - execFileSync('python3', ['-c', tomlParser, fileURLToPath(configPath)], { - encoding: 'utf8', - stdio: ['ignore', 'pipe', 'inherit'], - }), -) - -if (entries.length !== expectedIds.size) { - throw new Error(`Expected exactly ${expectedIds.size} OSV exceptions, found ${entries.length}`) -} - -const reviewLeadMs = 30 * 24 * 60 * 60 * 1000 -const reviewDeadline = Date.now() + reviewLeadMs -const seen = new Set() -for (const entry of entries) { - if (!expectedIds.has(entry.id)) throw new Error(`Unexpected OSV exception: ${entry.id}`) - if (seen.has(entry.id)) throw new Error(`Duplicate OSV exception: ${entry.id}`) - seen.add(entry.id) +function collectOccurrences(value, path) { + const found = [] + if (!value || typeof value !== 'object') return found + if (value.from === exemptPackage) found.push({ node: value, path }) + for (const [key, child] of Object.entries(value)) found.push(...collectOccurrences(child, `${path}.${key}`)) + return found +} - const expiry = Date.parse(`${entry.ignoreUntil}T00:00:00Z`) - if (!Number.isFinite(expiry)) throw new Error(`Invalid ignoreUntil for ${entry.id}: ${entry.ignoreUntil}`) - if (expiry <= reviewDeadline) { - throw new Error(`${entry.id} expires within 30 days (${entry.ignoreUntil}); re-evaluate the exception`) +// Checks the exceptions against the condition that justifies them, so any +// lockfile change that invalidates them fails here instead of relying on a +// pinned Vercel CLI version to force a manual re-review. +export function checkOsvExceptions(entries, projects, rootName, now = Date.now()) { + if (entries.length !== expectedIds.size) { + throw new Error(`Expected exactly ${expectedIds.size} OSV exceptions, found ${entries.length}`) } - - const advisoryUrl = `https://github.com/advisories/${entry.id}` - if (!entry.reason.includes('sandbox@3.4.0') || !entry.reason.includes(advisoryUrl)) { - throw new Error(`${entry.id} must retain the package identity and advisory evidence in its reason`) + const seen = new Set() + for (const entry of entries) { + if (!expectedIds.has(entry.id)) throw new Error(`Unexpected OSV exception: ${entry.id}`) + if (seen.has(entry.id)) throw new Error(`Duplicate OSV exception: ${entry.id}`) + seen.add(entry.id) + + const expiry = Date.parse(`${entry.ignoreUntil}T00:00:00Z`) + if (!Number.isFinite(expiry)) throw new Error(`Invalid ignoreUntil for ${entry.id}: ${entry.ignoreUntil}`) + if (expiry <= now + reviewLeadMs) { + throw new Error(`${entry.id} expires within 30 days (${entry.ignoreUntil}); re-evaluate the exception`) + } + if (expiry > now + maxHorizonMs) { + throw new Error(`${entry.id} expires more than a year out (${entry.ignoreUntil}); exceptions need yearly review`) + } + + const advisoryUrl = `https://github.com/advisories/${entry.id}` + if (!entry.reason.includes('vercel/sandbox') || !entry.reason.includes(advisoryUrl)) { + throw new Error(`${entry.id} must retain the package identity and advisory evidence in its reason`) + } } -} - -if (packageJson.devDependencies?.vercel !== '58.4.4') { - throw new Error('Re-evaluate OSV exceptions when the pinned Vercel CLI version changes') -} -const projects = JSON.parse( - execFileSync( - 'pnpm', - ['list', 'sandbox', '--recursive', '--depth', 'Infinity', '--lockfile-only', '--json'], - { encoding: 'utf8' }, - ), -) -const rootProject = projects.find((project) => project.name === packageJson.name) -if (!rootProject) { - throw new Error(`pnpm list did not return the expected root project: ${packageJson.name}`) -} - -const vercelNode = rootProject.devDependencies?.vercel -if (!vercelNode) throw new Error('pnpm list did not return the root Vercel CLI dependency') - -const sandboxNode = vercelNode.dependencies?.sandbox -if (!sandboxNode) throw new Error('pnpm list did not return the Vercel CLI -> sandbox dependency edge') - -const sandboxOccurrences = [] -function collectSandboxOccurrences(value, path = 'projects') { - if (!value || typeof value !== 'object') return - if (value.from === 'sandbox') sandboxOccurrences.push({ node: value, path }) + const rootProject = projects.find((project) => project.name === rootName) + if (!rootProject) throw new Error(`pnpm list did not return the expected root project: ${rootName}`) - for (const [key, child] of Object.entries(value)) { - collectSandboxOccurrences(child, `${path}.${key}`) + const occurrences = collectOccurrences(projects, 'projects') + if (!occurrences.length) { + throw new Error(`No ${exemptPackage} package remains in the lockfile; remove the stale OSV exceptions`) } -} -collectSandboxOccurrences(projects) - -if (sandboxOccurrences.length !== 1 || sandboxOccurrences[0].node !== sandboxNode) { - const found = sandboxOccurrences.map(({ node, path }) => `${path}@${node.version ?? 'unknown'}`).join(', ') - throw new Error(`Expected only the Vercel CLI sandbox@3.4.0 edge; found: ${found || 'none'}`) + const vercelNode = rootProject.devDependencies?.vercel + const viaVercel = new Set(collectOccurrences(vercelNode, 'vercel').map(({ node }) => node)) + const versions = new Set() + for (const { node, path } of occurrences) { + if (!viaVercel.has(node)) { + throw new Error(`${exemptPackage} is reachable outside the root Vercel CLI dependency: ${path}`) + } + const major = /^(\d+)\.\d+\.\d+$/.exec(node.version ?? '')?.[1] + if (major === undefined || Number(major) < 1) { + throw new Error(`${exemptPackage}@${node.version ?? 'unknown'} at ${path} is not a stable release outside the advisories' <1.0.0 range`) + } + versions.add(node.version) + } + return [...versions] } -const sandboxVersion = sandboxNode.version -if (sandboxVersion !== '3.4.0') { - throw new Error('Expected Vercel CLI 58.4.4 to retain its sandbox@3.4.0 dependency edge') +function main() { + const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8')) + const entries = JSON.parse( + execFileSync('python3', ['-c', tomlParser, fileURLToPath(configPath)], { + encoding: 'utf8', + stdio: ['ignore', 'pipe', 'inherit'], + }), + ) + const projects = JSON.parse( + execFileSync( + 'pnpm', + ['list', exemptPackage, '--recursive', '--depth', 'Infinity', '--lockfile-only', '--json'], + { encoding: 'utf8' }, + ), + ) + const versions = checkOsvExceptions(entries, projects, packageJson.name) + const found = versions.map((version) => `${exemptPackage}@${version}`).join(', ') + console.log(`OSV exception contract passed (${found} via the Vercel CLI is outside the <1.0.0 advisory range; review window 30 days to 1 year).`) } -console.log('OSV exception contract passed (2 package-scoped assumptions, >30-day review window).') +if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) main() diff --git a/scripts/check-osv-exceptions.test.mjs b/scripts/check-osv-exceptions.test.mjs new file mode 100644 index 00000000..c0032fd5 --- /dev/null +++ b/scripts/check-osv-exceptions.test.mjs @@ -0,0 +1,83 @@ +import assert from 'node:assert/strict' +import { readFileSync } from 'node:fs' +import { test } from 'node:test' +import { checkOsvExceptions } from './check-osv-exceptions.mjs' + +const now = Date.parse('2026-10-10T00:00:00Z') +const ids = ['GHSA-fm4j-4xhm-xpwx', 'GHSA-gc25-3vc5-2jf9'] +const entries = (change = () => {}) => ids.map((id) => { + const entry = { id, ignoreUntil: '2027-08-03', reason: `Vercel's vercel/sandbox package. See https://github.com/advisories/${id}.` } + change(entry) + return entry +}) +function projects({ vercel = '62.2.0', sandbox = { from: 'sandbox', version: '4.4.0' }, change = () => {} } = {}) { + const tree = [ + { name: 'betterman', devDependencies: { vercel: { from: 'vercel', version: vercel, dependencies: sandbox ? { sandbox } : {} } } }, + { name: 'betterman-nextjs' }, + ] + change(tree) + return tree +} + +test('accepts post-1.0.0 sandbox releases through the Vercel CLI independent of the CLI version', () => { + assert.deepEqual(checkOsvExceptions(entries(), projects(), 'betterman', now), ['4.4.0']) + assert.deepEqual(checkOsvExceptions(entries(), projects({ vercel: '58.4.4', sandbox: { from: 'sandbox', version: '3.4.0' } }), 'betterman', now), ['3.4.0']) + const nested = projects({ sandbox: null, change: (tree) => { + tree[0].devDependencies.vercel.dependencies['@vercel/cli-exec'] = { from: '@vercel/cli-exec', version: '1.0.0', dependencies: { sandbox: { from: 'sandbox', version: '5.0.0' } } } + } }) + assert.deepEqual(checkOsvExceptions(entries(), nested, 'betterman', now), ['5.0.0']) +}) + +test('rejects sandbox releases inside or not provably outside the advisory range', () => { + for (const version of ['0.8.6', '1.0.0-beta.1', '4.4.0-beta', 'npm:other@4.4.0', undefined]) { + assert.throws(() => checkOsvExceptions(entries(), projects({ sandbox: { from: 'sandbox', version } }), 'betterman', now), /not a stable release outside/) + } +}) + +test('rejects sandbox dependency paths outside the root Vercel CLI', () => { + for (const change of [ + (tree) => { tree[1].dependencies = { sandbox: { from: 'sandbox', version: '4.4.0' } } }, + (tree) => { tree[0].dependencies = { sandbox: { from: 'sandbox', version: '4.4.0' } } }, + (tree) => { tree[0].devDependencies.other = { from: 'other', version: '1.0.0', dependencies: { sandbox: { from: 'sandbox', version: '4.4.0' } } } }, + ]) assert.throws(() => checkOsvExceptions(entries(), projects({ change }), 'betterman', now), /reachable outside the root Vercel CLI/) + assert.throws(() => checkOsvExceptions(entries(), projects({ sandbox: null, change: (tree) => { + tree[1].dependencies = { sandbox: { from: 'sandbox', version: '4.4.0' } } + } }), 'betterman', now), /reachable outside/) +}) + +test('rejects stale exceptions once no sandbox package remains', () => { + assert.throws(() => checkOsvExceptions(entries(), projects({ sandbox: null }), 'betterman', now), /remove the stale OSV exceptions/) + assert.throws(() => checkOsvExceptions(entries(), [{ name: 'betterman' }], 'betterman', now), /remove the stale OSV exceptions/) + assert.throws(() => checkOsvExceptions(entries(), projects(), 'other-root', now), /expected root project/) +}) + +test('keeps the exception set narrow', () => { + assert.throws(() => checkOsvExceptions(entries().slice(1), projects(), 'betterman', now), /Expected exactly 2/) + assert.throws(() => checkOsvExceptions([...entries(), entries()[0]], projects(), 'betterman', now), /Expected exactly 2/) + assert.throws(() => checkOsvExceptions(entries((entry) => { entry.id = entry.id === ids[0] ? 'GHSA-xxxx-xxxx-xxxx' : entry.id }), projects(), 'betterman', now), /Unexpected OSV exception/) + assert.throws(() => checkOsvExceptions(entries((entry) => { entry.id = ids[0] }), projects(), 'betterman', now), /Duplicate OSV exception/) +}) + +test('requires every exception to expire between 30 days and one year out', () => { + for (const [ignoreUntil, message] of [ + ['2026-11-09', /expires within 30 days/], + ['2026-10-01', /expires within 30 days/], + ['2027-10-12', /more than a year out/], + ['2099-01-01', /more than a year out/], + ['soon', /Invalid ignoreUntil/], + ]) assert.throws(() => checkOsvExceptions(entries((entry) => { entry.ignoreUntil = ignoreUntil }), projects(), 'betterman', now), message) + assert.doesNotThrow(() => checkOsvExceptions(entries((entry) => { entry.ignoreUntil = '2027-10-11' }), projects(), 'betterman', now)) +}) + +test('requires package identity and advisory evidence in each reason', () => { + for (const reason of ['See https://github.com/advisories/GHSA-fm4j-4xhm-xpwx.', "Vercel's vercel/sandbox package.", '']) { + assert.throws(() => checkOsvExceptions(entries((entry) => { entry.reason = reason }), projects(), 'betterman', now), /package identity and advisory evidence/) + } +}) + +test('CI runs the OSV exception contract and its regression tests', () => { + const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) + assert.ok(pkg.scripts['ops:test'].split(/\s+/).includes('scripts/check-osv-exceptions.test.mjs')) + const ci = readFileSync(new URL('../.github/workflows/ci.yml', import.meta.url), 'utf8') + assert.match(ci, /^ {6}- name: Check bounded OSV exceptions\n {8}run: node scripts\/check-osv-exceptions\.mjs$/m) +}) diff --git a/scripts/check-vercel-provenance.mjs b/scripts/check-vercel-provenance.mjs index c71406bd..37f40012 100644 --- a/scripts/check-vercel-provenance.mjs +++ b/scripts/check-vercel-provenance.mjs @@ -13,7 +13,7 @@ export async function requireVercelProvenance(report, version, verifyBundle) { && item.location === 'node_modules/vercel' && item.registry === 'https://registry.npmjs.org/') const bundle = entry?.attestationBundles?.find((item) => item.predicateType === provenanceType)?.bundle if (entry?.attestations?.provenance?.predicateType !== provenanceType || !bundle?.dsseEnvelope?.payload) { - throw new Error(`vercel@${version} has no verified SLSA provenance`) + throw new Error(`vercel@${version} has no verified SLSA provenance; see docs/runbooks/vercel-ops.md#cli-provenance`) } // npm verifies the bundle but does not constrain its certificate identity. await verifyBundle(bundle, { diff --git a/scripts/check-vercel-provenance.test.mjs b/scripts/check-vercel-provenance.test.mjs index c396fd69..48439819 100644 --- a/scripts/check-vercel-provenance.test.mjs +++ b/scripts/check-vercel-provenance.test.mjs @@ -113,7 +113,9 @@ test('all production paths verify trusted tooling before deployment secrets are } const deployment = steps.find((step) => step.includes('scripts/deploy-vercel.sh')) assert.ok(deployment?.includes('export PATH="$GITHUB_WORKSPACE/tooling/node_modules/.bin:$PATH"')) - const version = JSON.parse(readRepositoryFile('package.json')).devDependencies.vercel - assert.match(version, /^\d+\.\d+\.\d+$/) - assert.ok(deployment.includes(`if [[ "$(vercel --version)" != "${version}" ]]; then`)) + assert.match(JSON.parse(readRepositoryFile('package.json')).devDependencies.vercel, /^\d+\.\d+\.\d+$/) + // The guard must compare against the same manifest the provenance gate verified. + assert.ok(deployment.includes(`trusted_vercel="$(node -p 'require(process.argv[1]).devDependencies.vercel' "$GITHUB_WORKSPACE/tooling/package.json")"`)) + assert.ok(deployment.includes('if [[ "$(vercel --version)" != "$trusted_vercel" ]]; then')) + assert.ok(deployment.indexOf('trusted_vercel=') < deployment.indexOf('scripts/deploy-vercel.sh')) })