diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62bded4..552e9b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,6 +35,21 @@ jobs: if: github.event_name == 'pull_request' run: pnpm test:fuzz:sample + security-audit: + name: Security audit (fail on unapproved critical advisories) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: pnpm/action-setup@v4 + with: + version: 10 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm audit:ci + entrypoints: name: Package entry point smoke tests runs-on: ubuntu-latest diff --git a/package.json b/package.json index 9cfd48b..c6f8dca 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,9 @@ "test:heap-leak": "node --expose-gc ./node_modules/vitest/vitest.mjs run test/leaks/heap-snapshot.test.ts --pool=threads", "size": "size-limit", "api:check": "api-extractor run --config api-extractor.json && api-extractor run --config api-extractor-evm.json && api-extractor run --config api-extractor-stellar.json && api-extractor run --config api-extractor-solana.json && api-extractor run --config api-extractor-ckb.json && api-extractor run --config api-extractor-vault.json", - "pack:check": "node scripts/release/verify-pack.mjs" + "pack:check": "node scripts/release/verify-pack.mjs", + "audit": "pnpm audit", + "audit:ci": "node scripts/security-audit.mjs" }, "size-limit": [ { @@ -180,6 +182,6 @@ "tsup": "^8.4.0", "typedoc": "^0.28.19", "typescript": "^5.7.0", - "vitest": "^3.1.0" + "vitest": "^3.2.6" } } diff --git a/packages/codemod/package.json b/packages/codemod/package.json index 054be1a..531a0e9 100644 --- a/packages/codemod/package.json +++ b/packages/codemod/package.json @@ -29,6 +29,6 @@ "@types/node": "^20.19.43", "tsup": "^8.4.0", "typescript": "^5.7.0", - "vitest": "^3.1.0" + "vitest": "^3.2.6" } } diff --git a/packages/sdk-agent/package.json b/packages/sdk-agent/package.json index 94f6ce9..633cd80 100644 --- a/packages/sdk-agent/package.json +++ b/packages/sdk-agent/package.json @@ -26,6 +26,6 @@ "devDependencies": { "tsup": "^8.0.0", "typescript": "^5.0.0", - "vitest": "^3.0.0" + "vitest": "^3.2.6" } } diff --git a/packages/sdk-react/package.json b/packages/sdk-react/package.json index ad2589f..786f797 100644 --- a/packages/sdk-react/package.json +++ b/packages/sdk-react/package.json @@ -37,7 +37,7 @@ "@types/react-dom": "^18.0.0", "tsup": "^8.0.0", "typescript": "^5.0.0", - "vitest": "^3.0.0", + "vitest": "^3.2.6", "@testing-library/react": "^14.0.0", "@testing-library/jest-dom": "^6.0.0", "jsdom": "^24.0.0" diff --git a/packages/sdk-solid/package.json b/packages/sdk-solid/package.json index 27c231a..6dad410 100644 --- a/packages/sdk-solid/package.json +++ b/packages/sdk-solid/package.json @@ -37,6 +37,6 @@ "tsup": "^8.4.0", "typescript": "^5.7.0", "vite-plugin-solid": "^2.11.0", - "vitest": "^3.1.0" + "vitest": "^3.2.6" } } diff --git a/packages/sdk-svelte/package.json b/packages/sdk-svelte/package.json index 92a9e2d..9171d0b 100644 --- a/packages/sdk-svelte/package.json +++ b/packages/sdk-svelte/package.json @@ -37,7 +37,7 @@ "svelte": "^5.0.0", "tsup": "^8.4.0", "typescript": "^5.7.0", - "vitest": "^3.1.0", + "vitest": "^3.2.6", "@sveltejs/vite-plugin-svelte": "^5.0.0", "svelte-check": "^4.0.0" } diff --git a/packages/sdk-vue/package.json b/packages/sdk-vue/package.json index a2e5877..1444e98 100644 --- a/packages/sdk-vue/package.json +++ b/packages/sdk-vue/package.json @@ -30,7 +30,7 @@ "devDependencies": { "tsup": "^8.4.0", "typescript": "^5.7.0", - "vitest": "^3.1.0", + "vitest": "^3.2.6", "@vue/test-utils": "^2.4.0", "jsdom": "^25.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 88976b8..16672a6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,8 +85,8 @@ importers: specifier: ^5.7.0 version: 5.9.3 vitest: - specifier: ^3.1.0 - version: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + specifier: ^3.2.6 + version: 3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) examples/agent: dependencies: @@ -530,8 +530,8 @@ importers: specifier: ^5.7.0 version: 5.9.3 vitest: - specifier: ^3.1.0 - version: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + specifier: ^3.2.6 + version: 3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) packages/sdk-agent: dependencies: @@ -546,8 +546,8 @@ importers: specifier: ^5.0.0 version: 5.9.3 vitest: - specifier: ^3.0.0 - version: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + specifier: ^3.2.6 + version: 3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) packages/sdk-react: dependencies: @@ -586,8 +586,8 @@ importers: specifier: ^5.0.0 version: 5.9.3 vitest: - specifier: ^3.0.0 - version: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@24.1.3(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + specifier: ^3.2.6 + version: 3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@24.1.3(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) packages/sdk-solid: dependencies: @@ -620,8 +620,8 @@ importers: specifier: ^2.11.0 version: 2.11.14(@testing-library/jest-dom@6.9.1)(solid-js@1.9.15)(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0)) vitest: - specifier: ^3.1.0 - version: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + specifier: ^3.2.6 + version: 3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) packages/sdk-svelte: dependencies: @@ -640,7 +640,7 @@ importers: version: 5.1.1(svelte@5.56.4)(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0)) '@testing-library/svelte': specifier: ^5.2.0 - version: 5.4.2(svelte@5.56.4)(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0))(vitest@3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0)) + version: 5.4.2(svelte@5.56.4)(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0))(vitest@3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0)) jsdom: specifier: ^25.0.0 version: 25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -657,8 +657,8 @@ importers: specifier: ^5.7.0 version: 5.9.3 vitest: - specifier: ^3.1.0 - version: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + specifier: ^3.2.6 + version: 3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) packages/sdk-vue: dependencies: @@ -685,8 +685,8 @@ importers: specifier: ^5.7.0 version: 5.9.3 vitest: - specifier: ^3.1.0 - version: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + specifier: ^3.2.6 + version: 3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) packages/test-vectors: devDependencies: @@ -3145,11 +3145,11 @@ packages: vite: ^5.0.0 || ^6.0.0 vue: ^3.2.25 - '@vitest/expect@3.2.4': - resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + '@vitest/expect@3.2.7': + resolution: {integrity: sha512-E8eBXaKibuvH2pSZErOjdVb5vF4PbKYcrnluBTYxEk1l/VhhwZg1kZQsdtjq+CsF5CFydf2Rdkz7jDHKSisi3w==} - '@vitest/mocker@3.2.4': - resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + '@vitest/mocker@3.2.7': + resolution: {integrity: sha512-Trr0hYO9CM3Wj6ksWHRhK9IZpIY6wTMO5u/MqXurMxT57sWBaOPEtP3Oq60ihZuh5JsiagKfz95OcxdEP6dBrA==} peerDependencies: msw: ^2.4.9 vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 @@ -3159,20 +3159,20 @@ packages: vite: optional: true - '@vitest/pretty-format@3.2.4': - resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + '@vitest/pretty-format@3.2.7': + resolution: {integrity: sha512-KUHlwqVu0sRlhCdyPdQ/wBoTfRahjUky1MubOmYw9fWfIZy1gNoHpuaaQBPAaMaVYdQYHJLurzj8ECCj5OwTqA==} - '@vitest/runner@3.2.4': - resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + '@vitest/runner@3.2.7': + resolution: {integrity: sha512-sB9y4ovltoQP+WaUPwmSxO9WIg9Ig694Di5PalVPsYHklAdE027mehpWF2SQSVq+k6sFgaivbTjTJwZLSHbedA==} - '@vitest/snapshot@3.2.4': - resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + '@vitest/snapshot@3.2.7': + resolution: {integrity: sha512-7C+MwShwtBSI5Buwoyg3s/iY1eHL9PKAf+O1wVh/TdnjXUtkoL/9YQtre90i4MtNXM6edP1wJ2zOBpfCyhIS7g==} - '@vitest/spy@3.2.4': - resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + '@vitest/spy@3.2.7': + resolution: {integrity: sha512-Q2eQGI6d2L/hBtZ0qNuKcAGid68XK6cv1xsoaIma6PaJhHPoqcEJhYpXZ/5myCMqkNgtP6UKuBhbc0nHKnrkuQ==} - '@vitest/utils@3.2.4': - resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + '@vitest/utils@3.2.7': + resolution: {integrity: sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==} '@volar/language-core@2.4.15': resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==} @@ -7560,16 +7560,16 @@ packages: vite: optional: true - vitest@3.2.4: - resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + 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/debug': ^4.1.12 '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - '@vitest/browser': 3.2.4 - '@vitest/ui': 3.2.4 + '@vitest/browser': 3.2.7 + '@vitest/ui': 3.2.7 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -10606,14 +10606,14 @@ snapshots: dependencies: svelte: 5.56.4 - '@testing-library/svelte@5.4.2(svelte@5.56.4)(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0))(vitest@3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0))': + '@testing-library/svelte@5.4.2(svelte@5.56.4)(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0))(vitest@3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0))': dependencies: '@testing-library/dom': 9.3.4 '@testing-library/svelte-core': 1.1.3(svelte@5.56.4) svelte: 5.56.4 optionalDependencies: vite: 7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) - vitest: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + vitest: 3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) '@types/argparse@1.0.38': {} @@ -10806,45 +10806,45 @@ snapshots: vite: 6.4.3(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) vue: 3.5.39(typescript@5.9.3) - '@vitest/expect@3.2.4': + '@vitest/expect@3.2.7': dependencies: '@types/chai': 5.2.3 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 + '@vitest/spy': 3.2.7 + '@vitest/utils': 3.2.7 chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0))': + '@vitest/mocker@3.2.7(vite@6.4.3(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0))': dependencies: - '@vitest/spy': 3.2.4 + '@vitest/spy': 3.2.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + vite: 6.4.3(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) - '@vitest/pretty-format@3.2.4': + '@vitest/pretty-format@3.2.7': dependencies: tinyrainbow: 2.0.0 - '@vitest/runner@3.2.4': + '@vitest/runner@3.2.7': dependencies: - '@vitest/utils': 3.2.4 + '@vitest/utils': 3.2.7 pathe: 2.0.3 strip-literal: 3.1.0 - '@vitest/snapshot@3.2.4': + '@vitest/snapshot@3.2.7': dependencies: - '@vitest/pretty-format': 3.2.4 + '@vitest/pretty-format': 3.2.7 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@3.2.4': + '@vitest/spy@3.2.7': dependencies: tinyspy: 4.0.4 - '@vitest/utils@3.2.4': + '@vitest/utils@3.2.7': dependencies: - '@vitest/pretty-format': 3.2.4 + '@vitest/pretty-format': 3.2.7 loupe: 3.2.1 tinyrainbow: 2.0.0 @@ -16068,7 +16068,7 @@ snapshots: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - postcss: 8.5.9 + postcss: 8.5.16 rollup: 4.60.1 tinyglobby: 0.2.17 optionalDependencies: @@ -16087,16 +16087,16 @@ snapshots: optionalDependencies: vite: 7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) - vitest@3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@24.1.3(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0): + vitest@3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@24.1.3(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0): dependencies: '@types/chai': 5.2.3 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 + '@vitest/expect': 3.2.7 + '@vitest/mocker': 3.2.7(vite@6.4.3(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(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.3.0 @@ -16106,10 +16106,10 @@ snapshots: std-env: 3.10.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + vite: 6.4.3(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) vite-node: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: @@ -16129,16 +16129,16 @@ snapshots: - tsx - yaml - vitest@3.2.4(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0): + vitest@3.2.7(@types/node@20.19.43)(jiti@2.6.1)(jsdom@25.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6))(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0): dependencies: '@types/chai': 5.2.3 - '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0)) - '@vitest/pretty-format': 3.2.4 - '@vitest/runner': 3.2.4 - '@vitest/snapshot': 3.2.4 - '@vitest/spy': 3.2.4 - '@vitest/utils': 3.2.4 + '@vitest/expect': 3.2.7 + '@vitest/mocker': 3.2.7(vite@6.4.3(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(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.3.0 @@ -16148,10 +16148,10 @@ snapshots: std-env: 3.10.0 tinybench: 2.9.0 tinyexec: 0.3.2 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.3.2(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) + vite: 6.4.3(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) vite-node: 3.2.4(@types/node@20.19.43)(jiti@2.6.1)(terser@5.48.0)(tsx@4.23.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: diff --git a/scripts/security-audit.mjs b/scripts/security-audit.mjs new file mode 100644 index 0000000..eeba8d9 --- /dev/null +++ b/scripts/security-audit.mjs @@ -0,0 +1,129 @@ +import { execSync } from 'node:child_process'; +import { accessSync, readFileSync } from 'node:fs'; + +/** + * security-audit.mjs + * + * Runs `pnpm audit --json` and fails with a non-zero exit code when any + * advisory of severity `critical` is present in the workspace dependency graph + * that is NOT listed in the tracked-criticals allowlist. + * + * Tracked criticals are advisories that are known, have a remediation path, and + * are intentionally not blocking this release (e.g. they live in private, + * unpublished example workspaces, or in dev tooling coupled to a dependency + * that cannot be upgraded yet). Any critical advisory NOT in the allowlist + * fails the run so that regressions are caught immediately. + * + * Moderate/high/low findings are always reported but never fail the run. + * + * Usage: node scripts/security-audit.mjs + */ + +const REPO_ROOT = new URL('..', import.meta.url).pathname; +const ALLOWLIST_PATH = new URL('../security-audit.allowlist.json', import.meta.url).pathname; + +// Resolve a pnpm binary that can read this repo's pnpm 10 lockfile. In CI, +// `pnpm/action-setup@v4` (version 10) puts pnpm 10 on `PATH`; locally and after +// any workspace install, `node_modules/.bin/pnpm` is pnpm 10 as well. +function resolvePnpm() { + const local = new URL('../node_modules/.bin/pnpm', import.meta.url).pathname; + try { + accessSync(local); + return local; + } catch { + return 'pnpm'; + } +} + +const PNPM = resolvePnpm(); + +// `pnpm audit` exits non-zero whenever *any* advisory exists, so we capture its +// JSON output regardless of exit code and evaluate only critical findings here. +let auditJson; +try { + execSync(`${PNPM} audit --json`, { + cwd: REPO_ROOT, + stdio: ['pipe', 'pipe', 'pipe'], + maxBuffer: 50 * 1024 * 1024, + }); +} catch (err) { + const stderr = err.stderr ? err.stderr.toString() : ''; + const stdout = err.stdout ? err.stdout.toString() : ''; + const candidate = stdout || stderr; + try { + auditJson = JSON.parse(candidate); + } catch { + process.stderr.write( + `security-audit: pnpm audit failed and produced no parseable JSON:\n${candidate.slice(0, 2000)}\n`, + ); + process.exit(2); + } +} + +if (!auditJson || !auditJson.advisories) { + console.log('security-audit: no advisories returned by pnpm audit.'); + process.exit(0); +} + +let allowlist = []; +try { + allowlist = JSON.parse(readFileSync(ALLOWLIST_PATH, 'utf8')).entries || []; +} catch { + // No allowlist file: every critical is unapproved. + allowlist = []; +} +const allowlistedIds = new Set(allowlist.map((e) => e.id)); + +const advisories = Object.values(auditJson.advisories); +const bySeverity = {}; +for (const a of advisories) { + bySeverity[a.severity] = (bySeverity[a.severity] || 0) + 1; +} + +console.log('security-audit: advisory summary by severity:'); +for (const [sev, count] of Object.entries(bySeverity).sort()) { + console.log(` ${sev}: ${count}`); +} + +const critical = advisories.filter((a) => a.severity === 'critical'); +const unapproved = critical.filter((a) => !allowlistedIds.has(ghsaId(a))); + +if (critical.length) { + console.log(`\nsecurity-audit: ${critical.length} critical advisory(ies) detected.`); + for (const a of critical) { + const tracked = allowlistedIds.has(ghsaId(a)); + const paths = (a.findings || []).map((f) => f.paths?.[0] ?? '(unknown path)').join(', '); + const marker = tracked ? '[tracked]' : '[UNTRACKED]'; + console.error( + ` ${marker} ${ghsaId(a)} ${a.title} (module: ${a.module_name}, ` + + `installed: ${a.findings?.[0]?.version ?? '?'}, patched: ${a.patched_versions})\n` + + ` path: ${paths}`, + ); + } +} + +if (unapproved.length) { + console.error( + `\nsecurity-audit: FAILED — ${unapproved.length} unapproved critical advisory(ies):`, + ); + for (const a of unapproved) { + console.error(` - ${ghsaId(a)} ${a.title}`); + } + console.error( + 'Upgrade or replace the affected dependency paths where patched versions exist, or add the advisory to security-audit.allowlist.json with a remediation plan, then re-run `pnpm audit:ci`.', + ); + process.exit(1); +} + +if (critical.length) { + console.log( + '\nsecurity-audit: OK — all critical advisories are tracked in the allowlist with remediation plans.', + ); +} else { + console.log('\nsecurity-audit: OK — no critical advisories in the workspace graph.'); +} + +function ghsaId(a) { + const id = a.github_advisory_id || a.id || ''; + return id.startsWith('GHSA-') ? id : `GHSA-${id}`; +} diff --git a/security-audit.allowlist.json b/security-audit.allowlist.json new file mode 100644 index 0000000..953909e --- /dev/null +++ b/security-audit.allowlist.json @@ -0,0 +1,77 @@ +{ + "version": 1, + "updated": "2026-10-19", + "notes": "Critical advisories that are known and intentionally not blocking this release. Every entry has a remediation path and is tracked for a follow-up. Any critical advisory NOT listed here fails `pnpm audit:ci`. Example-only findings are separated from the published SDK report: examples are private, unpublished workspaces.", + "entries": [ + { + "id": "GHSA-5gmw-xhrv-c9v3", + "module": "tinypool", + "installed": "1.1.1", + "patched": ">=2.1.1", + "finding_path": ".>vitest>tinypool", + "scope": "root dev tooling (not published)", + "reason": "vitest 3.2.x pins tinypool ^1.1.1 and is tightly coupled to its worker-pool API, so tinypool cannot be upgraded independently without breaking vitest.", + "remediation": "Upgrade vitest to a release that depends on tinypool 2.x (vitest 5.x) and re-run `pnpm audit:ci`." + }, + { + "id": "GHSA-85c8-ppgw-ccpr", + "module": "tinypool", + "installed": "1.1.1", + "patched": ">=2.1.2", + "finding_path": ".>vitest>tinypool", + "scope": "root dev tooling (not published)", + "reason": "vitest 3.2.x pins tinypool ^1.1.1 and is tightly coupled to its worker-pool API, so tinypool cannot be upgraded independently without breaking vitest.", + "remediation": "Upgrade vitest to a release that depends on tinypool 2.x (vitest 5.x) and re-run `pnpm audit:ci`." + }, + { + "id": "GHSA-p6vx-979v-rg4c", + "module": "seroval", + "installed": "1.5.6", + "patched": ">=1.6.2", + "finding_path": "examples__stellar-solid-receive>solid-js>seroval", + "scope": "example (private, unpublished)", + "reason": "Transitive dependency of solid-js in the stellar-solid-receive example. The example is `private: true` and is not part of the published SDK report.", + "remediation": "Upgrade solid-js in examples/stellar-solid-receive so its bundled seroval reaches >=1.6.2." + }, + { + "id": "GHSA-pqg4-j6r4-53mv", + "module": "shell-quote", + "installed": "1.9.0", + "patched": ">=1.11.0", + "finding_path": "examples__react-native-stellar>react-native>@react-native-community/cli>@react-native-community/cli-tools>shell-quote", + "scope": "example (private, unpublished)", + "reason": "Deep transitive dependency of react-native/expo in the react-native-stellar example. The example is `private: true` and is not part of the published SDK report.", + "remediation": "Upgrade react-native/expo in examples/react-native-stellar so shell-quote reaches >=1.11.0." + }, + { + "id": "GHSA-23hp-3jrh-7fpw", + "module": "tar", + "installed": "6.2.1", + "patched": ">=7.5.19", + "finding_path": "examples__react-native-stellar>expo>@expo/cli>tar", + "scope": "example (private, unpublished)", + "reason": "Deep transitive dependency of expo in the react-native-stellar example. The example is `private: true` and is not part of the published SDK report.", + "remediation": "Upgrade expo in examples/react-native-stellar so tar reaches >=7.5.19." + }, + { + "id": "GHSA-p293-qw3h-jr36", + "module": "next", + "installed": "14.2.35", + "patched": ">=15.5.24", + "finding_path": "examples__stellar-nextjs-app-router>next", + "scope": "example (private, unpublished)", + "reason": "Next.js 14 in the stellar-nextjs-app-router example. The example is `private: true` and is not part of the published SDK report; upgrading Next 14→15 is a major change tracked separately.", + "remediation": "Upgrade next in examples/stellar-nextjs-app-router to >=15.5.24." + }, + { + "id": "GHSA-2xp9-vwfh-vxw4", + "module": "next", + "installed": "14.2.35", + "patched": ">=15.5.24", + "finding_path": "examples__stellar-nextjs-app-router>next", + "scope": "example (private, unpublished)", + "reason": "Next.js 14 in the stellar-nextjs-app-router example. The example is `private: true` and is not part of the published SDK report; upgrading Next 14→15 is a major change tracked separately.", + "remediation": "Upgrade next in examples/stellar-nextjs-app-router to >=15.5.24." + } + ] +}