From 8e5588e3fee1c49747fbc95a09461fd0d9e60fda Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 17:53:04 +0200 Subject: [PATCH 01/20] chore(deps): bump the gh-actions-packages group across 1 directory with 3 updates (#139) Bumps the gh-actions-packages group with 3 updates in the / directory: [actions/checkout](https://github.com/actions/checkout), [actions/setup-node](https://github.com/actions/setup-node) and [DataDog/dd-octo-sts-action](https://github.com/datadog/dd-octo-sts-action). Updates `actions/checkout` from 6.0.2 to 7.0.0 - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/de0fac2e4500dabe0009e67214ff5f5447ce83dd...9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0) Updates `actions/setup-node` from 6.3.0 to 6.4.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/53b83947a5a98c8d113130e565377fae1a50d02f...48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e) Updates `DataDog/dd-octo-sts-action` from 1.0.3 to 1.0.4 - [Release notes](https://github.com/datadog/dd-octo-sts-action/releases) - [Commits](https://github.com/datadog/dd-octo-sts-action/compare/acaa02eee7e3bb0839e4272dacb37b8f3b58ba80...96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: gh-actions-packages - dependency-name: actions/setup-node dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gh-actions-packages - dependency-name: DataDog/dd-octo-sts-action dependency-version: 1.0.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gh-actions-packages ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 10 +++++----- .github/workflows/release.yml | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 52dc405c..1019981b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,9 +10,9 @@ 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 @@ -27,7 +27,7 @@ jobs: - datadog-js-zstd - pipeline 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: @@ -52,10 +52,10 @@ jobs: 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..f5ce2754 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,7 +15,7 @@ jobs: - datadog-js-zstd - pipeline 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: @@ -41,19 +41,19 @@ jobs: 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 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 - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: prebuilds path: prebuilds - - uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 with: node-version: '24' registry-url: 'https://registry.npmjs.org' From eae9a3f4172118a89231a0ed1a78750f3522daa5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 17:54:04 +0200 Subject: [PATCH 02/20] chore(deps): bump libdd-crashtracker from v35.0.0 to v37.0.0 (#147) Bumps [libdd-crashtracker](https://github.com/DataDog/libdatadog) from v35.0.0 to v37.0.0. - [Release notes](https://github.com/DataDog/libdatadog/releases) - [Commits](https://github.com/DataDog/libdatadog/compare/aa78483fba211c72ca3759c76318895f45e0184b...86b7f5700d3db4e58076794b5e8073a40d780083) --- updated-dependencies: - dependency-name: libdd-crashtracker dependency-version: b2a83ff19a2f4760d180bd9eb9e91f41566ba5b9 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 322 ++++++++++++++++++++------------- crates/crashtracker/Cargo.toml | 2 +- 2 files changed, 202 insertions(+), 122 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d852cbf4..ba662688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -181,6 +181,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" @@ -214,6 +220,16 @@ dependencies = [ "cc", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -697,7 +713,6 @@ dependencies = [ "hyper", "hyper-util", "rustls", - "rustls-native-certs", "tokio", "tokio-rustls", "tower-service", @@ -780,6 +795,50 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[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", + "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", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -838,7 +897,7 @@ dependencies = [ "futures-core", "http", "js-sys", - "libdd-capabilities 2.1.0", + "libdd-capabilities", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", @@ -847,18 +906,7 @@ dependencies = [ [[package]] name = "libdd-capabilities" version = "2.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" -dependencies = [ - "anyhow", - "bytes", - "http", - "thiserror", -] - -[[package]] -name = "libdd-capabilities" -version = "2.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "anyhow", "bytes", @@ -869,33 +917,20 @@ dependencies = [ [[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-body-util", - "libdd-capabilities 2.0.0", - "libdd-common 4.2.0", - "tokio", -] - -[[package]] -name = "libdd-capabilities-impl" -version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" -dependencies = [ - "bytes", - "http", - "http-body-util", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", + "libdd-capabilities", + "libdd-common", "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", @@ -917,6 +952,7 @@ dependencies = [ "regex", "rustls", "rustls-native-certs", + "rustls-platform-verifier", "serde", "static_assertions", "thiserror", @@ -926,40 +962,10 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "libdd-common" -version = "5.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" -dependencies = [ - "anyhow", - "bytes", - "cc", - "const_format", - "futures", - "futures-core", - "futures-util", - "hex", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-util", - "libc", - "nix 0.29.0", - "pin-project", - "regex", - "serde", - "static_assertions", - "thiserror", - "tokio", - "tower-service", - "windows-sys 0.52.0", -] - [[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", @@ -968,7 +974,7 @@ dependencies = [ "errno", "http", "libc", - "libdd-common 4.2.0", + "libdd-common", "libdd-libunwind-sys", "libdd-telemetry", "nix 0.29.0", @@ -1002,12 +1008,12 @@ dependencies = [ "getrandom 0.2.17", "http", "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", + "libdd-capabilities-impl", + "libdd-common", + "libdd-ddsketch", "libdd-dogstatsd-client", - "libdd-shared-runtime 2.0.0", + "libdd-shared-runtime", "libdd-tinybytes", "libdd-trace-normalization", "libdd-trace-protobuf 4.0.0", @@ -1026,15 +1032,7 @@ dependencies = [ [[package]] name = "libdd-ddsketch" version = "1.0.1" -source = "git+https://github.com/DataDog/libdatadog.git?tag=v35.0.0#aa78483fba211c72ca3759c76318895f45e0184b" -dependencies = [ - "prost", -] - -[[package]] -name = "libdd-ddsketch" -version = "1.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "prost", ] @@ -1047,7 +1045,7 @@ dependencies = [ "anyhow", "cadence", "http", - "libdd-common 5.1.0", + "libdd-common", "serde", "tracing", ] @@ -1097,31 +1095,14 @@ dependencies = [ [[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", - "tokio", - "tokio-util", - "tracing", - "wasm-bindgen-futures", -] - -[[package]] -name = "libdd-shared-runtime" -version = "2.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" -dependencies = [ - "async-trait", - "futures", - "futures-util", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common", "tokio", "tokio-util", "tracing", @@ -1130,8 +1111,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", @@ -1142,9 +1123,9 @@ dependencies = [ "http", "http-body-util", "libc", - "libdd-common 4.2.0", - "libdd-ddsketch 1.0.1", - "libdd-shared-runtime 1.0.0", + "libdd-common", + "libdd-ddsketch", + "libdd-shared-runtime", "serde", "serde_json", "sys-info", @@ -1179,8 +1160,8 @@ source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e dependencies = [ "anyhow", "fluent-uri", - "libdd-common 5.1.0", - "libdd-trace-protobuf 4.0.0", + "libdd-common", + "libdd-trace-protobuf 3.0.2 (git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0)", "libdd-trace-utils", "log", "percent-encoding", @@ -1219,12 +1200,11 @@ dependencies = [ "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", - "libdd-dogstatsd-client", - "libdd-shared-runtime 2.0.0", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common", + "libdd-ddsketch", + "libdd-shared-runtime", "libdd-trace-obfuscation", "libdd-trace-protobuf 4.0.0", "libdd-trace-utils", @@ -1250,10 +1230,9 @@ dependencies = [ "http-body", "http-body-util", "indexmap", - "itoa", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", + "libdd-capabilities", + "libdd-capabilities-impl", + "libdd-common", "libdd-tinybytes", "libdd-trace-normalization", "libdd-trace-protobuf 4.0.0", @@ -1743,11 +1722,10 @@ dependencies = [ "http", "js-sys", "libdatadog-nodejs-capabilities", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", + "libdd-capabilities", "libdd-data-pipeline", - "libdd-shared-runtime 2.0.0", - "libdd-trace-protobuf 4.0.0", + "libdd-shared-runtime", + "libdd-trace-protobuf 3.0.2 (git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0)", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -2039,6 +2017,33 @@ 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" @@ -2671,6 +2676,15 @@ dependencies = [ "semver", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2828,6 +2842,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 +2869,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 +2932,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 +2956,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 +2980,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 +3016,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 +3040,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 +3064,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 +3088,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" 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"] } From 16a51ad9c8eb2a8702f655d65ea2426edfbffd90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jul 2026 17:56:43 +0200 Subject: [PATCH 03/20] chore(deps-dev): bump the minor-updates group across 1 directory with 3 updates (#142) Bumps the minor-updates group with 3 updates in the / directory: [eslint](https://github.com/eslint/eslint), [eslint-plugin-import-x](https://github.com/un-ts/eslint-plugin-import-x) and [globals](https://github.com/sindresorhus/globals). Updates `eslint` from 10.0.3 to 10.6.0 - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v10.0.3...v10.6.0) Updates `eslint-plugin-import-x` from 4.16.2 to 4.17.1 - [Release notes](https://github.com/un-ts/eslint-plugin-import-x/releases) - [Changelog](https://github.com/un-ts/eslint-plugin-import-x/blob/master/CHANGELOG.md) - [Commits](https://github.com/un-ts/eslint-plugin-import-x/compare/v4.16.2...v4.17.1) Updates `globals` from 17.4.0 to 17.7.0 - [Release notes](https://github.com/sindresorhus/globals/releases) - [Commits](https://github.com/sindresorhus/globals/compare/v17.4.0...v17.7.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.5.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor-updates - dependency-name: eslint-plugin-import-x dependency-version: 4.17.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor-updates - dependency-name: globals dependency-version: 17.7.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor-updates ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 6 +- yarn.lock | 783 +++------------------------------------------------ 2 files changed, 44 insertions(+), 745 deletions(-) diff --git a/package.json b/package.json index 6bd8a096..5450536c 100644 --- a/package.json +++ b/package.json @@ -32,10 +32,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/yarn.lock b/yarn.lock index 5c4d745d..f5ecefed 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,11 +280,6 @@ 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" @@ -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" @@ -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" @@ -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" From 4a617fe4825add4ee742156acb7821e72fccdfe2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:44:24 +0200 Subject: [PATCH 04/20] chore(deps): bump express from 4.22.1 to 5.2.1 in /test/crashtracker (#141) Bumps [express](https://github.com/expressjs/express) from 4.22.1 to 5.2.1. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/v4.22.1...v5.2.1) --- updated-dependencies: - dependency-name: express dependency-version: 5.2.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- test/crashtracker/package-lock.json | 594 ++++++++++++++++++++-------- test/crashtracker/package.json | 2 +- test/crashtracker/yarn.lock | 370 ++++++++++------- 3 files changed, 660 insertions(+), 306 deletions(-) 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== From 588c9310094c5cfc0e408ec099cb4591fa7bfa42 Mon Sep 17 00:00:00 2001 From: "gh-worker-campaigns-3e9aa4[bot]" <244854796+gh-worker-campaigns-3e9aa4[bot]@users.noreply.github.com> Date: Fri, 3 Jul 2026 09:47:48 +0200 Subject: [PATCH 05/20] ADMS: vuln patch: brace-expansion, flatted, picomatch (#133) Co-authored-by: gh-worker-campaigns-3e9aa4[bot] <244854796+gh-worker-campaigns-3e9aa4[bot]@users.noreply.github.com> --- yarn.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index f5ecefed..14dca938 100644 --- a/yarn.lock +++ b/yarn.lock @@ -280,10 +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== -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== +brace-expansion@^5.0.2, brace-expansion@^5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.6.tgz#ec68fe0a641a29d8711579caf641d05bae1f2285" + integrity sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g== dependencies: balanced-match "^4.0.2" @@ -608,10 +608,10 @@ flat-cache@^4.0.0: flatted "^3.2.9" 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== +flatted@^3.2.9, flatted@^3.4.2: + 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" @@ -801,10 +801,10 @@ picocolors@^1.1.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" 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== +picomatch@^4.0.2, picomatch@^4.0.3, picomatch@^4.0.4: + 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" From 1a718a8369acec102393a2b772a384ab67b70963 Mon Sep 17 00:00:00 2001 From: Jules Wiriath <53870805+Aaalibaba42@users.noreply.github.com> Date: Fri, 31 Jul 2026 17:27:38 +0200 Subject: [PATCH 06/20] feat: added file capability [APMSP-3780] (#177) * feat: added file capability * fix: JS tomfoolery * chore: change input to main now that libdatadog's side was merged * fix: post bump fixes * fix: review * fix: address comments * fix: detached buffer thing * fix: transport for files renamed, uniform lazy loading --- Cargo.lock | 127 ++++++++++++++++++--- crates/capabilities/Cargo.toml | 4 +- crates/capabilities/src/file.rs | 156 ++++++++++++++++++++++++++ crates/capabilities/src/filesystem.js | 38 +++++++ crates/capabilities/src/lib.rs | 55 +++++++-- crates/pipeline/Cargo.toml | 17 ++- crates/pipeline/src/stats.rs | 3 +- eslint.config.js | 6 +- test/filesystem.js | 51 +++++++++ test/pipeline.js | 43 +++---- yarn.lock | 6 +- 11 files changed, 439 insertions(+), 67 deletions(-) create mode 100644 crates/capabilities/src/file.rs create mode 100644 crates/capabilities/src/filesystem.js create mode 100644 test/filesystem.js diff --git a/Cargo.lock b/Cargo.lock index ba662688..dc2ca607 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -914,6 +914,17 @@ dependencies = [ "thiserror", ] +[[package]] +name = "libdd-capabilities" +version = "2.1.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +dependencies = [ + "anyhow", + "bytes", + "http", + "thiserror", +] + [[package]] name = "libdd-capabilities-impl" version = "2.0.0" @@ -922,8 +933,22 @@ dependencies = [ "bytes", "http", "http-body-util", - "libdd-capabilities", - "libdd-common", + "libdd-capabilities 2.0.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=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +dependencies = [ + "anyhow", + "bytes", + "http", + "http-body-util", + "libdd-capabilities 2.1.0", + "libdd-common 5.1.0", "tokio", ] @@ -962,6 +987,36 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "libdd-common" +version = "5.1.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +dependencies = [ + "anyhow", + "bytes", + "cc", + "const_format", + "futures", + "futures-core", + "futures-util", + "hex", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "libc", + "nix 0.29.0", + "pin-project", + "regex", + "serde", + "static_assertions", + "thiserror", + "tokio", + "tower-service", + "windows-sys 0.52.0", +] + [[package]] name = "libdd-crashtracker" version = "1.0.0" @@ -998,13 +1053,14 @@ dependencies = [ [[package]] name = "libdd-data-pipeline" version = "7.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "anyhow", "arc-swap", "async-trait", "bytes", "either", + "futures", "getrandom 0.2.17", "http", "http-body-util", @@ -1027,6 +1083,7 @@ dependencies = [ "tokio-util", "tracing", "uuid", + "web-time", ] [[package]] @@ -1037,10 +1094,18 @@ dependencies = [ "prost", ] +[[package]] +name = "libdd-ddsketch" +version = "1.1.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +dependencies = [ + "prost", +] + [[package]] name = "libdd-dogstatsd-client" version = "4.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "anyhow", "cadence", @@ -1100,9 +1165,26 @@ dependencies = [ "async-trait", "futures", "futures-util", - "libdd-capabilities", - "libdd-capabilities-impl", - "libdd-common", + "libdd-capabilities 2.0.0", + "libdd-capabilities-impl 2.0.0", + "libdd-common 5.0.0", + "tokio", + "tokio-util", + "tracing", + "wasm-bindgen-futures", +] + +[[package]] +name = "libdd-shared-runtime" +version = "2.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +dependencies = [ + "async-trait", + "futures", + "futures-util", + "libdd-capabilities 2.1.0", + "libdd-capabilities-impl 3.0.0", + "libdd-common 5.1.0", "tokio", "tokio-util", "tracing", @@ -1139,7 +1221,7 @@ dependencies = [ [[package]] name = "libdd-tinybytes" version = "1.1.1" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "serde", ] @@ -1147,7 +1229,7 @@ dependencies = [ [[package]] name = "libdd-trace-normalization" version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "anyhow", "libdd-trace-protobuf 4.0.0", @@ -1156,7 +1238,7 @@ dependencies = [ [[package]] name = "libdd-trace-obfuscation" version = "5.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "anyhow", "fluent-uri", @@ -1182,7 +1264,7 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" version = "4.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "prost", "serde", @@ -1192,7 +1274,7 @@ dependencies = [ [[package]] name = "libdd-trace-stats" version = "6.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=6356aee4c69b51f27e7e82e43b1797f60b74905a#6356aee4c69b51f27e7e82e43b1797f60b74905a" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "anyhow", "arc-swap", @@ -1213,12 +1295,13 @@ dependencies = [ "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" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "anyhow", "base64", @@ -1230,9 +1313,10 @@ dependencies = [ "http-body", "http-body-util", "indexmap", - "libdd-capabilities", - "libdd-capabilities-impl", - "libdd-common", + "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", @@ -1735,6 +1819,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", + "web-time", ] [[package]] @@ -2676,6 +2761,16 @@ dependencies = [ "semver", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webpki-root-certs" version = "1.0.8" diff --git a/crates/capabilities/Cargo.toml b/crates/capabilities/Cargo.toml index f468e7d5..edb40adc 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 = "3081603d3c74f209be4e3be951f78a1a7469397f" } [dev-dependencies] wasm-bindgen-test = "0.3" 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/lib.rs b/crates/capabilities/src/lib.rs index f7cb4b01..ebd385f3 100644 --- a/crates/capabilities/src/lib.rs +++ b/crates/capabilities/src/lib.rs @@ -12,27 +12,32 @@ use std::future::Future; use std::time::Duration; +use libdd_capabilities::file::{FileCapability, FileError, FileMetadata}; use libdd_capabilities::http::HttpError; use libdd_capabilities::{HttpClientCapability, LogWriterCapability, MaybeSend, SleepCapability}; +pub mod file; pub mod http; pub mod sleep; +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, } impl Default for WasmCapabilities { @@ -46,16 +51,14 @@ impl WasmCapabilities { Self { http: WasmHttpClient::new_client(), sleep: WasmSleepCapability, + file: WasmFileCapability, } } } impl HttpClientCapability for WasmCapabilities { fn new_client() -> Self { - Self { - http: WasmHttpClient::new_client(), - sleep: WasmSleepCapability, - } + Self::new() } fn request( @@ -68,10 +71,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 +89,36 @@ 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) + } +} + diff --git a/crates/pipeline/Cargo.toml b/crates/pipeline/Cargo.toml index c4440cf9..29fc2722 100644 --- a/crates/pipeline/Cargo.toml +++ b/crates/pipeline/Cargo.toml @@ -14,15 +14,14 @@ 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 = "3081603d3c74f209be4e3be951f78a1a7469397f" } +libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } +libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } +libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false, features = ["change-buffer"] } +libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } +libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } +libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } +web-time = "1" rmp-serde = "1" bytes = "1" http = "1" diff --git a/crates/pipeline/src/stats.rs b/crates/pipeline/src/stats.rs index 127a21e6..ac17a112 100644 --- a/crates/pipeline/src/stats.rs +++ b/crates/pipeline/src/stats.rs @@ -7,7 +7,7 @@ //! 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 @@ -67,6 +67,7 @@ impl StatsCollector { ], Vec::new(), None, + Vec::new(), ), meta, agent_url, diff --git a/eslint.config.js b/eslint.config.js index e7b67365..690debfb 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -80,9 +80,9 @@ 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'], + // 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', }, 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/pipeline.js b/test/pipeline.js index 15bbc797..8b62197f 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) { diff --git a/yarn.lock b/yarn.lock index 14dca938..85f5c9f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -280,7 +280,7 @@ 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== -brace-expansion@^5.0.2, brace-expansion@^5.0.6: +brace-expansion@^5.0.2: version "5.0.6" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.6.tgz#ec68fe0a641a29d8711579caf641d05bae1f2285" integrity sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g== @@ -608,7 +608,7 @@ flat-cache@^4.0.0: flatted "^3.2.9" keyv "^4.5.4" -flatted@^3.2.9, flatted@^3.4.2: +flatted@^3.2.9: version "3.4.2" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.4.2.tgz#f5c23c107f0f37de8dbdf24f13722b3b98d52726" integrity sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA== @@ -801,7 +801,7 @@ picocolors@^1.1.1: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== -picomatch@^4.0.2, picomatch@^4.0.3, picomatch@^4.0.4: +picomatch@^4.0.2, picomatch@^4.0.3: version "4.0.4" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589" integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== From b1dca31da20925895131f0dd3c85b0ff08962185 Mon Sep 17 00:00:00 2001 From: Jules Wiriath <53870805+Aaalibaba42@users.noreply.github.com> Date: Thu, 6 Aug 2026 16:01:23 +0200 Subject: [PATCH 07/20] feat: added env capability [APMSP-3780] (#176) * feat: added env capability * feat: respect envcapabilities method unsafedness * feat: validate before saying it's ok * revert: remove set/unset since they would be dangerous APIs in libdatadog (and are most likely not useful in the near/middel future in dd-trace-js) * chore: change input to main's commit that has the change * docs: update doc to remove specific references to the capabilities * fix: remove extra checks * fix: cache env beforehand --- Cargo.lock | 46 +++++++++--------------- crates/capabilities/src/env.rs | 28 +++++++++++++++ crates/capabilities/src/env_transport.js | 7 ++++ crates/capabilities/src/lib.rs | 21 ++++++++--- crates/library_config/Cargo.toml | 2 +- crates/process_discovery/Cargo.toml | 7 ++-- test/env-transport.js | 31 ++++++++++++++++ 7 files changed, 102 insertions(+), 40 deletions(-) create mode 100644 crates/capabilities/src/env.rs create mode 100644 crates/capabilities/src/env_transport.js create mode 100644 test/env-transport.js diff --git a/Cargo.lock b/Cargo.lock index dc2ca607..5a71b7a9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1072,7 +1072,7 @@ dependencies = [ "libdd-shared-runtime", "libdd-tinybytes", "libdd-trace-normalization", - "libdd-trace-protobuf 4.0.0", + "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -1117,26 +1117,12 @@ dependencies = [ [[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?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4#0c6e2a5df2a163d34c4f385353ffc5d7257c72f4" dependencies = [ "anyhow", "libc", - "libdd-trace-protobuf 3.0.2", + "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4)", "memfd", "prost", "rand", @@ -1232,7 +1218,7 @@ version = "3.0.0" source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" dependencies = [ "anyhow", - "libdd-trace-protobuf 4.0.0", + "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", ] [[package]] @@ -1242,8 +1228,8 @@ source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e dependencies = [ "anyhow", "fluent-uri", - "libdd-common", - "libdd-trace-protobuf 3.0.2 (git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0)", + "libdd-common 5.1.0", + "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", "libdd-trace-utils", "log", "percent-encoding", @@ -1253,8 +1239,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?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4#0c6e2a5df2a163d34c4f385353ffc5d7257c72f4" dependencies = [ "prost", "serde", @@ -1288,7 +1274,7 @@ dependencies = [ "libdd-ddsketch", "libdd-shared-runtime", "libdd-trace-obfuscation", - "libdd-trace-protobuf 4.0.0", + "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", "libdd-trace-utils", "rmp-serde", "serde", @@ -1319,7 +1305,7 @@ dependencies = [ "libdd-common 5.1.0", "libdd-tinybytes", "libdd-trace-normalization", - "libdd-trace-protobuf 4.0.0", + "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", "prost", "rand", "rmp", @@ -1356,7 +1342,7 @@ version = "0.2.0" dependencies = [ "anyhow", "getrandom 0.2.17", - "libdd-library-config 1.0.0", + "libdd-library-config", "serde", "serde-wasm-bindgen", "wasm-bindgen", @@ -1808,8 +1794,8 @@ dependencies = [ "libdatadog-nodejs-capabilities", "libdd-capabilities", "libdd-data-pipeline", - "libdd-shared-runtime", - "libdd-trace-protobuf 3.0.2 (git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0)", + "libdd-shared-runtime 2.0.0", + "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -1870,8 +1856,8 @@ 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 (git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4)", "napi", "napi-derive", ] 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/lib.rs b/crates/capabilities/src/lib.rs index ebd385f3..e76a3812 100644 --- a/crates/capabilities/src/lib.rs +++ b/crates/capabilities/src/lib.rs @@ -4,22 +4,24 @@ //! 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}; +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; @@ -38,6 +40,7 @@ pub struct WasmCapabilities { sleep: WasmSleepCapability, /// Filesystem access delegated to the Node.js `fs` transport. file: WasmFileCapability, + env: WasmEnvCapability, } impl Default for WasmCapabilities { @@ -52,6 +55,7 @@ impl WasmCapabilities { http: WasmHttpClient::new_client(), sleep: WasmSleepCapability, file: WasmFileCapability, + env: WasmEnvCapability, } } } @@ -122,3 +126,12 @@ impl FileCapability for WasmCapabilities { } } +impl EnvCapability for WasmCapabilities { + fn new() -> Self { + Self::new() + } + + fn get(&self, name: &str) -> Result, EnvError> { + self.env.get(name) + } +} diff --git a/crates/library_config/Cargo.toml b/crates/library_config/Cargo.toml index be76bd45..b6deab09 100644 --- a/crates/library_config/Cargo.toml +++ b/crates/library_config/Cargo.toml @@ -8,7 +8,7 @@ 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", rev = "0c6e2a5df2a163d34c4f385353ffc5d7257c72f4" } wasm-bindgen = "0.2.100" serde = { version = "1.0", features = ["derive"] } diff --git a/crates/process_discovery/Cargo.toml b/crates/process_discovery/Cargo.toml index 44042286..32e9449e 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", rev = "0c6e2a5df2a163d34c4f385353ffc5d7257c72f4", features = ["otel-thread-ctx"] } +libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "0c6e2a5df2a163d34c4f385353ffc5d7257c72f4" } napi = { version = "2" } napi-derive = { version = "2", default-features = false } 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') + }) +}) From f8107be54c3b05a47897ae7a6df37cc2c4ab2afa Mon Sep 17 00:00:00 2001 From: Ilyas Shabi Date: Mon, 10 Aug 2026 17:25:55 +0200 Subject: [PATCH 08/20] feat: add DDSketch WASM bindings (#198) * feat: add DDSketch WASM bindings --- .github/workflows/build.yml | 1 + .github/workflows/release.yml | 1 + Cargo.lock | 8 ++++++++ crates/sketches/Cargo.toml | 15 ++++++++++++++ crates/sketches/src/lib.rs | 37 +++++++++++++++++++++++++++++++++++ package.json | 2 +- test/wasm/sketches/index.js | 29 +++++++++++++++++++++++++++ 7 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 crates/sketches/Cargo.toml create mode 100644 crates/sketches/src/lib.rs create mode 100644 test/wasm/sketches/index.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1019981b..de179fb7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,6 +26,7 @@ jobs: - library_config - datadog-js-zstd - pipeline + - sketches steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 'Use composite action' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f5ce2754..7533785d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,6 +14,7 @@ jobs: - library_config - datadog-js-zstd - pipeline + - sketches steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 'Use composite action' diff --git a/Cargo.lock b/Cargo.lock index 5a71b7a9..11a3de2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2331,6 +2331,14 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +[[package]] +name = "sketches" +version = "0.1.0" +dependencies = [ + "libdd-ddsketch 1.1.0", + "wasm-bindgen", +] + [[package]] name = "slab" version = "0.4.12" diff --git a/crates/sketches/Cargo.toml b/crates/sketches/Cargo.toml new file mode 100644 index 00000000..6747f461 --- /dev/null +++ b/crates/sketches/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "sketches" +version = "0.1.0" +edition = "2021" +description = "Wasm bindings for Datadog's DDSketch" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +libdd-ddsketch = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f" } +wasm-bindgen = "0.2" + +[package.metadata.wasm-pack.profile.release] +wasm-opt = ["-O", "--enable-bulk-memory", "--enable-nontrapping-float-to-int"] diff --git a/crates/sketches/src/lib.rs b/crates/sketches/src/lib.rs new file mode 100644 index 00000000..0b55db3d --- /dev/null +++ b/crates/sketches/src/lib.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/package.json b/package.json index 5450536c..71bf6b29 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "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 library_config && node scripts/build-wasm.js datadog-js-zstd && node scripts/build-wasm.js pipeline && node scripts/build-wasm.js sketches", "cargo-build-release": "yarn -s cargo-build -- --release", "cargo-build": "cargo build --message-format=json-render-diagnostics", "copy-artifacts": "node ./scripts/copy-artifacts", 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) From 617af2a9e43c297f0ddfe407069de1d6fba143ea Mon Sep 17 00:00:00 2001 From: Ilyas Shabi Date: Mon, 10 Aug 2026 21:09:43 +0200 Subject: [PATCH 09/20] build: simplify WASM build script (#199) --- package.json | 2 +- scripts/build-wasm.js | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 71bf6b29..a5d1e6c3 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "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 && node scripts/build-wasm.js sketches", + "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", diff --git a/scripts/build-wasm.js b/scripts/build-wasm.js index b5a20a6d..93b338e6 100644 --- a/scripts/build-wasm.js +++ b/scripts/build-wasm.js @@ -15,7 +15,12 @@ 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', + 'datadog-js-zstd', + 'pipeline', + 'sketches', +] const env = { ...process.env, @@ -44,8 +49,10 @@ if (isMacOS) { env.CXX_wasm32_unknown_unknown = `${llvmBinDir}/clang++` } -childProcess.execSync( - `wasm-pack build ${noWasmOpt} --target nodejs ./crates/${library} --out-dir ../../prebuilds/${library}`, { - env, - }, -) +for (const library of libraries) { + childProcess.execSync( + `wasm-pack build ${noWasmOpt} --target nodejs ./crates/${library} --out-dir ../../prebuilds/${library}`, { + env, + }, + ) +} From 1bc95f6ca5879ecd655bde1dbcffacde71bb7a1f Mon Sep 17 00:00:00 2001 From: Jules Wiriath <53870805+Aaalibaba42@users.noreply.github.com> Date: Tue, 11 Aug 2026 12:05:54 +0200 Subject: [PATCH 10/20] feat: Adopt TraceExporter's Telemetry stuff (#183) * feat: added env capability * feat: respect envcapabilities method unsafedness * feat: validate before saying it's ok * revert: remove set/unset since they would be dangerous APIs in libdatadog (and are most likely not useful in the near/middel future in dd-trace-js) * chore: change input to main's commit that has the change * docs: update doc to remove specific references to the capabilities * fix: remove extra checks * fix: cache env beforehand * feat: Adopt TraceExporter's Telemetry stuff * docs: fix libdatadog's behavior when 0 is passed * chore: js tomfoolery * fix: comments * fix: use Cells uniformaly * feat: make the losslessness obvious --- Cargo.lock | 46 ++++++++++++++++++++++++----- crates/pipeline/Cargo.toml | 4 +-- crates/pipeline/src/lib.rs | 57 ++++++++++++++++++++++++++++-------- crates/pipeline/src/stats.rs | 8 ++--- 4 files changed, 90 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11a3de2c..307ba14e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1031,7 +1031,7 @@ dependencies = [ "libc", "libdd-common", "libdd-libunwind-sys", - "libdd-telemetry", + "libdd-telemetry 5.0.1", "nix 0.29.0", "num-derive", "num-traits", @@ -1069,7 +1069,8 @@ dependencies = [ "libdd-common", "libdd-ddsketch", "libdd-dogstatsd-client", - "libdd-shared-runtime", + "libdd-shared-runtime 2.0.0", + "libdd-telemetry 6.0.0", "libdd-tinybytes", "libdd-trace-normalization", "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", @@ -1204,6 +1205,35 @@ dependencies = [ "winver", ] +[[package]] +name = "libdd-telemetry" +version = "6.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +dependencies = [ + "anyhow", + "async-trait", + "base64", + "bytes", + "futures", + "getrandom 0.2.17", + "hashbrown 0.15.5", + "http", + "libc", + "libdd-capabilities 2.1.0", + "libdd-common 5.1.0", + "libdd-ddsketch 1.1.0", + "libdd-shared-runtime 2.0.0", + "serde", + "serde_json", + "sys-info", + "tokio", + "tokio-util", + "tracing", + "uuid", + "web-time", + "winver", +] + [[package]] name = "libdd-tinybytes" version = "1.1.1" @@ -1268,11 +1298,13 @@ dependencies = [ "futures", "hashbrown 0.15.5", "http", - "libdd-capabilities", - "libdd-capabilities-impl", - "libdd-common", - "libdd-ddsketch", - "libdd-shared-runtime", + "libdd-capabilities 2.1.0", + "libdd-capabilities-impl 3.0.0", + "libdd-common 5.1.0", + "libdd-ddsketch 1.1.0", + "libdd-dogstatsd-client", + "libdd-shared-runtime 2.0.0", + "libdd-telemetry 6.0.0", "libdd-trace-obfuscation", "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", "libdd-trace-utils", diff --git a/crates/pipeline/Cargo.toml b/crates/pipeline/Cargo.toml index 29fc2722..8056816e 100644 --- a/crates/pipeline/Cargo.toml +++ b/crates/pipeline/Cargo.toml @@ -16,15 +16,15 @@ serde_json = "1" libdatadog-nodejs-capabilities = { path = "../capabilities" } libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f" } libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } -libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } +libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false, features = ["telemetry"] } libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false, features = ["change-buffer"] } libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } -web-time = "1" 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 ac17a112..3e65cb46 100644 --- a/crates/pipeline/src/stats.rs +++ b/crates/pipeline/src/stats.rs @@ -9,11 +9,11 @@ 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; From 4f1808e9e6e258ab3ddbe729e173da9259449140 Mon Sep 17 00:00:00 2001 From: "gh-worker-campaigns-3e9aa4[bot]" <244854796+gh-worker-campaigns-3e9aa4[bot]@users.noreply.github.com> Date: Thu, 20 Aug 2026 20:00:44 +0000 Subject: [PATCH 11/20] =?UTF-8?q?ADMS:=20vuln=20brace-expansion=20(patch?= =?UTF-8?q?=20=E2=86=92=205.0.9)=20(#201)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: gh-worker-campaigns-3e9aa4[bot] <244854796+gh-worker-campaigns-3e9aa4[bot]@users.noreply.github.com> --- yarn.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn.lock b/yarn.lock index 85f5c9f5..a8a63d10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -280,10 +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== -brace-expansion@^5.0.2: - version "5.0.6" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.6.tgz#ec68fe0a641a29d8711579caf641d05bae1f2285" - integrity sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g== +brace-expansion@^5.0.2, brace-expansion@^5.0.9: + 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" From 7224cbc508179bb79d0bd2a150f0fca1725c05e7 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 25 Aug 2026 21:59:27 +0200 Subject: [PATCH 12/20] Add remote config wasm layer (#197) * Add remote config wasm layer Also consistently upgrades to v40.0.0 instead of multiple revs being pinned. * Address codex comments * Fix node v18 test * Update to agentless rc * Drop webcrypto polyfill --- .github/actions/build-test-wasm/action.yaml | 16 +- .github/workflows/build.yml | 1 + .github/workflows/release.yml | 1 + Cargo.lock | 1082 ++++++++++++++++--- LICENSE-3rdparty.csv | 327 +++++- crates/capabilities/Cargo.toml | 2 +- crates/capabilities/src/http.rs | 16 +- crates/capabilities/src/http_transport.js | 5 +- crates/capabilities/src/lib.rs | 10 +- crates/library_config/Cargo.toml | 2 +- crates/pipeline/Cargo.toml | 14 +- crates/process_discovery/Cargo.toml | 4 +- crates/remote_config/Cargo.toml | 27 + crates/remote_config/src/lib.rs | 351 ++++++ scripts/build-wasm.js | 1 + test/http_transport.js | 70 +- test/pipeline.js | 8 +- test/remote-config.js | 284 +++++ 18 files changed, 1994 insertions(+), 227 deletions(-) create mode 100644 crates/remote_config/Cargo.toml create mode 100644 crates/remote_config/src/lib.rs create mode 100644 test/remote-config.js 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 de179fb7..2c9a2d71 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,6 +26,7 @@ jobs: - library_config - datadog-js-zstd - pipeline + - remote_config - sketches steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7533785d..d015ac47 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,6 +14,7 @@ jobs: - library_config - datadog-js-zstd - pipeline + - remote_config - sketches steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 diff --git a/Cargo.lock b/Cargo.lock index 307ba14e..8b5ae910 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,7 +55,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -98,6 +98,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + [[package]] name = "bitflags" version = "2.11.1" @@ -142,6 +148,15 @@ 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" @@ -206,8 +221,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ "iana-time-zone", + "js-sys", "num-traits", "serde", + "wasm-bindgen", "windows-link 0.2.1", ] @@ -357,9 +374,49 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn", + "syn 2.0.117", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "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.117", +] + +[[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.117", ] +[[package]] +name = "data-encoding" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" + [[package]] name = "datadog-js-zstd" version = "0.1.0" @@ -379,6 +436,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.117", +] + +[[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" @@ -395,10 +501,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags", + "bitflags 2.11.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.3", +] + [[package]] name = "dunce" version = "1.0.5" @@ -439,6 +556,12 @@ 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" @@ -456,12 +579,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" @@ -524,7 +662,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -611,10 +749,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" @@ -644,6 +788,17 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.18", +] + [[package]] name = "http" version = "1.4.0" @@ -651,7 +806,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "itoa", + "itoa 1.0.18", ] [[package]] @@ -661,7 +816,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.4.0", ] [[package]] @@ -672,7 +827,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http", + "http 1.4.0", "http-body", "pin-project-lite", ] @@ -693,10 +848,10 @@ dependencies = [ "bytes", "futures-channel", "futures-core", - "http", + "http 1.4.0", "http-body", "httparse", - "itoa", + "itoa 1.0.18", "pin-project-lite", "smallvec", "tokio", @@ -709,7 +864,7 @@ version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "http", + "http 1.4.0", "hyper", "hyper-util", "rustls", @@ -727,7 +882,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", + "http 1.4.0", "http-body", "hyper", "libc", @@ -762,12 +917,133 @@ dependencies = [ "cc", ] +[[package]] +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 = "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 = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +[[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" version = "2.14.0" @@ -789,12 +1065,71 @@ 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.117", +] + +[[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" @@ -806,7 +1141,7 @@ dependencies = [ "combine", "jni-sys 0.3.1", "log", - "thiserror", + "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] @@ -836,7 +1171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -895,9 +1230,9 @@ dependencies = [ "anyhow", "bytes", "futures-core", - "http", + "http 1.4.0", "js-sys", - "libdd-capabilities", + "libdd-capabilities 3.0.0", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", @@ -910,19 +1245,21 @@ source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3d dependencies = [ "anyhow", "bytes", - "http", - "thiserror", + "http 1.4.0", + "thiserror 1.0.69", ] [[package]] name = "libdd-capabilities" -version = "2.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "3.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "bytes", - "http", - "thiserror", + "futures-channel", + "futures-util", + "http 1.4.0", + "thiserror 1.0.69", ] [[package]] @@ -931,7 +1268,7 @@ version = "2.0.0" source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "bytes", - "http", + "http 1.4.0", "http-body-util", "libdd-capabilities 2.0.0", "libdd-common 5.0.0", @@ -940,15 +1277,15 @@ dependencies = [ [[package]] name = "libdd-capabilities-impl" -version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "4.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "bytes", - "http", + "http 1.4.0", "http-body-util", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", + "libdd-capabilities 3.0.0", + "libdd-common 5.2.0", "tokio", ] @@ -965,7 +1302,7 @@ dependencies = [ "futures-core", "futures-util", "hex", - "http", + "http 1.4.0", "http-body", "http-body-util", "hyper", @@ -980,7 +1317,7 @@ dependencies = [ "rustls-platform-verifier", "serde", "static_assertions", - "thiserror", + "thiserror 1.0.69", "tokio", "tokio-rustls", "tower-service", @@ -989,8 +1326,8 @@ dependencies = [ [[package]] name = "libdd-common" -version = "5.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "5.2.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "bytes", @@ -1000,19 +1337,24 @@ dependencies = [ "futures-core", "futures-util", "hex", - "http", + "http 1.4.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", ] @@ -1027,7 +1369,7 @@ dependencies = [ "cc", "chrono", "errno", - "http", + "http 1.4.0", "libc", "libdd-common", "libdd-libunwind-sys", @@ -1039,12 +1381,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", @@ -1052,8 +1394,8 @@ dependencies = [ [[package]] name = "libdd-data-pipeline" -version = "7.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "8.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "arc-swap", @@ -1062,18 +1404,18 @@ dependencies = [ "either", "futures", "getrandom 0.2.17", - "http", + "http 1.4.0", "http-body-util", - "libdd-capabilities", - "libdd-capabilities-impl", - "libdd-common", - "libdd-ddsketch", + "libdd-capabilities 3.0.0", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0", + "libdd-ddsketch 1.1.1", "libdd-dogstatsd-client", - "libdd-shared-runtime 2.0.0", - "libdd-telemetry 6.0.0", + "libdd-shared-runtime 3.0.0", + "libdd-telemetry 7.0.0", "libdd-tinybytes", "libdd-trace-normalization", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -1103,27 +1445,38 @@ dependencies = [ "prost", ] +[[package]] +name = "libdd-ddsketch" +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=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "5.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", + "async-trait", "cadence", - "http", - "libdd-common", + "http 1.4.0", + "libdd-common 5.2.0", + "libdd-shared-runtime 3.0.0", "serde", + "tokio", "tracing", ] [[package]] name = "libdd-library-config" version = "3.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4#0c6e2a5df2a163d34c4f385353ffc5d7257c72f4" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v40.0.0#ea75b04c3547037937730a14cf8a72a5ebf702d7" dependencies = [ "anyhow", "libc", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4)", + "libdd-trace-protobuf 4.0.0", "memfd", "prost", "rand", @@ -1144,6 +1497,44 @@ dependencies = [ "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.4.0", + "http-body-util", + "libdd-capabilities 3.0.0", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0", + "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" @@ -1163,15 +1554,15 @@ dependencies = [ [[package]] name = "libdd-shared-runtime" -version = "2.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +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", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0", "tokio", "tokio-util", "tracing", @@ -1189,7 +1580,7 @@ dependencies = [ "bytes", "futures", "hashbrown 0.15.5", - "http", + "http 1.4.0", "http-body-util", "libc", "libdd-common", @@ -1207,8 +1598,8 @@ dependencies = [ [[package]] name = "libdd-telemetry" -version = "6.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "7.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "async-trait", @@ -1217,14 +1608,16 @@ dependencies = [ "futures", "getrandom 0.2.17", "hashbrown 0.15.5", - "http", + "http 1.4.0", "libc", - "libdd-capabilities 2.1.0", - "libdd-common 5.1.0", - "libdd-ddsketch 1.1.0", - "libdd-shared-runtime 2.0.0", + "libdd-capabilities 3.0.0", + "libdd-common 5.2.0", + "libdd-ddsketch 1.1.1", + "libdd-shared-runtime 3.0.0", "serde", "serde_json", + "strum", + "strum_macros", "sys-info", "tokio", "tokio-util", @@ -1236,30 +1629,30 @@ dependencies = [ [[package]] name = "libdd-tinybytes" -version = "1.1.1" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +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=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "3.0.1" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", ] [[package]] name = "libdd-trace-obfuscation" -version = "5.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +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 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-common 5.2.0", + "libdd-trace-protobuf 4.0.1", "libdd-trace-utils", "log", "percent-encoding", @@ -1270,7 +1663,7 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" version = "4.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4#0c6e2a5df2a163d34c4f385353ffc5d7257c72f4" +source = "git+https://github.com/DataDog/libdatadog.git?tag=v40.0.0#ea75b04c3547037937730a14cf8a72a5ebf702d7" dependencies = [ "prost", "serde", @@ -1279,8 +1672,8 @@ dependencies = [ [[package]] name = "libdd-trace-protobuf" -version = "4.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "4.0.1" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "prost", "serde", @@ -1289,24 +1682,24 @@ dependencies = [ [[package]] name = "libdd-trace-stats" -version = "6.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +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.4.0", + "libdd-capabilities 3.0.0", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0", + "libdd-ddsketch 1.1.1", "libdd-dogstatsd-client", - "libdd-shared-runtime 2.0.0", - "libdd-telemetry 6.0.0", + "libdd-shared-runtime 3.0.0", + "libdd-telemetry 7.0.0", "libdd-trace-obfuscation", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", "libdd-trace-utils", "rmp-serde", "serde", @@ -1318,8 +1711,8 @@ dependencies = [ [[package]] name = "libdd-trace-utils" -version = "9.0.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "10.1.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75#966f921c226b63a1ba84c2e53e3d0f4625f90c75" dependencies = [ "anyhow", "base64", @@ -1327,17 +1720,17 @@ dependencies = [ "futures", "getrandom 0.2.17", "hex", - "http", + "http 1.4.0", "http-body", "http-body-util", - "indexmap", - "itoa", - "libdd-capabilities 2.1.0", - "libdd-capabilities-impl 3.0.0", - "libdd-common 5.1.0", + "indexmap 2.14.0", + "itoa 1.0.18", + "libdd-capabilities 3.0.0", + "libdd-capabilities-impl 4.0.0", + "libdd-common 5.2.0", "libdd-tinybytes", "libdd-trace-normalization", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-trace-protobuf 4.0.1", "prost", "rand", "rmp", @@ -1352,6 +1745,31 @@ dependencies = [ "tracing", ] +[[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" @@ -1387,12 +1805,27 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +[[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" @@ -1463,8 +1896,8 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeff6bd154a309b2ada5639b2661ca6ae4599b34e8487dc276d2cd637da2d76" dependencies = [ - "bitflags", - "itoa", + "bitflags 2.11.1", + "itoa 1.0.18", ] [[package]] @@ -1473,7 +1906,7 @@ version = "2.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" dependencies = [ - "bitflags", + "bitflags 2.11.1", "ctor", "napi-derive", "napi-sys", @@ -1493,7 +1926,7 @@ dependencies = [ "napi-derive-backend", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1506,7 +1939,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1524,7 +1957,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", @@ -1537,7 +1970,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags", + "bitflags 2.11.1", "cfg-if", "cfg_aliases", "libc", @@ -1552,6 +1985,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" @@ -1560,7 +1999,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1588,7 +2027,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", "objc2-foundation", ] @@ -1609,7 +2048,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags", + "bitflags 2.11.1", "dispatch2", "objc2", ] @@ -1620,7 +2059,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags", + "bitflags 2.11.1", "dispatch2", "objc2", "objc2-core-foundation", @@ -1653,7 +2092,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", "objc2-core-graphics", @@ -1671,7 +2110,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags", + "bitflags 2.11.1", "block2", "libc", "objc2", @@ -1684,7 +2123,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", ] @@ -1695,7 +2134,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags", + "bitflags 2.11.1", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -1707,7 +2146,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags", + "bitflags 2.11.1", "block2", "objc2", "objc2-cloud-kit", @@ -1805,7 +2244,7 @@ checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1821,13 +2260,14 @@ dependencies = [ "bytes", "console_error_panic_hook", "getrandom 0.2.17", - "http", + "http 1.4.0", "js-sys", "libdatadog-nodejs-capabilities", - "libdd-capabilities", + "libdd-capabilities 3.0.0", + "libdd-common 5.2.0", "libdd-data-pipeline", - "libdd-shared-runtime 2.0.0", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f)", + "libdd-shared-runtime 3.0.0", + "libdd-trace-protobuf 4.0.1", "libdd-trace-stats", "libdd-trace-utils", "rmp-serde", @@ -1855,6 +2295,30 @@ dependencies = [ "serde", ] +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "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" @@ -1871,7 +2335,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn", + "syn 2.0.117", ] [[package]] @@ -1889,7 +2353,7 @@ version = "0.1.0" dependencies = [ "anyhow", "libdd-library-config", - "libdd-trace-protobuf 4.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=0c6e2a5df2a163d34c4f385353ffc5d7257c72f4)", + "libdd-trace-protobuf 4.0.0", "napi", "napi-derive", ] @@ -1914,7 +2378,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -1985,7 +2449,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2017,6 +2481,23 @@ version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +[[package]] +name = "remote-config" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "libdatadog-nodejs-capabilities", + "libdd-common 5.2.0", + "libdd-remote-config", + "serde", + "serde-wasm-bindgen", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", +] + [[package]] name = "ring" version = "0.17.14" @@ -2027,7 +2508,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.17", "libc", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.52.0", ] @@ -2077,7 +2558,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.11.1", "errno", "libc", "linux-raw-sys", @@ -2156,7 +2637,7 @@ dependencies = [ "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -2201,6 +2682,30 @@ dependencies = [ "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", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "schemars_derive" version = "0.8.22" @@ -2210,7 +2715,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn", + "syn 2.0.117", ] [[package]] @@ -2219,7 +2724,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", + "bitflags 2.11.1", "core-foundation", "core-foundation-sys", "libc", @@ -2299,7 +2804,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2310,7 +2815,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2319,22 +2824,55 @@ version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" 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.117", +] + [[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", @@ -2405,6 +2943,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.117", +] + [[package]] name = "subtle" version = "2.6.1" @@ -2446,6 +3009,28 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +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.117", +] + [[package]] name = "sys-info" version = "0.9.1" @@ -2456,6 +3041,19 @@ 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.3.4", + "once_cell", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "thin-vec" version = "0.2.18" @@ -2468,7 +3066,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]] @@ -2479,9 +3086,75 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", +] + +[[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.3", +] + +[[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" @@ -2505,7 +3178,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2592,12 +3265,36 @@ 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" @@ -2701,7 +3398,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -2744,7 +3441,7 @@ checksum = "c610311887f9e6599a546d278d12d69dfd3a3e92639b2129e4b11ad6cf1961d6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2770,7 +3467,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap", + "indexmap 2.14.0", "wasm-encoder", "wasmparser", ] @@ -2781,9 +3478,9 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags", + "bitflags 2.11.1", "hashbrown 0.15.5", - "indexmap", + "indexmap 2.14.0", "semver", ] @@ -2890,7 +3587,7 @@ checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2901,7 +3598,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -2912,7 +3609,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", ] [[package]] @@ -3276,9 +3973,9 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", - "indexmap", + "indexmap 2.14.0", "prettyplease", - "syn", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -3294,7 +3991,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -3306,8 +4003,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags", - "indexmap", + "bitflags 2.11.1", + "indexmap 2.14.0", "log", "serde", "serde_derive", @@ -3326,7 +4023,7 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap", + "indexmap 2.14.0", "log", "semver", "serde", @@ -3336,6 +4033,35 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.8.48" @@ -3353,7 +4079,28 @@ checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.117", +] + +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", + "synstructure", ] [[package]] @@ -3362,6 +4109,39 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +[[package]] +name = "zerotrie" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +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 = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + [[package]] name = "zmij" version = "1.0.21" 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/crates/capabilities/Cargo.toml b/crates/capabilities/Cargo.toml index edb40adc..444ec123 100644 --- a/crates/capabilities/Cargo.toml +++ b/crates/capabilities/Cargo.toml @@ -15,7 +15,7 @@ http = "1" bytes = "1.4" futures-core = "0.3" anyhow = "1" -libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f" } +libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "966f921c226b63a1ba84c2e53e3d0f4625f90c75" } [dev-dependencies] wasm-bindgen-test = "0.3" 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 e76a3812..ca0c8285 100644 --- a/crates/capabilities/src/lib.rs +++ b/crates/capabilities/src/lib.rs @@ -14,7 +14,8 @@ 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; @@ -65,6 +66,13 @@ impl HttpClientCapability for WasmCapabilities { Self::new() } + fn new_without_connection_pooling() -> Self { + Self { + http: WasmHttpClient::new_without_connection_pooling(), + ..Self::new() + } + } + fn request( &self, req: ::http::Request<::bytes::Bytes>, diff --git a/crates/library_config/Cargo.toml b/crates/library_config/Cargo.toml index b6deab09..a3aa5855 100644 --- a/crates/library_config/Cargo.toml +++ b/crates/library_config/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] anyhow = "1" -libdd-library-config = { git = "https://github.com/DataDog/libdatadog.git", rev = "0c6e2a5df2a163d34c4f385353ffc5d7257c72f4" } +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"] } diff --git a/crates/pipeline/Cargo.toml b/crates/pipeline/Cargo.toml index 8056816e..67b7aad3 100644 --- a/crates/pipeline/Cargo.toml +++ b/crates/pipeline/Cargo.toml @@ -14,13 +14,13 @@ js-sys = "0.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1" libdatadog-nodejs-capabilities = { path = "../capabilities" } -libdd-capabilities = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f" } -libdd-common = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } -libdd-data-pipeline = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false, features = ["telemetry"] } -libdd-trace-utils = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false, features = ["change-buffer"] } -libdd-trace-stats = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } -libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", default-features = false } -libdd-shared-runtime = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f", 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" diff --git a/crates/process_discovery/Cargo.toml b/crates/process_discovery/Cargo.toml index 32e9449e..398ccc1c 100644 --- a/crates/process_discovery/Cargo.toml +++ b/crates/process_discovery/Cargo.toml @@ -8,8 +8,8 @@ crate-type = ["cdylib", "rlib"] [dependencies] anyhow = "1" -libdd-library-config = { git = "https://github.com/DataDog/libdatadog.git", rev = "0c6e2a5df2a163d34c4f385353ffc5d7257c72f4", features = ["otel-thread-ctx"] } -libdd-trace-protobuf = { git = "https://github.com/DataDog/libdatadog.git", rev = "0c6e2a5df2a163d34c4f385353ffc5d7257c72f4" } +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/scripts/build-wasm.js b/scripts/build-wasm.js index 93b338e6..acb69f4a 100644 --- a/scripts/build-wasm.js +++ b/scripts/build-wasm.js @@ -19,6 +19,7 @@ const libraries = [ 'library_config', 'datadog-js-zstd', 'pipeline', + 'remote_config', 'sketches', ] diff --git a/test/http_transport.js b/test/http_transport.js index a9418806..41abd10b 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 () => { @@ -204,7 +204,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 +273,75 @@ 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) + }) +}) + // 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 +497,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 8b62197f..fe9defa7 100644 --- a/test/pipeline.js +++ b/test/pipeline.js @@ -1163,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) => { @@ -1184,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/ }, + ) +}) From 1c987070892020c2f2c6607e3fcbe4687cc0053e Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Thu, 27 Aug 2026 13:41:28 -0400 Subject: [PATCH 13/20] feat(libdatadog): add universal core and optional extras packages (#207) * feat(libdatadog): add universal core and optional extras packages * refactor: restructure libdatadog packages * test: tighten wasm size budgets * ci(libdatadog): fix cross-platform builds and tests * fix(libdatadog): address package compatibility issues --- .github/workflows/build.yml | 235 +- .github/workflows/release.yml | 327 +- Cargo.lock | 892 ++-- README.md | 43 +- crates/datadog-js-zstd/Cargo.toml | 18 - crates/libdatadog-wasm/Cargo.toml | 33 + crates/libdatadog-wasm/src/lib.rs | 2 + .../src/sketches/mod.rs} | 0 .../src/zstd/mod.rs} | 3 +- crates/libdatadog/Cargo.toml | 17 + crates/libdatadog/build.rs | 3 + crates/libdatadog/src/lib.rs | 2 + crates/libdatadog/src/sketches/mod.rs | 41 + crates/libdatadog/src/zstd/mod.rs | 9 + crates/library_config/Cargo.toml | 2 - crates/sketches/Cargo.toml | 15 - eslint.config.js | 28 +- load.js | 10 +- package.json | 6 +- packages/libdatadog/.gitignore | 5 + packages/libdatadog/README.md | 24 + packages/libdatadog/index.d.ts | 10 + packages/libdatadog/index.js | 3 + packages/libdatadog/index.mjs | 9 + packages/libdatadog/lib/load.js | 11 + packages/libdatadog/lib/native.js | 49 + packages/libdatadog/lib/wasm.js | 9 + packages/libdatadog/package-lock.json | 3869 +++++++++++++++++ packages/libdatadog/package.json | 78 + packages/libdatadog/scripts/build-native.js | 30 + packages/libdatadog/scripts/inline-wasm.js | 35 + packages/libdatadog/scripts/package-native.js | 99 + packages/libdatadog/scripts/run-tests.js | 13 + packages/libdatadog/scripts/set-version.js | 26 + packages/libdatadog/test/bundlers.test.js | 58 + packages/libdatadog/test/capabilities.test.js | 63 + .../libdatadog/test/package-contents.test.js | 242 ++ packages/libdatadog/test/package.test.js | 86 + packages/libdatadog/test/types.test.ts | 27 + packages/libdatadog/wasm.js | 3 + packages/libdatadog/wasm.mjs | 9 + packages/libdatadog/wasm/package.json | 15 + scripts/build-wasm.js | 53 +- test/build-wasm.js | 85 + 44 files changed, 6037 insertions(+), 560 deletions(-) delete mode 100644 crates/datadog-js-zstd/Cargo.toml create mode 100644 crates/libdatadog-wasm/Cargo.toml create mode 100644 crates/libdatadog-wasm/src/lib.rs rename crates/{sketches/src/lib.rs => libdatadog-wasm/src/sketches/mod.rs} (100%) rename crates/{datadog-js-zstd/src/lib.rs => libdatadog-wasm/src/zstd/mod.rs} (69%) create mode 100644 crates/libdatadog/Cargo.toml create mode 100644 crates/libdatadog/build.rs create mode 100644 crates/libdatadog/src/lib.rs create mode 100644 crates/libdatadog/src/sketches/mod.rs create mode 100644 crates/libdatadog/src/zstd/mod.rs delete mode 100644 crates/sketches/Cargo.toml create mode 100644 packages/libdatadog/.gitignore create mode 100644 packages/libdatadog/README.md create mode 100644 packages/libdatadog/index.d.ts create mode 100644 packages/libdatadog/index.js create mode 100644 packages/libdatadog/index.mjs create mode 100644 packages/libdatadog/lib/load.js create mode 100644 packages/libdatadog/lib/native.js create mode 100644 packages/libdatadog/lib/wasm.js create mode 100644 packages/libdatadog/package-lock.json create mode 100644 packages/libdatadog/package.json create mode 100644 packages/libdatadog/scripts/build-native.js create mode 100644 packages/libdatadog/scripts/inline-wasm.js create mode 100644 packages/libdatadog/scripts/package-native.js create mode 100644 packages/libdatadog/scripts/run-tests.js create mode 100644 packages/libdatadog/scripts/set-version.js create mode 100644 packages/libdatadog/test/bundlers.test.js create mode 100644 packages/libdatadog/test/capabilities.test.js create mode 100644 packages/libdatadog/test/package-contents.test.js create mode 100644 packages/libdatadog/test/package.test.js create mode 100644 packages/libdatadog/test/types.test.ts create mode 100644 packages/libdatadog/wasm.js create mode 100644 packages/libdatadog/wasm.mjs create mode 100644 packages/libdatadog/wasm/package.json create mode 100644 test/build-wasm.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2c9a2d71..bb688d01 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,16 +18,237 @@ jobs: 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 + - run: npm ci --prefix packages/libdatadog + - run: cargo install wasm-pack --version 0.14.0 --locked + - 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 + + build-libdatadog-platform: + name: Build libdatadog (${{ matrix.package-target }}) + strategy: + fail-fast: false + matrix: + include: + - rust-target: aarch64-apple-darwin + package-target: darwin-arm64 + runner: macos-15 + - rust-target: x86_64-apple-darwin + package-target: darwin-x64 + runner: macos-15-intel + - rust-target: aarch64-unknown-linux-gnu + package-target: linux-arm64-gnu + runner: ubuntu-24.04-arm + - rust-target: aarch64-unknown-linux-musl + package-target: linux-arm64-musl + runner: ubuntu-24.04-arm + build_args: --cross-compile + zig_arch: aarch64 + zig_sha256: 958ed7d1e00d0ea76590d27666efbf7a932281b3d7ba0c6b01b0ff26498f667f + - rust-target: x86_64-unknown-linux-gnu + package-target: linux-x64-gnu + runner: ubuntu-latest + - rust-target: x86_64-unknown-linux-musl + package-target: linux-x64-musl + runner: ubuntu-latest + build_args: --cross-compile + zig_arch: x86_64 + zig_sha256: 02aa270f183da276e5b5920b1dac44a63f1a49e55050ebde3aecc9eb82f93239 + runs-on: ${{ matrix.runner }} + 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: Install Zig + if: matrix.zig_arch + env: + ZIG_ARCH: ${{ matrix.zig_arch }} + ZIG_SHA256: ${{ matrix.zig_sha256 }} + ZIG_VERSION: 0.15.2 + run: | + ZIG_ARCHIVE="${RUNNER_TEMP}/zig.tar.xz" + ZIG_DIRECTORY="${RUNNER_TEMP}/zig" + curl --fail --location --silent --show-error \ + --output "${ZIG_ARCHIVE}" \ + "https://ziglang.org/download/${ZIG_VERSION}/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}.tar.xz" + echo "${ZIG_SHA256} ${ZIG_ARCHIVE}" | sha256sum --check + mkdir -p "${ZIG_DIRECTORY}" + tar --extract --xz --file "${ZIG_ARCHIVE}" \ + --directory "${ZIG_DIRECTORY}" --strip-components=1 + echo "${ZIG_DIRECTORY}" >> "${GITHUB_PATH}" + - name: Install cargo-zigbuild + if: matrix.build_args + run: cargo install --locked cargo-zigbuild --version 0.23.0 + - name: Add Rust target + run: rustup target add '${{ matrix.rust-target }}' + - run: npm ci --prefix packages/libdatadog + - name: Build native extension + run: >- + npm run build:native --prefix packages/libdatadog -- + --target '${{ matrix.rust-target }}' ${{ matrix.build_args }} + - run: npm run package:native --prefix packages/libdatadog + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: libdatadog-binding-${{ matrix.package-target }} + path: packages/libdatadog/dist/native/*.node + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: libdatadog-platform-${{ matrix.package-target }} + path: packages/libdatadog/dist/packages + + 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-platform: + name: Test libdatadog (${{ matrix.platform.package_target }}, Node ${{ matrix.node }}) + needs: + - build-libdatadog + - build-libdatadog-platform + strategy: + fail-fast: false + matrix: + platform: + - package_target: darwin-arm64 + runner: macos-15 + - package_target: darwin-x64 + runner: macos-15-intel + - package_target: linux-arm64-gnu + runner: ubuntu-24.04-arm + - package_target: linux-x64-gnu + runner: ubuntu-latest + node: [18, 24] + runs-on: ${{ matrix.platform.runner }} + env: + DD_LIBDATADOG_EXPECTED_BACKEND: native + LIBDATADOG_TARGET: ${{ matrix.platform.package_target }} + 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-binding-${{ matrix.platform.package_target }} + path: packages/libdatadog/dist/native + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-platform-${{ matrix.platform.package_target }} + path: packages/libdatadog/dist/packages + - 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-platform-musl: + name: Test libdatadog (${{ matrix.platform.package_target }}, Node ${{ matrix.node }}) + needs: + - build-libdatadog + - build-libdatadog-platform + strategy: + fail-fast: false + matrix: + platform: + - package_target: linux-arm64-musl + runner: ubuntu-24.04-arm + - package_target: linux-x64-musl + runner: ubuntu-latest + node: [18, 24] + runs-on: ${{ matrix.platform.runner }} + env: + DD_LIBDATADOG_EXPECTED_BACKEND: native + LIBDATADOG_TARGET: ${{ matrix.platform.package_target }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-binding-${{ matrix.platform.package_target }} + path: packages/libdatadog/dist/native + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-platform-${{ matrix.platform.package_target }} + path: packages/libdatadog/dist/packages + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + - name: Test in Alpine + run: | + docker run --rm \ + --env DD_LIBDATADOG_EXPECTED_BACKEND \ + --env LIBDATADOG_TARGET \ + --volume "${GITHUB_WORKSPACE}:/workspace" \ + --workdir /workspace \ + "node:${{ matrix.node }}-alpine" \ + sh -c ' + apk add --no-cache git + npm ci --prefix packages/libdatadog + 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] + env: + DD_LIBDATADOG_EXPECTED_BACKEND: wasm + 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 - - sketches steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 'Use composite action' @@ -35,7 +256,7 @@ jobs: with: crate: '${{ matrix.crate }}' - build: + build-libdatadog-extras: uses: Datadog/action-prebuildify/.github/workflows/build.yml@main needs: build-test-wasm with: @@ -44,12 +265,14 @@ 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 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d015ac47..a8c0e27b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,18 +4,47 @@ 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 - - sketches steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: 'Use composite action' @@ -23,7 +52,7 @@ jobs: with: crate: '${{ matrix.crate }}' - build: + build-libdatadog-extras: uses: Datadog/action-prebuildify/.github/workflows/build.yml@main needs: build-test-wasm with: @@ -32,18 +61,238 @@ 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 + + build-libdatadog-platform: + name: Build libdatadog (${{ matrix.package-target }}) + needs: versions + strategy: + fail-fast: false + matrix: + include: + - rust-target: aarch64-apple-darwin + package-target: darwin-arm64 + runner: macos-15 + - rust-target: x86_64-apple-darwin + package-target: darwin-x64 + runner: macos-15-intel + - rust-target: aarch64-unknown-linux-gnu + package-target: linux-arm64-gnu + runner: ubuntu-24.04-arm + - rust-target: aarch64-unknown-linux-musl + package-target: linux-arm64-musl + runner: ubuntu-24.04-arm + install-musl: true + - rust-target: x86_64-unknown-linux-gnu + package-target: linux-x64-gnu + runner: ubuntu-latest + - rust-target: x86_64-unknown-linux-musl + package-target: linux-x64-musl + runner: ubuntu-latest + install-musl: true + runs-on: ${{ matrix.runner }} + 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: Install musl toolchain + if: matrix.install-musl + run: sudo apt-get update && sudo apt-get install -y musl-tools + - name: Add Rust target + run: rustup target add '${{ matrix.rust-target }}' + - run: npm ci --prefix packages/libdatadog + - name: Set package version + run: node packages/libdatadog/scripts/set-version.js '${{ needs.versions.outputs.version }}' + - name: Build native extension + run: npm run build:native --prefix packages/libdatadog -- --target '${{ matrix.rust-target }}' + - run: npm run package:native --prefix packages/libdatadog + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: libdatadog-binding-${{ matrix.package-target }} + path: packages/libdatadog/dist/native/*.node + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: libdatadog-platform-${{ matrix.package-target }} + path: packages/libdatadog/dist/packages + + 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-platform: + name: Test libdatadog (${{ matrix.platform.package_target }}, Node ${{ matrix.node }}) + needs: + - build-libdatadog-platform + - build-libdatadog-wasm + strategy: + fail-fast: false + matrix: + platform: + - package_target: darwin-arm64 + runner: macos-15 + - package_target: darwin-x64 + runner: macos-15-intel + - package_target: linux-arm64-gnu + runner: ubuntu-24.04-arm + - package_target: linux-x64-gnu + runner: ubuntu-latest + node: [18, 24] + runs-on: ${{ matrix.platform.runner }} + env: + DD_LIBDATADOG_EXPECTED_BACKEND: native + LIBDATADOG_TARGET: ${{ matrix.platform.package_target }} + 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-binding-${{ matrix.platform.package_target }} + path: packages/libdatadog/dist/native + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-platform-${{ matrix.platform.package_target }} + path: packages/libdatadog/dist/packages + - 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-platform-musl: + name: Test libdatadog (${{ matrix.platform.package_target }}, Node ${{ matrix.node }}) + needs: + - build-libdatadog-platform + - build-libdatadog-wasm + strategy: + fail-fast: false + matrix: + platform: + - package_target: linux-arm64-musl + runner: ubuntu-24.04-arm + - package_target: linux-x64-musl + runner: ubuntu-latest + node: [18, 24] + runs-on: ${{ matrix.platform.runner }} + env: + DD_LIBDATADOG_EXPECTED_BACKEND: native + LIBDATADOG_TARGET: ${{ matrix.platform.package_target }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-binding-${{ matrix.platform.package_target }} + path: packages/libdatadog/dist/native + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-platform-${{ matrix.platform.package_target }} + path: packages/libdatadog/dist/packages + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: libdatadog-wasm + path: packages/libdatadog/wasm/dist + - name: Test in Alpine + run: | + docker run --rm \ + --env DD_LIBDATADOG_EXPECTED_BACKEND \ + --env LIBDATADOG_TARGET \ + --volume "${GITHUB_WORKSPACE}:/workspace" \ + --workdir /workspace \ + "node:${{ matrix.node }}-alpine" \ + sh -c ' + apk add --no-cache git + npm ci --prefix packages/libdatadog + 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] + env: + DD_LIBDATADOG_EXPECTED_BACKEND: wasm + 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-platform + - build-libdatadog-wasm + - test-libdatadog-platform + - test-libdatadog-platform-musl + - 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@96a25462dbcb10ebf0bfd6e2ccc917d2ab235b9a # v1.0.4 + if: github.event_name == 'push' id: octo-sts with: scope: DataDog/libdatadog-nodejs @@ -51,20 +300,62 @@ jobs: - 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@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.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 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + pattern: libdatadog-platform-* + path: packages/libdatadog/dist/packages + merge-multiple: true + - 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 platform packages + env: + NPM_TAG: ${{ needs.versions.outputs.npm-tag }} + run: | + for package in packages/libdatadog/dist/packages/*; do + npm publish "$package" --access public --tag "$NPM_TAG" + done + - 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 8b5ae910..7b7cd390 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 2.0.117", + "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]] @@ -106,9 +107,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.11.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "blazesym" @@ -159,15 +160,15 @@ dependencies = [ [[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" @@ -186,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", @@ -210,15 +211,15 @@ 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", @@ -239,9 +240,9 @@ dependencies = [ [[package]] name = "combine" -version = "4.6.7" +version = "4.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +checksum = "cfc320937d09e6de266b31b9afb480f197d7a861be86be7cb2ea7e5d1bfffc5e" dependencies = [ "bytes", "memchr", @@ -287,6 +288,15 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "convert_case" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -336,26 +346,26 @@ version = "0.2.0" dependencies = [ "anyhow", "libdd-crashtracker", - "napi", - "napi-derive", + "napi 2.16.17", + "napi-derive 2.16.13", "rustls", "serde_json", ] [[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" @@ -374,9 +384,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.119", ] +[[package]] +name = "ctor" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" + [[package]] name = "darling" version = "0.23.0" @@ -397,7 +413,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -408,7 +424,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -417,16 +433,6 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" -[[package]] -name = "datadog-js-zstd" -version = "0.1.0" -dependencies = [ - "js-sys", - "wasm-bindgen", - "wasm-bindgen-test", - "zstd", -] - [[package]] name = "debugid" version = "0.8.0" @@ -455,7 +461,7 @@ dependencies = [ "defmt-parser", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -501,7 +507,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "objc2", ] @@ -513,7 +519,7 @@ checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -530,9 +536,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" @@ -564,9 +570,9 @@ 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" @@ -623,9 +629,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", @@ -633,9 +639,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" @@ -650,9 +656,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" @@ -662,20 +668,20 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "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" @@ -719,27 +725,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]] @@ -772,9 +764,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" @@ -801,9 +793,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa 1.0.18", @@ -811,23 +803,23 @@ dependencies = [ [[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 1.4.0", + "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 1.4.0", + "http 1.5.0", "http-body", "pin-project-lite", ] @@ -840,15 +832,15 @@ 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 1.4.0", + "http 1.5.0", "http-body", "httparse", "itoa 1.0.18", @@ -864,7 +856,7 @@ version = "0.27.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" dependencies = [ - "http 1.4.0", + "http 1.5.0", "hyper", "hyper-util", "rustls", @@ -882,7 +874,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.4.0", + "http 1.5.0", "http-body", "hyper", "libc", @@ -1000,12 +992,6 @@ dependencies = [ "zerovec", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "ident_case" version = "1.0.1" @@ -1051,7 +1037,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", ] @@ -1112,7 +1098,7 @@ dependencies = [ "jiff-core", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -1171,28 +1157,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn 2.0.117", + "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", ] @@ -1212,16 +1197,21 @@ 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" +version = "0.1.0" +dependencies = [ + "libdd-ddsketch 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "napi 3.12.2", + "napi-build", + "napi-derive 3.6.3", + "zstd", +] [[package]] name = "libdatadog-nodejs-capabilities" @@ -1230,7 +1220,7 @@ dependencies = [ "anyhow", "bytes", "futures-core", - "http 1.4.0", + "http 1.5.0", "js-sys", "libdd-capabilities 3.0.0", "wasm-bindgen", @@ -1238,6 +1228,17 @@ dependencies = [ "wasm-bindgen-test", ] +[[package]] +name = "libdatadog-wasm" +version = "0.1.0" +dependencies = [ + "getrandom 0.2.17", + "js-sys", + "libdd-ddsketch 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "wasm-bindgen", + "zrip", +] + [[package]] name = "libdd-capabilities" version = "2.0.0" @@ -1245,7 +1246,7 @@ source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3d dependencies = [ "anyhow", "bytes", - "http 1.4.0", + "http 1.5.0", "thiserror 1.0.69", ] @@ -1258,7 +1259,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.4.0", + "http 1.5.0", "thiserror 1.0.69", ] @@ -1268,7 +1269,7 @@ version = "2.0.0" source = "git+https://github.com/DataDog/libdatadog.git?tag=v37.0.0#86b7f5700d3db4e58076794b5e8073a40d780083" dependencies = [ "bytes", - "http 1.4.0", + "http 1.5.0", "http-body-util", "libdd-capabilities 2.0.0", "libdd-common 5.0.0", @@ -1282,7 +1283,7 @@ source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84 dependencies = [ "anyhow", "bytes", - "http 1.4.0", + "http 1.5.0", "http-body-util", "libdd-capabilities 3.0.0", "libdd-common 5.2.0", @@ -1302,7 +1303,7 @@ dependencies = [ "futures-core", "futures-util", "hex", - "http 1.4.0", + "http 1.5.0", "http-body", "http-body-util", "hyper", @@ -1337,7 +1338,7 @@ dependencies = [ "futures-core", "futures-util", "hex", - "http 1.4.0", + "http 1.5.0", "http-body", "http-body-util", "hyper", @@ -1369,7 +1370,7 @@ dependencies = [ "cc", "chrono", "errno", - "http 1.4.0", + "http 1.5.0", "libc", "libdd-common", "libdd-libunwind-sys", @@ -1404,12 +1405,12 @@ dependencies = [ "either", "futures", "getrandom 0.2.17", - "http 1.4.0", + "http 1.5.0", "http-body-util", "libdd-capabilities 3.0.0", "libdd-capabilities-impl 4.0.0", "libdd-common 5.2.0", - "libdd-ddsketch 1.1.1", + "libdd-ddsketch 1.1.1 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-dogstatsd-client", "libdd-shared-runtime 3.0.0", "libdd-telemetry 7.0.0", @@ -1439,8 +1440,9 @@ dependencies = [ [[package]] name = "libdd-ddsketch" -version = "1.1.0" -source = "git+https://github.com/DataDog/libdatadog.git?rev=3081603d3c74f209be4e3be951f78a1a7469397f#3081603d3c74f209be4e3be951f78a1a7469397f" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "827db9addada0e19a8371241e54fe4f27e9101c5a1dc30a13cf42dea5220e3f0" dependencies = [ "prost", ] @@ -1461,7 +1463,7 @@ dependencies = [ "anyhow", "async-trait", "cadence", - "http 1.4.0", + "http 1.5.0", "libdd-common 5.2.0", "libdd-shared-runtime 3.0.0", "serde", @@ -1488,9 +1490,9 @@ 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", @@ -1510,7 +1512,7 @@ dependencies = [ "futures-util", "getrandom 0.2.17", "hashbrown 0.15.5", - "http 1.4.0", + "http 1.5.0", "http-body-util", "libdd-capabilities 3.0.0", "libdd-capabilities-impl 4.0.0", @@ -1580,7 +1582,7 @@ dependencies = [ "bytes", "futures", "hashbrown 0.15.5", - "http 1.4.0", + "http 1.5.0", "http-body-util", "libc", "libdd-common", @@ -1608,11 +1610,11 @@ dependencies = [ "futures", "getrandom 0.2.17", "hashbrown 0.15.5", - "http 1.4.0", + "http 1.5.0", "libc", "libdd-capabilities 3.0.0", "libdd-common 5.2.0", - "libdd-ddsketch 1.1.1", + "libdd-ddsketch 1.1.1 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-shared-runtime 3.0.0", "serde", "serde_json", @@ -1690,11 +1692,11 @@ dependencies = [ "async-trait", "futures", "hashbrown 0.15.5", - "http 1.4.0", + "http 1.5.0", "libdd-capabilities 3.0.0", "libdd-capabilities-impl 4.0.0", "libdd-common 5.2.0", - "libdd-ddsketch 1.1.1", + "libdd-ddsketch 1.1.1 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-dogstatsd-client", "libdd-shared-runtime 3.0.0", "libdd-telemetry 7.0.0", @@ -1720,7 +1722,7 @@ dependencies = [ "futures", "getrandom 0.2.17", "hex", - "http 1.4.0", + "http 1.5.0", "http-body", "http-body-util", "indexmap 2.14.0", @@ -1780,6 +1782,16 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "libloading" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" +dependencies = [ + "cfg-if", + "windows-link 0.2.1", +] + [[package]] name = "libm" version = "0.2.16" @@ -1793,8 +1805,6 @@ dependencies = [ "anyhow", "getrandom 0.2.17", "libdd-library-config", - "serde", - "serde-wasm-bindgen", "wasm-bindgen", "wasm-bindgen-test", ] @@ -1813,9 +1823,9 @@ 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" @@ -1828,9 +1838,9 @@ dependencies = [ [[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" @@ -1843,9 +1853,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", ] @@ -1861,9 +1871,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", @@ -1881,9 +1891,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", @@ -1896,7 +1906,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbeff6bd154a309b2ada5639b2661ca6ae4599b34e8487dc276d2cd637da2d76" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "itoa 1.0.18", ] @@ -1906,15 +1916,37 @@ version = "2.16.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" dependencies = [ - "bitflags 2.11.1", - "ctor", - "napi-derive", - "napi-sys", + "bitflags 2.13.1", + "ctor 0.2.9", + "napi-derive 2.16.13", + "napi-sys 2.4.0", "once_cell", "serde", "serde_json", ] +[[package]] +name = "napi" +version = "3.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58c5f4d5375213fdb7be2655e152386e82f026f9a5ba36a75556e11359aafe09" +dependencies = [ + "bitflags 2.13.1", + "ctor 1.0.13", + "futures", + "libc", + "napi-build", + "napi-sys 3.3.0", + "nohash-hasher", + "rustc-hash", +] + +[[package]] +name = "napi-build" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60fdf9b392c50e7c4170fa633bd909490ed7835cea4c046776d1a4dd8d2ae0ab" + [[package]] name = "napi-derive" version = "2.16.13" @@ -1922,11 +1954,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c" dependencies = [ "cfg-if", - "convert_case", - "napi-derive-backend", + "convert_case 0.6.0", + "napi-derive-backend 1.0.75", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "napi-derive" +version = "3.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa55ea69990c90b888e9e77044410e304ce7f35de599dc6d0b5c1923d2e59af" +dependencies = [ + "convert_case 0.11.0", + "ctor 1.0.13", + "napi-derive-backend 6.1.2", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -1935,11 +1981,24 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf" dependencies = [ - "convert_case", + "convert_case 0.6.0", "once_cell", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "napi-derive-backend" +version = "6.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df4056ac7c18e4438ccf0edaed4340ca0d269278c8ec19284f7b23cb039fd0ae" +dependencies = [ + "convert_case 0.11.0", + "proc-macro2", + "quote", + "semver", + "syn 2.0.119", ] [[package]] @@ -1948,7 +2007,16 @@ version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3" dependencies = [ - "libloading", + "libloading 0.8.9", +] + +[[package]] +name = "napi-sys" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85fbf1fa9f1babfe396d74bbbf52b3643770243e8f5b0b46715d4caf7f0dfc9a" +dependencies = [ + "libloading 0.9.0", ] [[package]] @@ -1957,7 +2025,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "cfg-if", "cfg_aliases", "libc", @@ -1966,16 +2034,22 @@ 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 2.11.1", + "bitflags 2.13.1", "cfg-if", "cfg_aliases", "libc", ] +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -1999,7 +2073,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2027,7 +2101,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "objc2", "objc2-foundation", ] @@ -2048,7 +2122,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "dispatch2", "objc2", ] @@ -2059,7 +2133,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "dispatch2", "objc2", "objc2-core-foundation", @@ -2092,7 +2166,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "objc2", "objc2-core-foundation", "objc2-core-graphics", @@ -2110,7 +2184,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "block2", "libc", "objc2", @@ -2123,7 +2197,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "objc2", "objc2-core-foundation", ] @@ -2134,7 +2208,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "objc2", "objc2-core-foundation", "objc2-foundation", @@ -2146,7 +2220,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "block2", "objc2", "objc2-cloud-kit", @@ -2191,13 +2265,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", @@ -2229,22 +2303,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 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2260,7 +2334,7 @@ dependencies = [ "bytes", "console_error_panic_hook", "getrandom 0.2.17", - "http 1.4.0", + "http 1.5.0", "js-sys", "libdatadog-nodejs-capabilities", "libdd-capabilities 3.0.0", @@ -2282,15 +2356,15 @@ dependencies = [ [[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", ] @@ -2328,21 +2402,11 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.117", -] - [[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", ] @@ -2354,15 +2418,15 @@ dependencies = [ "anyhow", "libdd-library-config", "libdd-trace-protobuf 4.0.0", - "napi", - "napi-derive", + "napi 2.16.17", + "napi-derive 2.16.13", ] [[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", @@ -2370,32 +2434,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 2.0.117", + "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" @@ -2404,9 +2462,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", @@ -2434,29 +2492,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 2.0.117", + "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", @@ -2466,9 +2524,9 @@ 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", @@ -2477,9 +2535,9 @@ dependencies = [ [[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" @@ -2542,15 +2600,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" @@ -2558,7 +2616,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys", @@ -2567,9 +2625,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", @@ -2594,9 +2652,9 @@ 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", ] @@ -2630,9 +2688,9 @@ 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", @@ -2642,9 +2700,9 @@ dependencies = [ [[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" @@ -2715,7 +2773,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2724,7 +2782,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags 2.11.1", + "bitflags 2.13.1", "core-foundation", "core-foundation-sys", "libc", @@ -2804,7 +2862,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2815,14 +2873,14 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "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 2.14.0", "itoa 1.0.18", @@ -2862,7 +2920,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2891,23 +2949,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" - -[[package]] -name = "sketches" -version = "0.1.0" -dependencies = [ - "libdd-ddsketch 1.1.0", - "wasm-bindgen", -] +checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea" [[package]] name = "slab" @@ -2917,15 +2967,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", @@ -2965,7 +3015,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3000,9 +3050,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -3011,9 +3061,9 @@ dependencies = [ [[package]] name = "syn" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f" dependencies = [ "proc-macro2", "quote", @@ -3028,7 +3078,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3048,17 +3098,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.52.0", + "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" @@ -3086,7 +3136,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3097,7 +3147,7 @@ checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] @@ -3157,9 +3207,9 @@ 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", @@ -3172,13 +3222,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 2.0.117", + "syn 3.0.4", ] [[package]] @@ -3193,13 +3243,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", ] @@ -3237,9 +3288,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" @@ -3249,9 +3300,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" @@ -3297,11 +3348,11 @@ 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", @@ -3338,29 +3389,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", @@ -3371,9 +3404,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", @@ -3381,9 +3414,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", @@ -3391,31 +3424,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 2.0.117", + "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", @@ -3435,54 +3468,20 @@ 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 2.0.117", + "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap 2.14.0", - "wasm-encoder", - "wasmparser", -] - -[[package]] -name = "wasmparser" -version = "0.244.0" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags 2.11.1", - "hashbrown 0.15.5", - "indexmap 2.14.0", - "semver", -] +checksum = "33ff1c1b360982e93b6d8ea9c04836f71dba0817a16f91e229cf3a51bdd9d987" [[package]] name = "web-time" @@ -3496,9 +3495,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" +checksum = "b96554aa2acc8ccdb7e1c9a58a7a68dd5d13bccc69cd124cb09406db612a1c9b" dependencies = [ "rustls-pki-types", ] @@ -3587,7 +3586,7 @@ checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3598,7 +3597,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3609,7 +3608,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3939,100 +3938,6 @@ dependencies = [ "windows 0.48.0", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - -[[package]] -name = "wit-bindgen" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" - -[[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap 2.14.0", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags 2.11.1", - "indexmap 2.14.0", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" -dependencies = [ - "anyhow", - "id-arena", - "indexmap 2.14.0", - "log", - "semver", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", -] - [[package]] name = "writeable" version = "0.6.4" @@ -4058,28 +3963,28 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -4099,15 +4004,15 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zerotrie" @@ -4139,14 +4044,49 @@ checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" dependencies = [ "proc-macro2", "quote", - "syn 3.0.3", + "syn 3.0.4", ] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" + +[[package]] +name = "zrip" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +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 = "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/README.md b/README.md index 69caebcd..f8f8d834 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,41 @@ -# 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 optional native platform packages with an inlined WASM fallback. +- `@datadog/libdatadog-extras` provides additional functionality that is not + available or needed everywhere through native prebuilds and standalone WASM + modules. + +## `@datadog/libdatadog` + +The universal package is maintained under +[`packages/libdatadog`](packages/libdatadog). Its matching native and WASM +backends expose Zstandard compression and DDSketch from a single native or +WASM artifact. + +The package tries a platform-native napi-rs backend first. Native artifacts are +published as optional dependencies using napi-rs-compatible package names such +as `@datadog/libdatadog-linux-x64-gnu`. If the platform package cannot be +loaded, the package falls back to a wasm-bindgen backend whose WebAssembly bytes +are embedded in JavaScript. This fallback is always part of the metapackage, so +it also works when native extensions are unavailable, omitted by a bundler, or +moved to another platform. + +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/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-wasm/Cargo.toml b/crates/libdatadog-wasm/Cargo.toml new file mode 100644 index 00000000..1648b8cb --- /dev/null +++ b/crates/libdatadog-wasm/Cargo.toml @@ -0,0 +1,33 @@ +[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" +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"] } + +[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", +] diff --git a/crates/libdatadog-wasm/src/lib.rs b/crates/libdatadog-wasm/src/lib.rs new file mode 100644 index 00000000..259fcacf --- /dev/null +++ b/crates/libdatadog-wasm/src/lib.rs @@ -0,0 +1,2 @@ +mod sketches; +mod zstd; diff --git a/crates/sketches/src/lib.rs b/crates/libdatadog-wasm/src/sketches/mod.rs similarity index 100% rename from crates/sketches/src/lib.rs rename to crates/libdatadog-wasm/src/sketches/mod.rs 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/libdatadog/Cargo.toml b/crates/libdatadog/Cargo.toml new file mode 100644 index 00000000..f15da88a --- /dev/null +++ b/crates/libdatadog/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "libdatadog" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] +name = "libdatadog" + +[dependencies] +napi = { version = "3", default-features = false, features = ["napi8"] } +napi-derive = "3" +libdd-ddsketch = "1.1.1" +zstd = { version = "0.13.3", default-features = false, features = ["thin"] } + +[build-dependencies] +napi-build = "2" diff --git a/crates/libdatadog/build.rs b/crates/libdatadog/build.rs new file mode 100644 index 00000000..0f1b0100 --- /dev/null +++ b/crates/libdatadog/build.rs @@ -0,0 +1,3 @@ +fn main() { + napi_build::setup(); +} diff --git a/crates/libdatadog/src/lib.rs b/crates/libdatadog/src/lib.rs new file mode 100644 index 00000000..259fcacf --- /dev/null +++ b/crates/libdatadog/src/lib.rs @@ -0,0 +1,2 @@ +mod sketches; +mod zstd; diff --git a/crates/libdatadog/src/sketches/mod.rs b/crates/libdatadog/src/sketches/mod.rs new file mode 100644 index 00000000..d8fef5f0 --- /dev/null +++ b/crates/libdatadog/src/sketches/mod.rs @@ -0,0 +1,41 @@ +use libdd_ddsketch::DDSketch as InnerDDSketch; +use napi::bindgen_prelude::*; +use napi_derive::napi; + +#[napi(js_name = "DDSketch")] +#[derive(Default)] +pub struct DDSketch { + inner: InnerDDSketch, +} + +#[napi] +impl DDSketch { + #[napi(constructor)] + pub fn new() -> Self { + Self::default() + } + + #[napi] + pub fn add(&mut self, point: f64) -> Result<()> { + self.inner + .add(point) + .map_err(|error| Error::from_reason(error.to_string())) + } + + #[napi(js_name = "addWithCount")] + pub fn add_with_count(&mut self, point: f64, count: f64) -> Result<()> { + self.inner + .add_with_count(point, count) + .map_err(|error| Error::from_reason(error.to_string())) + } + + #[napi] + pub fn count(&self) -> f64 { + self.inner.count() + } + + #[napi] + pub fn encode(&self) -> Buffer { + self.inner.clone().encode_to_vec().into() + } +} diff --git a/crates/libdatadog/src/zstd/mod.rs b/crates/libdatadog/src/zstd/mod.rs new file mode 100644 index 00000000..779a8046 --- /dev/null +++ b/crates/libdatadog/src/zstd/mod.rs @@ -0,0 +1,9 @@ +use napi::bindgen_prelude::*; +use napi_derive::napi; + +#[napi(js_name = "zstd_compress")] +pub fn zstd_compress(data: Buffer, level: i32) -> Result { + zstd::encode_all(data.as_ref(), level) + .map(Buffer::from) + .map_err(|error| Error::from_reason(format!("failed to compress data: {error}"))) +} diff --git a/crates/library_config/Cargo.toml b/crates/library_config/Cargo.toml index a3aa5855..02e9383c 100644 --- a/crates/library_config/Cargo.toml +++ b/crates/library_config/Cargo.toml @@ -11,8 +11,6 @@ anyhow = "1" 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/sketches/Cargo.toml b/crates/sketches/Cargo.toml deleted file mode 100644 index 6747f461..00000000 --- a/crates/sketches/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "sketches" -version = "0.1.0" -edition = "2021" -description = "Wasm bindings for Datadog's DDSketch" - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -libdd-ddsketch = { git = "https://github.com/DataDog/libdatadog.git", rev = "3081603d3c74f209be4e3be951f78a1a7469397f" } -wasm-bindgen = "0.2" - -[package.metadata.wasm-pack.profile.release] -wasm-opt = ["-O", "--enable-bulk-memory", "--enable-nontrapping-float-to-int"] diff --git a/eslint.config.js b/eslint.config.js index 690debfb..b59926fb 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', @@ -79,6 +85,17 @@ module.exports = [ 'unicorn/consistent-function-scoping': 'off', }, }, + { + // 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/test/bundlers.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. @@ -88,6 +105,13 @@ module.exports = [ }, }, { - 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 a5d1e6c3..552476ab 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.1.0-pre", + "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", diff --git a/packages/libdatadog/.gitignore b/packages/libdatadog/.gitignore new file mode 100644 index 00000000..7262e8bc --- /dev/null +++ b/packages/libdatadog/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +dist/ +wasm/dist/ +*.node +*.wasm diff --git a/packages/libdatadog/README.md b/packages/libdatadog/README.md new file mode 100644 index 00000000..8406c780 --- /dev/null +++ b/packages/libdatadog/README.md @@ -0,0 +1,24 @@ +# @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. + +Universal Node.js bindings for libdatadog. Matching native and WASM bindings +are maintained in the root `crates/libdatadog` and `crates/libdatadog-wasm` +workspace crates. Optional libdatadog functionality is published separately as +`@datadog/libdatadog-extras`. + +Both backends expose Zstandard compression and DDSketch from a single native +or WASM artifact. + +The package tries a platform-native napi-rs backend first and falls back to 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. This directory +is itself the published metapackage. Platform-native packages follow the +napi-rs layout, are generated in `dist/packages`, and are installed as optional +dependencies. They are not npm workspaces because their mutually exclusive +`os`, `cpu`, and `libc` constraints would make local workspace installs +platform-dependent. No raw `.wasm` asset is published. diff --git a/packages/libdatadog/index.d.ts b/packages/libdatadog/index.d.ts new file mode 100644 index 00000000..9e026144 --- /dev/null +++ b/packages/libdatadog/index.d.ts @@ -0,0 +1,10 @@ +export function backend(): 'native' | '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..3c5e69a9 --- /dev/null +++ b/packages/libdatadog/index.js @@ -0,0 +1,3 @@ +'use strict' + +module.exports = require('./lib/load') diff --git a/packages/libdatadog/index.mjs b/packages/libdatadog/index.mjs new file mode 100644 index 00000000..9c1a9a9b --- /dev/null +++ b/packages/libdatadog/index.mjs @@ -0,0 +1,9 @@ +import libdatadog from './index.js' + +export const { + backend, + DDSketch, + zstd_compress, +} = libdatadog + +export { default } from './index.js' diff --git a/packages/libdatadog/lib/load.js b/packages/libdatadog/lib/load.js new file mode 100644 index 00000000..af12c48c --- /dev/null +++ b/packages/libdatadog/lib/load.js @@ -0,0 +1,11 @@ +'use strict' + +let native + +try { + native = require('./native') +} catch { + native = undefined +} + +module.exports = native ?? require('./wasm') diff --git a/packages/libdatadog/lib/native.js b/packages/libdatadog/lib/native.js new file mode 100644 index 00000000..86b430ff --- /dev/null +++ b/packages/libdatadog/lib/native.js @@ -0,0 +1,49 @@ +'use strict' + +const path = require('node:path') +const os = require('node:os') + +const target = getNativeTarget() +const binding = loadBinding(target) + +function getNativeTarget () { + const platform = os.platform() + const architecture = process.arch + + if (platform === 'darwin' && (architecture === 'arm64' || architecture === 'x64')) { + return `${platform}-${architecture}` + } + + if (platform === 'linux' && (architecture === 'arm64' || architecture === 'x64')) { + const libc = process.report?.getReport?.().header?.glibcVersionRuntime ? 'gnu' : 'musl' + return `linux-${architecture}-${libc}` + } + + throw new Error(`unsupported native libdatadog platform: ${platform}-${architecture}`) +} + +function loadBinding (target) { + if (process.env.DD_LIBDATADOG_NATIVE_PATH) { + return require(path.resolve(process.env.DD_LIBDATADOG_NATIVE_PATH)) + } + + const localArtifact = path.join( + __dirname, + '..', + 'dist', + 'native', + `libdatadog.${target}.node`, + ) + + try { + return require(localArtifact) + } catch { + return require(`@datadog/libdatadog-${target}`) + } +} + +module.exports = { + backend: () => 'native', + DDSketch: binding.DDSketch, + zstd_compress: binding.zstd_compress, +} diff --git a/packages/libdatadog/lib/wasm.js b/packages/libdatadog/lib/wasm.js new file mode 100644 index 00000000..8274b437 --- /dev/null +++ b/packages/libdatadog/lib/wasm.js @@ -0,0 +1,9 @@ +'use strict' + +const binding = require('@datadog/libdatadog-wasm') + +module.exports = { + backend: () => 'wasm', + DDSketch: binding.DDSketch, + zstd_compress: binding.zstd_compress, +} diff --git a/packages/libdatadog/package-lock.json b/packages/libdatadog/package-lock.json new file mode 100644 index 00000000..5d8940df --- /dev/null +++ b/packages/libdatadog/package-lock.json @@ -0,0 +1,3869 @@ +{ + "name": "@datadog/libdatadog", + "version": "0.1.0-pre", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@datadog/libdatadog", + "version": "0.1.0-pre", + "license": "Apache-2.0", + "workspaces": [ + "wasm" + ], + "dependencies": { + "@datadog/libdatadog-wasm": "0.1.0-pre" + }, + "devDependencies": { + "@napi-rs/cli": "^3.5.1", + "esbuild": "^0.28.2", + "typescript": "^6.0.3", + "webpack": "^5.109.2", + "webpack-cli": "^7.2.2" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@datadog/libdatadog-darwin-arm64": "0.1.0-pre", + "@datadog/libdatadog-darwin-x64": "0.1.0-pre", + "@datadog/libdatadog-linux-arm64-gnu": "0.1.0-pre", + "@datadog/libdatadog-linux-arm64-musl": "0.1.0-pre", + "@datadog/libdatadog-linux-x64-gnu": "0.1.0-pre", + "@datadog/libdatadog-linux-x64-musl": "0.1.0-pre" + } + }, + "node_modules/@datadog/libdatadog-darwin-arm64": { + "optional": true + }, + "node_modules/@datadog/libdatadog-darwin-x64": { + "optional": true + }, + "node_modules/@datadog/libdatadog-linux-arm64-gnu": { + "optional": true + }, + "node_modules/@datadog/libdatadog-linux-arm64-musl": { + "optional": true + }, + "node_modules/@datadog/libdatadog-linux-x64-gnu": { + "optional": true + }, + "node_modules/@datadog/libdatadog-linux-x64-musl": { + "optional": true + }, + "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/@emnapi/core": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", + "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", + "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.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/@inquirer/ansi": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.7.tgz", + "integrity": "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.2.1.tgz", + "integrity": "sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.7", + "@inquirer/core": "^11.2.1", + "@inquirer/figures": "^2.0.7", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.1.1.tgz", + "integrity": "sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.2.1", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "11.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.2.1.tgz", + "integrity": "sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.2.2.tgz", + "integrity": "sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.2.1", + "@inquirer/external-editor": "^3.0.3", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.1.1.tgz", + "integrity": "sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.2.1", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.2" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.7.tgz", + "integrity": "sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + } + }, + "node_modules/@inquirer/input": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.1.2.tgz", + "integrity": "sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.2.1", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.1.1.tgz", + "integrity": "sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.2.1", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.1.1.tgz", + "integrity": "sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.7", + "@inquirer/core": "^11.2.1", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.5.2.tgz", + "integrity": "sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.3.1.tgz", + "integrity": "sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.2.1", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.2.1.tgz", + "integrity": "sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^11.2.1", + "@inquirer/figures": "^2.0.7", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.2.1.tgz", + "integrity": "sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^2.0.7", + "@inquirer/core": "^11.2.1", + "@inquirer/figures": "^2.0.7", + "@inquirer/type": "^4.0.7" + }, + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.7.tgz", + "integrity": "sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "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/@napi-rs/cli": { + "version": "3.8.6", + "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-3.8.6.tgz", + "integrity": "sha512-FnJ9fghsV9Q4zh2aJGPSvQiUlJRC27B6KhzAXcIW2rlSD8keak3mhXw4tJYa3KJkP9whETfsPwqp/DJRnQg5ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/prompts": "^8.5.2", + "@napi-rs/cross-toolchain": "^1.0.3", + "@napi-rs/wasm-tools": "^1.1.0", + "@octokit/rest": "^22.0.1", + "clipanion": "^4.0.0-rc.4", + "colorette": "^2.0.20", + "es-toolkit": "^1.47.0", + "js-yaml": "^4.2.0", + "obug": "^2.1.2", + "semver": "^7.8.2", + "typanion": "^3.14.0", + "typescript": "^6.0.3" + }, + "bin": { + "napi": "dist/cli.js", + "napi-raw": "cli.mjs" + }, + "engines": { + "node": "^20.17.0 || ^22.13.0 || >= 23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4", + "emnapi": "^1.7.1 || ^2.0.0-alpha.4" + }, + "peerDependenciesMeta": { + "@emnapi/core": { + "optional": true + }, + "@emnapi/runtime": { + "optional": true + }, + "emnapi": { + "optional": true + } + } + }, + "node_modules/@napi-rs/cross-toolchain": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@napi-rs/cross-toolchain/-/cross-toolchain-1.0.3.tgz", + "integrity": "sha512-ENPfLe4937bsKVTDA6zdABx4pq9w0tHqRrJHyaGxgaPq03a2Bd1unD5XSKjXJjebsABJ+MjAv1A2OvCgK9yehg==", + "dev": true, + "license": "MIT", + "workspaces": [ + ".", + "arm64/*", + "x64/*" + ], + "dependencies": { + "@napi-rs/lzma": "^1.4.5", + "@napi-rs/tar": "^1.1.0", + "debug": "^4.4.1" + }, + "peerDependencies": { + "@napi-rs/cross-toolchain-arm64-target-aarch64": "^1.0.3", + "@napi-rs/cross-toolchain-arm64-target-armv7": "^1.0.3", + "@napi-rs/cross-toolchain-arm64-target-ppc64le": "^1.0.3", + "@napi-rs/cross-toolchain-arm64-target-s390x": "^1.0.3", + "@napi-rs/cross-toolchain-arm64-target-x86_64": "^1.0.3", + "@napi-rs/cross-toolchain-x64-target-aarch64": "^1.0.3", + "@napi-rs/cross-toolchain-x64-target-armv7": "^1.0.3", + "@napi-rs/cross-toolchain-x64-target-ppc64le": "^1.0.3", + "@napi-rs/cross-toolchain-x64-target-s390x": "^1.0.3", + "@napi-rs/cross-toolchain-x64-target-x86_64": "^1.0.3" + }, + "peerDependenciesMeta": { + "@napi-rs/cross-toolchain-arm64-target-aarch64": { + "optional": true + }, + "@napi-rs/cross-toolchain-arm64-target-armv7": { + "optional": true + }, + "@napi-rs/cross-toolchain-arm64-target-ppc64le": { + "optional": true + }, + "@napi-rs/cross-toolchain-arm64-target-s390x": { + "optional": true + }, + "@napi-rs/cross-toolchain-arm64-target-x86_64": { + "optional": true + }, + "@napi-rs/cross-toolchain-x64-target-aarch64": { + "optional": true + }, + "@napi-rs/cross-toolchain-x64-target-armv7": { + "optional": true + }, + "@napi-rs/cross-toolchain-x64-target-ppc64le": { + "optional": true + }, + "@napi-rs/cross-toolchain-x64-target-s390x": { + "optional": true + }, + "@napi-rs/cross-toolchain-x64-target-x86_64": { + "optional": true + } + } + }, + "node_modules/@napi-rs/lzma": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma/-/lzma-1.5.1.tgz", + "integrity": "sha512-sgOZ89+y8cDbY+3WbzR8CtIhCuFRWotZ9/2PjPVDJHz6np5KFTAev0DrwiyTJTgFsCRDhfGlbmhMgyhHbWdZ6g==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^22.20 || ^24.12 || >=25" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/lzma-android-arm-eabi": "1.5.1", + "@napi-rs/lzma-android-arm64": "1.5.1", + "@napi-rs/lzma-darwin-arm64": "1.5.1", + "@napi-rs/lzma-darwin-x64": "1.5.1", + "@napi-rs/lzma-freebsd-x64": "1.5.1", + "@napi-rs/lzma-linux-arm-gnueabihf": "1.5.1", + "@napi-rs/lzma-linux-arm64-gnu": "1.5.1", + "@napi-rs/lzma-linux-arm64-musl": "1.5.1", + "@napi-rs/lzma-linux-ppc64-gnu": "1.5.1", + "@napi-rs/lzma-linux-riscv64-gnu": "1.5.1", + "@napi-rs/lzma-linux-s390x-gnu": "1.5.1", + "@napi-rs/lzma-linux-x64-gnu": "1.5.1", + "@napi-rs/lzma-linux-x64-musl": "1.5.1", + "@napi-rs/lzma-wasm32-wasi": "1.5.1", + "@napi-rs/lzma-win32-arm64-msvc": "1.5.1", + "@napi-rs/lzma-win32-ia32-msvc": "1.5.1", + "@napi-rs/lzma-win32-x64-msvc": "1.5.1" + } + }, + "node_modules/@napi-rs/lzma-android-arm-eabi": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-android-arm-eabi/-/lzma-android-arm-eabi-1.5.1.tgz", + "integrity": "sha512-sahBe4ko2Z69NPTddaX6ZgbQZu9SDoITxw1S3dWl1gAGynZG34qHHCT8UaUMFxf3h3zMhCJjEzz4basaBxiTuQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-android-arm64": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-android-arm64/-/lzma-android-arm64-1.5.1.tgz", + "integrity": "sha512-7tkQAJJuBHxAxiEBNFgSTpvrtGpbwZYYJUSOmGEK3OfbdbNeoT2rdBxpM/gY1s+itEVbtOSlpaRPPG19MnwOzA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-darwin-arm64": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-darwin-arm64/-/lzma-darwin-arm64-1.5.1.tgz", + "integrity": "sha512-XWX8gtF+GHGk3nH3Wm3QUZNcxw9QHsFVZz3MzVLhWWHhceede1J4/vD+3dj3E1iKB9G6mualaZxOoD08R3E+7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-darwin-x64": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-darwin-x64/-/lzma-darwin-x64-1.5.1.tgz", + "integrity": "sha512-CfsqUpMTI1z8enrA/b+GcHM6YDI8D0kqCiqPYEnst4rbOABQ9KZ92ybTTNnlnZ7A017WoMZKUEWc36KXDwi0xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-freebsd-x64": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-freebsd-x64/-/lzma-freebsd-x64-1.5.1.tgz", + "integrity": "sha512-bTyNfg90FXIgE61U7l14aMmVOqRQ6AyP5JMT3jmCStaZI18apLNPdzZ8i7yqxZfKvRMVfPjE2brXIw27c+RRgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-linux-arm-gnueabihf": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-arm-gnueabihf/-/lzma-linux-arm-gnueabihf-1.5.1.tgz", + "integrity": "sha512-vNE+D8nrw+eOkBsdKCsmDhowDV3pIMKXEhedvXfbgrWbrO7GlZJH+RXL+X+RYLxGwi8Ym61ZMt15sIOnNmh9Sw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-linux-arm64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-arm64-gnu/-/lzma-linux-arm64-gnu-1.5.1.tgz", + "integrity": "sha512-csUem4WgoKGTprv/pOPm9UIWbb+hrfUwYXefpTHPAEGVFLl5behEFabisJ7FtihCa3yG2Efcl+yw25rlhhrIYw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-linux-arm64-musl": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-arm64-musl/-/lzma-linux-arm64-musl-1.5.1.tgz", + "integrity": "sha512-kB/xhlVN1eLvVmDJSKZEjp5Gg2xDYexNrB5jwpSMbOkeGS6N9AasByPBg5VqCpMYC+zZi7DM458DRhtWYhqXTQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-linux-ppc64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-ppc64-gnu/-/lzma-linux-ppc64-gnu-1.5.1.tgz", + "integrity": "sha512-s28RW0W1yBWQc1nbPdF7tp14koqslY3ZWLVI8uaanX292Dc6ezd4NPVwxEoCNBVON/oD7BmUbWGtyFvmm7dQ5A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-linux-riscv64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-riscv64-gnu/-/lzma-linux-riscv64-gnu-1.5.1.tgz", + "integrity": "sha512-+lGNwYlIN14YPMTNvYtIJJqHFevDTd6Juw/1NmXbWx/iRd/LLrjhlM/yluMX6pxs6NkOGsuuEXJJrbbEUS59OQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-linux-s390x-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-s390x-gnu/-/lzma-linux-s390x-gnu-1.5.1.tgz", + "integrity": "sha512-PB44FFWWFrLeQowhcep1hPD1YcLqKlnnY60RMU74qrxTlr4YGEyzeMItJqh2uivBfv9kQScOF/B0J9+Vab/oyw==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-gnu": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", + "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-linux-x64-musl": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-musl/-/lzma-linux-x64-musl-1.5.1.tgz", + "integrity": "sha512-I3nsYrWtrW9JpeCr+mkJIVDt0HY3m6qVUBs5vTtoIvJQxwqf1PBXSy5IS7T53ksQFH2kd2UX8rLxJ7B4WISpZg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-wasm32-wasi": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-wasm32-wasi/-/lzma-wasm32-wasi-1.5.1.tgz", + "integrity": "sha512-gy3wwPBa6+XEyA4fUzq6CClrXA1ajXjuVf5zbnHytJRgoHznj+mvpU3+co2fxXwqTCmIpn6KrzqH5bRDztBPhA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.2", + "@emnapi/runtime": "1.11.2", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-win32-arm64-msvc": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-arm64-msvc/-/lzma-win32-arm64-msvc-1.5.1.tgz", + "integrity": "sha512-dK+huOsHiyH6oJjij+cnjqFCakk2HgWmpI12Xm4pLUyPphe4ebYoJBgehaNAxprmjFqBQ7nL95YPVz9BHyqmPg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-win32-ia32-msvc": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-ia32-msvc/-/lzma-win32-ia32-msvc-1.5.1.tgz", + "integrity": "sha512-dGE8L+0EQ+GyU9ap9InqB/t/PmPG/bLj918q7OsJ29FuTdn8fK4OX3U4IQZhylHIA+/dQ/SXJk5n4yfah2XVvA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/lzma-win32-x64-msvc": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-x64-msvc/-/lzma-win32-x64-msvc-1.5.1.tgz", + "integrity": "sha512-EKW4t/iqdCT/xnd5t9oXLvVER/PMNAWXKqUAl3fgvUcOILeZIIht77/dVnfFcc9htA/DCBXC/6YQWdW+LusjFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^22.20 || ^24.12 || >=25" + } + }, + "node_modules/@napi-rs/tar": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar/-/tar-1.1.1.tgz", + "integrity": "sha512-p6q2HhUc5vwH1CNwfOcrhLoxfgn8ust8Sqlfx+sA4VzAcp1cMbvbkl99tZZlDqOjCHgQNSiTfk/yWPjl/D42qA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + }, + "optionalDependencies": { + "@napi-rs/tar-android-arm-eabi": "1.1.1", + "@napi-rs/tar-android-arm64": "1.1.1", + "@napi-rs/tar-darwin-arm64": "1.1.1", + "@napi-rs/tar-darwin-x64": "1.1.1", + "@napi-rs/tar-freebsd-x64": "1.1.1", + "@napi-rs/tar-linux-arm-gnueabihf": "1.1.1", + "@napi-rs/tar-linux-arm64-gnu": "1.1.1", + "@napi-rs/tar-linux-arm64-musl": "1.1.1", + "@napi-rs/tar-linux-ppc64-gnu": "1.1.1", + "@napi-rs/tar-linux-s390x-gnu": "1.1.1", + "@napi-rs/tar-linux-x64-gnu": "1.1.1", + "@napi-rs/tar-linux-x64-musl": "1.1.1", + "@napi-rs/tar-wasm32-wasi": "1.1.1", + "@napi-rs/tar-win32-arm64-msvc": "1.1.1", + "@napi-rs/tar-win32-ia32-msvc": "1.1.1", + "@napi-rs/tar-win32-x64-msvc": "1.1.1" + } + }, + "node_modules/@napi-rs/tar-android-arm-eabi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-android-arm-eabi/-/tar-android-arm-eabi-1.1.1.tgz", + "integrity": "sha512-cAhnA10cSusAUbcE9HtjQY/tZ9BH/0w2sKtRcQc94TzIlnm7QSr1htJSd/PPrbWNPtrv1orXb2CkrHlVlbnlHA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-android-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-android-arm64/-/tar-android-arm64-1.1.1.tgz", + "integrity": "sha512-EslUWHCDBY/g5abTPBiHLsMaML4GagV0TXLm5WL9hAjx/DDtlxz9fegMb77RJ+f7nFLOIsUxF/3QWFvgOT0sMQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-darwin-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-darwin-arm64/-/tar-darwin-arm64-1.1.1.tgz", + "integrity": "sha512-+A42/6ES5G9CQ35BOwzwA+WBjLID28r2jNPgc0dteD2hhClIhng0mva7D2ujUlXBNmgNOsr1LHn3stA4uTf4NQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-darwin-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-darwin-x64/-/tar-darwin-x64-1.1.1.tgz", + "integrity": "sha512-RYtE8w1dkEvj8hSJCDV5Jw0Rz2i13fsM7u893zv5O9n/4Ad5GNsw/f4RQ7/0YGSFaenkVxqPFrjmEvUHlKzsrg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-freebsd-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-freebsd-x64/-/tar-freebsd-x64-1.1.1.tgz", + "integrity": "sha512-rEepBvCJUwcuvUYkY83e8aot8RsR5Jcnal4PsG3tbWGKW1yAvcXhyMXf0fN6ZGpVRZFnB+FJqDyBxvsCPEXKhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-linux-arm-gnueabihf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-arm-gnueabihf/-/tar-linux-arm-gnueabihf-1.1.1.tgz", + "integrity": "sha512-an1bJdfyhI5FpZYyTQ20mrqwR+a676i8GkaYc4Uy12dH/a7TJIfrK6Qa2Gm46arZvxUvx56qxoRKXbpOjUPvwA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-linux-arm64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-arm64-gnu/-/tar-linux-arm64-gnu-1.1.1.tgz", + "integrity": "sha512-w++Vtx36T2yHTKws7GVnmHHcUT1ybB59xLWSh9A8bwEpJVG4dG7Qub9mFe5cpcbfrJ+XP2mKKxC3oUJSunK3iQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-linux-arm64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-arm64-musl/-/tar-linux-arm64-musl-1.1.1.tgz", + "integrity": "sha512-Rh6UFhNtj3i4deJHOBINFIeRL0072mgbeyuK5rl1HokKnNoMKx8qKIZNEzBTTqpogMfDHWGvzyTQdnVxes5dpA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-linux-ppc64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-ppc64-gnu/-/tar-linux-ppc64-gnu-1.1.1.tgz", + "integrity": "sha512-Cp+AxFbv9zcyAXtnzQi0OzmgDnQgy2w9D4Ubr+iwzMtVgJcztzcEoCcCrN1k2ATdEB01LX2Vb49IaocGOZhC9Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-linux-s390x-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-s390x-gnu/-/tar-linux-s390x-gnu-1.1.1.tgz", + "integrity": "sha512-ZyscC3SYKTBWyDRYjLOKAd5TyJ7q0KACRdQ8bWrb3rgrra1CCIJD66CsGTH6Dh0AVSdfLwZ8MfIIXU6+14BMjQ==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-linux-x64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-x64-gnu/-/tar-linux-x64-gnu-1.1.1.tgz", + "integrity": "sha512-LlIv+zg4fiOQge9LQX/ieBdRWE2fhVDjCTHxnunZkbugNmdhdelxWf1RpZb/6ZujWpNF4LPu4N/MW7ygg2oYAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-linux-x64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-x64-musl/-/tar-linux-x64-musl-1.1.1.tgz", + "integrity": "sha512-gZBeoKLjanOVj55qk4EMu13P2i9M0SuINmlGQkOxm1niIJofexzddHUYtqO5o/5QqtyL8lADmAcZplLILMLhHA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-wasm32-wasi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-wasm32-wasi/-/tar-wasm32-wasi-1.1.1.tgz", + "integrity": "sha512-rwtQ1Mdt/ft6g6I54fJzbUeLspl4yTwj6I3UJ6mitKnrN42soJkcDrdh3Y/FGvlpqZTad2YMQ96fGJl3EtAm2Q==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.2", + "@emnapi/runtime": "1.11.2", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@napi-rs/tar-win32-arm64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-arm64-msvc/-/tar-win32-arm64-msvc-1.1.1.tgz", + "integrity": "sha512-30PVp1AehRpfwxmv5wI4cg0yj3WmWBsZ+1QnLGnvEELu7Eu/+dhNU0nrmhI7VfPgLwSRK2eg9DQTB3tP7Wv9bA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-win32-ia32-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-ia32-msvc/-/tar-win32-ia32-msvc-1.1.1.tgz", + "integrity": "sha512-aI3/rmz+izUChiSeaPxcasAOxhf3FpJNuIHMXlxS/vpW+HIxUsSDR5+XV61PEG5DL4L/75iENVUxmSGM5l2yaw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/tar-win32-x64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-x64-msvc/-/tar-win32-x64-msvc-1.1.1.tgz", + "integrity": "sha512-yJsB2IsrODQVLKbm2Fg1nHiVRbEj49mSPbj4x7JPZWJI0jGVPjohE2Sif0FBbx8OxsVoUODvS0BwksZZ8jl/OA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz", + "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" + } + }, + "node_modules/@napi-rs/wasm-tools": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools/-/wasm-tools-1.1.0.tgz", + "integrity": "sha512-VjHyKEqXAwYZK+HY7iJctYvRm3TFEbaQxeZwvAG1QRkoo1a39phMY8J6x9tUEqJI03W6MysB8F2jacI6wvcx+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.22.0" + }, + "optionalDependencies": { + "@napi-rs/wasm-tools-android-arm-eabi": "1.1.0", + "@napi-rs/wasm-tools-android-arm64": "1.1.0", + "@napi-rs/wasm-tools-darwin-arm64": "1.1.0", + "@napi-rs/wasm-tools-darwin-x64": "1.1.0", + "@napi-rs/wasm-tools-freebsd-x64": "1.1.0", + "@napi-rs/wasm-tools-linux-arm64-gnu": "1.1.0", + "@napi-rs/wasm-tools-linux-arm64-musl": "1.1.0", + "@napi-rs/wasm-tools-linux-x64-gnu": "1.1.0", + "@napi-rs/wasm-tools-linux-x64-musl": "1.1.0", + "@napi-rs/wasm-tools-wasm32-wasi": "1.1.0", + "@napi-rs/wasm-tools-win32-arm64-msvc": "1.1.0", + "@napi-rs/wasm-tools-win32-ia32-msvc": "1.1.0", + "@napi-rs/wasm-tools-win32-x64-msvc": "1.1.0" + } + }, + "node_modules/@napi-rs/wasm-tools-android-arm-eabi": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-android-arm-eabi/-/wasm-tools-android-arm-eabi-1.1.0.tgz", + "integrity": "sha512-p6J8PB59I8d/XItXB/go5JH6nKW+xIbpzaL43EBTV0hi7mrS/Z4gs+MsB04ZrlqZN29BdZV8fChRyasuXLhRaA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-android-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-android-arm64/-/wasm-tools-android-arm64-1.1.0.tgz", + "integrity": "sha512-lWoKN3suypeBSCIRPIw+++sH9V2K6nQkhtdt1opu7XY3v9JwLs6Gw063HWRqkNjphlYpkd/Qy8XcfSPGbJj7nQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-darwin-arm64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-darwin-arm64/-/wasm-tools-darwin-arm64-1.1.0.tgz", + "integrity": "sha512-jfw5vyNDUf6oe0kP8lMveFN9U7cLk1cUosS7uMIfw/xmqmopYfKQ198DAx2g/6aEF7Tm+CqER2gpMpYKui30LA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-darwin-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-darwin-x64/-/wasm-tools-darwin-x64-1.1.0.tgz", + "integrity": "sha512-R+pjeudAB7BYdH1vKkOJM61Tfv5jB6uXkxmFscYd+KKpdUpWBlNG+s4hr0w4i1rMBM91VhIAETZn2pz+MDHK9A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-freebsd-x64": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-freebsd-x64/-/wasm-tools-freebsd-x64-1.1.0.tgz", + "integrity": "sha512-hQJTe+aazrT++Vgm6I4lUd9099ItUCFYdd+aKg6Ys6nax6d/cZ1barDLTwA2lwOoVDsXMekJI/FOL6ZvVlIYBg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-linux-arm64-gnu": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-arm64-gnu/-/wasm-tools-linux-arm64-gnu-1.1.0.tgz", + "integrity": "sha512-1TAXJxUHsWGar90k3W/MknavvBMwOWzjh7Q6Spxo8twRcWJbBD5Kow/Q2KhhDq5hxh2sKGDXn3uLc1tdtz4WUg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-linux-arm64-musl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-arm64-musl/-/wasm-tools-linux-arm64-musl-1.1.0.tgz", + "integrity": "sha512-7rw3nlubTjNAVRH2LwphCxHy1b/N2/TerXocQ6XRn4Q+buaY1Z7P/hbdALy1i1ex2yfOU2Xcij7ib7ZLi/lKfw==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-linux-x64-gnu": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-x64-gnu/-/wasm-tools-linux-x64-gnu-1.1.0.tgz", + "integrity": "sha512-1sel0t9MRjI/tdT89M8Dd6gPfANeeFP24Xa46R11WeHNwhjsXXZh+xUk50uWCRTSGcaCy3ugm3AMK/lmHYQJkg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-linux-x64-musl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-x64-musl/-/wasm-tools-linux-x64-musl-1.1.0.tgz", + "integrity": "sha512-o2jH5AMfor4EKF2HII1LBnMQxoWu7+usPifTEY8Zk6e9OiSi4EJkAXf9v3ANlX7TI2V/cUEV34OEW7r10GiVIA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-wasm32-wasi": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-wasm32-wasi/-/wasm-tools-wasm32-wasi-1.1.0.tgz", + "integrity": "sha512-s6YDtDR1UWrsqJPtaxf+JLYLceWVyn3l8OpQYElHkDhf3Qfz9R6Ba3S0OgznTBv38L5/TIHysQ9Q4yO73Z0csg==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.9.2", + "@emnapi/runtime": "1.9.2", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@napi-rs/wasm-tools-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", + "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.1", + "tslib": "^2.4.0" + } + }, + "node_modules/@napi-rs/wasm-tools-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", + "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@napi-rs/wasm-tools-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@napi-rs/wasm-tools-win32-arm64-msvc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-arm64-msvc/-/wasm-tools-win32-arm64-msvc-1.1.0.tgz", + "integrity": "sha512-x+NuxbG84VxU68tU8w7Rf5lSyq0l584M6dVlke5DTweHYFZoMyeqkpbwEq+qsyAX6ivfipK8xRsmFwamb5uDnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-win32-ia32-msvc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-ia32-msvc/-/wasm-tools-win32-ia32-msvc-1.1.0.tgz", + "integrity": "sha512-mdD96QDEp70SX67rXFTY6c725nVYeqEEjyDqzzbNh6u1APj7CI7IMNpMmvE75XbCRl4C2MHZVU4U6AWdAzvyQQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@napi-rs/wasm-tools-win32-x64-msvc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-x64-msvc/-/wasm-tools-win32-x64-msvc-1.1.0.tgz", + "integrity": "sha512-bVVjuvhlyVX++3eJXfDR63cXdw1ay5QYac6iq0MKQw8wZARInTM+bXCtByDT4fzVFI3+7ZthYb/ERWRdBNIqgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.22.0" + } + }, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", + "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/core": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.7.tgz", + "integrity": "sha512-DcB0M3KFgr9ECI328lhBMVsyFT2DnmNucSBTqEN3exyNKUzkkpUSCHmTRcunF41Eou2TIQKW4seewri8ON9bSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.4", + "@octokit/request": "^10.0.13", + "@octokit/request-error": "^7.1.1", + "@octokit/types": "^17.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/endpoint": { + "version": "11.0.4", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.4.tgz", + "integrity": "sha512-f1cOWoHPmxryJFknxbtDdjODWfV8A9tc8Aae6ermXPNgHFZ/x91AtHIz4gicEjL8hkJiip+u21QHJORfBv/qiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^17.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/graphql": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.4.tgz", + "integrity": "sha512-5s15CCiY8XXQ+FG+b1YQcl6Z2FA++nwAz/tg2VUrTmnMncP+2nnGUEYANImdnxsA2Fnq+Mbl7hDjUTw7cFAwcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/request": "^10.0.13", + "@octokit/types": "^17.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "28.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz", + "integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", + "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", + "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", + "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^16.0.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": { + "version": "27.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", + "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "16.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", + "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^27.0.0" + } + }, + "node_modules/@octokit/request": { + "version": "10.0.13", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.13.tgz", + "integrity": "sha512-v2269YxL9Yf+x3d+gRI63FP0vFQEiWgLyBzxe/Y+0yFDg2B/Tzf5dhh9VNfccVAQnfcfwQWyk/y6Bn7rUXXs7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^11.0.3", + "@octokit/request-error": "^7.1.1", + "@octokit/types": "^17.0.0", + "content-type": "^2.0.0", + "json-with-bigint": "^3.5.3", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.1.tgz", + "integrity": "sha512-+eaY7G2VVpSf2pc5Gn1+mph837V/d/TYTJAgWL9Tb0ogGYcpN3IlAVFgjL+Vv93F/sevrxkvsYCedtpLdcFLzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/types": "^17.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/rest": { + "version": "22.0.1", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.1.tgz", + "integrity": "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==", + "dev": true, + "license": "MIT", + "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" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/types": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz", + "integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^28.0.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "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/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "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/before-after-hook": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", + "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", + "dev": true, + "license": "Apache-2.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/chardet": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", + "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==", + "dev": true, + "license": "MIT" + }, + "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/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/clipanion": { + "version": "4.0.0-rc.4", + "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-4.0.0-rc.4.tgz", + "integrity": "sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q==", + "dev": true, + "license": "MIT", + "workspaces": [ + "website" + ], + "dependencies": { + "typanion": "^3.8.0" + }, + "peerDependencies": { + "typanion": "*" + } + }, + "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/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "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/content-type": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", + "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "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/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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/es-toolkit": { + "version": "1.51.0", + "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.51.0.tgz", + "integrity": "sha512-zC2lQGkM7QX+Gm6iM3+WIdZJzthsEd14LvRNJneSO2hzyz/zNBENR8+YXWo1cKxgPBtV6ksPYHELbcwBRzmdCw==", + "dev": true, + "license": "MIT", + "workspaces": [ + "docs", + "benchmarks", + "tests/types", + "tests/browser-compat" + ] + }, + "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-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "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/fast-wrap-ansi": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", + "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, + "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/iconv-lite": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", + "dev": true, + "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/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/js-yaml": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", + "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "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/json-with-bigint": { + "version": "3.5.12", + "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.12.tgz", + "integrity": "sha512-uwbF/wSSuOgC7qqlq27Xp5B6a2MHVug3t0idZdTqu0JnlFvgJuH7ju+KAk/J06C7GfhoYy2gnb9wz2INqcne7w==", + "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/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", + "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "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/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "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/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "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/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/typanion": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", + "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==", + "dev": true, + "license": "MIT", + "workspaces": [ + "website" + ] + }, + "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/universal-user-agent": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", + "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", + "dev": true, + "license": "ISC" + }, + "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.1.0-pre", + "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..f26db5e0 --- /dev/null +++ b/packages/libdatadog/package.json @@ -0,0 +1,78 @@ +{ + "name": "@datadog/libdatadog", + "version": "0.1.0-pre", + "description": "Universal 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" + } + }, + "files": [ + "README.md", + "index.js", + "index.mjs", + "wasm.js", + "wasm.mjs", + "index.d.ts", + "lib/" + ], + "workspaces": [ + "wasm" + ], + "engines": { + "node": ">=18" + }, + "scripts": { + "build:native": "node scripts/build-native.js", + "build:wasm": "npm run build:wasm:binary && npm run inline:wasm", + "build:wasm:binary": "node ../../scripts/build-wasm.js ../../crates/libdatadog-wasm wasm/dist", + "inline:wasm": "node scripts/inline-wasm.js", + "package:native": "node scripts/package-native.js", + "build": "npm run build:native && 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" + }, + "napi": { + "binaryName": "libdatadog", + "targets": [ + "x86_64-apple-darwin", + "aarch64-apple-darwin", + "x86_64-unknown-linux-gnu", + "aarch64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", + "aarch64-unknown-linux-musl" + ] + }, + "dependencies": { + "@datadog/libdatadog-wasm": "0.1.0-pre" + }, + "optionalDependencies": { + "@datadog/libdatadog-darwin-arm64": "0.1.0-pre", + "@datadog/libdatadog-darwin-x64": "0.1.0-pre", + "@datadog/libdatadog-linux-arm64-gnu": "0.1.0-pre", + "@datadog/libdatadog-linux-arm64-musl": "0.1.0-pre", + "@datadog/libdatadog-linux-x64-gnu": "0.1.0-pre", + "@datadog/libdatadog-linux-x64-musl": "0.1.0-pre" + }, + "devDependencies": { + "@napi-rs/cli": "^3.5.1", + "esbuild": "^0.28.2", + "typescript": "^6.0.3", + "webpack": "^5.109.2", + "webpack-cli": "^7.2.2" + } +} diff --git a/packages/libdatadog/scripts/build-native.js b/packages/libdatadog/scripts/build-native.js new file mode 100644 index 00000000..09e295f3 --- /dev/null +++ b/packages/libdatadog/scripts/build-native.js @@ -0,0 +1,30 @@ +'use strict' + +const fs = require('node:fs') +const path = require('node:path') +const { execFileSync } = require('node:child_process') + +const packageRoot = path.join(__dirname, '..') +const repositoryRoot = path.join(packageRoot, '..', '..') +const output = path.join(packageRoot, 'dist', 'native') +const napi = path.join( + packageRoot, + 'node_modules', + '.bin', + process.platform === 'win32' ? 'napi.cmd' : 'napi', +) + +fs.rmSync(output, { force: true, recursive: true }) +execFileSync(napi, [ + 'build', + '-r', + '--platform', + '--manifest-path', + path.join(repositoryRoot, 'crates', 'libdatadog', 'Cargo.toml'), + '-o', + output, + ...process.argv.slice(2), +], { + cwd: packageRoot, + stdio: 'inherit', +}) diff --git a/packages/libdatadog/scripts/inline-wasm.js b/packages/libdatadog/scripts/inline-wasm.js new file mode 100644 index 00000000..4fc004fc --- /dev/null +++ b/packages/libdatadog/scripts/inline-wasm.js @@ -0,0 +1,35 @@ +'use strict' + +const fs = require('node:fs') +const path = require('node:path') +const { constants, brotliCompressSync } = require('node:zlib') + +const outputDirectory = path.join(__dirname, '..', 'wasm', 'dist') +const gluePath = path.join(outputDirectory, 'libdatadog_wasm.js') +const wasmPath = path.join(outputDirectory, 'libdatadog_wasm_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}/libdatadog_wasm_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/package-native.js b/packages/libdatadog/scripts/package-native.js new file mode 100644 index 00000000..0c706053 --- /dev/null +++ b/packages/libdatadog/scripts/package-native.js @@ -0,0 +1,99 @@ +'use strict' + +const fs = require('node:fs') +const path = require('node:path') + +const packageJson = require('../package.json') +const root = path.join(__dirname, '..') +const artifacts = path.join(root, 'dist', 'native') +const output = path.join(root, 'dist', 'packages') +const targets = { + 'aarch64-apple-darwin': { + packageTarget: 'darwin-arm64', + cpu: ['arm64'], + os: ['darwin'], + }, + 'x86_64-apple-darwin': { + packageTarget: 'darwin-x64', + cpu: ['x64'], + os: ['darwin'], + }, + 'aarch64-unknown-linux-gnu': { + packageTarget: 'linux-arm64-gnu', + cpu: ['arm64'], + libc: ['glibc'], + os: ['linux'], + }, + 'aarch64-unknown-linux-musl': { + packageTarget: 'linux-arm64-musl', + cpu: ['arm64'], + libc: ['musl'], + os: ['linux'], + }, + 'x86_64-unknown-linux-gnu': { + packageTarget: 'linux-x64-gnu', + cpu: ['x64'], + libc: ['glibc'], + os: ['linux'], + }, + 'x86_64-unknown-linux-musl': { + packageTarget: 'linux-x64-musl', + cpu: ['x64'], + libc: ['musl'], + os: ['linux'], + }, +} + +if (!fs.existsSync(artifacts)) throw new Error('native artifacts were not built') + +const configuredTargets = packageJson.napi.targets.map((triple) => { + const target = targets[triple] + + if (!target) throw new Error(`unsupported napi-rs target: ${triple}`) + + return { triple, ...target } +}) +const targetsByPackage = new Map( + configuredTargets.map(target => [target.packageTarget, target]), +) +const nativeArtifacts = fs.readdirSync(artifacts) + .filter(artifact => /^libdatadog\..+\.node$/.test(artifact)) + +if (nativeArtifacts.length === 0) throw new Error('native artifacts were not built') + +fs.rmSync(output, { force: true, recursive: true }) + +for (const artifact of nativeArtifacts) { + const packageTarget = artifact.slice('libdatadog.'.length, -'.node'.length) + const target = targetsByPackage.get(packageTarget) + + if (!target) throw new Error(`unsupported native artifact: ${artifact}`) + + const packageName = `${packageJson.name}-${packageTarget}` + const packageDirectory = path.join(output, packageTarget) + + fs.mkdirSync(packageDirectory, { recursive: true }) + fs.copyFileSync( + path.join(artifacts, artifact), + path.join(packageDirectory, artifact), + ) + fs.writeFileSync( + path.join(packageDirectory, 'package.json'), + JSON.stringify({ + name: packageName, + version: packageJson.version, + cpu: target.cpu, + main: artifact, + files: [artifact], + description: packageJson.description, + license: packageJson.license, + engines: packageJson.engines, + os: target.os, + ...(target.libc ? { libc: target.libc } : {}), + }, undefined, 2) + '\n', + ) + fs.writeFileSync( + path.join(packageDirectory, 'README.md'), + `# \`${packageName}\`\n\nThis is the **${target.triple}** binary for \`${packageJson.name}\`\n`, + ) +} 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..59f83768 --- /dev/null +++ b/packages/libdatadog/scripts/set-version.js @@ -0,0 +1,26 @@ +'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 +for (const name of Object.keys(packageJson.optionalDependencies)) { + packageJson.optionalDependencies[name] = 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..17cc0d7a --- /dev/null +++ b/packages/libdatadog/test/bundlers.test.js @@ -0,0 +1,58 @@ +'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 esbuild = require('esbuild') +const webpack = require('webpack') + +const packageRoot = path.join(__dirname, '..') +const entry = path.join(packageRoot, 'wasm.js') + +test('esbuild bundles the WASM entry point without emitting an asset', async () => { + await assertBundle(async (output) => { + await esbuild.build({ + bundle: true, + entryPoints: [entry], + outfile: output, + platform: 'node', + }) + }) +}) + +test('webpack bundles the WASM entry point without emitting an asset', async () => { + await assertBundle(output => new Promise((resolve, reject) => { + webpack({ + entry, + mode: 'production', + output: { + filename: path.basename(output), + path: path.dirname(output), + }, + target: 'node', + }, (error, stats) => { + if (error) return reject(error) + if (stats.hasErrors()) return reject(new Error(stats.toString({ all: false, errors: true }))) + resolve() + }) + })) +}) + +async function assertBundle (bundle) { + const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'libdatadog-bundle-')) + const output = path.join(directory, 'bundle.cjs') + + try { + await bundle(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 }) + } +} diff --git a/packages/libdatadog/test/capabilities.test.js b/packages/libdatadog/test/capabilities.test.js new file mode 100644 index 00000000..626d5a4c --- /dev/null +++ b/packages/libdatadog/test/capabilities.test.js @@ -0,0 +1,63 @@ +'use strict' + +const assert = require('node:assert/strict') +const fs = require('node:fs') +const path = require('node:path') +const { test } = require('node:test') + +const packageRoot = path.join(__dirname, '..') +const nativeDirectory = path.join(packageRoot, 'dist', 'native') +const nativeArtifact = fs.existsSync(nativeDirectory) + ? fs.readdirSync(nativeDirectory).find(file => file.startsWith('libdatadog.') && file.endsWith('.node')) + : undefined +const wasm = require('../wasm') +const native = nativeArtifact ? loadNative() : undefined + +test('native and WASM backends expose the same capabilities', { + skip: !native, +}, () => { + assert.deepStrictEqual(new Set(Object.keys(native)), new Set(Object.keys(wasm))) +}) + +test('universal backends 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/) + }) +} + +function backends () { + return [ + ['WASM', wasm], + ...(native ? [['native', native]] : []), + ] +} + +function loadNative () { + process.env.DD_LIBDATADOG_NATIVE_PATH = path.join(nativeDirectory, nativeArtifact) + try { + return require('../lib/native') + } finally { + delete process.env.DD_LIBDATADOG_NATIVE_PATH + } +} diff --git a/packages/libdatadog/test/package-contents.test.js b/packages/libdatadog/test/package-contents.test.js new file mode 100644 index 00000000..8c960514 --- /dev/null +++ b/packages/libdatadog/test/package-contents.test.js @@ -0,0 +1,242 @@ +'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 nativeTarget = process.env.LIBDATADOG_TARGET ?? getNativeTarget() +const nativePackageRoot = nativeTarget + ? path.join(packageRoot, 'dist', 'packages', nativeTarget) + : undefined +const hasNativePackage = nativePackageRoot + && fs.existsSync(path.join(nativePackageRoot, `libdatadog.${nativeTarget}.node`)) +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.strictEqual(libdatadogWasm.name, '@datadog/libdatadog-wasm') + assert.strictEqual( + metapackageJson.dependencies['@datadog/libdatadog-wasm'], + libdatadog.version, + ) + assert(!names.some(file => file.includes('.node')), + 'metapackage must not contain platform-native artifacts') + assert(!names.some(file => file.startsWith('dist/')), + 'metapackage must not contain generated backend artifacts') +}) + +test('native platform package matches the napi-rs layout', { + skip: !hasNativePackage, +}, () => { + const nativePackage = pack(nativePackageRoot) + const nativePackageJson = JSON.parse(fs.readFileSync( + path.join(nativePackageRoot, 'package.json'), + 'utf8', + )) + const binary = `libdatadog.${nativeTarget}.node` + + assert.strictEqual( + nativePackage.name, + `@datadog/libdatadog-${nativeTarget}`, + ) + assert.strictEqual(nativePackageJson.main, binary) + assert.deepStrictEqual(nativePackageJson.files, [binary]) + assert(nativePackage.files.some(file => file.path === binary)) +}) + +test('installed metapackage falls back to 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', + '--omit=optional', + 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') + + 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, 'wasm') + } finally { + fs.rmSync(temporaryRoot, { force: true, recursive: true }) + } +}) + +test('installed metapackage selects its native optional dependency', { + skip: !hasNativePackage, +}, () => { + const temporaryRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'libdatadog-native-')) + 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-native-consumer', private: true }), + ) + + try { + const wasmTarball = createTarball(wasmPackageRoot, tarballRoot, environment) + const nativeTarball = createTarball(nativePackageRoot, tarballRoot, environment) + const metapackageTarball = createTarball(packageRoot, tarballRoot, environment) + + execFileSync(npm, [ + 'install', + '--ignore-scripts', + '--no-package-lock', + '--offline', + wasmTarball, + nativeTarball, + 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') + + assert.strictEqual(libdatadog.backend(), 'native') + assert.strictEqual(explicitWasm.backend(), 'wasm') + assertEsmImports(installRoot, environment, 'native') + } finally { + fs.rmSync(temporaryRoot, { force: true, recursive: true }) + } +}) + +function assertEsmImports (installRoot, environment, expectedBackend) { + const script = ` + import assert from 'node:assert/strict' + import libdatadog, { + backend, + DDSketch, + zstd_compress, + } from '@datadog/libdatadog' + import wasm, { + backend as wasmBackend, + DDSketch as WasmDDSketch, + zstd_compress as wasmCompress, + } from '@datadog/libdatadog/wasm' + + assert.strictEqual(backend(), ${JSON.stringify(expectedBackend)}) + assert.strictEqual(libdatadog.backend, backend) + 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(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) +} + +function getNativeTarget () { + if (process.platform === 'darwin' && ['arm64', 'x64'].includes(process.arch)) { + return `darwin-${process.arch}` + } + + if (process.platform === 'linux' && ['arm64', 'x64'].includes(process.arch)) { + const libc = process.report?.getReport?.().header?.glibcVersionRuntime + ? 'gnu' + : 'musl' + return `linux-${process.arch}-${libc}` + } +} diff --git a/packages/libdatadog/test/package.test.js b/packages/libdatadog/test/package.test.js new file mode 100644 index 00000000..5e27a400 --- /dev/null +++ b/packages/libdatadog/test/package.test.js @@ -0,0 +1,86 @@ +'use strict' + +const assert = require('node:assert/strict') +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') +}) + +test('uses napi-rs platform package names', () => { + const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'))) + const targets = [ + 'darwin-arm64', + 'darwin-x64', + 'linux-arm64-gnu', + 'linux-arm64-musl', + 'linux-x64-gnu', + 'linux-x64-musl', + ] + + assert.deepStrictEqual( + Object.keys(packageJson.optionalDependencies), + targets.map(target => `${packageJson.name}-${target}`), + ) +}) + +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, + ) + for (const version of Object.values(packageJson.optionalDependencies)) { + assert.strictEqual(version, repositoryPackageJson.version) + } +}) + +test('root entry point uses the expected backend', () => { + const libdatadog = require('..') + const nativeArtifact = getNativeArtifact() + const expected = process.env.DD_LIBDATADOG_EXPECTED_BACKEND + ?? (nativeArtifact ? 'native' : 'wasm') + + assert.strictEqual(libdatadog.backend(), expected) +}) + +test('embeds a Brotli-compressed WASM fallback below the size budgets', () => { + const gluePath = path.join( + packageRoot, + 'wasm', + 'dist', + 'libdatadog_wasm.js', + ) + 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') + const compressedWasm = Buffer.from(encodedWasm, 'base64') + assert.ok(Buffer.byteLength(glue) < 200 * 1024) + assert.ok(brotliDecompressSync(compressedWasm).length < 500 * 1024) +}) + +function getNativeArtifact () { + const nativeDirectory = path.join(packageRoot, 'dist', 'native') + + if (!fs.existsSync(nativeDirectory)) return + + return fs.readdirSync(nativeDirectory) + .find(file => /^libdatadog\..+\.node$/.test(file)) +} diff --git a/packages/libdatadog/test/types.test.ts b/packages/libdatadog/test/types.test.ts new file mode 100644 index 00000000..f921b6f6 --- /dev/null +++ b/packages/libdatadog/test/types.test.ts @@ -0,0 +1,27 @@ +import { + backend, + DDSketch, + zstd_compress, +} from '@datadog/libdatadog' +import * as wasm from '@datadog/libdatadog/wasm' + +const selectedBackend: 'native' | '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 + +void selectedBackend +void compressed +void count +void encoded +void wasmBackend +void wasmSketch +void wasmCompress 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..cbd61ba5 --- /dev/null +++ b/packages/libdatadog/wasm.mjs @@ -0,0 +1,9 @@ +import libdatadog from './wasm.js' + +export const { + backend, + 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..bc26de41 --- /dev/null +++ b/packages/libdatadog/wasm/package.json @@ -0,0 +1,15 @@ +{ + "name": "@datadog/libdatadog-wasm", + "version": "0.1.0-pre", + "description": "WASM fallback for @datadog/libdatadog", + "license": "Apache-2.0", + "type": "commonjs", + "main": "dist/libdatadog_wasm.js", + "types": "dist/libdatadog_wasm.d.ts", + "files": [ + "dist/" + ], + "engines": { + "node": ">=18" + } +} diff --git a/scripts/build-wasm.js b/scripts/build-wasm.js index acb69f4a..e94d0d76 100644 --- a/scripts/build-wasm.js +++ b/scripts/build-wasm.js @@ -11,16 +11,15 @@ // 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 libraries = [ 'library_config', - 'datadog-js-zstd', 'pipeline', 'remote_config', - 'sketches', ] const env = { @@ -35,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 } @@ -50,10 +53,40 @@ if (isMacOS) { env.CXX_wasm32_unknown_unknown = `${llvmBinDir}/clang++` } -for (const library of libraries) { - 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 {{ skipOptimization?: boolean }} options + * @returns {void} + */ +function buildWasm (cratePath, outputDirectory, options = {}) { + const { skipOptimization = false } = options + const resolvedOutputDirectory = path.resolve(cratePath, outputDirectory) + fs.rmSync(resolvedOutputDirectory, { force: true, recursive: true }) + const args = ['build'] + if (skipOptimization) args.push('--no-opt') + args.push('--target', 'nodejs', cratePath, '--out-dir', resolvedOutputDirectory) + childProcess.execFileSync('wasm-pack', args, { env }) + // 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] = process.argv.slice(2) +if (cratePath || outputDirectory) { + if (!cratePath || !outputDirectory) { + throw new Error('Both the WASM crate path and output directory are required') + } + buildWasm(path.resolve(cratePath), path.resolve(outputDirectory), { + skipOptimization: isMacOS, + }) +} else { + for (const library of libraries) { + buildWasm(`./crates/${library}`, `../../prebuilds/${library}`, { + skipOptimization: isMacOS, + }) + } } 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) +} From a67eca7c2e1fca30e91a9e06fa1a71480f6f9f95 Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Thu, 27 Aug 2026 14:04:21 -0400 Subject: [PATCH 14/20] feat(libdatadog): add apm data pipeline (#205) * feat(libdatadog): add apm data pipeline * test(libdatadog): load pipeline wasm artifact * docs(libdatadog): document cancellable sleep follow-up * test(libdatadog): stabilize timeout retry assertion * fix(libdatadog): expose pipeline API to ESM * refactor(libdatadog): share agentless pipeline adapter * chore(libdatadog): update data pipeline revision * chore(libdatadog): update data pipeline revision * chore(libdatadog): use merged data pipeline revision --- Cargo.lock | 200 ++++++++-- README.md | 4 +- crates/libdatadog-data-pipeline/Cargo.toml | 28 ++ crates/libdatadog-data-pipeline/src/lib.rs | 32 ++ crates/libdatadog-wasm/Cargo.toml | 17 + .../libdatadog-wasm/src/data_pipeline/mod.rs | 363 ++++++++++++++++++ crates/libdatadog-wasm/src/lib.rs | 1 + crates/libdatadog/Cargo.toml | 15 +- crates/libdatadog/src/data_pipeline/mod.rs | 335 ++++++++++++++++ crates/libdatadog/src/lib.rs | 1 + eslint.config.js | 1 + packages/libdatadog/README.md | 7 +- packages/libdatadog/index.d.ts | 21 + packages/libdatadog/index.mjs | 1 + .../libdatadog/lib/agentless-transport.js | 78 ++++ packages/libdatadog/lib/agentless.js | 54 +++ packages/libdatadog/lib/native.js | 3 + packages/libdatadog/lib/wasm.js | 3 + packages/libdatadog/package-lock.json | 11 + packages/libdatadog/package.json | 1 + packages/libdatadog/test/exporter.test.js | 361 +++++++++++++++++ .../libdatadog/test/package-contents.test.js | 4 + packages/libdatadog/test/transport.test.js | 82 ++++ packages/libdatadog/wasm.mjs | 1 + 24 files changed, 1591 insertions(+), 33 deletions(-) create mode 100644 crates/libdatadog-data-pipeline/Cargo.toml create mode 100644 crates/libdatadog-data-pipeline/src/lib.rs create mode 100644 crates/libdatadog-wasm/src/data_pipeline/mod.rs create mode 100644 crates/libdatadog/src/data_pipeline/mod.rs create mode 100644 packages/libdatadog/lib/agentless-transport.js create mode 100644 packages/libdatadog/lib/agentless.js create mode 100644 packages/libdatadog/test/exporter.test.js create mode 100644 packages/libdatadog/test/transport.test.js diff --git a/Cargo.lock b/Cargo.lock index 7b7cd390..4355bbe6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1206,6 +1206,12 @@ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" name = "libdatadog" version = "0.1.0" dependencies = [ + "anyhow", + "bytes", + "futures", + "http 1.5.0", + "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)", "napi 3.12.2", "napi-build", @@ -1213,6 +1219,16 @@ dependencies = [ "zstd", ] +[[package]] +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" version = "0.1.0" @@ -1222,7 +1238,7 @@ dependencies = [ "futures-core", "http 1.5.0", "js-sys", - "libdd-capabilities 3.0.0", + "libdd-capabilities 3.0.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", @@ -1232,10 +1248,17 @@ dependencies = [ 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", ] @@ -1250,6 +1273,19 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "libdd-capabilities" +version = "3.0.0" +source = "git+https://github.com/DataDog/libdatadog.git?rev=7327f3049c281090f7cce7830b9430206fba11cf#7327f3049c281090f7cce7830b9430206fba11cf" +dependencies = [ + "anyhow", + "bytes", + "futures-channel", + "futures-util", + "http 1.5.0", + "thiserror 1.0.69", +] + [[package]] name = "libdd-capabilities" version = "3.0.0" @@ -1285,8 +1321,8 @@ dependencies = [ "bytes", "http 1.5.0", "http-body-util", - "libdd-capabilities 3.0.0", - "libdd-common 5.2.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", ] @@ -1325,6 +1361,31 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "libdd-common" +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" @@ -1407,18 +1468,18 @@ dependencies = [ "getrandom 0.2.17", "http 1.5.0", "http-body-util", - "libdd-capabilities 3.0.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", + "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 3.0.0", "libdd-telemetry 7.0.0", - "libdd-tinybytes", - "libdd-trace-normalization", + "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", @@ -1430,6 +1491,19 @@ dependencies = [ "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" @@ -1464,7 +1538,7 @@ dependencies = [ "async-trait", "cadence", "http 1.5.0", - "libdd-common 5.2.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-shared-runtime 3.0.0", "serde", "tokio", @@ -1514,9 +1588,9 @@ dependencies = [ "hashbrown 0.15.5", "http 1.5.0", "http-body-util", - "libdd-capabilities 3.0.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", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-trace-protobuf 4.0.1", "libdd-tuf", "manual_future", @@ -1562,9 +1636,9 @@ dependencies = [ "async-trait", "futures", "futures-util", - "libdd-capabilities 3.0.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", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "tokio", "tokio-util", "tracing", @@ -1612,8 +1686,8 @@ dependencies = [ "hashbrown 0.15.5", "http 1.5.0", "libc", - "libdd-capabilities 3.0.0", - "libdd-common 5.2.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-ddsketch 1.1.1 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-shared-runtime 3.0.0", "serde", @@ -1629,6 +1703,14 @@ dependencies = [ "winver", ] +[[package]] +name = "libdd-tinybytes" +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" @@ -1646,6 +1728,15 @@ dependencies = [ "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 = "6.0.0" @@ -1653,9 +1744,9 @@ source = "git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84 dependencies = [ "anyhow", "fluent-uri", - "libdd-common 5.2.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-trace-protobuf 4.0.1", - "libdd-trace-utils", + "libdd-trace-utils 10.1.0", "log", "percent-encoding", "serde", @@ -1682,6 +1773,16 @@ dependencies = [ "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", + "serde_bytes", +] + [[package]] name = "libdd-trace-stats" version = "7.0.0" @@ -1693,16 +1794,16 @@ dependencies = [ "futures", "hashbrown 0.15.5", "http 1.5.0", - "libdd-capabilities 3.0.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", + "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 3.0.0", "libdd-telemetry 7.0.0", "libdd-trace-obfuscation", "libdd-trace-protobuf 4.0.1", - "libdd-trace-utils", + "libdd-trace-utils 10.1.0", "rmp-serde", "serde", "tokio", @@ -1727,11 +1828,11 @@ dependencies = [ "http-body-util", "indexmap 2.14.0", "itoa 1.0.18", - "libdd-capabilities 3.0.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", - "libdd-tinybytes", - "libdd-trace-normalization", + "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", @@ -1747,6 +1848,42 @@ 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" @@ -1939,6 +2076,7 @@ dependencies = [ "napi-sys 3.3.0", "nohash-hasher", "rustc-hash", + "tokio", ] [[package]] @@ -2337,13 +2475,13 @@ dependencies = [ "http 1.5.0", "js-sys", "libdatadog-nodejs-capabilities", - "libdd-capabilities 3.0.0", - "libdd-common 5.2.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 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", @@ -2533,6 +2671,12 @@ dependencies = [ "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.11" @@ -2546,7 +2690,7 @@ dependencies = [ "console_error_panic_hook", "js-sys", "libdatadog-nodejs-capabilities", - "libdd-common 5.2.0", + "libdd-common 5.2.0 (git+https://github.com/DataDog/libdatadog.git?rev=966f921c226b63a1ba84c2e53e3d0f4625f90c75)", "libdd-remote-config", "serde", "serde-wasm-bindgen", diff --git a/README.md b/README.md index f8f8d834..1c6689ec 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ published as two packages with different availability guarantees. The universal package is maintained under [`packages/libdatadog`](packages/libdatadog). Its matching native and WASM -backends expose Zstandard compression and DDSketch from a single native or -WASM artifact. +backends expose the agentless data pipeline, Zstandard compression, and +DDSketch from a single native or WASM artifact. The package tries a platform-native napi-rs backend first. Native artifacts are published as optional dependencies using napi-rs-compatible package names such 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 index 1648b8cb..91cbc953 100644 --- a/crates/libdatadog-wasm/Cargo.toml +++ b/crates/libdatadog-wasm/Cargo.toml @@ -10,10 +10,27 @@ 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"] } 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 index 259fcacf..e133c0a1 100644 --- a/crates/libdatadog-wasm/src/lib.rs +++ b/crates/libdatadog-wasm/src/lib.rs @@ -1,2 +1,3 @@ +mod data_pipeline; mod sketches; mod zstd; diff --git a/crates/libdatadog/Cargo.toml b/crates/libdatadog/Cargo.toml index f15da88a..5c5b3654 100644 --- a/crates/libdatadog/Cargo.toml +++ b/crates/libdatadog/Cargo.toml @@ -8,10 +8,23 @@ crate-type = ["cdylib"] name = "libdatadog" [dependencies] -napi = { version = "3", default-features = false, features = ["napi8"] } +napi = { version = "3", default-features = false, features = ["async", "napi8"] } napi-derive = "3" +anyhow = "1" +bytes = "1" +futures = "0.3" +http = "1" libdd-ddsketch = "1.1.1" zstd = { version = "0.13.3", default-features = false, features = ["thin"] } +[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"] + [build-dependencies] napi-build = "2" diff --git a/crates/libdatadog/src/data_pipeline/mod.rs b/crates/libdatadog/src/data_pipeline/mod.rs new file mode 100644 index 00000000..1ab402f5 --- /dev/null +++ b/crates/libdatadog/src/data_pipeline/mod.rs @@ -0,0 +1,335 @@ +use std::collections::HashMap; +use std::fmt; +use std::sync::atomic::{AtomicU32, Ordering}; +use std::sync::{Arc, Mutex}; +use std::time::Duration; + +use bytes::Bytes; +use futures::future::{AbortHandle, Abortable}; +use libdatadog_data_pipeline::{ + send_agentless_v04, AgentlessTraceConfig, SendAgentlessV04Error, TracerMetadata, + DEFAULT_AGENTLESS_TIMEOUT, +}; +use libdd_capabilities::{HttpClientCapability, HttpError, SleepCapability}; +use napi::bindgen_prelude::*; +use napi::threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}; +use napi::Status; +use napi_derive::napi; + +type RequestFunction = ThreadsafeFunction< + AgentlessRequest, + Promise, + AgentlessRequest, + Status, + false, + true, +>; +type SleepArgs = FnArgs<(u32, u32)>; +type SleepFunction = ThreadsafeFunction, SleepArgs, Status, false, true>; +type CancelFunction = ThreadsafeFunction; + +#[napi(object)] +pub struct AgentlessExporterOptions { + pub endpoint: String, + pub api_key: String, + pub hostname: Option, + pub env: Option, + pub service: Option, + pub version: Option, + pub runtime_id: Option, + pub container_id: Option, + pub tracer_version: String, + pub language_version: String, + pub language_interpreter: String, + pub timeout_ms: Option, +} + +#[napi(object)] +pub struct AgentlessRequestHeader { + pub name: String, + pub value: String, +} + +#[napi(object)] +pub struct AgentlessRequest { + pub id: u32, + pub url: String, + pub method: String, + pub headers: Vec, + pub body: Buffer, +} + +#[napi(object)] +pub struct AgentlessResponse { + pub status: u16, + pub body: Buffer, +} + +#[derive(Clone)] +struct HostCapabilities { + request: Arc, + cancel_request: Arc, + sleep: Arc, + cancel_sleep: Arc, + next_call_id: Arc, +} + +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 { + self.next_call_id.fetch_add(1, Ordering::Relaxed) + } +} + +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, + ) -> std::result::Result, HttpError> { + let id = self.next_call_id(); + let (parts, body) = request.into_parts(); + let headers = parts + .headers + .iter() + .map(|(name, value)| { + value + .to_str() + .map(|value| AgentlessRequestHeader { + name: name.to_string(), + value: value.to_string(), + }) + .map_err(|error| HttpError::InvalidRequest(error.into())) + }) + .collect::, _>>()?; + let request = AgentlessRequest { + id, + url: parts.uri.to_string(), + method: parts.method.to_string(), + headers, + body: body.to_vec().into(), + }; + let mut guard = CancelGuard::new(id, self.cancel_request.clone()); + let promise = self + .request + .call_async(request) + .await + .map_err(network_error)?; + let response = promise.await.map_err(network_error)?; + guard.disarm(); + + http::Response::builder() + .status(response.status) + .body(Bytes::from(response.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(promise) = self.sleep.call_async((id, milliseconds).into()).await { + let _ = promise.await; + } + guard.disarm(); + } +} + +struct CancelGuard { + id: u32, + cancel: Arc, + armed: bool, +} + +impl CancelGuard { + fn new(id: u32, cancel: Arc) -> Self { + Self { + id, + cancel, + armed: true, + } + } + + fn disarm(&mut self) { + self.armed = false; + } +} + +impl Drop for CancelGuard { + fn drop(&mut self) { + if self.armed { + self.cancel + .call(self.id, ThreadsafeFunctionCallMode::NonBlocking); + } + } +} + +#[napi] +pub struct AgentlessExporter { + metadata: TracerMetadata, + config: AgentlessTraceConfig, + capabilities: HostCapabilities, + in_flight: Arc>>, + next_operation_id: Arc, +} + +#[napi] +impl AgentlessExporter { + #[napi(constructor)] + pub fn new( + options: AgentlessExporterOptions, + request: Function<'_, AgentlessRequest, Promise>, + cancel_request: Function<'_, u32, ()>, + sleep: Function<'_, FnArgs<(u32, u32)>, Promise<()>>, + cancel_sleep: Function<'_, u32, ()>, + ) -> Result { + let timeout = options + .timeout_ms + .map(|timeout_ms| Duration::from_millis(u64::from(timeout_ms))) + .unwrap_or(DEFAULT_AGENTLESS_TIMEOUT); + 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 config = AgentlessTraceConfig { + endpoint_url: options.endpoint, + api_key: options.api_key, + timeout, + }; + let capabilities = HostCapabilities { + request: Arc::new( + request + .build_threadsafe_function::() + .weak::() + .build()?, + ), + cancel_request: Arc::new( + cancel_request + .build_threadsafe_function::() + .weak::() + .build()?, + ), + sleep: Arc::new( + sleep + .build_threadsafe_function::() + .weak::() + .build()?, + ), + cancel_sleep: Arc::new( + cancel_sleep + .build_threadsafe_function::() + .weak::() + .build()?, + ), + next_call_id: Arc::new(AtomicU32::new(1)), + }; + + Ok(Self { + metadata, + config, + capabilities, + in_flight: Arc::new(Mutex::new(HashMap::new())), + next_operation_id: Arc::new(AtomicU32::new(1)), + }) + } + + #[napi] + pub fn send_v04<'env>(&self, env: &'env Env, payload: Buffer) -> Result> { + let operation_id = self.next_operation_id.fetch_add(1, Ordering::Relaxed); + let (abort, registration) = AbortHandle::new_pair(); + lock(&self.in_flight).insert(operation_id, abort); + let capabilities = self.capabilities.clone(); + let metadata = self.metadata.clone(); + let config = self.config.clone(); + let in_flight = self.in_flight.clone(); + let cleanup = in_flight.clone(); + let future = async move { + let _guard = OperationGuard { + id: operation_id, + in_flight, + }; + let send = send_agentless_v04(&capabilities, payload.as_ref(), &metadata, &config); + + match Abortable::new(send, registration).await { + Ok(Ok(_)) => Ok(()), + Ok(Err(error)) => Err(send_error(error)), + Err(_) => Err(Error::from_reason("data-pipeline export was cancelled")), + } + }; + + match env.spawn_future(future) { + Ok(promise) => Ok(promise), + Err(error) => { + lock(&cleanup).remove(&operation_id); + Err(error) + } + } + } + + #[napi] + pub fn cancel_all(&self) { + for abort in lock(&self.in_flight).values() { + abort.abort(); + } + } +} + +impl Drop for AgentlessExporter { + fn drop(&mut self) { + self.cancel_all(); + } +} + +struct OperationGuard { + id: u32, + in_flight: Arc>>, +} + +impl Drop for OperationGuard { + fn drop(&mut self) { + lock(&self.in_flight).remove(&self.id); + } +} + +fn lock(mutex: &Mutex) -> std::sync::MutexGuard<'_, T> { + mutex.lock().unwrap_or_else(|error| error.into_inner()) +} + +fn duration_millis(duration: Duration) -> u32 { + u32::try_from(duration.as_millis()).unwrap_or(u32::MAX) +} + +fn network_error(error: napi::Error) -> HttpError { + HttpError::Network(anyhow::anyhow!(error.reason)) +} + +fn send_error(error: SendAgentlessV04Error) -> Error { + Error::from_reason(format!("failed to send data-pipeline export: {error}")) +} diff --git a/crates/libdatadog/src/lib.rs b/crates/libdatadog/src/lib.rs index 259fcacf..e133c0a1 100644 --- a/crates/libdatadog/src/lib.rs +++ b/crates/libdatadog/src/lib.rs @@ -1,2 +1,3 @@ +mod data_pipeline; mod sketches; mod zstd; diff --git a/eslint.config.js b/eslint.config.js index b59926fb..c362da00 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -91,6 +91,7 @@ module.exports = [ files: [ 'packages/libdatadog/lib/wasm.js', 'packages/libdatadog/test/bundlers.test.js', + 'packages/libdatadog/test/exporter.test.js', ], rules: { 'n/no-missing-require': 'off', diff --git a/packages/libdatadog/README.md b/packages/libdatadog/README.md index 8406c780..2e710cf6 100644 --- a/packages/libdatadog/README.md +++ b/packages/libdatadog/README.md @@ -10,8 +10,11 @@ are maintained in the root `crates/libdatadog` and `crates/libdatadog-wasm` workspace crates. Optional libdatadog functionality is published separately as `@datadog/libdatadog-extras`. -Both backends expose Zstandard compression and DDSketch from a single native -or WASM artifact. +Both backends expose the agentless data pipeline, Zstandard compression, and +DDSketch from a single native or WASM artifact. + +The package accepts Datadog v0.4 MessagePack payloads and exports them to an +agentless intake. The package tries a platform-native napi-rs backend first and falls back to a wasm-bindgen backend with the WebAssembly bytes embedded in JavaScript. The diff --git a/packages/libdatadog/index.d.ts b/packages/libdatadog/index.d.ts index 9e026144..6aec92a1 100644 --- a/packages/libdatadog/index.d.ts +++ b/packages/libdatadog/index.d.ts @@ -1,3 +1,24 @@ +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(): 'native' | 'wasm' export function zstd_compress(data: Uint8Array, level: number): Uint8Array diff --git a/packages/libdatadog/index.mjs b/packages/libdatadog/index.mjs index 9c1a9a9b..17e46561 100644 --- a/packages/libdatadog/index.mjs +++ b/packages/libdatadog/index.mjs @@ -2,6 +2,7 @@ import libdatadog from './index.js' export const { backend, + createAgentlessExporter, DDSketch, zstd_compress, } = libdatadog 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..5d823027 --- /dev/null +++ b/packages/libdatadog/lib/agentless.js @@ -0,0 +1,54 @@ +'use strict' + +const { randomUUID } = require('node:crypto') + +const { createHostTransport } = require('./agentless-transport') + +class AgentlessExporter { + #binding + #closed = false + #inFlight = new Set() + + 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) + } +} + +function createAgentlessExporter (binding, options) { + return new AgentlessExporter(binding, options) +} + +module.exports = { createAgentlessExporter } diff --git a/packages/libdatadog/lib/native.js b/packages/libdatadog/lib/native.js index 86b430ff..02e8a926 100644 --- a/packages/libdatadog/lib/native.js +++ b/packages/libdatadog/lib/native.js @@ -3,6 +3,8 @@ const path = require('node:path') const os = require('node:os') +const { createAgentlessExporter } = require('./agentless') + const target = getNativeTarget() const binding = loadBinding(target) @@ -45,5 +47,6 @@ function loadBinding (target) { module.exports = { backend: () => 'native', DDSketch: binding.DDSketch, + createAgentlessExporter: options => createAgentlessExporter(binding, options), zstd_compress: binding.zstd_compress, } diff --git a/packages/libdatadog/lib/wasm.js b/packages/libdatadog/lib/wasm.js index 8274b437..d77de2c5 100644 --- a/packages/libdatadog/lib/wasm.js +++ b/packages/libdatadog/lib/wasm.js @@ -2,8 +2,11 @@ const binding = require('@datadog/libdatadog-wasm') +const { createAgentlessExporter } = require('./agentless') + module.exports = { backend: () => 'wasm', DDSketch: binding.DDSketch, + createAgentlessExporter: options => createAgentlessExporter(binding, options), zstd_compress: binding.zstd_compress, } diff --git a/packages/libdatadog/package-lock.json b/packages/libdatadog/package-lock.json index 5d8940df..fe5079e9 100644 --- a/packages/libdatadog/package-lock.json +++ b/packages/libdatadog/package-lock.json @@ -15,6 +15,7 @@ "@datadog/libdatadog-wasm": "0.1.0-pre" }, "devDependencies": { + "@msgpack/msgpack": "^3.1.3", "@napi-rs/cli": "^3.5.1", "esbuild": "^0.28.2", "typescript": "^6.0.3", @@ -935,6 +936,16 @@ "@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/@napi-rs/cli": { "version": "3.8.6", "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-3.8.6.tgz", diff --git a/packages/libdatadog/package.json b/packages/libdatadog/package.json index f26db5e0..8303ac84 100644 --- a/packages/libdatadog/package.json +++ b/packages/libdatadog/package.json @@ -69,6 +69,7 @@ "@datadog/libdatadog-linux-x64-musl": "0.1.0-pre" }, "devDependencies": { + "@msgpack/msgpack": "^3.1.3", "@napi-rs/cli": "^3.5.1", "esbuild": "^0.28.2", "typescript": "^6.0.3", diff --git a/packages/libdatadog/test/exporter.test.js b/packages/libdatadog/test/exporter.test.js new file mode 100644 index 00000000..c13fcc89 --- /dev/null +++ b/packages/libdatadog/test/exporter.test.js @@ -0,0 +1,361 @@ +'use strict' + +const assert = require('node:assert/strict') +const { spawnSync } = require('node:child_process') +const fs = require('node:fs') +const http = require('node:http') +const path = require('node:path') +const { test } = require('node:test') +const { Worker } = require('node:worker_threads') +const { zstdDecompressSync } = require('node:zlib') + +const { encode } = require('@msgpack/msgpack') + +const zstdMagic = Buffer.from([0x28, 0xB5, 0x2F, 0xFD]) + +const packageRoot = path.join(__dirname, '..') +const nativeDirectory = path.join(packageRoot, 'dist', 'native') +const nativeArtifact = fs.existsSync(nativeDirectory) + ? fs.readdirSync(nativeDirectory).find(file => file.startsWith('libdatadog.') && file.endsWith('.node')) + : undefined +const wasmArtifact = path.join(packageRoot, 'wasm', 'dist', 'libdatadog_wasm.js') + +test('native backend compresses agentless v0.4 exports with Zstandard', { + skip: !nativeArtifact, +}, async () => { + process.env.DD_LIBDATADOG_NATIVE_PATH = path.join(nativeDirectory, nativeArtifact) + await assertExport( + require('../lib/native'), + 'native', + ) + delete process.env.DD_LIBDATADOG_NATIVE_PATH +}) + +test('inline-WASM backend compresses agentless v0.4 exports with Zstandard', { + skip: !fs.existsSync(wasmArtifact), +}, async () => { + await assertExport( + require('../wasm'), + 'wasm', + ) +}) + +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/, + ) +}) + +const backends = [ + { + name: 'native', + skip: !nativeArtifact, + load: loadNativePipeline, + }, + { + name: 'inline-WASM', + skip: !fs.existsSync(wasmArtifact), + load: () => require('../wasm'), + }, +] + +for (const backend of backends) { + test(`${backend.name} retries in Rust until the third attempt succeeds`, { + skip: backend.skip, + }, async () => { + const pipeline = backend.load() + 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(`${backend.name} applies Rust timeouts and retry policy`, { + skip: backend.skip, + }, async () => { + const pipeline = backend.load() + 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(`${backend.name} close cancels an active HTTP request`, { + skip: backend.skip, + }, async () => { + const pipeline = backend.load() + 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(`${backend.name} close cancels retry backoff`, { + skip: backend.skip, + }, async () => { + const pipeline = backend.load() + 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)) + } + }) +} + +test('an idle NAPI exporter does not keep Node alive', { + skip: !nativeArtifact, +}, () => { + const nativePath = path.join(nativeDirectory, nativeArtifact) + const modulePath = path.join(packageRoot, 'lib', 'native.js') + const script = ` + const pipeline = require(${JSON.stringify(modulePath)}) + pipeline.createAgentlessExporter({ + endpoint: 'http://127.0.0.1:1/api/v2/spans', + apiKey: 'test-api-key', + tracerVersion: '0.1.0', + languageVersion: process.version, + languageInterpreter: 'v8', + }) + ` + const result = spawnSync(process.execPath, ['-e', script], { + env: { ...process.env, DD_LIBDATADOG_NATIVE_PATH: nativePath }, + encoding: 'utf8', + timeout: 3000, + }) + + assert.notStrictEqual(result.error?.code, 'ETIMEDOUT') + assert.strictEqual(result.status, 0, result.stderr) +}) + +test('NAPI exporter survives worker teardown during an HTTP request', { + skip: !nativeArtifact, +}, async () => { + 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 { port } = server.address() + const worker = new Worker(` + const { workerData } = require('node:worker_threads') + process.env.DD_LIBDATADOG_NATIVE_PATH = workerData.nativePath + const pipeline = require(workerData.modulePath) + const exporter = pipeline.createAgentlessExporter({ + endpoint: workerData.endpoint, + apiKey: 'test-api-key', + tracerVersion: '0.1.0', + languageVersion: process.version, + languageInterpreter: 'v8', + }) + exporter.sendV04(Buffer.from(workerData.payload)).catch(() => {}) + `, { + eval: true, + workerData: { + nativePath: path.join(nativeDirectory, nativeArtifact), + modulePath: path.join(packageRoot, 'lib', 'native.js'), + endpoint: `http://127.0.0.1:${port}/api/v2/spans`, + payload: tracePayload(), + }, + }) + const workerError = new Promise((_, reject) => { + worker.once('error', reject) + }) + + try { + await Promise.race([request, workerError]) + const exitCode = await worker.terminate() + assert.strictEqual(exitCode, 1) + } finally { + await worker.terminate() + await new Promise(resolve => server.close(resolve)) + } +}) + +async function assertExport (pipeline, expectedBackend) { + 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(), expectedBackend) + 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 loadNativePipeline () { + process.env.DD_LIBDATADOG_NATIVE_PATH = path.join(nativeDirectory, nativeArtifact) + try { + return require('../lib/native') + } finally { + delete process.env.DD_LIBDATADOG_NATIVE_PATH + } +} + +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 index 8c960514..fdc2d4a3 100644 --- a/packages/libdatadog/test/package-contents.test.js +++ b/packages/libdatadog/test/package-contents.test.js @@ -184,22 +184,26 @@ function assertEsmImports (installRoot, environment, expectedBackend) { 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' assert.strictEqual(backend(), ${JSON.stringify(expectedBackend)}) 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) ` 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/wasm.mjs b/packages/libdatadog/wasm.mjs index cbd61ba5..7674c8e2 100644 --- a/packages/libdatadog/wasm.mjs +++ b/packages/libdatadog/wasm.mjs @@ -2,6 +2,7 @@ import libdatadog from './wasm.js' export const { backend, + createAgentlessExporter, DDSketch, zstd_compress, } = libdatadog From 50cf32b87b8daf0b33fad2f274c80ea67a8bb67c Mon Sep 17 00:00:00 2001 From: Roch Devost Date: Thu, 27 Aug 2026 14:17:02 -0400 Subject: [PATCH 15/20] ci(libdatadog): add artifact dependency and size reports (#208) * ci(libdatadog): add artifact dependency and size reports * ci(libdatadog): fix wasm report artifact path --- .github/workflows/build.yml | 13 +- crates/libdatadog-wasm/Cargo.toml | 14 + package.json | 1 + packages/libdatadog/package.json | 3 + .../libdatadog/scripts/report-napi-size.js | 183 +++++++++ .../libdatadog/scripts/report-wasm-size.js | 382 ++++++++++++++++++ packages/libdatadog/test/size-report.test.js | 101 +++++ scripts/build-wasm.js | 17 +- scripts/check-dependencies.js | 129 ++++++ test/dependencies.js | 62 +++ 10 files changed, 900 insertions(+), 5 deletions(-) create mode 100644 packages/libdatadog/scripts/report-napi-size.js create mode 100644 packages/libdatadog/scripts/report-wasm-size.js create mode 100644 packages/libdatadog/test/size-report.test.js create mode 100644 scripts/check-dependencies.js create mode 100644 test/dependencies.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bb688d01..57a04d57 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -28,9 +28,20 @@ jobs: 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:wasm --prefix packages/libdatadog + - run: cargo install cargo-bloat --version 0.12.1 --locked + - run: npm run build --prefix packages/libdatadog + - name: Report N-API binary size + run: npm run report:napi-size --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 diff --git a/crates/libdatadog-wasm/Cargo.toml b/crates/libdatadog-wasm/Cargo.toml index 91cbc953..71273b52 100644 --- a/crates/libdatadog-wasm/Cargo.toml +++ b/crates/libdatadog-wasm/Cargo.toml @@ -48,3 +48,17 @@ wasm-opt = [ "--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/package.json b/package.json index 552476ab..0f43068a 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "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" }, diff --git a/packages/libdatadog/package.json b/packages/libdatadog/package.json index 8303ac84..2d45cdcc 100644 --- a/packages/libdatadog/package.json +++ b/packages/libdatadog/package.json @@ -39,7 +39,10 @@ "build:native": "node scripts/build-native.js", "build:wasm": "npm run build:wasm:binary && npm run inline:wasm", "build:wasm:binary": "node ../../scripts/build-wasm.js ../../crates/libdatadog-wasm wasm/dist", + "size:profile": "node ../../scripts/build-wasm.js ../../crates/libdatadog-wasm ../../target/size --profiling", "inline:wasm": "node scripts/inline-wasm.js", + "report:napi-size": "node scripts/report-napi-size.js", + "report:wasm-size": "node scripts/report-wasm-size.js", "package:native": "node scripts/package-native.js", "build": "npm run build:native && npm run build:wasm", "test": "node scripts/run-tests.js && npm run test:types", diff --git a/packages/libdatadog/scripts/report-napi-size.js b/packages/libdatadog/scripts/report-napi-size.js new file mode 100644 index 00000000..63a0066e --- /dev/null +++ b/packages/libdatadog/scripts/report-napi-size.js @@ -0,0 +1,183 @@ +'use strict' + +const fs = require('node:fs') +const path = require('node:path') +const { spawnSync } = require('node:child_process') + +function formatBytes (bytes) { + return bytes.toLocaleString('en-US') +} + +function formatKibibytes (bytes) { + return (bytes / 1024).toFixed(1) +} + +function findArtifact () { + const directory = path.join(__dirname, '..', 'dist', 'native') + const artifacts = fs.readdirSync(directory) + .filter(file => /^libdatadog\..+\.node$/.test(file)) + + if (artifacts.length !== 1) { + throw new Error(`expected one native artifact in ${directory}, found ${artifacts.length}`) + } + + return path.join(directory, artifacts[0]) +} + +function runCommand (command, args) { + const result = spawnSync(command, args, { + encoding: 'utf8', + maxBuffer: 10 * 1024 * 1024, + }) + + if (result.error) throw result.error + if (result.status !== 0) { + const detail = result.stderr.trim() || result.stdout.trim() + throw new Error(`${command} failed: ${detail}`) + } + + return result.stdout +} + +function parseDarwinSections (output) { + const sections = [] + + for (const line of output.split('\n')) { + const match = line.match(/^Segment (\S+):\s+(\d+)$/) + if (match) sections.push({ name: match[1], bytes: Number(match[2]) }) + } + + return sections +} + +function parseElfSections (output) { + const sections = [] + + for (const line of output.split('\n')) { + const match = line.trim().match(/^(\S+)\s+(\d+)\s+[0-9a-fA-Fx]+$/) + if (match && match[1] !== 'section') { + sections.push({ name: match[1], bytes: Number(match[2]) }) + } + } + + return sections +} + +function readSections (artifactPath, platform = process.platform) { + const sections = platform === 'darwin' + ? parseDarwinSections(runCommand('size', ['-m', artifactPath])) + : parseElfSections(runCommand('size', ['-A', artifactPath])) + + if (sections.length === 0) throw new Error('could not read native binary sections') + return sections +} + +function readCrateSizes () { + const output = runCommand('cargo', [ + 'bloat', + '--release', + '--crates', + '-n', + '0', + '--message-format', + 'json', + '-p', + 'libdatadog', + '--lib', + ]) + + return JSON.parse(output) +} + +function appendCrateReport (lines, profile) { + const crates = profile.crates + .map(crate => ({ ...crate, name: crate.name.replaceAll('_', '-') })) + const attributedBytes = crates.reduce((total, crate) => total + crate.size, 0) + const overheadBytes = profile['text-section-size'] - attributedBytes + if (overheadBytes > 0) { + crates.push({ name: 'unattributed .text overhead', size: overheadBytes }) + crates.sort((left, right) => right.size - left.size) + } + const visible = crates.filter(crate => crate.size >= 2048) + const otherBytes = crates + .filter(crate => crate.size < 2048) + .reduce((total, crate) => total + crate.size, 0) + + if (otherBytes > 0) { + visible.push({ name: 'other crates (<2 KiB each)', size: otherBytes }) + } + + lines.push( + '', + '### Code by Rust crate', + '', + '| Crate | Bytes | KiB | Share of native code |', + '| --- | ---: | ---: | ---: |', + ) + + for (const crate of visible) { + const share = `${(crate.size / profile['text-section-size'] * 100).toFixed(1)}%` + lines.push( + `| ${crate.name} | ${formatBytes(crate.size)} | ` + + `${formatKibibytes(crate.size)} | ${share} |`, + ) + } + + lines.push( + '', + `.text section: ${formatBytes(profile['text-section-size'])} bytes ` + + `(${formatKibibytes(profile['text-section-size'])} KiB).`, + '', + 'Crate ownership comes from cargo-bloat using a separate symbol-preserving release build. ' + + 'It attributes native code only; data, unwind information, symbols, and file alignment ' + + 'remain in the section and artifact totals above.', + ) +} + +function createReport (artifactPath, profile) { + const artifactBytes = fs.statSync(artifactPath).size + const sections = readSections(artifactPath) + const totalSectionBytes = sections.reduce((total, section) => total + section.bytes, 0) + const lines = [ + '## libdatadog N-API size', + '', + '| Native artifact | Bytes | KiB |', + '| --- | ---: | ---: |', + `| **Shipped .node file** | **${formatBytes(artifactBytes)}** | ` + + `**${formatKibibytes(artifactBytes)}** |`, + '', + '### Native binary sections', + '', + '| Section/segment | Bytes | KiB | Share |', + '| --- | ---: | ---: | ---: |', + ] + + for (const section of sections) { + const share = `${(section.bytes / totalSectionBytes * 100).toFixed(1)}%` + lines.push( + `| ${section.name} | ${formatBytes(section.bytes)} | ` + + `${formatKibibytes(section.bytes)} | ${share} |`, + ) + } + + if (profile) appendCrateReport(lines, profile) + + lines.push('', `Generated from \`${path.relative(process.cwd(), artifactPath)}\`.`) + return lines.join('\n') +} + +if (require.main === module) { + const artifactPath = process.argv[2] ? path.resolve(process.argv[2]) : findArtifact() + const report = createReport(artifactPath, readCrateSizes()) + console.log(report) + + if (process.env.GITHUB_STEP_SUMMARY) { + fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, `${report}\n`) + } +} + +module.exports = { + createReport, + parseDarwinSections, + parseElfSections, +} 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/test/size-report.test.js b/packages/libdatadog/test/size-report.test.js new file mode 100644 index 00000000..86ba4821 --- /dev/null +++ b/packages/libdatadog/test/size-report.test.js @@ -0,0 +1,101 @@ +'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 test = require('node:test') + +const { + createReport: createWasmReport, + findForbiddenWasmCode, + inferCrate, + readSections, +} = require('../scripts/report-wasm-size') +const { + createReport: createNapiReport, + parseDarwinSections, + parseElfSections, +} = require('../scripts/report-napi-size') + +const nativeDirectory = path.join(__dirname, '..', 'dist', 'native') +const nativeArtifact = fs.existsSync(nativeDirectory) + ? fs.readdirSync(nativeDirectory) + .find(file => /^libdatadog\..+\.node$/.test(file)) + : undefined + +function napiReportSkipReason () { + if (!nativeArtifact) return 'a native artifact is not installed' + + const size = spawnSync('size', ['--version'], { stdio: 'ignore' }) + if (size.error?.code === 'ENOENT') return 'the size command is not installed' + + return false +} + +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('reports N-API artifact, section, and crate sizes', { + skip: napiReportSkipReason(), +}, () => { + const report = createNapiReport(path.join(nativeDirectory, nativeArtifact), { + 'text-section-size': 7000, + 'crates': [ + { name: 'libdatadog', size: 2500 }, + { name: 'small_crate', size: 500 }, + ], + }) + + assert.match(report, /Shipped \.node file/) + assert.match(report, /Native binary sections/) + assert.match(report, /Code by Rust crate/) + assert.match(report, /libdatadog/) + assert.match(report, /unattributed \.text overhead/) + assert.match(report, /other crates \(<2 KiB each\)/) +}) + +test('parses Darwin and ELF section reports', () => { + assert.deepEqual(parseDarwinSections('Segment __TEXT: 123\nSegment __DATA: 45\n'), [ + { name: '__TEXT', bytes: 123 }, + { name: '__DATA', bytes: 45 }, + ]) + assert.deepEqual(parseElfSections('.text 123 0x10\n.data 45 0x20\nTotal 168\n'), [ + { name: '.text', bytes: 123 }, + { name: '.data', bytes: 45 }, + ]) +}) + +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/scripts/build-wasm.js b/scripts/build-wasm.js index e94d0d76..a6717f93 100644 --- a/scripts/build-wasm.js +++ b/scripts/build-wasm.js @@ -58,29 +58,38 @@ if (isMacOS) { * * @param {string} cratePath * @param {string} outputDirectory - * @param {{ skipOptimization?: boolean }} options + * @param {{ profiling?: boolean, skipOptimization?: boolean }} options * @returns {void} */ function buildWasm (cratePath, outputDirectory, options = {}) { - const { skipOptimization = false } = 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 }) + 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] = process.argv.slice(2) +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 { diff --git a/scripts/check-dependencies.js b/scripts/check-dependencies.js new file mode 100644 index 00000000..01222c38 --- /dev/null +++ b/scripts/check-dependencies.js @@ -0,0 +1,129 @@ +'use strict' + +const path = require('node:path') +const { execFileSync } = require('node:child_process') + +const repositoryRoot = path.join(__dirname, '..') +const packageJson = require('../packages/libdatadog/package.json') +const trees = [ + ...packageJson.napi.targets.map(target => ({ package: 'libdatadog', target })), + { package: 'libdatadog-wasm', target: 'wasm32-unknown-unknown' }, +] + +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 +} + +function findDuplicateVersions (dependencies) { + 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) { + if (versions.size > 1) { + failures.push({ name, versions: [...versions] }) + } + } + return failures +} + +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 parent = dependency.path.at(-2) + const allowedNapiBridge = tree.package === 'libdatadog' + && isTokio + && parent === 'napi' + if (!allowedNapiBridge) 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)) { + 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 NAPI async bridge and absent from WASM.') + } + + if (duplicateFailures.length > 0 || forbiddenFailures.length > 0) { + process.exitCode = 1 + } +} + +if (require.main === module) checkTrees() + +module.exports = { + findDuplicateVersions, + findForbiddenDependencies, + parseCargoTree, +} diff --git a/test/dependencies.js b/test/dependencies.js new file mode 100644 index 00000000..91a7c098 --- /dev/null +++ b/test/dependencies.js @@ -0,0 +1,62 @@ +'use strict' + +const assert = require('node:assert/strict') +const { test } = require('node:test') + +const { + findDuplicateVersions, + findForbiddenDependencies, + parseCargoTree, +} = require('../scripts/check-dependencies') + +test('dependency validation allows Tokio only below the NAPI async bridge', () => { + const dependencies = parseCargoTree([ + '0libdatadog v0.1.0', + '1napi v3.12.1', + '2tokio v1.52.1', + ].join('\n')) + + assert.deepStrictEqual( + findForbiddenDependencies(dependencies, { package: 'libdatadog' }), + [], + ) +}) + +test('dependency validation rejects Tokio outside the NAPI async bridge', () => { + const dependencies = parseCargoTree([ + '0libdatadog v0.1.0', + '1tokio v1.52.1', + '1napi v3.12.1', + '2tokio-util v0.7.18', + ].join('\n')) + const failures = findForbiddenDependencies(dependencies, { package: 'libdatadog' }) + + assert.deepStrictEqual(failures.map(({ name }) => name), ['tokio', 'tokio-util']) +}) + +test('dependency validation rejects all Tokio packages in WASM', () => { + const dependencies = parseCargoTree([ + '0libdatadog-wasm v0.1.0', + '1napi v3.12.1', + '2tokio v1.52.1', + ].join('\n')) + + assert.strictEqual( + findForbiddenDependencies(dependencies, { package: 'libdatadog-wasm' }).length, + 1, + ) +}) + +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'], + }]) +}) From 717ec969d5a8261b256d750465300c97ba873fee Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Mon, 31 Aug 2026 18:15:41 +0200 Subject: [PATCH 16/20] refactor(libdatadog): keep data pipeline on WASM (#216) * refactor(libdatadog): keep data pipeline on WASM The agentless exporter has no native consumer yet, so its N-API implementation duplicates the WASM exporter and its lifecycle. The default entry point now loads the WASM binding only when it creates an exporter. Refs: https://github.com/DataDog/libdatadog-nodejs/pull/205 * refactor(libdatadog): isolate native backend The native facade exposed the agentless exporter even though every export used WASM, which kept a false backend-parity contract. * fix(libdatadog): defer agentless implementation loading The shared exporter imported the WASM workspace package directly, which root lint cannot resolve. Keeping binding ownership in the WASM facade also defers agentless transport loading until exporter creation. --- Cargo.lock | 7 - README.md | 6 +- crates/libdatadog/Cargo.toml | 15 +- crates/libdatadog/src/data_pipeline/mod.rs | 335 ------------------ crates/libdatadog/src/lib.rs | 1 - packages/libdatadog/README.md | 12 +- packages/libdatadog/lib/agentless.js | 11 + packages/libdatadog/lib/load.js | 10 +- packages/libdatadog/lib/native.js | 3 - packages/libdatadog/lib/wasm.js | 9 +- packages/libdatadog/test/capabilities.test.js | 4 +- packages/libdatadog/test/exporter.test.js | 277 ++++++--------- 12 files changed, 139 insertions(+), 551 deletions(-) delete mode 100644 crates/libdatadog/src/data_pipeline/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 4355bbe6..23cc4b3e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1206,12 +1206,6 @@ checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" name = "libdatadog" version = "0.1.0" dependencies = [ - "anyhow", - "bytes", - "futures", - "http 1.5.0", - "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)", "napi 3.12.2", "napi-build", @@ -2076,7 +2070,6 @@ dependencies = [ "napi-sys 3.3.0", "nohash-hasher", "rustc-hash", - "tokio", ] [[package]] diff --git a/README.md b/README.md index 1c6689ec..a5a2df12 100644 --- a/README.md +++ b/README.md @@ -17,9 +17,9 @@ published as two packages with different availability guarantees. ## `@datadog/libdatadog` The universal package is maintained under -[`packages/libdatadog`](packages/libdatadog). Its matching native and WASM -backends expose the agentless data pipeline, Zstandard compression, and -DDSketch from a single native or WASM artifact. +[`packages/libdatadog`](packages/libdatadog). Zstandard compression and +DDSketch use the native backend when it is available, with WASM as the +fallback. The agentless data pipeline always uses the WASM backend. The package tries a platform-native napi-rs backend first. Native artifacts are published as optional dependencies using napi-rs-compatible package names such diff --git a/crates/libdatadog/Cargo.toml b/crates/libdatadog/Cargo.toml index 5c5b3654..f15da88a 100644 --- a/crates/libdatadog/Cargo.toml +++ b/crates/libdatadog/Cargo.toml @@ -8,23 +8,10 @@ crate-type = ["cdylib"] name = "libdatadog" [dependencies] -napi = { version = "3", default-features = false, features = ["async", "napi8"] } +napi = { version = "3", default-features = false, features = ["napi8"] } napi-derive = "3" -anyhow = "1" -bytes = "1" -futures = "0.3" -http = "1" libdd-ddsketch = "1.1.1" zstd = { version = "0.13.3", default-features = false, features = ["thin"] } -[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"] - [build-dependencies] napi-build = "2" diff --git a/crates/libdatadog/src/data_pipeline/mod.rs b/crates/libdatadog/src/data_pipeline/mod.rs deleted file mode 100644 index 1ab402f5..00000000 --- a/crates/libdatadog/src/data_pipeline/mod.rs +++ /dev/null @@ -1,335 +0,0 @@ -use std::collections::HashMap; -use std::fmt; -use std::sync::atomic::{AtomicU32, Ordering}; -use std::sync::{Arc, Mutex}; -use std::time::Duration; - -use bytes::Bytes; -use futures::future::{AbortHandle, Abortable}; -use libdatadog_data_pipeline::{ - send_agentless_v04, AgentlessTraceConfig, SendAgentlessV04Error, TracerMetadata, - DEFAULT_AGENTLESS_TIMEOUT, -}; -use libdd_capabilities::{HttpClientCapability, HttpError, SleepCapability}; -use napi::bindgen_prelude::*; -use napi::threadsafe_function::{ThreadsafeFunction, ThreadsafeFunctionCallMode}; -use napi::Status; -use napi_derive::napi; - -type RequestFunction = ThreadsafeFunction< - AgentlessRequest, - Promise, - AgentlessRequest, - Status, - false, - true, ->; -type SleepArgs = FnArgs<(u32, u32)>; -type SleepFunction = ThreadsafeFunction, SleepArgs, Status, false, true>; -type CancelFunction = ThreadsafeFunction; - -#[napi(object)] -pub struct AgentlessExporterOptions { - pub endpoint: String, - pub api_key: String, - pub hostname: Option, - pub env: Option, - pub service: Option, - pub version: Option, - pub runtime_id: Option, - pub container_id: Option, - pub tracer_version: String, - pub language_version: String, - pub language_interpreter: String, - pub timeout_ms: Option, -} - -#[napi(object)] -pub struct AgentlessRequestHeader { - pub name: String, - pub value: String, -} - -#[napi(object)] -pub struct AgentlessRequest { - pub id: u32, - pub url: String, - pub method: String, - pub headers: Vec, - pub body: Buffer, -} - -#[napi(object)] -pub struct AgentlessResponse { - pub status: u16, - pub body: Buffer, -} - -#[derive(Clone)] -struct HostCapabilities { - request: Arc, - cancel_request: Arc, - sleep: Arc, - cancel_sleep: Arc, - next_call_id: Arc, -} - -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 { - self.next_call_id.fetch_add(1, Ordering::Relaxed) - } -} - -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, - ) -> std::result::Result, HttpError> { - let id = self.next_call_id(); - let (parts, body) = request.into_parts(); - let headers = parts - .headers - .iter() - .map(|(name, value)| { - value - .to_str() - .map(|value| AgentlessRequestHeader { - name: name.to_string(), - value: value.to_string(), - }) - .map_err(|error| HttpError::InvalidRequest(error.into())) - }) - .collect::, _>>()?; - let request = AgentlessRequest { - id, - url: parts.uri.to_string(), - method: parts.method.to_string(), - headers, - body: body.to_vec().into(), - }; - let mut guard = CancelGuard::new(id, self.cancel_request.clone()); - let promise = self - .request - .call_async(request) - .await - .map_err(network_error)?; - let response = promise.await.map_err(network_error)?; - guard.disarm(); - - http::Response::builder() - .status(response.status) - .body(Bytes::from(response.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(promise) = self.sleep.call_async((id, milliseconds).into()).await { - let _ = promise.await; - } - guard.disarm(); - } -} - -struct CancelGuard { - id: u32, - cancel: Arc, - armed: bool, -} - -impl CancelGuard { - fn new(id: u32, cancel: Arc) -> Self { - Self { - id, - cancel, - armed: true, - } - } - - fn disarm(&mut self) { - self.armed = false; - } -} - -impl Drop for CancelGuard { - fn drop(&mut self) { - if self.armed { - self.cancel - .call(self.id, ThreadsafeFunctionCallMode::NonBlocking); - } - } -} - -#[napi] -pub struct AgentlessExporter { - metadata: TracerMetadata, - config: AgentlessTraceConfig, - capabilities: HostCapabilities, - in_flight: Arc>>, - next_operation_id: Arc, -} - -#[napi] -impl AgentlessExporter { - #[napi(constructor)] - pub fn new( - options: AgentlessExporterOptions, - request: Function<'_, AgentlessRequest, Promise>, - cancel_request: Function<'_, u32, ()>, - sleep: Function<'_, FnArgs<(u32, u32)>, Promise<()>>, - cancel_sleep: Function<'_, u32, ()>, - ) -> Result { - let timeout = options - .timeout_ms - .map(|timeout_ms| Duration::from_millis(u64::from(timeout_ms))) - .unwrap_or(DEFAULT_AGENTLESS_TIMEOUT); - 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 config = AgentlessTraceConfig { - endpoint_url: options.endpoint, - api_key: options.api_key, - timeout, - }; - let capabilities = HostCapabilities { - request: Arc::new( - request - .build_threadsafe_function::() - .weak::() - .build()?, - ), - cancel_request: Arc::new( - cancel_request - .build_threadsafe_function::() - .weak::() - .build()?, - ), - sleep: Arc::new( - sleep - .build_threadsafe_function::() - .weak::() - .build()?, - ), - cancel_sleep: Arc::new( - cancel_sleep - .build_threadsafe_function::() - .weak::() - .build()?, - ), - next_call_id: Arc::new(AtomicU32::new(1)), - }; - - Ok(Self { - metadata, - config, - capabilities, - in_flight: Arc::new(Mutex::new(HashMap::new())), - next_operation_id: Arc::new(AtomicU32::new(1)), - }) - } - - #[napi] - pub fn send_v04<'env>(&self, env: &'env Env, payload: Buffer) -> Result> { - let operation_id = self.next_operation_id.fetch_add(1, Ordering::Relaxed); - let (abort, registration) = AbortHandle::new_pair(); - lock(&self.in_flight).insert(operation_id, abort); - let capabilities = self.capabilities.clone(); - let metadata = self.metadata.clone(); - let config = self.config.clone(); - let in_flight = self.in_flight.clone(); - let cleanup = in_flight.clone(); - let future = async move { - let _guard = OperationGuard { - id: operation_id, - in_flight, - }; - let send = send_agentless_v04(&capabilities, payload.as_ref(), &metadata, &config); - - match Abortable::new(send, registration).await { - Ok(Ok(_)) => Ok(()), - Ok(Err(error)) => Err(send_error(error)), - Err(_) => Err(Error::from_reason("data-pipeline export was cancelled")), - } - }; - - match env.spawn_future(future) { - Ok(promise) => Ok(promise), - Err(error) => { - lock(&cleanup).remove(&operation_id); - Err(error) - } - } - } - - #[napi] - pub fn cancel_all(&self) { - for abort in lock(&self.in_flight).values() { - abort.abort(); - } - } -} - -impl Drop for AgentlessExporter { - fn drop(&mut self) { - self.cancel_all(); - } -} - -struct OperationGuard { - id: u32, - in_flight: Arc>>, -} - -impl Drop for OperationGuard { - fn drop(&mut self) { - lock(&self.in_flight).remove(&self.id); - } -} - -fn lock(mutex: &Mutex) -> std::sync::MutexGuard<'_, T> { - mutex.lock().unwrap_or_else(|error| error.into_inner()) -} - -fn duration_millis(duration: Duration) -> u32 { - u32::try_from(duration.as_millis()).unwrap_or(u32::MAX) -} - -fn network_error(error: napi::Error) -> HttpError { - HttpError::Network(anyhow::anyhow!(error.reason)) -} - -fn send_error(error: SendAgentlessV04Error) -> Error { - Error::from_reason(format!("failed to send data-pipeline export: {error}")) -} diff --git a/crates/libdatadog/src/lib.rs b/crates/libdatadog/src/lib.rs index e133c0a1..259fcacf 100644 --- a/crates/libdatadog/src/lib.rs +++ b/crates/libdatadog/src/lib.rs @@ -1,3 +1,2 @@ -mod data_pipeline; mod sketches; mod zstd; diff --git a/packages/libdatadog/README.md b/packages/libdatadog/README.md index 2e710cf6..111b17d0 100644 --- a/packages/libdatadog/README.md +++ b/packages/libdatadog/README.md @@ -5,13 +5,15 @@ > applications or other libraries. Its API, behavior, and distribution may > change without notice. -Universal Node.js bindings for libdatadog. Matching native and WASM bindings -are maintained in the root `crates/libdatadog` and `crates/libdatadog-wasm` -workspace crates. Optional libdatadog functionality is published separately as +Universal Node.js bindings for libdatadog. Native and WASM bindings for +Zstandard compression and DDSketch are maintained in the root +`crates/libdatadog` and `crates/libdatadog-wasm` workspace crates. Optional +libdatadog functionality is published separately as `@datadog/libdatadog-extras`. -Both backends expose the agentless data pipeline, Zstandard compression, and -DDSketch from a single native or WASM artifact. +The agentless data pipeline always uses the WASM backend. Zstandard compression +and DDSketch use the native backend when it is available, with WASM as the +fallback. The package accepts Datadog v0.4 MessagePack payloads and exports them to an agentless intake. diff --git a/packages/libdatadog/lib/agentless.js b/packages/libdatadog/lib/agentless.js index 5d823027..d044ff32 100644 --- a/packages/libdatadog/lib/agentless.js +++ b/packages/libdatadog/lib/agentless.js @@ -4,11 +4,18 @@ 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() @@ -47,6 +54,10 @@ class AgentlessExporter { } } +/** + * @param {AgentlessBinding} binding + * @param {AgentlessExporterOptions} options + */ function createAgentlessExporter (binding, options) { return new AgentlessExporter(binding, options) } diff --git a/packages/libdatadog/lib/load.js b/packages/libdatadog/lib/load.js index af12c48c..53a7400a 100644 --- a/packages/libdatadog/lib/load.js +++ b/packages/libdatadog/lib/load.js @@ -8,4 +8,12 @@ try { native = undefined } -module.exports = native ?? require('./wasm') +module.exports = { + ...(native ?? require('./wasm')), + createAgentlessExporter, +} + +/** @param {import('../index').AgentlessExporterOptions} options */ +function createAgentlessExporter (options) { + return require('./wasm').createAgentlessExporter(options) +} diff --git a/packages/libdatadog/lib/native.js b/packages/libdatadog/lib/native.js index 02e8a926..86b430ff 100644 --- a/packages/libdatadog/lib/native.js +++ b/packages/libdatadog/lib/native.js @@ -3,8 +3,6 @@ const path = require('node:path') const os = require('node:os') -const { createAgentlessExporter } = require('./agentless') - const target = getNativeTarget() const binding = loadBinding(target) @@ -47,6 +45,5 @@ function loadBinding (target) { module.exports = { backend: () => 'native', DDSketch: binding.DDSketch, - createAgentlessExporter: options => createAgentlessExporter(binding, options), zstd_compress: binding.zstd_compress, } diff --git a/packages/libdatadog/lib/wasm.js b/packages/libdatadog/lib/wasm.js index d77de2c5..3bb9c3d5 100644 --- a/packages/libdatadog/lib/wasm.js +++ b/packages/libdatadog/lib/wasm.js @@ -2,11 +2,14 @@ const binding = require('@datadog/libdatadog-wasm') -const { createAgentlessExporter } = require('./agentless') - module.exports = { backend: () => 'wasm', DDSketch: binding.DDSketch, - createAgentlessExporter: options => createAgentlessExporter(binding, options), + 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/test/capabilities.test.js b/packages/libdatadog/test/capabilities.test.js index 626d5a4c..34f3e83a 100644 --- a/packages/libdatadog/test/capabilities.test.js +++ b/packages/libdatadog/test/capabilities.test.js @@ -13,10 +13,10 @@ const nativeArtifact = fs.existsSync(nativeDirectory) const wasm = require('../wasm') const native = nativeArtifact ? loadNative() : undefined -test('native and WASM backends expose the same capabilities', { +test('native backend excludes the WASM-only agentless exporter', { skip: !native, }, () => { - assert.deepStrictEqual(new Set(Object.keys(native)), new Set(Object.keys(wasm))) + assert.strictEqual(native.createAgentlessExporter, undefined) }) test('universal backends exclude optional extras', () => { diff --git a/packages/libdatadog/test/exporter.test.js b/packages/libdatadog/test/exporter.test.js index c13fcc89..91f8ae82 100644 --- a/packages/libdatadog/test/exporter.test.js +++ b/packages/libdatadog/test/exporter.test.js @@ -1,12 +1,10 @@ 'use strict' const assert = require('node:assert/strict') -const { spawnSync } = require('node:child_process') const fs = require('node:fs') const http = require('node:http') const path = require('node:path') const { test } = require('node:test') -const { Worker } = require('node:worker_threads') const { zstdDecompressSync } = require('node:zlib') const { encode } = require('@msgpack/msgpack') @@ -20,15 +18,28 @@ const nativeArtifact = fs.existsSync(nativeDirectory) : undefined const wasmArtifact = path.join(packageRoot, 'wasm', 'dist', 'libdatadog_wasm.js') -test('native backend compresses agentless v0.4 exports with Zstandard', { - skip: !nativeArtifact, +test('package entry points defer unused agentless modules', { + skip: !fs.existsSync(wasmArtifact), +}, () => { + const agentlessPath = require.resolve('../lib/agentless') + const wasmBindingPath = require.resolve('@datadog/libdatadog-wasm') + + if (nativeArtifact) { + loadNativePipeline() + assert.strictEqual(require.cache[wasmBindingPath], undefined) + } else { + require('..') + } + assert.strictEqual(require.cache[agentlessPath], undefined) + + require('../wasm') + assert.strictEqual(require.cache[agentlessPath], undefined) +}) + +test('universal entry point uses WASM for agentless v0.4 exports with a native backend', { + skip: !nativeArtifact || !fs.existsSync(wasmArtifact), }, async () => { - process.env.DD_LIBDATADOG_NATIVE_PATH = path.join(nativeDirectory, nativeArtifact) - await assertExport( - require('../lib/native'), - 'native', - ) - delete process.env.DD_LIBDATADOG_NATIVE_PATH + await assertExport(loadNativePipeline(), 'native') }) test('inline-WASM backend compresses agentless v0.4 exports with Zstandard', { @@ -70,155 +81,56 @@ test('inline-WASM backend validates optional values', { ) }) -const backends = [ - { - name: 'native', - skip: !nativeArtifact, - load: loadNativePipeline, - }, - { - name: 'inline-WASM', - skip: !fs.existsSync(wasmArtifact), - load: () => require('../wasm'), - }, -] - -for (const backend of backends) { - test(`${backend.name} retries in Rust until the third attempt succeeds`, { - skip: backend.skip, - }, async () => { - const pipeline = backend.load() - 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(`${backend.name} applies Rust timeouts and retry policy`, { - skip: backend.skip, - }, async () => { - const pipeline = backend.load() - let requests = 0 - const server = http.createServer((incoming) => { +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++ - incoming.resume() + 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, { 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(`${backend.name} close cancels an active HTTP request`, { - skip: backend.skip, - }, async () => { - const pipeline = backend.load() - 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(`${backend.name} close cancels retry backoff`, { - skip: backend.skip, - }, async () => { - const pipeline = backend.load() - 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)) - } - }) -} + 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('an idle NAPI exporter does not keep Node alive', { - skip: !nativeArtifact, -}, () => { - const nativePath = path.join(nativeDirectory, nativeArtifact) - const modulePath = path.join(packageRoot, 'lib', 'native.js') - const script = ` - const pipeline = require(${JSON.stringify(modulePath)}) - pipeline.createAgentlessExporter({ - endpoint: 'http://127.0.0.1:1/api/v2/spans', - apiKey: 'test-api-key', - tracerVersion: '0.1.0', - languageVersion: process.version, - languageInterpreter: 'v8', - }) - ` - const result = spawnSync(process.execPath, ['-e', script], { - env: { ...process.env, DD_LIBDATADOG_NATIVE_PATH: nativePath }, - encoding: 'utf8', - timeout: 3000, +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() }) - assert.notStrictEqual(result.error?.code, 'ETIMEDOUT') - assert.strictEqual(result.status, 0, result.stderr) + 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('NAPI exporter survives worker teardown during an HTTP request', { - skip: !nativeArtifact, +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 @@ -227,39 +139,50 @@ test('NAPI exporter survives worker teardown during an HTTP request', { incoming.resume() incoming.once('end', resolveRequest) }) + await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)) - const { port } = server.address() - const worker = new Worker(` - const { workerData } = require('node:worker_threads') - process.env.DD_LIBDATADOG_NATIVE_PATH = workerData.nativePath - const pipeline = require(workerData.modulePath) - const exporter = pipeline.createAgentlessExporter({ - endpoint: workerData.endpoint, - apiKey: 'test-api-key', - tracerVersion: '0.1.0', - languageVersion: process.version, - languageInterpreter: 'v8', - }) - exporter.sendV04(Buffer.from(workerData.payload)).catch(() => {}) - `, { - eval: true, - workerData: { - nativePath: path.join(nativeDirectory, nativeArtifact), - modulePath: path.join(packageRoot, 'lib', 'native.js'), - endpoint: `http://127.0.0.1:${port}/api/v2/spans`, - payload: tracePayload(), - }, + 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 workerError = new Promise((_, reject) => { - worker.once('error', reject) + 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 { - await Promise.race([request, workerError]) - const exitCode = await worker.terminate() - assert.strictEqual(exitCode, 1) + 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 worker.terminate() + await exporter.close() await new Promise(resolve => server.close(resolve)) } }) @@ -315,7 +238,7 @@ function tracePayload () { function loadNativePipeline () { process.env.DD_LIBDATADOG_NATIVE_PATH = path.join(nativeDirectory, nativeArtifact) try { - return require('../lib/native') + return require('..') } finally { delete process.env.DD_LIBDATADOG_NATIVE_PATH } From 3197ab649c121c43abd32b78c409dda4d36ab269 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Mon, 31 Aug 2026 18:33:32 +0200 Subject: [PATCH 17/20] refactor(libdatadog): remove N-API backend (#218) The package has no native-only consumer, so platform artifacts add build and release work without providing a required capability. --- .github/workflows/build.yml | 168 -- .github/workflows/release.yml | 160 -- Cargo.lock | 128 +- README.md | 18 +- crates/libdatadog/Cargo.toml | 17 - crates/libdatadog/build.rs | 3 - crates/libdatadog/src/lib.rs | 2 - crates/libdatadog/src/sketches/mod.rs | 41 - crates/libdatadog/src/zstd/mod.rs | 9 - packages/libdatadog/.gitignore | 2 - packages/libdatadog/README.md | 26 +- packages/libdatadog/index.d.ts | 2 +- packages/libdatadog/index.js | 2 +- packages/libdatadog/lib/load.js | 19 - packages/libdatadog/lib/native.js | 49 - packages/libdatadog/package-lock.json | 2049 +---------------- packages/libdatadog/package.json | 27 +- packages/libdatadog/scripts/build-native.js | 30 - packages/libdatadog/scripts/package-native.js | 99 - .../libdatadog/scripts/report-napi-size.js | 183 -- packages/libdatadog/scripts/set-version.js | 3 - packages/libdatadog/test/bundlers.test.js | 6 +- packages/libdatadog/test/capabilities.test.js | 41 +- packages/libdatadog/test/exporter.test.js | 41 +- .../libdatadog/test/package-contents.test.js | 105 +- packages/libdatadog/test/package.test.js | 36 +- packages/libdatadog/test/size-report.test.js | 53 - packages/libdatadog/test/types.test.ts | 2 +- scripts/check-dependencies.js | 21 +- test/dependencies.js | 69 +- 30 files changed, 150 insertions(+), 3261 deletions(-) delete mode 100644 crates/libdatadog/Cargo.toml delete mode 100644 crates/libdatadog/build.rs delete mode 100644 crates/libdatadog/src/lib.rs delete mode 100644 crates/libdatadog/src/sketches/mod.rs delete mode 100644 crates/libdatadog/src/zstd/mod.rs delete mode 100644 packages/libdatadog/lib/load.js delete mode 100644 packages/libdatadog/lib/native.js delete mode 100644 packages/libdatadog/scripts/build-native.js delete mode 100644 packages/libdatadog/scripts/package-native.js delete mode 100644 packages/libdatadog/scripts/report-napi-size.js diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 57a04d57..4f568bf9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,10 +32,7 @@ jobs: run: npm run check:dependencies - run: npm ci --prefix packages/libdatadog - run: cargo install wasm-pack --version 0.14.0 --locked - - run: cargo install cargo-bloat --version 0.12.1 --locked - run: npm run build --prefix packages/libdatadog - - name: Report N-API binary size - run: npm run report:napi-size --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 @@ -47,80 +44,6 @@ jobs: name: libdatadog-wasm path: packages/libdatadog/wasm/dist - build-libdatadog-platform: - name: Build libdatadog (${{ matrix.package-target }}) - strategy: - fail-fast: false - matrix: - include: - - rust-target: aarch64-apple-darwin - package-target: darwin-arm64 - runner: macos-15 - - rust-target: x86_64-apple-darwin - package-target: darwin-x64 - runner: macos-15-intel - - rust-target: aarch64-unknown-linux-gnu - package-target: linux-arm64-gnu - runner: ubuntu-24.04-arm - - rust-target: aarch64-unknown-linux-musl - package-target: linux-arm64-musl - runner: ubuntu-24.04-arm - build_args: --cross-compile - zig_arch: aarch64 - zig_sha256: 958ed7d1e00d0ea76590d27666efbf7a932281b3d7ba0c6b01b0ff26498f667f - - rust-target: x86_64-unknown-linux-gnu - package-target: linux-x64-gnu - runner: ubuntu-latest - - rust-target: x86_64-unknown-linux-musl - package-target: linux-x64-musl - runner: ubuntu-latest - build_args: --cross-compile - zig_arch: x86_64 - zig_sha256: 02aa270f183da276e5b5920b1dac44a63f1a49e55050ebde3aecc9eb82f93239 - runs-on: ${{ matrix.runner }} - 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: Install Zig - if: matrix.zig_arch - env: - ZIG_ARCH: ${{ matrix.zig_arch }} - ZIG_SHA256: ${{ matrix.zig_sha256 }} - ZIG_VERSION: 0.15.2 - run: | - ZIG_ARCHIVE="${RUNNER_TEMP}/zig.tar.xz" - ZIG_DIRECTORY="${RUNNER_TEMP}/zig" - curl --fail --location --silent --show-error \ - --output "${ZIG_ARCHIVE}" \ - "https://ziglang.org/download/${ZIG_VERSION}/zig-${ZIG_ARCH}-linux-${ZIG_VERSION}.tar.xz" - echo "${ZIG_SHA256} ${ZIG_ARCHIVE}" | sha256sum --check - mkdir -p "${ZIG_DIRECTORY}" - tar --extract --xz --file "${ZIG_ARCHIVE}" \ - --directory "${ZIG_DIRECTORY}" --strip-components=1 - echo "${ZIG_DIRECTORY}" >> "${GITHUB_PATH}" - - name: Install cargo-zigbuild - if: matrix.build_args - run: cargo install --locked cargo-zigbuild --version 0.23.0 - - name: Add Rust target - run: rustup target add '${{ matrix.rust-target }}' - - run: npm ci --prefix packages/libdatadog - - name: Build native extension - run: >- - npm run build:native --prefix packages/libdatadog -- - --target '${{ matrix.rust-target }}' ${{ matrix.build_args }} - - run: npm run package:native --prefix packages/libdatadog - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: libdatadog-binding-${{ matrix.package-target }} - path: packages/libdatadog/dist/native/*.node - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: libdatadog-platform-${{ matrix.package-target }} - path: packages/libdatadog/dist/packages - test-libdatadog: needs: build-libdatadog runs-on: ubuntu-latest @@ -140,95 +63,6 @@ jobs: path: packages/libdatadog/wasm/dist - run: npm test --prefix packages/libdatadog - test-libdatadog-platform: - name: Test libdatadog (${{ matrix.platform.package_target }}, Node ${{ matrix.node }}) - needs: - - build-libdatadog - - build-libdatadog-platform - strategy: - fail-fast: false - matrix: - platform: - - package_target: darwin-arm64 - runner: macos-15 - - package_target: darwin-x64 - runner: macos-15-intel - - package_target: linux-arm64-gnu - runner: ubuntu-24.04-arm - - package_target: linux-x64-gnu - runner: ubuntu-latest - node: [18, 24] - runs-on: ${{ matrix.platform.runner }} - env: - DD_LIBDATADOG_EXPECTED_BACKEND: native - LIBDATADOG_TARGET: ${{ matrix.platform.package_target }} - 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-binding-${{ matrix.platform.package_target }} - path: packages/libdatadog/dist/native - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: libdatadog-platform-${{ matrix.platform.package_target }} - path: packages/libdatadog/dist/packages - - 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-platform-musl: - name: Test libdatadog (${{ matrix.platform.package_target }}, Node ${{ matrix.node }}) - needs: - - build-libdatadog - - build-libdatadog-platform - strategy: - fail-fast: false - matrix: - platform: - - package_target: linux-arm64-musl - runner: ubuntu-24.04-arm - - package_target: linux-x64-musl - runner: ubuntu-latest - node: [18, 24] - runs-on: ${{ matrix.platform.runner }} - env: - DD_LIBDATADOG_EXPECTED_BACKEND: native - LIBDATADOG_TARGET: ${{ matrix.platform.package_target }} - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: libdatadog-binding-${{ matrix.platform.package_target }} - path: packages/libdatadog/dist/native - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: libdatadog-platform-${{ matrix.platform.package_target }} - path: packages/libdatadog/dist/packages - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: libdatadog-wasm - path: packages/libdatadog/wasm/dist - - name: Test in Alpine - run: | - docker run --rm \ - --env DD_LIBDATADOG_EXPECTED_BACKEND \ - --env LIBDATADOG_TARGET \ - --volume "${GITHUB_WORKSPACE}:/workspace" \ - --workdir /workspace \ - "node:${{ matrix.node }}-alpine" \ - sh -c ' - apk add --no-cache git - npm ci --prefix packages/libdatadog - npm test --prefix packages/libdatadog - ' - test-libdatadog-windows: name: Test libdatadog WASM (Windows, Node ${{ matrix.node }}) needs: build-libdatadog @@ -237,8 +71,6 @@ jobs: fail-fast: false matrix: node: [18, 24] - env: - DD_LIBDATADOG_EXPECTED_BACKEND: wasm steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Setup Node.js diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a8c0e27b..f815e4ca 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -88,60 +88,6 @@ jobs: name: libdatadog-wasm path: packages/libdatadog/wasm/dist - build-libdatadog-platform: - name: Build libdatadog (${{ matrix.package-target }}) - needs: versions - strategy: - fail-fast: false - matrix: - include: - - rust-target: aarch64-apple-darwin - package-target: darwin-arm64 - runner: macos-15 - - rust-target: x86_64-apple-darwin - package-target: darwin-x64 - runner: macos-15-intel - - rust-target: aarch64-unknown-linux-gnu - package-target: linux-arm64-gnu - runner: ubuntu-24.04-arm - - rust-target: aarch64-unknown-linux-musl - package-target: linux-arm64-musl - runner: ubuntu-24.04-arm - install-musl: true - - rust-target: x86_64-unknown-linux-gnu - package-target: linux-x64-gnu - runner: ubuntu-latest - - rust-target: x86_64-unknown-linux-musl - package-target: linux-x64-musl - runner: ubuntu-latest - install-musl: true - runs-on: ${{ matrix.runner }} - 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: Install musl toolchain - if: matrix.install-musl - run: sudo apt-get update && sudo apt-get install -y musl-tools - - name: Add Rust target - run: rustup target add '${{ matrix.rust-target }}' - - run: npm ci --prefix packages/libdatadog - - name: Set package version - run: node packages/libdatadog/scripts/set-version.js '${{ needs.versions.outputs.version }}' - - name: Build native extension - run: npm run build:native --prefix packages/libdatadog -- --target '${{ matrix.rust-target }}' - - run: npm run package:native --prefix packages/libdatadog - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: libdatadog-binding-${{ matrix.package-target }} - path: packages/libdatadog/dist/native/*.node - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: libdatadog-platform-${{ matrix.package-target }} - path: packages/libdatadog/dist/packages - test-libdatadog-wasm: needs: build-libdatadog-wasm runs-on: ubuntu-latest @@ -161,95 +107,6 @@ jobs: path: packages/libdatadog/wasm/dist - run: npm test --prefix packages/libdatadog - test-libdatadog-platform: - name: Test libdatadog (${{ matrix.platform.package_target }}, Node ${{ matrix.node }}) - needs: - - build-libdatadog-platform - - build-libdatadog-wasm - strategy: - fail-fast: false - matrix: - platform: - - package_target: darwin-arm64 - runner: macos-15 - - package_target: darwin-x64 - runner: macos-15-intel - - package_target: linux-arm64-gnu - runner: ubuntu-24.04-arm - - package_target: linux-x64-gnu - runner: ubuntu-latest - node: [18, 24] - runs-on: ${{ matrix.platform.runner }} - env: - DD_LIBDATADOG_EXPECTED_BACKEND: native - LIBDATADOG_TARGET: ${{ matrix.platform.package_target }} - 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-binding-${{ matrix.platform.package_target }} - path: packages/libdatadog/dist/native - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: libdatadog-platform-${{ matrix.platform.package_target }} - path: packages/libdatadog/dist/packages - - 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-platform-musl: - name: Test libdatadog (${{ matrix.platform.package_target }}, Node ${{ matrix.node }}) - needs: - - build-libdatadog-platform - - build-libdatadog-wasm - strategy: - fail-fast: false - matrix: - platform: - - package_target: linux-arm64-musl - runner: ubuntu-24.04-arm - - package_target: linux-x64-musl - runner: ubuntu-latest - node: [18, 24] - runs-on: ${{ matrix.platform.runner }} - env: - DD_LIBDATADOG_EXPECTED_BACKEND: native - LIBDATADOG_TARGET: ${{ matrix.platform.package_target }} - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: libdatadog-binding-${{ matrix.platform.package_target }} - path: packages/libdatadog/dist/native - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: libdatadog-platform-${{ matrix.platform.package_target }} - path: packages/libdatadog/dist/packages - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: libdatadog-wasm - path: packages/libdatadog/wasm/dist - - name: Test in Alpine - run: | - docker run --rm \ - --env DD_LIBDATADOG_EXPECTED_BACKEND \ - --env LIBDATADOG_TARGET \ - --volume "${GITHUB_WORKSPACE}:/workspace" \ - --workdir /workspace \ - "node:${{ matrix.node }}-alpine" \ - sh -c ' - apk add --no-cache git - npm ci --prefix packages/libdatadog - npm test --prefix packages/libdatadog - ' - test-libdatadog-windows: name: Test libdatadog WASM (Windows, Node ${{ matrix.node }}) needs: build-libdatadog-wasm @@ -258,8 +115,6 @@ jobs: fail-fast: false matrix: node: [18, 24] - env: - DD_LIBDATADOG_EXPECTED_BACKEND: wasm steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - name: Setup Node.js @@ -277,10 +132,7 @@ jobs: runs-on: ubuntu-latest needs: - build-libdatadog-extras - - build-libdatadog-platform - build-libdatadog-wasm - - test-libdatadog-platform - - test-libdatadog-platform-musl - test-libdatadog-wasm - test-libdatadog-windows - versions @@ -313,11 +165,6 @@ jobs: with: name: libdatadog-wasm path: packages/libdatadog/wasm/dist - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - pattern: libdatadog-platform-* - path: packages/libdatadog/dist/packages - merge-multiple: true - name: Set package versions run: | npm pkg set 'version=${{ needs.versions.outputs.version }}' @@ -328,13 +175,6 @@ jobs: env: NPM_TAG: ${{ needs.versions.outputs.npm-tag }} run: npm publish packages/libdatadog/wasm --access public --tag "$NPM_TAG" - - name: Publish libdatadog platform packages - env: - NPM_TAG: ${{ needs.versions.outputs.npm-tag }} - run: | - for package in packages/libdatadog/dist/packages/*; do - npm publish "$package" --access public --tag "$NPM_TAG" - done - name: Publish libdatadog env: NPM_TAG: ${{ needs.versions.outputs.npm-tag }} diff --git a/Cargo.lock b/Cargo.lock index 23cc4b3e..4589b216 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,15 +288,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "convert_case" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49" -dependencies = [ - "unicode-segmentation", -] - [[package]] name = "core-foundation" version = "0.10.1" @@ -346,8 +337,8 @@ version = "0.2.0" dependencies = [ "anyhow", "libdd-crashtracker", - "napi 2.16.17", - "napi-derive 2.16.13", + "napi", + "napi-derive", "rustls", "serde_json", ] @@ -387,12 +378,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "ctor" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" - [[package]] name = "darling" version = "0.23.0" @@ -1202,17 +1187,6 @@ version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" -[[package]] -name = "libdatadog" -version = "0.1.0" -dependencies = [ - "libdd-ddsketch 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "napi 3.12.2", - "napi-build", - "napi-derive 3.6.3", - "zstd", -] - [[package]] name = "libdatadog-data-pipeline" version = "0.1.0" @@ -1913,16 +1887,6 @@ dependencies = [ "windows-link 0.2.1", ] -[[package]] -name = "libloading" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "754ca22de805bb5744484a5b151a9e1a8e837d5dc232c2d7d8c2e3492edc8b60" -dependencies = [ - "cfg-if", - "windows-link 0.2.1", -] - [[package]] name = "libm" version = "0.2.16" @@ -2048,36 +2012,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55740c4ae1d8696773c78fdafd5d0e5fe9bc9f1b071c7ba493ba5c413a9184f3" dependencies = [ "bitflags 2.13.1", - "ctor 0.2.9", - "napi-derive 2.16.13", - "napi-sys 2.4.0", + "ctor", + "napi-derive", + "napi-sys", "once_cell", "serde", "serde_json", ] -[[package]] -name = "napi" -version = "3.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58c5f4d5375213fdb7be2655e152386e82f026f9a5ba36a75556e11359aafe09" -dependencies = [ - "bitflags 2.13.1", - "ctor 1.0.13", - "futures", - "libc", - "napi-build", - "napi-sys 3.3.0", - "nohash-hasher", - "rustc-hash", -] - -[[package]] -name = "napi-build" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60fdf9b392c50e7c4170fa633bd909490ed7835cea4c046776d1a4dd8d2ae0ab" - [[package]] name = "napi-derive" version = "2.16.13" @@ -2085,22 +2027,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cbe2585d8ac223f7d34f13701434b9d5f4eb9c332cccce8dee57ea18ab8ab0c" dependencies = [ "cfg-if", - "convert_case 0.6.0", - "napi-derive-backend 1.0.75", - "proc-macro2", - "quote", - "syn 2.0.119", -] - -[[package]] -name = "napi-derive" -version = "3.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa55ea69990c90b888e9e77044410e304ce7f35de599dc6d0b5c1923d2e59af" -dependencies = [ - "convert_case 0.11.0", - "ctor 1.0.13", - "napi-derive-backend 6.1.2", + "convert_case", + "napi-derive-backend", "proc-macro2", "quote", "syn 2.0.119", @@ -2112,42 +2040,20 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1639aaa9eeb76e91c6ae66da8ce3e89e921cd3885e99ec85f4abacae72fc91bf" dependencies = [ - "convert_case 0.6.0", + "convert_case", "once_cell", "proc-macro2", "quote", "syn 2.0.119", ] -[[package]] -name = "napi-derive-backend" -version = "6.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df4056ac7c18e4438ccf0edaed4340ca0d269278c8ec19284f7b23cb039fd0ae" -dependencies = [ - "convert_case 0.11.0", - "proc-macro2", - "quote", - "semver", - "syn 2.0.119", -] - [[package]] name = "napi-sys" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427802e8ec3a734331fec1035594a210ce1ff4dc5bc1950530920ab717964ea3" dependencies = [ - "libloading 0.8.9", -] - -[[package]] -name = "napi-sys" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85fbf1fa9f1babfe396d74bbbf52b3643770243e8f5b0b46715d4caf7f0dfc9a" -dependencies = [ - "libloading 0.9.0", + "libloading", ] [[package]] @@ -2175,12 +2081,6 @@ dependencies = [ "libc", ] -[[package]] -name = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -2549,8 +2449,8 @@ dependencies = [ "anyhow", "libdd-library-config", "libdd-trace-protobuf 4.0.0", - "napi 2.16.17", - "napi-derive 2.16.13", + "napi", + "napi-derive", ] [[package]] @@ -2936,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" diff --git a/README.md b/README.md index a5a2df12..0ec459a6 100644 --- a/README.md +++ b/README.md @@ -9,25 +9,17 @@ published as two packages with different availability guarantees. > libraries. Their APIs, behavior, and distribution may change without notice. - `@datadog/libdatadog` provides functionality required in every environment - through optional native platform packages with an inlined WASM fallback. + 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 universal package is maintained under -[`packages/libdatadog`](packages/libdatadog). Zstandard compression and -DDSketch use the native backend when it is available, with WASM as the -fallback. The agentless data pipeline always uses the WASM backend. - -The package tries a platform-native napi-rs backend first. Native artifacts are -published as optional dependencies using napi-rs-compatible package names such -as `@datadog/libdatadog-linux-x64-gnu`. If the platform package cannot be -loaded, the package falls back to a wasm-bindgen backend whose WebAssembly bytes -are embedded in JavaScript. This fallback is always part of the metapackage, so -it also works when native extensions are unavailable, omitted by a bundler, or -moved to another platform. +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. See the [package README](packages/libdatadog/README.md) for implementation and packaging details. diff --git a/crates/libdatadog/Cargo.toml b/crates/libdatadog/Cargo.toml deleted file mode 100644 index f15da88a..00000000 --- a/crates/libdatadog/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "libdatadog" -version = "0.1.0" -edition = "2021" - -[lib] -crate-type = ["cdylib"] -name = "libdatadog" - -[dependencies] -napi = { version = "3", default-features = false, features = ["napi8"] } -napi-derive = "3" -libdd-ddsketch = "1.1.1" -zstd = { version = "0.13.3", default-features = false, features = ["thin"] } - -[build-dependencies] -napi-build = "2" diff --git a/crates/libdatadog/build.rs b/crates/libdatadog/build.rs deleted file mode 100644 index 0f1b0100..00000000 --- a/crates/libdatadog/build.rs +++ /dev/null @@ -1,3 +0,0 @@ -fn main() { - napi_build::setup(); -} diff --git a/crates/libdatadog/src/lib.rs b/crates/libdatadog/src/lib.rs deleted file mode 100644 index 259fcacf..00000000 --- a/crates/libdatadog/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -mod sketches; -mod zstd; diff --git a/crates/libdatadog/src/sketches/mod.rs b/crates/libdatadog/src/sketches/mod.rs deleted file mode 100644 index d8fef5f0..00000000 --- a/crates/libdatadog/src/sketches/mod.rs +++ /dev/null @@ -1,41 +0,0 @@ -use libdd_ddsketch::DDSketch as InnerDDSketch; -use napi::bindgen_prelude::*; -use napi_derive::napi; - -#[napi(js_name = "DDSketch")] -#[derive(Default)] -pub struct DDSketch { - inner: InnerDDSketch, -} - -#[napi] -impl DDSketch { - #[napi(constructor)] - pub fn new() -> Self { - Self::default() - } - - #[napi] - pub fn add(&mut self, point: f64) -> Result<()> { - self.inner - .add(point) - .map_err(|error| Error::from_reason(error.to_string())) - } - - #[napi(js_name = "addWithCount")] - pub fn add_with_count(&mut self, point: f64, count: f64) -> Result<()> { - self.inner - .add_with_count(point, count) - .map_err(|error| Error::from_reason(error.to_string())) - } - - #[napi] - pub fn count(&self) -> f64 { - self.inner.count() - } - - #[napi] - pub fn encode(&self) -> Buffer { - self.inner.clone().encode_to_vec().into() - } -} diff --git a/crates/libdatadog/src/zstd/mod.rs b/crates/libdatadog/src/zstd/mod.rs deleted file mode 100644 index 779a8046..00000000 --- a/crates/libdatadog/src/zstd/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -use napi::bindgen_prelude::*; -use napi_derive::napi; - -#[napi(js_name = "zstd_compress")] -pub fn zstd_compress(data: Buffer, level: i32) -> Result { - zstd::encode_all(data.as_ref(), level) - .map(Buffer::from) - .map_err(|error| Error::from_reason(format!("failed to compress data: {error}"))) -} diff --git a/packages/libdatadog/.gitignore b/packages/libdatadog/.gitignore index 7262e8bc..6be07be5 100644 --- a/packages/libdatadog/.gitignore +++ b/packages/libdatadog/.gitignore @@ -1,5 +1,3 @@ node_modules/ -dist/ wasm/dist/ -*.node *.wasm diff --git a/packages/libdatadog/README.md b/packages/libdatadog/README.md index 111b17d0..a37bcc7a 100644 --- a/packages/libdatadog/README.md +++ b/packages/libdatadog/README.md @@ -5,25 +5,15 @@ > applications or other libraries. Its API, behavior, and distribution may > change without notice. -Universal Node.js bindings for libdatadog. Native and WASM bindings for -Zstandard compression and DDSketch are maintained in the root -`crates/libdatadog` and `crates/libdatadog-wasm` workspace crates. Optional -libdatadog functionality is published separately as -`@datadog/libdatadog-extras`. - -The agentless data pipeline always uses the WASM backend. Zstandard compression -and DDSketch use the native backend when it is available, with WASM as the -fallback. +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`. The package accepts Datadog v0.4 MessagePack payloads and exports them to an agentless intake. -The package tries a platform-native napi-rs backend first and falls back to 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. This directory -is itself the published metapackage. Platform-native packages follow the -napi-rs layout, are generated in `dist/packages`, and are installed as optional -dependencies. They are not npm workspaces because their mutually exclusive -`os`, `cpu`, and `libc` constraints would make local workspace installs -platform-dependent. No raw `.wasm` asset is published. +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. No raw `.wasm` +asset or native extension is published. diff --git a/packages/libdatadog/index.d.ts b/packages/libdatadog/index.d.ts index 6aec92a1..0786af66 100644 --- a/packages/libdatadog/index.d.ts +++ b/packages/libdatadog/index.d.ts @@ -19,7 +19,7 @@ export interface AgentlessExporter { } export function createAgentlessExporter(options: AgentlessExporterOptions): AgentlessExporter -export function backend(): 'native' | 'wasm' +export function backend(): 'wasm' export function zstd_compress(data: Uint8Array, level: number): Uint8Array diff --git a/packages/libdatadog/index.js b/packages/libdatadog/index.js index 3c5e69a9..963c32fc 100644 --- a/packages/libdatadog/index.js +++ b/packages/libdatadog/index.js @@ -1,3 +1,3 @@ 'use strict' -module.exports = require('./lib/load') +module.exports = require('./lib/wasm') diff --git a/packages/libdatadog/lib/load.js b/packages/libdatadog/lib/load.js deleted file mode 100644 index 53a7400a..00000000 --- a/packages/libdatadog/lib/load.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -let native - -try { - native = require('./native') -} catch { - native = undefined -} - -module.exports = { - ...(native ?? require('./wasm')), - createAgentlessExporter, -} - -/** @param {import('../index').AgentlessExporterOptions} options */ -function createAgentlessExporter (options) { - return require('./wasm').createAgentlessExporter(options) -} diff --git a/packages/libdatadog/lib/native.js b/packages/libdatadog/lib/native.js deleted file mode 100644 index 86b430ff..00000000 --- a/packages/libdatadog/lib/native.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict' - -const path = require('node:path') -const os = require('node:os') - -const target = getNativeTarget() -const binding = loadBinding(target) - -function getNativeTarget () { - const platform = os.platform() - const architecture = process.arch - - if (platform === 'darwin' && (architecture === 'arm64' || architecture === 'x64')) { - return `${platform}-${architecture}` - } - - if (platform === 'linux' && (architecture === 'arm64' || architecture === 'x64')) { - const libc = process.report?.getReport?.().header?.glibcVersionRuntime ? 'gnu' : 'musl' - return `linux-${architecture}-${libc}` - } - - throw new Error(`unsupported native libdatadog platform: ${platform}-${architecture}`) -} - -function loadBinding (target) { - if (process.env.DD_LIBDATADOG_NATIVE_PATH) { - return require(path.resolve(process.env.DD_LIBDATADOG_NATIVE_PATH)) - } - - const localArtifact = path.join( - __dirname, - '..', - 'dist', - 'native', - `libdatadog.${target}.node`, - ) - - try { - return require(localArtifact) - } catch { - return require(`@datadog/libdatadog-${target}`) - } -} - -module.exports = { - backend: () => 'native', - DDSketch: binding.DDSketch, - zstd_compress: binding.zstd_compress, -} diff --git a/packages/libdatadog/package-lock.json b/packages/libdatadog/package-lock.json index fe5079e9..71f2ca39 100644 --- a/packages/libdatadog/package-lock.json +++ b/packages/libdatadog/package-lock.json @@ -16,7 +16,6 @@ }, "devDependencies": { "@msgpack/msgpack": "^3.1.3", - "@napi-rs/cli": "^3.5.1", "esbuild": "^0.28.2", "typescript": "^6.0.3", "webpack": "^5.109.2", @@ -24,34 +23,8 @@ }, "engines": { "node": ">=18" - }, - "optionalDependencies": { - "@datadog/libdatadog-darwin-arm64": "0.1.0-pre", - "@datadog/libdatadog-darwin-x64": "0.1.0-pre", - "@datadog/libdatadog-linux-arm64-gnu": "0.1.0-pre", - "@datadog/libdatadog-linux-arm64-musl": "0.1.0-pre", - "@datadog/libdatadog-linux-x64-gnu": "0.1.0-pre", - "@datadog/libdatadog-linux-x64-musl": "0.1.0-pre" } }, - "node_modules/@datadog/libdatadog-darwin-arm64": { - "optional": true - }, - "node_modules/@datadog/libdatadog-darwin-x64": { - "optional": true - }, - "node_modules/@datadog/libdatadog-linux-arm64-gnu": { - "optional": true - }, - "node_modules/@datadog/libdatadog-linux-arm64-musl": { - "optional": true - }, - "node_modules/@datadog/libdatadog-linux-x64-gnu": { - "optional": true - }, - "node_modules/@datadog/libdatadog-linux-x64-musl": { - "optional": true - }, "node_modules/@datadog/libdatadog-wasm": { "resolved": "wasm", "link": true @@ -66,40 +39,6 @@ "node": ">=14.17.0" } }, - "node_modules/@emnapi/core": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.2.tgz", - "integrity": "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.2", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.2.tgz", - "integrity": "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", - "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@esbuild/aix-ppc64": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", @@ -511,1501 +450,7 @@ "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/@inquirer/ansi": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.7.tgz", - "integrity": "sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - } - }, - "node_modules/@inquirer/checkbox": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-5.2.1.tgz", - "integrity": "sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^2.0.7", - "@inquirer/core": "^11.2.1", - "@inquirer/figures": "^2.0.7", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/confirm": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-6.1.1.tgz", - "integrity": "sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^11.2.1", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/core": { - "version": "11.2.1", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-11.2.1.tgz", - "integrity": "sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/editor": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-5.2.2.tgz", - "integrity": "sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^11.2.1", - "@inquirer/external-editor": "^3.0.3", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/expand": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-5.1.1.tgz", - "integrity": "sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^11.2.1", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/external-editor": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-3.0.3.tgz", - "integrity": "sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chardet": "^2.1.1", - "iconv-lite": "^0.7.2" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/figures": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-2.0.7.tgz", - "integrity": "sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - } - }, - "node_modules/@inquirer/input": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-5.1.2.tgz", - "integrity": "sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^11.2.1", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/number": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-4.1.1.tgz", - "integrity": "sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^11.2.1", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/password": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-5.1.1.tgz", - "integrity": "sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^2.0.7", - "@inquirer/core": "^11.2.1", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/prompts": { - "version": "8.5.2", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-8.5.2.tgz", - "integrity": "sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==", - "dev": true, - "license": "MIT", - "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" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/rawlist": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-5.3.1.tgz", - "integrity": "sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^11.2.1", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/search": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-4.2.1.tgz", - "integrity": "sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/core": "^11.2.1", - "@inquirer/figures": "^2.0.7", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/select": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-5.2.1.tgz", - "integrity": "sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/ansi": "^2.0.7", - "@inquirer/core": "^11.2.1", - "@inquirer/figures": "^2.0.7", - "@inquirer/type": "^4.0.7" - }, - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@inquirer/type": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-4.0.7.tgz", - "integrity": "sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=23.5.0 || ^22.13.0 || ^20.17.0" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "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/@napi-rs/cli": { - "version": "3.8.6", - "resolved": "https://registry.npmjs.org/@napi-rs/cli/-/cli-3.8.6.tgz", - "integrity": "sha512-FnJ9fghsV9Q4zh2aJGPSvQiUlJRC27B6KhzAXcIW2rlSD8keak3mhXw4tJYa3KJkP9whETfsPwqp/DJRnQg5ng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@inquirer/prompts": "^8.5.2", - "@napi-rs/cross-toolchain": "^1.0.3", - "@napi-rs/wasm-tools": "^1.1.0", - "@octokit/rest": "^22.0.1", - "clipanion": "^4.0.0-rc.4", - "colorette": "^2.0.20", - "es-toolkit": "^1.47.0", - "js-yaml": "^4.2.0", - "obug": "^2.1.2", - "semver": "^7.8.2", - "typanion": "^3.14.0", - "typescript": "^6.0.3" - }, - "bin": { - "napi": "dist/cli.js", - "napi-raw": "cli.mjs" - }, - "engines": { - "node": "^20.17.0 || ^22.13.0 || >= 23.5.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", - "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4", - "emnapi": "^1.7.1 || ^2.0.0-alpha.4" - }, - "peerDependenciesMeta": { - "@emnapi/core": { - "optional": true - }, - "@emnapi/runtime": { - "optional": true - }, - "emnapi": { - "optional": true - } - } - }, - "node_modules/@napi-rs/cross-toolchain": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@napi-rs/cross-toolchain/-/cross-toolchain-1.0.3.tgz", - "integrity": "sha512-ENPfLe4937bsKVTDA6zdABx4pq9w0tHqRrJHyaGxgaPq03a2Bd1unD5XSKjXJjebsABJ+MjAv1A2OvCgK9yehg==", - "dev": true, - "license": "MIT", - "workspaces": [ - ".", - "arm64/*", - "x64/*" - ], - "dependencies": { - "@napi-rs/lzma": "^1.4.5", - "@napi-rs/tar": "^1.1.0", - "debug": "^4.4.1" - }, - "peerDependencies": { - "@napi-rs/cross-toolchain-arm64-target-aarch64": "^1.0.3", - "@napi-rs/cross-toolchain-arm64-target-armv7": "^1.0.3", - "@napi-rs/cross-toolchain-arm64-target-ppc64le": "^1.0.3", - "@napi-rs/cross-toolchain-arm64-target-s390x": "^1.0.3", - "@napi-rs/cross-toolchain-arm64-target-x86_64": "^1.0.3", - "@napi-rs/cross-toolchain-x64-target-aarch64": "^1.0.3", - "@napi-rs/cross-toolchain-x64-target-armv7": "^1.0.3", - "@napi-rs/cross-toolchain-x64-target-ppc64le": "^1.0.3", - "@napi-rs/cross-toolchain-x64-target-s390x": "^1.0.3", - "@napi-rs/cross-toolchain-x64-target-x86_64": "^1.0.3" - }, - "peerDependenciesMeta": { - "@napi-rs/cross-toolchain-arm64-target-aarch64": { - "optional": true - }, - "@napi-rs/cross-toolchain-arm64-target-armv7": { - "optional": true - }, - "@napi-rs/cross-toolchain-arm64-target-ppc64le": { - "optional": true - }, - "@napi-rs/cross-toolchain-arm64-target-s390x": { - "optional": true - }, - "@napi-rs/cross-toolchain-arm64-target-x86_64": { - "optional": true - }, - "@napi-rs/cross-toolchain-x64-target-aarch64": { - "optional": true - }, - "@napi-rs/cross-toolchain-x64-target-armv7": { - "optional": true - }, - "@napi-rs/cross-toolchain-x64-target-ppc64le": { - "optional": true - }, - "@napi-rs/cross-toolchain-x64-target-s390x": { - "optional": true - }, - "@napi-rs/cross-toolchain-x64-target-x86_64": { - "optional": true - } - } - }, - "node_modules/@napi-rs/lzma": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma/-/lzma-1.5.1.tgz", - "integrity": "sha512-sgOZ89+y8cDbY+3WbzR8CtIhCuFRWotZ9/2PjPVDJHz6np5KFTAev0DrwiyTJTgFsCRDhfGlbmhMgyhHbWdZ6g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^22.20 || ^24.12 || >=25" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "optionalDependencies": { - "@napi-rs/lzma-android-arm-eabi": "1.5.1", - "@napi-rs/lzma-android-arm64": "1.5.1", - "@napi-rs/lzma-darwin-arm64": "1.5.1", - "@napi-rs/lzma-darwin-x64": "1.5.1", - "@napi-rs/lzma-freebsd-x64": "1.5.1", - "@napi-rs/lzma-linux-arm-gnueabihf": "1.5.1", - "@napi-rs/lzma-linux-arm64-gnu": "1.5.1", - "@napi-rs/lzma-linux-arm64-musl": "1.5.1", - "@napi-rs/lzma-linux-ppc64-gnu": "1.5.1", - "@napi-rs/lzma-linux-riscv64-gnu": "1.5.1", - "@napi-rs/lzma-linux-s390x-gnu": "1.5.1", - "@napi-rs/lzma-linux-x64-gnu": "1.5.1", - "@napi-rs/lzma-linux-x64-musl": "1.5.1", - "@napi-rs/lzma-wasm32-wasi": "1.5.1", - "@napi-rs/lzma-win32-arm64-msvc": "1.5.1", - "@napi-rs/lzma-win32-ia32-msvc": "1.5.1", - "@napi-rs/lzma-win32-x64-msvc": "1.5.1" - } - }, - "node_modules/@napi-rs/lzma-android-arm-eabi": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-android-arm-eabi/-/lzma-android-arm-eabi-1.5.1.tgz", - "integrity": "sha512-sahBe4ko2Z69NPTddaX6ZgbQZu9SDoITxw1S3dWl1gAGynZG34qHHCT8UaUMFxf3h3zMhCJjEzz4basaBxiTuQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-android-arm64": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-android-arm64/-/lzma-android-arm64-1.5.1.tgz", - "integrity": "sha512-7tkQAJJuBHxAxiEBNFgSTpvrtGpbwZYYJUSOmGEK3OfbdbNeoT2rdBxpM/gY1s+itEVbtOSlpaRPPG19MnwOzA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-darwin-arm64": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-darwin-arm64/-/lzma-darwin-arm64-1.5.1.tgz", - "integrity": "sha512-XWX8gtF+GHGk3nH3Wm3QUZNcxw9QHsFVZz3MzVLhWWHhceede1J4/vD+3dj3E1iKB9G6mualaZxOoD08R3E+7g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-darwin-x64": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-darwin-x64/-/lzma-darwin-x64-1.5.1.tgz", - "integrity": "sha512-CfsqUpMTI1z8enrA/b+GcHM6YDI8D0kqCiqPYEnst4rbOABQ9KZ92ybTTNnlnZ7A017WoMZKUEWc36KXDwi0xg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-freebsd-x64": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-freebsd-x64/-/lzma-freebsd-x64-1.5.1.tgz", - "integrity": "sha512-bTyNfg90FXIgE61U7l14aMmVOqRQ6AyP5JMT3jmCStaZI18apLNPdzZ8i7yqxZfKvRMVfPjE2brXIw27c+RRgA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-linux-arm-gnueabihf": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-arm-gnueabihf/-/lzma-linux-arm-gnueabihf-1.5.1.tgz", - "integrity": "sha512-vNE+D8nrw+eOkBsdKCsmDhowDV3pIMKXEhedvXfbgrWbrO7GlZJH+RXL+X+RYLxGwi8Ym61ZMt15sIOnNmh9Sw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-linux-arm64-gnu": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-arm64-gnu/-/lzma-linux-arm64-gnu-1.5.1.tgz", - "integrity": "sha512-csUem4WgoKGTprv/pOPm9UIWbb+hrfUwYXefpTHPAEGVFLl5behEFabisJ7FtihCa3yG2Efcl+yw25rlhhrIYw==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-linux-arm64-musl": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-arm64-musl/-/lzma-linux-arm64-musl-1.5.1.tgz", - "integrity": "sha512-kB/xhlVN1eLvVmDJSKZEjp5Gg2xDYexNrB5jwpSMbOkeGS6N9AasByPBg5VqCpMYC+zZi7DM458DRhtWYhqXTQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-linux-ppc64-gnu": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-ppc64-gnu/-/lzma-linux-ppc64-gnu-1.5.1.tgz", - "integrity": "sha512-s28RW0W1yBWQc1nbPdF7tp14koqslY3ZWLVI8uaanX292Dc6ezd4NPVwxEoCNBVON/oD7BmUbWGtyFvmm7dQ5A==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-linux-riscv64-gnu": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-riscv64-gnu/-/lzma-linux-riscv64-gnu-1.5.1.tgz", - "integrity": "sha512-+lGNwYlIN14YPMTNvYtIJJqHFevDTd6Juw/1NmXbWx/iRd/LLrjhlM/yluMX6pxs6NkOGsuuEXJJrbbEUS59OQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-linux-s390x-gnu": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-s390x-gnu/-/lzma-linux-s390x-gnu-1.5.1.tgz", - "integrity": "sha512-PB44FFWWFrLeQowhcep1hPD1YcLqKlnnY60RMU74qrxTlr4YGEyzeMItJqh2uivBfv9kQScOF/B0J9+Vab/oyw==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-linux-x64-gnu": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz", - "integrity": "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-linux-x64-musl": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-musl/-/lzma-linux-x64-musl-1.5.1.tgz", - "integrity": "sha512-I3nsYrWtrW9JpeCr+mkJIVDt0HY3m6qVUBs5vTtoIvJQxwqf1PBXSy5IS7T53ksQFH2kd2UX8rLxJ7B4WISpZg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-wasm32-wasi": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-wasm32-wasi/-/lzma-wasm32-wasi-1.5.1.tgz", - "integrity": "sha512-gy3wwPBa6+XEyA4fUzq6CClrXA1ajXjuVf5zbnHytJRgoHznj+mvpU3+co2fxXwqTCmIpn6KrzqH5bRDztBPhA==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.11.2", - "@emnapi/runtime": "1.11.2", - "@napi-rs/wasm-runtime": "^1.1.6" - }, - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-win32-arm64-msvc": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-arm64-msvc/-/lzma-win32-arm64-msvc-1.5.1.tgz", - "integrity": "sha512-dK+huOsHiyH6oJjij+cnjqFCakk2HgWmpI12Xm4pLUyPphe4ebYoJBgehaNAxprmjFqBQ7nL95YPVz9BHyqmPg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-win32-ia32-msvc": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-ia32-msvc/-/lzma-win32-ia32-msvc-1.5.1.tgz", - "integrity": "sha512-dGE8L+0EQ+GyU9ap9InqB/t/PmPG/bLj918q7OsJ29FuTdn8fK4OX3U4IQZhylHIA+/dQ/SXJk5n4yfah2XVvA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/lzma-win32-x64-msvc": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/@napi-rs/lzma-win32-x64-msvc/-/lzma-win32-x64-msvc-1.5.1.tgz", - "integrity": "sha512-EKW4t/iqdCT/xnd5t9oXLvVER/PMNAWXKqUAl3fgvUcOILeZIIht77/dVnfFcc9htA/DCBXC/6YQWdW+LusjFA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^22.20 || ^24.12 || >=25" - } - }, - "node_modules/@napi-rs/tar": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar/-/tar-1.1.1.tgz", - "integrity": "sha512-p6q2HhUc5vwH1CNwfOcrhLoxfgn8ust8Sqlfx+sA4VzAcp1cMbvbkl99tZZlDqOjCHgQNSiTfk/yWPjl/D42qA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - }, - "optionalDependencies": { - "@napi-rs/tar-android-arm-eabi": "1.1.1", - "@napi-rs/tar-android-arm64": "1.1.1", - "@napi-rs/tar-darwin-arm64": "1.1.1", - "@napi-rs/tar-darwin-x64": "1.1.1", - "@napi-rs/tar-freebsd-x64": "1.1.1", - "@napi-rs/tar-linux-arm-gnueabihf": "1.1.1", - "@napi-rs/tar-linux-arm64-gnu": "1.1.1", - "@napi-rs/tar-linux-arm64-musl": "1.1.1", - "@napi-rs/tar-linux-ppc64-gnu": "1.1.1", - "@napi-rs/tar-linux-s390x-gnu": "1.1.1", - "@napi-rs/tar-linux-x64-gnu": "1.1.1", - "@napi-rs/tar-linux-x64-musl": "1.1.1", - "@napi-rs/tar-wasm32-wasi": "1.1.1", - "@napi-rs/tar-win32-arm64-msvc": "1.1.1", - "@napi-rs/tar-win32-ia32-msvc": "1.1.1", - "@napi-rs/tar-win32-x64-msvc": "1.1.1" - } - }, - "node_modules/@napi-rs/tar-android-arm-eabi": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-android-arm-eabi/-/tar-android-arm-eabi-1.1.1.tgz", - "integrity": "sha512-cAhnA10cSusAUbcE9HtjQY/tZ9BH/0w2sKtRcQc94TzIlnm7QSr1htJSd/PPrbWNPtrv1orXb2CkrHlVlbnlHA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-android-arm64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-android-arm64/-/tar-android-arm64-1.1.1.tgz", - "integrity": "sha512-EslUWHCDBY/g5abTPBiHLsMaML4GagV0TXLm5WL9hAjx/DDtlxz9fegMb77RJ+f7nFLOIsUxF/3QWFvgOT0sMQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-darwin-arm64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-darwin-arm64/-/tar-darwin-arm64-1.1.1.tgz", - "integrity": "sha512-+A42/6ES5G9CQ35BOwzwA+WBjLID28r2jNPgc0dteD2hhClIhng0mva7D2ujUlXBNmgNOsr1LHn3stA4uTf4NQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-darwin-x64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-darwin-x64/-/tar-darwin-x64-1.1.1.tgz", - "integrity": "sha512-RYtE8w1dkEvj8hSJCDV5Jw0Rz2i13fsM7u893zv5O9n/4Ad5GNsw/f4RQ7/0YGSFaenkVxqPFrjmEvUHlKzsrg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-freebsd-x64": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-freebsd-x64/-/tar-freebsd-x64-1.1.1.tgz", - "integrity": "sha512-rEepBvCJUwcuvUYkY83e8aot8RsR5Jcnal4PsG3tbWGKW1yAvcXhyMXf0fN6ZGpVRZFnB+FJqDyBxvsCPEXKhw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-arm-gnueabihf": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-arm-gnueabihf/-/tar-linux-arm-gnueabihf-1.1.1.tgz", - "integrity": "sha512-an1bJdfyhI5FpZYyTQ20mrqwR+a676i8GkaYc4Uy12dH/a7TJIfrK6Qa2Gm46arZvxUvx56qxoRKXbpOjUPvwA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-arm64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-arm64-gnu/-/tar-linux-arm64-gnu-1.1.1.tgz", - "integrity": "sha512-w++Vtx36T2yHTKws7GVnmHHcUT1ybB59xLWSh9A8bwEpJVG4dG7Qub9mFe5cpcbfrJ+XP2mKKxC3oUJSunK3iQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-arm64-musl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-arm64-musl/-/tar-linux-arm64-musl-1.1.1.tgz", - "integrity": "sha512-Rh6UFhNtj3i4deJHOBINFIeRL0072mgbeyuK5rl1HokKnNoMKx8qKIZNEzBTTqpogMfDHWGvzyTQdnVxes5dpA==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-ppc64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-ppc64-gnu/-/tar-linux-ppc64-gnu-1.1.1.tgz", - "integrity": "sha512-Cp+AxFbv9zcyAXtnzQi0OzmgDnQgy2w9D4Ubr+iwzMtVgJcztzcEoCcCrN1k2ATdEB01LX2Vb49IaocGOZhC9Q==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-s390x-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-s390x-gnu/-/tar-linux-s390x-gnu-1.1.1.tgz", - "integrity": "sha512-ZyscC3SYKTBWyDRYjLOKAd5TyJ7q0KACRdQ8bWrb3rgrra1CCIJD66CsGTH6Dh0AVSdfLwZ8MfIIXU6+14BMjQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-x64-gnu": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-x64-gnu/-/tar-linux-x64-gnu-1.1.1.tgz", - "integrity": "sha512-LlIv+zg4fiOQge9LQX/ieBdRWE2fhVDjCTHxnunZkbugNmdhdelxWf1RpZb/6ZujWpNF4LPu4N/MW7ygg2oYAQ==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-linux-x64-musl": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-linux-x64-musl/-/tar-linux-x64-musl-1.1.1.tgz", - "integrity": "sha512-gZBeoKLjanOVj55qk4EMu13P2i9M0SuINmlGQkOxm1niIJofexzddHUYtqO5o/5QqtyL8lADmAcZplLILMLhHA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-wasm32-wasi": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-wasm32-wasi/-/tar-wasm32-wasi-1.1.1.tgz", - "integrity": "sha512-rwtQ1Mdt/ft6g6I54fJzbUeLspl4yTwj6I3UJ6mitKnrN42soJkcDrdh3Y/FGvlpqZTad2YMQ96fGJl3EtAm2Q==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.11.2", - "@emnapi/runtime": "1.11.2", - "@napi-rs/wasm-runtime": "^1.1.6" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@napi-rs/tar-win32-arm64-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-arm64-msvc/-/tar-win32-arm64-msvc-1.1.1.tgz", - "integrity": "sha512-30PVp1AehRpfwxmv5wI4cg0yj3WmWBsZ+1QnLGnvEELu7Eu/+dhNU0nrmhI7VfPgLwSRK2eg9DQTB3tP7Wv9bA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-win32-ia32-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-ia32-msvc/-/tar-win32-ia32-msvc-1.1.1.tgz", - "integrity": "sha512-aI3/rmz+izUChiSeaPxcasAOxhf3FpJNuIHMXlxS/vpW+HIxUsSDR5+XV61PEG5DL4L/75iENVUxmSGM5l2yaw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/tar-win32-x64-msvc": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@napi-rs/tar-win32-x64-msvc/-/tar-win32-x64-msvc-1.1.1.tgz", - "integrity": "sha512-yJsB2IsrODQVLKbm2Fg1nHiVRbEj49mSPbj4x7JPZWJI0jGVPjohE2Sif0FBbx8OxsVoUODvS0BwksZZ8jl/OA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz", - "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@tybys/wasm-util": "^0.10.3" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=23.5.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Brooooooklyn" - }, - "peerDependencies": { - "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", - "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" - } - }, - "node_modules/@napi-rs/wasm-tools": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools/-/wasm-tools-1.1.0.tgz", - "integrity": "sha512-VjHyKEqXAwYZK+HY7iJctYvRm3TFEbaQxeZwvAG1QRkoo1a39phMY8J6x9tUEqJI03W6MysB8F2jacI6wvcx+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12.22.0" - }, - "optionalDependencies": { - "@napi-rs/wasm-tools-android-arm-eabi": "1.1.0", - "@napi-rs/wasm-tools-android-arm64": "1.1.0", - "@napi-rs/wasm-tools-darwin-arm64": "1.1.0", - "@napi-rs/wasm-tools-darwin-x64": "1.1.0", - "@napi-rs/wasm-tools-freebsd-x64": "1.1.0", - "@napi-rs/wasm-tools-linux-arm64-gnu": "1.1.0", - "@napi-rs/wasm-tools-linux-arm64-musl": "1.1.0", - "@napi-rs/wasm-tools-linux-x64-gnu": "1.1.0", - "@napi-rs/wasm-tools-linux-x64-musl": "1.1.0", - "@napi-rs/wasm-tools-wasm32-wasi": "1.1.0", - "@napi-rs/wasm-tools-win32-arm64-msvc": "1.1.0", - "@napi-rs/wasm-tools-win32-ia32-msvc": "1.1.0", - "@napi-rs/wasm-tools-win32-x64-msvc": "1.1.0" - } - }, - "node_modules/@napi-rs/wasm-tools-android-arm-eabi": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-android-arm-eabi/-/wasm-tools-android-arm-eabi-1.1.0.tgz", - "integrity": "sha512-p6J8PB59I8d/XItXB/go5JH6nKW+xIbpzaL43EBTV0hi7mrS/Z4gs+MsB04ZrlqZN29BdZV8fChRyasuXLhRaA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-android-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-android-arm64/-/wasm-tools-android-arm64-1.1.0.tgz", - "integrity": "sha512-lWoKN3suypeBSCIRPIw+++sH9V2K6nQkhtdt1opu7XY3v9JwLs6Gw063HWRqkNjphlYpkd/Qy8XcfSPGbJj7nQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-darwin-arm64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-darwin-arm64/-/wasm-tools-darwin-arm64-1.1.0.tgz", - "integrity": "sha512-jfw5vyNDUf6oe0kP8lMveFN9U7cLk1cUosS7uMIfw/xmqmopYfKQ198DAx2g/6aEF7Tm+CqER2gpMpYKui30LA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-darwin-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-darwin-x64/-/wasm-tools-darwin-x64-1.1.0.tgz", - "integrity": "sha512-R+pjeudAB7BYdH1vKkOJM61Tfv5jB6uXkxmFscYd+KKpdUpWBlNG+s4hr0w4i1rMBM91VhIAETZn2pz+MDHK9A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-freebsd-x64": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-freebsd-x64/-/wasm-tools-freebsd-x64-1.1.0.tgz", - "integrity": "sha512-hQJTe+aazrT++Vgm6I4lUd9099ItUCFYdd+aKg6Ys6nax6d/cZ1barDLTwA2lwOoVDsXMekJI/FOL6ZvVlIYBg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-linux-arm64-gnu": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-arm64-gnu/-/wasm-tools-linux-arm64-gnu-1.1.0.tgz", - "integrity": "sha512-1TAXJxUHsWGar90k3W/MknavvBMwOWzjh7Q6Spxo8twRcWJbBD5Kow/Q2KhhDq5hxh2sKGDXn3uLc1tdtz4WUg==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-linux-arm64-musl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-arm64-musl/-/wasm-tools-linux-arm64-musl-1.1.0.tgz", - "integrity": "sha512-7rw3nlubTjNAVRH2LwphCxHy1b/N2/TerXocQ6XRn4Q+buaY1Z7P/hbdALy1i1ex2yfOU2Xcij7ib7ZLi/lKfw==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-linux-x64-gnu": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-x64-gnu/-/wasm-tools-linux-x64-gnu-1.1.0.tgz", - "integrity": "sha512-1sel0t9MRjI/tdT89M8Dd6gPfANeeFP24Xa46R11WeHNwhjsXXZh+xUk50uWCRTSGcaCy3ugm3AMK/lmHYQJkg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-linux-x64-musl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-linux-x64-musl/-/wasm-tools-linux-x64-musl-1.1.0.tgz", - "integrity": "sha512-o2jH5AMfor4EKF2HII1LBnMQxoWu7+usPifTEY8Zk6e9OiSi4EJkAXf9v3ANlX7TI2V/cUEV34OEW7r10GiVIA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-wasm32-wasi": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-wasm32-wasi/-/wasm-tools-wasm32-wasi-1.1.0.tgz", - "integrity": "sha512-s6YDtDR1UWrsqJPtaxf+JLYLceWVyn3l8OpQYElHkDhf3Qfz9R6Ba3S0OgznTBv38L5/TIHysQ9Q4yO73Z0csg==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/core": "1.9.2", - "@emnapi/runtime": "1.9.2", - "@napi-rs/wasm-runtime": "^1.1.6" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@napi-rs/wasm-tools-wasm32-wasi/node_modules/@emnapi/core": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz", - "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "@emnapi/wasi-threads": "1.2.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@napi-rs/wasm-tools-wasm32-wasi/node_modules/@emnapi/runtime": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz", - "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@napi-rs/wasm-tools-wasm32-wasi/node_modules/@emnapi/wasi-threads": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", - "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@napi-rs/wasm-tools-win32-arm64-msvc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-arm64-msvc/-/wasm-tools-win32-arm64-msvc-1.1.0.tgz", - "integrity": "sha512-x+NuxbG84VxU68tU8w7Rf5lSyq0l584M6dVlke5DTweHYFZoMyeqkpbwEq+qsyAX6ivfipK8xRsmFwamb5uDnA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@napi-rs/wasm-tools-win32-ia32-msvc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-ia32-msvc/-/wasm-tools-win32-ia32-msvc-1.1.0.tgz", - "integrity": "sha512-mdD96QDEp70SX67rXFTY6c725nVYeqEEjyDqzzbNh6u1APj7CI7IMNpMmvE75XbCRl4C2MHZVU4U6AWdAzvyQQ==", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", "cpu": [ "ia32" ], @@ -2016,13 +461,13 @@ "win32" ], "engines": { - "node": ">= 12.22.0" + "node": ">=18" } }, - "node_modules/@napi-rs/wasm-tools-win32-x64-msvc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-tools-win32-x64-msvc/-/wasm-tools-win32-x64-msvc-1.1.0.tgz", - "integrity": "sha512-bVVjuvhlyVX++3eJXfDR63cXdw1ay5QYac6iq0MKQw8wZARInTM+bXCtByDT4fzVFI3+7ZthYb/ERWRdBNIqgQ==", + "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" ], @@ -2033,219 +478,67 @@ "win32" ], "engines": { - "node": ">= 12.22.0" - } - }, - "node_modules/@octokit/auth-token": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-6.0.0.tgz", - "integrity": "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/core": { - "version": "7.0.7", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-7.0.7.tgz", - "integrity": "sha512-DcB0M3KFgr9ECI328lhBMVsyFT2DnmNucSBTqEN3exyNKUzkkpUSCHmTRcunF41Eou2TIQKW4seewri8ON9bSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/auth-token": "^6.0.0", - "@octokit/graphql": "^9.0.4", - "@octokit/request": "^10.0.13", - "@octokit/request-error": "^7.1.1", - "@octokit/types": "^17.0.0", - "before-after-hook": "^4.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/endpoint": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-11.0.4.tgz", - "integrity": "sha512-f1cOWoHPmxryJFknxbtDdjODWfV8A9tc8Aae6ermXPNgHFZ/x91AtHIz4gicEjL8hkJiip+u21QHJORfBv/qiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^17.0.0", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/graphql": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-9.0.4.tgz", - "integrity": "sha512-5s15CCiY8XXQ+FG+b1YQcl6Z2FA++nwAz/tg2VUrTmnMncP+2nnGUEYANImdnxsA2Fnq+Mbl7hDjUTw7cFAwcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/request": "^10.0.13", - "@octokit/types": "^17.0.0", - "universal-user-agent": "^7.0.0" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-28.0.0.tgz", - "integrity": "sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-14.0.0.tgz", - "integrity": "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" + "node": ">=18" } }, - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", - "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", - "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", + "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": { - "@octokit/openapi-types": "^27.0.0" + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@octokit/plugin-request-log": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-6.0.0.tgz", - "integrity": "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==", + "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": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" + "node": ">=6.0.0" } }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-17.0.0.tgz", - "integrity": "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw==", + "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": { - "@octokit/types": "^16.0.0" - }, - "engines": { - "node": ">= 20" - }, - "peerDependencies": { - "@octokit/core": ">=6" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, - "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": { - "version": "27.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-27.0.0.tgz", - "integrity": "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA==", + "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/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { - "version": "16.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-16.0.0.tgz", - "integrity": "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^27.0.0" - } - }, - "node_modules/@octokit/request": { - "version": "10.0.13", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-10.0.13.tgz", - "integrity": "sha512-v2269YxL9Yf+x3d+gRI63FP0vFQEiWgLyBzxe/Y+0yFDg2B/Tzf5dhh9VNfccVAQnfcfwQWyk/y6Bn7rUXXs7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^11.0.3", - "@octokit/request-error": "^7.1.1", - "@octokit/types": "^17.0.0", - "content-type": "^2.0.0", - "json-with-bigint": "^3.5.3", - "universal-user-agent": "^7.0.2" - }, - "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/request-error": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-7.1.1.tgz", - "integrity": "sha512-+eaY7G2VVpSf2pc5Gn1+mph837V/d/TYTJAgWL9Tb0ogGYcpN3IlAVFgjL+Vv93F/sevrxkvsYCedtpLdcFLzA==", + "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": { - "@octokit/types": "^17.0.0" - }, - "engines": { - "node": ">= 20" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@octokit/rest": { - "version": "22.0.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-22.0.1.tgz", - "integrity": "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw==", + "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": "MIT", - "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" - }, + "license": "ISC", "engines": { - "node": ">= 20" - } - }, - "node_modules/@octokit/types": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-17.0.0.tgz", - "integrity": "sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^28.0.0" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", - "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" + "node": ">= 18" } }, "node_modules/@types/estree": { @@ -2508,13 +801,6 @@ "ajv": "^8.8.2" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, "node_modules/baseline-browser-mapping": { "version": "2.11.15", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.15.tgz", @@ -2528,13 +814,6 @@ "node": ">=6.0.0" } }, - "node_modules/before-after-hook": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", - "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==", - "dev": true, - "license": "Apache-2.0" - }, "node_modules/browserslist": { "version": "4.28.8", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", @@ -2597,13 +876,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/chardet": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", - "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==", - "dev": true, - "license": "MIT" - }, "node_modules/chrome-trace-event": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", @@ -2614,32 +886,6 @@ "node": ">=6.0" } }, - "node_modules/cli-width": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", - "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 12" - } - }, - "node_modules/clipanion": { - "version": "4.0.0-rc.4", - "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-4.0.0-rc.4.tgz", - "integrity": "sha512-CXkMQxU6s9GklO/1f714dkKBMu1lopS1WFF0B8o4AxPykR1hpozxSiUZ5ZUeBjfPgCWqbcNOtZVFhB8Lkfp1+Q==", - "dev": true, - "license": "MIT", - "workspaces": [ - "website" - ], - "dependencies": { - "typanion": "^3.8.0" - }, - "peerDependencies": { - "typanion": "*" - } - }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -2655,13 +901,6 @@ "node": ">=6" } }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, "node_modules/commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", @@ -2669,20 +908,6 @@ "dev": true, "license": "MIT" }, - "node_modules/content-type": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz", - "integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2698,24 +923,6 @@ "node": ">= 8" } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/electron-to-chromium": { "version": "1.5.408", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.408.tgz", @@ -2767,19 +974,6 @@ "dev": true, "license": "MIT" }, - "node_modules/es-toolkit": { - "version": "1.51.0", - "resolved": "https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.51.0.tgz", - "integrity": "sha512-zC2lQGkM7QX+Gm6iM3+WIdZJzthsEd14LvRNJneSO2hzyz/zNBENR8+YXWo1cKxgPBtV6ksPYHELbcwBRzmdCw==", - "dev": true, - "license": "MIT", - "workspaces": [ - "docs", - "benchmarks", - "tests/types", - "tests/browser-compat" - ] - }, "node_modules/esbuild": { "version": "0.28.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", @@ -2896,23 +1090,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fast-string-truncated-width": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", - "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-string-width": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", - "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-string-truncated-width": "^3.0.2" - } - }, "node_modules/fast-uri": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", @@ -2930,16 +1107,6 @@ ], "license": "BSD-3-Clause" }, - "node_modules/fast-wrap-ansi": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", - "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-string-width": "^3.0.2" - } - }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -3004,23 +1171,6 @@ "node": ">= 0.4" } }, - "node_modules/iconv-lite": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", - "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", - "dev": true, - "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/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", @@ -3112,29 +1262,6 @@ "node": ">= 10.13.0" } }, - "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -3142,13 +1269,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-with-bigint": { - "version": "3.5.12", - "resolved": "https://registry.npmjs.org/json-with-bigint/-/json-with-bigint-3.5.12.tgz", - "integrity": "sha512-uwbF/wSSuOgC7qqlq27Xp5B6a2MHVug3t0idZdTqu0JnlFvgJuH7ju+KAk/J06C7GfhoYy2gnb9wz2INqcne7w==", - "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", @@ -3250,23 +1370,6 @@ } } }, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/mute-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", - "integrity": "sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -3284,20 +1387,6 @@ "node": ">=18" } }, - "node_modules/obug": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", - "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", - "dev": true, - "funding": [ - "https://github.com/sponsors/sxzz", - "https://opencollective.com/debug" - ], - "license": "MIT", - "engines": { - "node": ">=12.20.0" - } - }, "node_modules/p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", @@ -3452,13 +1541,6 @@ "node": ">=8" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, "node_modules/schema-utils": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", @@ -3479,19 +1561,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -3528,19 +1597,6 @@ "node": ">=8" } }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3624,24 +1680,6 @@ "node": ">=10" } }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD", - "optional": true - }, - "node_modules/typanion": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", - "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==", - "dev": true, - "license": "MIT", - "workspaces": [ - "website" - ] - }, "node_modules/typescript": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", @@ -3663,13 +1701,6 @@ "dev": true, "license": "MIT" }, - "node_modules/universal-user-agent": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-7.0.3.tgz", - "integrity": "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==", - "dev": true, - "license": "ISC" - }, "node_modules/update-browserslist-db": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.1.tgz", diff --git a/packages/libdatadog/package.json b/packages/libdatadog/package.json index 2d45cdcc..3ffb9b9f 100644 --- a/packages/libdatadog/package.json +++ b/packages/libdatadog/package.json @@ -1,7 +1,7 @@ { "name": "@datadog/libdatadog", "version": "0.1.0-pre", - "description": "Universal Node.js bindings for libdatadog", + "description": "WASM Node.js bindings for libdatadog", "license": "Apache-2.0", "type": "commonjs", "main": "index.js", @@ -36,44 +36,21 @@ "node": ">=18" }, "scripts": { - "build:native": "node scripts/build-native.js", "build:wasm": "npm run build:wasm:binary && npm run inline:wasm", "build:wasm:binary": "node ../../scripts/build-wasm.js ../../crates/libdatadog-wasm wasm/dist", "size:profile": "node ../../scripts/build-wasm.js ../../crates/libdatadog-wasm ../../target/size --profiling", "inline:wasm": "node scripts/inline-wasm.js", - "report:napi-size": "node scripts/report-napi-size.js", "report:wasm-size": "node scripts/report-wasm-size.js", - "package:native": "node scripts/package-native.js", - "build": "npm run build:native && npm run build:wasm", + "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" }, - "napi": { - "binaryName": "libdatadog", - "targets": [ - "x86_64-apple-darwin", - "aarch64-apple-darwin", - "x86_64-unknown-linux-gnu", - "aarch64-unknown-linux-gnu", - "x86_64-unknown-linux-musl", - "aarch64-unknown-linux-musl" - ] - }, "dependencies": { "@datadog/libdatadog-wasm": "0.1.0-pre" }, - "optionalDependencies": { - "@datadog/libdatadog-darwin-arm64": "0.1.0-pre", - "@datadog/libdatadog-darwin-x64": "0.1.0-pre", - "@datadog/libdatadog-linux-arm64-gnu": "0.1.0-pre", - "@datadog/libdatadog-linux-arm64-musl": "0.1.0-pre", - "@datadog/libdatadog-linux-x64-gnu": "0.1.0-pre", - "@datadog/libdatadog-linux-x64-musl": "0.1.0-pre" - }, "devDependencies": { "@msgpack/msgpack": "^3.1.3", - "@napi-rs/cli": "^3.5.1", "esbuild": "^0.28.2", "typescript": "^6.0.3", "webpack": "^5.109.2", diff --git a/packages/libdatadog/scripts/build-native.js b/packages/libdatadog/scripts/build-native.js deleted file mode 100644 index 09e295f3..00000000 --- a/packages/libdatadog/scripts/build-native.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict' - -const fs = require('node:fs') -const path = require('node:path') -const { execFileSync } = require('node:child_process') - -const packageRoot = path.join(__dirname, '..') -const repositoryRoot = path.join(packageRoot, '..', '..') -const output = path.join(packageRoot, 'dist', 'native') -const napi = path.join( - packageRoot, - 'node_modules', - '.bin', - process.platform === 'win32' ? 'napi.cmd' : 'napi', -) - -fs.rmSync(output, { force: true, recursive: true }) -execFileSync(napi, [ - 'build', - '-r', - '--platform', - '--manifest-path', - path.join(repositoryRoot, 'crates', 'libdatadog', 'Cargo.toml'), - '-o', - output, - ...process.argv.slice(2), -], { - cwd: packageRoot, - stdio: 'inherit', -}) diff --git a/packages/libdatadog/scripts/package-native.js b/packages/libdatadog/scripts/package-native.js deleted file mode 100644 index 0c706053..00000000 --- a/packages/libdatadog/scripts/package-native.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict' - -const fs = require('node:fs') -const path = require('node:path') - -const packageJson = require('../package.json') -const root = path.join(__dirname, '..') -const artifacts = path.join(root, 'dist', 'native') -const output = path.join(root, 'dist', 'packages') -const targets = { - 'aarch64-apple-darwin': { - packageTarget: 'darwin-arm64', - cpu: ['arm64'], - os: ['darwin'], - }, - 'x86_64-apple-darwin': { - packageTarget: 'darwin-x64', - cpu: ['x64'], - os: ['darwin'], - }, - 'aarch64-unknown-linux-gnu': { - packageTarget: 'linux-arm64-gnu', - cpu: ['arm64'], - libc: ['glibc'], - os: ['linux'], - }, - 'aarch64-unknown-linux-musl': { - packageTarget: 'linux-arm64-musl', - cpu: ['arm64'], - libc: ['musl'], - os: ['linux'], - }, - 'x86_64-unknown-linux-gnu': { - packageTarget: 'linux-x64-gnu', - cpu: ['x64'], - libc: ['glibc'], - os: ['linux'], - }, - 'x86_64-unknown-linux-musl': { - packageTarget: 'linux-x64-musl', - cpu: ['x64'], - libc: ['musl'], - os: ['linux'], - }, -} - -if (!fs.existsSync(artifacts)) throw new Error('native artifacts were not built') - -const configuredTargets = packageJson.napi.targets.map((triple) => { - const target = targets[triple] - - if (!target) throw new Error(`unsupported napi-rs target: ${triple}`) - - return { triple, ...target } -}) -const targetsByPackage = new Map( - configuredTargets.map(target => [target.packageTarget, target]), -) -const nativeArtifacts = fs.readdirSync(artifacts) - .filter(artifact => /^libdatadog\..+\.node$/.test(artifact)) - -if (nativeArtifacts.length === 0) throw new Error('native artifacts were not built') - -fs.rmSync(output, { force: true, recursive: true }) - -for (const artifact of nativeArtifacts) { - const packageTarget = artifact.slice('libdatadog.'.length, -'.node'.length) - const target = targetsByPackage.get(packageTarget) - - if (!target) throw new Error(`unsupported native artifact: ${artifact}`) - - const packageName = `${packageJson.name}-${packageTarget}` - const packageDirectory = path.join(output, packageTarget) - - fs.mkdirSync(packageDirectory, { recursive: true }) - fs.copyFileSync( - path.join(artifacts, artifact), - path.join(packageDirectory, artifact), - ) - fs.writeFileSync( - path.join(packageDirectory, 'package.json'), - JSON.stringify({ - name: packageName, - version: packageJson.version, - cpu: target.cpu, - main: artifact, - files: [artifact], - description: packageJson.description, - license: packageJson.license, - engines: packageJson.engines, - os: target.os, - ...(target.libc ? { libc: target.libc } : {}), - }, undefined, 2) + '\n', - ) - fs.writeFileSync( - path.join(packageDirectory, 'README.md'), - `# \`${packageName}\`\n\nThis is the **${target.triple}** binary for \`${packageJson.name}\`\n`, - ) -} diff --git a/packages/libdatadog/scripts/report-napi-size.js b/packages/libdatadog/scripts/report-napi-size.js deleted file mode 100644 index 63a0066e..00000000 --- a/packages/libdatadog/scripts/report-napi-size.js +++ /dev/null @@ -1,183 +0,0 @@ -'use strict' - -const fs = require('node:fs') -const path = require('node:path') -const { spawnSync } = require('node:child_process') - -function formatBytes (bytes) { - return bytes.toLocaleString('en-US') -} - -function formatKibibytes (bytes) { - return (bytes / 1024).toFixed(1) -} - -function findArtifact () { - const directory = path.join(__dirname, '..', 'dist', 'native') - const artifacts = fs.readdirSync(directory) - .filter(file => /^libdatadog\..+\.node$/.test(file)) - - if (artifacts.length !== 1) { - throw new Error(`expected one native artifact in ${directory}, found ${artifacts.length}`) - } - - return path.join(directory, artifacts[0]) -} - -function runCommand (command, args) { - const result = spawnSync(command, args, { - encoding: 'utf8', - maxBuffer: 10 * 1024 * 1024, - }) - - if (result.error) throw result.error - if (result.status !== 0) { - const detail = result.stderr.trim() || result.stdout.trim() - throw new Error(`${command} failed: ${detail}`) - } - - return result.stdout -} - -function parseDarwinSections (output) { - const sections = [] - - for (const line of output.split('\n')) { - const match = line.match(/^Segment (\S+):\s+(\d+)$/) - if (match) sections.push({ name: match[1], bytes: Number(match[2]) }) - } - - return sections -} - -function parseElfSections (output) { - const sections = [] - - for (const line of output.split('\n')) { - const match = line.trim().match(/^(\S+)\s+(\d+)\s+[0-9a-fA-Fx]+$/) - if (match && match[1] !== 'section') { - sections.push({ name: match[1], bytes: Number(match[2]) }) - } - } - - return sections -} - -function readSections (artifactPath, platform = process.platform) { - const sections = platform === 'darwin' - ? parseDarwinSections(runCommand('size', ['-m', artifactPath])) - : parseElfSections(runCommand('size', ['-A', artifactPath])) - - if (sections.length === 0) throw new Error('could not read native binary sections') - return sections -} - -function readCrateSizes () { - const output = runCommand('cargo', [ - 'bloat', - '--release', - '--crates', - '-n', - '0', - '--message-format', - 'json', - '-p', - 'libdatadog', - '--lib', - ]) - - return JSON.parse(output) -} - -function appendCrateReport (lines, profile) { - const crates = profile.crates - .map(crate => ({ ...crate, name: crate.name.replaceAll('_', '-') })) - const attributedBytes = crates.reduce((total, crate) => total + crate.size, 0) - const overheadBytes = profile['text-section-size'] - attributedBytes - if (overheadBytes > 0) { - crates.push({ name: 'unattributed .text overhead', size: overheadBytes }) - crates.sort((left, right) => right.size - left.size) - } - const visible = crates.filter(crate => crate.size >= 2048) - const otherBytes = crates - .filter(crate => crate.size < 2048) - .reduce((total, crate) => total + crate.size, 0) - - if (otherBytes > 0) { - visible.push({ name: 'other crates (<2 KiB each)', size: otherBytes }) - } - - lines.push( - '', - '### Code by Rust crate', - '', - '| Crate | Bytes | KiB | Share of native code |', - '| --- | ---: | ---: | ---: |', - ) - - for (const crate of visible) { - const share = `${(crate.size / profile['text-section-size'] * 100).toFixed(1)}%` - lines.push( - `| ${crate.name} | ${formatBytes(crate.size)} | ` - + `${formatKibibytes(crate.size)} | ${share} |`, - ) - } - - lines.push( - '', - `.text section: ${formatBytes(profile['text-section-size'])} bytes ` - + `(${formatKibibytes(profile['text-section-size'])} KiB).`, - '', - 'Crate ownership comes from cargo-bloat using a separate symbol-preserving release build. ' - + 'It attributes native code only; data, unwind information, symbols, and file alignment ' - + 'remain in the section and artifact totals above.', - ) -} - -function createReport (artifactPath, profile) { - const artifactBytes = fs.statSync(artifactPath).size - const sections = readSections(artifactPath) - const totalSectionBytes = sections.reduce((total, section) => total + section.bytes, 0) - const lines = [ - '## libdatadog N-API size', - '', - '| Native artifact | Bytes | KiB |', - '| --- | ---: | ---: |', - `| **Shipped .node file** | **${formatBytes(artifactBytes)}** | ` - + `**${formatKibibytes(artifactBytes)}** |`, - '', - '### Native binary sections', - '', - '| Section/segment | Bytes | KiB | Share |', - '| --- | ---: | ---: | ---: |', - ] - - for (const section of sections) { - const share = `${(section.bytes / totalSectionBytes * 100).toFixed(1)}%` - lines.push( - `| ${section.name} | ${formatBytes(section.bytes)} | ` - + `${formatKibibytes(section.bytes)} | ${share} |`, - ) - } - - if (profile) appendCrateReport(lines, profile) - - lines.push('', `Generated from \`${path.relative(process.cwd(), artifactPath)}\`.`) - return lines.join('\n') -} - -if (require.main === module) { - const artifactPath = process.argv[2] ? path.resolve(process.argv[2]) : findArtifact() - const report = createReport(artifactPath, readCrateSizes()) - console.log(report) - - if (process.env.GITHUB_STEP_SUMMARY) { - fs.appendFileSync(process.env.GITHUB_STEP_SUMMARY, `${report}\n`) - } -} - -module.exports = { - createReport, - parseDarwinSections, - parseElfSections, -} diff --git a/packages/libdatadog/scripts/set-version.js b/packages/libdatadog/scripts/set-version.js index 59f83768..bc49659e 100644 --- a/packages/libdatadog/scripts/set-version.js +++ b/packages/libdatadog/scripts/set-version.js @@ -14,9 +14,6 @@ const wasmPackageJson = JSON.parse(fs.readFileSync(wasmPackagePath, 'utf8')) packageJson.version = version packageJson.dependencies['@datadog/libdatadog-wasm'] = version -for (const name of Object.keys(packageJson.optionalDependencies)) { - packageJson.optionalDependencies[name] = version -} wasmPackageJson.version = version fs.writeFileSync(packagePath, JSON.stringify(packageJson, undefined, 2) + '\n') diff --git a/packages/libdatadog/test/bundlers.test.js b/packages/libdatadog/test/bundlers.test.js index 17cc0d7a..ade95658 100644 --- a/packages/libdatadog/test/bundlers.test.js +++ b/packages/libdatadog/test/bundlers.test.js @@ -10,9 +10,9 @@ const esbuild = require('esbuild') const webpack = require('webpack') const packageRoot = path.join(__dirname, '..') -const entry = path.join(packageRoot, 'wasm.js') +const entry = path.join(packageRoot, 'index.js') -test('esbuild bundles the WASM entry point without emitting an asset', async () => { +test('esbuild bundles the package entry point without emitting an asset', async () => { await assertBundle(async (output) => { await esbuild.build({ bundle: true, @@ -23,7 +23,7 @@ test('esbuild bundles the WASM entry point without emitting an asset', async () }) }) -test('webpack bundles the WASM entry point without emitting an asset', async () => { +test('webpack bundles the package entry point without emitting an asset', async () => { await assertBundle(output => new Promise((resolve, reject) => { webpack({ entry, diff --git a/packages/libdatadog/test/capabilities.test.js b/packages/libdatadog/test/capabilities.test.js index 34f3e83a..a121853a 100644 --- a/packages/libdatadog/test/capabilities.test.js +++ b/packages/libdatadog/test/capabilities.test.js @@ -1,32 +1,21 @@ 'use strict' const assert = require('node:assert/strict') -const fs = require('node:fs') -const path = require('node:path') const { test } = require('node:test') -const packageRoot = path.join(__dirname, '..') -const nativeDirectory = path.join(packageRoot, 'dist', 'native') -const nativeArtifact = fs.existsSync(nativeDirectory) - ? fs.readdirSync(nativeDirectory).find(file => file.startsWith('libdatadog.') && file.endsWith('.node')) - : undefined -const wasm = require('../wasm') -const native = nativeArtifact ? loadNative() : undefined +const backends = [ + ['default', require('..')], + ['WASM', require('../wasm')], +] -test('native backend excludes the WASM-only agentless exporter', { - skip: !native, -}, () => { - assert.strictEqual(native.createAgentlessExporter, undefined) -}) - -test('universal backends exclude optional extras', () => { - for (const [, backend] of backends()) { +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()) { +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) @@ -45,19 +34,3 @@ for (const [name, backend] of backends()) { assert.throws(() => sketch.add(-1), /point is invalid/) }) } - -function backends () { - return [ - ['WASM', wasm], - ...(native ? [['native', native]] : []), - ] -} - -function loadNative () { - process.env.DD_LIBDATADOG_NATIVE_PATH = path.join(nativeDirectory, nativeArtifact) - try { - return require('../lib/native') - } finally { - delete process.env.DD_LIBDATADOG_NATIVE_PATH - } -} diff --git a/packages/libdatadog/test/exporter.test.js b/packages/libdatadog/test/exporter.test.js index 91f8ae82..375cd620 100644 --- a/packages/libdatadog/test/exporter.test.js +++ b/packages/libdatadog/test/exporter.test.js @@ -12,43 +12,24 @@ const { encode } = require('@msgpack/msgpack') const zstdMagic = Buffer.from([0x28, 0xB5, 0x2F, 0xFD]) const packageRoot = path.join(__dirname, '..') -const nativeDirectory = path.join(packageRoot, 'dist', 'native') -const nativeArtifact = fs.existsSync(nativeDirectory) - ? fs.readdirSync(nativeDirectory).find(file => file.startsWith('libdatadog.') && file.endsWith('.node')) - : undefined 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') - const wasmBindingPath = require.resolve('@datadog/libdatadog-wasm') - if (nativeArtifact) { - loadNativePipeline() - assert.strictEqual(require.cache[wasmBindingPath], undefined) - } else { - require('..') - } + require('..') assert.strictEqual(require.cache[agentlessPath], undefined) require('../wasm') assert.strictEqual(require.cache[agentlessPath], undefined) }) -test('universal entry point uses WASM for agentless v0.4 exports with a native backend', { - skip: !nativeArtifact || !fs.existsSync(wasmArtifact), -}, async () => { - await assertExport(loadNativePipeline(), 'native') -}) - -test('inline-WASM backend compresses agentless v0.4 exports with Zstandard', { +test('package entry point compresses agentless v0.4 exports with Zstandard', { skip: !fs.existsSync(wasmArtifact), }, async () => { - await assertExport( - require('../wasm'), - 'wasm', - ) + await assertExport(require('..')) }) test('inline-WASM backend validates optional values', { @@ -187,7 +168,10 @@ test('agentless exporter close cancels retry backoff', { } }) -async function assertExport (pipeline, expectedBackend) { +/** + * @param {typeof import('..')} pipeline + */ +async function assertExport (pipeline) { const received = await withIntake(async (endpoint) => { const exporter = pipeline.createAgentlessExporter({ endpoint, @@ -206,7 +190,7 @@ async function assertExport (pipeline, expectedBackend) { } }) - assert.strictEqual(pipeline.backend(), expectedBackend) + 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/) @@ -235,15 +219,6 @@ function tracePayload () { }]], { useBigInt64: true }) } -function loadNativePipeline () { - process.env.DD_LIBDATADOG_NATIVE_PATH = path.join(nativeDirectory, nativeArtifact) - try { - return require('..') - } finally { - delete process.env.DD_LIBDATADOG_NATIVE_PATH - } -} - function createExporter (pipeline, server, options = {}) { const { port } = server.address() return pipeline.createAgentlessExporter({ diff --git a/packages/libdatadog/test/package-contents.test.js b/packages/libdatadog/test/package-contents.test.js index fdc2d4a3..d67e9f46 100644 --- a/packages/libdatadog/test/package-contents.test.js +++ b/packages/libdatadog/test/package-contents.test.js @@ -10,12 +10,6 @@ const { test } = require('node:test') const packageRoot = path.join(__dirname, '..') const wasmPackageRoot = path.join(packageRoot, 'wasm') -const nativeTarget = process.env.LIBDATADOG_TARGET ?? getNativeTarget() -const nativePackageRoot = nativeTarget - ? path.join(packageRoot, 'dist', 'packages', nativeTarget) - : undefined -const hasNativePackage = nativePackageRoot - && fs.existsSync(path.join(nativePackageRoot, `libdatadog.${nativeTarget}.node`)) const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm' const npmCache = path.join(os.tmpdir(), 'libdatadog-npm-cache') const npmOptions = process.platform === 'win32' ? { shell: true } : {} @@ -52,31 +46,12 @@ test('published packages contain only the intended artifacts', () => { libdatadog.version, ) assert(!names.some(file => file.includes('.node')), - 'metapackage must not contain platform-native artifacts') + 'package must not contain native artifacts') assert(!names.some(file => file.startsWith('dist/')), - 'metapackage must not contain generated backend artifacts') + 'package must not contain generated backend artifacts') }) -test('native platform package matches the napi-rs layout', { - skip: !hasNativePackage, -}, () => { - const nativePackage = pack(nativePackageRoot) - const nativePackageJson = JSON.parse(fs.readFileSync( - path.join(nativePackageRoot, 'package.json'), - 'utf8', - )) - const binary = `libdatadog.${nativeTarget}.node` - - assert.strictEqual( - nativePackage.name, - `@datadog/libdatadog-${nativeTarget}`, - ) - assert.strictEqual(nativePackageJson.main, binary) - assert.deepStrictEqual(nativePackageJson.files, [binary]) - assert(nativePackage.files.some(file => file.path === binary)) -}) - -test('installed metapackage falls back to its WASM dependency', () => { +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') @@ -105,7 +80,6 @@ test('installed metapackage falls back to its WASM dependency', () => { '--ignore-scripts', '--no-package-lock', '--offline', - '--omit=optional', wasmTarball, metapackageTarball, ], { @@ -123,63 +97,17 @@ test('installed metapackage falls back to its WASM dependency', () => { 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, 'wasm') - } finally { - fs.rmSync(temporaryRoot, { force: true, recursive: true }) - } -}) - -test('installed metapackage selects its native optional dependency', { - skip: !hasNativePackage, -}, () => { - const temporaryRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'libdatadog-native-')) - 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-native-consumer', private: true }), - ) - - try { - const wasmTarball = createTarball(wasmPackageRoot, tarballRoot, environment) - const nativeTarball = createTarball(nativePackageRoot, tarballRoot, environment) - const metapackageTarball = createTarball(packageRoot, tarballRoot, environment) - - execFileSync(npm, [ - 'install', - '--ignore-scripts', - '--no-package-lock', - '--offline', - wasmTarball, - nativeTarball, - 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') - - assert.strictEqual(libdatadog.backend(), 'native') - assert.strictEqual(explicitWasm.backend(), 'wasm') - assertEsmImports(installRoot, environment, 'native') + assertEsmImports(installRoot, environment) } finally { fs.rmSync(temporaryRoot, { force: true, recursive: true }) } }) -function assertEsmImports (installRoot, environment, expectedBackend) { +/** + * @param {string} installRoot + * @param {NodeJS.ProcessEnv} environment + */ +function assertEsmImports (installRoot, environment) { const script = ` import assert from 'node:assert/strict' import libdatadog, { @@ -195,7 +123,7 @@ function assertEsmImports (installRoot, environment, expectedBackend) { zstd_compress as wasmCompress, } from '@datadog/libdatadog/wasm' - assert.strictEqual(backend(), ${JSON.stringify(expectedBackend)}) + assert.strictEqual(backend(), 'wasm') assert.strictEqual(libdatadog.backend, backend) assert.strictEqual(libdatadog.createAgentlessExporter, createAgentlessExporter) assert(zstd_compress(new Uint8Array(16), 3) instanceof Uint8Array) @@ -231,16 +159,3 @@ function createTarball (directory, destination, environment) { return path.join(destination, filename) } - -function getNativeTarget () { - if (process.platform === 'darwin' && ['arm64', 'x64'].includes(process.arch)) { - return `darwin-${process.arch}` - } - - if (process.platform === 'linux' && ['arm64', 'x64'].includes(process.arch)) { - const libc = process.report?.getReport?.().header?.glibcVersionRuntime - ? 'gnu' - : 'musl' - return `linux-${process.arch}-${libc}` - } -} diff --git a/packages/libdatadog/test/package.test.js b/packages/libdatadog/test/package.test.js index 5e27a400..f57e4e77 100644 --- a/packages/libdatadog/test/package.test.js +++ b/packages/libdatadog/test/package.test.js @@ -16,23 +16,6 @@ test('publishes the universal libdatadog package', () => { assert.strictEqual(packageJson.exports['./wasm'].require, './wasm.js') }) -test('uses napi-rs platform package names', () => { - const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'))) - const targets = [ - 'darwin-arm64', - 'darwin-x64', - 'linux-arm64-gnu', - 'linux-arm64-musl', - 'linux-x64-gnu', - 'linux-x64-musl', - ] - - assert.deepStrictEqual( - Object.keys(packageJson.optionalDependencies), - targets.map(target => `${packageJson.name}-${target}`), - ) -}) - test('uses the libdatadog release version', () => { const packageJson = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'))) const wasmPackageJson = JSON.parse(fs.readFileSync( @@ -46,18 +29,12 @@ test('uses the libdatadog release version', () => { packageJson.dependencies['@datadog/libdatadog-wasm'], repositoryPackageJson.version, ) - for (const version of Object.values(packageJson.optionalDependencies)) { - assert.strictEqual(version, repositoryPackageJson.version) - } }) -test('root entry point uses the expected backend', () => { +test('root entry point uses the WASM backend', () => { const libdatadog = require('..') - const nativeArtifact = getNativeArtifact() - const expected = process.env.DD_LIBDATADOG_EXPECTED_BACKEND - ?? (nativeArtifact ? 'native' : 'wasm') - assert.strictEqual(libdatadog.backend(), expected) + assert.strictEqual(libdatadog.backend(), 'wasm') }) test('embeds a Brotli-compressed WASM fallback below the size budgets', () => { @@ -75,12 +52,3 @@ test('embeds a Brotli-compressed WASM fallback below the size budgets', () => { assert.ok(Buffer.byteLength(glue) < 200 * 1024) assert.ok(brotliDecompressSync(compressedWasm).length < 500 * 1024) }) - -function getNativeArtifact () { - const nativeDirectory = path.join(packageRoot, 'dist', 'native') - - if (!fs.existsSync(nativeDirectory)) return - - return fs.readdirSync(nativeDirectory) - .find(file => /^libdatadog\..+\.node$/.test(file)) -} diff --git a/packages/libdatadog/test/size-report.test.js b/packages/libdatadog/test/size-report.test.js index 86ba4821..8adf2eaa 100644 --- a/packages/libdatadog/test/size-report.test.js +++ b/packages/libdatadog/test/size-report.test.js @@ -1,8 +1,6 @@ '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 test = require('node:test') @@ -12,27 +10,6 @@ const { inferCrate, readSections, } = require('../scripts/report-wasm-size') -const { - createReport: createNapiReport, - parseDarwinSections, - parseElfSections, -} = require('../scripts/report-napi-size') - -const nativeDirectory = path.join(__dirname, '..', 'dist', 'native') -const nativeArtifact = fs.existsSync(nativeDirectory) - ? fs.readdirSync(nativeDirectory) - .find(file => /^libdatadog\..+\.node$/.test(file)) - : undefined - -function napiReportSkipReason () { - if (!nativeArtifact) return 'a native artifact is not installed' - - const size = spawnSync('size', ['--version'], { stdio: 'ignore' }) - if (size.error?.code === 'ENOENT') return 'the size command is not installed' - - return false -} - test('reports inline packaging and WASM section sizes', () => { const gluePath = path.join(__dirname, '..', 'wasm', 'dist', 'libdatadog_wasm.js') const report = createWasmReport(gluePath) @@ -44,36 +21,6 @@ test('reports inline packaging and WASM section sizes', () => { assert.match(report, /\| data \|/) }) -test('reports N-API artifact, section, and crate sizes', { - skip: napiReportSkipReason(), -}, () => { - const report = createNapiReport(path.join(nativeDirectory, nativeArtifact), { - 'text-section-size': 7000, - 'crates': [ - { name: 'libdatadog', size: 2500 }, - { name: 'small_crate', size: 500 }, - ], - }) - - assert.match(report, /Shipped \.node file/) - assert.match(report, /Native binary sections/) - assert.match(report, /Code by Rust crate/) - assert.match(report, /libdatadog/) - assert.match(report, /unattributed \.text overhead/) - assert.match(report, /other crates \(<2 KiB each\)/) -}) - -test('parses Darwin and ELF section reports', () => { - assert.deepEqual(parseDarwinSections('Segment __TEXT: 123\nSegment __DATA: 45\n'), [ - { name: '__TEXT', bytes: 123 }, - { name: '__DATA', bytes: 45 }, - ]) - assert.deepEqual(parseElfSections('.text 123 0x10\n.data 45 0x20\nTotal 168\n'), [ - { name: '.text', bytes: 123 }, - { name: '.data', bytes: 45 }, - ]) -}) - test('rejects data that is not a WebAssembly binary', () => { assert.throws(() => readSections(Buffer.from('not wasm')), /not a WebAssembly 1 binary/) }) diff --git a/packages/libdatadog/test/types.test.ts b/packages/libdatadog/test/types.test.ts index f921b6f6..d4bc12b7 100644 --- a/packages/libdatadog/test/types.test.ts +++ b/packages/libdatadog/test/types.test.ts @@ -5,7 +5,7 @@ import { } from '@datadog/libdatadog' import * as wasm from '@datadog/libdatadog/wasm' -const selectedBackend: 'native' | 'wasm' = backend() +const selectedBackend: 'wasm' = backend() const compressed: Uint8Array = zstd_compress(new Uint8Array(16), 3) const sketch = new DDSketch() diff --git a/scripts/check-dependencies.js b/scripts/check-dependencies.js index 01222c38..b2d2212a 100644 --- a/scripts/check-dependencies.js +++ b/scripts/check-dependencies.js @@ -4,9 +4,7 @@ const path = require('node:path') const { execFileSync } = require('node:child_process') const repositoryRoot = path.join(__dirname, '..') -const packageJson = require('../packages/libdatadog/package.json') const trees = [ - ...packageJson.napi.targets.map(target => ({ package: 'libdatadog', target })), { package: 'libdatadog-wasm', target: 'wasm32-unknown-unknown' }, ] @@ -46,19 +44,18 @@ function findDuplicateVersions (dependencies) { return failures } -function findForbiddenDependencies (dependencies, tree) { +/** + * @template {{ name: string }} Dependency + * @param {Dependency[]} dependencies + * @returns {Dependency[]} + */ +function findForbiddenDependencies (dependencies) { const failures = [] for (const dependency of dependencies) { const isTokio = dependency.name === 'tokio' const isTokioCompanion = dependency.name.startsWith('tokio-') - if (!isTokio && !isTokioCompanion) continue - - const parent = dependency.path.at(-2) - const allowedNapiBridge = tree.package === 'libdatadog' - && isTokio - && parent === 'napi' - if (!allowedNapiBridge) failures.push(dependency) + if (isTokio || isTokioCompanion) failures.push(dependency) } return failures @@ -86,7 +83,7 @@ function checkTrees () { for (const failure of findDuplicateVersions(dependencies)) { duplicateFailures.push({ ...failure, ...tree }) } - for (const failure of findForbiddenDependencies(dependencies, tree)) { + for (const failure of findForbiddenDependencies(dependencies)) { forbiddenFailures.push({ ...failure, ...tree }) } } @@ -112,7 +109,7 @@ function checkTrees () { ) } } else { - console.log('Tokio is limited to the NAPI async bridge and absent from WASM.') + console.log('Tokio is absent from WASM.') } if (duplicateFailures.length > 0 || forbiddenFailures.length > 0) { diff --git a/test/dependencies.js b/test/dependencies.js index 91a7c098..e64c38e5 100644 --- a/test/dependencies.js +++ b/test/dependencies.js @@ -1,6 +1,10 @@ '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 { @@ -9,42 +13,53 @@ const { parseCargoTree, } = require('../scripts/check-dependencies') -test('dependency validation allows Tokio only below the NAPI async bridge', () => { - const dependencies = parseCargoTree([ - '0libdatadog v0.1.0', - '1napi v3.12.1', - '2tokio v1.52.1', - ].join('\n')) - - assert.deepStrictEqual( - findForbiddenDependencies(dependencies, { package: 'libdatadog' }), - [], - ) -}) - -test('dependency validation rejects Tokio outside the NAPI async bridge', () => { +test('dependency validation rejects all Tokio packages in WASM', () => { const dependencies = parseCargoTree([ - '0libdatadog v0.1.0', + '0libdatadog-wasm v0.1.0', '1tokio v1.52.1', - '1napi v3.12.1', - '2tokio-util v0.7.18', + '1tokio-util v0.7.18', ].join('\n')) - const failures = findForbiddenDependencies(dependencies, { package: 'libdatadog' }) + const failures = findForbiddenDependencies(dependencies) assert.deepStrictEqual(failures.map(({ name }) => name), ['tokio', 'tokio-util']) }) -test('dependency validation rejects all Tokio packages in WASM', () => { - const dependencies = parseCargoTree([ +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', - '1napi v3.12.1', - '2tokio v1.52.1', - ].join('\n')) + '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( - findForbiddenDependencies(dependencies, { package: 'libdatadog-wasm' }).length, - 1, - ) + 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 still finds multiple versions in one artifact tree', () => { From 90b9ef648a914b18d47a6e2576d7f5d36cfc34f7 Mon Sep 17 00:00:00 2001 From: Ruben Bridgewater Date: Mon, 31 Aug 2026 18:54:05 +0200 Subject: [PATCH 18/20] feat(libdatadog): add dedicated remote config WASM (#217) * feat(libdatadog): add dedicated remote config WASM Remote Config pulls in TUF, cryptography, and HTTP dependencies that existing users do not need. Keeping its artifact separate preserves the existing universal WASM load and compile cost. * ci(libdatadog): validate remote config entry point The lint job runs before generated Remote Config modules exist, so fresh checkouts reject both wrapper imports. The request test also verifies that the storage hook wraps the HTTP request. * refactor(libdatadog): simplify remote config packaging Package export maps can target the canonical CommonJS artifacts directly, so forwarding files own no format or compatibility boundary. --- README.md | 3 + eslint.config.js | 1 + packages/libdatadog/README.md | 8 +- packages/libdatadog/package.json | 14 +- packages/libdatadog/remote-config.d.ts | 1 + packages/libdatadog/remote-config.js | 3 + packages/libdatadog/scripts/inline-wasm.js | 14 +- packages/libdatadog/test/bundlers.test.js | 86 +++++++---- .../libdatadog/test/package-contents.test.js | 30 +++- packages/libdatadog/test/package.test.js | 88 ++++++++++- .../libdatadog/test/remote-config.test.js | 138 ++++++++++++++++++ packages/libdatadog/test/types.test.ts | 26 ++++ packages/libdatadog/wasm/package.json | 18 ++- packages/libdatadog/wasm/remote-config.d.ts | 35 +++++ scripts/check-dependencies.js | 52 ++++++- test/dependencies.js | 95 ++++++++++++ 16 files changed, 557 insertions(+), 55 deletions(-) create mode 100644 packages/libdatadog/remote-config.d.ts create mode 100644 packages/libdatadog/remote-config.js create mode 100644 packages/libdatadog/test/remote-config.test.js create mode 100644 packages/libdatadog/wasm/remote-config.d.ts diff --git a/README.md b/README.md index 0ec459a6..6dd4dd8c 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,9 @@ 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. diff --git a/eslint.config.js b/eslint.config.js index c362da00..daf48dea 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -90,6 +90,7 @@ module.exports = [ // 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', ], diff --git a/packages/libdatadog/README.md b/packages/libdatadog/README.md index a37bcc7a..ed1cdbef 100644 --- a/packages/libdatadog/README.md +++ b/packages/libdatadog/README.md @@ -10,10 +10,14 @@ 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. No raw `.wasm` -asset or native extension is published. +`@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/package.json b/packages/libdatadog/package.json index 3ffb9b9f..37ad762c 100644 --- a/packages/libdatadog/package.json +++ b/packages/libdatadog/package.json @@ -18,12 +18,20 @@ "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", @@ -36,10 +44,12 @@ "node": ">=18" }, "scripts": { - "build:wasm": "npm run build:wasm:binary && npm run inline:wasm", + "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", + "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", 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 index 4fc004fc..fe164f11 100644 --- a/packages/libdatadog/scripts/inline-wasm.js +++ b/packages/libdatadog/scripts/inline-wasm.js @@ -4,9 +4,15 @@ const fs = require('node:fs') const path = require('node:path') const { constants, brotliCompressSync } = require('node:zlib') -const outputDirectory = path.join(__dirname, '..', 'wasm', 'dist') -const gluePath = path.join(outputDirectory, 'libdatadog_wasm.js') -const wasmPath = path.join(outputDirectory, 'libdatadog_wasm_bg.wasm') +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, { @@ -15,7 +21,7 @@ const encodedWasm = brotliCompressSync(wasm, { }, }).toString('base64') const loader = [ - 'const wasmPath = `${__dirname}/libdatadog_wasm_bg.wasm`;', + `const wasmPath = \`\${__dirname}/${moduleName}_bg.wasm\`;`, 'const wasmBytes = require(\'fs\').readFileSync(wasmPath);', ].join('\n') diff --git a/packages/libdatadog/test/bundlers.test.js b/packages/libdatadog/test/bundlers.test.js index ade95658..037af0ff 100644 --- a/packages/libdatadog/test/bundlers.test.js +++ b/packages/libdatadog/test/bundlers.test.js @@ -5,48 +5,39 @@ 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 entry = path.join(packageRoot, 'index.js') - -test('esbuild bundles the package entry point without emitting an asset', async () => { - await assertBundle(async (output) => { - await esbuild.build({ - bundle: true, - entryPoints: [entry], - outfile: output, - platform: 'node', - }) +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) }) -}) - -test('webpack bundles the package entry point without emitting an asset', async () => { - await assertBundle(output => new Promise((resolve, reject) => { - webpack({ - entry, - mode: 'production', - output: { - filename: path.basename(output), - path: path.dirname(output), - }, - target: 'node', - }, (error, stats) => { - if (error) return reject(error) - if (stats.hasErrors()) return reject(new Error(stats.toString({ all: false, errors: true }))) - resolve() - }) - })) -}) - -async function assertBundle (bundle) { +} + +/** + * @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(output) + await bundle(entry, output) const files = fs.readdirSync(directory) const contents = fs.readFileSync(output, 'utf8') @@ -56,3 +47,34 @@ async function assertBundle (bundle) { 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/package-contents.test.js b/packages/libdatadog/test/package-contents.test.js index d67e9f46..9856df05 100644 --- a/packages/libdatadog/test/package-contents.test.js +++ b/packages/libdatadog/test/package-contents.test.js @@ -40,6 +40,13 @@ test('published packages contain only the intended artifacts', () => { `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'], @@ -92,7 +99,13 @@ test('installed package uses its WASM dependency', () => { 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) @@ -122,7 +135,22 @@ function assertEsmImports (installRoot, environment) { 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) diff --git a/packages/libdatadog/test/package.test.js b/packages/libdatadog/test/package.test.js index f57e4e77..37ccf99e 100644 --- a/packages/libdatadog/test/package.test.js +++ b/packages/libdatadog/test/package.test.js @@ -1,6 +1,7 @@ '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') @@ -14,6 +15,16 @@ test('publishes the universal libdatadog package', () => { 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', () => { @@ -38,17 +49,82 @@ test('root entry point uses the WASM backend', () => { }) test('embeds a Brotli-compressed WASM fallback below the size budgets', () => { - const gluePath = path.join( + 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') - const compressedWasm = Buffer.from(encodedWasm, 'base64') - assert.ok(Buffer.byteLength(glue) < 200 * 1024) - assert.ok(brotliDecompressSync(compressedWasm).length < 500 * 1024) -}) + 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/types.test.ts b/packages/libdatadog/test/types.test.ts index d4bc12b7..a742c8d4 100644 --- a/packages/libdatadog/test/types.test.ts +++ b/packages/libdatadog/test/types.test.ts @@ -3,6 +3,10 @@ import { 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() @@ -17,6 +21,27 @@ 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 @@ -25,3 +50,4 @@ void encoded void wasmBackend void wasmSketch void wasmCompress +void remoteConfigFetcher diff --git a/packages/libdatadog/wasm/package.json b/packages/libdatadog/wasm/package.json index bc26de41..6687aac6 100644 --- a/packages/libdatadog/wasm/package.json +++ b/packages/libdatadog/wasm/package.json @@ -6,8 +6,24 @@ "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/" + "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/check-dependencies.js b/scripts/check-dependencies.js index b2d2212a..b02fe0d7 100644 --- a/scripts/check-dependencies.js +++ b/scripts/check-dependencies.js @@ -6,7 +6,31 @@ 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 = [] @@ -26,7 +50,11 @@ function parseCargoTree (output) { return paths } -function findDuplicateVersions (dependencies) { +/** + * @param {{ name: string, version: string }[]} dependencies + * @param {{ package?: string }} [tree] + */ +function findDuplicateVersions (dependencies, tree = {}) { const versionsByPackage = new Map() const failures = [] @@ -37,7 +65,11 @@ function findDuplicateVersions (dependencies) { } for (const [name, versions] of versionsByPackage) { - if (versions.size > 1) { + 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] }) } } @@ -47,15 +79,21 @@ function findDuplicateVersions (dependencies) { /** * @template {{ name: string }} Dependency * @param {Dependency[]} dependencies + * @param {{ package?: string }} [tree] * @returns {Dependency[]} */ -function findForbiddenDependencies (dependencies) { +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) failures.push(dependency) + 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 @@ -80,10 +118,10 @@ function checkTrees () { }) const dependencies = parseCargoTree(output) - for (const failure of findDuplicateVersions(dependencies)) { + for (const failure of findDuplicateVersions(dependencies, tree)) { duplicateFailures.push({ ...failure, ...tree }) } - for (const failure of findForbiddenDependencies(dependencies)) { + for (const failure of findForbiddenDependencies(dependencies, tree)) { forbiddenFailures.push({ ...failure, ...tree }) } } @@ -109,7 +147,7 @@ function checkTrees () { ) } } else { - console.log('Tokio is absent from WASM.') + console.log('Tokio is limited to the dedicated remote config artifact.') } if (duplicateFailures.length > 0 || forbiddenFailures.length > 0) { diff --git a/test/dependencies.js b/test/dependencies.js index e64c38e5..8ad2c6b8 100644 --- a/test/dependencies.js +++ b/test/dependencies.js @@ -62,6 +62,25 @@ test('dependency validation reports forbidden packages from Cargo', () => { } }) +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', @@ -75,3 +94,79 @@ test('dependency validation still finds multiple versions in one artifact tree', 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 }) + } +}) From 14c0b30d09add5d31840ac6b68a6e8c806aa0a96 Mon Sep 17 00:00:00 2001 From: Bryan English Date: Mon, 31 Aug 2026 13:57:06 -0400 Subject: [PATCH 19/20] chore(release): adopt main's http_transport test and lockfiles v0.x's copy of the wasm request-body test predates the connectionPooling parameter, so replaying it here calls httpRequest with the old nine-argument signature and reads wasm_memory from the wrong slot. Take main's version, which #225 landed with the extra argument. Also take main's Cargo.lock and yarn.lock; replaying the dependency bumps produced only cosmetic dedupe-key differences from the tree those commits were reviewed against. --- Cargo.lock | 8 ++--- test/http_transport.js | 78 ++++++++++++++++++++++-------------------- yarn.lock | 2 +- 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4589b216..9ec5e564 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1401,7 +1401,7 @@ dependencies = [ "errno", "http 1.5.0", "libc", - "libdd-common", + "libdd-common 5.0.0", "libdd-libunwind-sys", "libdd-telemetry 5.0.1", "nix 0.29.0", @@ -1627,9 +1627,9 @@ dependencies = [ "http 1.5.0", "http-body-util", "libc", - "libdd-common", - "libdd-ddsketch", - "libdd-shared-runtime", + "libdd-common 5.0.0", + "libdd-ddsketch 1.0.1", + "libdd-shared-runtime 1.0.0", "serde", "serde_json", "sys-info", diff --git a/test/http_transport.js b/test/http_transport.js index 41abd10b..7333d8e8 100644 --- a/test/http_transport.js +++ b/test/http_transport.js @@ -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 @@ -342,6 +304,46 @@ describe('http_transport connection pooling', () => { }) }) +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. diff --git a/yarn.lock b/yarn.lock index a8a63d10..d8f55992 100644 --- a/yarn.lock +++ b/yarn.lock @@ -280,7 +280,7 @@ 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== -brace-expansion@^5.0.2, brace-expansion@^5.0.9: +brace-expansion@^5.0.2: 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== From 20e775a08d60beea1fc7eef4a825182fed29f08b Mon Sep 17 00:00:00 2001 From: Bryan English Date: Mon, 31 Aug 2026 13:57:12 -0400 Subject: [PATCH 20/20] v0.19.0 Bump the root, packages/libdatadog, and packages/libdatadog/wasm versions in lockstep, as packages/libdatadog/test/package.test.js requires. --- package.json | 2 +- packages/libdatadog/package-lock.json | 8 ++++---- packages/libdatadog/package.json | 4 ++-- packages/libdatadog/wasm/package.json | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 0f43068a..3fa52823 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@datadog/libdatadog-extras", - "version": "0.1.0-pre", + "version": "0.19.0", "description": "Optional native and WASM libdatadog functionality for Node.js", "main": "index.js", "scripts": { diff --git a/packages/libdatadog/package-lock.json b/packages/libdatadog/package-lock.json index 71f2ca39..9e695f20 100644 --- a/packages/libdatadog/package-lock.json +++ b/packages/libdatadog/package-lock.json @@ -1,18 +1,18 @@ { "name": "@datadog/libdatadog", - "version": "0.1.0-pre", + "version": "0.19.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@datadog/libdatadog", - "version": "0.1.0-pre", + "version": "0.19.0", "license": "Apache-2.0", "workspaces": [ "wasm" ], "dependencies": { - "@datadog/libdatadog-wasm": "0.1.0-pre" + "@datadog/libdatadog-wasm": "0.19.0" }, "devDependencies": { "@msgpack/msgpack": "^3.1.3", @@ -1901,7 +1901,7 @@ }, "wasm": { "name": "@datadog/libdatadog-wasm", - "version": "0.1.0-pre", + "version": "0.19.0", "license": "Apache-2.0", "engines": { "node": ">=18" diff --git a/packages/libdatadog/package.json b/packages/libdatadog/package.json index 37ad762c..6b896bd7 100644 --- a/packages/libdatadog/package.json +++ b/packages/libdatadog/package.json @@ -1,6 +1,6 @@ { "name": "@datadog/libdatadog", - "version": "0.1.0-pre", + "version": "0.19.0", "description": "WASM Node.js bindings for libdatadog", "license": "Apache-2.0", "type": "commonjs", @@ -57,7 +57,7 @@ "test:types": "tsc --noEmit --strict --target ES2022 --module Node16 --moduleResolution Node16 test/types.test.ts" }, "dependencies": { - "@datadog/libdatadog-wasm": "0.1.0-pre" + "@datadog/libdatadog-wasm": "0.19.0" }, "devDependencies": { "@msgpack/msgpack": "^3.1.3", diff --git a/packages/libdatadog/wasm/package.json b/packages/libdatadog/wasm/package.json index 6687aac6..5132bb55 100644 --- a/packages/libdatadog/wasm/package.json +++ b/packages/libdatadog/wasm/package.json @@ -1,6 +1,6 @@ { "name": "@datadog/libdatadog-wasm", - "version": "0.1.0-pre", + "version": "0.19.0", "description": "WASM fallback for @datadog/libdatadog", "license": "Apache-2.0", "type": "commonjs",