From c7956af05a06c5f35ac0a90488c0d3e3df6527e6 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:17:31 +0000 Subject: [PATCH 01/25] refactor ci Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 290 +++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 .github/workflows/napi-integration-tests.yml diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml new file mode 100644 index 000000000..41cc6c5eb --- /dev/null +++ b/.github/workflows/napi-integration-tests.yml @@ -0,0 +1,290 @@ +name: NAPI Integration Tests + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + paths: + - 'yellowstone-grpc-client-nodejs/**' + - '.github/workflows/napi-integration-tests.yml' + push: + branches: + - 'master' + - 'v*' + tags: + - 'v*' + workflow_dispatch: + +env: + CARGO_TERM_COLOR: always + NODE_VERSION: '20.18.0' + +jobs: + # Linux x64 GNU (glibc) - Ubuntu + test-linux-x64-gnu: + name: Test Linux x64 GNU (glibc) + runs-on: ubuntu-22.04 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: yellowstone-grpc-client-nodejs/package-lock.json + + - name: Set rust version + run: | + RUST_VERSION="$(grep -oP 'channel = "\K\d\.\d+\.\d+(?=")' rust-toolchain.toml)" + echo "RUST_STABLE=$RUST_VERSION" | tee -a $GITHUB_ENV + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.RUST_STABLE }} + targets: x86_64-unknown-linux-gnu + + - name: Install system dependencies + run: | + sudo apt-get update -y + sudo apt-get install -y build-essential protobuf-compiler libsasl2-dev + + - name: Install Node dependencies + working-directory: yellowstone-grpc-client-nodejs + run: npm ci + + - name: Build NAPI binary for linux-x64-gnu + working-directory: yellowstone-grpc-client-nodejs + env: + NAPI_TARGET: x86_64-unknown-linux-gnu + LIBC: gnu + run: | + npm run build -- --platform --release --target x86_64-unknown-linux-gnu + + - name: Validate binary (GNU libc) + working-directory: yellowstone-grpc-client-nodejs + run: | + ../ci/validate-binary.sh napi/yellowstone-grpc-napi.linux-x64-gnu.node gnu x86_64 + + - name: Build TypeScript SDK + working-directory: yellowstone-grpc-client-nodejs + run: npm run build:dev + + - name: Run tests + working-directory: yellowstone-grpc-client-nodejs + env: + TEST_ENDPOINT: ${{ secrets.TEST_ENDPOINT }} + TEST_TOKEN: ${{ secrets.TEST_TOKEN }} + run: npm test + + # Linux x64 MUSL - Alpine container + test-linux-x64-musl: + name: Test Linux x64 MUSL (Alpine) + runs-on: ubuntu-22.04 + container: + image: alpine:3.19 + env: + HOME: /root + + steps: + - name: Install build dependencies in Alpine + run: | + apk add --no-cache \ + git \ + bash \ + sed \ + nodejs \ + npm \ + python3 \ + make \ + g++ \ + gcc \ + musl-dev \ + linux-headers \ + protobuf-dev \ + cyrus-sasl-dev \ + curl \ + file \ + binutils + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set rust version (BusyBox compatible) + run: | + RUST_VERSION="$(sed -n 's/channel = "\([0-9]\+\.[0-9]\+\.[0-9]\+\)".*/\1/p' rust-toolchain.toml)" + echo "RUST_STABLE=$RUST_VERSION" | tee -a $GITHUB_ENV + echo "Rust version: $RUST_VERSION" + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.RUST_STABLE }} + targets: x86_64-unknown-linux-musl + + - name: Verify Rust installation + run: | + echo "PATH: $PATH" + which rustc + rustc --version + which cargo + cargo --version + + - name: Install Node dependencies + working-directory: yellowstone-grpc-client-nodejs + run: npm ci + + - name: Build NAPI binary for linux-x64-musl + working-directory: yellowstone-grpc-client-nodejs + env: + NAPI_TARGET: x86_64-unknown-linux-musl + LIBC: musl + run: | + npm run build -- --platform --release --target x86_64-unknown-linux-musl + + - name: Validate binary (MUSL libc) + working-directory: yellowstone-grpc-client-nodejs + run: | + ../ci/validate-binary.sh napi/yellowstone-grpc-napi.linux-x64-musl.node musl x86_64 + + - name: Build TypeScript SDK + working-directory: yellowstone-grpc-client-nodejs + run: npm run build:dev + + - name: Run tests + working-directory: yellowstone-grpc-client-nodejs + env: + TEST_ENDPOINT: ${{ secrets.TEST_ENDPOINT }} + TEST_TOKEN: ${{ secrets.TEST_TOKEN }} + run: npm test + + # macOS x64 (Intel) + test-macos-x64: + name: Test macOS x64 (Intel) + runs-on: macos-15-intel + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: yellowstone-grpc-client-nodejs/package-lock.json + + - name: Set rust version + run: | + RUST_VERSION="$(sed -n 's/^channel = "\([0-9.]*\)"/\1/p' rust-toolchain.toml)" + echo "RUST_STABLE=$RUST_VERSION" | tee -a "$GITHUB_ENV" + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.RUST_STABLE }} + targets: x86_64-apple-darwin + + - name: Install system dependencies + run: | + brew install protobuf + + - name: Install Node dependencies + working-directory: yellowstone-grpc-client-nodejs + run: npm ci + + - name: Build NAPI binary for darwin-x64 + working-directory: yellowstone-grpc-client-nodejs + env: + NAPI_TARGET: x86_64-apple-darwin + run: | + npm run build -- --platform --release --target x86_64-apple-darwin + + - name: Validate binary (macOS x64) + working-directory: yellowstone-grpc-client-nodejs + run: | + ../ci/validate-binary-macos.sh napi/yellowstone-grpc-napi.darwin-x64.node x86_64 + + - name: Build TypeScript SDK + working-directory: yellowstone-grpc-client-nodejs + run: npm run build:dev + + - name: Run tests + working-directory: yellowstone-grpc-client-nodejs + env: + TEST_ENDPOINT: ${{ secrets.TEST_ENDPOINT }} + TEST_TOKEN: ${{ secrets.TEST_TOKEN }} + run: npm test + + # # macOS ARM64 (Apple Silicon) + # test-macos-arm64: + # name: Test macOS ARM64 (Apple Silicon) + # runs-on: macos-latset + + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + + # - name: Set up Node.js + # uses: actions/setup-node@v4 + # with: + # node-version: ${{ env.NODE_VERSION }} + # cache: 'npm' + # cache-dependency-path: yellowstone-grpc-client-nodejs/package-lock.json + + # - name: Set rust version + # run: | + # RUST_VERSION="$(grep -oP 'channel = "\K\d\.\d+\.\d+(?=")' rust-toolchain.toml)" + # echo "RUST_STABLE=$RUST_VERSION" | tee -a $GITHUB_ENV + + # - name: Install Rust toolchain + # uses: dtolnay/rust-toolchain@stable + # with: + # toolchain: ${{ env.RUST_STABLE }} + # targets: aarch64-apple-darwin + + # - name: Install system dependencies + # run: | + # brew install protobuf + + # - name: Install Node dependencies + # working-directory: yellowstone-grpc-client-nodejs + # run: npm ci + + # - name: Build NAPI binary for darwin-arm64 + # working-directory: yellowstone-grpc-client-nodejs + # env: + # NAPI_TARGET: aarch64-apple-darwin + # run: | + # npm run build -- --platform --release --target aarch64-apple-darwin + + # - name: Validate binary (macOS ARM64) + # working-directory: yellowstone-grpc-client-nodejs + # run: | + # ../ci/validate-binary-macos.sh napi/yellowstone-grpc-napi.darwin-arm64.node arm64 + + # - name: Build TypeScript SDK + # working-directory: yellowstone-grpc-client-nodejs + # run: npm run build:dev + + # - name: Run tests + # working-directory: yellowstone-grpc-client-nodejs + # env: + # TEST_ENDPOINT: ${{ secrets.TEST_ENDPOINT }} + # TEST_TOKEN: ${{ secrets.TEST_TOKEN }} + # run: npm test + + # Release gate - all tests must pass + integration-tests-complete: + name: All Integration Tests Passed + needs: [test-linux-x64-gnu, test-linux-x64-musl, test-macos-x64] #test-macos-arm64] + runs-on: ubuntu-latest + steps: + - name: Mark as complete + run: echo "All NAPI integration tests passed successfully" + From 57e0d31a7be56931ea9f0fe31593260cf1d294cd Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Wed, 21 Jan 2026 07:30:33 +0000 Subject: [PATCH 02/25] fix tests, install musl dependencies Signed-off-by: GitHub --- .../__tests__/subscribe.test.ts | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts index cade8e0b0..1a2456e98 100644 --- a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts +++ b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts @@ -67,7 +67,7 @@ describe("subscribe response schema tests", () => { // See issue here: https://github.com/jestjs/jest/issues/2549 expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); expect(typeof response.account).toBe("object"); - expect(typeof response.account.slot).toBe("bigint"); + expect(typeof response.account.slot).toBe("string"); expect(typeof response.account.isStartup).toBe("boolean"); expect(typeof response.account.account).toBe("object"); @@ -75,9 +75,9 @@ describe("subscribe response schema tests", () => { expect(account.pubkey).toBeInstanceOf(Buffer); expect(account.owner).toBeInstanceOf(Buffer); expect(account.data).toBeInstanceOf(Buffer); - expect(typeof account.lamports).toBe("bigint"); - expect(typeof account.rentEpoch).toBe("bigint"); - expect(typeof account.writeVersion).toBe("bigint"); + expect(typeof account.lamports).toBe("string"); + expect(typeof account.rentEpoch).toBe("string"); + expect(typeof account.writeVersion).toBe("string"); expect(typeof account.executable).toBe("boolean"); }, TEST_TIMEOUT); @@ -124,7 +124,7 @@ describe("subscribe response schema tests", () => { // See issue here: https://github.com/jestjs/jest/issues/2549 expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); expect(typeof response.slot).toBe("object"); - expect(typeof response.slot.slot).toBe("bigint"); + expect(typeof response.slot.slot).toBe("string"); expect(typeof response.slot.status).toBe("number"); }, TEST_TIMEOUT); @@ -171,13 +171,13 @@ describe("subscribe response schema tests", () => { // See issue here: https://github.com/jestjs/jest/issues/2549 expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); expect(typeof response.transaction).toBe("object"); - expect(typeof response.transaction.slot).toBe("bigint"); + expect(typeof response.transaction.slot).toBe("string"); const tx = response.transaction.transaction; expect(tx.signature).toBeInstanceOf(Buffer); expect(typeof tx.transaction).toBe("object"); expect(typeof tx.meta).toBe("object"); - expect(typeof tx.index).toBe("bigint"); + expect(typeof tx.index).toBe("string"); expect(typeof tx.isVote).toBe("boolean"); const txMeta = response.transaction.transaction.meta; @@ -193,9 +193,9 @@ describe("subscribe response schema tests", () => { expect(typeof txMeta.innerInstructionsNone).toBe("boolean"); expect(typeof txMeta.logMessagesNone).toBe("boolean"); expect(typeof txMeta.returnDataNone).toBe("boolean"); - expect(typeof txMeta.computeUnitsConsumed).toBe("bigint"); - expect(typeof txMeta.fee).toBe("bigint"); - expect(typeof txMeta.costUnits).toBe("bigint"); + expect(typeof txMeta.computeUnitsConsumed).toBe("string"); + expect(typeof txMeta.fee).toBe("string"); + expect(typeof txMeta.costUnits).toBe("string"); const innerTx = response.transaction.transaction.transaction; expect(Object.prototype.toString.call(innerTx.signatures)).toBe("[object Array]"); @@ -257,13 +257,13 @@ describe("subscribe response schema tests", () => { expect(Object.prototype.toString.call(response.block.accounts)).toBe("[object Array]"); expect(Object.prototype.toString.call(response.block.transactions)).toBe("[object Array]"); expect(typeof response.block).toBe("object"); - expect(typeof response.block.slot).toBe("bigint"); + expect(typeof response.block.slot).toBe("string"); expect(typeof response.block.blockhash).toBe("string"); - expect(typeof response.block.parentSlot).toBe("bigint"); + expect(typeof response.block.parentSlot).toBe("string"); expect(typeof response.block.parentBlockhash).toBe("string"); - expect(typeof response.block.executedTransactionCount).toBe("bigint"); - expect(typeof response.block.updatedAccountCount).toBe("bigint"); - expect(typeof response.block.entriesCount).toBe("bigint"); + expect(typeof response.block.executedTransactionCount).toBe("string"); + expect(typeof response.block.updatedAccountCount).toBe("string"); + expect(typeof response.block.entriesCount).toBe("string"); const rewards = response.block.rewards; expect(typeof rewards).toBe("object"); @@ -275,7 +275,7 @@ describe("subscribe response schema tests", () => { const blockHeight = response.block.blockHeight; expect(typeof blockHeight).toBe("object"); - expect(typeof blockHeight.blockHeight).toBe("bigint"); + expect(typeof blockHeight.blockHeight).toBe("string"); }, TEST_TIMEOUT); @@ -321,11 +321,11 @@ describe("subscribe response schema tests", () => { // See issue here: https://github.com/jestjs/jest/issues/2549 expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); expect(typeof response.entry).toBe("object"); - expect(typeof response.entry.slot).toBe("bigint"); - expect(typeof response.entry.index).toBe("bigint"); - expect(typeof response.entry.numHashes).toBe("bigint"); - expect(typeof response.entry.executedTransactionCount).toBe("bigint"); - expect(typeof response.entry.startingTransactionIndex).toBe("bigint"); + expect(typeof response.entry.slot).toBe("string"); + expect(typeof response.entry.index).toBe("string"); + expect(typeof response.entry.numHashes).toBe("string"); + expect(typeof response.entry.executedTransactionCount).toBe("string"); + expect(typeof response.entry.startingTransactionIndex).toBe("string"); expect(response.entry.hash).toBeInstanceOf(Buffer); }, TEST_TIMEOUT); @@ -419,12 +419,12 @@ describe("subscribe response schema tests", () => { // See issue here: https://github.com/jestjs/jest/issues/2549 expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); expect(typeof response.blockMeta).toBe("object"); - expect(typeof response.blockMeta.slot).toBe("bigint"); + expect(typeof response.blockMeta.slot).toBe("string"); expect(typeof response.blockMeta.blockhash).toBe("string"); - expect(typeof response.blockMeta.parentSlot).toBe("bigint"); + expect(typeof response.blockMeta.parentSlot).toBe("string"); expect(typeof response.blockMeta.parentBlockhash).toBe("string"); - expect(typeof response.blockMeta.executedTransactionCount).toBe("bigint"); - expect(typeof response.blockMeta.entriesCount).toBe("bigint"); + expect(typeof response.blockMeta.executedTransactionCount).toBe("string"); + expect(typeof response.blockMeta.entriesCount).toBe("string"); const rewards = response.blockMeta.rewards; expect(typeof rewards).toBe("object"); @@ -436,7 +436,7 @@ describe("subscribe response schema tests", () => { const blockHeight = response.blockMeta.blockHeight; expect(typeof blockHeight).toBe("object"); - expect(typeof blockHeight.blockHeight).toBe("bigint"); + expect(typeof blockHeight.blockHeight).toBe("string"); }, TEST_TIMEOUT); }); From fee23f6a0cca5ef1c6be74c5fb3f667ecf7bae47 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Wed, 21 Jan 2026 06:38:57 +0000 Subject: [PATCH 03/25] ci, test fix Signed-off-by: GitHub --- yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts index 1a2456e98..5a326a1ff 100644 --- a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts +++ b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts @@ -13,6 +13,10 @@ describe("subscribe response schema tests", () => { const channelOptions = {}; const client = new Client(endpoint, xToken, channelOptions); + beforeAll(async () => { + await client.connect(); + }); + // A helper function to check the Buffer structure repeatedly const expectBufferSchema = (bufferObject: any) => { expect(bufferObject).toEqual( From 4ac9333880838863570deea04e429e4b82a29674 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Wed, 21 Jan 2026 06:25:07 +0000 Subject: [PATCH 04/25] fix ci Signed-off-by: GitHub --- yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts index 5a326a1ff..d8c5a78dd 100644 --- a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts +++ b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts @@ -1,6 +1,6 @@ import Client from "../src" -describe("subscribe response schema tests", () => { +describe("subscribe response schema tests", async () => { const TEST_TIMEOUT = 100000; // .env From 1af9d8423c5cd8f2dd96c9293131a5a2369274d2 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Wed, 21 Jan 2026 04:21:02 +0000 Subject: [PATCH 05/25] run on correct targets Signed-off-by: GitHub From eed55c59bfa644f6fee3da3fb37653cdb107d22c Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Thu, 22 Jan 2026 09:54:56 +0000 Subject: [PATCH 06/25] modify triggers Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index 41cc6c5eb..9ec9af830 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -9,12 +9,6 @@ on: paths: - 'yellowstone-grpc-client-nodejs/**' - '.github/workflows/napi-integration-tests.yml' - push: - branches: - - 'master' - - 'v*' - tags: - - 'v*' workflow_dispatch: env: From 74adc281585d6b4bd0ca8c4455ed2e68124f9296 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Thu, 22 Jan 2026 10:26:43 +0000 Subject: [PATCH 07/25] add shell files for binary verification Signed-off-by: GitHub --- ci/validate-binary-macos.sh | 87 +++++++++++++++++++++++++++++++++ ci/validate-binary.sh | 96 +++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 ci/validate-binary-macos.sh create mode 100644 ci/validate-binary.sh diff --git a/ci/validate-binary-macos.sh b/ci/validate-binary-macos.sh new file mode 100644 index 000000000..4e5ee3a6c --- /dev/null +++ b/ci/validate-binary-macos.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Script to validate macOS NAPI binary +# Usage: ./validate-binary-macos.sh +# arch: x86_64 or arm64 + +BINARY_PATH="${1:-}" +ARCH="${2:-}" + +if [[ -z "$BINARY_PATH" || -z "$ARCH" ]]; then + echo "Error: Missing required arguments" + echo "Usage: $0 " + echo " arch: x86_64 or arm64" + exit 1 +fi + +if [[ ! -f "$BINARY_PATH" ]]; then + echo "Error: Binary not found at $BINARY_PATH" + exit 1 +fi + +echo "==========================================" +echo "Validating macOS NAPI Binary" +echo "==========================================" +echo "Binary: $BINARY_PATH" +echo "Expected arch: $ARCH" +echo "" + +# Check file type +echo "File type:" +file "$BINARY_PATH" +echo "" + +# Verify it's a Mach-O binary +if ! file "$BINARY_PATH" | grep -q "Mach-O"; then + echo "Error: Binary is not a Mach-O file" + exit 1 +fi + +# Verify architecture with file command +if [[ "$ARCH" == "x86_64" ]]; then + if ! file "$BINARY_PATH" | grep -q "x86_64"; then + echo "Error: Binary is not x86_64 architecture" + exit 1 + fi +elif [[ "$ARCH" == "arm64" ]]; then + if ! file "$BINARY_PATH" | grep -q "arm64"; then + echo "Error: Binary is not arm64 architecture" + exit 1 + fi +fi + +# Check dynamic library dependencies with otool +echo "Dynamic library dependencies (otool -L):" +otool -L "$BINARY_PATH" +echo "" + +# Get detailed architecture info +echo "Architecture details (lipo -info):" +lipo -info "$BINARY_PATH" +echo "" + +# Verify architecture matches with lipo +if [[ "$ARCH" == "x86_64" ]]; then + if ! lipo -info "$BINARY_PATH" | grep -q "x86_64"; then + echo "Error: lipo shows binary is not x86_64" + exit 1 + fi +elif [[ "$ARCH" == "arm64" ]]; then + if ! lipo -info "$BINARY_PATH" | grep -q "arm64"; then + echo "Error: lipo shows binary is not arm64" + exit 1 + fi +fi + +# Check Mach-O header +echo "Mach-O header (otool -h):" +otool -h "$BINARY_PATH" +echo "" + +echo "==========================================" +echo "Binary validation PASSED ✓" +echo "==========================================" +echo "Binary: $BINARY_PATH" +echo "Architecture: $ARCH" +echo "" diff --git a/ci/validate-binary.sh b/ci/validate-binary.sh new file mode 100644 index 000000000..9aebb531a --- /dev/null +++ b/ci/validate-binary.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Script to validate Linux NAPI binary +# Usage: ./validate-binary.sh +# libc_type: gnu or musl +# arch: x86_64 or aarch64 + +BINARY_PATH="${1:-}" +LIBC_TYPE="${2:-}" +ARCH="${3:-}" + +if [[ -z "$BINARY_PATH" || -z "$LIBC_TYPE" || -z "$ARCH" ]]; then + echo "Error: Missing required arguments" + echo "Usage: $0 " + echo " libc_type: gnu or musl" + echo " arch: x86_64 or aarch64" + exit 1 +fi + +if [[ ! -f "$BINARY_PATH" ]]; then + echo "Error: Binary not found at $BINARY_PATH" + exit 1 +fi + +echo "==========================================" +echo "Validating NAPI Binary" +echo "==========================================" +echo "Binary: $BINARY_PATH" +echo "Expected libc: $LIBC_TYPE" +echo "Expected arch: $ARCH" +echo "" + +# Check file type +echo "File type:" +file "$BINARY_PATH" +echo "" + +# Verify it's a shared object +if ! file "$BINARY_PATH" | grep -q "shared object"; then + echo "Error: Binary is not a shared object" + exit 1 +fi + +# Verify architecture +if [[ "$ARCH" == "x86_64" ]]; then + if ! file "$BINARY_PATH" | grep -q "x86-64"; then + echo "Error: Binary is not x86-64 architecture" + exit 1 + fi +elif [[ "$ARCH" == "aarch64" ]]; then + if ! file "$BINARY_PATH" | grep -q "aarch64"; then + echo "Error: Binary is not aarch64 architecture" + exit 1 + fi +fi + +# Check libc linkage with ldd +echo "Library dependencies (ldd):" +ldd "$BINARY_PATH" || true +echo "" + +# Verify libc type +if [[ "$LIBC_TYPE" == "gnu" ]]; then + if ldd "$BINARY_PATH" 2>&1 | grep -q "musl"; then + echo "Error: Binary is linked against musl, expected glibc" + exit 1 + fi + # Check for glibc + if ! ldd "$BINARY_PATH" 2>&1 | grep -q "libc.so"; then + echo "Warning: Could not verify glibc linkage" + fi +elif [[ "$LIBC_TYPE" == "musl" ]]; then + if ! ldd "$BINARY_PATH" 2>&1 | grep -qi "musl"; then + echo "Error: Binary is not linked against musl" + exit 1 + fi +fi + +# Get readelf output for detailed verification +echo "ELF Header:" +readelf -h "$BINARY_PATH" | head -n 20 +echo "" + +# Check dynamic section +echo "Dynamic section (first 20 entries):" +readelf -d "$BINARY_PATH" | head -n 20 +echo "" + +echo "==========================================" +echo "Binary validation PASSED ✓" +echo "==========================================" +echo "Binary: $BINARY_PATH" +echo "Architecture: $ARCH" +echo "Libc: $LIBC_TYPE" +echo "" From 96c9bfc61feef86d76f506725db473d89b7e0524 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Thu, 22 Jan 2026 13:36:29 +0000 Subject: [PATCH 08/25] chmod shell scripts Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index 9ec9af830..8ccb99648 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -63,6 +63,7 @@ jobs: - name: Validate binary (GNU libc) working-directory: yellowstone-grpc-client-nodejs run: | + chmod u+x ../ci/validate-binary.sh ../ci/validate-binary.sh napi/yellowstone-grpc-napi.linux-x64-gnu.node gnu x86_64 - name: Build TypeScript SDK @@ -144,6 +145,7 @@ jobs: - name: Validate binary (MUSL libc) working-directory: yellowstone-grpc-client-nodejs run: | + chmod u+x ../ci/validate-binary.sh ../ci/validate-binary.sh napi/yellowstone-grpc-napi.linux-x64-musl.node musl x86_64 - name: Build TypeScript SDK @@ -202,6 +204,7 @@ jobs: - name: Validate binary (macOS x64) working-directory: yellowstone-grpc-client-nodejs run: | + chmod u+x ../ci/validate-binary-macos.sh ../ci/validate-binary-macos.sh napi/yellowstone-grpc-napi.darwin-x64.node x86_64 - name: Build TypeScript SDK @@ -260,6 +263,7 @@ jobs: # - name: Validate binary (macOS ARM64) # working-directory: yellowstone-grpc-client-nodejs # run: | + # chmod u+x ../ci/validate-binary-macos.sh # ../ci/validate-binary-macos.sh napi/yellowstone-grpc-napi.darwin-arm64.node arm64 # - name: Build TypeScript SDK From 1e676a52878dbe76ed04a4ce4cabb059de76629e Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Thu, 22 Jan 2026 14:11:43 +0000 Subject: [PATCH 09/25] fix test, validation Signed-off-by: GitHub --- ci/validate-binary.sh | 30 ++++++++++++++----- .../__tests__/subscribe.test.ts | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/ci/validate-binary.sh b/ci/validate-binary.sh index 9aebb531a..ffe579827 100644 --- a/ci/validate-binary.sh +++ b/ci/validate-binary.sh @@ -60,19 +60,33 @@ echo "Library dependencies (ldd):" ldd "$BINARY_PATH" || true echo "" -# Verify libc type +# Verify libc type using the ELF interpreter when available. +# ldd on musl can emit relocation errors for node addons because N-API +# symbols are resolved by the Node runtime, not the loader. +INTERPRETER="$(readelf -l "$BINARY_PATH" 2>/dev/null | awk -F': ' '/Requesting program interpreter/ {print $2; exit}')" +echo "ELF interpreter: ${INTERPRETER:-unknown}" +echo "" + if [[ "$LIBC_TYPE" == "gnu" ]]; then - if ldd "$BINARY_PATH" 2>&1 | grep -q "musl"; then - echo "Error: Binary is linked against musl, expected glibc" + if [[ -z "$INTERPRETER" ]]; then + echo "Error: Missing ELF interpreter; expected glibc loader (ld-linux)" exit 1 fi - # Check for glibc - if ! ldd "$BINARY_PATH" 2>&1 | grep -q "libc.so"; then - echo "Warning: Could not verify glibc linkage" + if ! echo "$INTERPRETER" | grep -q "ld-linux"; then + echo "Error: Expected glibc interpreter (ld-linux), got: $INTERPRETER" + exit 1 + fi + if echo "$INTERPRETER" | grep -q "ld-musl"; then + echo "Error: Interpreter indicates musl, expected glibc: $INTERPRETER" + exit 1 fi elif [[ "$LIBC_TYPE" == "musl" ]]; then - if ! ldd "$BINARY_PATH" 2>&1 | grep -qi "musl"; then - echo "Error: Binary is not linked against musl" + if [[ -z "$INTERPRETER" ]]; then + echo "Error: Missing ELF interpreter; expected musl loader (ld-musl)" + exit 1 + fi + if ! echo "$INTERPRETER" | grep -q "ld-musl"; then + echo "Error: Expected musl interpreter (ld-musl), got: $INTERPRETER" exit 1 fi fi diff --git a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts index d8c5a78dd..5a326a1ff 100644 --- a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts +++ b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts @@ -1,6 +1,6 @@ import Client from "../src" -describe("subscribe response schema tests", async () => { +describe("subscribe response schema tests", () => { const TEST_TIMEOUT = 100000; // .env From e712173f7fa7ed7ddb8974980cbea9c4c8031988 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Fri, 23 Jan 2026 10:35:27 +0000 Subject: [PATCH 10/25] test, binary validation fixes Signed-off-by: GitHub --- ci/validate-binary.sh | 27 ++++++++++----------- yellowstone-grpc-client-nodejs/package.json | 3 +-- 2 files changed, 14 insertions(+), 16 deletions(-) mode change 100644 => 100755 ci/validate-binary.sh diff --git a/ci/validate-binary.sh b/ci/validate-binary.sh old mode 100644 new mode 100755 index ffe579827..06ff3d3cd --- a/ci/validate-binary.sh +++ b/ci/validate-binary.sh @@ -60,33 +60,32 @@ echo "Library dependencies (ldd):" ldd "$BINARY_PATH" || true echo "" -# Verify libc type using the ELF interpreter when available. +# Verify libc type using ELF metadata. +# Shared objects often have no PT_INTERP, so fall back to NEEDED libs. # ldd on musl can emit relocation errors for node addons because N-API # symbols are resolved by the Node runtime, not the loader. INTERPRETER="$(readelf -l "$BINARY_PATH" 2>/dev/null | awk -F': ' '/Requesting program interpreter/ {print $2; exit}')" -echo "ELF interpreter: ${INTERPRETER:-unknown}" +NEEDED_LIBS="$(readelf -d "$BINARY_PATH" 2>/dev/null | awk -F'[][]' '/NEEDED/ {print $2}' | tr '\n' ' ')" +echo "ELF interpreter: ${INTERPRETER:-none}" +echo "NEEDED libs: ${NEEDED_LIBS:-none}" echo "" if [[ "$LIBC_TYPE" == "gnu" ]]; then - if [[ -z "$INTERPRETER" ]]; then - echo "Error: Missing ELF interpreter; expected glibc loader (ld-linux)" - exit 1 - fi - if ! echo "$INTERPRETER" | grep -q "ld-linux"; then - echo "Error: Expected glibc interpreter (ld-linux), got: $INTERPRETER" + if [[ -n "$INTERPRETER" ]] && echo "$INTERPRETER" | grep -q "ld-musl"; then + echo "Error: Interpreter indicates musl, expected glibc: $INTERPRETER" exit 1 fi - if echo "$INTERPRETER" | grep -q "ld-musl"; then - echo "Error: Interpreter indicates musl, expected glibc: $INTERPRETER" + if ! echo "$NEEDED_LIBS" | grep -q "libc.so.6"; then + echo "Error: Missing glibc NEEDED entry (libc.so.6)" exit 1 fi elif [[ "$LIBC_TYPE" == "musl" ]]; then - if [[ -z "$INTERPRETER" ]]; then - echo "Error: Missing ELF interpreter; expected musl loader (ld-musl)" + if [[ -n "$INTERPRETER" ]] && ! echo "$INTERPRETER" | grep -q "ld-musl"; then + echo "Error: Expected musl interpreter (ld-musl), got: $INTERPRETER" exit 1 fi - if ! echo "$INTERPRETER" | grep -q "ld-musl"; then - echo "Error: Expected musl interpreter (ld-musl), got: $INTERPRETER" + if ! echo "$NEEDED_LIBS" | grep -q "libc.musl"; then + echo "Error: Missing musl NEEDED entry (libc.musl-*.so.1)" exit 1 fi fi diff --git a/yellowstone-grpc-client-nodejs/package.json b/yellowstone-grpc-client-nodejs/package.json index c3faebacb..1dce307e6 100644 --- a/yellowstone-grpc-client-nodejs/package.json +++ b/yellowstone-grpc-client-nodejs/package.json @@ -16,8 +16,7 @@ "grpc-generate": "mkdir -p src/grpc && protoc -I../yellowstone-grpc-proto/proto --plugin=node_modules/.bin/protoc-gen-ts_proto --ts_proto_opt=forceLong=string --ts_proto_opt=outputServices=none --experimental_allow_proto3_optional --ts_proto_out=src/grpc geyser.proto --ts_proto_opt=esModuleInterop=true", "patch-napi-loader": "node napi/patch-napi-loader.js", "fmt": "prettier -w .", - "test": "jest", - "test:debug": "jest --detectOpenHandles" + "test": "jest --forceExit" }, "repository": { "type": "git", From 7f82320555294645def67a0a4dc2f2f3b7a49cce Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:19:35 +0000 Subject: [PATCH 11/25] ignore errors after exit Signed-off-by: GitHub --- .../__tests__/subscribe.test.ts | 125 +++++++----------- 1 file changed, 48 insertions(+), 77 deletions(-) diff --git a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts index 5a326a1ff..089e3211f 100644 --- a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts +++ b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts @@ -17,6 +17,26 @@ describe("subscribe response schema tests", () => { await client.connect(); }); + const waitForStreamClosed = ( + stream: NodeJS.ReadableStream, + ignoreErrors: { value: boolean }, + ) => + new Promise((resolve, reject) => { + stream.on("error", (error) => { + if (ignoreErrors.value) { + resolve(); + return; + } + reject(error); + }); + stream.on("end", () => { + resolve(); + }); + stream.on("close", () => { + resolve(); + }); + }); + // A helper function to check the Buffer structure repeatedly const expectBufferSchema = (bufferObject: any) => { expect(bufferObject).toEqual( @@ -45,22 +65,15 @@ describe("subscribe response schema tests", () => { } }); + const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; + ignoreErrors.value = true; + stream.end(); stream.destroy(); }); - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); + const streamClosed = waitForStreamClosed(stream, ignoreErrors); await streamClosed; @@ -102,22 +115,15 @@ describe("subscribe response schema tests", () => { } }); + const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; + ignoreErrors.value = true; + stream.end(); stream.destroy(); }); - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); + const streamClosed = waitForStreamClosed(stream, ignoreErrors); await streamClosed; @@ -149,22 +155,15 @@ describe("subscribe response schema tests", () => { } }); + const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; + ignoreErrors.value = true; + stream.end(); stream.destroy(); }); - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); + const streamClosed = waitForStreamClosed(stream, ignoreErrors); await streamClosed; @@ -232,22 +231,15 @@ describe("subscribe response schema tests", () => { } }); + const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; + ignoreErrors.value = true; + stream.end(); stream.destroy(); }); - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); + const streamClosed = waitForStreamClosed(stream, ignoreErrors); await streamClosed; @@ -299,22 +291,15 @@ describe("subscribe response schema tests", () => { } }); + const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; + ignoreErrors.value = true; + stream.end(); stream.destroy(); }); - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); + const streamClosed = waitForStreamClosed(stream, ignoreErrors); await streamClosed; @@ -350,22 +335,15 @@ describe("subscribe response schema tests", () => { } }); + const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; + ignoreErrors.value = true; + stream.end(); stream.destroy(); }); - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); + const streamClosed = waitForStreamClosed(stream, ignoreErrors); await streamClosed; @@ -397,22 +375,15 @@ describe("subscribe response schema tests", () => { } }); + const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; + ignoreErrors.value = true; + stream.end(); stream.destroy(); }); - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); + const streamClosed = waitForStreamClosed(stream, ignoreErrors); await streamClosed; From 5fc9aeb20ed0ef78496d9b4f9a7c6c7807f97a40 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:38:18 +0000 Subject: [PATCH 12/25] test debnug Signed-off-by: GitHub --- .../__tests__/subscribe.test.ts | 118 ++++++++++++------ 1 file changed, 77 insertions(+), 41 deletions(-) diff --git a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts index 089e3211f..17a8d0bb6 100644 --- a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts +++ b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts @@ -17,26 +17,6 @@ describe("subscribe response schema tests", () => { await client.connect(); }); - const waitForStreamClosed = ( - stream: NodeJS.ReadableStream, - ignoreErrors: { value: boolean }, - ) => - new Promise((resolve, reject) => { - stream.on("error", (error) => { - if (ignoreErrors.value) { - resolve(); - return; - } - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); - // A helper function to check the Buffer structure repeatedly const expectBufferSchema = (bufferObject: any) => { expect(bufferObject).toEqual( @@ -65,15 +45,23 @@ describe("subscribe response schema tests", () => { } }); - const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; - ignoreErrors.value = true; stream.end(); stream.destroy(); }); - const streamClosed = waitForStreamClosed(stream, ignoreErrors); + const streamClosed = new Promise((resolve, reject) => { + stream.on("error", (error) => { + reject(error); + }); + stream.on("end", () => { + resolve(); + }); + stream.on("close", () => { + resolve(); + }); + }); await streamClosed; @@ -115,15 +103,23 @@ describe("subscribe response schema tests", () => { } }); - const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; - ignoreErrors.value = true; stream.end(); stream.destroy(); }); - const streamClosed = waitForStreamClosed(stream, ignoreErrors); + const streamClosed = new Promise((resolve, reject) => { + stream.on("error", (error) => { + reject(error); + }); + stream.on("end", () => { + resolve(); + }); + stream.on("close", () => { + resolve(); + }); + }); await streamClosed; @@ -155,15 +151,23 @@ describe("subscribe response schema tests", () => { } }); - const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; - ignoreErrors.value = true; stream.end(); stream.destroy(); }); - const streamClosed = waitForStreamClosed(stream, ignoreErrors); + const streamClosed = new Promise((resolve, reject) => { + stream.on("error", (error) => { + reject(error); + }); + stream.on("end", () => { + resolve(); + }); + stream.on("close", () => { + resolve(); + }); + }); await streamClosed; @@ -231,15 +235,23 @@ describe("subscribe response schema tests", () => { } }); - const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; - ignoreErrors.value = true; stream.end(); stream.destroy(); }); - const streamClosed = waitForStreamClosed(stream, ignoreErrors); + const streamClosed = new Promise((resolve, reject) => { + stream.on("error", (error) => { + reject(error); + }); + stream.on("end", () => { + resolve(); + }); + stream.on("close", () => { + resolve(); + }); + }); await streamClosed; @@ -291,15 +303,23 @@ describe("subscribe response schema tests", () => { } }); - const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; - ignoreErrors.value = true; stream.end(); stream.destroy(); }); - const streamClosed = waitForStreamClosed(stream, ignoreErrors); + const streamClosed = new Promise((resolve, reject) => { + stream.on("error", (error) => { + reject(error); + }); + stream.on("end", () => { + resolve(); + }); + stream.on("close", () => { + resolve(); + }); + }); await streamClosed; @@ -335,15 +355,23 @@ describe("subscribe response schema tests", () => { } }); - const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; - ignoreErrors.value = true; stream.end(); stream.destroy(); }); - const streamClosed = waitForStreamClosed(stream, ignoreErrors); + const streamClosed = new Promise((resolve, reject) => { + stream.on("error", (error) => { + reject(error); + }); + stream.on("end", () => { + resolve(); + }); + stream.on("close", () => { + resolve(); + }); + }); await streamClosed; @@ -375,15 +403,23 @@ describe("subscribe response schema tests", () => { } }); - const ignoreErrors = { value: false }; stream.once("data", (data) => { response = data; - ignoreErrors.value = true; stream.end(); stream.destroy(); }); - const streamClosed = waitForStreamClosed(stream, ignoreErrors); + const streamClosed = new Promise((resolve, reject) => { + stream.on("error", (error) => { + reject(error); + }); + stream.on("end", () => { + resolve(); + }); + stream.on("close", () => { + resolve(); + }); + }); await streamClosed; From a1b2e39b61e635a378d30047edd691b31e4947e8 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:47:56 +0000 Subject: [PATCH 13/25] limited testing Signed-off-by: GitHub --- .../typescript/src/throughput-measurement.ts | 218 ++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 examples/typescript/src/throughput-measurement.ts diff --git a/examples/typescript/src/throughput-measurement.ts b/examples/typescript/src/throughput-measurement.ts new file mode 100644 index 000000000..1ba379375 --- /dev/null +++ b/examples/typescript/src/throughput-measurement.ts @@ -0,0 +1,218 @@ +// This script measures the throughput of a given gRPC endpoint +// It: +// 1. subscribes to all data for all filters for given duration (default: 30s) +// 2. log the data to a txt file +// 3. measure and the size of the txt file +// Throughput = data that you care about subscribed to, received and processed +// Usage: +// tsx src/throughput-measurement.ts --endpoint --x-token --duration + +import yargs from "yargs"; +import fs from "node:fs"; +import path from "node:path"; +import Client, { SubscribeRequest } from "@triton-one/yellowstone-grpc"; +import dotenv from "dotenv"; + +dotenv.config() + +const GRPC_ENDPOINT=process.env.GRPC_ENDPOINT +const GRPC_X_TOKEN=process.env.GRPC_X_TOKEN + +async function main() { + let client: Client | undefined; + let stream: any; + let writeStream: fs.WriteStream | undefined; + const args = parseCommandLineArgs(); + z/ + // Create measurement-outputs directory if it doesn't exist + const outputDir = "measurement-outputs"; + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + console.log(`Created directory: ${outputDir}`); + } + + const outputFilename = path.join(outputDir, `${Date.now()}.txt`); + + try { + // Create output file stream + writeStream = fs.createWriteStream(outputFilename); + console.log(`Writing data to: ${outputFilename}`); + + // Initialize gRPC client + client = new Client(GRPC_ENDPOINT, GRPC_X_TOKEN, { + // "grpc.max_receive_message_length": 64 * 1024 * 1024, // 64MiB + grpcMaxDecodingMessageSize: 64 * 1024 * 1024, //64MiB + }); + + await client.connect(); + console.log("Connected successfully"); + + // Subscribe for events + stream = await client.subscribe(); + + // Create promises for stream handling + const streamClosed = new Promise((resolve, reject) => { + stream.on("error", (error) => { + console.error("Stream error:", error); + reject(error); + }); + stream.on("end", () => { + console.log("Stream ended"); + resolve(); + }); + stream.on("close", () => { + console.log("Stream closed"); + resolve(); + }); + }); + + // Handle incoming data + stream.on("data", (data) => { + if (writeStream && !writeStream.destroyed) { + writeStream.write(JSON.stringify(data, null, 2) + "\n"); + } + }); + + // Create subscribe request for everything to get loads of data + const request: SubscribeRequest = { + accounts: { + allAccounts: { + account: [], + filters: [], + owner: [] + }, + }, + slots: { + allSlots: {}, + }, + transactions: { + allTransactions: { + accountExclude: [], + accountInclude: [], + accountRequired: [] + } + }, + transactionsStatus: { + allTransactionsStatus: { + accountExclude: [], + accountInclude: [], + accountRequired: [] + } + }, + entry: { + allEntries: {}, + }, + blocks: { + allBlocks: { + accountInclude: [], + } + }, + blocksMeta: { + allBlocksMeta: {} + }, + accountsDataSlice: [], + ping: undefined, + }; + + // Send subscribe request + await new Promise((resolve, reject) => { + stream.write(request, (err) => { + if (err === null || err === undefined) { + resolve(); + } else { + reject(err); + } + }); + }); + + console.log(`Collecting data for ${args.duration} seconds...`); + + // Set up duration timer + const timerPromise = new Promise((resolve) => { + setTimeout(() => { + console.log("Duration elapsed, stopping subscription..."); + stream.end(); + resolve(); + }, args.duration * 1000); + }); + + // Wait for either timer to complete or stream to close + await Promise.race([timerPromise, streamClosed]); + + // Close write stream and wait for it to finish + if (writeStream && !writeStream.destroyed) { + await new Promise((resolve, reject) => { + writeStream!.end(() => { + resolve(); + }); + writeStream!.on("error", reject); + }); + } + + // Wait briefly to ensure all writes are flushed + await new Promise((resolve) => setTimeout(resolve, 100)); + + // Measure file size + const stats = fs.statSync(outputFilename); + const fileSizeInBytes = stats.size; + const fileSizeInMB = fileSizeInBytes / (1024 * 1024); + + // Log results + console.log("\n=== Throughput Measurement Results ==="); + console.log(`File: ${outputFilename}`); + console.log(`Size: ${fileSizeInMB.toFixed(2)} MB`); + console.log(`Duration: ${args.duration} seconds`); + console.log(`Throughput: ${(fileSizeInMB / args.duration).toFixed(2)} MB/s`); + console.log("=====================================\n"); + process.exit(1) + } catch (error) { + console.error("Error:", error); + process.exit(1); + } finally { + await cleanup(client, stream, writeStream); + } +} + +async function cleanup( + client: Client | undefined, + stream: any, + writeStream: fs.WriteStream | undefined +) { + try { + if (stream && !stream.destroyed) { + stream.end(); + } + if (writeStream && !writeStream.destroyed) { + writeStream.end(); + } + // Wait briefly for cleanup to complete + await new Promise((resolve) => setTimeout(resolve, 100)); + } catch (error) { + console.error("Cleanup error:", error); + } +} + +function parseCommandLineArgs() { + return yargs(process.argv.slice(2)) + .options({ + // endpoint: { + // alias: "e", + // describe: "gRPC endpoint", + // type: "string", + // demandOption: true, + // }, + // "x-token": { + // describe: "token for auth, can be used only with ssl", + // type: "string", + // }, + duration: { + alias: "d", + describe: "duration in seconds to collect data", + type: "number", + default: 30, + }, + }) + .help().argv; +} + +main(); From d9a017e355bb664b14524bb46b0745f7cb5dd3a7 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:58:52 +0000 Subject: [PATCH 14/25] commit the correct file Signed-off-by: GitHub --- .../typescript/src/throughput-measurement.ts | 218 ---------------- .../__tests__/subscribe.test.ts | 244 ------------------ 2 files changed, 462 deletions(-) delete mode 100644 examples/typescript/src/throughput-measurement.ts diff --git a/examples/typescript/src/throughput-measurement.ts b/examples/typescript/src/throughput-measurement.ts deleted file mode 100644 index 1ba379375..000000000 --- a/examples/typescript/src/throughput-measurement.ts +++ /dev/null @@ -1,218 +0,0 @@ -// This script measures the throughput of a given gRPC endpoint -// It: -// 1. subscribes to all data for all filters for given duration (default: 30s) -// 2. log the data to a txt file -// 3. measure and the size of the txt file -// Throughput = data that you care about subscribed to, received and processed -// Usage: -// tsx src/throughput-measurement.ts --endpoint --x-token --duration - -import yargs from "yargs"; -import fs from "node:fs"; -import path from "node:path"; -import Client, { SubscribeRequest } from "@triton-one/yellowstone-grpc"; -import dotenv from "dotenv"; - -dotenv.config() - -const GRPC_ENDPOINT=process.env.GRPC_ENDPOINT -const GRPC_X_TOKEN=process.env.GRPC_X_TOKEN - -async function main() { - let client: Client | undefined; - let stream: any; - let writeStream: fs.WriteStream | undefined; - const args = parseCommandLineArgs(); - z/ - // Create measurement-outputs directory if it doesn't exist - const outputDir = "measurement-outputs"; - if (!fs.existsSync(outputDir)) { - fs.mkdirSync(outputDir, { recursive: true }); - console.log(`Created directory: ${outputDir}`); - } - - const outputFilename = path.join(outputDir, `${Date.now()}.txt`); - - try { - // Create output file stream - writeStream = fs.createWriteStream(outputFilename); - console.log(`Writing data to: ${outputFilename}`); - - // Initialize gRPC client - client = new Client(GRPC_ENDPOINT, GRPC_X_TOKEN, { - // "grpc.max_receive_message_length": 64 * 1024 * 1024, // 64MiB - grpcMaxDecodingMessageSize: 64 * 1024 * 1024, //64MiB - }); - - await client.connect(); - console.log("Connected successfully"); - - // Subscribe for events - stream = await client.subscribe(); - - // Create promises for stream handling - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - console.error("Stream error:", error); - reject(error); - }); - stream.on("end", () => { - console.log("Stream ended"); - resolve(); - }); - stream.on("close", () => { - console.log("Stream closed"); - resolve(); - }); - }); - - // Handle incoming data - stream.on("data", (data) => { - if (writeStream && !writeStream.destroyed) { - writeStream.write(JSON.stringify(data, null, 2) + "\n"); - } - }); - - // Create subscribe request for everything to get loads of data - const request: SubscribeRequest = { - accounts: { - allAccounts: { - account: [], - filters: [], - owner: [] - }, - }, - slots: { - allSlots: {}, - }, - transactions: { - allTransactions: { - accountExclude: [], - accountInclude: [], - accountRequired: [] - } - }, - transactionsStatus: { - allTransactionsStatus: { - accountExclude: [], - accountInclude: [], - accountRequired: [] - } - }, - entry: { - allEntries: {}, - }, - blocks: { - allBlocks: { - accountInclude: [], - } - }, - blocksMeta: { - allBlocksMeta: {} - }, - accountsDataSlice: [], - ping: undefined, - }; - - // Send subscribe request - await new Promise((resolve, reject) => { - stream.write(request, (err) => { - if (err === null || err === undefined) { - resolve(); - } else { - reject(err); - } - }); - }); - - console.log(`Collecting data for ${args.duration} seconds...`); - - // Set up duration timer - const timerPromise = new Promise((resolve) => { - setTimeout(() => { - console.log("Duration elapsed, stopping subscription..."); - stream.end(); - resolve(); - }, args.duration * 1000); - }); - - // Wait for either timer to complete or stream to close - await Promise.race([timerPromise, streamClosed]); - - // Close write stream and wait for it to finish - if (writeStream && !writeStream.destroyed) { - await new Promise((resolve, reject) => { - writeStream!.end(() => { - resolve(); - }); - writeStream!.on("error", reject); - }); - } - - // Wait briefly to ensure all writes are flushed - await new Promise((resolve) => setTimeout(resolve, 100)); - - // Measure file size - const stats = fs.statSync(outputFilename); - const fileSizeInBytes = stats.size; - const fileSizeInMB = fileSizeInBytes / (1024 * 1024); - - // Log results - console.log("\n=== Throughput Measurement Results ==="); - console.log(`File: ${outputFilename}`); - console.log(`Size: ${fileSizeInMB.toFixed(2)} MB`); - console.log(`Duration: ${args.duration} seconds`); - console.log(`Throughput: ${(fileSizeInMB / args.duration).toFixed(2)} MB/s`); - console.log("=====================================\n"); - process.exit(1) - } catch (error) { - console.error("Error:", error); - process.exit(1); - } finally { - await cleanup(client, stream, writeStream); - } -} - -async function cleanup( - client: Client | undefined, - stream: any, - writeStream: fs.WriteStream | undefined -) { - try { - if (stream && !stream.destroyed) { - stream.end(); - } - if (writeStream && !writeStream.destroyed) { - writeStream.end(); - } - // Wait briefly for cleanup to complete - await new Promise((resolve) => setTimeout(resolve, 100)); - } catch (error) { - console.error("Cleanup error:", error); - } -} - -function parseCommandLineArgs() { - return yargs(process.argv.slice(2)) - .options({ - // endpoint: { - // alias: "e", - // describe: "gRPC endpoint", - // type: "string", - // demandOption: true, - // }, - // "x-token": { - // describe: "token for auth, can be used only with ssl", - // type: "string", - // }, - duration: { - alias: "d", - describe: "duration in seconds to collect data", - type: "number", - default: 30, - }, - }) - .help().argv; -} - -main(); diff --git a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts index 17a8d0bb6..f8236dc83 100644 --- a/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts +++ b/yellowstone-grpc-client-nodejs/__tests__/subscribe.test.ts @@ -17,18 +17,6 @@ describe("subscribe response schema tests", () => { await client.connect(); }); - // A helper function to check the Buffer structure repeatedly - const expectBufferSchema = (bufferObject: any) => { - expect(bufferObject).toEqual( - expect.objectContaining({ - type: expect.any(String), // Should be 'Buffer' - data: expect.any(Array), // The array of bytes - }) - ); - // Optionally, ensure the data array contains only numbers - expect(bufferObject.data.every((item: any) => typeof item === 'number')).toBe(true); - }; - test("account", async () => { let response: any; const stream = await client.subscribe(); @@ -218,236 +206,4 @@ describe("subscribe response schema tests", () => { expect(typeof innerTx.message.versioned).toBe("boolean"); }, TEST_TIMEOUT) - - test("block", async () => { - let response: any; - const stream = await client.subscribe(); - const request = { - blocks: { - client: {} - }, - commitment: 2 - }; - - stream.write(request, (err) => { - if (err) { - console.error(`error writing to stream: ${err}`) - } - }); - - stream.once("data", (data) => { - response = data; - stream.end(); - stream.destroy(); - }); - - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); - - await streamClosed; - - expect(response.filters).toEqual(["client"]); - // We're doing it this way so we can bypass the Jest Globals vs Node Globals - // type conflicts that makes expect(Date).toBeInstanceOf(Date) to fail. - // - // See issue here: https://github.com/jestjs/jest/issues/2549 - expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); - expect(Object.prototype.toString.call(response.block.entries)).toBe("[object Array]"); - expect(Object.prototype.toString.call(response.block.accounts)).toBe("[object Array]"); - expect(Object.prototype.toString.call(response.block.transactions)).toBe("[object Array]"); - expect(typeof response.block).toBe("object"); - expect(typeof response.block.slot).toBe("string"); - expect(typeof response.block.blockhash).toBe("string"); - expect(typeof response.block.parentSlot).toBe("string"); - expect(typeof response.block.parentBlockhash).toBe("string"); - expect(typeof response.block.executedTransactionCount).toBe("string"); - expect(typeof response.block.updatedAccountCount).toBe("string"); - expect(typeof response.block.entriesCount).toBe("string"); - - const rewards = response.block.rewards; - expect(typeof rewards).toBe("object"); - expect(Object.prototype.toString.call(rewards.rewards)).toBe("[object Array]"); - - const blockTime = response.block.blockTime; - expect(typeof blockTime).toBe("object"); - expect(typeof blockTime.timestamp).toBe("string"); - - const blockHeight = response.block.blockHeight; - expect(typeof blockHeight).toBe("object"); - expect(typeof blockHeight.blockHeight).toBe("string"); - - }, TEST_TIMEOUT); - - test("entry", async () => { - let response: any; - const stream = await client.subscribe(); - const request = { - entry: { - client: {} - }, - commitment: 2 - }; - - stream.write(request, (err) => { - if (err) { - console.error(`error writing to stream: ${err}`) - } - }); - - stream.once("data", (data) => { - response = data; - stream.end(); - stream.destroy(); - }); - - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); - - await streamClosed; - - expect(response.filters).toEqual(["client"]); - // We're doing it this way so we can bypass the Jest Globals vs Node Globals - // type conflicts that makes expect(Date).toBeInstanceOf(Date) to fail. - // - // See issue here: https://github.com/jestjs/jest/issues/2549 - expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); - expect(typeof response.entry).toBe("object"); - expect(typeof response.entry.slot).toBe("string"); - expect(typeof response.entry.index).toBe("string"); - expect(typeof response.entry.numHashes).toBe("string"); - expect(typeof response.entry.executedTransactionCount).toBe("string"); - expect(typeof response.entry.startingTransactionIndex).toBe("string"); - expect(response.entry.hash).toBeInstanceOf(Buffer); - - }, TEST_TIMEOUT); - - test("ping", async () => { - let response: any; - const stream = await client.subscribe(); - const request = { - ping: { - id: 0 - }, - commitment: 2 - }; - - stream.write(request, (err) => { - if (err) { - console.error(`error writing to stream: ${err}`) - } - }); - - stream.once("data", (data) => { - response = data; - stream.end(); - stream.destroy(); - }); - - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); - - await streamClosed; - - expect(response.filters).toEqual([]); - // We're doing it this way so we can bypass the Jest Globals vs Node Globals - // type conflicts that makes expect(Date).toBeInstanceOf(Date) to fail. - // - // See issue here: https://github.com/jestjs/jest/issues/2549 - expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); - expect(typeof response.pong).toBe("object"); - expect(typeof response.pong.id).toBe("number"); - expect(response.pong.id).toEqual(0); - - }, TEST_TIMEOUT); - - test("blockMeta", async () => { - let response: any; - const stream = await client.subscribe(); - const request = { - blocksMeta: { - client: {}, - }, - commitment: 2 - }; - - stream.write(request, (err) => { - if (err) { - console.error(`error writing to stream: ${err}`) - } - }); - - stream.once("data", (data) => { - response = data; - stream.end(); - stream.destroy(); - }); - - const streamClosed = new Promise((resolve, reject) => { - stream.on("error", (error) => { - reject(error); - }); - stream.on("end", () => { - resolve(); - }); - stream.on("close", () => { - resolve(); - }); - }); - - await streamClosed; - - expect(response.filters).toEqual(["client"]); - // We're doing it this way so we can bypass the Jest Globals vs Node Globals - // type conflicts that makes expect(Date).toBeInstanceOf(Date) to fail. - // - // See issue here: https://github.com/jestjs/jest/issues/2549 - expect(Object.prototype.toString.call(response.createdAt)).toBe("[object Date]"); - expect(typeof response.blockMeta).toBe("object"); - expect(typeof response.blockMeta.slot).toBe("string"); - expect(typeof response.blockMeta.blockhash).toBe("string"); - expect(typeof response.blockMeta.parentSlot).toBe("string"); - expect(typeof response.blockMeta.parentBlockhash).toBe("string"); - expect(typeof response.blockMeta.executedTransactionCount).toBe("string"); - expect(typeof response.blockMeta.entriesCount).toBe("string"); - - const rewards = response.blockMeta.rewards; - expect(typeof rewards).toBe("object"); - expect(Object.prototype.toString.call(rewards.rewards)).toBe("[object Array]"); - - const blockTime = response.blockMeta.blockTime; - expect(typeof blockTime).toBe("object"); - expect(typeof blockTime.timestamp).toBe("string"); - - const blockHeight = response.blockMeta.blockHeight; - expect(typeof blockHeight).toBe("object"); - expect(typeof blockHeight.blockHeight).toBe("string"); - - }, TEST_TIMEOUT); }); From ec0d93a5dfdfce0977a2917dd781f687e48b68a1 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Fri, 23 Jan 2026 17:14:49 +0000 Subject: [PATCH 15/25] run on macos-latest Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 114 +++++++++---------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index 8ccb99648..153399cd1 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -218,64 +218,64 @@ jobs: TEST_TOKEN: ${{ secrets.TEST_TOKEN }} run: npm test - # # macOS ARM64 (Apple Silicon) - # test-macos-arm64: - # name: Test macOS ARM64 (Apple Silicon) - # runs-on: macos-latset + # macOS ARM64 (Apple Silicon) + test-macos-arm64: + name: Test macOS ARM64 (Apple Silicon) + runs-on: macos-latset - # steps: - # - name: Checkout repository - # uses: actions/checkout@v4 - - # - name: Set up Node.js - # uses: actions/setup-node@v4 - # with: - # node-version: ${{ env.NODE_VERSION }} - # cache: 'npm' - # cache-dependency-path: yellowstone-grpc-client-nodejs/package-lock.json - - # - name: Set rust version - # run: | - # RUST_VERSION="$(grep -oP 'channel = "\K\d\.\d+\.\d+(?=")' rust-toolchain.toml)" - # echo "RUST_STABLE=$RUST_VERSION" | tee -a $GITHUB_ENV - - # - name: Install Rust toolchain - # uses: dtolnay/rust-toolchain@stable - # with: - # toolchain: ${{ env.RUST_STABLE }} - # targets: aarch64-apple-darwin - - # - name: Install system dependencies - # run: | - # brew install protobuf - - # - name: Install Node dependencies - # working-directory: yellowstone-grpc-client-nodejs - # run: npm ci - - # - name: Build NAPI binary for darwin-arm64 - # working-directory: yellowstone-grpc-client-nodejs - # env: - # NAPI_TARGET: aarch64-apple-darwin - # run: | - # npm run build -- --platform --release --target aarch64-apple-darwin - - # - name: Validate binary (macOS ARM64) - # working-directory: yellowstone-grpc-client-nodejs - # run: | - # chmod u+x ../ci/validate-binary-macos.sh - # ../ci/validate-binary-macos.sh napi/yellowstone-grpc-napi.darwin-arm64.node arm64 - - # - name: Build TypeScript SDK - # working-directory: yellowstone-grpc-client-nodejs - # run: npm run build:dev - - # - name: Run tests - # working-directory: yellowstone-grpc-client-nodejs - # env: - # TEST_ENDPOINT: ${{ secrets.TEST_ENDPOINT }} - # TEST_TOKEN: ${{ secrets.TEST_TOKEN }} - # run: npm test + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'npm' + cache-dependency-path: yellowstone-grpc-client-nodejs/package-lock.json + + - name: Set rust version + run: | + RUST_VERSION="$(grep -oP 'channel = "\K\d\.\d+\.\d+(?=")' rust-toolchain.toml)" + echo "RUST_STABLE=$RUST_VERSION" | tee -a $GITHUB_ENV + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: ${{ env.RUST_STABLE }} + targets: aarch64-apple-darwin + + - name: Install system dependencies + run: | + brew install protobuf + + - name: Install Node dependencies + working-directory: yellowstone-grpc-client-nodejs + run: npm ci + + - name: Build NAPI binary for darwin-arm64 + working-directory: yellowstone-grpc-client-nodejs + env: + NAPI_TARGET: aarch64-apple-darwin + run: | + npm run build -- --platform --release --target aarch64-apple-darwin + + - name: Validate binary (macOS ARM64) + working-directory: yellowstone-grpc-client-nodejs + run: | + chmod u+x ../ci/validate-binary-macos.sh + ../ci/validate-binary-macos.sh napi/yellowstone-grpc-napi.darwin-arm64.node arm64 + + - name: Build TypeScript SDK + working-directory: yellowstone-grpc-client-nodejs + run: npm run build:dev + + - name: Run tests + working-directory: yellowstone-grpc-client-nodejs + env: + TEST_ENDPOINT: ${{ secrets.TEST_ENDPOINT }} + TEST_TOKEN: ${{ secrets.TEST_TOKEN }} + run: npm test # Release gate - all tests must pass integration-tests-complete: From 6faa6049359979a2034ac1b8cac7bd48307ec8f8 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Sat, 24 Jan 2026 07:11:27 +0000 Subject: [PATCH 16/25] fix: typo in runner name Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index 153399cd1..e534bc518 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -20,7 +20,7 @@ jobs: test-linux-x64-gnu: name: Test Linux x64 GNU (glibc) runs-on: ubuntu-22.04 - + steps: - name: Checkout repository uses: actions/checkout@v4 @@ -221,7 +221,7 @@ jobs: # macOS ARM64 (Apple Silicon) test-macos-arm64: name: Test macOS ARM64 (Apple Silicon) - runs-on: macos-latset + runs-on: macos-latest steps: - name: Checkout repository @@ -280,7 +280,7 @@ jobs: # Release gate - all tests must pass integration-tests-complete: name: All Integration Tests Passed - needs: [test-linux-x64-gnu, test-linux-x64-musl, test-macos-x64] #test-macos-arm64] + needs: [test-linux-x64-gnu, test-linux-x64-musl, test-macos-x64, test-macos-arm64] runs-on: ubuntu-latest steps: - name: Mark as complete From 23431ec5583381733323eee627d68d1f995d3261 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Sat, 24 Jan 2026 07:13:50 +0000 Subject: [PATCH 17/25] fix rust install Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index e534bc518..c925c3f26 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -236,14 +236,14 @@ jobs: - name: Set rust version run: | - RUST_VERSION="$(grep -oP 'channel = "\K\d\.\d+\.\d+(?=")' rust-toolchain.toml)" - echo "RUST_STABLE=$RUST_VERSION" | tee -a $GITHUB_ENV + RUST_VERSION="$(sed -n 's/^channel = "\([0-9.]*\)"/\1/p' rust-toolchain.toml)" + echo "RUST_STABLE=$RUST_VERSION" | tee -a "$GITHUB_ENV" - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ env.RUST_STABLE }} - targets: aarch64-apple-darwin + targets: x86_64-apple-darwin - name: Install system dependencies run: | From d079f4ae078c4b07942e1ad5856aef340a6e5dd6 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Sat, 24 Jan 2026 10:47:49 +0000 Subject: [PATCH 18/25] musl validation test should fail Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index c925c3f26..d1f6d8056 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -138,7 +138,7 @@ jobs: working-directory: yellowstone-grpc-client-nodejs env: NAPI_TARGET: x86_64-unknown-linux-musl - LIBC: musl + # LIBC: musl run: | npm run build -- --platform --release --target x86_64-unknown-linux-musl From 244fa7106c2fbce3fdba300a55e83bc8b6abb22b Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Sat, 24 Jan 2026 11:07:54 +0000 Subject: [PATCH 19/25] fix musl test Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index d1f6d8056..c925c3f26 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -138,7 +138,7 @@ jobs: working-directory: yellowstone-grpc-client-nodejs env: NAPI_TARGET: x86_64-unknown-linux-musl - # LIBC: musl + LIBC: musl run: | npm run build -- --platform --release --target x86_64-unknown-linux-musl From a03b2489c9951058b00193fe16b87a514e270418 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Sun, 25 Jan 2026 03:59:31 +0000 Subject: [PATCH 20/25] set workflow permissions Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index c925c3f26..f741cf818 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -1,5 +1,8 @@ name: NAPI Integration Tests +permissions: + contents: read + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true From fe1f5e608bd644484c5858f278c2d2c21fef6e83 Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Sun, 25 Jan 2026 04:14:24 +0000 Subject: [PATCH 21/25] cargo clean napi builds to clear space Signed-off-by: GitHub --- .github/workflows/napi-integration-tests.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.github/workflows/napi-integration-tests.yml b/.github/workflows/napi-integration-tests.yml index f741cf818..52e5d3ad3 100644 --- a/.github/workflows/napi-integration-tests.yml +++ b/.github/workflows/napi-integration-tests.yml @@ -79,6 +79,11 @@ jobs: TEST_ENDPOINT: ${{ secrets.TEST_ENDPOINT }} TEST_TOKEN: ${{ secrets.TEST_TOKEN }} run: npm test + + - name: cargo clean + working-directory: yellowstone-grpc-client-nodejs/napi + run: + cargo clean # Linux x64 MUSL - Alpine container test-linux-x64-musl: @@ -162,6 +167,11 @@ jobs: TEST_TOKEN: ${{ secrets.TEST_TOKEN }} run: npm test + - name: cargo clean + working-directory: yellowstone-grpc-client-nodejs/napi + run: + cargo clean + # macOS x64 (Intel) test-macos-x64: name: Test macOS x64 (Intel) @@ -221,6 +231,11 @@ jobs: TEST_TOKEN: ${{ secrets.TEST_TOKEN }} run: npm test + - name: cargo clean + working-directory: yellowstone-grpc-client-nodejs/napi + run: + cargo clean + # macOS ARM64 (Apple Silicon) test-macos-arm64: name: Test macOS ARM64 (Apple Silicon) @@ -280,6 +295,11 @@ jobs: TEST_TOKEN: ${{ secrets.TEST_TOKEN }} run: npm test + - name: cargo clean + working-directory: yellowstone-grpc-client-nodejs/napi + run: + cargo clean + # Release gate - all tests must pass integration-tests-complete: name: All Integration Tests Passed From fd14473f3fb97e7faad093d04c7b35e5ca897d0a Mon Sep 17 00:00:00 2001 From: Wilfred Almeida <60785452+WilfredAlmeida@users.noreply.github.com> Date: Mon, 2 Feb 2026 04:05:29 +0000 Subject: [PATCH 22/25] refactor: bump package versions Signed-off-by: GitHub --- .../package-lock.json | 906 +++++++++--------- yellowstone-grpc-client-nodejs/package.json | 10 +- 2 files changed, 455 insertions(+), 461 deletions(-) diff --git a/yellowstone-grpc-client-nodejs/package-lock.json b/yellowstone-grpc-client-nodejs/package-lock.json index aeaba32b4..9d0fe944e 100644 --- a/yellowstone-grpc-client-nodejs/package-lock.json +++ b/yellowstone-grpc-client-nodejs/package-lock.json @@ -1,12 +1,12 @@ { "name": "@triton-one/yellowstone-grpc", - "version": "5.0.1", + "version": "5.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@triton-one/yellowstone-grpc", - "version": "5.0.1", + "version": "5.0.2", "license": "Apache-2.0", "dependencies": { "@bufbuild/protobuf": "=2.10.2", @@ -36,20 +36,20 @@ "node": ">=20.18.0" }, "optionalDependencies": { - "@triton-one/yellowstone-grpc-napi-darwin-arm64": "0.0.5", - "@triton-one/yellowstone-grpc-napi-darwin-x64": "0.0.5", - "@triton-one/yellowstone-grpc-napi-linux-x64-gnu": "0.0.5", - "@triton-one/yellowstone-grpc-napi-linux-x64-musl": "0.0.5" + "@triton-one/yellowstone-grpc-napi-darwin-arm64": "0.0.6", + "@triton-one/yellowstone-grpc-napi-darwin-x64": "0.0.6", + "@triton-one/yellowstone-grpc-napi-linux-x64-gnu": "0.0.6", + "@triton-one/yellowstone-grpc-napi-linux-x64-musl": "0.0.6" } }, "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" }, @@ -58,9 +58,9 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", "engines": { @@ -68,22 +68,21 @@ } }, "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -100,14 +99,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.0.tgz", + "integrity": "sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -130,13 +129,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", + "@babel/compat-data": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -147,18 +146,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz", - "integrity": "sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.6.tgz", + "integrity": "sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-replace-supers": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/traverse": "^7.28.5", + "@babel/traverse": "^7.28.6", "semver": "^6.3.1" }, "engines": { @@ -187,17 +186,17 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", - "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.6.tgz", + "integrity": "sha512-mOAsxeeKkUKayvZR3HeTYD/fICpCPLJrU5ZjelT/PA6WHtNDBOE436YiaEUvHN454bRM3CebhDsIpieCc4texA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "debug": "^4.4.1", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "debug": "^4.4.3", "lodash.debounce": "^4.0.8", - "resolve": "^1.22.10" + "resolve": "^1.22.11" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -228,29 +227,29 @@ } }, "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -273,9 +272,9 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", "engines": { @@ -301,15 +300,15 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", - "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.28.6.tgz", + "integrity": "sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.28.5", "@babel/helper-optimise-call-expression": "^7.27.1", - "@babel/traverse": "^7.27.1" + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -363,42 +362,42 @@ } }, "node_modules/@babel/helper-wrap-function": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz", - "integrity": "sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.28.6.tgz", + "integrity": "sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.3", - "@babel/types": "^7.28.2" + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", + "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.5" + "@babel/types": "^7.29.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -475,14 +474,14 @@ } }, "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz", - "integrity": "sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.6.tgz", + "integrity": "sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/traverse": "^7.28.3" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -560,13 +559,13 @@ } }, "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", - "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.28.6.tgz", + "integrity": "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -576,13 +575,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", - "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -618,13 +617,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -744,13 +743,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -793,15 +792,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz", - "integrity": "sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.29.0.tgz", + "integrity": "sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1", - "@babel/traverse": "^7.28.0" + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -811,14 +810,14 @@ } }, "node_modules/@babel/plugin-transform-async-to-generator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz", - "integrity": "sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.28.6.tgz", + "integrity": "sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-remap-async-to-generator": "^7.27.1" }, "engines": { @@ -845,13 +844,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz", - "integrity": "sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.6.tgz", + "integrity": "sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -861,14 +860,14 @@ } }, "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", - "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.28.6.tgz", + "integrity": "sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -878,14 +877,14 @@ } }, "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz", - "integrity": "sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.6.tgz", + "integrity": "sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -895,18 +894,18 @@ } }, "node_modules/@babel/plugin-transform-classes": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz", - "integrity": "sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.6.tgz", + "integrity": "sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-compilation-targets": "^7.28.6", "@babel/helper-globals": "^7.28.0", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/helper-replace-supers": "^7.27.1", - "@babel/traverse": "^7.28.4" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/helper-replace-supers": "^7.28.6", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -916,14 +915,14 @@ } }, "node_modules/@babel/plugin-transform-computed-properties": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", - "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.28.6.tgz", + "integrity": "sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/template": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/template": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -950,14 +949,14 @@ } }, "node_modules/@babel/plugin-transform-dotall-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", - "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.28.6.tgz", + "integrity": "sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -983,14 +982,14 @@ } }, "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1016,14 +1015,14 @@ } }, "node_modules/@babel/plugin-transform-explicit-resource-management": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz", - "integrity": "sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.6.tgz", + "integrity": "sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0" + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -1033,13 +1032,13 @@ } }, "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz", - "integrity": "sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.6.tgz", + "integrity": "sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1100,13 +1099,13 @@ } }, "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", - "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.28.6.tgz", + "integrity": "sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1132,13 +1131,13 @@ } }, "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz", - "integrity": "sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.6.tgz", + "integrity": "sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1181,14 +1180,14 @@ } }, "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", - "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.28.6.tgz", + "integrity": "sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1198,16 +1197,16 @@ } }, "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz", - "integrity": "sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.29.0.tgz", + "integrity": "sha512-PrujnVFbOdUpw4UHiVwKvKRLMMic8+eC0CuNlxjsyZUiBjhFdPsewdXCkveh2KqBA9/waD0W1b4hXSOBQJezpQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.5" + "@babel/traverse": "^7.29.0" }, "engines": { "node": ">=6.9.0" @@ -1234,14 +1233,14 @@ } }, "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", - "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.29.0.tgz", + "integrity": "sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1267,13 +1266,13 @@ } }, "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", - "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.28.6.tgz", + "integrity": "sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1283,13 +1282,13 @@ } }, "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", - "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.28.6.tgz", + "integrity": "sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1299,17 +1298,17 @@ } }, "node_modules/@babel/plugin-transform-object-rest-spread": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz", - "integrity": "sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.6.tgz", + "integrity": "sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", - "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-transform-destructuring": "^7.28.5", "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/traverse": "^7.28.4" + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1336,13 +1335,13 @@ } }, "node_modules/@babel/plugin-transform-optional-catch-binding": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", - "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.28.6.tgz", + "integrity": "sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1352,13 +1351,13 @@ } }, "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz", - "integrity": "sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.6.tgz", + "integrity": "sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { @@ -1385,14 +1384,14 @@ } }, "node_modules/@babel/plugin-transform-private-methods": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", - "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.28.6.tgz", + "integrity": "sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1402,15 +1401,15 @@ } }, "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", - "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.28.6.tgz", + "integrity": "sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.27.1", - "@babel/helper-create-class-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1436,13 +1435,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz", - "integrity": "sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.29.0.tgz", + "integrity": "sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1452,14 +1451,14 @@ } }, "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", - "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.28.6.tgz", + "integrity": "sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1501,13 +1500,13 @@ } }, "node_modules/@babel/plugin-transform-spread": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", - "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.28.6.tgz", + "integrity": "sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" }, "engines": { @@ -1566,17 +1565,17 @@ } }, "node_modules/@babel/plugin-transform-typescript": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz", - "integrity": "sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.6.tgz", + "integrity": "sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.27.3", - "@babel/helper-create-class-features-plugin": "^7.28.5", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1" + "@babel/plugin-syntax-typescript": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1602,14 +1601,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-property-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", - "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.28.6.tgz", + "integrity": "sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1636,14 +1635,14 @@ } }, "node_modules/@babel/plugin-transform-unicode-sets-regex": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", - "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.28.6.tgz", + "integrity": "sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.27.1", - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.28.5", + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -1653,81 +1652,81 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.28.5.tgz", - "integrity": "sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.29.0.tgz", + "integrity": "sha512-fNEdfc0yi16lt6IZo2Qxk3knHVdfMYX33czNb4v8yWhemoBhibCpQK/uYHtSKIiO+p/zd3+8fYVXhQdOVV608w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-plugin-utils": "^7.27.1", + "@babel/compat-data": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", "@babel/helper-validator-option": "^7.27.1", "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.28.5", "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.27.1", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.27.1", "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.27.1", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.3", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.28.6", "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.27.1", - "@babel/plugin-syntax-import-attributes": "^7.27.1", + "@babel/plugin-syntax-import-assertions": "^7.28.6", + "@babel/plugin-syntax-import-attributes": "^7.28.6", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.27.1", - "@babel/plugin-transform-async-generator-functions": "^7.28.0", - "@babel/plugin-transform-async-to-generator": "^7.27.1", + "@babel/plugin-transform-async-generator-functions": "^7.29.0", + "@babel/plugin-transform-async-to-generator": "^7.28.6", "@babel/plugin-transform-block-scoped-functions": "^7.27.1", - "@babel/plugin-transform-block-scoping": "^7.28.5", - "@babel/plugin-transform-class-properties": "^7.27.1", - "@babel/plugin-transform-class-static-block": "^7.28.3", - "@babel/plugin-transform-classes": "^7.28.4", - "@babel/plugin-transform-computed-properties": "^7.27.1", + "@babel/plugin-transform-block-scoping": "^7.28.6", + "@babel/plugin-transform-class-properties": "^7.28.6", + "@babel/plugin-transform-class-static-block": "^7.28.6", + "@babel/plugin-transform-classes": "^7.28.6", + "@babel/plugin-transform-computed-properties": "^7.28.6", "@babel/plugin-transform-destructuring": "^7.28.5", - "@babel/plugin-transform-dotall-regex": "^7.27.1", + "@babel/plugin-transform-dotall-regex": "^7.28.6", "@babel/plugin-transform-duplicate-keys": "^7.27.1", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-dynamic-import": "^7.27.1", - "@babel/plugin-transform-explicit-resource-management": "^7.28.0", - "@babel/plugin-transform-exponentiation-operator": "^7.28.5", + "@babel/plugin-transform-explicit-resource-management": "^7.28.6", + "@babel/plugin-transform-exponentiation-operator": "^7.28.6", "@babel/plugin-transform-export-namespace-from": "^7.27.1", "@babel/plugin-transform-for-of": "^7.27.1", "@babel/plugin-transform-function-name": "^7.27.1", - "@babel/plugin-transform-json-strings": "^7.27.1", + "@babel/plugin-transform-json-strings": "^7.28.6", "@babel/plugin-transform-literals": "^7.27.1", - "@babel/plugin-transform-logical-assignment-operators": "^7.28.5", + "@babel/plugin-transform-logical-assignment-operators": "^7.28.6", "@babel/plugin-transform-member-expression-literals": "^7.27.1", "@babel/plugin-transform-modules-amd": "^7.27.1", - "@babel/plugin-transform-modules-commonjs": "^7.27.1", - "@babel/plugin-transform-modules-systemjs": "^7.28.5", + "@babel/plugin-transform-modules-commonjs": "^7.28.6", + "@babel/plugin-transform-modules-systemjs": "^7.29.0", "@babel/plugin-transform-modules-umd": "^7.27.1", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.27.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.29.0", "@babel/plugin-transform-new-target": "^7.27.1", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.27.1", - "@babel/plugin-transform-numeric-separator": "^7.27.1", - "@babel/plugin-transform-object-rest-spread": "^7.28.4", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.28.6", + "@babel/plugin-transform-numeric-separator": "^7.28.6", + "@babel/plugin-transform-object-rest-spread": "^7.28.6", "@babel/plugin-transform-object-super": "^7.27.1", - "@babel/plugin-transform-optional-catch-binding": "^7.27.1", - "@babel/plugin-transform-optional-chaining": "^7.28.5", + "@babel/plugin-transform-optional-catch-binding": "^7.28.6", + "@babel/plugin-transform-optional-chaining": "^7.28.6", "@babel/plugin-transform-parameters": "^7.27.7", - "@babel/plugin-transform-private-methods": "^7.27.1", - "@babel/plugin-transform-private-property-in-object": "^7.27.1", + "@babel/plugin-transform-private-methods": "^7.28.6", + "@babel/plugin-transform-private-property-in-object": "^7.28.6", "@babel/plugin-transform-property-literals": "^7.27.1", - "@babel/plugin-transform-regenerator": "^7.28.4", - "@babel/plugin-transform-regexp-modifiers": "^7.27.1", + "@babel/plugin-transform-regenerator": "^7.29.0", + "@babel/plugin-transform-regexp-modifiers": "^7.28.6", "@babel/plugin-transform-reserved-words": "^7.27.1", "@babel/plugin-transform-shorthand-properties": "^7.27.1", - "@babel/plugin-transform-spread": "^7.27.1", + "@babel/plugin-transform-spread": "^7.28.6", "@babel/plugin-transform-sticky-regex": "^7.27.1", "@babel/plugin-transform-template-literals": "^7.27.1", "@babel/plugin-transform-typeof-symbol": "^7.27.1", "@babel/plugin-transform-unicode-escapes": "^7.27.1", - "@babel/plugin-transform-unicode-property-regex": "^7.27.1", + "@babel/plugin-transform-unicode-property-regex": "^7.28.6", "@babel/plugin-transform-unicode-regex": "^7.27.1", - "@babel/plugin-transform-unicode-sets-regex": "^7.27.1", + "@babel/plugin-transform-unicode-sets-regex": "^7.28.6", "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.14", - "babel-plugin-polyfill-corejs3": "^0.13.0", - "babel-plugin-polyfill-regenerator": "^0.6.5", - "core-js-compat": "^3.43.0", + "babel-plugin-polyfill-corejs2": "^0.4.15", + "babel-plugin-polyfill-corejs3": "^0.14.0", + "babel-plugin-polyfill-regenerator": "^0.6.6", + "core-js-compat": "^3.48.0", "semver": "^6.3.1" }, "engines": { @@ -1773,33 +1772,33 @@ } }, "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", "debug": "^4.3.1" }, "engines": { @@ -1807,9 +1806,9 @@ } }, "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", "dependencies": { @@ -1868,9 +1867,9 @@ } }, "node_modules/@inquirer/ansi": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.2.tgz", - "integrity": "sha512-SYLX05PwJVnW+WVegZt1T4Ip1qba1ik+pNJPDiqvk6zS5Y/i8PhRzLpGEtVd7sW0G8cMtkD8t4AZYhQwm8vnww==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.3.tgz", + "integrity": "sha512-g44zhR3NIKVs0zUesa4iMzExmZpLUdTLRMCStqX3GE5NT6VkPcxQGJ+uC8tDgBUC/vB1rUhUd55cOf++4NZcmw==", "dev": true, "license": "MIT", "engines": { @@ -1878,16 +1877,16 @@ } }, "node_modules/@inquirer/checkbox": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.0.3.tgz", - "integrity": "sha512-xtQP2eXMFlOcAhZ4ReKP2KZvDIBb1AnCfZ81wWXG3DXLVH0f0g4obE0XDPH+ukAEMRcZT0kdX2AS1jrWGXbpxw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.0.4.tgz", + "integrity": "sha512-DrAMU3YBGMUAp6ArwTIp/25CNDtDbxk7UjIrrtM25JVVrlVYlVzHh5HR1BDFu9JMyUoZ4ZanzeaHqNDttf3gVg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^2.0.2", - "@inquirer/core": "^11.1.0", - "@inquirer/figures": "^2.0.2", - "@inquirer/type": "^4.0.2" + "@inquirer/ansi": "^2.0.3", + "@inquirer/core": "^11.1.1", + "@inquirer/figures": "^2.0.3", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -1902,14 +1901,14 @@ } }, "node_modules/@inquirer/confirm": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.0.3.tgz", - "integrity": "sha512-lyEvibDFL+NA5R4xl8FUmNhmu81B+LDL9L/MpKkZlQDJZXzG8InxiqYxiAlQYa9cqLLhYqKLQwZqXmSTqCLjyw==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.0.4.tgz", + "integrity": "sha512-WdaPe7foUnoGYvXzH4jp4wH/3l+dBhZ3uwhKjXjwdrq5tEIFaANxj6zrGHxLdsIA0yKM0kFPVcEalOZXBB5ISA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^11.1.0", - "@inquirer/type": "^4.0.2" + "@inquirer/core": "^11.1.1", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -1924,15 +1923,15 @@ } }, "node_modules/@inquirer/core": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.1.0.tgz", - "integrity": "sha512-+jD/34T1pK8M5QmZD/ENhOfXdl9Zr+BrQAUc5h2anWgi7gggRq15ZbiBeLoObj0TLbdgW7TAIQRU2boMc9uOKQ==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.1.1.tgz", + "integrity": "sha512-hV9o15UxX46OyQAtaoMqAOxGR8RVl1aZtDx1jHbCtSJy1tBdTfKxLPKf7utsE4cRy4tcmCQ4+vdV+ca+oNxqNA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^2.0.2", - "@inquirer/figures": "^2.0.2", - "@inquirer/type": "^4.0.2", + "@inquirer/ansi": "^2.0.3", + "@inquirer/figures": "^2.0.3", + "@inquirer/type": "^4.0.3", "cli-width": "^4.1.0", "mute-stream": "^3.0.0", "signal-exit": "^4.1.0", @@ -1951,15 +1950,15 @@ } }, "node_modules/@inquirer/editor": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.0.3.tgz", - "integrity": "sha512-wYyQo96TsAqIciP/r5D3cFeV8h4WqKQ/YOvTg5yOfP2sqEbVVpbxPpfV3LM5D0EP4zUI3EZVHyIUIllnoIa8OQ==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.0.4.tgz", + "integrity": "sha512-QI3Jfqcv6UO2/VJaEFONH8Im1ll++Xn/AJTBn9Xf+qx2M+H8KZAdQ5sAe2vtYlo+mLW+d7JaMJB4qWtK4BG3pw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^11.1.0", - "@inquirer/external-editor": "^2.0.2", - "@inquirer/type": "^4.0.2" + "@inquirer/core": "^11.1.1", + "@inquirer/external-editor": "^2.0.3", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -1974,14 +1973,14 @@ } }, "node_modules/@inquirer/expand": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.0.3.tgz", - "integrity": "sha512-2oINvuL27ujjxd95f6K2K909uZOU2x1WiAl7Wb1X/xOtL8CgQ1kSxzykIr7u4xTkXkXOAkCuF45T588/YKee7w==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.0.4.tgz", + "integrity": "sha512-0I/16YwPPP0Co7a5MsomlZLpch48NzYfToyqYAOWtBmaXSB80RiNQ1J+0xx2eG+Wfxt0nHtpEWSRr6CzNVnOGg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^11.1.0", - "@inquirer/type": "^4.0.2" + "@inquirer/core": "^11.1.1", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -1996,14 +1995,14 @@ } }, "node_modules/@inquirer/external-editor": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-2.0.2.tgz", - "integrity": "sha512-X/fMXK7vXomRWEex1j8mnj7s1mpnTeP4CO/h2gysJhHLT2WjBnLv4ZQEGpm/kcYI8QfLZ2fgW+9kTKD+jeopLg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-2.0.3.tgz", + "integrity": "sha512-LgyI7Agbda74/cL5MvA88iDpvdXI2KuMBCGRkbCl2Dg1vzHeOgs+s0SDcXV7b+WZJrv2+ERpWSM65Fpi9VfY3w==", "dev": true, "license": "MIT", "dependencies": { "chardet": "^2.1.1", - "iconv-lite": "^0.7.0" + "iconv-lite": "^0.7.2" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -2018,9 +2017,9 @@ } }, "node_modules/@inquirer/figures": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.2.tgz", - "integrity": "sha512-qXm6EVvQx/FmnSrCWCIGtMHwqeLgxABP8XgcaAoywsL0NFga9gD5kfG0gXiv80GjK9Hsoz4pgGwF/+CjygyV9A==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.3.tgz", + "integrity": "sha512-y09iGt3JKoOCBQ3w4YrSJdokcD8ciSlMIWsD+auPu+OZpfxLuyz+gICAQ6GCBOmJJt4KEQGHuZSVff2jiNOy7g==", "dev": true, "license": "MIT", "engines": { @@ -2028,14 +2027,14 @@ } }, "node_modules/@inquirer/input": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.0.3.tgz", - "integrity": "sha512-4R0TdWl53dtp79Vs6Df2OHAtA2FVNqya1hND1f5wjHWxZJxwDMSNB1X5ADZJSsQKYAJ5JHCTO+GpJZ42mK0Otw==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.0.4.tgz", + "integrity": "sha512-4B3s3jvTREDFvXWit92Yc6jF1RJMDy2VpSqKtm4We2oVU65YOh2szY5/G14h4fHlyQdpUmazU5MPCFZPRJ0AOw==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^11.1.0", - "@inquirer/type": "^4.0.2" + "@inquirer/core": "^11.1.1", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -2050,14 +2049,14 @@ } }, "node_modules/@inquirer/number": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.0.3.tgz", - "integrity": "sha512-TjQLe93GGo5snRlu83JxE38ZPqj5ZVggL+QqqAF2oBA5JOJoxx25GG3EGH/XN/Os5WOmKfO8iLVdCXQxXRZIMQ==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.0.4.tgz", + "integrity": "sha512-CmMp9LF5HwE+G/xWsC333TlCzYYbXMkcADkKzcawh49fg2a1ryLc7JL1NJYYt1lJ+8f4slikNjJM9TEL/AljYQ==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^11.1.0", - "@inquirer/type": "^4.0.2" + "@inquirer/core": "^11.1.1", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -2072,15 +2071,15 @@ } }, "node_modules/@inquirer/password": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.0.3.tgz", - "integrity": "sha512-rCozGbUMAHedTeYWEN8sgZH4lRCdgG/WinFkit6ZPsp8JaNg2T0g3QslPBS5XbpORyKP/I+xyBO81kFEvhBmjA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.0.4.tgz", + "integrity": "sha512-ZCEPyVYvHK4W4p2Gy6sTp9nqsdHQCfiPXIP9LbJVW4yCinnxL/dDDmPaEZVysGrj8vxVReRnpfS2fOeODe9zjg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^2.0.2", - "@inquirer/core": "^11.1.0", - "@inquirer/type": "^4.0.2" + "@inquirer/ansi": "^2.0.3", + "@inquirer/core": "^11.1.1", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -2095,22 +2094,22 @@ } }, "node_modules/@inquirer/prompts": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.1.0.tgz", - "integrity": "sha512-LsZMdKcmRNF5LyTRuZE5nWeOjganzmN3zwbtNfcs6GPh3I2TsTtF1UYZlbxVfhxd+EuUqLGs/Lm3Xt4v6Az1wA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.2.0.tgz", + "integrity": "sha512-rqTzOprAj55a27jctS3vhvDDJzYXsr33WXTjODgVOru21NvBo9yIgLIAf7SBdSV0WERVly3dR6TWyp7ZHkvKFA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/checkbox": "^5.0.3", - "@inquirer/confirm": "^6.0.3", - "@inquirer/editor": "^5.0.3", - "@inquirer/expand": "^5.0.3", - "@inquirer/input": "^5.0.3", - "@inquirer/number": "^4.0.3", - "@inquirer/password": "^5.0.3", - "@inquirer/rawlist": "^5.1.0", - "@inquirer/search": "^4.0.3", - "@inquirer/select": "^5.0.3" + "@inquirer/checkbox": "^5.0.4", + "@inquirer/confirm": "^6.0.4", + "@inquirer/editor": "^5.0.4", + "@inquirer/expand": "^5.0.4", + "@inquirer/input": "^5.0.4", + "@inquirer/number": "^4.0.4", + "@inquirer/password": "^5.0.4", + "@inquirer/rawlist": "^5.2.0", + "@inquirer/search": "^4.1.0", + "@inquirer/select": "^5.0.4" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -2125,14 +2124,14 @@ } }, "node_modules/@inquirer/rawlist": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.1.0.tgz", - "integrity": "sha512-yUCuVh0jW026Gr2tZlG3kHignxcrLKDR3KBp+eUgNz+BAdSeZk0e18yt2gyBr+giYhj/WSIHCmPDOgp1mT2niQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.2.0.tgz", + "integrity": "sha512-CciqGoOUMrFo6HxvOtU5uL8fkjCmzyeB6fG7O1vdVAZVSopUBYECOwevDBlqNLyyYmzpm2Gsn/7nLrpruy9RFg==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^11.1.0", - "@inquirer/type": "^4.0.2" + "@inquirer/core": "^11.1.1", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -2147,15 +2146,15 @@ } }, "node_modules/@inquirer/search": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.0.3.tgz", - "integrity": "sha512-lzqVw0YwuKYetk5VwJ81Ba+dyVlhseHPx9YnRKQgwXdFS0kEavCz2gngnNhnMIxg8+j1N/rUl1t5s1npwa7bqg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.1.0.tgz", + "integrity": "sha512-EAzemfiP4IFvIuWnrHpgZs9lAhWDA0GM3l9F4t4mTQ22IFtzfrk8xbkMLcAN7gmVML9O/i+Hzu8yOUyAaL6BKA==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/core": "^11.1.0", - "@inquirer/figures": "^2.0.2", - "@inquirer/type": "^4.0.2" + "@inquirer/core": "^11.1.1", + "@inquirer/figures": "^2.0.3", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -2170,16 +2169,16 @@ } }, "node_modules/@inquirer/select": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.0.3.tgz", - "integrity": "sha512-M+ynbwS0ecQFDYMFrQrybA0qL8DV0snpc4kKevCCNaTpfghsRowRY7SlQBeIYNzHqXtiiz4RG9vTOeb/udew7w==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.0.4.tgz", + "integrity": "sha512-s8KoGpPYMEQ6WXc0dT9blX2NtIulMdLOO3LA1UKOiv7KFWzlJ6eLkEYTDBIi+JkyKXyn8t/CD6TinxGjyLt57g==", "dev": true, "license": "MIT", "dependencies": { - "@inquirer/ansi": "^2.0.2", - "@inquirer/core": "^11.1.0", - "@inquirer/figures": "^2.0.2", - "@inquirer/type": "^4.0.2" + "@inquirer/ansi": "^2.0.3", + "@inquirer/core": "^11.1.1", + "@inquirer/figures": "^2.0.3", + "@inquirer/type": "^4.0.3" }, "engines": { "node": ">=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0" @@ -2194,9 +2193,9 @@ } }, "node_modules/@inquirer/type": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.2.tgz", - "integrity": "sha512-cae7mzluplsjSdgFA6ACLygb5jC8alO0UUnFPyu0E7tNRPrL+q/f8VcSXp+cjZQ7l5CMpDpi2G1+IQvkOiL1Lw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.3.tgz", + "integrity": "sha512-cKZN7qcXOpj1h+1eTTcGDVLaBIHNMT1Rz9JqJP5MnEJ0JhgVWllx7H/tahUp5YEK1qaByH2Itb8wLG/iScD5kw==", "dev": true, "license": "MIT", "engines": { @@ -3916,7 +3915,6 @@ "integrity": "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", @@ -4092,9 +4090,9 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.34.46", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.46.tgz", - "integrity": "sha512-kiW7CtS/NkdvTUjkjUJo7d5JsFfbJ14YjdhDk9KoEgK6nFjKNXZPrX0jfLA8ZlET4cFLHxOZ/0vFKOP+bOxIOQ==", + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", "dev": true, "license": "MIT" }, @@ -4455,9 +4453,9 @@ } }, "node_modules/@triton-one/yellowstone-grpc-napi-darwin-arm64": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@triton-one/yellowstone-grpc-napi-darwin-arm64/-/yellowstone-grpc-napi-darwin-arm64-0.0.5.tgz", - "integrity": "sha512-UyxNkkBvLMOiR77s96q8OIi51mPE0YwSQT5wxPhOTvptFcfX8qbZbsqAWOnphUBtW8CoTQsAHrMz51PdCOqgEw==", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@triton-one/yellowstone-grpc-napi-darwin-arm64/-/yellowstone-grpc-napi-darwin-arm64-0.0.6.tgz", + "integrity": "sha512-sQ+0wPnDX4vBbqWotgs+T7eJas64CRMhGL3mCYqk35zaU5k+1C9XKTghYao9sp+/8635oo3r1K2of1ZPI0m4tg==", "cpu": [ "arm64" ], @@ -4467,9 +4465,9 @@ ] }, "node_modules/@triton-one/yellowstone-grpc-napi-darwin-x64": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@triton-one/yellowstone-grpc-napi-darwin-x64/-/yellowstone-grpc-napi-darwin-x64-0.0.5.tgz", - "integrity": "sha512-Lj5rR0T9wB3xeq76VtaJUHyaNstu0Mc2kwieAtHOigGfaCUvGwc5XgpbYcx5aVrUq4R8gGF9kM/9+n+GcqXxig==", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@triton-one/yellowstone-grpc-napi-darwin-x64/-/yellowstone-grpc-napi-darwin-x64-0.0.6.tgz", + "integrity": "sha512-hWP6TDtX8kG01l7Y3bSmuH95ESgB7ZsNMB9Kr57qTWgRWgcj2tyy7QjxZNZC8f9n0iGxjCgCZB78rsAkIVjrag==", "cpu": [ "x64" ], @@ -4479,9 +4477,9 @@ ] }, "node_modules/@triton-one/yellowstone-grpc-napi-linux-x64-gnu": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@triton-one/yellowstone-grpc-napi-linux-x64-gnu/-/yellowstone-grpc-napi-linux-x64-gnu-0.0.5.tgz", - "integrity": "sha512-Cx6ifzYSyaGn5uF0wN5dwwWS/wj6sDWIqZa8YRTuF6pP5pkjM78neoHNMr9taOrH5LRtwC1JSaSYyQw+inGq4g==", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@triton-one/yellowstone-grpc-napi-linux-x64-gnu/-/yellowstone-grpc-napi-linux-x64-gnu-0.0.6.tgz", + "integrity": "sha512-ZMbSNp1I4dvVIdY50zlKO7iiiBNsDdbmGl5cDSOwGG39bxPx+N8Vk1B2ZIQShc5ja7V7pmdYA3maplgkp/Fjjw==", "cpu": [ "x64" ], @@ -4491,9 +4489,9 @@ ] }, "node_modules/@triton-one/yellowstone-grpc-napi-linux-x64-musl": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/@triton-one/yellowstone-grpc-napi-linux-x64-musl/-/yellowstone-grpc-napi-linux-x64-musl-0.0.5.tgz", - "integrity": "sha512-lLb5sBVAoELgjrX57qcxe0FtJTtDaBxo4KOCQfuqqYgeEd1ooOhGeuYx2KO+zMbBXa8+8OD4mt4ZHcW5b/n9tg==", + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@triton-one/yellowstone-grpc-napi-linux-x64-musl/-/yellowstone-grpc-napi-linux-x64-musl-0.0.6.tgz", + "integrity": "sha512-kORs4rX1aTzReidLLbFhrK8oGj4R3hVP3aDhR8tKFm8modbhaEZPyqY2MPyTS3VNYyFeMQrKTLllOJ5wsUeVkQ==", "cpu": [ "x64" ], @@ -4602,7 +4600,6 @@ "integrity": "sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~7.16.0" } @@ -5120,14 +5117,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", - "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "version": "0.4.15", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.15.tgz", + "integrity": "sha512-hR3GwrRwHUfYwGfrisXPIDP3JcYfBrW7wKE7+Au6wDYl7fm/ka1NEII6kORzxNU556JjfidZeBsO10kYvtV1aw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.7", - "@babel/helper-define-polyfill-provider": "^0.6.5", + "@babel/compat-data": "^7.28.6", + "@babel/helper-define-polyfill-provider": "^0.6.6", "semver": "^6.3.1" }, "peerDependencies": { @@ -5135,27 +5132,27 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz", - "integrity": "sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.14.0.tgz", + "integrity": "sha512-AvDcMxJ34W4Wgy4KBIIePQTAOP1Ie2WFwkQp3dB7FQ/f0lI5+nM96zUnYEOE1P9sEg0es5VCP0HxiWu5fUHZAQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5", - "core-js-compat": "^3.43.0" + "@babel/helper-define-polyfill-provider": "^0.6.6", + "core-js-compat": "^3.48.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", - "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.6.tgz", + "integrity": "sha512-hYm+XLYRMvupxiQzrvXUj7YyvFFVfv5gI0R71AJzudg1g2AI2vyCPPIFEBjk162/wFzti3inBHo7isWFuEVS/A==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.5" + "@babel/helper-define-polyfill-provider": "^0.6.6" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5213,9 +5210,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.9.11", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.11.tgz", - "integrity": "sha512-Sg0xJUNDU1sJNGdfGWhVHX0kkZ+HWcvmVymJbj6NSgZZmW/8S9Y2HQ5euytnIgakgxN6papOAWiwDo1ctFDcoQ==", + "version": "2.9.19", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz", + "integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==", "dev": true, "license": "Apache-2.0", "bin": { @@ -5272,7 +5269,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -5338,9 +5334,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001762", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001762.tgz", - "integrity": "sha512-PxZwGNvH7Ak8WX5iXzoK1KPZttBXNPuaOvI2ZYU7NrlM+d9Ov+TUvlLOBNGzVXAntMSMMlJPd+jY6ovrVjSmUw==", + "version": "1.0.30001766", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", + "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", "dev": true, "funding": [ { @@ -5401,9 +5397,9 @@ "license": "MIT" }, "node_modules/ci-info": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", - "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", "dev": true, "funding": [ { @@ -5612,13 +5608,13 @@ "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.47.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.47.0.tgz", - "integrity": "sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==", + "version": "3.48.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.48.0.tgz", + "integrity": "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.28.0" + "browserslist": "^4.28.1" }, "funding": { "type": "opencollective", @@ -5747,9 +5743,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.267", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", - "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", + "version": "1.5.283", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.283.tgz", + "integrity": "sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==", "dev": true, "license": "ISC" }, @@ -5799,9 +5795,9 @@ } }, "node_modules/es-toolkit": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.43.0.tgz", - "integrity": "sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==", + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.44.0.tgz", + "integrity": "sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==", "dev": true, "license": "MIT", "workspaces": [ @@ -6193,9 +6189,9 @@ } }, "node_modules/iconv-lite": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", - "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, "license": "MIT", "dependencies": { @@ -6437,7 +6433,6 @@ "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@jest/core": "30.2.0", "@jest/types": "30.2.0", @@ -8170,9 +8165,9 @@ } }, "node_modules/prettier": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", - "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", "bin": { @@ -8668,9 +8663,9 @@ } }, "node_modules/synckit": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", - "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", + "version": "0.11.12", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", + "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8861,9 +8856,9 @@ } }, "node_modules/ts-proto": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-2.10.1.tgz", - "integrity": "sha512-4sOE1hCs0uobJgdRCtcEwdbc8MAyKP+LJqUIKxZIiKac0rPBlVKsRGEGo2oQ1MnKA2Wwk0KuGP2POkiCwPtebw==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/ts-proto/-/ts-proto-2.11.1.tgz", + "integrity": "sha512-llKeP/1jmRvZSWTEpt7whdhXY9j7J9GShtp5ZhiERq/dtnTLZMJ9DxAUjmX3FdG8Gh3HqjFYr8tPiA9qkieSKw==", "dev": true, "license": "ISC", "dependencies": { @@ -8931,7 +8926,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/yellowstone-grpc-client-nodejs/package.json b/yellowstone-grpc-client-nodejs/package.json index 1dce307e6..1199e5cce 100644 --- a/yellowstone-grpc-client-nodejs/package.json +++ b/yellowstone-grpc-client-nodejs/package.json @@ -1,6 +1,6 @@ { "name": "@triton-one/yellowstone-grpc", - "version": "5.0.1", + "version": "5.0.2", "license": "Apache-2.0", "author": "Triton One", "description": "Yellowstone gRPC Geyser Node.js Client", @@ -39,10 +39,10 @@ "@solana/rpc-types": "=5.1.0" }, "optionalDependencies": { - "@triton-one/yellowstone-grpc-napi-linux-x64-gnu": "0.0.5", - "@triton-one/yellowstone-grpc-napi-linux-x64-musl": "0.0.5", - "@triton-one/yellowstone-grpc-napi-darwin-arm64": "0.0.5", - "@triton-one/yellowstone-grpc-napi-darwin-x64": "0.0.5" + "@triton-one/yellowstone-grpc-napi-linux-x64-gnu": "0.0.6", + "@triton-one/yellowstone-grpc-napi-linux-x64-musl": "0.0.6", + "@triton-one/yellowstone-grpc-napi-darwin-arm64": "0.0.6", + "@triton-one/yellowstone-grpc-napi-darwin-x64": "0.0.6" }, "devDependencies": { "@babel/core": "^7.28.5", From af43df615c399ac91edb3f6ed61051ab55045601 Mon Sep 17 00:00:00 2001 From: juanito87 <11276687+Juanito87@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:49:18 +0000 Subject: [PATCH 23/25] Updating test to run in public runner, updating task to consume less disk space. --- .github/workflows/test.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d39cc666e..3645ffd78 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,8 +22,8 @@ jobs: test: strategy: matrix: - os: [ubuntu-22.04, ubuntu-24.04] - runs-on: ["${{ matrix.os }}"] + os: [ubuntu-22.04] + runs-on: ["${{ matrix.os }}", "Public"] steps: - name: Maximize build space uses: easimon/maximize-build-space@v10 @@ -35,6 +35,12 @@ jobs: remove-codeql: 'true' - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Clear rust cache before creating it + run: | + cargo cache -r all - uses: actions/cache@v4 with: From 64a858deb0cc9bf3d6e2406d7d90a822f2a36d7d Mon Sep 17 00:00:00 2001 From: juanito87 <11276687+Juanito87@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:51:33 +0000 Subject: [PATCH 24/25] UPD. --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3645ffd78..9ffc73e4d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,7 +23,8 @@ jobs: strategy: matrix: os: [ubuntu-22.04] - runs-on: ["${{ matrix.os }}", "Public"] + runs-on: + group: Public steps: - name: Maximize build space uses: easimon/maximize-build-space@v10 From 549379ecbeb11a20b507aebc0cda4122641f61e1 Mon Sep 17 00:00:00 2001 From: juanito87 <11276687+Juanito87@users.noreply.github.com> Date: Mon, 2 Feb 2026 16:19:04 +0000 Subject: [PATCH 25/25] Removing unneeded task as it has been moved to the public runner. --- .github/workflows/test.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9ffc73e4d..ea464ff24 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,15 +26,6 @@ jobs: runs-on: group: Public steps: - - name: Maximize build space - uses: easimon/maximize-build-space@v10 - with: - root-reserve-mb: 4096 - remove-dotnet: 'true' - remove-android: 'true' - remove-haskell: 'true' - remove-codeql: 'true' - - uses: actions/checkout@v4 with: fetch-depth: 0