diff --git a/.github/actions/build-test-wasm/action.yaml b/.github/actions/build-test-wasm/action.yaml index 90cafd52..fe006065 100644 --- a/.github/actions/build-test-wasm/action.yaml +++ b/.github/actions/build-test-wasm/action.yaml @@ -22,15 +22,15 @@ runs: wasm-pack build --target nodejs ./crates/${{ inputs.crate }} --out-dir ../../prebuilds/${{ inputs.crate }} shell: bash - name: Test WASM - # The pipeline crate's tests are top-level node:test suites that need - # --test-force-exit (the wasm exporter keeps the event loop alive after - # a flush); the other wasm crates use plain test/wasm// scripts. + # pipeline and remote_config have top-level node:test suites; the other wasm crates use + # plain test/wasm// scripts. pipeline additionally needs --test-force-exit, since its + # wasm exporter keeps the event loop alive after a flush. run: | - if [ "${{ inputs.crate }}" = "pipeline" ]; then - node --test --test-force-exit test/pipeline.js - else - node test-wasm.js ${{ inputs.crate }} - fi + case "${{ inputs.crate }}" in + pipeline) node --test --test-force-exit test/pipeline.js ;; + remote_config) node --test test/remote-config.js ;; + *) node test-wasm.js ${{ inputs.crate }} ;; + esac shell: bash - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52dc405c..4f568bf9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,30 +10,96 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Setup Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - run: yarn install - run: yarn install working-directory: test/crashtracker - run: yarn lint + build-libdatadog: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 24 + - name: Add WASM target + run: rustup target add wasm32-unknown-unknown + - name: Validate artifact dependencies + run: npm run check:dependencies + - run: npm ci --prefix packages/libdatadog + - run: cargo install wasm-pack --version 0.14.0 --locked + - run: npm run build --prefix packages/libdatadog + - name: Build symbolized WASM for size attribution + run: npm run size:profile --prefix packages/libdatadog + - name: Report and validate WASM binary size + run: >- + npm run report:wasm-size --prefix packages/libdatadog -- + ../../target/size/libdatadog_wasm_bg.wasm + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + + test-libdatadog: + needs: build-libdatadog + runs-on: ubuntu-latest + strategy: + matrix: + node: [18, 24] + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ matrix.node }} + - run: npm ci --prefix packages/libdatadog + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + - run: npm test --prefix packages/libdatadog + + test-libdatadog-windows: + name: Test libdatadog WASM (Windows, Node ${{ matrix.node }}) + needs: build-libdatadog + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + node: [18, 24] + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ matrix.node }} + - run: npm ci --prefix packages/libdatadog + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + - run: npm test --prefix packages/libdatadog + build-test-wasm: runs-on: ubuntu-latest strategy: matrix: crate: - library_config - - datadog-js-zstd - pipeline + - remote_config steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 'Use composite action' uses: ./.github/actions/build-test-wasm with: crate: '${{ matrix.crate }}' - build: + build-libdatadog-extras: uses: Datadog/action-prebuildify/.github/workflows/build.yml@main needs: build-test-wasm with: @@ -42,20 +108,22 @@ jobs: min-node-version: 18 rust: true only: darwin-arm64,darwin-x64,linux-arm64,linux-x64 - # Need this, now that libdatadog packages libunwind as a submodule - prebuild: '(command -v apk >/dev/null && apk add autoconf automake libtool) || (command -v apt-get >/dev/null && apt-get update && apt-get install -y autoconf automake libtool) || true' + prebuild: >- + (command -v apk >/dev/null && apk add autoconf automake libtool) || + (command -v apt-get >/dev/null && apt-get update && + apt-get install -y autoconf automake libtool) || true package-size: runs-on: ubuntu-latest - needs: build + needs: build-libdatadog-extras permissions: issues: write pull-requests: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - name: Setup Node.js - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - run: yarn install - name: Compute module size tree and report uses: qard/heaviest-objects-in-the-universe@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 256da64b..f815e4ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,24 +4,55 @@ on: push: branches: - v0.x + workflow_dispatch: + +concurrency: + group: npm-release-${{ github.ref }} + cancel-in-progress: false jobs: + versions: + runs-on: ubuntu-latest + outputs: + npm-tag: ${{ steps.versions.outputs.npm-tag }} + version: ${{ steps.versions.outputs.version }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - id: versions + env: + DEV_RELEASE: ${{ github.event_name == 'workflow_dispatch' }} + run: | + VERSION=$(node -p "require('./package.json').version") + + if [ "$DEV_RELEASE" = "true" ]; then + SUFFIX="dev-$(git rev-parse --short HEAD)+${{ github.run_id }}.${{ github.run_attempt }}" + VERSION="${VERSION%%-*}-$SUFFIX" + NPM_TAG=dev + else + NPM_TAG=latest + fi + + { + echo "npm-tag=$NPM_TAG" + echo "version=$VERSION" + } >> "$GITHUB_OUTPUT" + build-test-wasm: runs-on: ubuntu-latest strategy: matrix: crate: - library_config - - datadog-js-zstd - pipeline + - remote_config steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 'Use composite action' uses: ./.github/actions/build-test-wasm with: crate: '${{ matrix.crate }}' - build: + build-libdatadog-extras: uses: Datadog/action-prebuildify/.github/workflows/build.yml@main needs: build-test-wasm with: @@ -30,39 +61,141 @@ jobs: min-node-version: 18 rust: true only: darwin-arm64,darwin-x64,linux-arm64,linux-x64 + # libdatadog packages libunwind as a submodule. + prebuild: >- + (command -v apk >/dev/null && apk add autoconf automake libtool) || + (command -v apt-get >/dev/null && apt-get update && + apt-get install -y autoconf automake libtool) || true + + build-libdatadog-wasm: + runs-on: ubuntu-latest + needs: versions + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: 24 + - name: Add WASM target + run: rustup target add wasm32-unknown-unknown + - run: npm ci --prefix packages/libdatadog + - run: cargo install wasm-pack --version 0.14.0 --locked + - name: Set package version + run: node packages/libdatadog/scripts/set-version.js '${{ needs.versions.outputs.version }}' + - run: npm run build:wasm --prefix packages/libdatadog + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + + test-libdatadog-wasm: + needs: build-libdatadog-wasm + runs-on: ubuntu-latest + strategy: + matrix: + node: [18, 24] + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ matrix.node }} + - run: npm ci --prefix packages/libdatadog + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + - run: npm test --prefix packages/libdatadog + + test-libdatadog-windows: + name: Test libdatadog WASM (Windows, Node ${{ matrix.node }}) + needs: build-libdatadog-wasm + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + node: [18, 24] + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: ${{ matrix.node }} + - run: npm ci --prefix packages/libdatadog + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + - run: npm test --prefix packages/libdatadog publish: runs-on: ubuntu-latest - needs: build - environment: npm + needs: + - build-libdatadog-extras + - build-libdatadog-wasm + - test-libdatadog-wasm + - test-libdatadog-windows + - versions + environment: + name: npm + url: https://npmjs.com/package/@datadog/libdatadog permissions: id-token: write # Required for OIDC contents: read - outputs: - pkgjson: ${{ steps.pkg.outputs.json }} steps: - - uses: DataDog/dd-octo-sts-action@acaa02eee7e3bb0839e4272dacb37b8f3b58ba80 # v1.0.3 + - uses: DataDog/dd-octo-sts-action@96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a # v1.0.4 + if: github.event_name == 'push' id: octo-sts with: scope: DataDog/libdatadog-nodejs policy: self.github.release.push-tags - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: persist-credentials: false # drop GITHUB_TOKEN so the dd-octo-sts token is used for the tag push + - name: Setup Node.js + uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 + with: + node-version: '24' + registry-url: https://registry.npmjs.org - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: prebuilds path: prebuilds - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - node-version: '24' - registry-url: 'https://registry.npmjs.org' - - run: chmod -R +x ./prebuilds - - run: npm publish - - id: pkg + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + - name: Set package versions + run: | + npm pkg set 'version=${{ needs.versions.outputs.version }}' + node packages/libdatadog/scripts/set-version.js '${{ needs.versions.outputs.version }}' + - run: chmod -R +x prebuilds + - run: npm run test:package --prefix packages/libdatadog + - name: Publish libdatadog WASM + env: + NPM_TAG: ${{ needs.versions.outputs.npm-tag }} + run: npm publish packages/libdatadog/wasm --access public --tag "$NPM_TAG" + - name: Publish libdatadog + env: + NPM_TAG: ${{ needs.versions.outputs.npm-tag }} + run: npm publish packages/libdatadog --access public --tag "$NPM_TAG" + - name: Publish libdatadog extras + env: + NPM_TAG: ${{ needs.versions.outputs.npm-tag }} + run: npm publish --access public --tag "$NPM_TAG" + - name: Tag release + if: github.event_name == 'push' + env: + RELEASE_VERSION: ${{ needs.versions.outputs.version }} + RELEASE_TOKEN: ${{ steps.octo-sts.outputs.token }} + run: | + git tag "v$RELEASE_VERSION" + git push "https://x-access-token:$RELEASE_TOKEN@github.com/${{ github.repository }}.git" "v$RELEASE_VERSION" + - name: Summarize release + env: + NPM_TAG: ${{ needs.versions.outputs.npm-tag }} + VERSION: ${{ needs.versions.outputs.version }} run: | - content=`cat ./package.json | tr '\n' ' '` - echo "json=$content" >> $GITHUB_OUTPUT - - run: | - git tag v${{ fromJson(steps.pkg.outputs.json).version }} - git push https://x-access-token:${{ steps.octo-sts.outputs.token }}@github.com/${{ github.repository }}.git v${{ fromJson(steps.pkg.outputs.json).version }} + echo "Published @datadog/libdatadog@$VERSION with the npm $NPM_TAG tag." + echo "Published @datadog/libdatadog-wasm@$VERSION with the npm $NPM_TAG tag." + echo "Published @datadog/libdatadog-extras@$VERSION with the npm $NPM_TAG tag." diff --git a/Cargo.lock b/Cargo.lock index d852cbf4..9ec5e564 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -25,37 +25,37 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] [[package]] name = "anyhow" -version = "1.0.103" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a4385e2e34eb35d6b3efe798b9eb88096925d87726c0798709bf56d9ed84af3" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arc-swap" -version = "1.9.1" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +checksum = "c049c0be4daef0b145cb3555416b3b8ef5b7888a38aea1a3a155801fe7b0810b" dependencies = [ "rustversion", ] [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] @@ -66,15 +66,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" dependencies = [ "aws-lc-sys", "zeroize", @@ -82,14 +82,15 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.44.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" dependencies = [ "cc", "cmake", "dunce", "fs_extra", + "pkg-config", ] [[package]] @@ -100,9 +101,15 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "2.11.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "blazesym" @@ -142,17 +149,26 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc0b364ead1874514c8c2855ab558056ebfeb775653e7ae45ff72f28f8f3166c" +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cadence" @@ -171,9 +187,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.61" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "jobserver", @@ -181,6 +197,12 @@ dependencies = [ "shlex", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cfg-if" version = "1.0.4" @@ -189,19 +211,21 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", + "js-sys", "num-traits", "serde", + "wasm-bindgen", "windows-link 0.2.1", ] @@ -214,6 +238,16 @@ dependencies = [ "cc", ] +[[package]] +name = "combine" +version = "4.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -311,18 +345,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.15" +version = "0.5.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "d85363c37faeca707aef026efa9f3b34d077bce547e48f770770625c6013679e" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crypto-common" @@ -341,19 +375,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn", + "syn 2.0.119", ] [[package]] -name = "datadog-js-zstd" -version = "0.1.0" +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" dependencies = [ - "js-sys", - "wasm-bindgen", - "wasm-bindgen-test", - "zstd", + "darling_core", + "darling_macro", ] +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.119", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "data-encoding" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" + [[package]] name = "debugid" version = "0.8.0" @@ -363,6 +427,55 @@ dependencies = [ "uuid", ] +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.20", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "derp" +version = "0.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9b84cfd9b6fa437e498215e5625e9e3ae3bf9bb54d623028a181c40820db169" +dependencies = [ + "untrusted 0.7.1", +] + [[package]] name = "digest" version = "0.10.7" @@ -379,10 +492,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags", + "bitflags 2.13.1", "objc2", ] +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.4", +] + [[package]] name = "dunce" version = "1.0.5" @@ -397,9 +521,9 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "either" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "equivalent" @@ -423,11 +547,17 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" +[[package]] +name = "fastrand" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "fluent-uri" @@ -440,12 +570,27 @@ dependencies = [ "serde", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foldhash" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fs_extra" version = "1.3.0" @@ -469,9 +614,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -479,9 +624,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" @@ -496,9 +641,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" @@ -508,20 +653,20 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" @@ -565,27 +710,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" -dependencies = [ - "cfg-if", - "libc", - "r-efi 5.3.0", - "wasip2", -] - -[[package]] -name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "libc", - "r-efi 6.0.0", - "wasip2", - "wasip3", + "r-efi", ] [[package]] @@ -595,10 +726,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" dependencies = [ "fallible-iterator", - "indexmap", + "indexmap 2.14.0", "stable_deref_trait", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.15.5" @@ -612,9 +749,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "heck" @@ -630,33 +767,44 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" -version = "1.4.0" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", - "itoa", + "fnv", + "itoa 1.0.18", +] + +[[package]] +name = "http" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" +dependencies = [ + "bytes", + "itoa 1.0.18", ] [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", - "http", + "http 1.5.0", ] [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", - "http", + "http 1.5.0", "http-body", "pin-project-lite", ] @@ -669,18 +817,18 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" dependencies = [ "atomic-waker", "bytes", "futures-channel", "futures-core", - "http", + "http 1.5.0", "http-body", "httparse", - "itoa", + "itoa 1.0.18", "pin-project-lite", "smallvec", "tokio", @@ -693,11 +841,10 @@ version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "http", + "http 1.5.0", "hyper", "hyper-util", "rustls", - "rustls-native-certs", "tokio", "tokio-rustls", "tower-service", @@ -712,7 +859,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", + "http 1.5.0", "http-body", "hyper", "libc", @@ -748,10 +895,125 @@ dependencies = [ ] [[package]] -name = "id-arena" +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] [[package]] name = "indexmap" @@ -760,7 +1022,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] @@ -774,31 +1036,133 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + [[package]] name = "itoa" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jiff" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link 0.2.1", +] + +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + +[[package]] +name = "jiff-static" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys 0.3.1", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.119", +] + [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.97" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] @@ -818,16 +1182,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" [[package]] -name = "leb128fmt" -version = "0.1.0" +name = "libc" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] -name = "libc" -version = "0.2.186" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +name = "libdatadog-data-pipeline" +version = "0.1.0" +dependencies = [ + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf)", + "libdd-data-pipeline-core", + "libdd-trace-utils 11.0.0", + "thiserror 1.0.69", +] [[package]] name = "libdatadog-nodejs-capabilities" @@ -836,66 +1204,100 @@ dependencies = [ "anyhow", "bytes", "futures-core", - "http", + "http 1.5.0", "js-sys", - "libdd-capabilities 2.1.0", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", ] +[[package]] +name = "libdatadog-wasm" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "futures", + "getrandom 0.2.17", + "http 1.5.0", + "js-sys", + "libdatadog-data-pipeline", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf)", + "libdd-ddsketch 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen", + "wasm-bindgen-futures", + "zrip", +] + [[package]] name = "libdd-capabilities" version = "2.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "anyhow", "bytes", - "http", - "thiserror", + "http 1.5.0", + "thiserror 1.0.69", ] [[package]] name = "libdd-capabilities" -version = "2.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "3.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf#7327f3049c281090f7cce7830b9430206fba11cf" dependencies = [ "anyhow", "bytes", - "http", - "thiserror", + "futures-channel", + "futures-util", + "http 1.5.0", + "thiserror 1.0.69", +] + +[[package]] +name = "libdd-capabilities" +version = "3.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" +dependencies = [ + "anyhow", + "bytes", + "futures-channel", + "futures-util", + "http 1.5.0", + "thiserror 1.0.69", ] [[package]] name = "libdd-capabilities-impl" version = "2.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "bytes", - "http", + "http 1.5.0", "http-body-util", "libdd-capabilities 2.0.0", - "libdd-common 4.2.0", + "libdd-common 5.0.0", "tokio", ] [[package]] name = "libdd-capabilities-impl" -version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "4.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ + "anyhow", "bytes", - "http", + "http 1.5.0", "http-body-util", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "tokio", ] [[package]] name = "libdd-common" -version = "4.2.0" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" +version = "5.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "anyhow", "bytes", @@ -905,7 +1307,7 @@ dependencies = [ "futures-core", "futures-util", "hex", - "http", + "http 1.5.0", "http-body", "http-body-util", "hyper", @@ -917,9 +1319,10 @@ dependencies = [ "regex", "rustls", "rustls-native-certs", + "rustls-platform-verifier", "serde", "static_assertions", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-rustls", "tower-service", @@ -928,8 +1331,33 @@ dependencies = [ [[package]] name = "libdd-common" -version = "5.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "5.2.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf#7327f3049c281090f7cce7830b9430206fba11cf" +dependencies = [ + "anyhow", + "bytes", + "cc", + "const_format", + "futures", + "futures-core", + "futures-util", + "hex", + "http 1.5.0", + "libc", + "nix 0.29.0", + "pin-project", + "regex", + "regex-lite", + "serde", + "static_assertions", + "thiserror 1.0.69", + "windows-sys 0.52.0", +] + +[[package]] +name = "libdd-common" +version = "5.2.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "bytes", @@ -939,19 +1367,24 @@ dependencies = [ "futures-core", "futures-util", "hex", - "http", + "http 1.5.0", "http-body", "http-body-util", "hyper", + "hyper-rustls", "hyper-util", "libc", "nix 0.29.0", "pin-project", "regex", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier", "serde", "static_assertions", - "thiserror", + "thiserror 1.0.69", "tokio", + "tokio-rustls", "tower-service", "windows-sys 0.52.0", ] @@ -959,18 +1392,18 @@ dependencies = [ [[package]] name = "libdd-crashtracker" version = "1.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "anyhow", "blazesym", "cc", "chrono", "errno", - "http", + "http 1.5.0", "libc", - "libdd-common 4.2.0", + "libdd-common 5.0.0", "libdd-libunwind-sys", - "libdd-telemetry", + "libdd-telemetry 5.0.1", "nix 0.29.0", "num-derive", "num-traits", @@ -978,12 +1411,12 @@ dependencies = [ "page_size", "portable-atomic", "rand", - "schemars", + "schemars 0.8.22", "serde", "serde_json", "symbolic-common", "symbolic-demangle", - "thiserror", + "thiserror 1.0.69", "tokio", "uuid", "windows 0.59.0", @@ -991,28 +1424,30 @@ dependencies = [ [[package]] name = "libdd-data-pipeline" -version = "7.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "8.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "arc-swap", "async-trait", "bytes", "either", + "futures", "getrandom 0.2.17", - "http", + "http 1.5.0", "http-body-util", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", - "libdd-ddsketch 1.1.0", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-ddsketch 1.1.1 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-dogstatsd-client", - "libdd-shared-runtime 2.0.0", - "libdd-tinybytes", - "libdd-trace-normalization", - "libdd-trace-protobuf 4.0.0", + "libdd-shared-runtime 3.0.0", + "libdd-telemetry 7.0.0", + "libdd-tinybytes 1.1.2 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-trace-normalization 3.0.1", + "libdd-trace-protobuf 4.0.1", "libdd-trace-stats", - "libdd-trace-utils", + "libdd-trace-utils 10.1.0", "rmp-serde", "serde", "serde_json", @@ -1021,59 +1456,71 @@ dependencies = [ "tokio-util", "tracing", "uuid", + "web-time", +] + +[[package]] +name = "libdd-data-pipeline-core" +version = "1.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf#7327f3049c281090f7cce7830b9430206fba11cf" +dependencies = [ + "http 1.5.0", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf)", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf)", + "libdd-trace-utils 11.0.0", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "libdd-ddsketch" +version = "1.0.1" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" +dependencies = [ + "prost", ] [[package]] name = "libdd-ddsketch" -version = "1.0.1" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "827db9addada0e19a8371241e54fe4f27e9101c5a1dc30a13cf42dea5220e3f0" dependencies = [ "prost", ] [[package]] name = "libdd-ddsketch" -version = "1.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "1.1.1" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "prost", ] [[package]] name = "libdd-dogstatsd-client" -version = "4.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "5.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", + "async-trait", "cadence", - "http", - "libdd-common 5.1.0", + "http 1.5.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-shared-runtime 3.0.0", "serde", + "tokio", "tracing", ] [[package]] name = "libdd-library-config" -version = "1.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=353134770b312b7ccd2df6afabc253090b948e5f#353134770b312b7ccd2df6afabc253090b948e5f" -dependencies = [ - "anyhow", - "memfd", - "rand", - "rmp", - "rmp-serde", - "serde", - "serde_yaml", -] - -[[package]] -name = "libdd-library-config" -version = "2.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=7cdeb7896e92d1ba38bde495934e112dac2eda25#7cdeb7896e92d1ba38bde495934e112dac2eda25" +version = "3.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v40.0.0#ea75b04c3547037937730a14cf8a72a5ebf702d7" dependencies = [ "anyhow", "libc", - "libdd-trace-protobuf 3.0.2", + "libdd-trace-protobuf 4.0.0", "memfd", "prost", "rand", @@ -1085,26 +1532,64 @@ dependencies = [ [[package]] name = "libdd-libunwind-sys" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "227f0e30af5fbb91d1b3768db7997fdd1ded87c44b371663783c4ff3eb686908" +checksum = "cf4d5ce7d99aa9244d4dff12d25faf8ad96793183ed049b20f366ce88cf59e68" dependencies = [ "cc", "libc", "paste", ] +[[package]] +name = "libdd-remote-config" +version = "3.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" +dependencies = [ + "anyhow", + "base64", + "bytes", + "chrono", + "futures", + "futures-util", + "getrandom 0.2.17", + "hashbrown 0.15.5", + "http 1.5.0", + "http-body-util", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-trace-protobuf 4.0.1", + "libdd-tuf", + "manual_future", + "prost", + "rand", + "ring", + "serde", + "serde_json", + "serde_with", + "sha2", + "strum", + "strum_macros", + "thiserror 2.0.20", + "time", + "tokio", + "tokio-util", + "tracing", + "uuid", +] + [[package]] name = "libdd-shared-runtime" version = "1.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "async-trait", "futures", "futures-util", "libdd-capabilities 2.0.0", "libdd-capabilities-impl 2.0.0", - "libdd-common 4.2.0", + "libdd-common 5.0.0", "tokio", "tokio-util", "tracing", @@ -1113,15 +1598,15 @@ dependencies = [ [[package]] name = "libdd-shared-runtime" -version = "2.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "3.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "async-trait", "futures", "futures-util", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "tokio", "tokio-util", "tracing", @@ -1130,8 +1615,8 @@ dependencies = [ [[package]] name = "libdd-telemetry" -version = "5.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" +version = "5.0.1" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "anyhow", "async-trait", @@ -1139,10 +1624,10 @@ dependencies = [ "bytes", "futures", "hashbrown 0.15.5", - "http", + "http 1.5.0", "http-body-util", "libc", - "libdd-common 4.2.0", + "libdd-common 5.0.0", "libdd-ddsketch 1.0.1", "libdd-shared-runtime 1.0.0", "serde", @@ -1155,33 +1640,81 @@ dependencies = [ "winver", ] +[[package]] +name = "libdd-telemetry" +version = "7.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" +dependencies = [ + "anyhow", + "async-trait", + "base64", + "bytes", + "futures", + "getrandom 0.2.17", + "hashbrown 0.15.5", + "http 1.5.0", + "libc", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-ddsketch 1.1.1 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-shared-runtime 3.0.0", + "serde", + "serde_json", + "strum", + "strum_macros", + "sys-info", + "tokio", + "tokio-util", + "tracing", + "uuid", + "web-time", + "winver", +] + [[package]] name = "libdd-tinybytes" -version = "1.1.1" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "1.1.2" +source = "git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf#7327f3049c281090f7cce7830b9430206fba11cf" +dependencies = [ + "serde", +] + +[[package]] +name = "libdd-tinybytes" +version = "1.1.2" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "serde", ] [[package]] name = "libdd-trace-normalization" -version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "3.0.1" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", - "libdd-trace-protobuf 4.0.0", + "libdd-trace-protobuf 4.0.1", +] + +[[package]] +name = "libdd-trace-normalization" +version = "4.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf#7327f3049c281090f7cce7830b9430206fba11cf" +dependencies = [ + "anyhow", + "libdd-trace-protobuf 5.0.0", ] [[package]] name = "libdd-trace-obfuscation" -version = "5.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "6.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "fluent-uri", - "libdd-common 5.1.0", - "libdd-trace-protobuf 4.0.0", - "libdd-trace-utils", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-trace-protobuf 4.0.1", + "libdd-trace-utils 10.1.0", "log", "percent-encoding", "serde", @@ -1190,8 +1723,8 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" -version = "3.0.2" -source = "git+https://github.com/DataDog/libdatadog.git?rev=7cdeb7896e92d1ba38bde495934e112dac2eda25#7cdeb7896e92d1ba38bde495934e112dac2eda25" +version = "4.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v40.0.0#ea75b04c3547037937730a14cf8a72a5ebf702d7" dependencies = [ "prost", "serde", @@ -1200,8 +1733,18 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" -version = "4.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "4.0.1" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" +dependencies = [ + "prost", + "serde", + "serde_bytes", +] + +[[package]] +name = "libdd-trace-protobuf" +version = "5.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf#7327f3049c281090f7cce7830b9430206fba11cf" dependencies = [ "prost", "serde", @@ -1210,35 +1753,37 @@ dependencies = [ [[package]] name = "libdd-trace-stats" -version = "6.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "7.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "arc-swap", "async-trait", "futures", "hashbrown 0.15.5", - "http", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", - "libdd-ddsketch 1.1.0", + "http 1.5.0", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-ddsketch 1.1.1 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-dogstatsd-client", - "libdd-shared-runtime 2.0.0", + "libdd-shared-runtime 3.0.0", + "libdd-telemetry 7.0.0", "libdd-trace-obfuscation", - "libdd-trace-protobuf 4.0.0", - "libdd-trace-utils", + "libdd-trace-protobuf 4.0.1", + "libdd-trace-utils 10.1.0", "rmp-serde", "serde", "tokio", "tokio-util", "tracing", + "web-time", ] [[package]] name = "libdd-trace-utils" -version = "9.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +version = "10.1.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "base64", @@ -1246,17 +1791,17 @@ dependencies = [ "futures", "getrandom 0.2.17", "hex", - "http", + "http 1.5.0", "http-body", "http-body-util", - "indexmap", - "itoa", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", - "libdd-tinybytes", - "libdd-trace-normalization", - "libdd-trace-protobuf 4.0.0", + "indexmap 2.14.0", + "itoa 1.0.18", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-tinybytes 1.1.2 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-trace-normalization 3.0.1", + "libdd-trace-protobuf 4.0.1", "prost", "rand", "rmp", @@ -1271,6 +1816,67 @@ dependencies = [ "tracing", ] +[[package]] +name = "libdd-trace-utils" +version = "11.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf#7327f3049c281090f7cce7830b9430206fba11cf" +dependencies = [ + "anyhow", + "base64", + "bytes", + "futures", + "getrandom 0.2.17", + "hex", + "http 1.5.0", + "http-body", + "http-body-util", + "indexmap 2.14.0", + "itoa 1.0.18", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf)", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf)", + "libdd-tinybytes 1.1.2 (git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf)", + "libdd-trace-normalization 4.0.0", + "libdd-trace-protobuf 5.0.0", + "prost", + "rand", + "rmp", + "rmp-serde", + "rmpv", + "rustc-hash", + "serde", + "serde-transcode", + "serde_json", + "thin-vec", + "tracing", + "zrip", + "zstd", +] + +[[package]] +name = "libdd-tuf" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7e7c44ae16b25063087e576b0ec25b46ef3a84c8a2239ea85ef7685fd46fb6" +dependencies = [ + "chrono", + "data-encoding", + "derp", + "futures-io", + "futures-util", + "http 0.2.12", + "itoa 0.4.8", + "log", + "percent-encoding", + "ring", + "serde", + "serde_derive", + "serde_json", + "tempfile", + "thiserror 1.0.69", + "untrusted 0.7.1", + "url", +] + [[package]] name = "libloading" version = "0.8.9" @@ -1293,9 +1899,7 @@ version = "0.2.0" dependencies = [ "anyhow", "getrandom 0.2.17", - "libdd-library-config 1.0.0", - "serde", - "serde-wasm-bindgen", + "libdd-library-config", "wasm-bindgen", "wasm-bindgen-test", ] @@ -1306,17 +1910,32 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + [[package]] name = "log" -version = "0.4.29" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" + +[[package]] +name = "manual_future" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c72f11f1d8e0c453cbd8042dfb83c2b50384f78a5a5d41019627c5f2062ece" +dependencies = [ + "futures-util", +] [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "memfd" @@ -1329,9 +1948,9 @@ dependencies = [ [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -1347,9 +1966,9 @@ dependencies = [ [[package]] name = "minicov" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4869b6a491569605d66d3952bcdf03df789e5b536e5f0cf7758a7f08a55ae24d" +checksum = "c3aa3aa12b448ac225b3102217d1ac5cc717908f02722926524b0599c933c7a0" dependencies = [ "cc", "walkdir", @@ -1367,9 +1986,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", @@ -1382,8 +2001,8 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeff6bd154a309b2ada5639b2661ca6ae4599b34e8487dc276d2cd637da2d76" dependencies = [ - "bitflags", - "itoa", + "bitflags 2.13.1", + "itoa 1.0.18", ] [[package]] @@ -1392,7 +2011,7 @@ version = "2.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" dependencies = [ - "bitflags", + "bitflags 2.13.1", "ctor", "napi-derive", "napi-sys", @@ -1412,7 +2031,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1425,7 +2044,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1443,7 +2062,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags", + "bitflags 2.13.1", "cfg-if", "cfg_aliases", "libc", @@ -1452,11 +2071,11 @@ dependencies = [ [[package]] name = "nix" -version = "0.30.1" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags", + "bitflags 2.13.1", "cfg-if", "cfg_aliases", "libc", @@ -1471,6 +2090,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + [[package]] name = "num-derive" version = "0.4.2" @@ -1479,7 +2104,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1507,7 +2132,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags", + "bitflags 2.13.1", "objc2", "objc2-foundation", ] @@ -1528,7 +2153,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags", + "bitflags 2.13.1", "dispatch2", "objc2", ] @@ -1539,7 +2164,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags", + "bitflags 2.13.1", "dispatch2", "objc2", "objc2-core-foundation", @@ -1572,7 +2197,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags", + "bitflags 2.13.1", "objc2", "objc2-core-foundation", "objc2-core-graphics", @@ -1590,7 +2215,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags", + "bitflags 2.13.1", "block2", "libc", "objc2", @@ -1603,7 +2228,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags", + "bitflags 2.13.1", "objc2", "objc2-core-foundation", ] @@ -1614,7 +2239,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags", + "bitflags 2.13.1", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -1626,7 +2251,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags", + "bitflags 2.13.1", "block2", "objc2", "objc2-cloud-kit", @@ -1671,13 +2296,13 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "os_info" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224" +checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b" dependencies = [ "android_system_properties", "log", - "nix 0.30.1", + "nix 0.31.3", "objc2", "objc2-foundation", "objc2-ui-kit", @@ -1709,22 +2334,22 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -1740,16 +2365,16 @@ dependencies = [ "bytes", "console_error_panic_hook", "getrandom 0.2.17", - "http", + "http 1.5.0", "js-sys", "libdatadog-nodejs-capabilities", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-data-pipeline", - "libdd-shared-runtime 2.0.0", - "libdd-trace-protobuf 4.0.0", + "libdd-shared-runtime 3.0.0", + "libdd-trace-protobuf 4.0.1", "libdd-trace-stats", - "libdd-trace-utils", + "libdd-trace-utils 10.1.0", "rmp-serde", "serde", "serde_json", @@ -1757,47 +2382,62 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", + "web-time", ] [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" dependencies = [ "serde", ] [[package]] -name = "ppv-lite86" -version = "0.2.21" +name = "portable-atomic-util" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" dependencies = [ - "zerocopy", + "portable-atomic", ] [[package]] -name = "prettyplease" -version = "0.2.37" +name = "potential_utf" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" dependencies = [ - "proc-macro2", - "syn", + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -1807,17 +2447,17 @@ name = "process-discovery" version = "0.1.0" dependencies = [ "anyhow", - "libdd-library-config 2.0.0", - "libdd-trace-protobuf 3.0.2", + "libdd-library-config", + "libdd-trace-protobuf 4.0.0", "napi", "napi-derive", ] [[package]] name = "prost" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ "bytes", "prost-derive", @@ -1825,32 +2465,26 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", "itertools", "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - [[package]] name = "r-efi" version = "6.0.0" @@ -1859,9 +2493,9 @@ checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" dependencies = [ "libc", "rand_chacha", @@ -1889,29 +2523,29 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.25" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -1921,20 +2555,43 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "remote-config" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "libdatadog-nodejs-capabilities", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", + "libdd-remote-config", + "serde", + "serde-wasm-bindgen", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", +] [[package]] name = "ring" @@ -1946,7 +2603,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.17", "libc", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.52.0", ] @@ -1980,15 +2637,15 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustix" @@ -1996,7 +2653,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys", @@ -2005,9 +2662,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "aws-lc-rs", "once_cell", @@ -2032,30 +2689,57 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a7197ae7eb376e574fe940d068c30fe0462554a3ddbe4eca7838e049c937a9" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "zeroize", ] +[[package]] +name = "rustls-platform-verifier" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "ryu" @@ -2085,10 +2769,34 @@ dependencies = [ name = "schemars" version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" dependencies = [ "dyn-clone", - "schemars_derive", + "ref-cast", "serde", "serde_json", ] @@ -2102,7 +2810,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 2.0.119", ] [[package]] @@ -2111,7 +2819,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", + "bitflags 2.13.1", "core-foundation", "core-foundation-sys", "libc", @@ -2128,12 +2836,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" - [[package]] name = "serde" version = "1.0.228" @@ -2191,7 +2893,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2202,31 +2904,64 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ - "indexmap", - "itoa", + "indexmap 2.14.0", + "itoa 1.0.18", "memchr", "serde", "serde_core", "zmij", ] +[[package]] +name = "serde_with" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee78f1fbe43ac4a0e47aadb3dbd357b69eb0d3793e948624cd03dd2750ab1c0a" +dependencies = [ + "base64", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "jiff", + "schemars 0.9.0", + "schemars 1.2.2", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8705578779c2b6bd90d84d66eb2e206b708b1a4d7b9f17641b293545bf1c7e46" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "serde_yaml" version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap", - "itoa", + "indexmap 2.14.0", + "itoa 1.0.18", "ryu", "serde", "unsafe-libyaml", @@ -2245,15 +2980,15 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "slab" @@ -2263,15 +2998,15 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", @@ -2289,6 +3024,31 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.119", +] + [[package]] name = "subtle" version = "2.6.1" @@ -2321,15 +3081,37 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "sys-info" version = "0.9.1" @@ -2340,11 +3122,24 @@ dependencies = [ "libc", ] +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.3", + "once_cell", + "rustix", + "windows-sys 0.61.2", +] + [[package]] name = "thin-vec" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f7e269b48f0a7dd0146680fa24b50cc67fc0373f086a5b2f99bd084639b482" +checksum = "79def32ffcd477db1ff26f76dab9e3a91f0bd42a85ca96577089b24623056f9d" [[package]] name = "thiserror" @@ -2352,7 +3147,16 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl 2.0.20", ] [[package]] @@ -2363,14 +3167,80 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.4", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", ] +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" -version = "1.52.1" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -2383,13 +3253,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] @@ -2404,13 +3274,14 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", + "libc", "pin-project-lite", "tokio", ] @@ -2448,9 +3319,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-ident" @@ -2460,9 +3331,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-xid" @@ -2476,19 +3347,43 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uuid" -version = "1.23.1" +version = "1.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "f053576934f05a761a402421fbbe3d425d9366f75f978806a037b3ca481abecc" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -2525,29 +3420,11 @@ version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" -[[package]] -name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" -dependencies = [ - "wit-bindgen 0.51.0", -] - [[package]] name = "wasm-bindgen" -version = "0.2.120" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -2558,9 +3435,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.70" +version = "0.4.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" dependencies = [ "js-sys", "wasm-bindgen", @@ -2568,9 +3445,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.120" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2578,31 +3455,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.120" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.120" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-bindgen-test" -version = "0.3.70" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29826f9d9ecaa314c480d376b276d1c790e6cb6a4681fab8532da69cbabf977d" +checksum = "895a2607575412a4eda1df892084a375ea10dfeadc4d7d2ab87b854e4ddc7ba1" dependencies = [ "async-trait", "cast", @@ -2622,53 +3499,38 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.70" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c610311887f9e6599a546d278d12d69dfd3a3e92639b2129e4b11ad6cf1961d6" +checksum = "4288cb0ebe215033bf949ae1fd046726daa4c32a157f24b9dc6ac387a52aa759" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] name = "wasm-bindgen-test-shared" -version = "0.2.120" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60238e5b4b1b295701d6f9a66d2a126fe19990348f5fb9dae3b623a370119d94" - -[[package]] -name = "wasm-encoder" -version = "0.244.0" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] +checksum = "33ff1c1b360982e93b6d8ea9c04836f71dba0817a16f91e229cf3a51bdd9d987" [[package]] -name = "wasm-metadata" -version = "0.244.0" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "wasmparser" -version = "0.244.0" +name = "webpki-root-certs" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver", + "rustls-pki-types", ] [[package]] @@ -2755,7 +3617,7 @@ checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2766,7 +3628,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2777,7 +3639,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.119", ] [[package]] @@ -2828,6 +3690,15 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.52.0" @@ -2846,6 +3717,21 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -2894,6 +3780,12 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -2912,6 +3804,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -2930,6 +3828,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -2960,6 +3864,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -2978,6 +3888,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -2996,6 +3912,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3014,6 +3936,12 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3042,130 +3970,154 @@ dependencies = [ ] [[package]] -name = "wit-bindgen" -version = "0.51.0" +name = "writeable" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] -name = "wit-bindgen" -version = "0.57.1" +name = "yoke" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] [[package]] -name = "wit-bindgen-core" -version = "0.51.0" +name = "yoke-derive" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ - "anyhow", - "heck", - "wit-parser", + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", ] [[package]] -name = "wit-bindgen-rust" -version = "0.51.0" +name = "zerocopy" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", + "zerocopy-derive", ] [[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" +name = "zerocopy-derive" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ - "anyhow", - "prettyplease", "proc-macro2", "quote", - "syn", - "wit-bindgen-core", - "wit-bindgen-rust", + "syn 2.0.119", ] [[package]] -name = "wit-component" -version = "0.244.0" +name = "zerofrom" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", + "zerofrom-derive", ] [[package]] -name = "wit-parser" -version = "0.244.0" +name = "zerofrom-derive" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", ] [[package]] -name = "zerocopy" -version = "0.8.48" +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zerotrie" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" dependencies = [ - "zerocopy-derive", + "displaydoc", + "yoke", + "zerofrom", ] [[package]] -name = "zerocopy-derive" -version = "0.8.48" +name = "zerovec" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 3.0.4", ] [[package]] -name = "zeroize" -version = "1.8.2" +name = "zmij" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" [[package]] -name = "zmij" -version = "1.0.21" +name = "zrip" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964fe9f1ea10a0d183fc143a7525266cbe16978883dbe304725da34b314c04cf" +dependencies = [ + "zrip-core", + "zrip-decode", + "zrip-encode", +] + +[[package]] +name = "zrip-core" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc201ba56175f86e67cc88bdaf1a7af9c061815c7dde719c7a6a1ed5aaa186b" + +[[package]] +name = "zrip-decode" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "038f795e49887bdeaab197fff84c8165644484a98dc3f2354e5df3d2e5f4f978" +dependencies = [ + "zrip-core", +] + +[[package]] +name = "zrip-encode" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3dfdcbb503db2045716492d5ab31cd82f2852d0d93d8edf6a9235653d9da685" +dependencies = [ + "zrip-core", +] [[package]] name = "zstd" diff --git a/LICENSE-3rdparty.csv b/LICENSE-3rdparty.csv index 2a79a4cd..3e05281c 100644 --- a/LICENSE-3rdparty.csv +++ b/LICENSE-3rdparty.csv @@ -1,26 +1,66 @@ Component,Origin,License,Copyright -addr2line,https://github.com/gimli-rs/addr2line,Apache-2.0 OR MIT,The addr2line Authors -adler,https://github.com/jonas-schievink/adler,0BSD OR MIT OR Apache-2.0,Jonas Schievink +adler2,https://github.com/oyvindln/adler2,0BSD OR MIT OR Apache-2.0,"Jonas Schievink , oyvindln " aho-corasick,https://github.com/BurntSushi/aho-corasick,Unlicense OR MIT,Andrew Gallant +allocator-api2,https://github.com/zakarumych/allocator-api2,MIT OR Apache-2.0,Zakarum +android_system_properties,https://github.com/nical/android_system_properties,MIT OR Apache-2.0,Nicolas Silva anyhow,https://github.com/dtolnay/anyhow,MIT OR Apache-2.0,David Tolnay -backtrace,https://github.com/rust-lang/backtrace-rs,MIT OR Apache-2.0,The Rust Project Developers -base64,https://github.com/marshallpierce/rust-base64,MIT OR Apache-2.0,"Alice Maz , Marshall Pierce " +arc-swap,https://github.com/vorner/arc-swap,MIT OR Apache-2.0,Michal 'vorner' Vaner +async-trait,https://github.com/dtolnay/async-trait,MIT OR Apache-2.0,David Tolnay +atomic-waker,https://github.com/smol-rs/atomic-waker,Apache-2.0 OR MIT,"Stjepan Glavina , Contributors to futures-rs" +aws-lc-rs,https://github.com/aws/aws-lc-rs,ISC AND (Apache-2.0 OR ISC),AWS-LibCrypto +aws-lc-sys,https://github.com/aws/aws-lc-rs,ISC AND (Apache-2.0 OR ISC) AND Apache-2.0 AND MIT AND BSD-3-Clause AND (Apache-2.0 OR ISC OR MIT) AND (Apache-2.0 OR ISC OR MIT-0),AWS-LC +base64,https://github.com/marshallpierce/rust-base64,MIT OR Apache-2.0,Marshall Pierce bitflags,https://github.com/bitflags/bitflags,MIT OR Apache-2.0,The Rust Project Developers +blazesym,https://github.com/libbpf/blazesym,BSD-3-Clause,"Daniel Müller , Kui-Feng " +block-buffer,https://github.com/RustCrypto/utils,MIT OR Apache-2.0,RustCrypto Developers +block2,https://github.com/madsmtm/objc2,MIT,Mads Marquart +borrow-or-share,https://github.com/yescallop/borrow-or-share,MIT-0,Scallop Ye +bs58,https://github.com/Nullus157/bs58-rs,MIT OR Apache-2.0,The bs58 Authors bumpalo,https://github.com/fitzgen/bumpalo,MIT OR Apache-2.0,Nick Fitzgerald -byteorder,https://github.com/BurntSushi/byteorder,Unlicense OR MIT,Andrew Gallant bytes,https://github.com/tokio-rs/bytes,MIT,"Carl Lerche , Sean McArthur " -cfg-if,https://github.com/alexcrichton/cfg-if,MIT OR Apache-2.0,Alex Crichton -collector,https://github.com/DataDog/libdatadog,Apache-2.0,The collector Authors +cadence,https://github.com/56quarters/cadence,Apache-2.0 OR MIT,Nick Pillitteri +cast,https://github.com/japaric/cast.rs,MIT OR Apache-2.0,Jorge Aparicio +cc,https://github.com/rust-lang/cc-rs,MIT OR Apache-2.0,Alex Crichton +cesu8,https://github.com/emk/cesu8-rs,Apache-2.0 OR MIT,Eric Kidd +cfg-if,https://github.com/rust-lang/cfg-if,MIT OR Apache-2.0,Alex Crichton +chrono,https://github.com/chronotope/chrono,MIT OR Apache-2.0,The chrono Authors +combine,https://github.com/Marwes/combine,MIT,Markus Westerlind +console_error_panic_hook,https://github.com/rustwasm/console_error_panic_hook,Apache-2.0 OR MIT,Nick Fitzgerald +const_format,https://github.com/rodrimati1992/const_format_crates,Zlib,rodrimati1992 +const_format_proc_macros,https://github.com/rodrimati1992/const_format_crates,Zlib,rodrimati1992 +convert_case,https://github.com/rutrum/convert-case,MIT,Rutrum core-foundation,https://github.com/servo/core-foundation-rs,MIT OR Apache-2.0,The Servo Project Developers -crc32fast,https://github.com/srijs/rust-crc32fast,MIT OR Apache-2.0,"Sam Rijs , Alex Crichton " -data-pipeline,https://github.com/DataDog/libdatadog,Apache-2.0,The data-pipeline Authors -datadog-trace-normalization,https://github.com/DataDog/libdatadog,Apache-2.0,David Lee -datadog-trace-protobuf,https://github.com/DataDog/libdatadog,Apache-2.0,David Lee -datadog-trace-utils,https://github.com/DataDog/libdatadog,Apache-2.0,David Lee -ddcommon,https://github.com/DataDog/libdatadog,Apache-2.0,The ddcommon Authors +core-foundation-sys,https://github.com/servo/core-foundation-rs,MIT OR Apache-2.0,The Servo Project Developers +cpp_demangle,https://github.com/gimli-rs/cpp_demangle,MIT OR Apache-2.0,"Nick Fitzgerald , Jim Blandy , Kyle Huey " +cpufeatures,https://github.com/RustCrypto/utils,MIT OR Apache-2.0,RustCrypto Developers +crossbeam-channel,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-channel Authors +crossbeam-utils,https://github.com/crossbeam-rs/crossbeam,MIT OR Apache-2.0,The crossbeam-utils Authors +crypto-common,https://github.com/RustCrypto/traits,MIT OR Apache-2.0,RustCrypto Developers +ctor,https://github.com/mmastrac/rust-ctor,Apache-2.0 OR MIT,Matt Mastracci +darling,https://github.com/TedDriggs/darling,MIT,Ted Driggs +darling_core,https://github.com/TedDriggs/darling,MIT,Ted Driggs +darling_macro,https://github.com/TedDriggs/darling,MIT,Ted Driggs +data-encoding,https://github.com/ia0/data-encoding,MIT,The data-encoding Authors +debugid,https://github.com/getsentry/rust-debugid,Apache-2.0,Sentry +defmt,https://github.com/knurling-rs/defmt,MIT OR Apache-2.0,The Knurling-rs developers +defmt-macros,https://github.com/knurling-rs/defmt,MIT OR Apache-2.0,The Knurling-rs developers +defmt-parser,https://github.com/knurling-rs/defmt,MIT OR Apache-2.0,The Knurling-rs developers +deranged,https://github.com/jhpratt/deranged,MIT OR Apache-2.0,Jacob Pratt +derp,https://github.com/heartsucker/derp,ISC,heartsucker +digest,https://github.com/RustCrypto/traits,MIT OR Apache-2.0,RustCrypto Developers +dispatch2,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,"Mads Marquart , Mary " +displaydoc,https://github.com/yaahc/displaydoc,MIT OR Apache-2.0,Jane Lusby +dyn-clone,https://github.com/dtolnay/dyn-clone,MIT OR Apache-2.0,David Tolnay either,https://github.com/rayon-rs/either,MIT OR Apache-2.0,bluss -flate2,https://github.com/rust-lang/flate2-rs,MIT OR Apache-2.0,"Alex Crichton , Josh Triplett " +equivalent,https://github.com/indexmap-rs/equivalent,Apache-2.0 OR MIT,The equivalent Authors +errno,https://github.com/lambda-fairy/rust-errno,MIT OR Apache-2.0,"Chris Wong , Dan Gohman " +fallible-iterator,https://github.com/sfackler/rust-fallible-iterator,MIT OR Apache-2.0,Steven Fackler +fastrand,https://github.com/smol-rs/fastrand,Apache-2.0 OR MIT,Stjepan Glavina +find-msvc-tools,https://github.com/rust-lang/cc-rs,MIT OR Apache-2.0,The find-msvc-tools Authors +fluent-uri,https://github.com/yescallop/fluent-uri-rs,MIT,Scallop Ye fnv,https://github.com/servo/rust-fnv,Apache-2.0 OR MIT,Alex Crichton +foldhash,https://github.com/orlp/foldhash,Zlib,Orson Peters +form_urlencoded,https://github.com/servo/rust-url,MIT OR Apache-2.0,The rust-url developers futures,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures Authors futures-channel,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-channel Authors futures-core,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-core Authors @@ -30,91 +70,284 @@ futures-macro,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futu futures-sink,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-sink Authors futures-task,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-task Authors futures-util,https://github.com/rust-lang/futures-rs,MIT OR Apache-2.0,The futures-util Authors +generic-array,https://github.com/fizyk20/generic-array,MIT,"Bartłomiej Kamiński , Aaron Trent " getrandom,https://github.com/rust-random/getrandom,MIT OR Apache-2.0,The Rand Project Developers gimli,https://github.com/gimli-rs/gimli,MIT OR Apache-2.0,The gimli Authors -hermit-abi,https://github.com/hermit-os/hermit-rs,MIT OR Apache-2.0,Stefan Lankes +hashbrown,https://github.com/rust-lang/hashbrown,MIT OR Apache-2.0,Amanieu d'Antras +heck,https://github.com/withoutboats/heck,MIT OR Apache-2.0,The heck Authors hex,https://github.com/KokaKiwi/rust-hex,MIT OR Apache-2.0,KokaKiwi http,https://github.com/hyperium/http,MIT OR Apache-2.0,"Alex Crichton , Carl Lerche , Sean McArthur " http-body,https://github.com/hyperium/http-body,MIT,"Carl Lerche , Lucio Franco , Sean McArthur " +http-body-util,https://github.com/hyperium/http-body,MIT,"Carl Lerche , Lucio Franco , Sean McArthur " httparse,https://github.com/seanmonstar/httparse,MIT OR Apache-2.0,Sean McArthur -httpdate,https://github.com/pyfisch/httpdate,MIT OR Apache-2.0,Pyfisch hyper,https://github.com/hyperium/hyper,MIT,Sean McArthur -hyper-rustls,https://github.com/ctz/hyper-rustls,Apache-2.0 OR ISC OR MIT,The hyper-rustls Authors +hyper-rustls,https://github.com/rustls/hyper-rustls,Apache-2.0 OR ISC OR MIT,The hyper-rustls Authors +hyper-util,https://github.com/hyperium/hyper-util,MIT,Sean McArthur +iana-time-zone,https://github.com/strawlab/iana-time-zone,MIT OR Apache-2.0,"Andrew Straw , René Kijewski , Ryan Lopopolo " +iana-time-zone-haiku,https://github.com/strawlab/iana-time-zone,MIT OR Apache-2.0,René Kijewski +icu_collections,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +icu_locale_core,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +icu_normalizer,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +icu_normalizer_data,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +icu_properties,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +icu_properties_data,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +icu_provider,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +id-arena,https://github.com/fitzgen/id-arena,MIT OR Apache-2.0,"Nick Fitzgerald , Aleksey Kladov " +ident_case,https://github.com/TedDriggs/ident_case,MIT OR Apache-2.0,Ted Driggs +idna,https://github.com/servo/rust-url,MIT OR Apache-2.0,The rust-url developers +idna_adapter,https://github.com/hsivonen/idna_adapter,Apache-2.0 OR MIT,The rust-url developers +indexmap,https://github.com/bluss/indexmap,Apache-2.0 OR MIT,The indexmap Authors +indexmap,https://github.com/indexmap-rs/indexmap,Apache-2.0 OR MIT,The indexmap Authors itertools,https://github.com/rust-itertools/itertools,MIT OR Apache-2.0,bluss itoa,https://github.com/dtolnay/itoa,MIT OR Apache-2.0,David Tolnay -js-sys,https://github.com/rustwasm/wasm-bindgen/tree/master/crates/js-sys,MIT OR Apache-2.0,The wasm-bindgen Developers -lazy_static,https://github.com/rust-lang-nursery/lazy-static.rs,MIT OR Apache-2.0,Marvin Löbel +jiff,https://github.com/BurntSushi/jiff,Unlicense OR MIT,Andrew Gallant +jiff-core,https://github.com/BurntSushi/jiff,Unlicense OR MIT,Andrew Gallant +jiff-static,https://github.com/BurntSushi/jiff,Unlicense OR MIT,Andrew Gallant +jiff-tzdb,https://github.com/BurntSushi/jiff,Unlicense OR MIT,Andrew Gallant +jiff-tzdb-platform,https://github.com/BurntSushi/jiff,Unlicense OR MIT,Andrew Gallant +jni,https://github.com/jni-rs/jni-rs,MIT OR Apache-2.0,Josh Chase +jni-sys,https://github.com/jni-rs/jni-sys,MIT OR Apache-2.0,Steven Fackler +jni-sys,https://github.com/jni-rs/jni-sys,MIT OR Apache-2.0,"Steven Fackler , Robert Bragg " +jni-sys-macros,https://github.com/jni-rs/jni-sys,MIT OR Apache-2.0,Robert Bragg +jobserver,https://github.com/rust-lang/jobserver-rs,MIT OR Apache-2.0,Alex Crichton +js-sys,https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/js-sys,MIT OR Apache-2.0,The wasm-bindgen Developers +konst,https://github.com/rodrimati1992/konst,Zlib,rodrimati1992 +konst_macro_rules,https://github.com/rodrimati1992/konst,Zlib,rodrimati1992 +leb128fmt,https://github.com/bluk/leb128fmt,MIT OR Apache-2.0,Bryant Luk libc,https://github.com/rust-lang/libc,MIT OR Apache-2.0,The Rust Project Developers +libdd-capabilities,https://github.com/DataDog/libdatadog/tree/main/libdd-capabilities,Apache-2.0,The libdd-capabilities Authors +libdd-capabilities-impl,https://github.com/DataDog/libdatadog/tree/main/libdd-capabilities-impl,Apache-2.0,The libdd-capabilities-impl Authors +libdd-common,https://github.com/DataDog/libdatadog/tree/main/datadog-common,Apache-2.0,The libdd-common Authors +libdd-crashtracker,https://github.com/DataDog/libdatadog/tree/main/libdd-crashtracker,Apache-2.0,The libdd-crashtracker Authors +libdd-data-pipeline,https://github.com/DataDog/libdatadog/tree/main/libdd-data-pipeline,Apache-2.0,The libdd-data-pipeline Authors +libdd-ddsketch,https://github.com/DataDog/libdatadog/tree/main/libdd-ddsketch,Apache-2.0,The libdd-ddsketch Authors +libdd-dogstatsd-client,https://github.com/DataDog/libdatadog/tree/main/libdd-dogstatsd-client,Apache-2.0,The libdd-dogstatsd-client Authors +libdd-library-config,https://github.com/DataDog/libdatadog/tree/main/libdd-library-config,Apache-2.0,The libdd-library-config Authors +libdd-libunwind-sys,https://github.com/DataDog/libdatadog/tree/main/libdd-libunwind-sys,Apache-2.0,The libdd-libunwind-sys Authors +libdd-remote-config,https://github.com/DataDog/libdatadog/tree/main/libdd-remote-config,Apache-2.0,Datadog Inc. +libdd-shared-runtime,https://github.com/DataDog/libdatadog/tree/main/libdd-shared-runtime,Apache-2.0,The libdd-shared-runtime Authors +libdd-telemetry,https://github.com/DataDog/libdatadog/tree/main/libdd-telemetry,Apache-2.0,The libdd-telemetry Authors +libdd-tinybytes,https://github.com/DataDog/libdatadog/tree/main/libdd-tinybytes,Apache-2.0,The libdd-tinybytes Authors +libdd-trace-normalization,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-normalization,Apache-2.0,David Lee +libdd-trace-obfuscation,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-obfuscation,Apache-2.0,Datadog Inc. +libdd-trace-protobuf,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-protobuf,Apache-2.0,The libdd-trace-protobuf Authors +libdd-trace-stats,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-stats,Apache-2.0,The libdd-trace-stats Authors +libdd-trace-utils,https://github.com/DataDog/libdatadog/tree/main/libdd-trace-utils,Apache-2.0,The libdd-trace-utils Authors +libdd-tuf,https://github.com/theupdateframework/rust-tuf,MIT OR Apache-2.0,"heartsucker , Erick Tryzelaar " libloading,https://github.com/nagisa/rust_libloading,ISC,Simonas Kazlauskas +libm,https://github.com/rust-lang/compiler-builtins,MIT,"Alex Crichton , Amanieu d'Antras , Jorge Aparicio , Trevor Gross " +linux-raw-sys,https://github.com/sunfishcode/linux-raw-sys,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Dan Gohman +litemap,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers log,https://github.com/rust-lang/log,MIT OR Apache-2.0,The Rust Project Developers +manual_future,https://github.com/dmarcuse/manual_future,MIT,Dana Marcuse memchr,https://github.com/BurntSushi/memchr,Unlicense OR MIT,"Andrew Gallant , bluss" -miniz_oxide,https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide,MIT OR Zlib OR Apache-2.0,"Frommi , oyvindln " +memfd,https://github.com/lucab/memfd-rs,MIT OR Apache-2.0,"Luca Bruno , Simonas Kazlauskas " +memmap2,https://github.com/RazrFalcon/memmap2-rs,MIT OR Apache-2.0,"Dan Burkert , Yevhenii Reizner , The Contributors" +memoffset,https://github.com/Gilnaa/memoffset,MIT,Gilad Naaman +minicov,https://github.com/Amanieu/minicov,Apache-2.0 OR MIT,Amanieu d'Antras +miniz_oxide,https://github.com/Frommi/miniz_oxide/tree/master/miniz_oxide,MIT OR Zlib OR Apache-2.0,"Frommi , oyvindln , Rich Geldreich richgel99@gmail.com" mio,https://github.com/tokio-rs/mio,MIT,"Carl Lerche , Thomas de Zeeuw , Tokio Contributors " -neon,https://github.com/neon-bindings/neon,MIT OR Apache-2.0,Dave Herman +msvc-demangler,https://github.com/mstange/msvc-demangler-rust,MIT OR NCSA,"Markus Stange , Jeff Muizelaar " +napi,https://github.com/napi-rs/napi-rs,MIT,"Nathan Sobo , Yinan Long " +napi-derive,https://github.com/napi-rs/napi-rs,MIT,"LongYinan , Forehalo " +napi-derive-backend,https://github.com/napi-rs/napi-rs,MIT,The napi-derive-backend Authors +napi-sys,https://github.com/napi-rs/napi-rs,MIT,LongYinan +nix,https://github.com/nix-rust/nix,MIT,The nix-rust Project Developers +nu-ansi-term,https://github.com/nushell/nu-ansi-term,MIT,"ogham@bsago.me, Ryan Scheel (Havvy) , Josh Triplett , The Nushell Project Developers" +num-conv,https://github.com/jhpratt/num-conv,MIT OR Apache-2.0,Jacob Pratt +num-derive,https://github.com/rust-num/num-derive,MIT OR Apache-2.0,The Rust Project Developers num-traits,https://github.com/rust-num/num-traits,MIT OR Apache-2.0,The Rust Project Developers -num_cpus,https://github.com/seanmonstar/num_cpus,MIT OR Apache-2.0,Sean McArthur -object,https://github.com/gimli-rs/object,Apache-2.0 OR MIT,The object Authors +objc2,https://github.com/madsmtm/objc2,MIT,Mads Marquart +objc2-cloud-kit,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-cloud-kit Authors +objc2-core-data,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-core-data Authors +objc2-core-foundation,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-core-foundation Authors +objc2-core-graphics,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-core-graphics Authors +objc2-core-image,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-core-image Authors +objc2-core-location,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-core-location Authors +objc2-core-text,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-core-text Authors +objc2-encode,https://github.com/madsmtm/objc2,MIT,Mads Marquart +objc2-foundation,https://github.com/madsmtm/objc2,MIT,The objc2-foundation Authors +objc2-io-surface,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-io-surface Authors +objc2-quartz-core,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-quartz-core Authors +objc2-ui-kit,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-ui-kit Authors +objc2-user-notifications,https://github.com/madsmtm/objc2,Zlib OR Apache-2.0 OR MIT,The objc2-user-notifications Authors once_cell,https://github.com/matklad/once_cell,MIT OR Apache-2.0,Aleksey Kladov +oorandom,https://hg.sr.ht/~icefox/oorandom,MIT,Simon Heath openssl-probe,https://github.com/alexcrichton/openssl-probe,MIT OR Apache-2.0,Alex Crichton +os_info,https://github.com/stanislav-tkach/os_info,MIT,"Jan Schulte , Stanislav Tkach " +page_size,https://github.com/Elzair/page_size_rs,MIT OR Apache-2.0,Philip Woods paste,https://github.com/dtolnay/paste,MIT OR Apache-2.0,David Tolnay +percent-encoding,https://github.com/servo/rust-url,MIT OR Apache-2.0,The rust-url developers pin-project,https://github.com/taiki-e/pin-project,Apache-2.0 OR MIT,The pin-project Authors pin-project-internal,https://github.com/taiki-e/pin-project,Apache-2.0 OR MIT,The pin-project-internal Authors pin-project-lite,https://github.com/taiki-e/pin-project-lite,Apache-2.0 OR MIT,The pin-project-lite Authors -pin-utils,https://github.com/rust-lang-nursery/pin-utils,MIT OR Apache-2.0,Josef Brandl +portable-atomic,https://github.com/taiki-e/portable-atomic,Apache-2.0 OR MIT,The portable-atomic Authors +portable-atomic-util,https://github.com/taiki-e/portable-atomic-util,Apache-2.0 OR MIT,The portable-atomic-util Authors +potential_utf,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +powerfmt,https://github.com/jhpratt/powerfmt,MIT OR Apache-2.0,Jacob Pratt +ppv-lite86,https://github.com/cryptocorrosion/cryptocorrosion,MIT OR Apache-2.0,The CryptoCorrosion Contributors +prettyplease,https://github.com/dtolnay/prettyplease,MIT OR Apache-2.0,David Tolnay proc-macro2,https://github.com/dtolnay/proc-macro2,MIT OR Apache-2.0,"David Tolnay , Alex Crichton " -prost,https://github.com/tokio-rs/prost,Apache-2.0,"Dan Burkert , Lucio Franco " -prost-derive,https://github.com/tokio-rs/prost,Apache-2.0,"Dan Burkert , Lucio Franco , Tokio Contributors " +prost,https://github.com/tokio-rs/prost,Apache-2.0,"Dan Burkert , Lucio Franco , Casper Meijn , Tokio Contributors " +prost-derive,https://github.com/tokio-rs/prost,Apache-2.0,"Dan Burkert , Lucio Franco , Casper Meijn , Tokio Contributors " quote,https://github.com/dtolnay/quote,MIT OR Apache-2.0,David Tolnay +r-efi,https://github.com/r-efi/r-efi,MIT OR Apache-2.0 OR LGPL-2.1-or-later,The r-efi Authors +rand,https://github.com/rust-random/rand,MIT OR Apache-2.0,"The Rand Project Developers, The Rust Project Developers" +rand_chacha,https://github.com/rust-random/rand,MIT OR Apache-2.0,"The Rand Project Developers, The Rust Project Developers, The CryptoCorrosion Contributors" +rand_core,https://github.com/rust-random/rand,MIT OR Apache-2.0,"The Rand Project Developers, The Rust Project Developers" +ref-cast,https://github.com/dtolnay/ref-cast,MIT OR Apache-2.0,David Tolnay +ref-cast-impl,https://github.com/dtolnay/ref-cast,MIT OR Apache-2.0,David Tolnay regex,https://github.com/rust-lang/regex,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " -regex-automata,https://github.com/rust-lang/regex/tree/master/regex-automata,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " -regex-syntax,https://github.com/rust-lang/regex/tree/master/regex-syntax,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " -ring,https://github.com/briansmith/ring,OpenSSL license,Brian Smith -rmp,https://github.com/3Hren/msgpack-rust,MIT,Evgeny Safronov +regex-automata,https://github.com/rust-lang/regex,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " +regex-syntax,https://github.com/rust-lang/regex,MIT OR Apache-2.0,"The Rust Project Developers, Andrew Gallant " +ring,https://github.com/briansmith/ring,Apache-2.0 AND ISC,The ring Authors +rmp,https://github.com/3Hren/msgpack-rust,MIT,"Evgeny Safronov , Kornel " rmp-serde,https://github.com/3Hren/msgpack-rust,MIT,Evgeny Safronov -rustc-demangle,https://github.com/alexcrichton/rustc-demangle,MIT OR Apache-2.0,Alex Crichton +rmpv,https://github.com/3Hren/msgpack-rust,MIT,Evgeny Safronov +rustc-demangle,https://github.com/rust-lang/rustc-demangle,MIT OR Apache-2.0,Alex Crichton +rustc-hash,https://github.com/rust-lang/rustc-hash,Apache-2.0 OR MIT,The Rust Project Developers +rustix,https://github.com/bytecodealliance/rustix,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,"Dan Gohman , Jakub Konka " rustls,https://github.com/rustls/rustls,Apache-2.0 OR ISC OR MIT,The rustls Authors -rustls-native-certs,https://github.com/ctz/rustls-native-certs,Apache-2.0 OR ISC OR MIT,The rustls-native-certs Authors -rustls-pemfile,https://github.com/rustls/pemfile,Apache-2.0 OR ISC OR MIT,The rustls-pemfile Authors +rustls-native-certs,https://github.com/rustls/rustls-native-certs,Apache-2.0 OR ISC OR MIT,The rustls-native-certs Authors +rustls-pki-types,https://github.com/rustls/pki-types,MIT OR Apache-2.0,The rustls-pki-types Authors +rustls-platform-verifier,https://github.com/rustls/rustls-platform-verifier,MIT OR Apache-2.0,The rustls-platform-verifier Authors +rustls-platform-verifier-android,https://github.com/rustls/rustls-platform-verifier,MIT OR Apache-2.0,The rustls-platform-verifier-android Authors +rustls-webpki,https://github.com/rustls/webpki,ISC,The rustls-webpki Authors +rustversion,https://github.com/dtolnay/rustversion,MIT OR Apache-2.0,David Tolnay ryu,https://github.com/dtolnay/ryu,Apache-2.0 OR BSL-1.0,David Tolnay +same-file,https://github.com/BurntSushi/same-file,Unlicense OR MIT,Andrew Gallant schannel,https://github.com/steffengy/schannel-rs,MIT,"Steven Fackler , Steffen Butzer " -sct,https://github.com/rustls/sct.rs,Apache-2.0 OR ISC OR MIT,Joseph Birr-Pixton +schemars,https://github.com/GREsau/schemars,MIT,Graham Esau +schemars_derive,https://github.com/GREsau/schemars,MIT,Graham Esau security-framework,https://github.com/kornelski/rust-security-framework,MIT OR Apache-2.0,"Steven Fackler , Kornel " +security-framework-sys,https://github.com/kornelski/rust-security-framework,MIT OR Apache-2.0,"Steven Fackler , Kornel " semver,https://github.com/dtolnay/semver,MIT OR Apache-2.0,David Tolnay -send_wrapper,https://github.com/thk1/send_wrapper,MIT OR Apache-2.0,Thomas Keh serde,https://github.com/serde-rs/serde,MIT OR Apache-2.0,"Erick Tryzelaar , David Tolnay " +serde-transcode,https://github.com/sfackler/serde-transcode,MIT OR Apache-2.0,Steven Fackler +serde-wasm-bindgen,https://github.com/cloudflare/serde-wasm-bindgen,MIT,Ingvar Stepanyan serde_bytes,https://github.com/serde-rs/bytes,MIT OR Apache-2.0,David Tolnay +serde_core,https://github.com/serde-rs/serde,MIT OR Apache-2.0,"Erick Tryzelaar , David Tolnay " +serde_derive,https://github.com/serde-rs/serde,MIT OR Apache-2.0,"Erick Tryzelaar , David Tolnay " +serde_derive_internals,https://github.com/serde-rs/serde,MIT OR Apache-2.0,"Erick Tryzelaar , David Tolnay " serde_json,https://github.com/serde-rs/json,MIT OR Apache-2.0,"Erick Tryzelaar , David Tolnay " +serde_with,https://github.com/jonasbb/serde_with,MIT OR Apache-2.0,"Jonas Bushart, Marcin Kaźmierczak" +serde_with_macros,https://github.com/jonasbb/serde_with,MIT OR Apache-2.0,Jonas Bushart +serde_yaml,https://github.com/dtolnay/serde-yaml,MIT OR Apache-2.0,David Tolnay +sha2,https://github.com/RustCrypto/hashes,MIT OR Apache-2.0,RustCrypto Developers +shlex,https://github.com/comex/rust-shlex,MIT OR Apache-2.0,"comex , Fenhl , Adrian Taylor , Alex Touchet , Daniel Parks , Garrett Berg " +simd-adler32,https://github.com/mcountryman/simd-adler32,MIT,Marvin Countryman slab,https://github.com/tokio-rs/slab,MIT,Carl Lerche smallvec,https://github.com/servo/rust-smallvec,MIT OR Apache-2.0,The Servo Project Developers socket2,https://github.com/rust-lang/socket2,MIT OR Apache-2.0,"Alex Crichton , Thomas de Zeeuw " -spin,https://github.com/mvdnes/spin-rs,MIT,"Mathijs van de Nes , John Ericson " -spin,https://github.com/mvdnes/spin-rs,MIT,"Mathijs van de Nes , John Ericson , Joshua Barretto " +stable_deref_trait,https://github.com/storyyeller/stable_deref_trait,MIT OR Apache-2.0,Robert Grosse +static_assertions,https://github.com/nvzqz/static-assertions-rs,MIT OR Apache-2.0,Nikolai Vazquez +strsim,https://github.com/rapidfuzz/strsim-rs,MIT,"Danny Guo , maxbachmann " +strum,https://github.com/Peternator7/strum,MIT,Peter Glotfelty +strum_macros,https://github.com/Peternator7/strum,MIT,Peter Glotfelty +subtle,https://github.com/dalek-cryptography/subtle,BSD-3-Clause,"Isis Lovecruft , Henry de Valence " +symbolic-common,https://github.com/getsentry/symbolic,MIT,"Armin Ronacher , Jan Michael Auer " +symbolic-demangle,https://github.com/getsentry/symbolic,MIT,"Armin Ronacher , Jan Michael Auer " syn,https://github.com/dtolnay/syn,MIT OR Apache-2.0,David Tolnay -syn-mid,https://github.com/taiki-e/syn-mid,Apache-2.0 OR MIT,The syn-mid Authors +synstructure,https://github.com/mystor/synstructure,MIT,Nika Layzell +sys-info,https://github.com/FillZpp/sys-info-rs,MIT,Siyu Wang +tempfile,https://github.com/Stebalien/tempfile,MIT OR Apache-2.0,"Steven Allen , The Rust Project Developers, Ashley Mannix , Jason White " +thin-vec,https://github.com/mozilla/thin-vec,MIT OR Apache-2.0,Aria Beingessner +thiserror,https://github.com/dtolnay/thiserror,MIT OR Apache-2.0,David Tolnay +thiserror-impl,https://github.com/dtolnay/thiserror,MIT OR Apache-2.0,David Tolnay +time,https://github.com/time-rs/time,MIT OR Apache-2.0,"Jacob Pratt , Time contributors" +time-core,https://github.com/time-rs/time,MIT OR Apache-2.0,"Jacob Pratt , Time contributors" +time-macros,https://github.com/time-rs/time,MIT OR Apache-2.0,"Jacob Pratt , Time contributors" +tinystr,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +tinyvec,https://github.com/Lokathor/tinyvec,Zlib OR Apache-2.0 OR MIT,Lokathor +tinyvec_macros,https://github.com/Soveu/tinyvec_macros,MIT OR Apache-2.0 OR Zlib,Soveu tokio,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors -tokio-rustls,https://github.com/tokio-rs/tls,MIT OR Apache-2.0,quininer kel +tokio-macros,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors +tokio-rustls,https://github.com/rustls/tokio-rustls,MIT OR Apache-2.0,The tokio-rustls Authors +tokio-util,https://github.com/tokio-rs/tokio,MIT,Tokio Contributors tower-service,https://github.com/tower-rs/tower,MIT,Tower Maintainers tracing,https://github.com/tokio-rs/tracing,MIT,"Eliza Weisman , Tokio Contributors " tracing-core,https://github.com/tokio-rs/tracing,MIT,Tokio Contributors try-lock,https://github.com/seanmonstar/try-lock,MIT,Sean McArthur -unicode-ident,https://github.com/dtolnay/unicode-ident,(MIT OR Apache-2.0) AND Unicode-DFS-2016,David Tolnay +typenum,https://github.com/paholg/typenum,MIT OR Apache-2.0,"Paho Lurie-Gregg , Andre Bogus " +unicode-ident,https://github.com/dtolnay/unicode-ident,(MIT OR Apache-2.0) AND Unicode-3.0,David Tolnay +unicode-segmentation,https://github.com/unicode-rs/unicode-segmentation,MIT OR Apache-2.0,"kwantam , Manish Goregaokar " +unicode-xid,https://github.com/unicode-rs/unicode-xid,MIT OR Apache-2.0,"erick.tryzelaar , kwantam , Manish Goregaokar " +unsafe-libyaml,https://github.com/dtolnay/unsafe-libyaml,MIT,David Tolnay untrusted,https://github.com/briansmith/untrusted,ISC,Brian Smith +url,https://github.com/servo/rust-url,MIT OR Apache-2.0,The rust-url developers +utf8_iter,https://github.com/hsivonen/utf8_iter,Apache-2.0 OR MIT,Henri Sivonen +uuid,https://github.com/uuid-rs/uuid,Apache-2.0 OR MIT,"Ashley Mannix, Dylan DPC, Hunar Roop Kahlon" want,https://github.com/seanmonstar/want,MIT,Sean McArthur wasi,https://github.com/bytecodealliance/wasi,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,The Cranelift Project Developers -wasm-bindgen,https://github.com/rustwasm/wasm-bindgen,MIT OR Apache-2.0,The wasm-bindgen Developers -wasm-bindgen-backend,https://github.com/rustwasm/wasm-bindgen/tree/master/crates/backend,MIT OR Apache-2.0,The wasm-bindgen Developers -wasm-bindgen-macro,https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro,MIT OR Apache-2.0,The wasm-bindgen Developers -wasm-bindgen-macro-support,https://github.com/rustwasm/wasm-bindgen/tree/master/crates/macro-support,MIT OR Apache-2.0,The wasm-bindgen Developers -wasm-bindgen-shared,https://github.com/rustwasm/wasm-bindgen/tree/master/crates/shared,MIT OR Apache-2.0,The wasm-bindgen Developers -web-sys,https://github.com/rustwasm/wasm-bindgen/tree/master/crates/web-sys,MIT OR Apache-2.0,The wasm-bindgen Developers -webpki,https://github.com/briansmith/webpki,ISC-style,Brian Smith +wasip2,https://github.com/bytecodealliance/wasi-rs,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,The wasip2 Authors +wasip3,https://github.com/bytecodealliance/wasi-rs,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,The wasip3 Authors +wasm-bindgen,https://github.com/wasm-bindgen/wasm-bindgen,MIT OR Apache-2.0,The wasm-bindgen Developers +wasm-bindgen-futures,https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/futures,MIT OR Apache-2.0,The wasm-bindgen Developers +wasm-bindgen-macro,https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/macro,MIT OR Apache-2.0,The wasm-bindgen Developers +wasm-bindgen-macro-support,https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/macro-support,MIT OR Apache-2.0,The wasm-bindgen Developers +wasm-bindgen-shared,https://github.com/wasm-bindgen/wasm-bindgen/tree/master/crates/shared,MIT OR Apache-2.0,The wasm-bindgen Developers +wasm-bindgen-test-macro,https://github.com/wasm-bindgen/wasm-bindgen,MIT OR Apache-2.0,The wasm-bindgen Developers +wasm-bindgen-test-shared,https://github.com/rustwasm/wasm-bindgen/tree/master/crates/test-shared,MIT OR Apache-2.0,The wasm-bindgen Developers +wasm-encoder,https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-encoder,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Nick Fitzgerald +wasm-metadata,https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-metadata,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,The wasm-metadata Authors +wasmparser,https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasmparser,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Yury Delendik +web-time,https://github.com/daxpedda/web-time,MIT OR Apache-2.0,The web-time Authors +webpki-root-certs,https://github.com/rustls/webpki-roots,CDLA-Permissive-2.0,The webpki-root-certs Authors winapi,https://github.com/retep998/winapi-rs,MIT OR Apache-2.0,Peter Atashian +winapi-i686-pc-windows-gnu,https://github.com/retep998/winapi-rs,MIT OR Apache-2.0,Peter Atashian +winapi-util,https://github.com/BurntSushi/winapi-util,Unlicense OR MIT,Andrew Gallant +winapi-x86_64-pc-windows-gnu,https://github.com/retep998/winapi-rs,MIT OR Apache-2.0,Peter Atashian +windows,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-core,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-core,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-core Authors +windows-implement,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-implement,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-implement Authors +windows-interface,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-interface Authors +windows-link,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-link,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-link Authors +windows-result,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-result,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-result Authors +windows-strings,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-strings,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-strings Authors windows-sys,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-sys,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-sys Authors windows-targets,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows-targets,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows-targets Authors windows_aarch64_gnullvm,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows_aarch64_gnullvm,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows_aarch64_gnullvm Authors windows_aarch64_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows_aarch64_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows_aarch64_msvc Authors windows_i686_gnu,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows_i686_gnu,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows_i686_gnu Authors +windows_i686_gnullvm,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows_i686_gnullvm,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows_i686_gnullvm Authors windows_i686_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows_i686_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows_i686_msvc Authors windows_x86_64_gnu,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows_x86_64_gnu,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows_x86_64_gnu Authors windows_x86_64_gnullvm,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows_x86_64_gnullvm,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows_x86_64_gnullvm Authors windows_x86_64_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,Microsoft +windows_x86_64_msvc,https://github.com/microsoft/windows-rs,MIT OR Apache-2.0,The windows_x86_64_msvc Authors +winver,https://github.com/rhysd/winver,MIT,rhysd +wit-bindgen,https://github.com/bytecodealliance/wit-bindgen,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Alex Crichton +wit-bindgen-core,https://github.com/bytecodealliance/wit-bindgen,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Alex Crichton +wit-bindgen-rust,https://github.com/bytecodealliance/wit-bindgen,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Alex Crichton +wit-bindgen-rust-macro,https://github.com/bytecodealliance/wit-bindgen,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Alex Crichton +wit-component,https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wit-component,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Peter Huene +wit-parser,https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wit-parser,Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT,Alex Crichton +writeable,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +yoke,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaokar +yoke-derive,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaokar +zerocopy,https://github.com/google/zerocopy,BSD-2-Clause OR Apache-2.0 OR MIT,"Joshua Liebow-Feeser , Jack Wrenn " +zerocopy-derive,https://github.com/google/zerocopy,BSD-2-Clause OR Apache-2.0 OR MIT,"Joshua Liebow-Feeser , Jack Wrenn " +zerofrom,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +zerofrom-derive,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaokar +zeroize,https://github.com/RustCrypto/utils,Apache-2.0 OR MIT,The RustCrypto Project Developers +zerotrie,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +zerovec,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers +zerovec-derive,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaokar +zmij,https://github.com/dtolnay/zmij,MIT,David Tolnay +zstd,https://github.com/gyscos/zstd-rs,MIT,Alexandre Bury +zstd-safe,https://github.com/gyscos/zstd-rs,MIT OR Apache-2.0,Alexandre Bury +zstd-sys,https://github.com/gyscos/zstd-rs,MIT OR Apache-2.0,Alexandre Bury diff --git a/README.md b/README.md index 69caebcd..6dd4dd8c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,36 @@ -# libdatadog-nodejs +# libdatadog Node.js bindings -Node.js bindings for [libdatadog](https://github.com/DataDog/libdatadog). +Node.js bindings for [libdatadog](https://github.com/DataDog/libdatadog), +published as two packages with different availability guarantees. -## Installing +> **Internal packages:** These packages are published solely for use by +> [`dd-trace`](https://github.com/DataDog/dd-trace-js). They are not supported +> as standalone APIs and must not be used directly by applications or other +> libraries. Their APIs, behavior, and distribution may change without notice. -This project is currently meant to be used only by [dd-trace-js](https://github.com/DataDog/dd-trace-js) -and installing it directly is not supported at the moment. +- `@datadog/libdatadog` provides functionality required in every environment + through inlined WASM. +- `@datadog/libdatadog-extras` provides additional functionality that is not + available or needed everywhere through native prebuilds and standalone WASM + modules. + +## `@datadog/libdatadog` + +The package is maintained under [`packages/libdatadog`](packages/libdatadog). +Zstandard compression, DDSketch, and the agentless data pipeline use a +wasm-bindgen backend whose WebAssembly bytes are embedded in JavaScript. No raw +`.wasm` asset or native extension is published. + +Remote configuration is available from `@datadog/libdatadog/remote-config`. +It uses a dedicated wasm-bindgen artifact that loads only with this entry point. + +See the [package README](packages/libdatadog/README.md) for implementation and +packaging details. + +## `@datadog/libdatadog-extras` + +The root package contains optional capabilities such as crash tracking, +process discovery, the legacy pipeline, and library configuration. +Platform-native extensions are combined under platform-specific directories +in `prebuilds`. Standalone WASM modules are stored under capability-specific +directories in the same location. diff --git a/crates/capabilities/Cargo.toml b/crates/capabilities/Cargo.toml index f468e7d5..444ec123 100644 --- a/crates/capabilities/Cargo.toml +++ b/crates/capabilities/Cargo.toml @@ -15,9 +15,7 @@ http = "1" bytes = "1.4" futures-core = "0.3" anyhow = "1" -# TODO: Replace this temporary libdatadog PR rev with the official release/tag -# that contains DataDog/libdatadog#2235, then regenerate Cargo.lock. -libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "6356aee4c69b51f27e7e82e43b1797f60b74905a" } +libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75" } [dev-dependencies] wasm-bindgen-test = "0.3" diff --git a/crates/capabilities/src/env.rs b/crates/capabilities/src/env.rs new file mode 100644 index 00000000..716d4b4a --- /dev/null +++ b/crates/capabilities/src/env.rs @@ -0,0 +1,28 @@ +// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +//! Wasm implementation of [`EnvCapability`] backed by Node.js `process.env`. + +use wasm_bindgen::prelude::*; + +use libdd_capabilities::env::{EnvCapability, EnvError}; + +#[wasm_bindgen(module = "/src/env_transport.js")] +extern "C" { + #[wasm_bindgen(js_name = "get")] + fn js_env_get(name: &str) -> JsValue; +} + +#[derive(Debug, Clone)] +pub struct WasmEnvCapability; + +impl EnvCapability for WasmEnvCapability { + fn new() -> Self { + Self + } + + fn get(&self, name: &str) -> Result, EnvError> { + // Node coerces every process.env value to a string, so NotUnicode is unreachable here. + Ok(js_env_get(name).as_string()) + } +} diff --git a/crates/capabilities/src/env_transport.js b/crates/capabilities/src/env_transport.js new file mode 100644 index 00000000..92d6504b --- /dev/null +++ b/crates/capabilities/src/env_transport.js @@ -0,0 +1,7 @@ +'use strict' + +const { env } = process + +module.exports.get = (name) => { + return env[name] +} diff --git a/crates/capabilities/src/file.rs b/crates/capabilities/src/file.rs new file mode 100644 index 00000000..fe8eb4e6 --- /dev/null +++ b/crates/capabilities/src/file.rs @@ -0,0 +1,156 @@ +// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +//! Wasm implementation of [`FileCapability`] backed by Node.js `fs`. +//! +//! The JS transport is imported via `wasm_bindgen(module = ...)` from +//! `filesystem.js`, which ships alongside the wasm output. + +use std::future::Future; + +use bytes::Bytes; +use js_sys::{self, Reflect, Uint8Array}; +use wasm_bindgen::prelude::*; +use wasm_bindgen_futures::JsFuture; + +use libdd_capabilities::file::{FileCapability, FileError, FileMetadata}; +use libdd_capabilities::maybe_send::MaybeSend; + +#[wasm_bindgen(module = "/src/filesystem.js")] +extern "C" { + #[wasm_bindgen(js_name = "readFile", catch)] + fn js_read_file(path: &str) -> Result; + + #[wasm_bindgen(js_name = "writeFile", catch)] + fn js_write_file(path: &str, data: &[u8]) -> Result; + + #[wasm_bindgen(js_name = "metadata", catch)] + fn js_metadata(path: &str) -> Result; + + #[wasm_bindgen(js_name = "exists", catch)] + fn js_exists(path: &str) -> Result; +} + +#[derive(Debug, Clone)] +pub struct WasmFileCapability; + +impl FileCapability for WasmFileCapability { + fn new() -> Self { + Self + } + + #[allow(clippy::manual_async_fn)] + fn read(&self, path: &str) -> impl Future> + MaybeSend { + let path = path.to_owned(); + async move { + let promise = + js_read_file(&path).map_err(|e| map_js_error(&e, &path))?; + let value = JsFuture::from(promise) + .await + .map_err(|e| map_js_error(&e, &path))?; + let array = Uint8Array::unchecked_from_js(value); + Ok(Bytes::from(array.to_vec())) + } + } + + #[allow(clippy::manual_async_fn)] + fn write( + &self, + path: &str, + contents: Bytes, + ) -> impl Future> + MaybeSend { + let path = path.to_owned(); + async move { + let promise = js_write_file(&path, &contents) + .map_err(|e| map_js_error(&e, &path))?; + JsFuture::from(promise) + .await + .map_err(|e| map_js_error(&e, &path))?; + Ok(()) + } + } + + #[allow(clippy::manual_async_fn)] + fn metadata( + &self, + path: &str, + ) -> impl Future> + MaybeSend { + let path = path.to_owned(); + async move { + let promise = + js_metadata(&path).map_err(|e| map_js_error(&e, &path))?; + let value = JsFuture::from(promise) + .await + .map_err(|e| map_js_error(&e, &path))?; + parse_metadata(&value, &path) + } + } + + #[allow(clippy::manual_async_fn)] + fn exists(&self, path: &str) -> impl Future> + MaybeSend { + let path = path.to_owned(); + async move { + let promise = js_exists(&path).map_err(|e| map_js_error(&e, &path))?; + let value = JsFuture::from(promise) + .await + .map_err(|e| map_js_error(&e, &path))?; + value + .as_bool() + .ok_or_else(|| FileError::Io(anyhow::anyhow!("exists({path}) did not return a boolean"))) + } + } +} + +fn map_js_error(err: &JsValue, path: &str) -> FileError { + let code = Reflect::get(err, &JsValue::from_str("code")) + .ok() + .and_then(|v| v.as_string()); + match code.as_deref() { + Some("ENOENT") => FileError::NotFound(path.to_owned()), + Some("EACCES") | Some("EPERM") => FileError::PermissionDenied(path.to_owned()), + _ => { + let message = Reflect::get(err, &JsValue::from_str("message")) + .ok() + .and_then(|v| v.as_string()) + .unwrap_or_else(|| format!("{err:?}")); + FileError::Io(anyhow::anyhow!("{message} (path: {path})")) + } + } +} + +fn parse_metadata(value: &JsValue, path: &str) -> Result { + let size = read_bigint_u64(value, "size", path)?; + // Node populates `stat().ino` on every platform, so `inode` is always Some. + let inode = Some(read_bigint_u64(value, "inode", path)?); + let is_file = read_bool(value, "is_file", path)?; + let is_dir = read_bool(value, "is_dir", path)?; + Ok(FileMetadata { + size, + inode, + is_file, + is_dir, + }) +} + +fn read_bigint_u64(value: &JsValue, key: &str, path: &str) -> Result { + let v = Reflect::get(value, &JsValue::from_str(key)) + .map_err(|_| FileError::Io(anyhow::anyhow!("metadata({path}) could not read field `{key}`")))?; + if v.is_undefined() || v.is_null() { + return Err(FileError::Io(anyhow::anyhow!("metadata({path}) missing field `{key}`"))); + } + let bigint = js_sys::BigInt::try_from(v) + .map_err(|_| FileError::Io(anyhow::anyhow!("metadata({path}) field `{key}` is not a BigInt")))?; + u64::try_from(bigint) + .map_err(|_| FileError::Io(anyhow::anyhow!("metadata({path}) field `{key}` overflows u64"))) +} + +fn read_bool(value: &JsValue, key: &str, path: &str) -> Result { + Reflect::get(value, &JsValue::from_str(key)) + .ok() + .and_then(|v| v.as_bool()) + .ok_or_else(|| { + FileError::Io(anyhow::anyhow!( + "metadata({path}) is missing boolean field `{key}`" + )) + }) +} diff --git a/crates/capabilities/src/filesystem.js b/crates/capabilities/src/filesystem.js new file mode 100644 index 00000000..014049a0 --- /dev/null +++ b/crates/capabilities/src/filesystem.js @@ -0,0 +1,38 @@ +// Lazy `require('node:fs')` — see http_transport.js. The cached accessor +// avoids paying the module-resolution cost on every call. + +'use strict' + +let _fs +function fs () { + return _fs ??= require('node:fs') +} + +module.exports.readFile = function (path) { + return fs().promises.readFile(path) +} + +module.exports.writeFile = function (path, data) { + // Copy off the wasm-memory view before the async write; a memory grow would + // otherwise detach the underlying ArrayBuffer mid-write. + return fs().promises.writeFile(path, Buffer.from(data)) +} + +module.exports.metadata = function (path) { + return fs().promises.stat(path, { bigint: true }).then(s => ({ + size: s.size, + inode: s.ino, + is_file: s.isFile(), + is_dir: s.isDirectory(), + })) +} + +module.exports.exists = function (path) { + return fs().promises.stat(path).then( + () => true, + (error) => { + if (error && error.code === 'ENOENT') return false + throw error + }, + ) +} diff --git a/crates/capabilities/src/http.rs b/crates/capabilities/src/http.rs index 4248cb30..e9c2b8ca 100644 --- a/crates/capabilities/src/http.rs +++ b/crates/capabilities/src/http.rs @@ -32,6 +32,7 @@ extern "C" { port: u16, is_https: bool, socket_path: &str, + connection_pooling: bool, head_ptr: *const u8, head_len: u32, body_ptr: *const u8, @@ -52,11 +53,21 @@ extern "C" { /// [`crate::WasmCapabilities`] alongside the sleep and log-output capabilities /// that `TraceExporter` requires. #[derive(Debug, Clone)] -pub struct WasmHttpClient; +pub struct WasmHttpClient { + connection_pooling: bool, +} impl HttpClientCapability for WasmHttpClient { fn new_client() -> Self { - Self + Self { + connection_pooling: true, + } + } + + fn new_without_connection_pooling() -> Self { + Self { + connection_pooling: false, + } } #[allow(clippy::manual_async_fn)] @@ -101,6 +112,7 @@ impl HttpClientCapability for WasmHttpClient { port, is_https, &socket_path, + self.connection_pooling, head.as_ptr(), head.len() as u32, body.as_ptr(), diff --git a/crates/capabilities/src/http_transport.js b/crates/capabilities/src/http_transport.js index 05080410..0fd60257 100644 --- a/crates/capabilities/src/http_transport.js +++ b/crates/capabilities/src/http_transport.js @@ -171,7 +171,7 @@ module.exports._resetEntityHeadersCache = () => { cachedEntityHeaders = undefined } -module.exports.httpRequest = function (host, port, isHttps, socketPath, head_ptr, head_len, body_ptr, body_len, wasm_memory) { +module.exports.httpRequest = function (host, port, isHttps, socketPath, connectionPooling, head_ptr, head_len, body_ptr, body_len, wasm_memory) { // A non-empty socketPath routes over a Unix domain socket (or Windows named // pipe) instead of TCP. Sockets are always plaintext HTTP/1.1, so https is // ignored in that mode. @@ -206,9 +206,12 @@ module.exports.httpRequest = function (host, port, isHttps, socketPath, head_ptr // request options so the connection uses the correct method/path/headers // on both Node and Bun (host/port or socketPath drive the connection). const { method, path, headers } = parseRequestHead(applyEntityHeaders(headView)) + // `agent: false` gives this request its own short-lived agent rather than the global + // keep-alive one, which is what a caller asking for no connection pooling wants. const requestOptions = useSocket ? { socketPath, method, path, headers } : { host, port, method, path, headers } + if (!connectionPooling) requestOptions.agent = false const req = transport.request(requestOptions, (res) => { const chunks = [] res.on('data', chunk => chunks.push(chunk)) diff --git a/crates/capabilities/src/lib.rs b/crates/capabilities/src/lib.rs index f7cb4b01..ca0c8285 100644 --- a/crates/capabilities/src/lib.rs +++ b/crates/capabilities/src/lib.rs @@ -4,35 +4,44 @@ //! Wasm capability implementations for libdatadog-nodejs. //! //! [`WasmCapabilities`] is the bundle struct that implements every capability -//! trait `TraceExporter` requires (HTTP, sleep, log output) using wasm_bindgen -//! and JS transports. The wasm binding crate pins this type as the capability -//! generic for libdatadog's `TraceExporter`, mirroring libdatadog's native -//! `NativeCapabilities`. +//! trait `TraceExporter` requires using wasm_bindgen and JS transports. The +//! wasm binding crate pins this type as the capability generic for libdatadog's +//! `TraceExporter`, mirroring libdatadog's native `NativeCapabilities`. use std::future::Future; use std::time::Duration; +use libdd_capabilities::env::{EnvCapability, EnvError}; +use libdd_capabilities::file::{FileCapability, FileError, FileMetadata}; use libdd_capabilities::http::HttpError; -use libdd_capabilities::{HttpClientCapability, LogWriterCapability, MaybeSend, SleepCapability}; +// Re-exported so consumers can name the traits without depending on `libdd-capabilities` directly. +pub use libdd_capabilities::{HttpClientCapability, LogWriterCapability, MaybeSend, SleepCapability}; +pub mod env; +pub mod file; pub mod http; pub mod sleep; +pub use env::WasmEnvCapability; +pub use file::WasmFileCapability; pub use http::WasmHttpClient; pub use sleep::WasmSleepCapability; /// Bundle of wasm platform capabilities for libdatadog's `TraceExporter`. /// -/// Mirrors libdatadog's native `NativeCapabilities`: delegates HTTP to -/// [`WasmHttpClient`] and sleep to [`WasmSleepCapability`]. Log output is a -/// no-op (see the [`LogWriterCapability`] impl). Per-function bounds stay +/// Mirrors libdatadog's native `NativeCapabilities`. Per-function bounds stay /// minimal in libdatadog (e.g. stats-only code uses [`WasmHttpClient`] /// directly), so this bundle is only needed where the full `TraceExporter` /// capability set is. #[derive(Clone, Debug)] pub struct WasmCapabilities { + /// Outbound HTTP requests routed through the JS fetch/socket transport. http: WasmHttpClient, + /// Async sleep backed by `setTimeout` via wasm-bindgen. sleep: WasmSleepCapability, + /// Filesystem access delegated to the Node.js `fs` transport. + file: WasmFileCapability, + env: WasmEnvCapability, } impl Default for WasmCapabilities { @@ -46,15 +55,21 @@ impl WasmCapabilities { Self { http: WasmHttpClient::new_client(), sleep: WasmSleepCapability, + file: WasmFileCapability, + env: WasmEnvCapability, } } } impl HttpClientCapability for WasmCapabilities { fn new_client() -> Self { + Self::new() + } + + fn new_without_connection_pooling() -> Self { Self { - http: WasmHttpClient::new_client(), - sleep: WasmSleepCapability, + http: WasmHttpClient::new_without_connection_pooling(), + ..Self::new() } } @@ -68,10 +83,7 @@ impl HttpClientCapability for WasmCapabilities { impl SleepCapability for WasmCapabilities { fn new() -> Self { - Self { - http: WasmHttpClient::new_client(), - sleep: WasmSleepCapability, - } + Self::new() } fn sleep(&self, duration: Duration) -> impl Future + MaybeSend { @@ -89,3 +101,45 @@ impl LogWriterCapability for WasmCapabilities { Ok(()) } } + +impl FileCapability for WasmCapabilities { + fn new() -> Self { + Self::new() + } + + fn read( + &self, + path: &str, + ) -> impl Future> + MaybeSend { + self.file.read(path) + } + + fn write( + &self, + path: &str, + contents: ::bytes::Bytes, + ) -> impl Future> + MaybeSend { + self.file.write(path, contents) + } + + fn metadata( + &self, + path: &str, + ) -> impl Future> + MaybeSend { + self.file.metadata(path) + } + + fn exists(&self, path: &str) -> impl Future> + MaybeSend { + self.file.exists(path) + } +} + +impl EnvCapability for WasmCapabilities { + fn new() -> Self { + Self::new() + } + + fn get(&self, name: &str) -> Result, EnvError> { + self.env.get(name) + } +} diff --git a/crates/crashtracker/Cargo.toml b/crates/crashtracker/Cargo.toml index f349c08a..8bce6975 100644 --- a/crates/crashtracker/Cargo.toml +++ b/crates/crashtracker/Cargo.toml @@ -14,7 +14,7 @@ path = "src/bin/receiver.rs" [dependencies] anyhow = "1" -libdd-crashtracker = { git = "https://github.com/DataDog/libdatadog.git", tag = "v35.0.0" } +libdd-crashtracker = { git = "https://github.com/DataDog/libdatadog.git", tag = "v37.0.0" } napi = { version = "2", features = ["serde-json"] } napi-derive = { version = "2", default-features = false } rustls = { version = "*", default-features = false, features = ["aws-lc-rs"] } diff --git a/crates/datadog-js-zstd/Cargo.toml b/crates/datadog-js-zstd/Cargo.toml deleted file mode 100644 index 6a4a626d..00000000 --- a/crates/datadog-js-zstd/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "datadog-js-zstd" -version = "0.1.0" -edition = "2018" - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -wasm-bindgen = "0.2.100" -zstd = "0.13.3" -js-sys = "0.3.77" - -[package.metadata.wasm-pack.profile.release] -wasm-opt = ["-O", "--enable-bulk-memory"] - -[dev-dependencies] -wasm-bindgen-test = "0.3.50" diff --git a/crates/libdatadog-data-pipeline/Cargo.toml b/crates/libdatadog-data-pipeline/Cargo.toml new file mode 100644 index 00000000..1769b9df --- /dev/null +++ b/crates/libdatadog-data-pipeline/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "libdatadog-data-pipeline" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +thiserror = "1" + +[dependencies.libdd-capabilities] +git = "https://github.com/DataDog/libdatadog.git" +rev = "7327f3049c281090f7cce7830b9430206fba11cf" +default-features = false + +[dependencies.libdd-data-pipeline-core] +git = "https://github.com/DataDog/libdatadog.git" +rev = "7327f3049c281090f7cce7830b9430206fba11cf" +default-features = false + +[dependencies.libdd-trace-utils] +git = "https://github.com/DataDog/libdatadog.git" +rev = "7327f3049c281090f7cce7830b9430206fba11cf" +default-features = false + +[features] +default = [] +compression = ["libdd-data-pipeline-core/compression"] +regex-lite = ["libdd-data-pipeline-core/regex-lite"] diff --git a/crates/libdatadog-data-pipeline/src/lib.rs b/crates/libdatadog-data-pipeline/src/lib.rs new file mode 100644 index 00000000..c4dded4e --- /dev/null +++ b/crates/libdatadog-data-pipeline/src/lib.rs @@ -0,0 +1,32 @@ +// Copyright 2026-Present Datadog, Inc. https://www.datadoghq.com/ +// SPDX-License-Identifier: Apache-2.0 + +use libdd_capabilities::{HttpClientCapability, SleepCapability}; +use thiserror::Error; + +pub use libdd_data_pipeline_core::{ + AgentlessTraceConfig, TracerMetadata, DEFAULT_AGENTLESS_TIMEOUT, +}; + +#[derive(Debug, Error)] +pub enum SendAgentlessV04Error { + #[error("failed to decode v0.4 traces: {0}")] + Deserialization(libdd_trace_utils::msgpack_decoder::decode::error::DecodeError), + #[error(transparent)] + Agentless(#[from] libdd_data_pipeline_core::AgentlessError), +} + +pub async fn send_agentless_v04( + capabilities: &C, + payload: &[u8], + metadata: &TracerMetadata, + config: &AgentlessTraceConfig, +) -> Result<(), SendAgentlessV04Error> +where + C: HttpClientCapability + SleepCapability, +{ + let (traces, _) = libdd_trace_utils::msgpack_decoder::v04::from_slice(payload) + .map_err(SendAgentlessV04Error::Deserialization)?; + libdd_data_pipeline_core::send_agentless_traces(capabilities, traces, metadata, config).await?; + Ok(()) +} diff --git a/crates/libdatadog-wasm/Cargo.toml b/crates/libdatadog-wasm/Cargo.toml new file mode 100644 index 00000000..71273b52 --- /dev/null +++ b/crates/libdatadog-wasm/Cargo.toml @@ -0,0 +1,64 @@ +[package] +name = "libdatadog-wasm" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] +name = "libdatadog_wasm" + +[dependencies] +js-sys = "0.3" +wasm-bindgen = "0.2" +wasm-bindgen-futures = "0.4" +anyhow = "1" +bytes = "1" +futures = "0.3" +http = "1" +# The agentless v0.4 path does not compile or evaluate user-provided patterns. +# Use the smaller regex engine so the full engine and its Unicode tables are +# removed by the WASM linker. +libdd-ddsketch = "1.1.1" +# Keep this aligned with the pure-Rust WASM encoder used by libdatadog. +zrip = { version = "=0.6.0", default-features = false, features = ["alloc"] } + +[dependencies.libdd-capabilities] +git = "https://github.com/DataDog/libdatadog.git" +rev = "7327f3049c281090f7cce7830b9430206fba11cf" +default-features = false + +[dependencies.libdatadog-data-pipeline] +path = "../libdatadog-data-pipeline" +features = ["compression", "regex-lite"] + +[target.'cfg(target_arch = "wasm32")'.dependencies] +getrandom = { version = "0.2", features = ["js"] } + +[package.metadata.wasm-pack.profile.release] +# Do not use --all-features: Binaryen may then emit WebAssembly GC instructions, +# which are not supported by Node.js 18. Keep this list to features used by the +# Rust output and supported by every Node.js version that we test. +wasm-opt = [ + "-Oz", + "--enable-mutable-globals", + "--enable-nontrapping-float-to-int", + "--enable-bulk-memory", + "--enable-sign-ext", + "--enable-reference-types", + "--enable-multivalue", + "--converge", +] + +[package.metadata.wasm-pack.profile.profiling] +# Keep function names for crate attribution after wasm-opt runs in Linux CI. +wasm-opt = [ + "-Oz", + "--enable-mutable-globals", + "--enable-nontrapping-float-to-int", + "--enable-bulk-memory", + "--enable-sign-ext", + "--enable-reference-types", + "--enable-multivalue", + "--converge", + "-g", +] diff --git a/crates/libdatadog-wasm/src/data_pipeline/mod.rs b/crates/libdatadog-wasm/src/data_pipeline/mod.rs new file mode 100644 index 00000000..3ec8bf70 --- /dev/null +++ b/crates/libdatadog-wasm/src/data_pipeline/mod.rs @@ -0,0 +1,363 @@ +use std::cell::{Cell, RefCell}; +use std::collections::HashMap; +use std::fmt; +use std::rc::Rc; +use std::time::Duration; + +use bytes::Bytes; +use futures::future::{AbortHandle, Abortable}; +use js_sys::{Array, Function, Object, Promise, Reflect, Uint8Array}; +use libdatadog_data_pipeline::{ + send_agentless_v04, AgentlessTraceConfig, SendAgentlessV04Error, TracerMetadata, + DEFAULT_AGENTLESS_TIMEOUT, +}; +use libdd_capabilities::{HttpClientCapability, HttpError, SleepCapability}; +use wasm_bindgen::prelude::*; +use wasm_bindgen_futures::JsFuture; + +#[derive(Clone)] +struct AgentlessExporterOptions { + endpoint: String, + api_key: String, + hostname: Option, + env: Option, + service: Option, + version: Option, + runtime_id: Option, + container_id: Option, + tracer_version: String, + language_version: String, + language_interpreter: String, + timeout_ms: Option, +} + +#[derive(Clone)] +struct HostCapabilities { + request: Function, + cancel_request: Function, + sleep: Function, + cancel_sleep: Function, + next_call_id: Rc>, +} + +impl fmt::Debug for HostCapabilities { + fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("HostCapabilities") + } +} + +impl HostCapabilities { + fn next_call_id(&self) -> u32 { + let id = self.next_call_id.get(); + self.next_call_id.set(id.wrapping_add(1)); + id + } +} + +impl HttpClientCapability for HostCapabilities { + fn new_client() -> Self { + panic!("host capabilities must be constructed with JavaScript functions") + } + + fn new_without_connection_pooling() -> Self { + Self::new_client() + } + + async fn request( + &self, + request: http::Request, + ) -> Result, HttpError> { + let id = self.next_call_id(); + let plan = request_value(id, request)?; + let mut guard = CancelGuard::new(id, self.cancel_request.clone()); + let promise = self + .request + .call1(&JsValue::UNDEFINED, &plan) + .map(|value| Promise::resolve(&value)) + .map_err(network_error)?; + let response = JsFuture::from(promise).await.map_err(network_error)?; + guard.disarm(); + + let status = required_number(&response, "status")?; + let status = + u16::try_from(status).map_err(|error| HttpError::InvalidRequest(error.into()))?; + let body = Reflect::get(&response, &JsValue::from_str("body")).map_err(network_error)?; + http::Response::builder() + .status(status) + .body(Bytes::from(Uint8Array::new(&body).to_vec())) + .map_err(|error| HttpError::InvalidRequest(error.into())) + } +} + +impl SleepCapability for HostCapabilities { + fn new() -> Self { + panic!("host capabilities must be constructed with JavaScript functions") + } + + async fn sleep(&self, duration: Duration) { + let id = self.next_call_id(); + let milliseconds = duration_millis(duration); + let mut guard = CancelGuard::new(id, self.cancel_sleep.clone()); + if let Ok(value) = self.sleep.call2( + &JsValue::UNDEFINED, + &JsValue::from_f64(f64::from(id)), + &JsValue::from_f64(f64::from(milliseconds)), + ) { + let _ = JsFuture::from(Promise::resolve(&value)).await; + } + guard.disarm(); + } +} + +struct CancelGuard { + id: u32, + cancel: Function, + armed: bool, +} + +impl CancelGuard { + fn new(id: u32, cancel: Function) -> Self { + Self { + id, + cancel, + armed: true, + } + } + + fn disarm(&mut self) { + self.armed = false; + } +} + +impl Drop for CancelGuard { + fn drop(&mut self) { + if self.armed { + let _ = self + .cancel + .call1(&JsValue::UNDEFINED, &JsValue::from_f64(f64::from(self.id))); + } + } +} + +#[wasm_bindgen] +pub struct AgentlessExporter { + metadata: TracerMetadata, + config: AgentlessTraceConfig, + capabilities: HostCapabilities, + in_flight: Rc>>, + next_operation_id: Cell, +} + +#[wasm_bindgen] +impl AgentlessExporter { + #[wasm_bindgen(constructor)] + pub fn new( + value: JsValue, + request: Function, + cancel_request: Function, + sleep: Function, + cancel_sleep: Function, + ) -> Result { + let options = AgentlessExporterOptions { + endpoint: required_string(&value, "endpoint")?, + api_key: required_string(&value, "apiKey")?, + hostname: optional_string(&value, "hostname")?, + env: optional_string(&value, "env")?, + service: optional_string(&value, "service")?, + version: optional_string(&value, "version")?, + runtime_id: optional_string(&value, "runtimeId")?, + container_id: optional_string(&value, "containerId")?, + tracer_version: required_string(&value, "tracerVersion")?, + language_version: required_string(&value, "languageVersion")?, + language_interpreter: required_string(&value, "languageInterpreter")?, + timeout_ms: optional_number(&value, "timeoutMs")?, + }; + let metadata = TracerMetadata { + hostname: options.hostname.unwrap_or_default(), + env: options.env.unwrap_or_default(), + app_version: options.version.unwrap_or_default(), + runtime_id: options.runtime_id.unwrap_or_default(), + service: options.service.unwrap_or_default(), + tracer_version: options.tracer_version, + language: "nodejs".to_string(), + language_version: options.language_version, + language_interpreter: options.language_interpreter, + container_id: options.container_id.unwrap_or_default(), + ..Default::default() + }; + let timeout = options + .timeout_ms + .map(|timeout_ms| Duration::from_millis(u64::from(timeout_ms))) + .unwrap_or(DEFAULT_AGENTLESS_TIMEOUT); + let config = AgentlessTraceConfig { + endpoint_url: options.endpoint, + api_key: options.api_key, + timeout, + }; + let capabilities = HostCapabilities { + request, + cancel_request, + sleep, + cancel_sleep, + next_call_id: Rc::new(Cell::new(1)), + }; + + Ok(Self { + metadata, + config, + capabilities, + in_flight: Rc::new(RefCell::new(HashMap::new())), + next_operation_id: Cell::new(1), + }) + } + + #[wasm_bindgen(js_name = sendV04)] + pub async fn send_v04(&self, payload: &[u8]) -> Result<(), JsValue> { + let operation_id = self.next_operation_id.get(); + self.next_operation_id.set(operation_id.wrapping_add(1)); + let (abort, registration) = AbortHandle::new_pair(); + self.in_flight.borrow_mut().insert(operation_id, abort); + let _guard = OperationGuard { + id: operation_id, + in_flight: self.in_flight.clone(), + }; + let send = send_agentless_v04(&self.capabilities, payload, &self.metadata, &self.config); + + match Abortable::new(send, registration).await { + Ok(Ok(_)) => Ok(()), + Ok(Err(error)) => Err(send_error(error)), + Err(_) => Err(JsValue::from_str("data-pipeline export was cancelled")), + } + } + + #[wasm_bindgen(js_name = cancelAll)] + pub fn cancel_all(&self) { + for abort in self.in_flight.borrow().values() { + abort.abort(); + } + } +} + +impl Drop for AgentlessExporter { + fn drop(&mut self) { + self.cancel_all(); + } +} + +struct OperationGuard { + id: u32, + in_flight: Rc>>, +} + +impl Drop for OperationGuard { + fn drop(&mut self) { + self.in_flight.borrow_mut().remove(&self.id); + } +} + +fn request_value(id: u32, request: http::Request) -> Result { + let (parts, body) = request.into_parts(); + let headers = Array::new(); + for (name, value) in &parts.headers { + let value = value + .to_str() + .map_err(|error| HttpError::InvalidRequest(error.into()))?; + let header = Object::new(); + Reflect::set( + &header, + &JsValue::from_str("name"), + &JsValue::from_str(name.as_str()), + ) + .map_err(network_error)?; + Reflect::set( + &header, + &JsValue::from_str("value"), + &JsValue::from_str(value), + ) + .map_err(network_error)?; + headers.push(&header); + } + + let plan = Object::new(); + set(&plan, "id", &JsValue::from_f64(f64::from(id)))?; + set(&plan, "url", &JsValue::from_str(&parts.uri.to_string()))?; + set(&plan, "method", &JsValue::from_str(parts.method.as_str()))?; + set(&plan, "headers", &headers)?; + set(&plan, "body", &Uint8Array::from(body.as_ref()))?; + Ok(plan.into()) +} + +fn set(object: &Object, key: &str, value: &JsValue) -> Result<(), HttpError> { + Reflect::set(object, &JsValue::from_str(key), value) + .map(|_| ()) + .map_err(network_error) +} + +fn duration_millis(duration: Duration) -> u32 { + u32::try_from(duration.as_millis()).unwrap_or(u32::MAX) +} + +fn network_error(error: JsValue) -> HttpError { + HttpError::Network(anyhow::anyhow!(js_error_message(error))) +} + +fn send_error(error: SendAgentlessV04Error) -> JsValue { + JsValue::from_str(&format!("failed to send data-pipeline export: {error}")) +} + +fn js_error_message(value: JsValue) -> String { + Reflect::get(&value, &JsValue::from_str("message")) + .ok() + .and_then(|message| message.as_string()) + .or_else(|| value.as_string()) + .unwrap_or_else(|| "JavaScript transport error".to_string()) +} + +fn required_string(value: &JsValue, key: &str) -> Result { + optional_string(value, key)? + .ok_or_else(|| JsValue::from_str(&format!("{key} must be a string"))) +} + +fn optional_string(value: &JsValue, key: &str) -> Result, JsValue> { + let value = Reflect::get(value, &JsValue::from_str(key))?; + if value.is_null() || value.is_undefined() { + return Ok(None); + } + value + .as_string() + .ok_or_else(|| JsValue::from_str(&format!("{key} must be a string"))) + .map(Some) +} + +fn optional_number(value: &JsValue, key: &str) -> Result, JsValue> { + let value = Reflect::get(value, &JsValue::from_str(key))?; + if value.is_null() || value.is_undefined() { + return Ok(None); + } + let number = value + .as_f64() + .filter(|number| { + number.is_finite() + && *number >= 0.0 + && *number <= f64::from(u32::MAX) + && number.fract() == 0.0 + }) + .ok_or_else(|| JsValue::from_str(&format!("{key} must be an unsigned integer")))?; + Ok(Some(u32::try_from(number as u64).map_err(|_| { + JsValue::from_str(&format!("{key} must be an unsigned integer")) + })?)) +} + +fn required_number(value: &JsValue, key: &str) -> Result { + let number = Reflect::get(value, &JsValue::from_str(key)) + .map_err(network_error)? + .as_f64() + .filter(|number| { + number.is_finite() + && *number >= 0.0 + && *number <= f64::from(u32::MAX) + && number.fract() == 0.0 + }) + .ok_or_else(|| HttpError::InvalidRequest(anyhow::anyhow!("{key} must be an integer")))?; + Ok(number as u32) +} diff --git a/crates/libdatadog-wasm/src/lib.rs b/crates/libdatadog-wasm/src/lib.rs new file mode 100644 index 00000000..e133c0a1 --- /dev/null +++ b/crates/libdatadog-wasm/src/lib.rs @@ -0,0 +1,3 @@ +mod data_pipeline; +mod sketches; +mod zstd; diff --git a/crates/libdatadog-wasm/src/sketches/mod.rs b/crates/libdatadog-wasm/src/sketches/mod.rs new file mode 100644 index 00000000..0b55db3d --- /dev/null +++ b/crates/libdatadog-wasm/src/sketches/mod.rs @@ -0,0 +1,37 @@ +use libdd_ddsketch::DDSketch as InnerDDSketch; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +#[derive(Default)] +pub struct DDSketch { + inner: InnerDDSketch, +} + +#[wasm_bindgen] +impl DDSketch { + #[wasm_bindgen(constructor)] + pub fn new() -> Self { + Self::default() + } + + pub fn add(&mut self, point: f64) -> Result<(), JsError> { + self.inner + .add(point) + .map_err(|error| JsError::new(&error.to_string())) + } + + #[wasm_bindgen(js_name = addWithCount)] + pub fn add_with_count(&mut self, point: f64, count: f64) -> Result<(), JsError> { + self.inner + .add_with_count(point, count) + .map_err(|error| JsError::new(&error.to_string())) + } + + pub fn count(&self) -> f64 { + self.inner.count() + } + + pub fn encode(&self) -> Vec { + self.inner.clone().encode_to_vec() + } +} diff --git a/crates/datadog-js-zstd/src/lib.rs b/crates/libdatadog-wasm/src/zstd/mod.rs similarity index 69% rename from crates/datadog-js-zstd/src/lib.rs rename to crates/libdatadog-wasm/src/zstd/mod.rs index fed9b1c7..7d24d441 100644 --- a/crates/datadog-js-zstd/src/lib.rs +++ b/crates/libdatadog-wasm/src/zstd/mod.rs @@ -3,7 +3,6 @@ use wasm_bindgen::prelude::*; #[wasm_bindgen] pub fn zstd_compress(data: Uint8Array, level: i32) -> Uint8Array { - let vecdata = data.to_vec(); - let compressed_data = zstd::encode_all(&vecdata[..], level).expect("Failed to compress data"); + let compressed_data = zrip::compress(&data.to_vec(), level).expect("Failed to compress data"); Uint8Array::from(compressed_data.as_slice()) } diff --git a/crates/library_config/Cargo.toml b/crates/library_config/Cargo.toml index be76bd45..02e9383c 100644 --- a/crates/library_config/Cargo.toml +++ b/crates/library_config/Cargo.toml @@ -8,11 +8,9 @@ crate-type = ["cdylib", "rlib"] [dependencies] anyhow = "1" -libdd-library-config = { git = "https://github.com/DataDog/libdatadog.git", rev = "353134770b312b7ccd2df6afabc253090b948e5f" } +libdd-library-config = { git = "https://github.com/DataDog/libdatadog.git", tag = "v40.0.0" } wasm-bindgen = "0.2.100" -serde = { version = "1.0", features = ["derive"] } -serde-wasm-bindgen = "0.4" [package.metadata.wasm-pack.profile.release] wasm-opt = ["-O", "--enable-bulk-memory"] diff --git a/crates/pipeline/Cargo.toml b/crates/pipeline/Cargo.toml index c4440cf9..67b7aad3 100644 --- a/crates/pipeline/Cargo.toml +++ b/crates/pipeline/Cargo.toml @@ -14,18 +14,17 @@ js-sys = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1" libdatadog-nodejs-capabilities = { path = "../capabilities" } -# TODO: Replace these temporary libdatadog PR revs with the official release/tag -# that contains DataDog/libdatadog#2235, then regenerate Cargo.lock. -libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "6356aee4c69b51f27e7e82e43b1797f60b74905a" } -libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "6356aee4c69b51f27e7e82e43b1797f60b74905a", default-features = false } -libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "6356aee4c69b51f27e7e82e43b1797f60b74905a", default-features = false } -libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "6356aee4c69b51f27e7e82e43b1797f60b74905a", default-features = false, features = ["change-buffer"] } -libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "6356aee4c69b51f27e7e82e43b1797f60b74905a", default-features = false } -libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "6356aee4c69b51f27e7e82e43b1797f60b74905a", default-features = false } -libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "6356aee4c69b51f27e7e82e43b1797f60b74905a", default-features = false } +libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75" } +libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75", default-features = false } +libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75", default-features = false, features = ["telemetry"] } +libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75", default-features = false, features = ["change-buffer"] } +libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75", default-features = false } +libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75", default-features = false } +libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75", default-features = false } rmp-serde = "1" bytes = "1" http = "1" +web-time = "1" console_error_panic_hook = "0.1" [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/crates/pipeline/src/lib.rs b/crates/pipeline/src/lib.rs index 31188af5..eb25866e 100644 --- a/crates/pipeline/src/lib.rs +++ b/crates/pipeline/src/lib.rs @@ -1,7 +1,7 @@ use libdatadog_nodejs_capabilities::WasmCapabilities; use libdd_data_pipeline::trace_exporter::agent_response::AgentResponse; use libdd_data_pipeline::trace_exporter::{ - TraceExporter, TraceExporterBuilder, TraceExporterOutputFormat, + TelemetryConfig, TraceExporter, TraceExporterBuilder, TraceExporterOutputFormat, }; use libdd_data_pipeline::OtlpProtocol; use libdd_shared_runtime::LocalRuntime; @@ -197,13 +197,17 @@ pub struct WasmSpanState { /// Datadog agent. libdatadog maps its internal traces to OTLP, so no /// JS-formatted spans are involved. Like `use_v05`, only takes effect if /// set before the first send (when the exporter is built). - otlp_endpoint: RefCell>, + otlp_endpoint: Cell>, /// OTLP wire protocol (`http/json` default, or `http/protobuf`). Only /// applied when `otlp_endpoint` is set. otlp_protocol: Cell>, /// Extra HTTP headers for OTLP export (e.g. collector auth), as key/value /// pairs. Only applied when `otlp_endpoint` is set. - otlp_headers: RefCell>, + otlp_headers: Cell>, + /// When set, the lazily-built exporter has telemetry enabled with this + /// config. Only takes effect if set before the first send + /// (when the exporter is built). + telemetry_config: Cell>, /// Latched message from a failed lazy `build_async`. Building is one-shot and /// a failure is fatal (bad config), so once set every send returns it (as a /// distinguishable error) instead of a misleading "builder already consumed", @@ -335,9 +339,10 @@ impl WasmSpanState { prepared_spans: RefCell::new(Vec::new()), sending: Cell::new(false), use_v05: Cell::new(false), - otlp_endpoint: RefCell::new(None), + otlp_endpoint: Cell::new(None), otlp_protocol: Cell::new(None), - otlp_headers: RefCell::new(Vec::new()), + otlp_headers: Cell::new(Vec::new()), + telemetry_config: Cell::new(None), build_error: RefCell::new(None), }) } @@ -359,7 +364,7 @@ impl WasmSpanState { /// Takes precedence over `setUseV05` (OTLP bypasses the agent entirely). #[wasm_bindgen(js_name = "setOtlpEndpoint")] pub fn set_otlp_endpoint(&self, url: String) { - *self.otlp_endpoint.borrow_mut() = Some(url); + self.otlp_endpoint.set(Some(url)); } /// Select the OTLP wire protocol: `http/json` (default) or `http/protobuf`. @@ -374,6 +379,31 @@ impl WasmSpanState { Ok(()) } + /// Enable telemetry on the lazily-built trace exporter. + /// + /// Must be called before the first `sendPreparedChunk`. Later calls have + /// no effect. + /// + /// # Arguments + /// + /// - `heartbeat_ms`: sets the metric-flush cadence. Set to 0 to defer to + /// libdatadog's default interval. + /// - `runtime_id`: tags telemetry payloads with the tracer's runtime id when provided + /// - `debug_enabled`: toggles libdd-telemetry's verbose logging + #[wasm_bindgen(js_name = "enableTelemetry")] + pub fn enable_telemetry( + &self, + heartbeat_ms: u32, + runtime_id: Option, + debug_enabled: bool, + ) { + self.telemetry_config.set(Some(TelemetryConfig { + heartbeat: u64::from(heartbeat_ms), + runtime_id, + debug_enabled, + })); + } + /// Set extra HTTP headers for OTLP export as a flat `[key, value, ...]` /// array (the host flattens its key/value map). Only takes effect with an /// OTLP endpoint set, before the first send. A trailing unpaired element on @@ -386,7 +416,7 @@ impl WasmSpanState { .chunks_exact(2) .map(|pair| (pair[0].clone(), pair[1].clone())) .collect(); - *self.otlp_headers.borrow_mut() = headers; + self.otlp_headers.set(headers); } #[wasm_bindgen] @@ -520,16 +550,19 @@ impl WasmSpanState { // When an OTLP endpoint is configured, libdatadog exports traces via // OTLP HTTP to that endpoint instead of the Datadog agent (mutually // exclusive with the agent v0.4/v0.5 path). - if let Some(url) = self.otlp_endpoint.borrow().as_deref() { - builder.set_otlp_endpoint(url); - if let Some(protocol) = self.otlp_protocol.get() { + if let Some(url) = self.otlp_endpoint.take() { + builder.set_otlp_endpoint(&url); + if let Some(protocol) = self.otlp_protocol.take() { builder.set_otlp_protocol(protocol); } - let headers = self.otlp_headers.borrow(); + let headers = self.otlp_headers.take(); if !headers.is_empty() { - builder.set_otlp_headers(headers.clone()); + builder.set_otlp_headers(headers); } } + if let Some(cfg) = self.telemetry_config.take() { + builder.enable_telemetry(cfg); + } match builder.build_async::().await { Ok(built) => *exporter_slot = Some(built), Err(e) => { diff --git a/crates/pipeline/src/stats.rs b/crates/pipeline/src/stats.rs index 127a21e6..3e65cb46 100644 --- a/crates/pipeline/src/stats.rs +++ b/crates/pipeline/src/stats.rs @@ -7,13 +7,13 @@ //! HTTP transport for flushing stats to the Datadog agent's `/v0.6/stats` //! endpoint. -use std::time::{Duration, SystemTime}; +use web_time::{Duration, SystemTime}; -/// Wall-clock now() for wasm. `std::time::SystemTime::now()` is unimplemented on -/// `wasm32-unknown-unknown` (it panics/traps), so derive the time from JS -/// `Date.now()` (milliseconds since the Unix epoch). +/// Wall-clock now() for wasm. Delegates to `web_time::SystemTime::now()`, +/// which routes to JS `Date.now()` on `wasm32-unknown-unknown` (native +/// `std::time::SystemTime::now()` is unimplemented on that target and traps). fn now() -> SystemTime { - SystemTime::UNIX_EPOCH + Duration::from_millis(js_sys::Date::now() as u64) + SystemTime::now() } use bytes::Bytes; @@ -67,6 +67,7 @@ impl StatsCollector { ], Vec::new(), None, + Vec::new(), ), meta, agent_url, diff --git a/crates/process_discovery/Cargo.toml b/crates/process_discovery/Cargo.toml index 44042286..398ccc1c 100644 --- a/crates/process_discovery/Cargo.toml +++ b/crates/process_discovery/Cargo.toml @@ -8,11 +8,8 @@ crate-type = ["cdylib", "rlib"] [dependencies] anyhow = "1" -# Pointed at the merge commit that introduced ThreadLocalMetadata (caller-supplied -# schema version + extra process-context attributes). Swap back to a tagged release -# once one that includes 7cdeb7896e92d1ba38bde495934e112dac2eda25 is published. -libdd-library-config = { git = "https://github.com/DataDog/libdatadog.git", rev = "7cdeb7896e92d1ba38bde495934e112dac2eda25", features = ["otel-thread-ctx"] } -libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "7cdeb7896e92d1ba38bde495934e112dac2eda25" } +libdd-library-config = { git = "https://github.com/DataDog/libdatadog.git", tag = "v40.0.0", features = ["otel-thread-ctx"] } +libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", tag = "v40.0.0" } napi = { version = "2" } napi-derive = { version = "2", default-features = false } diff --git a/crates/remote_config/Cargo.toml b/crates/remote_config/Cargo.toml new file mode 100644 index 00000000..4512e8aa --- /dev/null +++ b/crates/remote_config/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "remote-config" +version = "0.1.0" +edition = "2021" +description = "Wasm binding for libdatadog's remote config client" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +libdd-remote-config = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75", default-features = false, features = ["client", "agentless"] } +libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75", default-features = false } +libdatadog-nodejs-capabilities = { path = "../capabilities" } + +wasm-bindgen = "0.2" +js-sys = "0.3" +wasm-bindgen-futures = "0.4" +serde = { version = "1.0", features = ["derive"] } +serde-wasm-bindgen = "0.4" +serde_json = "1" +console_error_panic_hook = "0.1" + +[package.metadata.wasm-pack.profile.release] +wasm-opt = ["-O", "--all-features"] + +[dev-dependencies] +wasm-bindgen-test = "0.3" diff --git a/crates/remote_config/src/lib.rs b/crates/remote_config/src/lib.rs new file mode 100644 index 00000000..6c69eef8 --- /dev/null +++ b/crates/remote_config/src/lib.rs @@ -0,0 +1,351 @@ +//! Wasm binding for libdatadog's remote config client. + +use std::cell::RefCell; +use std::rc::Rc; +use std::str::FromStr; +use std::sync::Arc; + +use libdatadog_nodejs_capabilities::{HttpClientCapability, WasmCapabilities}; +use libdd_remote_config::fetch::{ + AgentlessConfig, ConfigApplyState, ConfigInvariants, ConfigOptions, SingleChangesFetcher, +}; +use libdd_remote_config::file_change_tracker::{Change, FilePath}; +use libdd_remote_config::file_storage::{RawFile, SimpleFileStorage}; +use libdd_remote_config::{ + RemoteConfigCapabilities, RemoteConfigPath, RemoteConfigProduct, Target, +}; +use serde::{Deserialize, Serialize}; +use wasm_bindgen::prelude::*; + +#[wasm_bindgen(start)] +fn init() { + console_error_panic_hook::set_once(); +} + +const APPLY_STATE_UNACKNOWLEDGED: u32 = 1; +const APPLY_STATE_ACKNOWLEDGED: u32 = 2; +const APPLY_STATE_ERROR: u32 = 3; + +type Fetcher = SingleChangesFetcher; + +/// A real `Error`, not a bare string: the JS side logs rejections with a logger that identifies a +/// cause by its `stack`, and the pure-JS fallback client rejects with `Error`s too. +fn to_js_err(err: impl std::fmt::Display) -> JsValue { + js_sys::Error::new(&err.to_string()).into() +} + +/// Deserializing capabilities one name at a time keeps an unrecognized one from discarding +/// the whole set. +fn parse_capability(name: &str) -> Option { + serde_json::from_value(serde_json::Value::String(name.to_string())).ok() +} + +/// Options accepted by [`RemoteConfigFetcher::new`]. These populate the `Client`/`ClientTracer` of +/// the remote config request. +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct FetcherOptions { + client_id: String, + runtime_id: String, + service: String, + env: String, + app_version: String, + /// Already-formatted `"key:value"` strings. + tags: Vec, + /// Already-formatted `"key:value"` strings. + process_tags: Vec, + language: String, + tracer_version: String, + /// In agent mode the agent base URL, either `http(s)://host:port` or `unix:///path/to/socket`; + /// in agentless mode the Datadog site, e.g. `https://api.datadoghq.com`. + url: String, + timeout_ms: u64, + /// Enables agentless if set. + #[serde(default)] + api_key: Option, + #[serde(default)] + hostname: Option, +} + +/// A single add/update/remove of one remote config file, as diffed against the previous poll. +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +struct ChangeRecord { + /// One of `"add"`, `"update"`, `"remove"`. + kind: &'static str, + /// Full unparsed remote config path, e.g. `datadog/2/APM_TRACING/config-id/name` or + /// `employee/APM_TRACING/config-id/name`. Pass this back to `setConfigState`. + path: String, + product: String, + config_id: String, + name: String, + version: f64, + /// The hash-verified file contents. Omitted for `"remove"`: the consumer already holds them from + /// the `"add"`/`"update"` that introduced the config. + #[serde(skip_serializing_if = "Option::is_none")] + contents: Option, +} + +fn to_record( + kind: &'static str, + file: &Arc>>, + contents: Option, +) -> ChangeRecord { + let path = file.path(); + ChangeRecord { + kind, + path: path.to_string(), + product: path.product().to_string(), + config_id: path.config_id().to_string(), + name: path.name().to_string(), + // Read after `contents`: both lock the same mutex, which is not reentrant. + version: file.version() as f64, + contents, + } +} + +fn to_contents(file: &Arc>>) -> Option { + // Lossy like `Buffer#toString('utf8')`: a config file that is not valid UTF-8 is not valid JSON + // either, so the consumer rejects it either way. + Some(String::from_utf8_lossy(file.contents().as_slice()).into_owned()) +} + +fn to_change_record(change: Change>>, Vec>) -> ChangeRecord { + match change { + Change::Add(file) => to_record("add", &file, to_contents(&file)), + Change::Update(file, _old_contents) => to_record("update", &file, to_contents(&file)), + Change::Remove(file) => to_record("remove", &file, None), + } +} + +/// Mutations recorded by the setters while a poll may be in flight, applied at the start of the next +/// one. `fetchChanges` holds the fetcher borrow across its whole round trip, so the setters must not +/// take it -- they would find it already borrowed and have nowhere to put the update. +#[derive(Default)] +struct PendingUpdates { + product_capabilities: Option<(Vec, Vec)>, + extra_services: Option>, + config_states: Vec<(RemoteConfigPath, ConfigApplyState)>, +} + +/// Everything needed to build the fetcher, kept around because building it is deferred. +struct FetcherConfig { + target: Target, + runtime_id: String, + client_id: String, + invariants: ConfigInvariants, +} + +impl FetcherConfig { + async fn build(&self) -> Result { + Ok(SingleChangesFetcher::new( + SimpleFileStorage::default(), + self.target.clone(), + self.runtime_id.clone(), + ConfigOptions { + invariants: self.invariants.clone(), + // Products and capabilities are only known once the subsystems that own them have + // registered their handlers, which always happens before the first poll. + products: vec![], + capabilities: vec![], + }, + WasmCapabilities::new_without_connection_pooling(), + ) + .await + .map_err(to_js_err)? + .with_client_id(self.client_id.clone())) + } +} + +/// The fetcher is built on the first poll rather than in the constructor to be able to await.. +struct FetcherState { + config: FetcherConfig, + fetcher: Option, +} + +#[wasm_bindgen] +pub struct RemoteConfigFetcher { + state: Rc>, + pending: Rc>, +} + +#[wasm_bindgen] +impl RemoteConfigFetcher { + #[wasm_bindgen(constructor)] + pub fn new(options: JsValue) -> Result { + let options: FetcherOptions = serde_wasm_bindgen::from_value(options).map_err(to_js_err)?; + + let url = libdd_common::parse_uri(&options.url).map_err(to_js_err)?; + + // Validate, otherwise libdatadog will panic here + if url.scheme().is_none() || url.authority().is_none() { + return Err(to_js_err(format!( + "Remote config agent URL needs both a scheme and a host: {}", + options.url + ))); + } + + let endpoint = libdd_common::Endpoint { + url, + timeout_ms: options.timeout_ms, + api_key: options.api_key.map(Into::into), + ..Default::default() + }; + + let agentless = match endpoint.api_key { + Some(_) => Some( + AgentlessConfig::new(options.hostname.unwrap_or_default(), &endpoint) + .map_err(to_js_err)?, + ), + None => None, + }; + + let config = FetcherConfig { + target: Target::new( + options.service, + options.env, + options.app_version, + options.tags, + options.process_tags, + ), + runtime_id: options.runtime_id, + client_id: options.client_id, + invariants: ConfigInvariants { + language: options.language, + tracer_version: options.tracer_version, + endpoint, + agentless, + }, + }; + + Ok(RemoteConfigFetcher { + state: Rc::new(RefCell::new(FetcherState { + config, + fetcher: None, + })), + pending: Rc::new(RefCell::new(PendingUpdates::default())), + }) + } + + /// Polls the agent once and resolves with the changes (add/update/remove) relative to the + /// previous successful poll. An empty array means nothing changed. + /// + /// Holding the borrow across the await is deliberate: on wasm there is one thread, and the + /// borrow is what serializes polls. + #[allow(clippy::await_holding_refcell_ref)] + #[wasm_bindgen(js_name = "fetchChanges")] + pub async fn fetch_changes(&self) -> Result { + let cell = self.state.clone(); + let pending = self.pending.clone(); + + // The scheduler above this only arms the next poll once the previous settled, so an + // overlapping call is a guard, not a path. + let mut state = cell + .try_borrow_mut() + .map_err(|_| to_js_err("A remote config poll is already in flight"))?; + let state = &mut *state; + + let fetcher = match &mut state.fetcher { + Some(fetcher) => fetcher, + slot => slot.insert(state.config.build().await?), + }; + + let updates = std::mem::take(&mut *pending.borrow_mut()); + if let Some((products, capabilities)) = updates.product_capabilities { + fetcher.set_product_capabilities(products, capabilities); + } + if let Some(services) = updates.extra_services { + fetcher.set_extra_services(services); + } + for (path, state) in updates.config_states { + fetcher.fetcher.set_config_state(&path, state); + } + + let changes = fetcher + .fetch_changes::>() + .await + .map_err(to_js_err)?; + + let records: Vec = changes.into_iter().map(to_change_record).collect(); + + serde_wasm_bindgen::to_value(&records).map_err(to_js_err) + } + + /// Reports the apply outcome of a previously received change, identified by the `path` handed + /// back by `fetchChanges`. `applyState` is one of `APPLY_STATE_*` constants. + #[wasm_bindgen(js_name = "setConfigState")] + pub fn set_config_state( + &self, + path: String, + apply_state: u32, + apply_error: Option, + ) -> Result<(), JsValue> { + let state = match apply_state { + APPLY_STATE_UNACKNOWLEDGED => ConfigApplyState::Unacknowledged, + APPLY_STATE_ACKNOWLEDGED => ConfigApplyState::Acknowledged, + APPLY_STATE_ERROR => ConfigApplyState::Error(apply_error.unwrap_or_default()), + other => return Err(to_js_err(format!("Unknown apply state {other}"))), + }; + let path = RemoteConfigPath::try_parse(&path).map_err(to_js_err)?; + + self.pending + .borrow_mut() + .config_states + .push((path.into(), state)); + + Ok(()) + } + + /// Replaces the set of extra services reported to the agent. + #[wasm_bindgen(js_name = "setExtraServices")] + pub fn set_extra_services(&self, services: Vec) { + self.pending.borrow_mut().extra_services = Some(services); + } + + /// Replaces the set of subscribed products and capabilities. + /// + /// Names this build does not know are skipped and returned, so that a tracer whose own list has + /// moved ahead of libdatadog's keeps working with the names that do resolve. Reporting them is + /// left to the caller, which owns the logger. + #[wasm_bindgen(js_name = "setProductCapabilities")] + pub fn set_product_capabilities( + &self, + products: Vec, + capabilities: Vec, + ) -> Vec { + let mut unknown = vec![]; + + let products = products + .into_iter() + .filter_map(|name| match RemoteConfigProduct::from_str(&name) { + Ok(product) => Some(product), + Err(_) => { + unknown.push(name); + None + } + }) + .collect(); + + let capabilities = capabilities + .into_iter() + .filter_map(|name| match parse_capability(&name) { + Some(capability) => Some(capability), + None => { + unknown.push(name); + None + } + }) + .collect(); + + self.pending.borrow_mut().product_capabilities = Some((products, capabilities)); + + unknown + } +} + +/// Installs the host's async-context hook, so the HTTP request this module issues is not +/// re-instrumented by the tracer's own http plugin. +#[wasm_bindgen(js_name = "setStorage")] +pub fn set_storage(new_storage: &JsValue) { + libdatadog_nodejs_capabilities::http::set_storage(new_storage); +} diff --git a/eslint.config.js b/eslint.config.js index e7b67365..daf48dea 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -43,6 +43,12 @@ module.exports = [ 'unicorn/prevent-abbreviations': 'off', }, }, + { + files: ['**/*.mjs'], + languageOptions: { + sourceType: 'module', + }, + }, { files: ['load.js'], languageOptions: { @@ -71,7 +77,7 @@ module.exports = [ // flags these as "experimental" for the >=18 floor, but they are available on // every Node version the test matrix runs (18.20+). Test harnesses also pass // `null` to mirror the real inputs the wasm bindings receive. - files: ['test/**/*.js'], + files: ['test/**/*.js', 'packages/*/test/**/*.js'], rules: { 'n/no-unsupported-features/node-builtins': 'off', 'unicorn/no-null': 'off', @@ -80,14 +86,34 @@ module.exports = [ }, }, { - // Loaded by Rust via `wasm_bindgen(module = ".../http_transport.js")`, so the - // snake_case filename must match the Rust module path. - files: ['**/http_transport.js'], + // These imports are either installed by the package test workflow or + // generated during its build; root lint cannot resolve them. + files: [ + 'packages/libdatadog/lib/wasm.js', + 'packages/libdatadog/remote-config.js', + 'packages/libdatadog/test/bundlers.test.js', + 'packages/libdatadog/test/exporter.test.js', + ], + rules: { + 'n/no-missing-require': 'off', + }, + }, + { + // Loaded by Rust via `wasm_bindgen(module = ".../_transport.js")`, so + // the snake_case filename must match the Rust module path. + files: ['**/*_transport.js'], rules: { 'unicorn/filename-case': 'off', }, }, { - ignores: ['build/', 'target/', 'prebuilds/'], + ignores: [ + 'build/', + 'dist/', + 'target/', + 'prebuilds/', + 'packages/libdatadog/dist/', + 'packages/libdatadog/wasm/dist/', + ], }, ] diff --git a/load.js b/load.js index 69cdca51..c1dcf963 100644 --- a/load.js +++ b/load.js @@ -39,9 +39,13 @@ function load (name) { function findWASM (name) { const root = __dirname const prebuilds = path.join(root, 'prebuilds') - const folders = readdirSync(prebuilds) - if (folders.includes(name)) { - return path.join(prebuilds, name, `${name.replaceAll('-', '_')}.js`) + try { + const folders = readdirSync(prebuilds) + if (folders.includes(name)) { + return path.join(prebuilds, name, `${name.replaceAll('-', '_')}.js`) + } + } catch { + // No WASM build exists for this optional capability. } } diff --git a/package.json b/package.json index 6bd8a096..3fa52823 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { - "name": "@datadog/libdatadog", - "version": "0.18.1", - "description": "Node.js binding for libdatadog", + "name": "@datadog/libdatadog-extras", + "version": "0.19.0", + "description": "Optional native and WASM libdatadog functionality for Node.js", "main": "index.js", "scripts": { "install-wasm-pack": "curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh", @@ -9,10 +9,11 @@ "build-debug": "mkdir -p target && yarn -s cargo-build > ./target/out.ndjson && yarn -s copy-artifacts", "build-release": "mkdir -p target && yarn -s cargo-build-release > ./target/out.ndjson && yarn -s copy-artifacts", "build-all": "mkdir -p target && yarn -s cargo-build -- --workspace > ./target/out.ndjson && yarn -s copy-artifacts && yarn -s build-wasm", - "build-wasm": "yarn -s install-wasm-pack && node scripts/build-wasm.js library_config && node scripts/build-wasm.js datadog-js-zstd && node scripts/build-wasm.js pipeline", + "build-wasm": "yarn -s install-wasm-pack && node scripts/build-wasm.js", "cargo-build-release": "yarn -s cargo-build -- --release", "cargo-build": "cargo build --message-format=json-render-diagnostics", "copy-artifacts": "node ./scripts/copy-artifacts", + "check:dependencies": "node scripts/check-dependencies.js", "lint": "eslint .", "test": "bash scripts/test.sh" }, @@ -32,10 +33,10 @@ "devDependencies": { "@eslint/js": "^10.0.1", "@stylistic/eslint-plugin": "^5.9.0", - "eslint": "^10.0.2", - "eslint-plugin-import-x": "^4.12.2", + "eslint": "^10.6.0", + "eslint-plugin-import-x": "^4.17.1", "eslint-plugin-n": "^17.24.0", "eslint-plugin-unicorn": "^63.0.0", - "globals": "^17.4.0" + "globals": "^17.7.0" } } diff --git a/packages/libdatadog/.gitignore b/packages/libdatadog/.gitignore new file mode 100644 index 00000000..6be07be5 --- /dev/null +++ b/packages/libdatadog/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +wasm/dist/ +*.wasm diff --git a/packages/libdatadog/README.md b/packages/libdatadog/README.md new file mode 100644 index 00000000..ed1cdbef --- /dev/null +++ b/packages/libdatadog/README.md @@ -0,0 +1,23 @@ +# @datadog/libdatadog + +> **Internal package:** This package is published solely for use by `dd-trace`. +> It is not a supported standalone API and must not be used directly by +> applications or other libraries. Its API, behavior, and distribution may +> change without notice. + +WASM Node.js bindings for libdatadog. The bindings for Zstandard compression, +DDSketch, and the agentless data pipeline are maintained in the root +`crates/libdatadog-wasm` workspace crate. Optional libdatadog functionality is +published separately as `@datadog/libdatadog-extras`. + +Remote configuration is available from `@datadog/libdatadog/remote-config`. +It uses a dedicated wasm-bindgen artifact that loads only with this entry point. + +The package accepts Datadog v0.4 MessagePack payloads and exports them to an +agentless intake. + +The package uses a wasm-bindgen backend with the WebAssembly bytes embedded in +JavaScript. The canonical inlined output is published as the regular +`@datadog/libdatadog-wasm` dependency from the `wasm` workspace. The WASM +package also contains the separate remote configuration artifact. No raw +`.wasm` asset or native extension is published. diff --git a/packages/libdatadog/index.d.ts b/packages/libdatadog/index.d.ts new file mode 100644 index 00000000..0786af66 --- /dev/null +++ b/packages/libdatadog/index.d.ts @@ -0,0 +1,31 @@ +export interface AgentlessExporterOptions { + endpoint: string + apiKey: string + hostname?: string + env?: string + service?: string + version?: string + runtimeId?: string + containerId?: string + tracerVersion: string + languageVersion: string + languageInterpreter: string + timeoutMs?: number +} + +export interface AgentlessExporter { + sendV04(payload: Uint8Array): Promise + close(): void | Promise +} + +export function createAgentlessExporter(options: AgentlessExporterOptions): AgentlessExporter +export function backend(): 'wasm' + +export function zstd_compress(data: Uint8Array, level: number): Uint8Array + +export class DDSketch { + add(point: number): void + addWithCount(point: number, count: number): void + count(): number + encode(): Uint8Array +} diff --git a/packages/libdatadog/index.js b/packages/libdatadog/index.js new file mode 100644 index 00000000..963c32fc --- /dev/null +++ b/packages/libdatadog/index.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = require('./lib/wasm') diff --git a/packages/libdatadog/index.mjs b/packages/libdatadog/index.mjs new file mode 100644 index 00000000..17e46561 --- /dev/null +++ b/packages/libdatadog/index.mjs @@ -0,0 +1,10 @@ +import libdatadog from './index.js' + +export const { + backend, + createAgentlessExporter, + DDSketch, + zstd_compress, +} = libdatadog + +export { default } from './index.js' diff --git a/packages/libdatadog/lib/agentless-transport.js b/packages/libdatadog/lib/agentless-transport.js new file mode 100644 index 00000000..daef09b8 --- /dev/null +++ b/packages/libdatadog/lib/agentless-transport.js @@ -0,0 +1,78 @@ +'use strict' + +function createHostTransport () { + const requests = new Map() + const timers = new Map() + + async function request ({ id, url, method, headers: headerList, body }) { + const target = new URL(url) + const client = target.protocol === 'https:' ? require('node:https') : require('node:http') + const headers = Object.fromEntries(headerList.map(({ name, value }) => [name, value])) + + return new Promise((resolve, reject) => { + let settled = false + const finish = (callback, value) => { + if (settled) return + settled = true + requests.delete(id) + callback(value) + } + const outgoing = client.request(target, { + agent: false, + headers: { ...headers, connection: 'close' }, + method, + }, (response) => { + const chunks = [] + response.on('data', chunk => chunks.push(chunk)) + response.once('aborted', () => finish(reject, new Error('response aborted'))) + response.once('error', error => finish(reject, error)) + response.on('end', () => finish(resolve, { + status: response.statusCode, + body: Buffer.concat(chunks), + })) + }) + + requests.set(id, { + cancel: () => { + const error = new Error('agentless request was cancelled') + finish(reject, error) + outgoing.destroy(error) + }, + }) + outgoing.once('error', error => finish(reject, error)) + outgoing.end(body) + }) + } + + function cancelRequest (id) { + requests.get(id)?.cancel() + } + + // TODO(libdd-capabilities): Make host-backed capability futures cancel their + // underlying operation when dropped. Then sleep can return a cancellable + // operation directly, removing timer IDs, the timers map, and cancelSleep. + function sleep (id, milliseconds) { + return new Promise((resolve, reject) => { + const timeout = setTimeout(() => { + timers.delete(id) + resolve() + }, milliseconds) + timeout.unref?.() + timers.set(id, { + cancel: () => { + clearTimeout(timeout) + timers.delete(id) + reject(new Error('agentless timer was cancelled')) + }, + }) + }) + } + + function cancelSleep (id) { + timers.get(id)?.cancel() + } + + return { request, cancelRequest, sleep, cancelSleep } +} + +module.exports = { createHostTransport } diff --git a/packages/libdatadog/lib/agentless.js b/packages/libdatadog/lib/agentless.js new file mode 100644 index 00000000..d044ff32 --- /dev/null +++ b/packages/libdatadog/lib/agentless.js @@ -0,0 +1,65 @@ +'use strict' + +const { randomUUID } = require('node:crypto') + +const { createHostTransport } = require('./agentless-transport') + +/** @typedef {import('../index').AgentlessExporterOptions} AgentlessExporterOptions */ +/** @typedef {typeof import('@datadog/libdatadog-wasm')} AgentlessBinding */ + +class AgentlessExporter { + #binding + #closed = false + #inFlight = new Set() + + /** + * @param {AgentlessBinding} binding + * @param {AgentlessExporterOptions} options + */ + constructor (binding, options) { + const runtimeId = options.runtimeId ?? randomUUID() + const transport = createHostTransport() + this.#binding = new binding.AgentlessExporter( + { ...options, runtimeId }, + transport.request, + transport.cancelRequest, + transport.sleep, + transport.cancelSleep, + ) + } + + sendV04 (payload) { + if (this.#closed) { + return Promise.reject(new Error('data-pipeline exporter is closed')) + } + + let operation + try { + operation = this.#binding.sendV04(payload) + } catch (error) { + operation = Promise.reject(error) + } + this.#inFlight.add(operation) + operation.then( + () => this.#inFlight.delete(operation), + () => this.#inFlight.delete(operation), + ) + return operation + } + + async close () { + this.#closed = true + this.#binding.cancelAll() + await Promise.allSettled(this.#inFlight) + } +} + +/** + * @param {AgentlessBinding} binding + * @param {AgentlessExporterOptions} options + */ +function createAgentlessExporter (binding, options) { + return new AgentlessExporter(binding, options) +} + +module.exports = { createAgentlessExporter } diff --git a/packages/libdatadog/lib/wasm.js b/packages/libdatadog/lib/wasm.js new file mode 100644 index 00000000..3bb9c3d5 --- /dev/null +++ b/packages/libdatadog/lib/wasm.js @@ -0,0 +1,15 @@ +'use strict' + +const binding = require('@datadog/libdatadog-wasm') + +module.exports = { + backend: () => 'wasm', + DDSketch: binding.DDSketch, + createAgentlessExporter, + zstd_compress: binding.zstd_compress, +} + +/** @param {import('../index').AgentlessExporterOptions} options */ +function createAgentlessExporter (options) { + return require('./agentless').createAgentlessExporter(binding, options) +} diff --git a/packages/libdatadog/package-lock.json b/packages/libdatadog/package-lock.json new file mode 100644 index 00000000..9e695f20 --- /dev/null +++ b/packages/libdatadog/package-lock.json @@ -0,0 +1,1911 @@ +{ + "name": "@datadog/libdatadog", + "version": "0.19.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@datadog/libdatadog", + "version": "0.19.0", + "license": "Apache-2.0", + "workspaces": [ + "wasm" + ], + "dependencies": { + "@datadog/libdatadog-wasm": "0.19.0" + }, + "devDependencies": { + "@msgpack/msgpack": "^3.1.3", + "esbuild": "^0.28.2", + "typescript": "^6.0.3", + "webpack": "^5.109.2", + "webpack-cli": "^7.2.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@datadog/libdatadog-wasm": { + "resolved": "wasm", + "link": true + }, + "node_modules/@discoveryjs/json-ext": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-1.1.0.tgz", + "integrity": "sha512-Xc3VhU02wqZ1HvHRJUwL09HkZSTvidqY5Ya0NXBSYOxAp+Ln9dcJr9fySI+CkONzP3PekQo9WdzCv0PGER/mOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@msgpack/msgpack": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.1.3.tgz", + "integrity": "sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 18" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.2.0.tgz", + "integrity": "sha512-5IviulTZeRNp2vAJ514cc/HUlY5nZ9fCbq9DMyC52BrhFZACo3nI0R7qBxhQmo/d27NFe96ur/b7Wwxklda+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.3.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/acorn": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", + "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.15", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.15.tgz", + "integrity": "sha512-FwMjJJ7HnyZpWe+oWxegG0fezZyBZUagI5LZEoO3GCbtbKNwRfMH9Ue5d5v01PNePBy1QSfPSDTTeVL0Hb9EzA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", + "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.11.12", + "caniuse-lite": "^1.0.30001809", + "electron-to-chromium": "^1.5.402", + "node-releases": "^2.0.53", + "update-browserslist-db": "^1.3.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001809", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001809.tgz", + "integrity": "sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.408", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.408.tgz", + "integrity": "sha512-SLoprcYpJ/OH2v2ps0+N5biv9H4/KBT3+YmmDew64TwK5y9j2wv7pMOFY7IorVkyMtEyLSCRlXKLsNlakeAlPw==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.24.5", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", + "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.21.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", + "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-core-module": { + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimizer-webpack-plugin": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz", + "integrity": "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@minify-html/node": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "@swc/css": { + "optional": true + }, + "@swc/html": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "cssnano": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "html-minifier-terser": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "postcss": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.53.tgz", + "integrity": "sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", + "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser": { + "version": "5.50.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.50.0.tgz", + "integrity": "sha512-CN9BVxWhgS/hRxtUMjtC2uRWSTcSfQFHMDWma6sKKfIivCD91sM+FOPfvwoaRMqCSrUpe1nv3jDamd9eEQ4y+w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", + "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", + "integrity": "sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/watchpack": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", + "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.109.2", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.109.2.tgz", + "integrity": "sha512-U9/cvLzxObKNEZ9+TtdqrHM5/9z3lgl2c+c4BzbqGxFQvQvBAq87yql5A8pQ+rrMbS496MZJeF5enVBndIy2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.16.0", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.24.4", + "es-module-lexer": "^2.1.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "graceful-fs": "^4.2.11", + "mime-db": "^1.54.0", + "minimizer-webpack-plugin": "^5.6.1", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "watchpack": "^2.5.2", + "webpack-sources": "^3.5.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-7.2.2.tgz", + "integrity": "sha512-lD0pALneslq8FfV+rwvm1BMW0AFAJrHHhNupAGN4asYjMvqrtRsenU4iKpiBo09gS4ntMxKGUxl9jhTEzVt0oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^1.1.0", + "commander": "^14.0.3", + "cross-spawn": "^7.0.6", + "envinfo": "^7.21.0", + "import-local": "^3.2.0", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^6.0.1" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "js-yaml": "^4.0.0 || ^5.0.0", + "json5": "^2.2.3", + "toml": "^3.0.0 || ^4.0.0", + "webpack": "^5.101.0", + "webpack-bundle-analyzer": "^4.0.0 || ^5.0.0", + "webpack-dev-server": "^5.0.0 || ^6.0.0" + }, + "peerDependenciesMeta": { + "js-yaml": { + "optional": true + }, + "json5": { + "optional": true + }, + "toml": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", + "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "wasm": { + "name": "@datadog/libdatadog-wasm", + "version": "0.19.0", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + } + } +} diff --git a/packages/libdatadog/package.json b/packages/libdatadog/package.json new file mode 100644 index 00000000..6b896bd7 --- /dev/null +++ b/packages/libdatadog/package.json @@ -0,0 +1,69 @@ +{ + "name": "@datadog/libdatadog", + "version": "0.19.0", + "description": "WASM Node.js bindings for libdatadog", + "license": "Apache-2.0", + "type": "commonjs", + "main": "index.js", + "types": "index.d.ts", + "exports": { + ".": { + "types": "./index.d.ts", + "import": "./index.mjs", + "require": "./index.js", + "default": "./index.js" + }, + "./wasm": { + "types": "./index.d.ts", + "import": "./wasm.mjs", + "require": "./wasm.js", + "default": "./wasm.js" + }, + "./remote-config": { + "types": "./remote-config.d.ts", + "import": "./remote-config.js", + "require": "./remote-config.js", + "default": "./remote-config.js" + } + }, + "files": [ + "README.md", + "index.js", + "index.mjs", + "remote-config.js", + "remote-config.d.ts", + "wasm.js", + "wasm.mjs", + "index.d.ts", + "lib/" + ], + "workspaces": [ + "wasm" + ], + "engines": { + "node": ">=18" + }, + "scripts": { + "build:wasm": "npm run build:wasm:binary && npm run build:remote-config:binary && npm run inline:wasm && npm run inline:remote-config", + "build:wasm:binary": "node ../../scripts/build-wasm.js ../../crates/libdatadog-wasm wasm/dist", + "build:remote-config:binary": "node ../../scripts/build-wasm.js ../../crates/remote_config wasm/dist/remote-config", + "size:profile": "node ../../scripts/build-wasm.js ../../crates/libdatadog-wasm ../../target/size --profiling", + "inline:wasm": "node scripts/inline-wasm.js libdatadog_wasm wasm/dist", + "inline:remote-config": "node scripts/inline-wasm.js remote_config wasm/dist/remote-config", + "report:wasm-size": "node scripts/report-wasm-size.js", + "build": "npm run build:wasm", + "test": "node scripts/run-tests.js && npm run test:types", + "test:package": "node --test test/package-contents.test.js", + "test:types": "tsc --noEmit --strict --target ES2022 --module Node16 --moduleResolution Node16 test/types.test.ts" + }, + "dependencies": { + "@datadog/libdatadog-wasm": "0.19.0" + }, + "devDependencies": { + "@msgpack/msgpack": "^3.1.3", + "esbuild": "^0.28.2", + "typescript": "^6.0.3", + "webpack": "^5.109.2", + "webpack-cli": "^7.2.2" + } +} diff --git a/packages/libdatadog/remote-config.d.ts b/packages/libdatadog/remote-config.d.ts new file mode 100644 index 00000000..3e8e78fe --- /dev/null +++ b/packages/libdatadog/remote-config.d.ts @@ -0,0 +1 @@ +export * from '@datadog/libdatadog-wasm/remote-config' diff --git a/packages/libdatadog/remote-config.js b/packages/libdatadog/remote-config.js new file mode 100644 index 00000000..68d2f554 --- /dev/null +++ b/packages/libdatadog/remote-config.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = require('@datadog/libdatadog-wasm/remote-config') diff --git a/packages/libdatadog/scripts/inline-wasm.js b/packages/libdatadog/scripts/inline-wasm.js new file mode 100644 index 00000000..fe164f11 --- /dev/null +++ b/packages/libdatadog/scripts/inline-wasm.js @@ -0,0 +1,41 @@ +'use strict' + +const fs = require('node:fs') +const path = require('node:path') +const { constants, brotliCompressSync } = require('node:zlib') + +const [moduleName, relativeOutputDirectory] = process.argv.slice(2) + +if (!moduleName || !relativeOutputDirectory) { + throw new Error('usage: node scripts/inline-wasm.js ') +} + +const outputDirectory = path.join(__dirname, '..', relativeOutputDirectory) +const gluePath = path.join(outputDirectory, `${moduleName}.js`) +const wasmPath = path.join(outputDirectory, `${moduleName}_bg.wasm`) +const glue = fs.readFileSync(gluePath, 'utf8') +const wasm = fs.readFileSync(wasmPath) +const encodedWasm = brotliCompressSync(wasm, { + params: { + [constants.BROTLI_PARAM_QUALITY]: 11, + }, +}).toString('base64') +const loader = [ + `const wasmPath = \`\${__dirname}/${moduleName}_bg.wasm\`;`, + 'const wasmBytes = require(\'fs\').readFileSync(wasmPath);', +].join('\n') + +if (!glue.includes(loader)) { + throw new Error('wasm-bindgen loader changed; refusing to publish an external WASM asset') +} + +fs.writeFileSync( + gluePath, + glue.replace( + loader, + `const wasmBytes = require('node:zlib').brotliDecompressSync(Buffer.from('${encodedWasm}', 'base64'));`, + ), +) +fs.rmSync(wasmPath) +fs.rmSync(path.join(outputDirectory, '.gitignore'), { force: true }) +fs.rmSync(path.join(outputDirectory, 'package.json'), { force: true }) diff --git a/packages/libdatadog/scripts/report-wasm-size.js b/packages/libdatadog/scripts/report-wasm-size.js new file mode 100644 index 00000000..16b5294a --- /dev/null +++ b/packages/libdatadog/scripts/report-wasm-size.js @@ -0,0 +1,382 @@ +'use strict' + +const fs = require('node:fs') +const path = require('node:path') +const { brotliDecompressSync } = require('node:zlib') + +const sectionNames = [ + 'custom', + 'type', + 'import', + 'function', + 'table', + 'memory', + 'global', + 'export', + 'start', + 'element', + 'code', + 'data', + 'data count', + 'tag', +] + +const forbiddenWasmCode = [ + { + dependency: 'regex', + owners: new Set(['aho-corasick', 'regex', 'regex-automata', 'regex-syntax']), + }, + { + dependency: 'zstd', + owners: new Set(['zstd', 'zstd-safe']), + }, + { + dependency: 'zstd-sys', + owners: new Set(['zstd-sys', 'zstd-sys (C)']), + }, +] + +function readUnsignedLeb128 (bytes, start) { + let offset = start + let multiplier = 1 + let value = 0 + + while (offset < bytes.length) { + const byte = bytes[offset++] + value += (byte & 0x7F) * multiplier + if ((byte & 0x80) === 0) return { offset, value } + multiplier *= 128 + } + + throw new Error('WASM contains an unterminated section length') +} + +function validateWasm (wasm) { + const expectedHeader = Buffer.from([ + 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, + ]) + if (wasm.length < expectedHeader.length || !wasm.subarray(0, 8).equals(expectedHeader)) { + throw new Error('inline payload is not a WebAssembly 1 binary') + } +} + +function readSectionRecords (wasm) { + validateWasm(wasm) + + const sections = [] + let offset = 8 + + while (offset < wasm.length) { + const sectionStart = offset + const id = wasm[offset++] + const length = readUnsignedLeb128(wasm, offset) + const payloadStart = length.offset + const payloadEnd = payloadStart + length.value + if (payloadEnd > wasm.length) throw new Error('WASM section extends past the binary') + sections.push({ + bytes: payloadEnd - sectionStart, + id, + payloadEnd, + payloadStart, + }) + offset = payloadEnd + } + + return sections +} + +function readSections (wasm) { + const sections = [{ name: 'header', bytes: 8 }] + + for (const record of readSectionRecords(wasm)) { + const { bytes, id } = record + const name = sectionNames[id] || `unknown (${id})` + const existing = sections.find(section => section.name === name) + if (existing) existing.bytes += bytes + else sections.push({ name, bytes }) + } + + return sections +} + +function readWasmString (wasm, start) { + const length = readUnsignedLeb128(wasm, start) + const end = length.offset + length.value + if (end > wasm.length) throw new Error('WASM string extends past the binary') + return { + offset: end, + value: wasm.toString('utf8', length.offset, end), + } +} + +function skipLimits (wasm, start) { + const flags = readUnsignedLeb128(wasm, start) + const minimum = readUnsignedLeb128(wasm, flags.offset) + if ((flags.value & 1) === 0) return minimum.offset + return readUnsignedLeb128(wasm, minimum.offset).offset +} + +function readImportedFunctionCount (wasm, sections) { + const section = sections.find(section => section.id === 2) + if (!section) return 0 + + const cursor = readUnsignedLeb128(wasm, section.payloadStart) + let offset = cursor.offset + let functionCount = 0 + + for (let index = 0; index < cursor.value; index++) { + offset = readWasmString(wasm, offset).offset + offset = readWasmString(wasm, offset).offset + const kind = wasm[offset++] + + switch (kind) { + case 0: { + functionCount++ + offset = readUnsignedLeb128(wasm, offset).offset + break + } + case 1: { + offset++ + offset = skipLimits(wasm, offset) + break + } + case 2: { + offset = skipLimits(wasm, offset) + break + } + case 3: { + offset += 2 + break + } + case 4: { + offset++ + offset = readUnsignedLeb128(wasm, offset).offset + break + } + default: { + throw new Error(`unsupported WASM import kind: ${kind}`) + } + } + } + + return functionCount +} + +function readFunctionNames (wasm, sections) { + const names = new Map() + + for (const section of sections) { + if (section.id !== 0) continue + const customName = readWasmString(wasm, section.payloadStart) + if (customName.value !== 'name') continue + + let offset = customName.offset + while (offset < section.payloadEnd) { + const subsectionId = wasm[offset++] + const length = readUnsignedLeb128(wasm, offset) + const subsectionEnd = length.offset + length.value + offset = length.offset + + if (subsectionId === 1) { + const count = readUnsignedLeb128(wasm, offset) + offset = count.offset + for (let index = 0; index < count.value; index++) { + const functionIndex = readUnsignedLeb128(wasm, offset) + const name = readWasmString(wasm, functionIndex.offset) + names.set(functionIndex.value, name.value) + offset = name.offset + } + } + + offset = subsectionEnd + } + } + + return names +} + +function inferCrate (functionName) { + if (/^(COVER|FASTCOVER|FSE|HIST|HUF|POOL|XXH|ZSTD|ZSTDMT)_/.test(functionName)) { + return 'zstd-sys (C)' + } + if (/^__(externref|wbindgen|wbg)/.test(functionName)) return 'wasm-bindgen runtime' + if (/^(__rust|__rg_|dlmalloc::)/.test(functionName)) return 'Rust runtime' + + const match = functionName.match(/(?:^|[< &(,])(?:mut )?([A-Za-z][A-Za-z0-9_]*)::/) + if (!match) return 'bindings / unattributed' + if (['alloc', 'core', 'std'].includes(match[1])) return 'Rust standard library' + return match[1].replaceAll('_', '-') +} + +function insertBySize (entries, entry) { + const index = entries.findIndex(candidate => candidate.bytes < entry.bytes) + if (index === -1) entries.push(entry) + else entries.splice(index, 0, entry) +} + +function readCrateSizes (wasm) { + const sections = readSectionRecords(wasm) + const code = sections.find(section => section.id === 10) + if (!code) throw new Error('symbolized WASM does not contain a code section') + const names = readFunctionNames(wasm, sections) + if (names.size === 0) throw new Error('symbolized WASM does not contain function names') + + const importedFunctions = readImportedFunctionCount(wasm, sections) + const sizes = new Map() + const count = readUnsignedLeb128(wasm, code.payloadStart) + let offset = count.offset + let totalBytes = 0 + + for (let index = 0; index < count.value; index++) { + const bodyStart = offset + const body = readUnsignedLeb128(wasm, bodyStart) + offset = body.offset + body.value + if (offset > code.payloadEnd) throw new Error('WASM function extends past the code section') + + const bytes = offset - bodyStart + const name = names.get(importedFunctions + index) || '' + const crate = inferCrate(name) + sizes.set(crate, (sizes.get(crate) || 0) + bytes) + totalBytes += bytes + } + + const entries = [] + for (const [name, bytes] of sizes) insertBySize(entries, { bytes, name }) + return { entries, totalBytes } +} + +function findForbiddenWasmCode (entries) { + const failures = [] + + for (const entry of entries) { + const forbidden = forbiddenWasmCode.find(candidate => candidate.owners.has(entry.name)) + if (forbidden) failures.push({ ...entry, dependency: forbidden.dependency }) + } + + return failures +} + +function formatBytes (bytes) { + return bytes.toLocaleString('en-US') +} + +function formatKibibytes (bytes) { + return (bytes / 1024).toFixed(1) +} + +function layerRow (name, bytes, emphasis = false) { + const formattedBytes = formatBytes(bytes) + const kibibytes = formatKibibytes(bytes) + if (emphasis) return `| **${name}** | **${formattedBytes}** | **${kibibytes}** |` + return `| ${name} | ${formattedBytes} | ${kibibytes} |` +} + +function appendCrateReport (lines, profilePath) { + const profileWasm = fs.readFileSync(profilePath) + const { entries, totalBytes } = readCrateSizes(profileWasm) + const visibleEntries = entries.filter(entry => entry.bytes >= 2048) + const otherBytes = entries + .filter(entry => entry.bytes < 2048) + .reduce((total, entry) => total + entry.bytes, 0) + if (otherBytes > 0) { + visibleEntries.push({ bytes: otherBytes, name: 'other crates (<2 KiB each)' }) + } + const attributionNote = [ + 'Crate ownership comes from a separate symbol-preserving build with the same size settings.', + 'Debug-name bytes are excluded; generic functions are assigned to their symbol owner.', + ].join(' ') + + lines.push( + '', + '### Code by Rust crate', + '', + '| Crate/function owner | Bytes | KiB | Share |', + '| --- | ---: | ---: | ---: |', + ) + + for (const entry of visibleEntries) { + const share = `${(entry.bytes / totalBytes * 100).toFixed(1)}%` + lines.push( + `| ${entry.name} | ${formatBytes(entry.bytes)} | ` + + `${formatKibibytes(entry.bytes)} | ${share} |`, + ) + } + + lines.push('', attributionNote) +} + +function createReport (gluePath, profilePath) { + const glue = fs.readFileSync(gluePath, 'utf8') + const match = glue.match(/Buffer\.from\('([A-Za-z0-9+/=]+)', 'base64'\)/) + if (!match) throw new Error('could not find the inline base64 WASM payload') + + const base64Bytes = Buffer.byteLength(match[1]) + const compressed = Buffer.from(match[1], 'base64') + const wasm = brotliDecompressSync(compressed) + const glueBytes = Buffer.byteLength(glue) - base64Bytes + const inlineBytes = Buffer.byteLength(glue) + const base64Overhead = base64Bytes - compressed.length + const sections = readSections(wasm) + const lines = [ + '## libdatadog WASM size', + '', + '| Inline artifact layer | Bytes | KiB |', + '| --- | ---: | ---: |', + layerRow('Raw WASM (before Brotli)', wasm.length), + layerRow('Brotli-compressed WASM', compressed.length), + layerRow('Base64 encoding overhead', base64Overhead), + layerRow('JavaScript glue/loader', glueBytes), + layerRow('Final inlined JavaScript', inlineBytes, true), + '', + '### Raw WebAssembly sections', + '', + '| Section | Bytes | KiB | Share |', + '| --- | ---: | ---: | ---: |', + ] + + for (const section of sections) { + const share = `${(section.bytes / wasm.length * 100).toFixed(1)}%` + lines.push( + `| ${section.name} | ${formatBytes(section.bytes)} | ` + + `${formatKibibytes(section.bytes)} | ${share} |`, + ) + } + + if (profilePath) appendCrateReport(lines, profilePath) + + lines.push('', `Generated from \`${path.relative(process.cwd(), gluePath)}\`.`) + return lines.join('\n') +} + +if (require.main === module) { + const gluePath = path.join(__dirname, '..', 'wasm', 'dist', 'libdatadog_wasm.js') + const profilePath = process.argv[2] && path.resolve(process.argv[2]) + const report = createReport(gluePath, profilePath) + console.log(report) + + if (process.env.GITHUB_STEP_SUMMARY) { + fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, `${report}\n`) + } + + if (profilePath) { + const profileWasm = fs.readFileSync(profilePath) + const failures = findForbiddenWasmCode(readCrateSizes(profileWasm).entries) + if (failures.length > 0) { + console.error('Forbidden code found in the symbolized WASM binary:') + for (const failure of failures) { + console.error( + `- ${failure.dependency} via ${failure.name}: ${formatBytes(failure.bytes)} bytes`, + ) + } + process.exitCode = 1 + } + } +} + +module.exports = { + createReport, + findForbiddenWasmCode, + inferCrate, + readCrateSizes, + readSections, +} diff --git a/packages/libdatadog/scripts/run-tests.js b/packages/libdatadog/scripts/run-tests.js new file mode 100644 index 00000000..ce33ab4c --- /dev/null +++ b/packages/libdatadog/scripts/run-tests.js @@ -0,0 +1,13 @@ +const { readdirSync } = require('node:fs') +const path = require('node:path') +const { spawnSync } = require('node:child_process') + +const testFiles = readdirSync(path.join(__dirname, '..', 'test')) + .filter(file => file.endsWith('.test.js')) + .map(file => path.join('test', file)) +const result = spawnSync(process.execPath, ['--test', ...testFiles], { + stdio: 'inherit', +}) + +if (result.error) throw result.error +process.exitCode = result.status ?? 1 diff --git a/packages/libdatadog/scripts/set-version.js b/packages/libdatadog/scripts/set-version.js new file mode 100644 index 00000000..bc49659e --- /dev/null +++ b/packages/libdatadog/scripts/set-version.js @@ -0,0 +1,23 @@ +'use strict' + +const fs = require('node:fs') +const path = require('node:path') + +const version = process.argv[2] + +if (!version) throw new Error('usage: node scripts/set-version.js ') + +const packagePath = path.join(__dirname, '..', 'package.json') +const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8')) +const wasmPackagePath = path.join(__dirname, '..', 'wasm', 'package.json') +const wasmPackageJson = JSON.parse(fs.readFileSync(wasmPackagePath, 'utf8')) + +packageJson.version = version +packageJson.dependencies['@datadog/libdatadog-wasm'] = version +wasmPackageJson.version = version + +fs.writeFileSync(packagePath, JSON.stringify(packageJson, undefined, 2) + '\n') +fs.writeFileSync( + wasmPackagePath, + JSON.stringify(wasmPackageJson, undefined, 2) + '\n', +) diff --git a/packages/libdatadog/test/bundlers.test.js b/packages/libdatadog/test/bundlers.test.js new file mode 100644 index 00000000..037af0ff --- /dev/null +++ b/packages/libdatadog/test/bundlers.test.js @@ -0,0 +1,80 @@ +'use strict' + +const assert = require('node:assert/strict') +const fs = require('node:fs') +const os = require('node:os') +const path = require('node:path') +const { test } = require('node:test') +const { promisify } = require('node:util') + +const esbuild = require('esbuild') +const webpack = require('webpack') + +const packageRoot = path.join(__dirname, '..') +const webpackAsync = promisify(webpack) +const entries = new Map([ + ['package', path.join(packageRoot, 'index.js')], + ['WASM', path.join(packageRoot, 'wasm.js')], + ['remote config', path.join(packageRoot, 'remote-config.js')], +]) + +for (const [name, entry] of entries) { + test(`esbuild bundles the ${name} entry point without emitting an asset`, async () => { + await assertBundle(entry, bundleWithEsbuild) + }) + + test(`webpack bundles the ${name} entry point without emitting an asset`, async () => { + await assertBundle(entry, bundleWithWebpack) + }) +} + +/** + * @param {string} entry + * @param {(entry: string, output: string) => Promise} bundle + */ +async function assertBundle (entry, bundle) { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'libdatadog-bundle-')) + const output = path.join(directory, 'bundle.cjs') + + try { + await bundle(entry, output) + const files = fs.readdirSync(directory) + const contents = fs.readFileSync(output, 'utf8') + + assert.deepStrictEqual(files, ['bundle.cjs']) + assert.doesNotMatch(contents, /\.wasm(?:['"`)]|$)/m) + } finally { + fs.rmSync(directory, { force: true, recursive: true }) + } +} + +/** + * @param {string} entry + * @param {string} output + */ +async function bundleWithEsbuild (entry, output) { + await esbuild.build({ + bundle: true, + entryPoints: [entry], + outfile: output, + platform: 'node', + }) +} + +/** + * @param {string} entry + * @param {string} output + */ +async function bundleWithWebpack (entry, output) { + const stats = await webpackAsync({ + entry, + mode: 'production', + output: { + filename: path.basename(output), + path: path.dirname(output), + }, + target: 'node', + }) + + if (stats.hasErrors()) throw new Error(stats.toString({ all: false, errors: true })) +} diff --git a/packages/libdatadog/test/capabilities.test.js b/packages/libdatadog/test/capabilities.test.js new file mode 100644 index 00000000..a121853a --- /dev/null +++ b/packages/libdatadog/test/capabilities.test.js @@ -0,0 +1,36 @@ +'use strict' + +const assert = require('node:assert/strict') +const { test } = require('node:test') + +const backends = [ + ['default', require('..')], + ['WASM', require('../wasm')], +] + +test('package entry points exclude optional extras', () => { + for (const [, backend] of backends) { + assert.strictEqual(backend.JsConfigurator, undefined) + assert.strictEqual(backend.ConfigEntry, undefined) + } +}) + +for (const [name, backend] of backends) { + test(`${name} backend compresses a Uint8Array with Zstandard`, () => { + const input = new Uint8Array(4096).fill(42) + const compressed = backend.zstd_compress(input, 3) + + assert(compressed instanceof Uint8Array) + assert.deepStrictEqual([...compressed.subarray(0, 4)], [0x28, 0xB5, 0x2F, 0xFD]) + }) + + test(`${name} backend provides DDSketch`, () => { + const sketch = new backend.DDSketch() + + sketch.add(1) + sketch.addWithCount(2, 3) + assert.strictEqual(sketch.count(), 4) + assert(sketch.encode() instanceof Uint8Array) + assert.throws(() => sketch.add(-1), /point is invalid/) + }) +} diff --git a/packages/libdatadog/test/exporter.test.js b/packages/libdatadog/test/exporter.test.js new file mode 100644 index 00000000..375cd620 --- /dev/null +++ b/packages/libdatadog/test/exporter.test.js @@ -0,0 +1,259 @@ +'use strict' + +const assert = require('node:assert/strict') +const fs = require('node:fs') +const http = require('node:http') +const path = require('node:path') +const { test } = require('node:test') +const { zstdDecompressSync } = require('node:zlib') + +const { encode } = require('@msgpack/msgpack') + +const zstdMagic = Buffer.from([0x28, 0xB5, 0x2F, 0xFD]) + +const packageRoot = path.join(__dirname, '..') +const wasmArtifact = path.join(packageRoot, 'wasm', 'dist', 'libdatadog_wasm.js') + +test('package entry points defer unused agentless modules', { + skip: !fs.existsSync(wasmArtifact), +}, () => { + const agentlessPath = require.resolve('../lib/agentless') + + require('..') + assert.strictEqual(require.cache[agentlessPath], undefined) + + require('../wasm') + assert.strictEqual(require.cache[agentlessPath], undefined) +}) + +test('package entry point compresses agentless v0.4 exports with Zstandard', { + skip: !fs.existsSync(wasmArtifact), +}, async () => { + await assertExport(require('..')) +}) + +test('inline-WASM backend validates optional values', { + skip: !fs.existsSync(wasmArtifact), +}, async () => { + const pipeline = require('../wasm') + const options = { + endpoint: 'http://127.0.0.1:8126/api/v2/spans', + apiKey: 'test-api-key', + tracerVersion: '0.1.0', + languageVersion: process.version, + languageInterpreter: 'v8', + } + + const exporter = pipeline.createAgentlessExporter({ + ...options, + hostname: null, + env: null, + service: null, + version: null, + runtimeId: null, + containerId: null, + timeoutMs: null, + }) + await exporter.close() + + assert.throws( + () => pipeline.createAgentlessExporter({ ...options, timeoutMs: 1.5 }), + /timeoutMs must be an unsigned integer/, + ) +}) + +test('agentless exporter retries in Rust until the third attempt succeeds', { + skip: !fs.existsSync(wasmArtifact), +}, async () => { + const pipeline = require('../wasm') + let requests = 0 + const server = http.createServer((incoming, response) => { + incoming.resume() + incoming.once('end', () => { + requests++ + response.writeHead(requests < 3 ? 500 : 202) + response.end() + }) + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + const exporter = createExporter(pipeline, server) + try { + await exporter.sendV04(tracePayload()) + assert.strictEqual(requests, 3) + } finally { + await exporter.close() + await new Promise(resolve => server.close(resolve)) + } +}) + +test('agentless exporter applies Rust timeouts and retry policy', { + skip: !fs.existsSync(wasmArtifact), +}, async () => { + const pipeline = require('../wasm') + let requests = 0 + const server = http.createServer((incoming) => { + requests++ + incoming.resume() + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + const exporter = createExporter(pipeline, server, { timeoutMs: 100 }) + try { + await assert.rejects(exporter.sendV04(tracePayload()), /Request timed out/) + assert.strictEqual(requests, 3) + } finally { + await exporter.close() + await new Promise(resolve => server.close(resolve)) + } +}) + +test('agentless exporter close cancels an active HTTP request', { + skip: !fs.existsSync(wasmArtifact), +}, async () => { + const pipeline = require('../wasm') + let resolveRequest + const request = new Promise((resolve) => { + resolveRequest = resolve + }) + const server = http.createServer((incoming) => { + incoming.resume() + incoming.once('end', resolveRequest) + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + const exporter = createExporter(pipeline, server) + try { + const send = exporter.sendV04(tracePayload()) + await request + await exporter.close() + await assert.rejects(send, /export was cancelled/) + } finally { + await exporter.close() + await new Promise(resolve => server.close(resolve)) + } +}) + +test('agentless exporter close cancels retry backoff', { + skip: !fs.existsSync(wasmArtifact), +}, async () => { + const pipeline = require('../wasm') + let requests = 0 + let resolveResponse + const responseSent = new Promise((resolve) => { + resolveResponse = resolve + }) + const server = http.createServer((incoming, response) => { + incoming.resume() + incoming.once('end', () => { + requests++ + response.writeHead(500) + response.end(resolveResponse) + }) + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + const exporter = createExporter(pipeline, server) + try { + const send = exporter.sendV04(tracePayload()) + await responseSent + await new Promise(resolve => setTimeout(resolve, 50)) + await exporter.close() + await assert.rejects(send, /export was cancelled/) + await new Promise(resolve => setTimeout(resolve, 1100)) + assert.strictEqual(requests, 1) + } finally { + await exporter.close() + await new Promise(resolve => server.close(resolve)) + } +}) + +/** + * @param {typeof import('..')} pipeline + */ +async function assertExport (pipeline) { + const received = await withIntake(async (endpoint) => { + const exporter = pipeline.createAgentlessExporter({ + endpoint, + apiKey: 'test-api-key', + tracerVersion: '0.1.0', + languageVersion: process.version, + languageInterpreter: 'v8', + service: 'service', + containerId: 'container-id', + }) + + try { + await exporter.sendV04(tracePayload()) + } finally { + await exporter.close() + } + }) + + assert.strictEqual(pipeline.backend(), 'wasm') + assert.strictEqual(received.headers['dd-api-key'], 'test-api-key') + assert.strictEqual(received.headers['datadog-container-id'], 'container-id') + assert.match(received.headers['content-type'], /^application\/json/) + assert.strictEqual(received.headers['content-encoding'], 'zstd') + assert.deepStrictEqual(received.body.subarray(0, zstdMagic.length), zstdMagic) + if (zstdDecompressSync) { + const body = JSON.parse(zstdDecompressSync(received.body).toString()) + assert.strictEqual(body.traces[0].spans[0].name, 'operation') + assert.strictEqual(body.traces[0].spans[0].service, 'service') + } +} + +function tracePayload () { + return encode([[{ + service: 'service', + name: 'operation', + resource: 'resource', + trace_id: 1n, + span_id: 2n, + parent_id: 0n, + start: 1, + duration: 1, + error: 0, + meta: {}, + metrics: {}, + }]], { useBigInt64: true }) +} + +function createExporter (pipeline, server, options = {}) { + const { port } = server.address() + return pipeline.createAgentlessExporter({ + endpoint: `http://127.0.0.1:${port}/api/v2/spans`, + apiKey: 'test-api-key', + tracerVersion: '0.1.0', + languageVersion: process.version, + languageInterpreter: 'v8', + ...options, + }) +} + +async function withIntake (send) { + let resolveRequest + const request = new Promise((resolve) => { + resolveRequest = resolve + }) + const server = http.createServer((incoming, response) => { + const chunks = [] + incoming.on('data', chunk => chunks.push(chunk)) + incoming.on('end', () => { + resolveRequest({ + headers: incoming.headers, + body: Buffer.concat(chunks), + }) + response.end() + }) + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + try { + const { port } = server.address() + await send(`http://127.0.0.1:${port}/api/v2/spans`) + return await request + } finally { + await new Promise(resolve => server.close(resolve)) + } +} diff --git a/packages/libdatadog/test/package-contents.test.js b/packages/libdatadog/test/package-contents.test.js new file mode 100644 index 00000000..9856df05 --- /dev/null +++ b/packages/libdatadog/test/package-contents.test.js @@ -0,0 +1,189 @@ +'use strict' + +const assert = require('node:assert/strict') +const fs = require('node:fs') +const os = require('node:os') +const path = require('node:path') +const { execFileSync } = require('node:child_process') +const { createRequire } = require('node:module') +const { test } = require('node:test') + +const packageRoot = path.join(__dirname, '..') +const wasmPackageRoot = path.join(packageRoot, 'wasm') +const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm' +const npmCache = path.join(os.tmpdir(), 'libdatadog-npm-cache') +const npmOptions = process.platform === 'win32' ? { shell: true } : {} + +function pack (directory) { + const output = execFileSync(npm, ['pack', '--json', '--dry-run'], { + ...npmOptions, + cwd: directory, + encoding: 'utf8', + env: { ...process.env, npm_config_cache: npmCache }, + }) + return JSON.parse(output)[0] +} + +test('published packages contain only the intended artifacts', () => { + const libdatadog = pack(packageRoot) + const libdatadogWasm = pack(wasmPackageRoot) + const metapackageJson = JSON.parse(fs.readFileSync( + path.join(packageRoot, 'package.json'), + 'utf8', + )) + const names = libdatadog.files.map(file => file.path) + const wasmNames = libdatadogWasm.files.map(file => file.path) + const standaloneWasm = [...names, ...wasmNames] + .filter(file => file.endsWith('.wasm')) + + assert.deepStrictEqual(standaloneWasm, [], + `packages must not contain standalone WASM files: ${standaloneWasm.join(', ')}`) + assert(wasmNames.includes('dist/libdatadog_wasm.js'), + 'WASM package must contain the inline-WASM JavaScript fallback') + assert(wasmNames.includes('dist/remote-config/remote_config.js'), + 'WASM package must contain the dedicated remote config artifact') + assert.strictEqual(wasmNames.includes('remote-config.js'), false) + assert(wasmNames.includes('remote-config.d.ts')) + assert(names.includes('remote-config.js')) + assert.strictEqual(names.includes('remote-config.mjs'), false) + assert(names.includes('remote-config.d.ts')) + assert.strictEqual(libdatadogWasm.name, '@datadog/libdatadog-wasm') + assert.strictEqual( + metapackageJson.dependencies['@datadog/libdatadog-wasm'], + libdatadog.version, + ) + assert(!names.some(file => file.includes('.node')), + 'package must not contain native artifacts') + assert(!names.some(file => file.startsWith('dist/')), + 'package must not contain generated backend artifacts') +}) + +test('installed package uses its WASM dependency', () => { + const temporaryRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'libdatadog-install-')) + const installRoot = path.join(temporaryRoot, 'consumer') + const tarballRoot = path.join(temporaryRoot, 'tarballs') + const environment = { + ...process.env, + npm_config_cache: path.join(temporaryRoot, 'npm-cache'), + } + + fs.mkdirSync(installRoot) + fs.mkdirSync(tarballRoot) + fs.writeFileSync( + path.join(installRoot, 'package.json'), + JSON.stringify({ name: 'libdatadog-test-consumer', private: true }), + ) + + try { + const wasmTarball = createTarball(wasmPackageRoot, tarballRoot, environment) + const metapackageTarball = createTarball( + packageRoot, + tarballRoot, + environment, + ) + + execFileSync(npm, [ + 'install', + '--ignore-scripts', + '--no-package-lock', + '--offline', + wasmTarball, + metapackageTarball, + ], { + ...npmOptions, + cwd: installRoot, + env: environment, + stdio: 'pipe', + }) + + const requireInstalled = createRequire(path.join(installRoot, 'package.json')) + const libdatadog = requireInstalled('@datadog/libdatadog') + const explicitWasm = requireInstalled('@datadog/libdatadog/wasm') + const directRemoteConfig = requireInstalled('@datadog/libdatadog-wasm/remote-config') + + assert.strictEqual(libdatadog.RemoteConfigFetcher, undefined) + assert.strictEqual(explicitWasm.RemoteConfigFetcher, undefined) + const remoteConfig = requireInstalled('@datadog/libdatadog/remote-config') + assert.strictEqual(typeof remoteConfig.RemoteConfigFetcher, 'function') + assert.strictEqual(remoteConfig.RemoteConfigFetcher, directRemoteConfig.RemoteConfigFetcher) + assert.strictEqual(libdatadog.backend(), 'wasm') + assert.strictEqual(explicitWasm.backend(), 'wasm') + assert(libdatadog.zstd_compress(Buffer.alloc(16), 3) instanceof Uint8Array) + assert.strictEqual(new libdatadog.DDSketch().count(), 0) + assertEsmImports(installRoot, environment) + } finally { + fs.rmSync(temporaryRoot, { force: true, recursive: true }) + } +}) + +/** + * @param {string} installRoot + * @param {NodeJS.ProcessEnv} environment + */ +function assertEsmImports (installRoot, environment) { + const script = ` + import assert from 'node:assert/strict' + import libdatadog, { + backend, + createAgentlessExporter, + DDSketch, + zstd_compress, + } from '@datadog/libdatadog' + import wasm, { + backend as wasmBackend, + createAgentlessExporter as createWasmAgentlessExporter, + DDSketch as WasmDDSketch, + zstd_compress as wasmCompress, + } from '@datadog/libdatadog/wasm' + import remoteConfig, { + RemoteConfigFetcher, + setStorage, + } from '@datadog/libdatadog/remote-config' + import directRemoteConfig, { + RemoteConfigFetcher as DirectRemoteConfigFetcher, + setStorage as setDirectStorage, + } from '@datadog/libdatadog-wasm/remote-config' + + assert.strictEqual(libdatadog.RemoteConfigFetcher, undefined) + assert.strictEqual(wasm.RemoteConfigFetcher, undefined) + assert.strictEqual(remoteConfig.RemoteConfigFetcher, RemoteConfigFetcher) + assert.strictEqual(remoteConfig.setStorage, setStorage) + assert.strictEqual(directRemoteConfig.RemoteConfigFetcher, DirectRemoteConfigFetcher) + assert.strictEqual(directRemoteConfig.setStorage, setDirectStorage) + assert.strictEqual(RemoteConfigFetcher, DirectRemoteConfigFetcher) + assert.strictEqual(backend(), 'wasm') + assert.strictEqual(libdatadog.backend, backend) + assert.strictEqual(libdatadog.createAgentlessExporter, createAgentlessExporter) + assert(zstd_compress(new Uint8Array(16), 3) instanceof Uint8Array) + assert.strictEqual(new DDSketch().count(), 0) + + assert.strictEqual(wasmBackend(), 'wasm') + assert.strictEqual(wasm.backend, wasmBackend) + assert.strictEqual(wasm.createAgentlessExporter, createWasmAgentlessExporter) + assert(wasmCompress(new Uint8Array(16), 3) instanceof Uint8Array) + assert.strictEqual(new WasmDDSketch().count(), 0) + ` + + execFileSync(process.execPath, ['--input-type=module', '--eval', script], { + cwd: installRoot, + env: environment, + stdio: 'pipe', + }) +} + +function createTarball (directory, destination, environment) { + const output = execFileSync(npm, [ + 'pack', + '--json', + '--pack-destination', + destination, + ], { + ...npmOptions, + cwd: directory, + encoding: 'utf8', + env: environment, + }) + const [{ filename }] = JSON.parse(output) + + return path.join(destination, filename) +} diff --git a/packages/libdatadog/test/package.test.js b/packages/libdatadog/test/package.test.js new file mode 100644 index 00000000..37ccf99e --- /dev/null +++ b/packages/libdatadog/test/package.test.js @@ -0,0 +1,130 @@ +'use strict' + +const assert = require('node:assert/strict') +const { spawnSync } = require('node:child_process') +const fs = require('node:fs') +const path = require('node:path') +const { brotliDecompressSync } = require('node:zlib') +const { test } = require('node:test') + +const packageRoot = path.join(__dirname, '..') +const repositoryRoot = path.join(packageRoot, '..', '..') + +test('publishes the universal libdatadog package', () => { + const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'))) + + assert.strictEqual(packageJson.name, '@datadog/libdatadog') + assert.strictEqual(packageJson.exports['./wasm'].require, './wasm.js') + assert.strictEqual(packageJson.exports['./remote-config'].import, './remote-config.js') + assert.strictEqual(packageJson.exports['./remote-config'].require, './remote-config.js') + + const wasmPackageJson = JSON.parse(fs.readFileSync( + path.join(packageRoot, 'wasm', 'package.json'), + )) + assert.strictEqual( + wasmPackageJson.exports['./remote-config'].require, + './dist/remote-config/remote_config.js', + ) +}) + +test('uses the libdatadog release version', () => { + const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'))) + const wasmPackageJson = JSON.parse(fs.readFileSync( + path.join(packageRoot, 'wasm', 'package.json'), + )) + const repositoryPackageJson = JSON.parse(fs.readFileSync(path.join(repositoryRoot, 'package.json'))) + + assert.strictEqual(packageJson.version, repositoryPackageJson.version) + assert.strictEqual(wasmPackageJson.version, repositoryPackageJson.version) + assert.strictEqual( + packageJson.dependencies['@datadog/libdatadog-wasm'], + repositoryPackageJson.version, + ) +}) + +test('root entry point uses the WASM backend', () => { + const libdatadog = require('..') + + assert.strictEqual(libdatadog.backend(), 'wasm') +}) + +test('embeds a Brotli-compressed WASM fallback below the size budgets', () => { + const { glue, wasm } = readInlineWasm(path.join( + packageRoot, + 'wasm', + 'dist', + 'libdatadog_wasm.js', + )) + + assert.ok(Buffer.byteLength(glue) < 200 * 1024) + assert.ok(wasm.length < 500 * 1024) +}) + +test('embeds dedicated remote config WASM below the size budgets', () => { + const { glue, wasm } = readInlineWasm(path.join( + packageRoot, + 'wasm', + 'dist', + 'remote-config', + 'remote_config.js', + )) + + assert.ok(Buffer.byteLength(glue) < 450 * 1024) + assert.ok(wasm.length < 1024 * 1024) +}) + +test('requires an artifact name and output directory when inlining WASM', () => { + const script = path.join(packageRoot, 'scripts', 'inline-wasm.js') + + for (const scriptArguments of [[], ['fixture']]) { + const result = spawnSync(process.execPath, [script, ...scriptArguments]) + + assert.notStrictEqual(result.status, 0) + assert.match(result.stderr.toString(), /usage: node scripts\/inline-wasm\.js/) + } +}) + +test('inlines a named WASM artifact into its generated module', () => { + const outputDirectory = fs.mkdtempSync(path.join(packageRoot, '.inline-wasm-')) + const moduleName = 'fixture' + const wasm = Buffer.from('fixture WASM') + const loader = [ + `const wasmPath = \`\${__dirname}/${moduleName}_bg.wasm\`;`, + 'const wasmBytes = require(\'fs\').readFileSync(wasmPath);', + ].join('\n') + + try { + fs.writeFileSync(path.join(outputDirectory, `${moduleName}.js`), loader) + fs.writeFileSync(path.join(outputDirectory, `${moduleName}_bg.wasm`), wasm) + fs.writeFileSync(path.join(outputDirectory, '.gitignore'), '') + fs.writeFileSync(path.join(outputDirectory, 'package.json'), '{}') + + const result = spawnSync(process.execPath, [ + path.join(packageRoot, 'scripts', 'inline-wasm.js'), + moduleName, + path.relative(packageRoot, outputDirectory), + ]) + + assert.strictEqual(result.status, 0, result.stderr.toString()) + assert.deepStrictEqual(readInlineWasm(path.join(outputDirectory, `${moduleName}.js`)).wasm, wasm) + assert.strictEqual(fs.existsSync(path.join(outputDirectory, `${moduleName}_bg.wasm`)), false) + assert.strictEqual(fs.existsSync(path.join(outputDirectory, '.gitignore')), false) + assert.strictEqual(fs.existsSync(path.join(outputDirectory, 'package.json')), false) + } finally { + fs.rmSync(outputDirectory, { force: true, recursive: true }) + } +}) + +/** + * @param {string} gluePath + */ +function readInlineWasm (gluePath) { + const glue = fs.readFileSync(gluePath, 'utf8') + const encodedWasm = glue.match(/brotliDecompressSync\(Buffer\.from\('([^']+)', 'base64'\)\)/)?.[1] + + assert.ok(encodedWasm, 'WASM must be embedded as a Brotli-compressed base64 string') + return { + glue, + wasm: brotliDecompressSync(Buffer.from(encodedWasm, 'base64')), + } +} diff --git a/packages/libdatadog/test/remote-config.test.js b/packages/libdatadog/test/remote-config.test.js new file mode 100644 index 00000000..3ff4ac0b --- /dev/null +++ b/packages/libdatadog/test/remote-config.test.js @@ -0,0 +1,138 @@ +'use strict' + +/* eslint-disable unicorn/prefer-event-target -- Node stream mocks use EventEmitter. */ + +const assert = require('node:assert/strict') +const { AsyncLocalStorage } = require('node:async_hooks') +const { EventEmitter } = require('node:events') +const https = require('node:https') +const { test } = require('node:test') + +const { RemoteConfigFetcher, setStorage } = require('../remote-config') + +const CONFIG_PATH = 'datadog/2/ASM_FEATURES/asm-features-1/config' + +/** @typedef {import('../remote-config').RemoteConfigFetcherOptions} RemoteConfigFetcherOptions */ + +/** + * @param {Partial} [overrides] + */ +function fetcherOptions (overrides = {}) { + return { + clientId: 'client-id', + runtimeId: 'runtime-id', + service: 'service', + env: 'env', + appVersion: '1.0.0', + tags: [], + processTags: [], + language: 'nodejs', + tracerVersion: '1.0.0', + url: 'https://datadoghq.com', + timeoutMs: 5000, + apiKey: 'api-key', + hostname: 'host', + ...overrides, + } +} + +test('keeps remote config out of the universal WASM entry point', () => { + const wasm = require('../wasm') + + assert.strictEqual(wasm.RemoteConfigFetcher, undefined) + assert.strictEqual(wasm.setStorage, undefined) + assert.strictEqual(typeof RemoteConfigFetcher, 'function') +}) + +test('exports agentless remote config from the dedicated entry point', async () => { + const requests = [] + const storage = new AsyncLocalStorage() + const storageValue = {} + const observedStorageValues = [] + const originalRequest = https.request + + /** @param {() => void} callback */ + function runInStorage (callback) { + storage.run(storageValue, callback) + } + + /** + * @param {import('node:https').RequestOptions} options + * @param {(response: import('node:http').IncomingMessage) => void} onResponse + */ + function request (options, onResponse) { + observedStorageValues.push(storage.getStore()) + const outgoing = new EventEmitter() + const chunks = [] + + /** + * @param {string | Uint8Array} chunk + */ + outgoing.write = function write (chunk) { + chunks.push(Buffer.from(chunk)) + } + outgoing.end = () => { + requests.push({ body: Buffer.concat(chunks), options }) + queueMicrotask(() => { + const response = new EventEmitter() + response.statusCode = 200 + response.rawHeaders = [] + onResponse(response) + response.emit('end') + }) + } + return outgoing + } + https.request = request + setStorage(runInStorage) + + try { + const fetcher = new RemoteConfigFetcher(fetcherOptions()) + assert.deepStrictEqual( + fetcher.setProductCapabilities(['ASM_FEATURES'], ['ASM_ACTIVATION']), + [], + ) + fetcher.setExtraServices(['extra-service']) + + await assert.rejects(fetcher.fetchChanges()) + assert.strictEqual(observedStorageValues.some(value => value !== storageValue), false) + assert(observedStorageValues.length > 0) + + let configRequest + for (const request of requests) { + if (request.options.path === '/api/v0.1/configurations') { + configRequest = request + break + } + } + assert(configRequest) + assert.strictEqual(configRequest.options.headers['dd-api-key'], 'api-key') + assert.strictEqual(configRequest.options.method, 'POST') + assert(configRequest.body.length > 0) + } finally { + setStorage(runWithoutStorage) + https.request = originalRequest + } +}) + +/** @param {() => void} callback */ +function runWithoutStorage (callback) { + callback() +} + +test('keeps the WASM remote config validation contract', () => { + const fetcher = new RemoteConfigFetcher(fetcherOptions()) + + assert.deepStrictEqual( + fetcher.setProductCapabilities( + ['ASM_FEATURES', 'NOT_A_PRODUCT'], + ['ASM_ACTIVATION', 'NOT_A_CAPABILITY'], + ), + ['NOT_A_PRODUCT', 'NOT_A_CAPABILITY'], + ) + assert.throws( + () => fetcher.setConfigState(CONFIG_PATH, 42), + /Unknown apply state 42/, + ) + assert.strictEqual(typeof setStorage, 'function') +}) diff --git a/packages/libdatadog/test/size-report.test.js b/packages/libdatadog/test/size-report.test.js new file mode 100644 index 00000000..8adf2eaa --- /dev/null +++ b/packages/libdatadog/test/size-report.test.js @@ -0,0 +1,48 @@ +'use strict' + +const assert = require('node:assert/strict') +const path = require('node:path') +const test = require('node:test') + +const { + createReport: createWasmReport, + findForbiddenWasmCode, + inferCrate, + readSections, +} = require('../scripts/report-wasm-size') +test('reports inline packaging and WASM section sizes', () => { + const gluePath = path.join(__dirname, '..', 'wasm', 'dist', 'libdatadog_wasm.js') + const report = createWasmReport(gluePath) + + assert.match(report, /Raw WASM \(before Brotli\)/) + assert.match(report, /Base64 encoding overhead/) + assert.match(report, /Raw WebAssembly sections/) + assert.match(report, /\| code \|/) + assert.match(report, /\| data \|/) +}) + +test('rejects data that is not a WebAssembly binary', () => { + assert.throws(() => readSections(Buffer.from('not wasm')), /not a WebAssembly 1 binary/) +}) + +test('attributes symbolized functions to their Rust crate', () => { + assert.equal( + inferCrate('libdd_data_pipeline::trace_exporter::send'), + 'libdd-data-pipeline', + ) + assert.equal(inferCrate('::serialize'), 'serde-yaml') + assert.equal(inferCrate('ZSTD_compress'), 'zstd-sys (C)') + assert.equal(inferCrate('core::slice::sort'), 'Rust standard library') +}) + +test('rejects forbidden code linked into WASM', () => { + assert.deepEqual(findForbiddenWasmCode([ + { bytes: 10, name: 'regex-lite' }, + { bytes: 20, name: 'regex-automata' }, + { bytes: 30, name: 'zstd-sys (C)' }, + { bytes: 40, name: 'zrip-encode' }, + ]), [ + { bytes: 20, dependency: 'regex', name: 'regex-automata' }, + { bytes: 30, dependency: 'zstd-sys', name: 'zstd-sys (C)' }, + ]) +}) diff --git a/packages/libdatadog/test/transport.test.js b/packages/libdatadog/test/transport.test.js new file mode 100644 index 00000000..6e55df6f --- /dev/null +++ b/packages/libdatadog/test/transport.test.js @@ -0,0 +1,82 @@ +'use strict' + +const assert = require('node:assert/strict') +const http = require('node:http') +const { test } = require('node:test') + +const { createHostTransport } = require('../lib/agentless-transport') + +test('host transport rejects when a response is aborted', async () => { + const transport = createHostTransport() + let resolveResponseClosed + const responseClosed = new Promise((resolve) => { + resolveResponseClosed = resolve + }) + const server = http.createServer((request, response) => { + response.writeHead(200, { 'content-length': 100 }) + response.write('partial') + response.once('close', resolveResponseClosed) + setImmediate(() => response.destroy()) + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + try { + const { port } = server.address() + const result = transport.request({ + id: 1, + url: `http://127.0.0.1:${port}`, + method: 'POST', + headers: [], + body: Buffer.alloc(0), + }).then( + () => ({ status: 'resolved' }), + error => ({ error, status: 'rejected' }), + ) + + await responseClosed + const outcome = await result + + assert.strictEqual(outcome.status, 'rejected') + assert.match(outcome.error.message, /response aborted|aborted/) + } finally { + await new Promise(resolve => server.close(resolve)) + } +}) + +test('host transport cancels an active request', async () => { + const transport = createHostTransport() + let resolveRequest + const received = new Promise((resolve) => { + resolveRequest = resolve + }) + const server = http.createServer((request) => { + request.resume() + request.once('end', resolveRequest) + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + try { + const { port } = server.address() + const request = transport.request({ + id: 2, + url: `http://127.0.0.1:${port}`, + method: 'POST', + headers: [], + body: Buffer.alloc(0), + }) + await received + transport.cancelRequest(2) + await assert.rejects(request, /request was cancelled/) + } finally { + await new Promise(resolve => server.close(resolve)) + } +}) + +test('host transport cancels a pending timer', async () => { + const transport = createHostTransport() + const sleep = transport.sleep(3, 60_000) + + transport.cancelSleep(3) + + await assert.rejects(sleep, /timer was cancelled/) +}) diff --git a/packages/libdatadog/test/types.test.ts b/packages/libdatadog/test/types.test.ts new file mode 100644 index 00000000..a742c8d4 --- /dev/null +++ b/packages/libdatadog/test/types.test.ts @@ -0,0 +1,53 @@ +import { + backend, + DDSketch, + zstd_compress, +} from '@datadog/libdatadog' +import { + RemoteConfigFetcher, + setStorage, +} from '@datadog/libdatadog/remote-config' +import * as wasm from '@datadog/libdatadog/wasm' + +const selectedBackend: 'wasm' = backend() +const compressed: Uint8Array = zstd_compress(new Uint8Array(16), 3) +const sketch = new DDSketch() + +sketch.add(1) +sketch.addWithCount(2, 3) +const count: number = sketch.count() +const encoded: Uint8Array = sketch.encode() + +const wasmBackend: typeof backend = wasm.backend +const wasmSketch: typeof DDSketch = wasm.DDSketch +const wasmCompress: typeof zstd_compress = wasm.zstd_compress +const remoteConfigFetcher = new RemoteConfigFetcher({ + clientId: 'client-id', + runtimeId: 'runtime-id', + service: 'service', + env: 'env', + appVersion: '1.0.0', + tags: [], + processTags: [], + language: 'nodejs', + tracerVersion: '1.0.0', + url: 'http://127.0.0.1:8126', + timeoutMs: 5000, +}) + +remoteConfigFetcher.setExtraServices([]) +remoteConfigFetcher.setProductCapabilities([], []) +setStorage(runInStorage) + +function runInStorage (callback: () => void): void { + callback() +} + +void selectedBackend +void compressed +void count +void encoded +void wasmBackend +void wasmSketch +void wasmCompress +void remoteConfigFetcher diff --git a/packages/libdatadog/wasm.js b/packages/libdatadog/wasm.js new file mode 100644 index 00000000..963c32fc --- /dev/null +++ b/packages/libdatadog/wasm.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = require('./lib/wasm') diff --git a/packages/libdatadog/wasm.mjs b/packages/libdatadog/wasm.mjs new file mode 100644 index 00000000..7674c8e2 --- /dev/null +++ b/packages/libdatadog/wasm.mjs @@ -0,0 +1,10 @@ +import libdatadog from './wasm.js' + +export const { + backend, + createAgentlessExporter, + DDSketch, + zstd_compress, +} = libdatadog + +export { default } from './wasm.js' diff --git a/packages/libdatadog/wasm/package.json b/packages/libdatadog/wasm/package.json new file mode 100644 index 00000000..5132bb55 --- /dev/null +++ b/packages/libdatadog/wasm/package.json @@ -0,0 +1,31 @@ +{ + "name": "@datadog/libdatadog-wasm", + "version": "0.19.0", + "description": "WASM fallback for @datadog/libdatadog", + "license": "Apache-2.0", + "type": "commonjs", + "main": "dist/libdatadog_wasm.js", + "types": "dist/libdatadog_wasm.d.ts", + "exports": { + ".": { + "types": "./dist/libdatadog_wasm.d.ts", + "import": "./dist/libdatadog_wasm.js", + "require": "./dist/libdatadog_wasm.js", + "default": "./dist/libdatadog_wasm.js" + }, + "./remote-config": { + "types": "./remote-config.d.ts", + "import": "./dist/remote-config/remote_config.js", + "require": "./dist/remote-config/remote_config.js", + "default": "./dist/remote-config/remote_config.js" + }, + "./*": "./*" + }, + "files": [ + "dist/", + "remote-config.d.ts" + ], + "engines": { + "node": ">=18" + } +} diff --git a/packages/libdatadog/wasm/remote-config.d.ts b/packages/libdatadog/wasm/remote-config.d.ts new file mode 100644 index 00000000..e182181c --- /dev/null +++ b/packages/libdatadog/wasm/remote-config.d.ts @@ -0,0 +1,35 @@ +export interface RemoteConfigFetcherOptions { + clientId: string + runtimeId: string + service: string + env: string + appVersion: string + tags: string[] + processTags: string[] + language: string + tracerVersion: string + url: string + timeoutMs: number + apiKey?: string + hostname?: string +} + +export interface RemoteConfigChange { + kind: 'add' | 'update' | 'remove' + path: string + product: string + configId: string + name: string + version: number + contents?: string +} + +export class RemoteConfigFetcher { + constructor(options: RemoteConfigFetcherOptions) + fetchChanges(): Promise + setConfigState(path: string, applyState: number, applyError?: string): void + setExtraServices(services: string[]): void + setProductCapabilities(products: string[], capabilities: string[]): string[] +} + +export function setStorage(storage: (callback: () => void) => void): void diff --git a/scripts/build-wasm.js b/scripts/build-wasm.js index b5a20a6d..a6717f93 100644 --- a/scripts/build-wasm.js +++ b/scripts/build-wasm.js @@ -11,11 +11,16 @@ // script only allows development to happen on macOS. const os = require('node:os') +const fs = require('node:fs') +const path = require('node:path') const childProcess = require('node:child_process') const isMacOS = os.platform() === 'darwin' -const noWasmOpt = isMacOS ? '--no-opt' : '' -const library = process.argv[2] +const libraries = [ + 'library_config', + 'pipeline', + 'remote_config', +] const env = { ...process.env, @@ -29,7 +34,11 @@ if (isMacOS) { try { childProcess.execSync(`${llvmBinDir}/llvm-config --version`) } catch { - console.error(`‼️ LLVM not found in ${llvmDir}.\n‼️ Please install LLVM using Homebrew:\n📝 brew install llvm`) + console.error([ + `‼️ LLVM not found in ${llvmDir}.`, + '‼️ Please install LLVM using Homebrew:', + '📝 brew install llvm', + ].join('\n')) process.exit(1) // eslint-disable-line unicorn/no-process-exit } @@ -44,8 +53,49 @@ if (isMacOS) { env.CXX_wasm32_unknown_unknown = `${llvmBinDir}/clang++` } -childProcess.execSync( - `wasm-pack build ${noWasmOpt} --target nodejs ./crates/${library} --out-dir ../../prebuilds/${library}`, { - env, - }, -) +/** + * Build one WASM crate with the platform-specific compiler configuration. + * + * @param {string} cratePath + * @param {string} outputDirectory + * @param {{ profiling?: boolean, skipOptimization?: boolean }} options + * @returns {void} + */ +function buildWasm (cratePath, outputDirectory, options = {}) { + const { profiling = false, skipOptimization = false } = options + const resolvedOutputDirectory = path.resolve(cratePath, outputDirectory) + fs.rmSync(resolvedOutputDirectory, { force: true, recursive: true }) + const args = ['build'] + if (profiling) args.push('--profiling') + if (skipOptimization) args.push('--no-opt') + args.push('--target', 'nodejs', cratePath, '--out-dir', resolvedOutputDirectory) + childProcess.execFileSync('wasm-pack', args, { + env: { + ...env, + // Cargo's release profile strips the function names needed for size attribution. + ...(profiling && { CARGO_PROFILE_RELEASE_STRIP: 'false' }), + }, + }) + // wasm-pack ignores its output by default. These outputs are package inputs, + // so remove the nested ignore file and let each npm package's files allowlist + // decide whether they are published. + fs.rmSync(path.join(resolvedOutputDirectory, '.gitignore'), { force: true }) +} + +const [cratePath, outputDirectory, mode] = process.argv.slice(2) +if (cratePath || outputDirectory) { + if (!cratePath || !outputDirectory) { + throw new Error('Both the WASM crate path and output directory are required') + } + if (mode && mode !== '--profiling') throw new Error(`Unknown build mode: ${mode}`) + buildWasm(path.resolve(cratePath), path.resolve(outputDirectory), { + profiling: mode === '--profiling', + skipOptimization: isMacOS, + }) +} else { + for (const library of libraries) { + buildWasm(`./crates/${library}`, `../../prebuilds/${library}`, { + skipOptimization: isMacOS, + }) + } +} diff --git a/scripts/check-dependencies.js b/scripts/check-dependencies.js new file mode 100644 index 00000000..b02fe0d7 --- /dev/null +++ b/scripts/check-dependencies.js @@ -0,0 +1,164 @@ +'use strict' + +const path = require('node:path') +const { execFileSync } = require('node:child_process') + +const repositoryRoot = path.join(__dirname, '..') +const trees = [ + { package: 'libdatadog-wasm', target: 'wasm32-unknown-unknown' }, + { package: 'remote-config', target: 'wasm32-unknown-unknown' }, +] +// libdd-tuf 0.3.1 uses older dependency majors. Exact sets keep unrelated duplicates failing validation. +const remoteConfigDuplicatePackages = new Map([ + ['http', new Set(['0.2.12', '1.5.0'])], + ['itoa', new Set(['0.4.8', '1.0.18'])], + ['syn', new Set(['2.0.119', '3.0.4'])], + ['thiserror', new Set(['1.0.69', '2.0.20'])], + ['thiserror-impl', new Set(['1.0.69', '2.0.20'])], + ['untrusted', new Set(['0.7.1', '0.9.0'])], +]) +const remoteConfigTokioPackages = new Set(['tokio', 'tokio-macros', 'tokio-util']) + +/** + * @param {Set} actual + * @param {Set} expected + */ +function setsEqual (actual, expected) { + if (actual.size !== expected.size) return false + + for (const value of actual) { + if (!expected.has(value)) return false + } + return true +} + +function parseCargoTree (output) { + const paths = [] + const stack = [] + + for (const line of output.split('\n')) { + const match = line.match(/^(\d+)(\S+) v(\S+)/) + if (!match) continue + + const [, depthValue, name, version] = match + const depth = Number(depthValue) + stack.length = depth + stack[depth] = name + paths.push({ depth, name, path: [...stack], version }) + } + + return paths +} + +/** + * @param {{ name: string, version: string }[]} dependencies + * @param {{ package?: string }} [tree] + */ +function findDuplicateVersions (dependencies, tree = {}) { + const versionsByPackage = new Map() + const failures = [] + + for (const { name, version } of dependencies) { + const versions = versionsByPackage.get(name) ?? new Set() + versions.add(version) + versionsByPackage.set(name, versions) + } + + for (const [name, versions] of versionsByPackage) { + const allowedVersions = remoteConfigDuplicatePackages.get(name) + const allowedRemoteConfigDuplicate = tree.package === 'remote-config' + && allowedVersions !== undefined + && setsEqual(versions, allowedVersions) + if (versions.size > 1 && !allowedRemoteConfigDuplicate) { + failures.push({ name, versions: [...versions] }) + } + } + return failures +} + +/** + * @template {{ name: string }} Dependency + * @param {Dependency[]} dependencies + * @param {{ package?: string }} [tree] + * @returns {Dependency[]} + */ +function findForbiddenDependencies (dependencies, tree = {}) { + const failures = [] + + for (const dependency of dependencies) { + const isTokio = dependency.name === 'tokio' + const isTokioCompanion = dependency.name.startsWith('tokio-') + if (!isTokio && !isTokioCompanion) continue + + const allowedRemoteConfigRuntime = tree.package === 'remote-config' + && remoteConfigTokioPackages.has(dependency.name) + && dependency.path.includes('libdd-remote-config') + if (!allowedRemoteConfigRuntime) failures.push(dependency) + } + + return failures +} + +function checkTrees () { + const duplicateFailures = [] + const forbiddenFailures = [] + + for (const tree of trees) { + const output = execFileSync('cargo', [ + 'tree', + '--locked', + '--package', tree.package, + '--target', tree.target, + '--edges', 'normal,build', + '--prefix', 'depth', + '--format', '{p}', + ], { + cwd: repositoryRoot, + encoding: 'utf8', + }) + const dependencies = parseCargoTree(output) + + for (const failure of findDuplicateVersions(dependencies, tree)) { + duplicateFailures.push({ ...failure, ...tree }) + } + for (const failure of findForbiddenDependencies(dependencies, tree)) { + forbiddenFailures.push({ ...failure, ...tree }) + } + } + + if (duplicateFailures.length > 0) { + console.error('Dependencies with multiple versions found:') + for (const failure of duplicateFailures) { + console.error( + `- ${failure.package} (${failure.target}): ` + + `${failure.name} ${failure.versions.join(', ')}`, + ) + } + } else { + console.log(`No dependency version duplicates found in ${trees.length} artifact trees.`) + } + + if (forbiddenFailures.length > 0) { + console.error('Forbidden Tokio dependencies found:') + for (const failure of forbiddenFailures) { + console.error( + `- ${failure.package} (${failure.target}): ` + + `${failure.name} through ${failure.path.join(' -> ')}`, + ) + } + } else { + console.log('Tokio is limited to the dedicated remote config artifact.') + } + + if (duplicateFailures.length > 0 || forbiddenFailures.length > 0) { + process.exitCode = 1 + } +} + +if (require.main === module) checkTrees() + +module.exports = { + findDuplicateVersions, + findForbiddenDependencies, + parseCargoTree, +} diff --git a/test/build-wasm.js b/test/build-wasm.js new file mode 100644 index 00000000..69d613cf --- /dev/null +++ b/test/build-wasm.js @@ -0,0 +1,85 @@ +'use strict' + +const assert = require('node:assert/strict') +const fs = require('node:fs') +const os = require('node:os') +const path = require('node:path') +const { execFileSync } = require('node:child_process') +const { test } = require('node:test') + +const buildScript = path.join(__dirname, '..', 'scripts', 'build-wasm.js') + +test('cleans WASM output relative to each crate', () => { + const temporaryRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'build-wasm-')) + const projectRoot = path.join(temporaryRoot, 'nested', 'repository') + const binaryDirectory = path.join(temporaryRoot, 'bin') + const homebrewDirectory = path.join(temporaryRoot, 'homebrew') + const llvmDirectory = path.join(homebrewDirectory, 'opt', 'llvm', 'bin') + + try { + fs.mkdirSync(projectRoot, { recursive: true }) + fs.mkdirSync(binaryDirectory) + fs.mkdirSync(llvmDirectory, { recursive: true }) + writeExecutable(path.join(llvmDirectory, 'llvm-config'), 'process.exit(0)') + writeExecutable(path.join(binaryDirectory, 'wasm-pack'), ` + const fs = require('node:fs') + const path = require('node:path') + const outputIndex = process.argv.indexOf('--out-dir') + 1 + const outputDirectory = process.argv[outputIndex] + fs.mkdirSync(outputDirectory, { recursive: true }) + fs.writeFileSync(path.join(outputDirectory, '.gitignore'), '') + fs.writeFileSync(path.join(outputDirectory, 'built'), '') + `) + + for (const library of ['library_config', 'pipeline']) { + const crateDirectory = path.join(projectRoot, 'crates', library) + const outputDirectory = path.join(projectRoot, 'prebuilds', library) + const unrelatedDirectory = path.resolve( + projectRoot, + '..', + '..', + 'prebuilds', + library, + ) + + fs.mkdirSync(crateDirectory, { recursive: true }) + fs.mkdirSync(outputDirectory, { recursive: true }) + fs.mkdirSync(unrelatedDirectory, { recursive: true }) + fs.writeFileSync(path.join(outputDirectory, 'stale'), '') + fs.writeFileSync(path.join(unrelatedDirectory, 'keep'), '') + } + + execFileSync(process.execPath, [buildScript], { + cwd: projectRoot, + env: { + ...process.env, + HOMEBREW_DIR: homebrewDirectory, + PATH: `${binaryDirectory}${path.delimiter}${process.env.PATH}`, + }, + stdio: 'pipe', + }) + + for (const library of ['library_config', 'pipeline']) { + const outputDirectory = path.join(projectRoot, 'prebuilds', library) + const unrelatedDirectory = path.resolve( + projectRoot, + '..', + '..', + 'prebuilds', + library, + ) + + assert(!fs.existsSync(path.join(outputDirectory, 'stale'))) + assert(fs.existsSync(path.join(outputDirectory, 'built'))) + assert(!fs.existsSync(path.join(outputDirectory, '.gitignore'))) + assert(fs.existsSync(path.join(unrelatedDirectory, 'keep'))) + } + } finally { + fs.rmSync(temporaryRoot, { force: true, recursive: true }) + } +}) + +function writeExecutable (file, body) { + fs.writeFileSync(file, `#!/usr/bin/env node\n${body}\n`) + fs.chmodSync(file, 0o755) +} diff --git a/test/crashtracker/package-lock.json b/test/crashtracker/package-lock.json index e6236c70..92fc554d 100644 --- a/test/crashtracker/package-lock.json +++ b/test/crashtracker/package-lock.json @@ -7,7 +7,7 @@ "dependencies": { "@datadog/segfaultify": "^0.1.1", "body-parser": "^1.20.3", - "express": "^4.19.2" + "express": "^5.2.1" } }, "node_modules/@datadog/segfaultify": { @@ -20,23 +20,42 @@ } }, "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "license": "MIT", "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { "node": ">= 0.6" } }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" + "node_modules/accepts/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, "node_modules/body-parser": { "version": "1.20.4", @@ -101,15 +120,16 @@ } }, "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/content-type": { @@ -131,10 +151,13 @@ } }, "node_modules/cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", - "license": "MIT" + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } }, "node_modules/debug": { "version": "2.6.9", @@ -239,69 +262,263 @@ } }, "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "~1.20.3", - "content-disposition": "~0.5.4", - "content-type": "~1.0.4", - "cookie": "~0.7.1", - "cookie-signature": "~1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "~1.3.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "~0.1.12", - "proxy-addr": "~2.0.7", - "qs": "~6.14.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "~0.19.0", - "serve-static": "~1.16.2", - "setprototypeof": "1.2.0", - "statuses": "~2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { - "node": ">= 0.10.0" + "node": ">= 18" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" } }, - "node_modules/finalhandler": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "node_modules/express/node_modules/body-parser": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", + "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "statuses": "~2.0.2", - "unpipe": "~1.0.0" + "bytes": "^3.1.2", + "content-type": "^2.0.0", + "debug": "^4.4.3", + "http-errors": "^2.0.1", + "iconv-lite": "^0.7.2", + "on-finished": "^2.4.1", + "qs": "^6.15.2", + "raw-body": "^3.0.2", + "type-is": "^2.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/body-parser/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/express/node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", "engines": { "node": ">= 0.8" } }, + "node_modules/express/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/express/node_modules/qs": { + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/express/node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/express/node_modules/type-is": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", + "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", + "license": "MIT", + "dependencies": { + "content-type": "^2.0.0", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/type-is/node_modules/content-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", + "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, "node_modules/forwarded": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", @@ -312,12 +529,12 @@ } }, "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/function-bind": { @@ -449,6 +666,12 @@ "node": ">= 0.10" } }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -468,33 +691,15 @@ } }, "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "license": "MIT", "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" + "node": ">=18" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/mime-db": { @@ -525,9 +730,9 @@ "license": "MIT" }, "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -568,6 +773,15 @@ "node": ">= 0.8" } }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -578,10 +792,14 @@ } }, "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "license": "MIT" + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -635,24 +853,43 @@ "node": ">= 0.8" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/router/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true } - ], + } + }, + "node_modules/router/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, "node_modules/safer-buffer": { @@ -662,27 +899,71 @@ "license": "MIT" }, "node_modules/send": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", - "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.4.1", - "range-parser": "~1.2.1", - "statuses": "~2.0.2" + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/send/node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/send/node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/send/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/send/node_modules/ms": { @@ -692,18 +973,22 @@ "license": "MIT" }, "node_modules/serve-static": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", - "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "~0.19.1" + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/setprototypeof": { @@ -824,15 +1109,6 @@ "node": ">= 0.8" } }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -841,6 +1117,12 @@ "engines": { "node": ">= 0.8" } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" } } } diff --git a/test/crashtracker/package.json b/test/crashtracker/package.json index 2f81fde3..d5af9436 100644 --- a/test/crashtracker/package.json +++ b/test/crashtracker/package.json @@ -4,6 +4,6 @@ "dependencies": { "@datadog/segfaultify": "^0.1.1", "body-parser": "^1.20.3", - "express": "^4.19.2" + "express": "^5.2.1" } } diff --git a/test/crashtracker/yarn.lock b/test/crashtracker/yarn.lock index af309dca..34ee2463 100644 --- a/test/crashtracker/yarn.lock +++ b/test/crashtracker/yarn.lock @@ -9,20 +9,15 @@ dependencies: node-gyp-build "^3.9.0" -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== +accepts@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-2.0.0.tgz#bbcf4ba5075467f3f2131eab3cffc73c2f5d7895" + integrity sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng== dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + mime-types "^3.0.0" + negotiator "^1.0.0" -body-parser@^1.20.3, body-parser@~1.20.3: +body-parser@^1.20.3: version "1.20.4" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.4.tgz#f8e20f4d06ca8a50a71ed329c15dccad1cdc547f" integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA== @@ -40,7 +35,22 @@ body-parser@^1.20.3, body-parser@~1.20.3: type-is "~1.6.18" unpipe "~1.0.0" -bytes@~3.1.2: +body-parser@^2.2.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.3.0.tgz#6d8662f4d8c336028b8ac9aa24251b0ca64ba437" + integrity sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw== + dependencies: + bytes "^3.1.2" + content-type "^2.0.0" + debug "^4.4.3" + http-errors "^2.0.1" + iconv-lite "^0.7.2" + on-finished "^2.4.1" + qs "^6.15.2" + raw-body "^3.0.2" + type-is "^2.1.0" + +bytes@^3.1.2, bytes@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== @@ -61,24 +71,27 @@ call-bound@^1.0.2: call-bind-apply-helpers "^1.0.2" get-intrinsic "^1.3.0" -content-disposition@~0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" +content-disposition@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.1.0.tgz#f3db789c752d45564cc7e9e1e0b31790d4a38e17" + integrity sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g== -content-type@~1.0.4, content-type@~1.0.5: +content-type@^1.0.5, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -cookie-signature@~1.0.6: - version "1.0.7" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.7.tgz#ab5dd7ab757c54e60f37ef6550f481c426d10454" - integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== +content-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-2.0.0.tgz#2fb3ede69dffa0af78ca7c4ce7589680638b56df" + integrity sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ== + +cookie-signature@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.2.tgz#57c7fc3cc293acab9fec54d73e15690ebe4a1793" + integrity sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg== -cookie@~0.7.1: +cookie@^0.7.1: version "0.7.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== @@ -90,12 +103,19 @@ debug@2.6.9: dependencies: ms "2.0.0" -depd@2.0.0, depd@~2.0.0: +debug@^4.4.0, debug@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + +depd@2.0.0, depd@^2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -destroy@1.2.0, destroy@~1.2.0: +destroy@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== @@ -114,7 +134,7 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -encodeurl@~2.0.0: +encodeurl@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== @@ -136,75 +156,71 @@ es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: dependencies: es-errors "^1.3.0" -escape-html@~1.0.3: +escape-html@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -etag@~1.8.1: +etag@^1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== -express@^4.19.2: - version "4.22.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.22.1.tgz#1de23a09745a4fffdb39247b344bb5eaff382069" - integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "~1.20.3" - content-disposition "~0.5.4" - content-type "~1.0.4" - cookie "~0.7.1" - cookie-signature "~1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.3.1" - fresh "~0.5.2" - http-errors "~2.0.0" - merge-descriptors "1.0.3" - methods "~1.1.2" - on-finished "~2.4.1" - parseurl "~1.3.3" - path-to-regexp "~0.1.12" - proxy-addr "~2.0.7" - qs "~6.14.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "~0.19.0" - serve-static "~1.16.2" - setprototypeof "1.2.0" - statuses "~2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -finalhandler@~1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.2.tgz#1ebc2228fc7673aac4a472c310cc05b77d852b88" - integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== +express@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/express/-/express-5.2.1.tgz#8f21d15b6d327f92b4794ecf8cb08a72f956ac04" + integrity sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw== dependencies: - debug "2.6.9" - encodeurl "~2.0.0" - escape-html "~1.0.3" - on-finished "~2.4.1" - parseurl "~1.3.3" - statuses "~2.0.2" - unpipe "~1.0.0" + accepts "^2.0.0" + body-parser "^2.2.1" + content-disposition "^1.0.0" + content-type "^1.0.5" + cookie "^0.7.1" + cookie-signature "^1.2.1" + debug "^4.4.0" + depd "^2.0.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + finalhandler "^2.1.0" + fresh "^2.0.0" + http-errors "^2.0.0" + merge-descriptors "^2.0.0" + mime-types "^3.0.0" + on-finished "^2.4.1" + once "^1.4.0" + parseurl "^1.3.3" + proxy-addr "^2.0.7" + qs "^6.14.0" + range-parser "^1.2.1" + router "^2.2.0" + send "^1.1.0" + serve-static "^2.2.0" + statuses "^2.0.1" + type-is "^2.0.1" + vary "^1.1.2" + +finalhandler@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-2.1.1.tgz#a2c517a6559852bcdb06d1f8bd7f51b68fad8099" + integrity sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA== + dependencies: + debug "^4.4.0" + encodeurl "^2.0.0" + escape-html "^1.0.3" + on-finished "^2.4.1" + parseurl "^1.3.3" + statuses "^2.0.1" forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fresh@~0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-2.0.0.tgz#8dd7df6a1b3a1b3a5cf186c05a5dd267622635a4" + integrity sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A== function-bind@^1.1.2: version "1.1.2" @@ -252,7 +268,7 @@ hasown@^2.0.2: dependencies: function-bind "^1.1.2" -http-errors@~2.0.0, http-errors@~2.0.1: +http-errors@^2.0.0, http-errors@^2.0.1, http-errors@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b" integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== @@ -263,6 +279,13 @@ http-errors@~2.0.0, http-errors@~2.0.1: statuses "~2.0.2" toidentifier "~1.0.1" +iconv-lite@^0.7.2, iconv-lite@~0.7.0: + version "0.7.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" + integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + iconv-lite@~0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -280,6 +303,11 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +is-promise@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" + integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== + math-intrinsics@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" @@ -290,47 +318,54 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== -merge-descriptors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" - integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== +media-typer@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== +merge-descriptors@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808" + integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g== mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@~2.1.24, mime-types@~2.1.34: +mime-db@^1.54.0: + version "1.54.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + +mime-types@^3.0.0, mime-types@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.2.tgz#39002d4182575d5af036ffa118100f2524b2e2ab" + integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== + dependencies: + mime-db "^1.54.0" + +mime-types@~2.1.24: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== -ms@2.1.3: +ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== +negotiator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" + integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== node-gyp-build@^3.9.0: version "3.9.0" @@ -342,24 +377,31 @@ object-inspect@^1.13.3: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== -on-finished@~2.4.1: +on-finished@^2.4.1, on-finished@~2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== dependencies: ee-first "1.1.1" -parseurl@~1.3.3: +once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +parseurl@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -path-to-regexp@~0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" - integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== +path-to-regexp@^8.0.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.4.2.tgz#795c420c4f7ca45c5b887366f622ee0c9852cccd" + integrity sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA== -proxy-addr@~2.0.7: +proxy-addr@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== @@ -367,6 +409,13 @@ proxy-addr@~2.0.7: forwarded "0.2.0" ipaddr.js "1.9.1" +qs@^6.14.0, qs@^6.15.2: + version "6.15.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.2.tgz#fd55426d710403ddccc45e0f9eab16db7727ece9" + integrity sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw== + dependencies: + side-channel "^1.1.0" + qs@~6.14.0: version "6.14.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.2.tgz#b5634cf9d9ad9898e31fba3504e866e8efb6798c" @@ -374,11 +423,21 @@ qs@~6.14.0: dependencies: side-channel "^1.1.0" -range-parser@~1.2.1: +range-parser@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== +raw-body@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.2.tgz#3e3ada5ae5568f9095d84376fd3a49b8fb000a51" + integrity sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA== + dependencies: + bytes "~3.1.2" + http-errors "~2.0.1" + iconv-lite "~0.7.0" + unpipe "~1.0.0" + raw-body@~2.5.3: version "2.5.3" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.3.tgz#11c6650ee770a7de1b494f197927de0c923822e2" @@ -389,46 +448,50 @@ raw-body@~2.5.3: iconv-lite "~0.4.24" unpipe "~1.0.0" -safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +router@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/router/-/router-2.2.0.tgz#019be620b711c87641167cc79b99090f00b146ef" + integrity sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ== + dependencies: + debug "^4.4.0" + depd "^2.0.0" + is-promise "^4.0.0" + parseurl "^1.3.3" + path-to-regexp "^8.0.0" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -send@~0.19.0, send@~0.19.1: - version "0.19.2" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.2.tgz#59bc0da1b4ea7ad42736fd642b1c4294e114ff29" - integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== +send@^1.1.0, send@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/send/-/send-1.2.1.tgz#9eab743b874f3550f40a26867bf286ad60d3f3ed" + integrity sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ== dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "~0.5.2" - http-errors "~2.0.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.4.1" - range-parser "~1.2.1" - statuses "~2.0.2" - -serve-static@~1.16.2: - version "1.16.3" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.3.tgz#a97b74d955778583f3862a4f0b841eb4d5d78cf9" - integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== + debug "^4.4.3" + encodeurl "^2.0.0" + escape-html "^1.0.3" + etag "^1.8.1" + fresh "^2.0.0" + http-errors "^2.0.1" + mime-types "^3.0.2" + ms "^2.1.3" + on-finished "^2.4.1" + range-parser "^1.2.1" + statuses "^2.0.2" + +serve-static@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-2.2.1.tgz#7f186a4a4e5f5b663ad7a4294ff1bf37cf0e98a9" + integrity sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw== dependencies: - encodeurl "~2.0.0" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "~0.19.1" + encodeurl "^2.0.0" + escape-html "^1.0.3" + parseurl "^1.3.3" + send "^1.2.0" -setprototypeof@1.2.0, setprototypeof@~1.2.0: +setprototypeof@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== @@ -473,7 +536,7 @@ side-channel@^1.1.0: side-channel-map "^1.0.1" side-channel-weakmap "^1.0.2" -statuses@~2.0.1, statuses@~2.0.2: +statuses@^2.0.1, statuses@^2.0.2, statuses@~2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== @@ -483,6 +546,15 @@ toidentifier@~1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +type-is@^2.0.1, type-is@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.1.0.tgz#71d1a7053293582e16ac9f3ebaf1ab9aa49e5570" + integrity sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA== + dependencies: + content-type "^2.0.0" + media-typer "^1.1.0" + mime-types "^3.0.0" + type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" @@ -496,12 +568,12 @@ unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -vary@~1.1.2: +vary@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== diff --git a/test/dependencies.js b/test/dependencies.js new file mode 100644 index 00000000..8ad2c6b8 --- /dev/null +++ b/test/dependencies.js @@ -0,0 +1,172 @@ +'use strict' + +const assert = require('node:assert/strict') +const { spawnSync } = require('node:child_process') +const fs = require('node:fs') +const os = require('node:os') +const path = require('node:path') +const { test } = require('node:test') + +const { + findDuplicateVersions, + findForbiddenDependencies, + parseCargoTree, +} = require('../scripts/check-dependencies') + +test('dependency validation rejects all Tokio packages in WASM', () => { + const dependencies = parseCargoTree([ + '0libdatadog-wasm v0.1.0', + '1tokio v1.52.1', + '1tokio-util v0.7.18', + ].join('\n')) + const failures = findForbiddenDependencies(dependencies) + + assert.deepStrictEqual(failures.map(({ name }) => name), ['tokio', 'tokio-util']) +}) + +test('dependency validation reports forbidden packages from Cargo', () => { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'libdatadog-cargo-tree-')) + const preload = path.join(directory, 'cargo-tree.cjs') + const output = [ + '0libdatadog-wasm v0.1.0', + '1tokio v1.52.1', + ].join('\n') + const source = [ + '\'use strict\'', + '', + 'const childProcess = require(\'node:child_process\')', + '', + 'childProcess.execFileSync = function execFileSync () {', + ` return ${JSON.stringify(output)}`, + '}', + '', + ].join('\n') + + fs.writeFileSync(preload, source) + try { + const nodeOptions = [ + process.env.NODE_OPTIONS, + `--require=${preload}`, + ].filter(Boolean).join(' ') + const result = spawnSync(process.execPath, [ + path.join(__dirname, '..', 'scripts', 'check-dependencies.js'), + ], { + encoding: 'utf8', + env: { ...process.env, NODE_OPTIONS: nodeOptions }, + }) + + assert.strictEqual(result.status, 1) + assert.match(result.stderr, /tokio through libdatadog-wasm -> tokio/) + } finally { + fs.rmSync(directory, { force: true, recursive: true }) + } +}) + +test('dependency validation allows Tokio only through remote config', () => { + const dependencies = parseCargoTree([ + '0remote-config v0.1.0', + '1libdd-remote-config v3.0.0', + '2tokio v1.53.1', + '3tokio-macros v2.7.2', + '2tokio-util v0.7.19', + '1tokio v1.53.1', + ].join('\n')) + const tree = { package: 'remote-config' } + const names = [] + + for (const { name } of findForbiddenDependencies(dependencies, tree)) { + names.push(name) + } + + assert.deepStrictEqual(names, ['tokio']) +}) + +test('dependency validation still finds multiple versions in one artifact tree', () => { + const dependencies = parseCargoTree([ + '0libdatadog v0.1.0', + '1bytes v1.10.0', + '1dependency v1.0.0', + '2bytes v1.11.0', + ].join('\n')) + + assert.deepStrictEqual(findDuplicateVersions(dependencies), [{ + name: 'bytes', + versions: ['1.10.0', '1.11.0'], + }]) +}) + +test('dependency validation scopes duplicate exceptions to remote config', () => { + const dependencies = parseCargoTree([ + '0remote-config v0.1.0', + '1syn v2.0.119', + '1libdd-remote-config v3.0.0', + '2syn v3.0.4', + ].join('\n')) + const unexpectedVersion = parseCargoTree([ + '0remote-config v0.1.0', + '1syn v2.0.119', + '1libdd-remote-config v3.0.0', + '2syn v3.0.4', + '2other-dependency v1.0.0', + '3syn v1.0.109', + ].join('\n')) + const replacementVersion = parseCargoTree([ + '0remote-config v0.1.0', + '1syn v2.0.119', + '1libdd-remote-config v3.0.0', + '2syn v1.0.109', + ].join('\n')) + + assert.deepStrictEqual( + findDuplicateVersions(dependencies, { package: 'remote-config' }), + [], + ) + assert.deepStrictEqual(findDuplicateVersions(dependencies), [{ + name: 'syn', + versions: ['2.0.119', '3.0.4'], + }]) + assert.deepStrictEqual( + findDuplicateVersions(unexpectedVersion, { package: 'remote-config' }), + [{ + name: 'syn', + versions: ['2.0.119', '3.0.4', '1.0.109'], + }], + ) + assert.deepStrictEqual( + findDuplicateVersions(replacementVersion, { package: 'remote-config' }), + [{ + name: 'syn', + versions: ['2.0.119', '1.0.109'], + }], + ) +}) + +test('dependency validation reports unexpected remote config duplicate versions', () => { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'libdatadog-cargo-')) + const cargoPath = path.join(directory, 'cargo') + + try { + fs.writeFileSync(cargoPath, [ + '#!/usr/bin/env node', + `const output = process.argv.includes('remote-config')`, + String.raw` ? '0remote-config v0.1.0\n1syn v2.0.119\n1syn v3.0.4\n1syn v1.0.109\n'`, + String.raw` : '0fixture v1.0.0\n'`, + 'process.stdout.write(output)', + ].join('\n'), { mode: 0o755 }) + + const result = spawnSync(process.execPath, [ + path.join(__dirname, '..', 'scripts', 'check-dependencies.js'), + ], { + env: { + ...process.env, + PATH: `${directory}${path.delimiter}${process.env.PATH}`, + }, + }) + + assert.strictEqual(result.status, 1) + assert.match(result.stderr.toString(), /Dependencies with multiple versions found:/) + assert.match(result.stderr.toString(), /syn 2\.0\.119, 3\.0\.4, 1\.0\.109/) + } finally { + fs.rmSync(directory, { force: true, recursive: true }) + } +}) diff --git a/test/env-transport.js b/test/env-transport.js new file mode 100644 index 00000000..f45a3779 --- /dev/null +++ b/test/env-transport.js @@ -0,0 +1,31 @@ +'use strict' + +// The transport shim is plain CommonJS, so drive it directly. + +const { describe, it, before, after } = require('node:test') +const assert = require('node:assert') + +const envTransport = require('../crates/capabilities/src/env_transport') + +describe('env_transport', () => { + const NAME = 'LIBDD_CAP_TEST_ENV_TRANSPORT' + let savedValue + + before(() => { + savedValue = process.env[NAME] + }) + after(() => { + if (savedValue === undefined) delete process.env[NAME] + else process.env[NAME] = savedValue + }) + + it('returns undefined for an unset var', () => { + delete process.env[NAME] + assert.strictEqual(envTransport.get(NAME), undefined) + }) + + it('returns the value when the var is set', () => { + process.env[NAME] = 'value1' + assert.strictEqual(envTransport.get(NAME), 'value1') + }) +}) diff --git a/test/filesystem.js b/test/filesystem.js new file mode 100644 index 00000000..ec14bccd --- /dev/null +++ b/test/filesystem.js @@ -0,0 +1,51 @@ +'use strict' + +// The shim is plain CommonJS, so drive it directly. + +const { describe, it, before, after } = require('node:test') +const assert = require('node:assert') +const fs = require('node:fs') +const os = require('node:os') +const path = require('node:path') + +const filesystem = require('../crates/capabilities/src/filesystem') + +describe('filesystem', () => { + let tmp + before(() => { + tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'libdd-file-')) + }) + after(() => { + fs.rmSync(tmp, { recursive: true, force: true }) + }) + + it('writes and reads a file round-trip', async () => { + const p = path.join(tmp, 'hello.bin') + await filesystem.writeFile(p, Buffer.from('hello')) + const got = await filesystem.readFile(p) + assert.strictEqual(Buffer.from(got).toString('utf8'), 'hello') + }) + + it('readFile on a missing path rejects with ENOENT', async () => { + const p = path.join(tmp, 'does-not-exist') + await assert.rejects(filesystem.readFile(p), error => error && error.code === 'ENOENT') + }) + + it('metadata reports size, kind, and a positive inode', async () => { + const p = path.join(tmp, 'meta.bin') + fs.writeFileSync(p, '0123456789') + const m = await filesystem.metadata(p) + assert.strictEqual(m.size, 10n) + assert.strictEqual(m.is_file, true) + assert.strictEqual(m.is_dir, false) + assert.ok(m.inode > 0n, `expected positive inode, got ${m.inode}`) + }) + + it('exists returns true for a present path and false for a missing one', async () => { + const present = path.join(tmp, 'here') + fs.writeFileSync(present, '') + const absent = path.join(tmp, 'gone') + assert.strictEqual(await filesystem.exists(present), true) + assert.strictEqual(await filesystem.exists(absent), false) + }) +}) diff --git a/test/http_transport.js b/test/http_transport.js index a9418806..7333d8e8 100644 --- a/test/http_transport.js +++ b/test/http_transport.js @@ -56,7 +56,7 @@ describe('http_transport response header observer', () => { ) // head occupies [0, head.length); body is empty (offset 0, length 0). // Empty socketPath -> TCP transport. - return transport.httpRequest('127.0.0.1', port, false, '', 0, head.length, 0, 0, fakeWasmMemory(head)) + return transport.httpRequest('127.0.0.1', port, false, '', true, 0, head.length, 0, 0, fakeWasmMemory(head)) } it('invokes the observer with the raw response headers', async () => { @@ -128,44 +128,6 @@ describe('http_transport response header observer', () => { assert.strictEqual(body.length, Buffer.byteLength(RESPONSE_BODY)) assert.strictEqual(Buffer.from(body).toString('utf8'), RESPONSE_BODY) }) - - it('copies the request body before queued writes can observe detached wasm memory', async () => { - const received = [] - const body = Buffer.from('wasm-backed request body') - const server = http.createServer((req, res) => { - req.on('data', chunk => received.push(chunk)) - req.on('end', () => res.end(RESPONSE_BODY)) - }) - - await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) - try { - const port = server.address().port - const head = Buffer.from( - `POST /v0.4/traces HTTP/1.1\r\nHost: 127.0.0.1:${port}\r\n` - + `Content-Length: ${body.length}\r\nConnection: close\r\n\r\n`, - 'utf8', - ) - const memory = new WebAssembly.Memory({ initial: 1 }) - const bytes = new Uint8Array(memory.buffer) - bytes.set(head, 0) - bytes.set(body, head.length) - - const result = transport.httpRequest( - '127.0.0.1', port, false, '', 0, head.length, head.length, body.length, memory, - ) - // Old behavior passed a live wasm-memory view to req.write(). If the memory - // grew before Node assigned a socket and flushed its queued output, Node - // threw `Cannot perform Construct on a detached ArrayBuffer` from - // ClientRequest._flushOutput, outside httpRequest's try/catch retry path. - memory.grow(1) - - const [status] = await result - assert.strictEqual(status, 200) - assert.strictEqual(Buffer.concat(received).toString('utf8'), body.toString('utf8')) - } finally { - await new Promise(resolve => server.close(resolve)) - } - }) }) // libdatadog derives the request host from the agent URI, which keeps the @@ -204,7 +166,7 @@ describe('http_transport IPv6 host', () => { 'utf8', ) // Bracketed IPv6 host, exactly as libdatadog passes it from the agent URI. - const [status] = await transport.httpRequest('[::1]', port, false, '', 0, head.length, 0, 0, fakeWasmMemory(head)) + const [status] = await transport.httpRequest('[::1]', port, false, '', true, 0, head.length, 0, 0, fakeWasmMemory(head)) assert.strictEqual(status, 200) }) }) @@ -273,13 +235,115 @@ describe('http_transport unix socket', { skip: process.platform === 'win32' }, ( ) // host/port empty/0; socketPath drives the connection. const [status, , body] = await transport.httpRequest( - '', 0, false, socketPath, 0, head.length, 0, 0, fakeWasmMemory(head), + '', 0, false, socketPath, true, 0, head.length, 0, 0, fakeWasmMemory(head), ) assert.strictEqual(status, 200) assert.strictEqual(Buffer.from(body).toString('utf8'), RESPONSE_BODY) }) }) +describe('http_transport connection pooling', () => { + let server + let port + let sockets + let previousAgent + + before(async () => { + // Pin the agent instead of relying on `http.globalAgent`: its keep-alive default only arrived + // in Node 19, and even where it is on, reuse is an optimization Node does not guarantee. With + // an explicit keep-alive agent capped at one socket, "pooled" is deterministic on every + // supported version, and `agent: false` still bypasses it entirely. + previousAgent = http.globalAgent + http.globalAgent = new http.Agent({ keepAlive: true, maxSockets: 1 }) + + sockets = new Set() + server = http.createServer((req, res) => { + sockets.add(req.socket) + req.on('data', () => {}) + req.on('end', () => res.end(RESPONSE_BODY)) + }) + server.keepAliveTimeout = 60_000 + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + port = server.address().port + }) + + after(async () => { + http.globalAgent.destroy() + http.globalAgent = previousAgent + await new Promise(resolve => server.close(resolve)) + }) + + // No `Connection: close`, so the connection is reusable and pooling is observable. + function keepAliveHead () { + return Buffer.from( + `POST /v0.4/traces HTTP/1.1\r\nHost: 127.0.0.1:${port}\r\nContent-Length: 0\r\n\r\n`, + 'utf8', + ) + } + + async function poll (connectionPooling) { + sockets.clear() + for (let i = 0; i < 3; i++) { + const head = keepAliveHead() + const [status] = await transport.httpRequest( + '127.0.0.1', port, false, '', connectionPooling, 0, head.length, 0, 0, fakeWasmMemory(head), + ) + assert.strictEqual(status, 200) + } + return sockets.size + } + + it('reuses one connection when pooling is on', async () => { + assert.strictEqual(await poll(true), 1) + }) + + it('opens a fresh connection per request when pooling is off', async () => { + // What a caller polling on a fixed interval asks for: the agent's short idle keep-alive can + // close a pooled connection between polls, which turns reuse into intermittent failures. + assert.strictEqual(await poll(false), 3) + }) +}) + +describe('http_transport request body lifetime', () => { + it('copies the request body before queued writes can observe detached wasm memory', async () => { + const received = [] + const body = Buffer.from('wasm-backed request body') + const server = http.createServer((req, res) => { + req.on('data', chunk => received.push(chunk)) + req.on('end', () => res.end(RESPONSE_BODY)) + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + try { + const port = server.address().port + const head = Buffer.from( + `POST /v0.4/traces HTTP/1.1\r\nHost: 127.0.0.1:${port}\r\n` + + `Content-Length: ${body.length}\r\nConnection: close\r\n\r\n`, + 'utf8', + ) + const memory = new WebAssembly.Memory({ initial: 1 }) + const bytes = new Uint8Array(memory.buffer) + bytes.set(head, 0) + bytes.set(body, head.length) + + const result = transport.httpRequest( + '127.0.0.1', port, false, '', true, 0, head.length, head.length, body.length, memory, + ) + // Old behavior passed a live wasm-memory view to req.write(). If the memory + // grew before Node assigned a socket and flushed its queued output, Node + // threw `Cannot perform Construct on a detached ArrayBuffer` from + // ClientRequest._flushOutput, outside httpRequest's try/catch retry path. + memory.grow(1) + + const [status] = await result + assert.strictEqual(status, 200) + assert.strictEqual(Buffer.concat(received).toString('utf8'), body.toString('utf8')) + } finally { + await new Promise(resolve => server.close(resolve)) + } + }) +}) + // Entity-header injection: container-id / entity-id / external-env detection // (Node reads /proc + env; libdatadog's own detection is inert on wasm) and the // rewrite of the Rust-rendered request head that carries them. @@ -435,7 +499,7 @@ describe('http_transport entity headers', () => { view.set(body, head.length) const [status] = await transport.httpRequest( - '127.0.0.1', port, false, '', 0, head.length, head.length, body.length, { buffer: mem }, + '127.0.0.1', port, false, '', true, 0, head.length, head.length, body.length, { buffer: mem }, ) assert.strictEqual(status, 200) assert.strictEqual(received['datadog-meta-lang'], 'nodejs') diff --git a/test/pipeline.js b/test/pipeline.js index 15bbc797..fe9defa7 100644 --- a/test/pipeline.js +++ b/test/pipeline.js @@ -181,13 +181,19 @@ class NativeSpansInterface { this._cqbBytes = new Uint8Array(this._wasmMemory.buffer, this._cqbPtr) } - resetChangeQueue () { - this.cqbIndex = 8 - this.cqbCount = 0 - // Check if WASM memory was detached/grown + // Any Rust call can trigger a WASM memory.grow(), which detaches the + // JS-side ArrayBuffer. Callers must invoke this before every read/write to + // the shared buffers when a Rust call may have happened since the last check. + _ensureViews () { if (this._wasmMemory.buffer !== this._cqbView.buffer) { this._refreshViews() } + } + + resetChangeQueue () { + this.cqbIndex = 8 + this.cqbCount = 0 + this._ensureViews() this._cqbView.setUint32(0, 0, true) this._cqbView.setUint32(4, 0, true) } @@ -228,10 +234,7 @@ class NativeSpansInterface { } queueOp (op, spanId, ...args) { - // Check if WASM memory was detached/grown - if (this._wasmMemory.buffer !== this._cqbView.buffer) { - this._refreshViews() - } + this._ensureViews() // Check if Rust flushed the queue (wrote 0 to count position) if (this._cqbView.getUint32(0, true) === 0 && this.cqbCount > 0) { @@ -239,22 +242,20 @@ class NativeSpansInterface { this.cqbCount = 0 } - let view = this._cqbView // Op header: opcode (u16 LE) + span_id (u64 LE) = 10 bytes. Rust reads the // opcode as a u16, then the span_id as a u64. - view.setUint16(this.cqbIndex, op, true) + this._cqbView.setUint16(this.cqbIndex, op, true) this.cqbIndex += 2 this._writeBytesLE(spanId, this.cqbIndex) this.cqbIndex += 8 for (const arg of args) { if (typeof arg === 'string') { + // getStringId may call into Rust (stringTableInsertOne), which can + // grow WASM memory and detach our views. Re-check after the call. const stringId = this.getStringId(arg) - if (this._wasmMemory.buffer !== view.buffer) { - this._refreshViews() - view = this._cqbView - } - view.setUint32(this.cqbIndex, stringId, true) + this._ensureViews() + this._cqbView.setUint32(this.cqbIndex, stringId, true) this.cqbIndex += 4 } else { const [typ, num] = arg @@ -265,12 +266,12 @@ class NativeSpansInterface { break } case 'u64n': { - view.setBigUint64(this.cqbIndex, BigInt(num), true) + this._cqbView.setBigUint64(this.cqbIndex, BigInt(num), true) this.cqbIndex += 8 break } case 'u32n': { // raw, pre-resolved string-table id - view.setUint32(this.cqbIndex, num, true) + this._cqbView.setUint32(this.cqbIndex, num, true) this.cqbIndex += 4 break } @@ -282,17 +283,17 @@ class NativeSpansInterface { break } case 'i64': { - view.setBigInt64(this.cqbIndex, num, true) + this._cqbView.setBigInt64(this.cqbIndex, num, true) this.cqbIndex += 8 break } case 'i32': { - view.setInt32(this.cqbIndex, num, true) + this._cqbView.setInt32(this.cqbIndex, num, true) this.cqbIndex += 4 break } case 'f64': { - view.setFloat64(this.cqbIndex, num, true) + this._cqbView.setFloat64(this.cqbIndex, num, true) this.cqbIndex += 8 break } @@ -304,7 +305,7 @@ class NativeSpansInterface { } this.cqbCount++ - view.setBigUint64(0, BigInt(this.cqbCount), true) + this._cqbView.setBigUint64(0, BigInt(this.cqbCount), true) } createSpan (traceId, parentId) { @@ -1162,6 +1163,10 @@ describe('pipeline', { skip }, () => { }) it('returns collapsed span count when stats cardinality overflows', async () => { + // The resource field has its own cardinality limit (1024) and collapses to a placeholder long + // before the whole-key limit (~7000) is reached, so varying it no longer overflows the key at all. + // `service` has no per-field limit, so distinct services still overflow the whole key -- which is + // what `collapsedSpans` counts. const http = require('node:http') const seen = [] const server = http.createServer((req, res) => { @@ -1183,8 +1188,8 @@ describe('pipeline', { skip }, () => { for (let i = 0; i < 15_000; i++) { const span = ns.createSpan() span.name = 'stats-span' - span.service = 'stats-svc' - span.resource = `/stats/${i}` + span.service = `stats-svc-${i}` + span.resource = '/stats' span.type = 'web' span.setTag('span.kind', 'server') span.duration = 5_000_000n diff --git a/test/remote-config.js b/test/remote-config.js new file mode 100644 index 00000000..a5e94524 --- /dev/null +++ b/test/remote-config.js @@ -0,0 +1,284 @@ +'use strict' + +const assert = require('node:assert') +const { createHash } = require('node:crypto') +const { execFileSync } = require('node:child_process') +const { createServer } = require('node:http') +const { test } = require('node:test') + +const libdatadog = require('..') +const { RemoteConfigFetcher } = libdatadog.load('remote_config') +assert(RemoteConfigFetcher !== undefined) + +const APPLY_STATE_ACKNOWLEDGED = 2 +const APPLY_STATE_ERROR = 3 + +const CONFIG_PATH = 'datadog/2/ASM_FEATURES/asm-features-1/config' + +/** + * Builds a `/v0.7/config` response body: a base64 encoded TUF-like `targets` document plus the + * base64 encoded files themselves, which is what the agent sends. + */ +function agentResponse (configs, targetsVersion) { + const targets = {} + const targetFiles = [] + + for (const { path, file, version } of configs) { + const raw = Buffer.from(JSON.stringify(file), 'utf8') + targets[path] = { + custom: { v: version }, + hashes: { sha256: createHash('sha256').update(raw).digest('hex') }, + length: raw.length, + } + targetFiles.push({ path, raw: raw.toString('base64') }) + } + + return JSON.stringify({ + client_configs: configs.map(({ path }) => path), + targets: Buffer.from(JSON.stringify({ + signatures: [], + signed: { + _type: 'targets', + custom: { agent_refresh_interval: 5, opaque_backend_state: `backend-state-${targetsVersion}` }, + expires: '2100-01-01T00:00:00.000000000Z', + spec_version: '1.0.0', + targets, + version: targetsVersion, + }, + }), 'utf8').toString('base64'), + target_files: targetFiles, + }) +} + +function fetcherOptions (overrides) { + return { + clientId: 'client-id-1', + runtimeId: 'runtime-id-1', + service: 'my_svc', + env: 'my_env', + appVersion: '1.0.0', + tags: ['runtime-id:runtime-id-1'], + processTags: ['entrypoint.type:script'], + language: 'nodejs', + tracerVersion: '1.2.3', + url: 'http://127.0.0.1:8126', + timeoutMs: 5000, + ...overrides, + } +} + +async function withAgent (run) { + const requests = [] + const responses = [] + + const server = createServer((req, res) => { + const chunks = [] + req + .on('data', chunk => chunks.push(chunk)) + .on('end', () => { + requests.push(JSON.parse(Buffer.concat(chunks).toString('utf8'))) + res.writeHead(200, { 'content-type': 'application/json' }) + res.end(responses.shift() ?? '{}') + }) + }) + + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) + + const fetcher = new RemoteConfigFetcher(fetcherOptions({ + url: `http://127.0.0.1:${server.address().port}`, + })) + + try { + await run({ fetcher, requests, responses }) + } finally { + await new Promise(resolve => server.close(resolve)) + } +} + +test('reports the client identity, products and capabilities', async () => { + await withAgent(async ({ fetcher, requests }) => { + fetcher.setProductCapabilities(['ASM_FEATURES', 'ASM_DD'], ['ASM_ACTIVATION', 'ASM_DD_RULES']) + fetcher.setExtraServices(['other_svc']) + + assert.deepStrictEqual(await fetcher.fetchChanges(), []) + + const { client } = requests[0] + + assert.strictEqual(client.id, 'client-id-1') + assert.strictEqual(client.is_tracer, true) + assert.deepStrictEqual(client.products, ['ASM_FEATURES', 'ASM_DD']) + // Bits 1 (ASM_ACTIVATION) and 3 (ASM_DD_RULES) of a big-endian octet string. + assert.deepStrictEqual(client.capabilities, [0b1010]) + assert.strictEqual(client.client_tracer.language, 'nodejs') + assert.strictEqual(client.client_tracer.service, 'my_svc') + assert.deepStrictEqual(client.client_tracer.extra_services, ['other_svc']) + assert.deepStrictEqual(client.client_tracer.process_tags, ['entrypoint.type:script']) + }) +}) + +test('diffs successive polls into add, update and remove changes', async () => { + await withAgent(async ({ fetcher, responses }) => { + fetcher.setProductCapabilities(['ASM_FEATURES'], []) + + responses.push(agentResponse([{ path: CONFIG_PATH, file: { asm: { enabled: true } }, version: 1 }], 1)) + + const added = await fetcher.fetchChanges() + assert.strictEqual(added.length, 1) + assert.strictEqual(added[0].kind, 'add') + assert.strictEqual(added[0].path, CONFIG_PATH) + assert.strictEqual(added[0].product, 'ASM_FEATURES') + assert.strictEqual(added[0].configId, 'asm-features-1') + assert.strictEqual(added[0].name, 'config') + assert.strictEqual(added[0].version, 1) + assert.deepStrictEqual(JSON.parse(added[0].contents), { asm: { enabled: true } }) + + // An unchanged config is not reported again. + responses.push(agentResponse([{ path: CONFIG_PATH, file: { asm: { enabled: true } }, version: 1 }], 2)) + assert.deepStrictEqual(await fetcher.fetchChanges(), []) + + responses.push(agentResponse([{ path: CONFIG_PATH, file: { asm: { enabled: false } }, version: 2 }], 3)) + + const updated = await fetcher.fetchChanges() + assert.strictEqual(updated.length, 1) + assert.strictEqual(updated[0].kind, 'update') + assert.strictEqual(updated[0].version, 2) + assert.deepStrictEqual(JSON.parse(updated[0].contents), { asm: { enabled: false } }) + + responses.push(agentResponse([], 4)) + + const removed = await fetcher.fetchChanges() + assert.strictEqual(removed.length, 1) + assert.strictEqual(removed[0].kind, 'remove') + assert.strictEqual(removed[0].path, CONFIG_PATH) + assert.strictEqual(removed[0].contents, undefined) + }) +}) + +test('sends the apply state set for a config on the next poll', async () => { + await withAgent(async ({ fetcher, requests, responses }) => { + fetcher.setProductCapabilities(['ASM_FEATURES'], []) + + responses.push(agentResponse([{ path: CONFIG_PATH, file: { asm: { enabled: true } }, version: 1 }], 1)) + await fetcher.fetchChanges() + + fetcher.setConfigState(CONFIG_PATH, APPLY_STATE_ERROR, 'Error: could not apply') + + responses.push(agentResponse([{ path: CONFIG_PATH, file: { asm: { enabled: true } }, version: 1 }], 2)) + await fetcher.fetchChanges() + + assert.deepStrictEqual(requests[1].client.state.config_states, [{ + id: 'asm-features-1', + version: 1, + product: 'ASM_FEATURES', + apply_state: APPLY_STATE_ERROR, + apply_error: 'Error: could not apply', + }]) + assert.deepStrictEqual(requests[1].cached_target_files, [{ + path: CONFIG_PATH, + length: 24, + hashes: [{ + algorithm: 'sha256', + hash: createHash('sha256').update(JSON.stringify({ asm: { enabled: true } })).digest('hex'), + }], + }]) + + fetcher.setConfigState(CONFIG_PATH, APPLY_STATE_ACKNOWLEDGED, '') + + responses.push(agentResponse([{ path: CONFIG_PATH, file: { asm: { enabled: true } }, version: 1 }], 3)) + await fetcher.fetchChanges() + + assert.strictEqual(requests[2].client.state.config_states[0].apply_state, APPLY_STATE_ACKNOWLEDGED) + assert.strictEqual(requests[2].client.state.config_states[0].apply_error, '') + }) +}) + +test('skips unknown products and capabilities, and rejects bad apply states', async () => { + await withAgent(async ({ fetcher }) => { + // Names this build does not know are skipped and returned, so that a tracer whose own lists + // have moved ahead of libdatadog's keeps working with the names that do resolve. + assert.deepStrictEqual( + fetcher.setProductCapabilities(['ASM_FEATURES', 'NOT_A_PRODUCT'], ['ASM_ACTIVATION', 'NOT_A_CAPABILITY']), + ['NOT_A_PRODUCT', 'NOT_A_CAPABILITY'], + ) + + assert.throws(() => fetcher.setConfigState(CONFIG_PATH, 42, ''), { message: /Unknown apply state 42/ }) + assert.throws(() => fetcher.setConfigState('nonsense', APPLY_STATE_ACKNOWLEDGED, '')) + }) +}) + +test('polls on a runtime without a WebCrypto global', () => { + // libdatadog identifies the client with a UUID, and `uuid`'s wasm RNG is bound to + // `globalThis.crypto` with no fallback -- a global Node only exposes inside a module from v20, so + // it panicked there and trapped the whole module. libdatadog draws those bytes through + // `getrandom` instead, which reaches Node's `crypto` module when the global is missing. + // + // Polling rather than constructing: the id is generated when the fetcher is built, which is + // deferred to the first poll, so a constructor alone proves nothing. A child process, because + // the global has to be absent before the module loads. + const script = ` + delete globalThis.crypto + if (globalThis.crypto !== undefined) throw new Error('could not hide the global') + const { createServer } = require('node:http') + const { RemoteConfigFetcher } = require(${JSON.stringify(require.resolve('..'))}).load('remote_config') + const server = createServer((req, res) => { res.writeHead(200); res.end('{}') }) + server.listen(0, '127.0.0.1', async () => { + const options = ${JSON.stringify(fetcherOptions())} + options.url = 'http://127.0.0.1:' + server.address().port + const changes = await new RemoteConfigFetcher(options).fetchChanges() + process.stdout.write('polled ' + JSON.stringify(changes)) + server.close() + }) + ` + + const out = execFileSync(process.execPath, ['-e', script], { encoding: 'utf8' }) + + assert.strictEqual(out, 'polled []') +}) + +test('rejects an agent url without a scheme and host', () => { + // libdatadog appends the remote config path to this URI and unwraps the result, so a scheme + // without an authority would panic -- and abort the process, since release builds do not unwind. + // `agent-host:8126` is the reachable shape: JavaScript's `new URL` accepts it too. + assert.throws( + () => new RemoteConfigFetcher(fetcherOptions({ url: 'agent-host:8126' })), + { message: /needs both a scheme and a host/ }, + ) +}) + +test('rejects a failed poll', async () => { + // Only the URL parsing is exercised here: no socket is listening, so the poll fails. + const fetcher = new RemoteConfigFetcher(fetcherOptions({ + url: 'unix:///tmp/definitely-not-a-datadog-apm-socket', + })) + + await assert.rejects(fetcher.fetchChanges()) +}) + +test('polls the backend directly when an api key is set', async () => { + const fetcher = new RemoteConfigFetcher(fetcherOptions({ + url: 'https://api.example.invalid', + apiKey: 'an-api-key', + hostname: 'my-host', + })) + + // The backend cannot be faked: its responses are verified against TUF roots embedded in + // libdatadog. What the failure does show is that the poll went to the configs endpoint derived + // from the site URL rather than to the URL itself, which only happens in agentless mode. + await assert.rejects(fetcher.fetchChanges(), { message: /config\.api\.example\.invalid/ }) +}) + +test('rejects an api key without an https site url', () => { + // Talking to the backend without the agent in between means there is no localhost hop to be + // plaintext on, so libdatadog refuses anything but https. + assert.throws( + () => new RemoteConfigFetcher(fetcherOptions({ apiKey: 'an-api-key', hostname: 'my-host' })), + { message: /agentless endpoint is invalid/ }, + ) +}) + +test('rejects an api key without a hostname', () => { + assert.throws( + () => new RemoteConfigFetcher(fetcherOptions({ url: 'https://api.example.invalid', apiKey: 'an-api-key' })), + { message: /hostname is empty/ }, + ) +}) diff --git a/test/wasm/sketches/index.js b/test/wasm/sketches/index.js new file mode 100644 index 00000000..dfae84f6 --- /dev/null +++ b/test/wasm/sketches/index.js @@ -0,0 +1,29 @@ +'use strict' + +const assert = require('node:assert') + +const loader = require('../../../load') +const { DDSketch } = loader.load('sketches') + +const sketch = new DDSketch() +assert.strictEqual(sketch.count(), 0) + +sketch.add(1) +sketch.addWithCount(2, 3) +assert.strictEqual(sketch.count(), 4) + +assert.throws(() => sketch.add(-1), /point is invalid/) +assert.throws(() => sketch.addWithCount(1, Number.NaN), /count is invalid/) + +const encoded = sketch.encode() +assert(encoded instanceof Uint8Array) +assert(encoded.length > 0) + +assert.strictEqual(sketch.count(), 4) +sketch.add(3) +assert.strictEqual(sketch.count(), 5) + +const reencoded = sketch.encode() +assert(reencoded instanceof Uint8Array) +assert(reencoded.length > 0) +assert.strictEqual(sketch.count(), 5) diff --git a/yarn.lock b/yarn.lock index 5c4d745d..d8f55992 100644 --- a/yarn.lock +++ b/yarn.lock @@ -41,26 +41,26 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== -"@eslint/config-array@^0.23.3": - version "0.23.3" - resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.23.3.tgz#3f4a93dd546169c09130cbd10f2415b13a20a219" - integrity sha512-j+eEWmB6YYLwcNOdlwQ6L2OsptI/LO6lNBuLIqe5R7RetD658HLoF+Mn7LzYmAWWNNzdC6cqP+L6r8ujeYXWLw== +"@eslint/config-array@^0.23.5": + version "0.23.5" + resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.23.5.tgz#56e86d243049195d8acc0c06a1b3dfdc3fa3de95" + integrity sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA== dependencies: - "@eslint/object-schema" "^3.0.3" + "@eslint/object-schema" "^3.0.5" debug "^4.3.1" minimatch "^10.2.4" -"@eslint/config-helpers@^0.5.2": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.5.3.tgz#721fe6bbb90d74b0c80d6ff2428e5bbcb002becb" - integrity sha512-lzGN0onllOZCGroKJmRwY6QcEHxbjBw1gwB8SgRSqK8YbbtEXMvKynsXc3553ckIEBxsbMBU7oOZXKIPGZNeZw== +"@eslint/config-helpers@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.6.0.tgz#ef9a36881d39dfd5dbeac22b0da997fabfb08b03" + integrity sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA== dependencies: - "@eslint/core" "^1.1.1" + "@eslint/core" "^1.2.1" -"@eslint/core@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-1.1.1.tgz#450f3d2be2d463ccd51119544092256b4e88df32" - integrity sha512-QUPblTtE51/7/Zhfv8BDwO0qkkzQL7P/aWWbqcf4xWLEYn1oKjdO0gglQBB4GAsu7u6wjijbCmzsUTy6mnk6oQ== +"@eslint/core@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@eslint/core/-/core-1.2.1.tgz#c1da7cd1b82fa8787f98b5629fb811848a1b63ce" + integrity sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ== dependencies: "@types/json-schema" "^7.0.15" @@ -69,17 +69,17 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-10.0.1.tgz#1e8a876f50117af8ab67e47d5ad94d38d6622583" integrity sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA== -"@eslint/object-schema@^3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-3.0.3.tgz#5bf671e52e382e4adc47a9906f2699374637db6b" - integrity sha512-iM869Pugn9Nsxbh/YHRqYiqd23AmIbxJOcpUMOuWCVNdoQJ5ZtwL6h3t0bcZzJUlC3Dq9jCFCESBZnX0GTv7iQ== +"@eslint/object-schema@^3.0.5": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-3.0.5.tgz#88e9bf4d11d2b19c082e78ebe7ce88724a5eb091" + integrity sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw== -"@eslint/plugin-kit@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.6.1.tgz#eb9e6689b56ce8bc1855bb33090e63f3fc115e8e" - integrity sha512-iH1B076HoAshH1mLpHMgwdGeTs0CYwL0SPMkGuSebZrwBp16v415e9NZXg2jtrqPVQjf6IANe2Vtlr5KswtcZQ== +"@eslint/plugin-kit@^0.7.2": + version "0.7.2" + resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz#4b0962f3f2c7ce8bc98b3ecfe34525c09d2cb729" + integrity sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A== dependencies: - "@eslint/core" "^1.1.1" + "@eslint/core" "^1.2.1" levn "^0.4.1" "@humanfs/core@^0.19.1": @@ -105,386 +105,6 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba" integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== -"@inquirer/ansi@^2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@inquirer/ansi/-/ansi-2.0.7.tgz#86de22810cac3ed406ec10f8d66016815b8226b4" - integrity sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q== - -"@inquirer/checkbox@^5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@inquirer/checkbox/-/checkbox-5.2.1.tgz#7f148b3153a776cee202015b10f9a985068d188d" - integrity sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw== - dependencies: - "@inquirer/ansi" "^2.0.7" - "@inquirer/core" "^11.2.1" - "@inquirer/figures" "^2.0.7" - "@inquirer/type" "^4.0.7" - -"@inquirer/confirm@^6.1.1": - version "6.1.1" - resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-6.1.1.tgz#9c6a7d79c6132b2af57fdb75747f056204e55356" - integrity sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ== - dependencies: - "@inquirer/core" "^11.2.1" - "@inquirer/type" "^4.0.7" - -"@inquirer/core@^11.2.1": - version "11.2.1" - resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-11.2.1.tgz#54ccd8f7d47852140b6066cbd77d63b2c2b168fd" - integrity sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA== - dependencies: - "@inquirer/ansi" "^2.0.7" - "@inquirer/figures" "^2.0.7" - "@inquirer/type" "^4.0.7" - cli-width "^4.1.0" - fast-wrap-ansi "^0.2.0" - mute-stream "^3.0.0" - signal-exit "^4.1.0" - -"@inquirer/editor@^5.2.2": - version "5.2.2" - resolved "https://registry.yarnpkg.com/@inquirer/editor/-/editor-5.2.2.tgz#7c73e2fc0e7bd4c40cfd38a180ae5bbd24d32b90" - integrity sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg== - dependencies: - "@inquirer/core" "^11.2.1" - "@inquirer/external-editor" "^3.0.3" - "@inquirer/type" "^4.0.7" - -"@inquirer/expand@^5.1.1": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@inquirer/expand/-/expand-5.1.1.tgz#e2afeac247d97dd64ee18aa81e902bdd1fe0ea70" - integrity sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g== - dependencies: - "@inquirer/core" "^11.2.1" - "@inquirer/type" "^4.0.7" - -"@inquirer/external-editor@^3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@inquirer/external-editor/-/external-editor-3.0.3.tgz#d79e772542cf8d340642e9dabd3a1ea7f5a30104" - integrity sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA== - dependencies: - chardet "^2.1.1" - iconv-lite "^0.7.2" - -"@inquirer/figures@^2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-2.0.7.tgz#f5cc5843732a81304d06a0db4b53cc7dbda15541" - integrity sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw== - -"@inquirer/input@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@inquirer/input/-/input-5.1.2.tgz#9305cb170dfc3a5323e5eac885a945e7cddd5c4b" - integrity sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg== - dependencies: - "@inquirer/core" "^11.2.1" - "@inquirer/type" "^4.0.7" - -"@inquirer/number@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@inquirer/number/-/number-4.1.1.tgz#b133668d8e0e099b4133abb915221501e0ff75d7" - integrity sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA== - dependencies: - "@inquirer/core" "^11.2.1" - "@inquirer/type" "^4.0.7" - -"@inquirer/password@^5.1.1": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@inquirer/password/-/password-5.1.1.tgz#f21efb614da9c905095262f51781fd2a721fceac" - integrity sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg== - dependencies: - "@inquirer/ansi" "^2.0.7" - "@inquirer/core" "^11.2.1" - "@inquirer/type" "^4.0.7" - -"@inquirer/prompts@^8.5.2": - version "8.5.2" - resolved "https://registry.yarnpkg.com/@inquirer/prompts/-/prompts-8.5.2.tgz#09c0132ada2bbba94c91d341115e1e41cb3f1525" - integrity sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g== - dependencies: - "@inquirer/checkbox" "^5.2.1" - "@inquirer/confirm" "^6.1.1" - "@inquirer/editor" "^5.2.2" - "@inquirer/expand" "^5.1.1" - "@inquirer/input" "^5.1.2" - "@inquirer/number" "^4.1.1" - "@inquirer/password" "^5.1.1" - "@inquirer/rawlist" "^5.3.1" - "@inquirer/search" "^4.2.1" - "@inquirer/select" "^5.2.1" - -"@inquirer/rawlist@^5.3.1": - version "5.3.1" - resolved "https://registry.yarnpkg.com/@inquirer/rawlist/-/rawlist-5.3.1.tgz#66f6b8e6aa82d47399c433b8262128e7c1a4f9ce" - integrity sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og== - dependencies: - "@inquirer/core" "^11.2.1" - "@inquirer/type" "^4.0.7" - -"@inquirer/search@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@inquirer/search/-/search-4.2.1.tgz#c8f4b78ab3f866fdf0503fac0cd08c4a6661c11e" - integrity sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g== - dependencies: - "@inquirer/core" "^11.2.1" - "@inquirer/figures" "^2.0.7" - "@inquirer/type" "^4.0.7" - -"@inquirer/select@^5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@inquirer/select/-/select-5.2.1.tgz#3a05e76e58d9e1bb095e912c3e7093aa04cd4604" - integrity sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw== - dependencies: - "@inquirer/ansi" "^2.0.7" - "@inquirer/core" "^11.2.1" - "@inquirer/figures" "^2.0.7" - "@inquirer/type" "^4.0.7" - -"@inquirer/type@^4.0.7": - version "4.0.7" - resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-4.0.7.tgz#9c6f0d857fe6ad549a3a932343b64e76acb34b10" - integrity sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g== - -"@napi-rs/cli@^3.6.0": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@napi-rs/cli/-/cli-3.7.2.tgz#4a43d7bc7703159da0de1a7e3b1cd94141132b10" - integrity sha512-shDW0Td/XZQpP04Yy+OsMt1ILMKGGkoLcy1zVAsSAK0fLfWm0Upgkmfs/NOV2ZhMQwkgpR3ZEdyHmTwgrUDQuA== - dependencies: - "@inquirer/prompts" "^8.5.2" - "@napi-rs/cross-toolchain" "^1.0.3" - "@napi-rs/wasm-tools" "^1.0.1" - "@octokit/rest" "^22.0.1" - clipanion "^4.0.0-rc.4" - colorette "^2.0.20" - emnapi "^1.11.1" - es-toolkit "^1.47.0" - js-yaml "^4.2.0" - obug "^2.1.2" - semver "^7.8.2" - typanion "^3.14.0" - -"@napi-rs/cross-toolchain@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@napi-rs/cross-toolchain/-/cross-toolchain-1.0.3.tgz#8e345d0c9a8aeeaf9287e7af1d4ce83476681373" - integrity sha512-ENPfLe4937bsKVTDA6zdABx4pq9w0tHqRrJHyaGxgaPq03a2Bd1unD5XSKjXJjebsABJ+MjAv1A2OvCgK9yehg== - dependencies: - "@napi-rs/lzma" "^1.4.5" - "@napi-rs/tar" "^1.1.0" - debug "^4.4.1" - -"@napi-rs/lzma-android-arm-eabi@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-android-arm-eabi/-/lzma-android-arm-eabi-1.4.5.tgz#c6722a1d7201e269fdb6ba997d28cb41223e515c" - integrity sha512-Up4gpyw2SacmyKWWEib06GhiDdF+H+CCU0LAV8pnM4aJIDqKKd5LHSlBht83Jut6frkB0vwEPmAkv4NjQ5u//Q== - -"@napi-rs/lzma-android-arm64@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-android-arm64/-/lzma-android-arm64-1.4.5.tgz#05df61667e84419e0550200b48169057b734806f" - integrity sha512-uwa8sLlWEzkAM0MWyoZJg0JTD3BkPknvejAFG2acUA1raXM8jLrqujWCdOStisXhqQjZ2nDMp3FV6cs//zjfuQ== - -"@napi-rs/lzma-darwin-arm64@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-darwin-arm64/-/lzma-darwin-arm64-1.4.5.tgz#c37a01c53f25cb7f014870d2ea6c5576138bcaaa" - integrity sha512-0Y0TQLQ2xAjVabrMDem1NhIssOZzF/y/dqetc6OT8mD3xMTDtF8u5BqZoX3MyPc9FzpsZw4ksol+w7DsxHrpMA== - -"@napi-rs/lzma-darwin-x64@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-darwin-x64/-/lzma-darwin-x64-1.4.5.tgz#555b1dd65d7b104d28b2a12d925d7059226c7f4b" - integrity sha512-vR2IUyJY3En+V1wJkwmbGWcYiT8pHloTAWdW4pG24+51GIq+intst6Uf6D/r46citObGZrlX0QvMarOkQeHWpw== - -"@napi-rs/lzma-freebsd-x64@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-freebsd-x64/-/lzma-freebsd-x64-1.4.5.tgz#683beff15b37774ec91e1de7b4d337894bf43694" - integrity sha512-XpnYQC5SVovO35tF0xGkbHYjsS6kqyNCjuaLQ2dbEblFRr5cAZVvsJ/9h7zj/5FluJPJRDojVNxGyRhTp4z2lw== - -"@napi-rs/lzma-linux-arm-gnueabihf@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-arm-gnueabihf/-/lzma-linux-arm-gnueabihf-1.4.5.tgz#505f659a9131474b7270afa4a4e9caf709c4d213" - integrity sha512-ic1ZZMoRfRMwtSwxkyw4zIlbDZGC6davC9r+2oX6x9QiF247BRqqT94qGeL5ZP4Vtz0Hyy7TEViWhx5j6Bpzvw== - -"@napi-rs/lzma-linux-arm64-gnu@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-arm64-gnu/-/lzma-linux-arm64-gnu-1.4.5.tgz#ecbb944635fa004a9415d1f50f165bc0d26d3807" - integrity sha512-asEp7FPd7C1Yi6DQb45a3KPHKOFBSfGuJWXcAd4/bL2Fjetb2n/KK2z14yfW8YC/Fv6x3rBM0VAZKmJuz4tysg== - -"@napi-rs/lzma-linux-arm64-musl@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-arm64-musl/-/lzma-linux-arm64-musl-1.4.5.tgz#c0d17f40ce2db0b075469a28f233fd8ce31fbb95" - integrity sha512-yWjcPDgJ2nIL3KNvi4536dlT/CcCWO0DUyEOlBs/SacG7BeD6IjGh6yYzd3/X1Y3JItCbZoDoLUH8iB1lTXo3w== - -"@napi-rs/lzma-linux-ppc64-gnu@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-ppc64-gnu/-/lzma-linux-ppc64-gnu-1.4.5.tgz#2f17b9d1fc920c6c511d2086c7623752172c2f07" - integrity sha512-0XRhKuIU/9ZjT4WDIG/qnX7Xz7mSQHYZo9Gb3MP2gcvBgr6BA4zywQ9k3gmQaPn9ECE+CZg2V7DV7kT+x2pUMQ== - -"@napi-rs/lzma-linux-riscv64-gnu@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-riscv64-gnu/-/lzma-linux-riscv64-gnu-1.4.5.tgz#63c2a4e1157586252186e39604370d5b29c6db85" - integrity sha512-QrqDIPEUUB23GCpyQj/QFyMlr8SGxxyExeZz9OWFnHfb70kXdTLWrHS/hEI1Ru+lSbQ/6xRqeoGyQ4Aqdg+/RA== - -"@napi-rs/lzma-linux-s390x-gnu@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-s390x-gnu/-/lzma-linux-s390x-gnu-1.4.5.tgz#6f2ca44bf5c5bef1b31d7516bf15d63c35cdf59f" - integrity sha512-k8RVM5aMhW86E9H0QXdquwojew4H3SwPxbRVbl49/COJQWCUjGi79X6mYruMnMPEznZinUiT1jgKbFo2A00NdA== - -"@napi-rs/lzma-linux-x64-gnu@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.4.5.tgz#54879d88a9c370687b5463c7c1b6208b718c1ab2" - integrity sha512-6rMtBgnIq2Wcl1rQdZsnM+rtCcVCbws1nF8S2NzaUsVaZv8bjrPiAa0lwg4Eqnn1d9lgwqT+cZgm5m+//K08Kw== - -"@napi-rs/lzma-linux-x64-musl@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-linux-x64-musl/-/lzma-linux-x64-musl-1.4.5.tgz#412705f6925f10f45122bd0f3e2fb6e597bed4f8" - integrity sha512-eiadGBKi7Vd0bCArBUOO/qqRYPHt/VQVvGyYvDFt6C2ZSIjlD+HuOl+2oS1sjf4CFjK4eDIog6EdXnL0NE6iyQ== - -"@napi-rs/lzma-wasm32-wasi@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-wasm32-wasi/-/lzma-wasm32-wasi-1.4.5.tgz#4b74abfd144371123cb6f5b7bad5bae868206ecf" - integrity sha512-+VyHHlr68dvey6fXc2hehw9gHVFIW3TtGF1XkcbAu65qVXsA9D/T+uuoRVqhE+JCyFHFrO0ixRbZDRK1XJt1sA== - dependencies: - "@napi-rs/wasm-runtime" "^1.0.3" - -"@napi-rs/lzma-win32-arm64-msvc@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-win32-arm64-msvc/-/lzma-win32-arm64-msvc-1.4.5.tgz#7ed8c80d588fa244a7fd55249cb0d011d04bf984" - integrity sha512-eewnqvIyyhHi3KaZtBOJXohLvwwN27gfS2G/YDWdfHlbz1jrmfeHAmzMsP5qv8vGB+T80TMHNkro4kYjeh6Deg== - -"@napi-rs/lzma-win32-ia32-msvc@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-win32-ia32-msvc/-/lzma-win32-ia32-msvc-1.4.5.tgz#e6f70ca87bd88370102aa610ee9e44ec28911b46" - integrity sha512-OeacFVRCJOKNU/a0ephUfYZ2Yt+NvaHze/4TgOwJ0J0P4P7X1mHzN+ig9Iyd74aQDXYqc7kaCXA2dpAOcH87Cg== - -"@napi-rs/lzma-win32-x64-msvc@1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma-win32-x64-msvc/-/lzma-win32-x64-msvc-1.4.5.tgz#ecfcfe364e805915608ce0ff41ed4c950fdb51b8" - integrity sha512-T4I1SamdSmtyZgDXGAGP+y5LEK5vxHUFwe8mz6D4R7Sa5/WCxTcCIgPJ9BD7RkpO17lzhlaM2vmVvMy96Lvk9Q== - -"@napi-rs/lzma@^1.4.5": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@napi-rs/lzma/-/lzma-1.4.5.tgz#43e17cdfe332a3f33fa640422da348db3d8825e1" - integrity sha512-zS5LuN1OBPAyZpda2ZZgYOEDC+xecUdAGnrvbYzjnLXkrq/OBC3B9qcRvlxbDR3k5H/gVfvef1/jyUqPknqjbg== - optionalDependencies: - "@napi-rs/lzma-android-arm-eabi" "1.4.5" - "@napi-rs/lzma-android-arm64" "1.4.5" - "@napi-rs/lzma-darwin-arm64" "1.4.5" - "@napi-rs/lzma-darwin-x64" "1.4.5" - "@napi-rs/lzma-freebsd-x64" "1.4.5" - "@napi-rs/lzma-linux-arm-gnueabihf" "1.4.5" - "@napi-rs/lzma-linux-arm64-gnu" "1.4.5" - "@napi-rs/lzma-linux-arm64-musl" "1.4.5" - "@napi-rs/lzma-linux-ppc64-gnu" "1.4.5" - "@napi-rs/lzma-linux-riscv64-gnu" "1.4.5" - "@napi-rs/lzma-linux-s390x-gnu" "1.4.5" - "@napi-rs/lzma-linux-x64-gnu" "1.4.5" - "@napi-rs/lzma-linux-x64-musl" "1.4.5" - "@napi-rs/lzma-wasm32-wasi" "1.4.5" - "@napi-rs/lzma-win32-arm64-msvc" "1.4.5" - "@napi-rs/lzma-win32-ia32-msvc" "1.4.5" - "@napi-rs/lzma-win32-x64-msvc" "1.4.5" - -"@napi-rs/tar-android-arm-eabi@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-android-arm-eabi/-/tar-android-arm-eabi-1.1.0.tgz#08ae6ebbaf38d416954a28ca09bf77410d5b0c2b" - integrity sha512-h2Ryndraj/YiKgMV/r5by1cDusluYIRT0CaE0/PekQ4u+Wpy2iUVqvzVU98ZPnhXaNeYxEvVJHNGafpOfaD0TA== - -"@napi-rs/tar-android-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-android-arm64/-/tar-android-arm64-1.1.0.tgz#825a76140116f89d7e930245bda9f70b196da565" - integrity sha512-DJFyQHr1ZxNZorm/gzc1qBNLF/FcKzcH0V0Vwan5P+o0aE2keQIGEjJ09FudkF9v6uOuJjHCVDdK6S6uHtShAw== - -"@napi-rs/tar-darwin-arm64@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-darwin-arm64/-/tar-darwin-arm64-1.1.0.tgz#8821616c40ea52ec2c00a055be56bf28dee76013" - integrity sha512-Zz2sXRzjIX4e532zD6xm2SjXEym6MkvfCvL2RMpG2+UwNVDVscHNcz3d47Pf3sysP2e2af7fBB3TIoK2f6trPw== - -"@napi-rs/tar-darwin-x64@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-darwin-x64/-/tar-darwin-x64-1.1.0.tgz#4a975e41932a145c58181cb43c8f483c3858e359" - integrity sha512-EI+CptIMNweT0ms9S3mkP/q+J6FNZ1Q6pvpJOEcWglRfyfQpLqjlC0O+dptruTPE8VamKYuqdjxfqD8hifZDOA== - -"@napi-rs/tar-freebsd-x64@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-freebsd-x64/-/tar-freebsd-x64-1.1.0.tgz#5ebc0633f257b258aacc59ac1420835513ed0967" - integrity sha512-J0PIqX+pl6lBIAckL/c87gpodLbjZB1OtIK+RDscKC9NLdpVv6VGOxzUV/fYev/hctcE8EfkLbgFOfpmVQPg2g== - -"@napi-rs/tar-linux-arm-gnueabihf@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-linux-arm-gnueabihf/-/tar-linux-arm-gnueabihf-1.1.0.tgz#1d309bd4f46f0490353d9608e79d260cf6c7cd43" - integrity sha512-SLgIQo3f3EjkZ82ZwvrEgFvMdDAhsxCYjyoSuWfHCz0U16qx3SuGCp8+FYOPYCECHN3ZlGjXnoAIt9ERd0dEUg== - -"@napi-rs/tar-linux-arm64-gnu@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-linux-arm64-gnu/-/tar-linux-arm64-gnu-1.1.0.tgz#88d974821f3f8e9ee6948b4d51c78c019dee88ad" - integrity sha512-d014cdle52EGaH6GpYTQOP9Py7glMO1zz/+ynJPjjzYFSxvdYx0byrjumZk2UQdIyGZiJO2MEFpCkEEKFSgPYA== - -"@napi-rs/tar-linux-arm64-musl@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-linux-arm64-musl/-/tar-linux-arm64-musl-1.1.0.tgz#ab2baee7b288df5e68cef0b2d12fa79d2a551b58" - integrity sha512-L/y1/26q9L/uBqiW/JdOb/Dc94egFvNALUZV2WCGKQXc6UByPBMgdiEyW2dtoYxYYYYc+AKD+jr+wQPcvX2vrQ== - -"@napi-rs/tar-linux-ppc64-gnu@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-linux-ppc64-gnu/-/tar-linux-ppc64-gnu-1.1.0.tgz#7500e60d27849ba36fa4802a346249974e7ecf74" - integrity sha512-EPE1K/80RQvPbLRJDJs1QmCIcH+7WRi0F73+oTe1582y9RtfGRuzAkzeBuAGRXAQEjRQw/RjtNqr6UTJ+8UuWQ== - -"@napi-rs/tar-linux-s390x-gnu@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-linux-s390x-gnu/-/tar-linux-s390x-gnu-1.1.0.tgz#cfc0923bfad1dea8ef9da22148a8d4932aa52d08" - integrity sha512-B2jhWiB1ffw1nQBqLUP1h4+J1ovAxBOoe5N2IqDMOc63fsPZKNqF1PvO/dIem8z7LL4U4bsfmhy3gBfu547oNQ== - -"@napi-rs/tar-linux-x64-gnu@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-linux-x64-gnu/-/tar-linux-x64-gnu-1.1.0.tgz#5fdf9e1bb12b10a951c6ab03268a9f8d9788c929" - integrity sha512-tbZDHnb9617lTnsDMGo/eAMZxnsQFnaRe+MszRqHguKfMwkisc9CCJnks/r1o84u5fECI+J/HOrKXgczq/3Oww== - -"@napi-rs/tar-linux-x64-musl@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-linux-x64-musl/-/tar-linux-x64-musl-1.1.0.tgz#f001fc0a0a2996dcf99e787a15eade8dce215e91" - integrity sha512-dV6cODlzbO8u6Anmv2N/ilQHq/AWz0xyltuXoLU3yUyXbZcnWYZuB2rL8OBGPmqNcD+x9NdScBNXh7vWN0naSQ== - -"@napi-rs/tar-wasm32-wasi@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-wasm32-wasi/-/tar-wasm32-wasi-1.1.0.tgz#c1c7df7738b23f1cdbcff261d5bea6968d0a3c9a" - integrity sha512-jIa9nb2HzOrfH0F8QQ9g3WE4aMH5vSI5/1NYVNm9ysCmNjCCtMXCAhlI3WKCdm/DwHf0zLqdrrtDFXODcNaqMw== - dependencies: - "@napi-rs/wasm-runtime" "^1.0.3" - -"@napi-rs/tar-win32-arm64-msvc@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-win32-arm64-msvc/-/tar-win32-arm64-msvc-1.1.0.tgz#4c8519eab28021e1eda0847433cab949d5389833" - integrity sha512-vfpG71OB0ijtjemp3WTdmBKJm9R70KM8vsSExMsIQtV0lVzP07oM1CW6JbNRPXNLhRoue9ofYLiUDk8bE0Hckg== - -"@napi-rs/tar-win32-ia32-msvc@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-win32-ia32-msvc/-/tar-win32-ia32-msvc-1.1.0.tgz#4f61af0da2c53b23f7d58c77970eaa4449e8eb79" - integrity sha512-hGPyPW60YSpOSgzfy68DLBHgi6HxkAM+L59ZZZPMQ0TOXjQg+p2EW87+TjZfJOkSpbYiEkULwa/f4a2hcVjsqQ== - -"@napi-rs/tar-win32-x64-msvc@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar-win32-x64-msvc/-/tar-win32-x64-msvc-1.1.0.tgz#eb63fb44ecde001cce6be238f175e66a06c15035" - integrity sha512-L6Ed1DxXK9YSCMyvpR8MiNAyKNkQLjsHsHK9E0qnHa8NzLFqzDKhvs5LfnWxM2kJ+F7m/e5n9zPm24kHb3LsVw== - -"@napi-rs/tar@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@napi-rs/tar/-/tar-1.1.0.tgz#acecd9e29f705a3f534d5fb3d8aa36b3266727d0" - integrity sha512-7cmzIu+Vbupriudo7UudoMRH2OA3cTw67vva8MxeoAe5S7vPFI7z0vp0pMXiA25S8IUJefImQ90FeJjl8fjEaQ== - optionalDependencies: - "@napi-rs/tar-android-arm-eabi" "1.1.0" - "@napi-rs/tar-android-arm64" "1.1.0" - "@napi-rs/tar-darwin-arm64" "1.1.0" - "@napi-rs/tar-darwin-x64" "1.1.0" - "@napi-rs/tar-freebsd-x64" "1.1.0" - "@napi-rs/tar-linux-arm-gnueabihf" "1.1.0" - "@napi-rs/tar-linux-arm64-gnu" "1.1.0" - "@napi-rs/tar-linux-arm64-musl" "1.1.0" - "@napi-rs/tar-linux-ppc64-gnu" "1.1.0" - "@napi-rs/tar-linux-s390x-gnu" "1.1.0" - "@napi-rs/tar-linux-x64-gnu" "1.1.0" - "@napi-rs/tar-linux-x64-musl" "1.1.0" - "@napi-rs/tar-wasm32-wasi" "1.1.0" - "@napi-rs/tar-win32-arm64-msvc" "1.1.0" - "@napi-rs/tar-win32-ia32-msvc" "1.1.0" - "@napi-rs/tar-win32-x64-msvc" "1.1.0" - "@napi-rs/wasm-runtime@^0.2.11": version "0.2.12" resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" @@ -494,199 +114,6 @@ "@emnapi/runtime" "^1.4.3" "@tybys/wasm-util" "^0.10.0" -"@napi-rs/wasm-runtime@^1.0.3": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz#cccd6ebc40b991dea6936f9126b1b8155b6c4c95" - integrity sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q== - dependencies: - "@tybys/wasm-util" "^0.10.2" - -"@napi-rs/wasm-tools-android-arm-eabi@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-android-arm-eabi/-/wasm-tools-android-arm-eabi-1.0.1.tgz#a709f93ddd95508a4ef949b5ceff2b2e85b676f7" - integrity sha512-lr07E/l571Gft5v4aA1dI8koJEmF1F0UigBbsqg9OWNzg80H3lDPO+auv85y3T/NHE3GirDk7x/D3sLO57vayw== - -"@napi-rs/wasm-tools-android-arm64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-android-arm64/-/wasm-tools-android-arm64-1.0.1.tgz#304b5761b4fcc871b876ebd34975c72c9d11a7fc" - integrity sha512-WDR7S+aRLV6LtBJAg5fmjKkTZIdrEnnQxgdsb7Cf8pYiMWBHLU+LC49OUVppQ2YSPY0+GeYm9yuZWW3kLjJ7Bg== - -"@napi-rs/wasm-tools-darwin-arm64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-darwin-arm64/-/wasm-tools-darwin-arm64-1.0.1.tgz#dafb4330986a8b46e8de1603ea2f6932a19634c6" - integrity sha512-qWTI+EEkiN0oIn/N2gQo7+TVYil+AJ20jjuzD2vATS6uIjVz+Updeqmszi7zq7rdFTLp6Ea3/z4kDKIfZwmR9g== - -"@napi-rs/wasm-tools-darwin-x64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-darwin-x64/-/wasm-tools-darwin-x64-1.0.1.tgz#0919e63714ee0a52b1120f6452bbc3a4d793ce3c" - integrity sha512-bA6hubqtHROR5UI3tToAF/c6TDmaAgF0SWgo4rADHtQ4wdn0JeogvOk50gs2TYVhKPE2ZD2+qqt7oBKB+sxW3A== - -"@napi-rs/wasm-tools-freebsd-x64@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-freebsd-x64/-/wasm-tools-freebsd-x64-1.0.1.tgz#1f50a2d5d5af041c55634f43f623ae49192bce9c" - integrity sha512-90+KLBkD9hZEjPQW1MDfwSt5J1L46EUKacpCZWyRuL6iIEO5CgWU0V/JnEgFsDOGyyYtiTvHc5bUdUTWd4I9Vg== - -"@napi-rs/wasm-tools-linux-arm64-gnu@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-linux-arm64-gnu/-/wasm-tools-linux-arm64-gnu-1.0.1.tgz#6106d5e65a25ec2ae417c2fcfebd5c8f14d80e84" - integrity sha512-rG0QlS65x9K/u3HrKafDf8cFKj5wV2JHGfl8abWgKew0GVPyp6vfsDweOwHbWAjcHtp2LHi6JHoW80/MTHm52Q== - -"@napi-rs/wasm-tools-linux-arm64-musl@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-linux-arm64-musl/-/wasm-tools-linux-arm64-musl-1.0.1.tgz#0eb3d4d1fbc1938b0edd907423840365ebc53859" - integrity sha512-jAasbIvjZXCgX0TCuEFQr+4D6Lla/3AAVx2LmDuMjgG4xoIXzjKWl7c4chuaD+TI+prWT0X6LJcdzFT+ROKGHQ== - -"@napi-rs/wasm-tools-linux-x64-gnu@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-linux-x64-gnu/-/wasm-tools-linux-x64-gnu-1.0.1.tgz#5de6a567083a83efed16d046f47b680cbe7c9b53" - integrity sha512-Plgk5rPqqK2nocBGajkMVbGm010Z7dnUgq0wtnYRZbzWWxwWcXfZMPa8EYxrK4eE8SzpI7VlZP1tdVsdjgGwMw== - -"@napi-rs/wasm-tools-linux-x64-musl@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-linux-x64-musl/-/wasm-tools-linux-x64-musl-1.0.1.tgz#04cc17ef12b4e5012f2d0e46b09cabe473566e5a" - integrity sha512-GW7AzGuWxtQkyHknHWYFdR0CHmW6is8rG2Rf4V6GNmMpmwtXt/ItWYWtBe4zqJWycMNazpfZKSw/BpT7/MVCXQ== - -"@napi-rs/wasm-tools-wasm32-wasi@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-wasm32-wasi/-/wasm-tools-wasm32-wasi-1.0.1.tgz#6ced3bd03428c854397f00509b1694c3af857a0f" - integrity sha512-/nQVSTrqSsn7YdAc2R7Ips/tnw5SPUcl3D7QrXCNGPqjbatIspnaexvaOYNyKMU6xPu+pc0BTnKVmqhlJJCPLA== - dependencies: - "@napi-rs/wasm-runtime" "^1.0.3" - -"@napi-rs/wasm-tools-win32-arm64-msvc@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-win32-arm64-msvc/-/wasm-tools-win32-arm64-msvc-1.0.1.tgz#e776f66eb637eee312b562e987c0a5871ddc6dac" - integrity sha512-PFi7oJIBu5w7Qzh3dwFea3sHRO3pojMsaEnUIy22QvsW+UJfNQwJCryVrpoUt8m4QyZXI+saEq/0r4GwdoHYFQ== - -"@napi-rs/wasm-tools-win32-ia32-msvc@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-win32-ia32-msvc/-/wasm-tools-win32-ia32-msvc-1.0.1.tgz#9167919a62d24cb3a46f01fada26fee38aeaf884" - integrity sha512-gXkuYzxQsgkj05Zaq+KQTkHIN83dFAwMcTKa2aQcpYPRImFm2AQzEyLtpXmyCWzJ0F9ZYAOmbSyrNew8/us6bw== - -"@napi-rs/wasm-tools-win32-x64-msvc@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools-win32-x64-msvc/-/wasm-tools-win32-x64-msvc-1.0.1.tgz#f896ab29a83605795bb12cf2cfc1a215bc830c65" - integrity sha512-rEAf05nol3e3eei2sRButmgXP+6ATgm0/38MKhz9Isne82T4rPIMYsCIFj0kOisaGeVwoi2fnm7O9oWp5YVnYQ== - -"@napi-rs/wasm-tools@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-tools/-/wasm-tools-1.0.1.tgz#f54caa0132322fd5275690b2aeb581d11539262f" - integrity sha512-enkZYyuCdo+9jneCPE/0fjIta4wWnvVN9hBo2HuiMpRF0q3lzv1J6b/cl7i0mxZUKhBrV3aCKDBQnCOhwKbPmQ== - optionalDependencies: - "@napi-rs/wasm-tools-android-arm-eabi" "1.0.1" - "@napi-rs/wasm-tools-android-arm64" "1.0.1" - "@napi-rs/wasm-tools-darwin-arm64" "1.0.1" - "@napi-rs/wasm-tools-darwin-x64" "1.0.1" - "@napi-rs/wasm-tools-freebsd-x64" "1.0.1" - "@napi-rs/wasm-tools-linux-arm64-gnu" "1.0.1" - "@napi-rs/wasm-tools-linux-arm64-musl" "1.0.1" - "@napi-rs/wasm-tools-linux-x64-gnu" "1.0.1" - "@napi-rs/wasm-tools-linux-x64-musl" "1.0.1" - "@napi-rs/wasm-tools-wasm32-wasi" "1.0.1" - "@napi-rs/wasm-tools-win32-arm64-msvc" "1.0.1" - "@napi-rs/wasm-tools-win32-ia32-msvc" "1.0.1" - "@napi-rs/wasm-tools-win32-x64-msvc" "1.0.1" - -"@octokit/auth-token@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-6.0.0.tgz#b02e9c08a2d8937df09a2a981f226ad219174c53" - integrity sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w== - -"@octokit/core@^7.0.6": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-7.0.6.tgz#0d58704391c6b681dec1117240ea4d2a98ac3916" - integrity sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q== - dependencies: - "@octokit/auth-token" "^6.0.0" - "@octokit/graphql" "^9.0.3" - "@octokit/request" "^10.0.6" - "@octokit/request-error" "^7.0.2" - "@octokit/types" "^16.0.0" - before-after-hook "^4.0.0" - universal-user-agent "^7.0.0" - -"@octokit/endpoint@^11.0.3": - version "11.0.3" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-11.0.3.tgz#acf5f7feddde4e12185d5312ee38ff77235d8205" - integrity sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag== - dependencies: - "@octokit/types" "^16.0.0" - universal-user-agent "^7.0.2" - -"@octokit/graphql@^9.0.3": - version "9.0.3" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-9.0.3.tgz#5b8341c225909e924b466705c13477face869456" - integrity sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA== - dependencies: - "@octokit/request" "^10.0.6" - "@octokit/types" "^16.0.0" - universal-user-agent "^7.0.0" - -"@octokit/openapi-types@^27.0.0": - version "27.0.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-27.0.0.tgz#374ea53781965fd02a9d36cacb97e152cefff12d" - integrity sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA== - -"@octokit/plugin-paginate-rest@^14.0.0": - version "14.0.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz#44dc9fff2dacb148d4c5c788b573ddc044503026" - integrity sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw== - dependencies: - "@octokit/types" "^16.0.0" - -"@octokit/plugin-request-log@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz#de1c1e557df6c08adb631bf78264fa741e01b317" - integrity sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q== - -"@octokit/plugin-rest-endpoint-methods@^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz#8c54397d3a4060356a1c8a974191ebf945924105" - integrity sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw== - dependencies: - "@octokit/types" "^16.0.0" - -"@octokit/request-error@^7.0.2": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-7.1.0.tgz#440fa3cae310466889778f5a222b47a580743638" - integrity sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw== - dependencies: - "@octokit/types" "^16.0.0" - -"@octokit/request@^10.0.6": - version "10.0.10" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-10.0.10.tgz#45e46934f3d772f006733be6b5ec18f22e54a00c" - integrity sha512-KxNC2pTqqhszMNrf12ZRd4PonRgyJdsM4F/jySiddQK+DsRcfBtUvqn8t7UsyZhnRJHvX46OohDt5N3VqIWC2w== - dependencies: - "@octokit/endpoint" "^11.0.3" - "@octokit/request-error" "^7.0.2" - "@octokit/types" "^16.0.0" - content-type "^2.0.0" - json-with-bigint "^3.5.3" - universal-user-agent "^7.0.2" - -"@octokit/rest@^22.0.1": - version "22.0.1" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-22.0.1.tgz#4d866c32b76b711d3f736f91992e2b534163b416" - integrity sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw== - dependencies: - "@octokit/core" "^7.0.6" - "@octokit/plugin-paginate-rest" "^14.0.0" - "@octokit/plugin-request-log" "^6.0.0" - "@octokit/plugin-rest-endpoint-methods" "^17.0.0" - -"@octokit/types@^16.0.0": - version "16.0.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-16.0.0.tgz#fbd7fa590c2ef22af881b1d79758bfaa234dbb7c" - integrity sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg== - dependencies: - "@octokit/openapi-types" "^27.0.0" - -"@package-json/types@^0.0.12": - version "0.0.12" - resolved "https://registry.yarnpkg.com/@package-json/types/-/types-0.0.12.tgz#4629e833ba128ed9880b6b7a947633ee22952462" - integrity sha512-uu43FGU34B5VM9mCNjXCwLaGHYjXdNincqKLaraaCW+7S2+SmiBg1Nv8bPnmschrIfZmfKNY9f3fC376MRrObw== - "@stylistic/eslint-plugin@^5.9.0": version "5.10.0" resolved "https://registry.yarnpkg.com/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz#471bbd9f7a27ceaac4a217e7f5b3890855e5640c" @@ -706,13 +133,6 @@ dependencies: tslib "^2.4.0" -"@tybys/wasm-util@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.2.tgz#12b3a1b33db1f9cad4ddff1f604ab7dd00bf464e" - integrity sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg== - dependencies: - tslib "^2.4.0" - "@types/esrecurse@^4.3.1": version "4.3.1" resolved "https://registry.yarnpkg.com/@types/esrecurse/-/esrecurse-4.3.1.tgz#6f636af962fbe6191b830bd676ba5986926bccec" @@ -850,11 +270,6 @@ ajv@^6.14.0: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - balanced-match@^4.0.2: version "4.0.4" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" @@ -865,15 +280,10 @@ baseline-browser-mapping@^2.9.0: resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz#5b09935025bf8a80e29130251e337c6a7fc8cbb9" integrity sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA== -before-after-hook@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-4.0.0.tgz#cf1447ab9160df6a40f3621da64d6ffc36050cb9" - integrity sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ== - brace-expansion@^5.0.2: - version "5.0.4" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.4.tgz#614daaecd0a688f660bbbc909a8748c3d80d4336" - integrity sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg== + version "5.0.9" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.9.tgz#7c72438809b5fa5babf54199a1f1c281a6984fcf" + integrity sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg== dependencies: balanced-match "^4.0.2" @@ -903,11 +313,6 @@ change-case@^5.4.4: resolved "https://registry.yarnpkg.com/change-case/-/change-case-5.4.4.tgz#0d52b507d8fb8f204343432381d1a6d7bff97a02" integrity sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w== -chardet@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-2.1.1.tgz#5c75593704a642f71ee53717df234031e65373c8" - integrity sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ== - ci-info@^4.3.1: version "4.4.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.4.0.tgz#7d54eff9f54b45b62401c26032696eb59c8bd18c" @@ -920,33 +325,11 @@ clean-regexp@^1.0.0: dependencies: escape-string-regexp "^1.0.5" -cli-width@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" - integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== - -clipanion@^4.0.0-rc.4: - version "4.0.0-rc.4" - resolved "https://registry.yarnpkg.com/clipanion/-/clipanion-4.0.0-rc.4.tgz#7191a940e47ef197e5f18c9cbbe419278b5f5903" - integrity sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q== - dependencies: - typanion "^3.8.0" - -colorette@^2.0.20: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - comment-parser@^1.4.1: version "1.4.5" resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.4.5.tgz#6c595cd090737a1010fe5ff40d86e1d21b7bd6ce" integrity sha512-aRDkn3uyIlCFfk5NUA+VdwMmMsh8JGhc4hapfV4yxymHGQ3BVskMQfoXGpCo5IoBuQ9tS5iiVKhCpTcB4pW4qw== -content-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-2.0.0.tgz#2fb3ede69dffa0af78ca7c4ce7589680638b56df" - integrity sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ== - core-js-compat@^3.46.0: version "3.48.0" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.48.0.tgz#7efbe1fc1cbad44008190462217cc5558adaeaa6" @@ -980,11 +363,6 @@ electron-to-chromium@^1.5.263: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.307.tgz#09f8973100c39fb0d003b890393cd1d58932b1c8" integrity sha512-5z3uFKBWjiNR44nFcYdkcXjKMbg5KXNdciu7mhTPo9tB7NbqSNP2sSnGR+fqknZSCwKkBN+oxiiajWs4dT6ORg== -emnapi@^1.11.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/emnapi/-/emnapi-1.11.1.tgz#9f3da4463d61a89822ac902f95a3e324adfd340e" - integrity sha512-kSRjhIcxjMFsBqk7ORvoc9aA5SBKDmecrtF5RMcmOTao0kD/zamaxsuTxMI8C1//wGUuvE7a+19pCE7AEhGVnA== - enhanced-resolve@^5.17.1: version "5.20.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.20.0.tgz#323c2a70d2aa7fb4bdfd6d3c24dfc705c581295d" @@ -993,11 +371,6 @@ enhanced-resolve@^5.17.1: graceful-fs "^4.2.4" tapable "^2.3.0" -es-toolkit@^1.47.0: - version "1.47.1" - resolved "https://registry.yarnpkg.com/es-toolkit/-/es-toolkit-1.47.1.tgz#6f049fef04c2ef27400e8f38255a0dca323e1c3a" - integrity sha512-5RAqEwf4P4E17p+W75KLOWw/nOvKZzSQpxM32IpI2KZLaVonjTrZ0Ai5ghMaVI9eKC2p8eoQgcBdkEDgzFk6+Q== - escalade@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" @@ -1037,12 +410,11 @@ eslint-plugin-es-x@^7.8.0: "@eslint-community/regexpp" "^4.11.0" eslint-compat-utils "^0.5.1" -eslint-plugin-import-x@^4.12.2: - version "4.16.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.2.tgz#95d1f798795566712c87897317ef8433d101db29" - integrity sha512-rM9K8UBHcWKpzQzStn1YRN2T5NvdeIfSVoKu/lKF41znQXHAUcBbYXe5wd6GNjZjTrP7viQ49n1D83x/2gYgIw== +eslint-plugin-import-x@^4.17.1: + version "4.17.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import-x/-/eslint-plugin-import-x-4.17.1.tgz#6e9211acd8e98d2da11f96c12c9c00aa49e3e035" + integrity sha512-4cdstYkKCyjumM2Q9NSI03K8D2a9F4Ssz33K2lv2hQa4KmR9jPLwk3uWGtNvclfqBrPGfGuMBwsGMbe6dMRbfg== dependencies: - "@package-json/types" "^0.0.12" "@typescript-eslint/types" "^8.56.0" comment-parser "^1.4.1" debug "^4.4.1" @@ -1115,17 +487,17 @@ eslint-visitor-keys@^5.0.1: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz#9e3c9489697824d2d4ce3a8ad12628f91e9f59be" integrity sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA== -eslint@^10.0.2: - version "10.0.3" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-10.0.3.tgz#360a7de7f2706eb8a32caa17ca983f0089efe694" - integrity sha512-COV33RzXZkqhG9P2rZCFl9ZmJ7WL+gQSCRzE7RhkbclbQPtLAWReL7ysA0Sh4c8Im2U9ynybdR56PV0XcKvqaQ== +eslint@^10.6.0: + version "10.6.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-10.6.0.tgz#e1b4059c582be950c7088c9b55f984738b243c27" + integrity sha512-6lVbcqSodALYo+4ELD0heG6lFiFxnLMuLkiMi2qV8LMp54N8tE8FT1GMH+ev4Ti00nFjNze2+Su6DsV5OQW3Dg== dependencies: "@eslint-community/eslint-utils" "^4.8.0" "@eslint-community/regexpp" "^4.12.2" - "@eslint/config-array" "^0.23.3" - "@eslint/config-helpers" "^0.5.2" - "@eslint/core" "^1.1.1" - "@eslint/plugin-kit" "^0.6.1" + "@eslint/config-array" "^0.23.5" + "@eslint/config-helpers" "^0.6.0" + "@eslint/core" "^1.2.1" + "@eslint/plugin-kit" "^0.7.2" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/retry" "^0.4.2" @@ -1136,7 +508,7 @@ eslint@^10.0.2: escape-string-regexp "^4.0.0" eslint-scope "^9.1.2" eslint-visitor-keys "^5.0.1" - espree "^11.1.1" + espree "^11.2.0" esquery "^1.7.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -1160,7 +532,7 @@ espree@^10.4.0: acorn-jsx "^5.3.2" eslint-visitor-keys "^4.2.1" -espree@^11.1.1: +espree@^11.2.0: version "11.2.0" resolved "https://registry.yarnpkg.com/espree/-/espree-11.2.0.tgz#01d5e47dc332aaba3059008362454a8cc34ccaa5" integrity sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw== @@ -1208,25 +580,6 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== -fast-string-truncated-width@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz#23afe0da67d752ca0727538f1e6967759728ce49" - integrity sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g== - -fast-string-width@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/fast-string-width/-/fast-string-width-3.0.2.tgz#16dbabb491ce5585b5ecb675b65c165d71688eeb" - integrity sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg== - dependencies: - fast-string-truncated-width "^3.0.2" - -fast-wrap-ansi@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz#95e952a0145bce3f59ad56e179f84c48d4072935" - integrity sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q== - dependencies: - fast-string-width "^3.0.2" - file-entry-cache@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" @@ -1256,9 +609,9 @@ flat-cache@^4.0.0: keyv "^4.5.4" flatted@^3.2.9: - version "3.4.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.1.tgz#84ccd9579e76e9cc0d246c11d8be0beb019143e6" - integrity sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ== + version "3.4.2" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.2.tgz#f5c23c107f0f37de8dbdf24f13722b3b98d52726" + integrity sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA== get-tsconfig@^4.10.1, get-tsconfig@^4.8.1: version "4.13.6" @@ -1284,10 +637,10 @@ globals@^16.4.0: resolved "https://registry.yarnpkg.com/globals/-/globals-16.5.0.tgz#ccf1594a437b97653b2be13ed4d8f5c9f850cac1" integrity sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ== -globals@^17.4.0: - version "17.4.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-17.4.0.tgz#33d7d297ed1536b388a0e2f4bcd0ff19c8ff91b5" - integrity sha512-hjrNztw/VajQwOLsMNT1cbJiH2muO3OROCHnbehc8eY5JyD2gqz4AcMHPqgaOR59DjgUjYAYLeH699g/eWi2jw== +globals@^17.7.0: + version "17.7.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-17.7.0.tgz#553d55090b4dde8209ec2da42580d6e7e7d8b10d" + integrity sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg== globrex@^0.1.2: version "0.1.2" @@ -1299,13 +652,6 @@ graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -iconv-lite@^0.7.2: - version "0.7.2" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.2.tgz#d0bdeac3f12b4835b7359c2ad89c422a4d1cc72e" - integrity sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - ignore@^5.2.0, ignore@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" @@ -1345,13 +691,6 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -js-yaml@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.2.0.tgz#2bd9e85682dd91bd469afb809d816043b3d49524" - integrity sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw== - dependencies: - argparse "^2.0.1" - jsesc@^3.1.0, jsesc@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" @@ -1372,11 +711,6 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json-with-bigint@^3.5.3: - version "3.5.8" - resolved "https://registry.yarnpkg.com/json-with-bigint/-/json-with-bigint-3.5.8.tgz#1b1edb55a1bc4816ca87ac684297591acd822383" - integrity sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw== - keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -1411,11 +745,6 @@ ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mute-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-3.0.0.tgz#cd8014dd2acb72e1e91bb67c74f0019e620ba2d1" - integrity sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw== - napi-postinstall@^0.3.0: version "0.3.4" resolved "https://registry.yarnpkg.com/napi-postinstall/-/napi-postinstall-0.3.4.tgz#7af256d6588b5f8e952b9190965d6b019653bbb9" @@ -1431,11 +760,6 @@ node-releases@^2.0.27: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.36.tgz#99fd6552aaeda9e17c4713b57a63964a2e325e9d" integrity sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA== -obug@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/obug/-/obug-2.1.3.tgz#c02c60f95abd603409330e767db7f2823193331e" - integrity sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg== - optionator@^0.9.3: version "0.9.4" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" @@ -1478,9 +802,9 @@ picocolors@^1.1.1: integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== picomatch@^4.0.2, picomatch@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" - integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== + version "4.0.4" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589" + integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== pluralize@^8.0.0: version "8.0.0" @@ -1514,21 +838,11 @@ resolve-pkg-maps@^1.0.0: resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== -"safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - semver@^7.5.4, semver@^7.6.3, semver@^7.7.2, semver@^7.7.3: version "7.7.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== -semver@^7.8.2: - version "7.8.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.8.4.tgz#c73eceebae0616934be8dff28a7fd70757c8e696" - integrity sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA== - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -1541,11 +855,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - stable-hash-x@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/stable-hash-x/-/stable-hash-x-0.2.0.tgz#dfd76bfa5d839a7470125c6a6b3c8b22061793e9" @@ -1573,11 +882,6 @@ tslib@^2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== -typanion@^3.14.0, typanion@^3.8.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/typanion/-/typanion-3.14.0.tgz#a766a91810ce8258033975733e836c43a2929b94" - integrity sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug== - type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -1585,11 +889,6 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -universal-user-agent@^7.0.0, universal-user-agent@^7.0.2: - version "7.0.3" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-7.0.3.tgz#c05870a58125a2dc00431f2df815a77fe69736be" - integrity sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A== - unrs-resolver@^1.9.2: version "1.11.1" resolved "https://registry.yarnpkg.com/unrs-resolver/-/unrs-resolver-1.11.1.tgz#be9cd8686c99ef53ecb96df2a473c64d304048a9"