diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 2c9a0b76f..1d8841207 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -83,6 +83,200 @@ jobs: VERSION: ${{ steps.cli.outputs.version }} run: yarn oclif promote --no-xz --sha ${GITHUB_SHA:0:7} --version $VERSION || yarn oclif promote --no-xz --sha ${GITHUB_SHA:0:8} --version $VERSION + publish_rust: + name: Publish Rust + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: Look for changes + id: rust_changed + run: | + lines=$( git diff HEAD~ HEAD --name-only -- 'packages/libraries/router' | wc -l ) + if [ $lines -gt 0 ]; then + echo '::set-output name=rust_changed::true' + fi + publish_rust_windows: + needs: publish_rust + if: needs.publish_rust.outputs.rust_changed == 'true' + name: Publish for Windows + runs-on: windows-latest + timeout-minutes: 40 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Cache Rust + uses: Swatinem/rust-cache@v1 + + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + args: --release + + - name: Compress + run: ./target/release/compress ./target/release/router.exe ./router.tar.gz + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + name: router-win + path: router.tar.gz + + - name: Upload to R2 + uses: randomairborne/r2-release@v1.0.2 + with: + endpoint: https://6d5bc18cd8d13babe7ed321adba3d8ae.r2.cloudflarestorage.com + accesskeyid: ${{ secrets.R2_ACCESS_KEY_ID }} + secretaccesskey: ${{ secrets.R2_SECRET_ACCESS_KEY }} + bucket: apollo-router + file: router.tar.gz + destination: ${{ github.sha }}/win/router.tar.gz + + - name: Upload to R2 as latest + uses: randomairborne/r2-release@v1.0.2 + with: + endpoint: https://6d5bc18cd8d13babe7ed321adba3d8ae.r2.cloudflarestorage.com + accesskeyid: ${{ secrets.R2_ACCESS_KEY_ID }} + secretaccesskey: ${{ secrets.R2_SECRET_ACCESS_KEY }} + bucket: apollo-router + file: router.tar.gz + destination: latest/win/router.tar.gz + + publish_rust_macos: + needs: publish_rust + if: needs.publish_rust.outputs.rust_changed == 'true' + name: Publish for MacOS + runs-on: macos-latest + timeout-minutes: 40 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install Node + uses: actions/setup-node@v2 + with: + node-version: 16 + + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + + - name: Cache Rust + uses: Swatinem/rust-cache@v1 + + - name: Build + uses: actions-rs/cargo@v1 + with: + command: build + args: --release + + - name: Strip binary from debug symbols + run: strip target/release/router + + - name: Compress + run: ./target/release/compress ./target/release/router ./router.tar.gz + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: router-macos + path: router.tar.gz + + - name: Upload to R2 + uses: randomairborne/r2-release@v1.0.2 + with: + endpoint: https://6d5bc18cd8d13babe7ed321adba3d8ae.r2.cloudflarestorage.com + accesskeyid: ${{ secrets.R2_ACCESS_KEY_ID }} + secretaccesskey: ${{ secrets.R2_SECRET_ACCESS_KEY }} + bucket: apollo-router + file: router.tar.gz + destination: ${{ github.sha }}/macos/router.tar.gz + + - name: Upload to R2 as latest + uses: randomairborne/r2-release@v1.0.2 + with: + endpoint: https://6d5bc18cd8d13babe7ed321adba3d8ae.r2.cloudflarestorage.com + accesskeyid: ${{ secrets.R2_ACCESS_KEY_ID }} + secretaccesskey: ${{ secrets.R2_SECRET_ACCESS_KEY }} + bucket: apollo-router + file: router.tar.gz + destination: latest/macos/router.tar.gz + + publish_rust_linux: + needs: publish_rust + if: needs.publish_rust.outputs.rust_changed == 'true' + name: Publish for Linux + runs-on: ubuntu-latest + timeout-minutes: 40 + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install Node + uses: actions/setup-node@v2 + with: + node-version: 16 + + - name: Install Rust + run: | + curl https://sh.rustup.rs -sSf | sh -s -- -y + rustup target add x86_64-unknown-linux-gnu + + - name: Cache Rust + uses: Swatinem/rust-cache@v1 + with: + key: rust_linux_cross + + - name: Build + run: cargo build --target x86_64-unknown-linux-gnu --release + + - name: Strip binary from debug symbols + run: strip target/x86_64-unknown-linux-gnu/release/router + + - name: Compress + run: ./target/x86_64-unknown-linux-gnu/release/compress ./target/x86_64-unknown-linux-gnu/release/router ./router.tar.gz + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: router-linux + path: router.tar.gz + + - name: Upload to R2 + uses: randomairborne/r2-release@v1.0.2 + with: + endpoint: https://6d5bc18cd8d13babe7ed321adba3d8ae.r2.cloudflarestorage.com + accesskeyid: ${{ secrets.R2_ACCESS_KEY_ID }} + secretaccesskey: ${{ secrets.R2_SECRET_ACCESS_KEY }} + bucket: apollo-router + file: router.tar.gz + destination: ${{ github.sha }}/linux/router.tar.gz + + - name: Upload to R2 as latest + uses: randomairborne/r2-release@v1.0.2 + with: + endpoint: https://6d5bc18cd8d13babe7ed321adba3d8ae.r2.cloudflarestorage.com + accesskeyid: ${{ secrets.R2_ACCESS_KEY_ID }} + secretaccesskey: ${{ secrets.R2_SECRET_ACCESS_KEY }} + bucket: apollo-router + file: router.tar.gz + destination: latest/linux/router.tar.gz + deploy: name: 'deploy to staging' needs: publish diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index d0559b04b..5d3cb93f4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -37,7 +37,8 @@ jobs: with: fetch-depth: 1 - - uses: actions/setup-node@v2 + - name: Install Node + uses: actions/setup-node@v2 with: node-version: 16 @@ -83,7 +84,8 @@ jobs: with: fetch-depth: 5 - - uses: actions/setup-node@v2 + - name: Install Node + uses: actions/setup-node@v2 with: node-version: 16 @@ -142,7 +144,8 @@ jobs: with: fetch-depth: 5 - - uses: actions/setup-node@v2 + - name: Install Node + uses: actions/setup-node@v2 with: node-version: 16 @@ -181,7 +184,8 @@ jobs: with: fetch-depth: 1 - - uses: actions/setup-node@v2 + - name: Install Node + uses: actions/setup-node@v2 with: node-version: 16 @@ -201,7 +205,7 @@ jobs: name: Build runs-on: ubuntu-latest needs: setup - timeout-minutes: 5 + timeout-minutes: 10 env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} @@ -215,7 +219,8 @@ jobs: with: fetch-depth: 5 - - uses: actions/setup-node@v2 + - name: Install Node + uses: actions/setup-node@v2 with: node-version: 16 @@ -234,11 +239,52 @@ jobs: - name: Build run: yarn build + rust: + name: Build Rust + runs-on: ubuntu-latest + timeout-minutes: 40 + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 2 + + - name: Install Node + uses: actions/setup-node@v2 + with: + node-version: 16 + + - name: Install Rust + run: | + curl https://sh.rustup.rs -sSf | sh -s -- -y + rustup target add x86_64-unknown-linux-gnu + + - name: Cache Rust + uses: Swatinem/rust-cache@v1 + with: + key: rust_linux_cross + + - name: Build + run: cargo build --target x86_64-unknown-linux-gnu --release + + - name: Strip binary from debug symbols + run: strip target/x86_64-unknown-linux-gnu/release/router + + - name: Compress + run: ./target/x86_64-unknown-linux-gnu/release/compress ./target/x86_64-unknown-linux-gnu/release/router ./router.tar.gz + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: router-linux + path: target/x86_64-unknown-linux-gnu/release/router + lint: name: Lint runs-on: ubuntu-latest needs: setup - timeout-minutes: 15 + timeout-minutes: 25 env: TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }} diff --git a/.gitignore b/.gitignore index 26e2b258c..2814aaff5 100644 --- a/.gitignore +++ b/.gitignore @@ -112,3 +112,6 @@ integration-tests/testkit/gql/ *.pem /.husky/_/ + +# Rust +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..a28e7218a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4307 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "access-json" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed51fb0cfa6f88331d4424a7aca87146b315a3b5bd2bbad298ec855718ef9df" +dependencies = [ + "erased-serde", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "addr2line" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom", + "once_cell", + "serde", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ef4730490ad1c4eae5c4325b2a95f521d023e5c885853ff7aca0a6a1631db3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "anyhow" +version = "1.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c794e162a5eff65c72ef524dfe393eb923c354e350bb78b9c7383df13f3bc142" + +[[package]] +name = "apollo-encoder" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cde958e05663a85c6e22a18f4e758fda923526908e3e5b8ba89a00828eb8c71" + +[[package]] +name = "apollo-parser" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c32d41e059d7acd1044e365af9ee7d54ee7efd60b1e0b5ad35895729db4d4a06" +dependencies = [ + "rowan", +] + +[[package]] +name = "apollo-router" +version = "0.14.0" +source = "git+https://github.com/apollographql/router.git?branch=main#4204b03f1d9da2aa2e64bd38ca6ad6381f5efeec" +dependencies = [ + "access-json", + "anyhow", + "apollo-parser", + "apollo-spaceport", + "apollo-uplink", + "async-compression", + "async-trait", + "atty", + "axum", + "backtrace", + "buildstructor", + "bytes", + "clap", + "dashmap 5.3.4", + "deadpool", + "derivative", + "derive_more", + "directories", + "displaydoc", + "envmnt", + "futures", + "hex", + "hotwatch", + "http", + "http-body", + "humantime", + "humantime-serde", + "hyper", + "hyper-rustls", + "include_dir", + "indexmap", + "itertools", + "jsonschema", + "lazy_static", + "libc", + "lru", + "miette", + "mime", + "mockall", + "moka", + "multimap", + "once_cell", + "opentelemetry", + "opentelemetry-datadog", + "opentelemetry-http", + "opentelemetry-jaeger", + "opentelemetry-otlp", + "opentelemetry-prometheus", + "opentelemetry-semantic-conventions", + "opentelemetry-zipkin", + "paste", + "prometheus", + "regex", + "reqwest", + "rhai", + "router-bridge", + "schemars", + "serde", + "serde_json", + "serde_json_bytes", + "serde_urlencoded", + "serde_yaml", + "sha2", + "startup", + "static_assertions", + "sys-info", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util 0.7.3", + "tonic", + "tower", + "tower-http", + "tower-service", + "tower-test", + "tracing", + "tracing-core", + "tracing-futures", + "tracing-opentelemetry", + "tracing-subscriber", + "uname", + "url", + "urlencoding", + "yaml-rust", +] + +[[package]] +name = "apollo-spaceport" +version = "0.14.0" +source = "git+https://github.com/apollographql/router.git?branch=main#4204b03f1d9da2aa2e64bd38ca6ad6381f5efeec" +dependencies = [ + "bytes", + "clap", + "flate2", + "prost", + "prost-types", + "reqwest", + "serde", + "sys-info", + "tokio", + "tokio-stream", + "tonic", + "tonic-build", + "tracing", + "tracing-subscriber", + "uname", +] + +[[package]] +name = "apollo-uplink" +version = "0.14.0" +source = "git+https://github.com/apollographql/router.git?branch=main#4204b03f1d9da2aa2e64bd38ca6ad6381f5efeec" +dependencies = [ + "futures", + "graphql_client", + "launchpad", + "reqwest", + "serde", + "tokio", + "tokio-stream", + "tracing", + "url", +] + +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + +[[package]] +name = "async-channel" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2114d64672151c0c5eaa5e131ec84a74f06e1e559830dabba01ca30605d66319" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-compression" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345fd392ab01f746c717b1357165b76f0b67a60192007b234058c9045fdcf695" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-io" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5e18f61464ae81cde0a23e713ae8fd299580c54d697a35820cfd0625b8b0e07" +dependencies = [ + "concurrent-queue", + "futures-lite", + "libc", + "log", + "once_cell", + "parking", + "polling", + "slab", + "socket2", + "waker-fn", + "winapi 0.3.9", +] + +[[package]] +name = "async-lock" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76464446b8bc32758d7e88ee1a804d9914cd9b1cb264c029899680b0be29826f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "axum" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b9496f0c1d1afb7a2af4338bbe1d969cddfead41d87a9fb3aaa6d0bbc7af648" +dependencies = [ + "async-trait", + "axum-core", + "bitflags", + "bytes", + "futures-util", + "headers", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-http", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4f44a0e6200e9d11a1cdc989e4b358f6e3d354fbf48478f345a17f4e43f8635" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", +] + +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "getrandom", + "instant", + "rand", +] + +[[package]] +name = "backtrace" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7" +dependencies = [ + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block-buffer" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "3.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "buildstructor" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a7772d3542812693473268c2308979967035162dd36d053ec728e6c947ba93f" +dependencies = [ + "lazy_static", + "proc-macro2", + "quote", + "str_inflector", + "syn", + "thiserror", + "try_match", +] + +[[package]] +name = "bumpalo" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" + +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec8a7b6a70fde80372154c65702f00a0f56f3e1c36abbc6c440484be248856db" + +[[package]] +name = "cache-padded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c" + +[[package]] +name = "camino" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869119e97797867fd90f5e22af7d0bd274bd4635ebb9eb68c04f3f513ae6c412" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.13", + "serde", + "serde_json", +] + +[[package]] +name = "cc" +version = "1.0.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "3.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3dbbb6653e7c55cc8595ad3e1f7be8f32aba4eb7ff7f0fd1163d4f3d137c0a9" +dependencies = [ + "bitflags", + "clap_derive", + "clap_lex", + "indexmap", + "once_cell", + "textwrap", +] + +[[package]] +name = "clap_derive" +version = "3.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ba52acd3b0a5c33aeada5cdaa3267cdc7c594a98731d4268cdc1532f4264cb4" +dependencies = [ + "heck 0.4.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +dependencies = [ + "os_str_bytes", +] + +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + +[[package]] +name = "combine" +version = "4.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a604e93b79d1808327a6fca85a6f2d69de66461e7620f5a4cbf5fb4d1d7c948" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "compress" +version = "0.0.1" +dependencies = [ + "flate2", + "tar", +] + +[[package]] +name = "concurrent-queue" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c" +dependencies = [ + "cache-padded", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "countme" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636" + +[[package]] +name = "cpufeatures" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "045ebe27666471bb549370b4b0b3e51b07f56325befa4284db65fc89c02511b1" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "crossbeam-utils", + "memoffset", + "once_cell", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "dashmap" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" +dependencies = [ + "cfg-if 1.0.0", + "num_cpus", +] + +[[package]] +name = "dashmap" +version = "5.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown", + "lock_api", + "parking_lot_core", + "serde", +] + +[[package]] +name = "deadpool" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "421fe0f90f2ab22016f32a9881be5134fdd71c65298917084b0c7477cbc3856e" +dependencies = [ + "async-trait", + "deadpool-runtime", + "num_cpus", + "retain_mut", + "tokio", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaa37046cc0f6c3cc6090fbdbf73ef0b8ef4cfcc37f6befc0020f63e8cf121e1" +dependencies = [ + "tokio", +] + +[[package]] +name = "deno_core" +version = "0.142.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65c902448001f76f4112341c226456d20ecffe4266051495c2181ad60144b38c" +dependencies = [ + "anyhow", + "deno_ops", + "futures", + "indexmap", + "libc", + "log", + "once_cell", + "parking_lot", + "pin-project", + "serde", + "serde_json", + "serde_v8", + "sourcemap", + "url", + "v8", +] + +[[package]] +name = "deno_ops" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66c12cd4ed52c7a96b4ab4663d4b2a0098489986316bb2e36dcdaffe7ae6e3d" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "syn", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "digest" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.9", +] + +[[package]] +name = "displaydoc" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bf95dc3f046b9da4f2d51833c0d3547d8564ef6910f5c1ed130306a75b92886" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "downcast" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" + +[[package]] +name = "dunce" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "453440c271cf5577fd2a40e4942540cb7d0d2f85e27c8d07dd0023c925a67541" + +[[package]] +name = "dyn-clone" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d07a982d1fb29db01e5a59b1918e03da4df7297eaeee7686ac45542fd4e59c8" + +[[package]] +name = "either" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" + +[[package]] +name = "encoding_rs" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "envmnt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbb2fcaad9e6c9e3388dfcc1b44ae5508ae864b7af36f163a8a7c1a48796eee" +dependencies = [ + "fsio", + "indexmap", +] + +[[package]] +name = "erased-serde" +version = "0.3.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003000e712ad0f95857bd4d2ef8d1890069e06554101697d12050668b2f6f020" +dependencies = [ + "serde", +] + +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fancy-regex" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95b4efe5be9104a4a18a9916e86654319895138be727b229820c39257c30dda" +dependencies = [ + "bit-set", + "regex", +] + +[[package]] +name = "fastrand" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a407cfaa3385c4ae6b23e84623d48c2798d06e3e6a1878f7f59f17b3f86499" +dependencies = [ + "instant", +] + +[[package]] +name = "filetime" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94a7bbaa59354bc20dd75b67f23e2797b4490e9d6928203fb105c79e448c86c" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "windows-sys", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +dependencies = [ + "num-traits", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "fraction" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb65943183b6b3cbf00f64c181e8178217e30194381b150e4f87ec59864c803" +dependencies = [ + "lazy_static", + "num", +] + +[[package]] +name = "fragile" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85dcb89d2b10c5f6133de2efd8c11959ce9dbb46a2f7a4cab208c4eeda6ce1ab" + +[[package]] +name = "fsevent" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6" +dependencies = [ + "bitflags", + "fsevent-sys", +] + +[[package]] +name = "fsevent-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0" +dependencies = [ + "libc", +] + +[[package]] +name = "fsio" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de6fce87c901c64837f745e7fffddeca1de8e054b544ba82c419905d40a0e1be" +dependencies = [ + "dunce", +] + +[[package]] +name = "fslock" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57eafdd0c16f57161105ae1b98a1238f97645f2f588438b2949c99a2af9616bf" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" + +[[package]] +name = "futures-lite" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "futures-task" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" + +[[package]] +name = "futures-util" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "graphql-hive-router" +version = "0.0.1" +dependencies = [ + "anyhow", + "apollo-router", + "async-trait", + "futures", + "graphql-parser 0.4.0 (git+https://github.com/kamilkisiela/graphql-parser.git?branch=kamil-minifier)", + "graphql-tools", + "http", + "lru", + "md5", + "rand", + "reqwest", + "schemars", + "serde", + "serde_json", + "sha2", + "tokio", + "tower", + "tracing", +] + +[[package]] +name = "graphql-introspection-query" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2a4732cf5140bd6c082434494f785a19cfb566ab07d1382c3671f5812fed6d" +dependencies = [ + "serde", +] + +[[package]] +name = "graphql-parser" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ebc8013b4426d5b81a4364c419a95ed0b404af2b82e2457de52d9348f0e474" +dependencies = [ + "combine 3.8.1", + "thiserror", +] + +[[package]] +name = "graphql-parser" +version = "0.4.0" +source = "git+https://github.com/kamilkisiela/graphql-parser.git?branch=kamil-minifier#98b7d89dba38850fffa0c7f652dc2f7db79e7017" +dependencies = [ + "combine 3.8.1", + "thiserror", +] + +[[package]] +name = "graphql-tools" +version = "0.0.20" +source = "git+https://github.com/dotansimha/graphql-tools-rs.git?branch=kamil-transformer#e8abb1440e4a50d187c2fc4e02587b3ac12b10ee" +dependencies = [ + "combine 4.6.4", + "graphql-parser 0.4.0 (git+https://github.com/kamilkisiela/graphql-parser.git?branch=kamil-minifier)", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "graphql_client" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fc16d75d169fddb720d8f1c7aed6413e329e1584079b9734ff07266a193f5bc" +dependencies = [ + "graphql_query_derive", + "serde", + "serde_json", +] + +[[package]] +name = "graphql_client_codegen" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f290ecfa3bea3e8a157899dc8a1d96ee7dd6405c18c8ddd213fc58939d18a0e9" +dependencies = [ + "graphql-introspection-query", + "graphql-parser 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "heck 0.4.0", + "lazy_static", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", +] + +[[package]] +name = "graphql_query_derive" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a755cc59cda2641ea3037b4f9f7ef40471c329f55c1fa2db6fa0bb7ae6c1f7ce" +dependencies = [ + "graphql_client_codegen", + "proc-macro2", + "syn", +] + +[[package]] +name = "h2" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util 0.7.3", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hdrhistogram" +version = "7.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31672b7011be2c4f7456c4ddbcb40e7e9a4a9fad8efe49a6ebaf5f307d0109c0" +dependencies = [ + "byteorder", + "num-traits", +] + +[[package]] +name = "headers" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cff78e5788be1e0ab65b04d306b2ed5092c815ec97ec70f4ebd5aee158aa55d" +dependencies = [ + "base64 0.13.0", + "bitflags", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha-1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hotwatch" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39301670a6f5798b75f36a1b149a379a50df5aa7c71be50f4b41ec6eab445cb8" +dependencies = [ + "log", + "notify", +] + +[[package]] +name = "http" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" + +[[package]] +name = "httparse" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" + +[[package]] +name = "httpdate" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + +[[package]] +name = "hyper" +version = "0.14.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02c929dc5c39e335a03c405292728118860721b10190d98c2a0f0efd5baafbac" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +dependencies = [ + "http", + "hyper", + "log", + "rustls 0.20.6", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.23.4", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if_chain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" + +[[package]] +name = "include_dir" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "482a2e29200b7eed25d7fdbd14423326760b7f6658d21a4cf12d55a50713c69f" +dependencies = [ + "include_dir_macros", +] + +[[package]] +name = "include_dir_macros" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e074c19deab2501407c91ba1860fa3d6820bfde307db6d8cb851b55a10be89b" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "indexmap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" +dependencies = [ + "autocfg", + "hashbrown", + "serde", +] + +[[package]] +name = "inotify" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f" +dependencies = [ + "bitflags", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "ipnet" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" + +[[package]] +name = "is_ci" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" + +[[package]] +name = "iso8601" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5b94fbeb759754d87e1daea745bc8efd3037cd16980331fe1d1524c9a79ce96" +dependencies = [ + "nom", +] + +[[package]] +name = "itertools" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" + +[[package]] +name = "js-sys" +version = "0.3.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonschema" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebd40599e7f1230ce296f73b88c022b98ed66689f97eaa54bbeadc337a2ffa6" +dependencies = [ + "ahash", + "anyhow", + "base64 0.13.0", + "bytecount", + "fancy-regex", + "fraction", + "iso8601", + "itoa", + "lazy_static", + "memchr", + "num-cmp", + "parking_lot", + "percent-encoding", + "regex", + "serde", + "serde_json", + "time", + "url", + "uuid 0.8.2", +] + +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "launchpad" +version = "0.1.0" +source = "git+https://github.com/apollographql/rover.git?rev=d72ad078d9d845112bd33bd100a723a1fa0e72ff#d72ad078d9d845112bd33bd100a723a1fa0e72ff" +dependencies = [ + "apollo-encoder", + "backoff", + "graphql_client", + "humantime", + "hyper", + "reqwest", + "semver 1.0.13", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "lru" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999beba7b6e8345721bd280141ed958096a2e4abdf74f67ff4ce49b4b54e47a" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "matchit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miette" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e2c9d50e919ffdc4d2d83b83972a13e8ba86ba8245a205bee9e314d593c15a8" +dependencies = [ + "atty", + "backtrace", + "miette-derive", + "once_cell", + "owo-colors", + "supports-color", + "supports-hyperlinks", + "supports-unicode", + "terminal_size", + "textwrap", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8d10c73bcc9f0ab5c918521dab23d178062a56e6b328eb37106d497280bd94" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow", + "net2", + "slab", + "winapi 0.2.8", +] + +[[package]] +name = "mio" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys", +] + +[[package]] +name = "mio-extras" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" +dependencies = [ + "lazycell", + "log", + "mio 0.6.23", + "slab", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", +] + +[[package]] +name = "mockall" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2be9a9090bc1cac2930688fa9478092a64c6a92ddc6ae0692d46b37d9cab709" +dependencies = [ + "cfg-if 1.0.0", + "downcast", + "fragile", + "lazy_static", + "mockall_derive", + "predicates", + "predicates-tree", +] + +[[package]] +name = "mockall_derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d702a0530a0141cf4ed147cf5ec7be6f2c187d4e37fcbefc39cf34116bfe8f" +dependencies = [ + "cfg-if 1.0.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "moka" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6eb67e4dc6898bb8cffa0b16ba679de61227945673d9d9a0e7bffd25679db6" +dependencies = [ + "async-io", + "async-lock", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "futures-util", + "num_cpus", + "once_cell", + "parking_lot", + "quanta", + "scheduled-thread-pool", + "skeptic", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid 1.1.2", +] + +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "normalize-line-endings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" + +[[package]] +name = "notify" +version = "4.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257" +dependencies = [ + "bitflags", + "filetime", + "fsevent", + "fsevent-sys", + "inotify", + "libc", + "mio 0.6.23", + "mio-extras", + "walkdir", + "winapi 0.3.9", +] + +[[package]] +name = "num" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8536030f9fea7127f841b45bb6243b27255787fb4eb83958aa1ef9d2fdc0c36" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-cmp" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa" + +[[package]] +name = "num-complex" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b19411a9719e753aff12e5187b74d60d3dc449ec3f4dc21e3989c3f554bc95" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "object" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "opentelemetry" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6105e89802af13fdf48c49d7646d3b533a70e536d818aae7e78ba0433d01acb8" +dependencies = [ + "async-trait", + "crossbeam-channel", + "dashmap 4.0.2", + "fnv", + "futures-channel", + "futures-executor", + "futures-util", + "js-sys", + "lazy_static", + "percent-encoding", + "pin-project", + "rand", + "serde", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "opentelemetry-datadog" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "457462dc4cd365992c574c79181ff11ee6f66c5cbfb15a352217b4e0b35eac34" +dependencies = [ + "async-trait", + "http", + "indexmap", + "itertools", + "lazy_static", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-semantic-conventions", + "reqwest", + "rmp", + "thiserror", +] + +[[package]] +name = "opentelemetry-http" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449048140ee61e28f57abe6e9975eedc1f3a29855c7407bd6c12b18578863379" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry", + "reqwest", +] + +[[package]] +name = "opentelemetry-jaeger" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c0b12cd9e3f9b35b52f6e0dac66866c519b26f424f4bbf96e3fe8bfbdc5229" +dependencies = [ + "async-trait", + "headers", + "http", + "lazy_static", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-semantic-conventions", + "reqwest", + "thiserror", + "thrift", + "tokio", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1a6ca9de4c8b00aa7f1a153bd76cb263287155cec642680d79d98706f3d28a" +dependencies = [ + "async-trait", + "futures", + "futures-util", + "http", + "opentelemetry", + "opentelemetry-http", + "prost", + "prost-build", + "reqwest", + "thiserror", + "tokio", + "tonic", + "tonic-build", +] + +[[package]] +name = "opentelemetry-prometheus" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9328977e479cebe12ce0d3fcecdaea4721d234895a9440c5b5dfd113f0594ac6" +dependencies = [ + "opentelemetry", + "prometheus", + "protobuf", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985cc35d832d412224b2cffe2f9194b1b89b6aa5d0bef76d080dce09d90e62bd" +dependencies = [ + "opentelemetry", +] + +[[package]] +name = "opentelemetry-zipkin" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb86c6e02de97a3a7ffa5d267e1ff3f0c930ccf8a31e286277a209af6ed6cfc1" +dependencies = [ + "async-trait", + "http", + "lazy_static", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-semantic-conventions", + "reqwest", + "serde", + "serde_json", + "thiserror", + "typed-builder", +] + +[[package]] +name = "ordered-float" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3305af35278dd29f46fcdd139e0b1fbfae2153f0e5928b39b035542dd31e37b7" +dependencies = [ + "num-traits", +] + +[[package]] +name = "os_str_bytes" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" + +[[package]] +name = "owo-colors" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "decf7381921fea4dcb2549c5667eda59b3ec297ab7e2b5fc33eac69d2e7da87b" + +[[package]] +name = "parking" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + +[[package]] +name = "paste" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9423e2b32f7a043629287a536f21951e8c6a82482d0acb1eeebfc90bc2225b22" + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "petgraph" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78203e83c48cffbe01e4a2d35d566ca4de445d79a85372fc64e378bfc812a260" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710faf75e1b33345361201d36d04e98ac1ed8909151a017ed384700836104c74" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "polling" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685404d509889fade3e86fe3a5803bca2ec09b0c0778d5ada6ec8bf7a8de5259" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "log", + "wepoll-ffi", + "winapi 0.3.9", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "predicates" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5aab5be6e4732b473071984b3164dbbfb7a3674d30ea5ff44410b6bcd960c3c" +dependencies = [ + "difflib", + "float-cmp", + "itertools", + "normalize-line-endings", + "predicates-core", + "regex", +] + +[[package]] +name = "predicates-core" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da1c2388b1513e1b605fcec39a95e0a9e8ef088f71443ef37099fa9ae6673fcb" + +[[package]] +name = "predicates-tree" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d86de6de25020a36c6d3643a86d9a6a9f552107c0559c60ea03551b5e16c032" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "proc-macro-crate" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d50bfb8c23f23915855a00d98b5a35ef2e0b871bb52937bacadb798fbb66c8" +dependencies = [ + "once_cell", + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2ca2c61bc9f3d74d2886294ab7b9853abd9c1ad903a3ac7815c58989bb7bab" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cface98dfa6d645ea4c789839f176e4b072265d085bfcc48eaa8d137f58d3c39" +dependencies = [ + "cfg-if 1.0.0", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "protobuf", + "thiserror", +] + +[[package]] +name = "prost" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444879275cb4fd84958b1a1d5420d15e6fcf7c235fe47f053c9c2a80aceb6001" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62941722fb675d463659e49c4f3fe1fe792ff24fe5bbaa9c08cd3b98a1c354f5" +dependencies = [ + "bytes", + "heck 0.3.3", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prost", + "prost-types", + "regex", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9cc1a3263e07e0bf68e96268f37665207b49560d98739662cdfaae215c720fe" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534b7a0e836e3c482d2693070f982e39e7611da9695d4d1f5a4b186b51faef0a" +dependencies = [ + "bytes", + "prost", +] + +[[package]] +name = "protobuf" +version = "2.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf7e6d18738ecd0902d30d1ad232c9125985a3422929b16c65517b38adc14f96" + +[[package]] +name = "pulldown-cmark" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d9cc634bc78768157b5cbfe988ffcd1dcba95cd2b2f03a88316c08c6d00ed63" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + +[[package]] +name = "quanta" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7e31331286705f455e56cca62e0e717158474ff02b7936c1fa596d983f4ae27" +dependencies = [ + "crossbeam-utils", + "libc", + "mach", + "once_cell", + "raw-cpuid", + "wasi 0.10.2+wasi-snapshot-preview1", + "web-sys", + "winapi 0.3.9", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "raw-cpuid" +version = "10.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c49596760fce12ca21550ac21dc5a9617b2ea4b6e0aa7d8dab8ff2824fc2bba" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "reqwest" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" +dependencies = [ + "base64 0.13.0", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "rustls 0.20.6", + "rustls-native-certs", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls 0.23.4", + "tokio-util 0.7.3", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "retain_mut" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" + +[[package]] +name = "rhai" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f8a1b0ce6aba109eb3628f36db9c1818c1d396bd5a56449d5203e96e4b713a7" +dependencies = [ + "ahash", + "bitflags", + "instant", + "num-traits", + "rhai_codegen", + "serde", + "smallvec", + "smartstring", +] + +[[package]] +name = "rhai_codegen" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36791b0b801159db25130fd46ac726d2751c070260bba3a4a0a3eeb6231bb82a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi 0.3.9", +] + +[[package]] +name = "rmp" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44519172358fd6d58656c86ab8e7fbc9e1490c3e8f14d35ed78ca0dd07403c9f" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "router-bridge" +version = "0.1.0" +source = "git+https://github.com/apollographql/federation-rs.git?branch=geal/defer#72f1fff5e57a80b4ed4fcbf13ef2ac33b0314b80" +dependencies = [ + "anyhow", + "async-channel", + "deno_core", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tower-service", + "tracing", + "uuid 0.8.2", + "which", +] + +[[package]] +name = "rowan" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88acf7b001007e9e8c989fe7449f6601d909e5dd2c56399fc158977ad6c56e8" +dependencies = [ + "countme", + "hashbrown", + "memoffset", + "rustc-hash", + "text-size", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.13", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.0", + "log", + "ring", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" +dependencies = [ + "log", + "ring", + "sct 0.7.0", + "webpki 0.22.0", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0864aeff53f8c05aa08d86e5ef839d3dfcf07aeba2db32f12db0ef716e87bd55" +dependencies = [ + "base64 0.13.0", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d6731146462ea25d9244b2ed5fd1d716d25c52e4d54aa4fb0f3c4e9854dbe2" +dependencies = [ + "lazy_static", + "windows-sys", +] + +[[package]] +name = "scheduled-thread-pool" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf" +dependencies = [ + "parking_lot", +] + +[[package]] +name = "schemars" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1847b767a3d62d95cbf3d8a9f0e421cf57a0d8aa4f411d4b16525afb0284d4ed" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "schemars_derive" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af4d7e1b012cb3d9129567661a63755ea4b8a7386d339dc945ae187e403c6743" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc14f172faf8a0194a3aded622712b0de276821addc574fa54fc0a1167e10dc" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0160a13a177a45bfb43ce71c01580998474f556ad854dcbca936dd2841a5c556" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f6841e709003d68bb2deee8c343572bf446003ec20a583e76f7b15cebf3711" +dependencies = [ + "serde", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7af873f2c95b99fcb0bd0fe622a43e29514658873c8ceba88c4cb88833a22500" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.141" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75743a150d003dd863b51dc809bcad0d73f2102c53632f1e954e738192a3413f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_json_bytes" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07cc85f924551185aa24952d5bf52c8433ffd040eeeff3908bb684c55035002" +dependencies = [ + "bytes", + "indexmap", + "serde", + "serde_json", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_v8" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b0c0792ac64702a8aba4f6520b190ea5651db42266136636ad2a6d04811686f" +dependencies = [ + "bytes", + "derive_more", + "serde", + "smallvec", + "v8", +] + +[[package]] +name = "serde_yaml" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + +[[package]] +name = "sha-1" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55deaec60f81eefe3cce0dc50bda92d6d8e88f2a27df7c5033b42afeb1ed2676" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + +[[package]] +name = "skeptic" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" +dependencies = [ + "bytecount", + "cargo_metadata", + "error-chain", + "glob", + "pulldown-cmark", + "tempfile", + "walkdir", +] + +[[package]] +name = "slab" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "serde", + "static_assertions", + "version_check", +] + +[[package]] +name = "smawk" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043" + +[[package]] +name = "socket2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "sourcemap" +version = "6.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e031f2463ecbdd5f34c950f89f5c1e1032f22c0f8e3dc4bdb2e8b6658cf61eb" +dependencies = [ + "base64 0.11.0", + "if_chain", + "lazy_static", + "regex", + "rustc_version 0.2.3", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "startup" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4b82fbe497696de0a02ab63e42cf58b4d64333da2b550494eaa676c98d932f" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "str_inflector" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0b848d5a7695b33ad1be00f84a3c079fe85c9278a325ff9159e6c99cef4ef7" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "supports-color" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4872ced36b91d47bae8a214a683fe54e7078875b399dfa251df346c9b547d1f9" +dependencies = [ + "atty", + "is_ci", +] + +[[package]] +name = "supports-hyperlinks" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "590b34f7c5f01ecc9d78dba4b3f445f31df750a67621cf31626f3b7441ce6406" +dependencies = [ + "atty", +] + +[[package]] +name = "supports-unicode" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8b945e45b417b125a8ec51f1b7df2f8df7920367700d1f98aedd21e5735f8b2" +dependencies = [ + "atty", +] + +[[package]] +name = "syn" +version = "1.0.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dbef6ec655055e20b86b15a8cc6d439cca19b667537ac6a1369572d151ab13" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20518fe4a4c9acf048008599e464deb21beeae3d3578418951a189c235a7a9a8" + +[[package]] +name = "sys-info" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tar" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b55807c0344e1e6c04d7c965f5289c39a8d94ae23ed5c0b57aabac549f871c6" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "libc", + "redox_syscall", + "remove_dir_all", + "winapi 0.3.9", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "termtree" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507e9898683b6c43a9aa55b64259b721b52ba226e0f3779137e50ad114a4c90b" + +[[package]] +name = "text-size" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a" + +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f6586b7f764adc0231f4c79be7b920e766bb2f3e51b3661cdb263828f19994" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12bafc5b54507e0149cdf1b145a5d80ab80a90bcd9275df43d4fff68460f6c21" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180" +dependencies = [ + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "thrift" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b82ca8f46f95b3ce96081fe3dd89160fdea970c254bb72925255d1b62aae692e" +dependencies = [ + "byteorder", + "integer-encoding", + "log", + "ordered-float", + "threadpool", +] + +[[package]] +name = "time" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74b7cc93fc23ba97fde84f7eea56c55d1ba183f495c6715defdfc7b9cb8c870f" +dependencies = [ + "js-sys", + "libc", + "num_threads", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a8325f63a7d4774dd041e363b2409ed1c5cbbd0f867795e661df066b2b0a581" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio 0.8.4", + "num_cpus", + "once_cell", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "winapi 0.3.9", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls 0.19.1", + "tokio", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.6", + "tokio", + "webpki 0.22.0", +] + +[[package]] +name = "tokio-stream" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df54d54117d6fdc4e4fea40fe1e4e566b3505700e148a6827e59b34b0d2600d9" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util 0.7.3", +] + +[[package]] +name = "tokio-test" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53474327ae5e166530d17f2d956afcb4f8a004de581b3cae10f12006bc8163e3" +dependencies = [ + "async-stream", + "bytes", + "futures-core", + "tokio", + "tokio-stream", +] + +[[package]] +name = "tokio-util" +version = "0.6.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +dependencies = [ + "serde", +] + +[[package]] +name = "tonic" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff08f4649d10a70ffa3522ca559031285d8e421d727ac85c60825761818f5d0a" +dependencies = [ + "async-stream", + "async-trait", + "base64 0.13.0", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-rustls 0.22.0", + "tokio-stream", + "tokio-util 0.6.10", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9403f1bafde247186684b230dc6f38b5cd514584e8bec1dd32514be4745fa757" +dependencies = [ + "proc-macro2", + "prost-build", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "hdrhistogram", + "indexmap", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util 0.7.3", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c530c8675c1dbf98facee631536fa116b5fb6382d7dd6dc1b118d970eafe3ba" +dependencies = [ + "async-compression", + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "pin-project-lite", + "tokio", + "tokio-util 0.7.3", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343bc9466d3fe6b0f960ef45960509f84480bf4fd96f92901afe7ff3df9d3a62" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tower-test" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4546773ffeab9e4ea02b8872faa49bb616a80a7da66afc2f32688943f97efa7" +dependencies = [ + "futures-util", + "pin-project", + "tokio", + "tokio-test", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tracing" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" +dependencies = [ + "cfg-if 1.0.0", + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11c75893af559bc8e10716548bdef5cb2b983f8e637db9d0e15126b61b484ee2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" +dependencies = [ + "lazy_static", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "futures", + "futures-task", + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.17.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbbe89715c1dbbb790059e2565353978564924ee85017b5fff365c872ff6721f" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bc28f93baff38037f64e6f43d34cfa1605f27a49c34e8a04c5e78b0babf2596" +dependencies = [ + "ansi_term", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "triomphe" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe1b3800b35f9b936c28dc59dbda91b195371269396784d931fe2a5a2be3d2f" + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "try_match" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "789f9cd474cc74c591dcc98669b846e158f2409ace4e6e342502ab44a41c584b" +dependencies = [ + "try_match_inner", +] + +[[package]] +name = "try_match_inner" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "607e6b75bc1bdf1a60d4201c500ca965834c11f30e25921cfd28569315db49a9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typed-builder" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a46ee5bd706ff79131be9c94e7edcb82b703c487766a114434e5790361cf08c5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" + +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", +] + +[[package]] +name = "unicase" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-ident" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" + +[[package]] +name = "unicode-linebreak" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a52dcaab0c48d931f7cc8ef826fa51690a08e1ea55117ef26f89864f532383f" +dependencies = [ + "regex", +] + +[[package]] +name = "unicode-normalization" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854cbdc4f7bc6ae19c820d44abdc3277ac3e1b2b93db20a636825d9322fb60e6" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b90931029ab9b034b300b797048cf23723400aa757e8a2bfb9d748102f9821" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "uuid" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" +dependencies = [ + "getrandom", +] + +[[package]] +name = "v8" +version = "0.44.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3f92c29dd66c7342443280695afc5bb79d773c3aa3eb02978cf24f058ae2b3d" +dependencies = [ + "bitflags", + "fslock", + "lazy_static", + "libc", + "which", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi 0.3.9", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a" + +[[package]] +name = "web-sys" +version = "0.3.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed055ab27f941423197eb86b2035720b1a3ce40504df082cac2ecc6ed73335a1" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1c760f0d366a6c24a02ed7816e23e691f5d92291f94d15e836006fd11b04daf" +dependencies = [ + "webpki 0.22.0", +] + +[[package]] +name = "wepoll-ffi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" +dependencies = [ + "cc", +] + +[[package]] +name = "which" +version = "4.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" +dependencies = [ + "either", + "lazy_static", + "libc", +] + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi 0.3.9", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + +[[package]] +name = "xattr" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d1526bbe5aaeb5eb06885f4d987bcdfa5e23187055de9b83fe00156a821fabc" +dependencies = [ + "libc", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 000000000..20e58cd43 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,5 @@ +[workspace] +members = [ + "packages/libraries/router", + "scripts/compress" +] \ No newline at end of file diff --git a/packages/libraries/client/README.md b/packages/libraries/client/README.md index 686a23f60..3e4e59ded 100644 --- a/packages/libraries/client/README.md +++ b/packages/libraries/client/README.md @@ -80,37 +80,39 @@ The `collectUsage` method accepts the same arguments as execute function of grap - `finish(result)` (function returned by `collectUsage(args)`) - has to be invoked right after execution finishes. ```ts -import express from 'express'; -import { graphqlHTTP } from 'express-graphql'; -import { createHive } from '@graphql-hive/client'; +import express from 'express' +import { graphqlHTTP } from 'express-graphql' +import { createHive } from '@graphql-hive/client' -const app = express(); +const app = express() const hive = createHive({ enabled: true, // Enable/Disable Hive Client debug: true, // Debugging mode token: 'YOUR-TOKEN', reporting: { - // feel free to set dummy values here + // feel free to set dummy values here author: 'Author of the latest change', - commit: 'git sha or any identifier', + commit: 'git sha or any identifier' }, - usage: true, // Collects schema usage based operations - }, -}); + usage: true // Collects schema usage based operations +}) // Report Schema -hive.reportSchema({ schema: yourSchema }); +hive.reportSchema({ schema: yourSchema }) -app.post("/graphql", graphqlHTTP({ - schema: yourSchema, - async customExecuteFn(args) { - // Collecting usage - const finish = hive.collectUsage(args); - const result = await execute(args); - finish(result); - return result; - } -})); +app.post( + '/graphql', + graphqlHTTP({ + schema: yourSchema, + async customExecuteFn(args) { + // Collecting usage + const finish = hive.collectUsage(args) + const result = await execute(args) + finish(result) + return result + } + }) +) ``` #### Using the registry when Stitching @@ -154,21 +156,20 @@ startMyGraphQLGateway({ You can connect your Apollo Gateway with Hive client. -The `experimental_pollInterval` value is up to you. Apollo Gateway uses 10s (10_000 ms) by default but we think it's better to fetch a supergraph more often. - - `HIVE_CDN_ENDPOINT` - the endpoint Hive generated for you in the previous step - `HIVE_CDN_KEY` - the access ```ts -import { createSupergraphSDLFetcher } from '@graphql-hive/client' +import { createSupergraphManager } from '@graphql-hive/client' import { ApolloGateway } from '@apollo/gateway' import { ApolloServer } from 'apollo-server' const gateway = new ApolloGateway({ - experimental_pollInterval: 10_000, // define the poll interval (in ms) - experimental_updateSupergraphSdl: createSupergraphFetcher({ + // Apollo Gateway will fetch Supergraph from GraphQL Hive CDN + supergraphSdl: createSupergraphManager({ endpoint: HIVE_CDN_ENDPOINT, - key: HIVE_CDN_KEY + key: HIVE_CDN_KEY, + pollIntervalInMs: 15_000 }) }) diff --git a/packages/libraries/router/Cargo.toml b/packages/libraries/router/Cargo.toml new file mode 100644 index 000000000..c73ed5fc6 --- /dev/null +++ b/packages/libraries/router/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "graphql-hive-router" +version = "0.0.1" +authors = ["Kamil Kisiela "] +edition = "2021" +license = "MIT" +publish = false + +[[bin]] +name = "router" +path = "src/main.rs" + +[dependencies] +apollo-router = { git = "https://github.com/apollographql/router.git", branch = "main" } +reqwest = { version = "0.11.11", default-features = false, features = ["rustls-tls", "blocking", "json"] } +sha2 = { version = "0.10.2", features = ["std"] } +anyhow = "1" +tracing = "0.1" +async-trait = "0.1" +futures = "0.3" +schemars = { version = "0.8", features = ["url"] } +serde = "1" +serde_json = "1" +tokio = { version = "1", features = ["full"] } +tower = { version = "0.4", features = ["full"] } +http = "0.2" +graphql-parser = { git = "https://github.com/kamilkisiela/graphql-parser.git", branch = "kamil-minifier" } +graphql-tools = { git = "https://github.com/dotansimha/graphql-tools-rs.git", branch = "kamil-transformer" } +lru = "0.7.8" +md5 = "0.7.0" +rand = "0.8.5" \ No newline at end of file diff --git a/packages/libraries/router/src/agent.rs b/packages/libraries/router/src/agent.rs new file mode 100644 index 000000000..d6329ae48 --- /dev/null +++ b/packages/libraries/router/src/agent.rs @@ -0,0 +1,295 @@ +use super::graphql::OperationProcessor; +use graphql_parser::schema::{parse_schema, Document}; +use serde::Serialize; +use std::collections::{HashMap, VecDeque}; +use std::sync::{Arc, Mutex}; +use std::time::Duration; +use tokio::sync::mpsc; +use tokio::sync::oneshot; +use tokio::time::sleep; + +static COMMIT: Option<&'static str> = option_env!("GITHUB_SHA"); + +#[derive(Serialize, Debug)] +struct Report { + size: usize, + map: HashMap, + operations: Vec, +} + +#[allow(non_snake_case)] +#[derive(Serialize, Debug)] +struct OperationMapRecord { + operation: String, + operationName: Option, + fields: Vec, +} + +#[allow(non_snake_case)] +#[derive(Serialize, Debug)] +struct Operation { + operationMapKey: String, + timestamp: u64, + execution: Execution, + metadata: Option, +} + +#[allow(non_snake_case)] +#[derive(Serialize, Debug)] +struct Execution { + ok: bool, + duration: u128, + errorsTotal: usize, +} + +#[derive(Serialize, Debug)] +struct Metadata { + client: Option, +} + +#[derive(Serialize, Debug)] +struct ClientInfo { + name: Option, + version: Option, +} + +#[derive(Debug, Clone)] +pub struct ExecutionReport { + pub client_name: Option, + pub client_version: Option, + pub timestamp: u64, + pub duration: Duration, + pub ok: bool, + pub errors: usize, + pub operation_body: String, + pub operation_name: Option, +} + +#[derive(Debug, Clone)] +pub struct State { + buffer: VecDeque, + schema: Document<'static, String>, +} + +impl State { + fn new(schema: Document<'static, String>) -> Self { + Self { + buffer: VecDeque::new(), + schema, + } + } + + pub fn push(&mut self, report: ExecutionReport) -> usize { + self.buffer.push_back(report); + self.buffer.len() + } + + pub fn drain(&mut self) -> Vec { + self.buffer.drain(0..).collect::>() + } +} + +#[derive(Clone)] +pub struct UsageAgent { + pub sender: mpsc::Sender, + token: String, + endpoint: String, + state: Arc>, + processor: Arc>, +} + +fn non_empty_string(value: Option) -> Option { + match value { + Some(value) => match value.is_empty() { + true => None, + false => Some(value), + }, + None => None, + } +} + +impl UsageAgent { + pub fn new( + schema: String, + token: String, + endpoint: String, + _shutdown_signal: Option>, + ) -> Self { + let (tx, mut rx) = mpsc::channel::(1024); + let schema = parse_schema::(&schema) + .expect("parsed schema") + .into_static(); + let state = Arc::new(Mutex::new(State::new(schema))); + let processor = Arc::new(Mutex::new(OperationProcessor::new())); + + let agent = Self { + sender: tx, + state, + processor, + endpoint, + token, + }; + + let agent_for_report_receiver = agent.clone(); + let agent_for_interval = agent.clone(); + + // TODO: make this working + // tokio::task::spawn(async move { + // if let Some(shutdown_signal) = shutdown_signal { + // tracing::info!("waiting for shutdown signal"); + // shutdown_signal.await.expect("shutdown signal"); + // tracing::info!("Flushing reports because of shutdown signal"); + // // agent_for_shutdown_signal.clone().flush().await; + // // tracing::info!("Flushed because of shutdown"); + // } + + // tracing::info!("Closing spawn for shutdown signal receiver"); + // }); + + tokio::task::spawn(async move { + while let Some(execution_report) = rx.recv().await { + agent_for_report_receiver + .clone() + .add_report(execution_report) + .await + } + }); + + tokio::task::spawn(async move { + loop { + sleep(Duration::from_secs(5)).await; + agent_for_interval.clone().flush().await; + } + }); + + agent + } + + fn produce_report(&mut self, reports: Vec) -> Report { + let mut report = Report { + size: 0, + map: HashMap::new(), + operations: Vec::new(), + }; + let schema = self.state.lock().unwrap().schema.clone(); + // iterate over reports and check if they are valid + for op in reports { + let operation = self + .processor + .lock() + .expect("lock normalizer") + .process(&op.operation_body, &schema); + match operation { + Err(e) => { + tracing::warn!("Dropping operation: {}", e); + continue; + } + Ok(operation) => { + let hash = operation.hash; + report.operations.push(Operation { + operationMapKey: hash.clone(), + timestamp: op.timestamp, + execution: Execution { + ok: op.ok, + duration: op.duration.as_nanos(), + errorsTotal: op.errors, + }, + metadata: Some(Metadata { + client: Some(ClientInfo { + name: non_empty_string(op.client_name), + version: non_empty_string(op.client_version), + }), + }), + }); + if !report.map.contains_key(&hash) { + report.map.insert( + hash, + OperationMapRecord { + operation: operation.operation, + operationName: non_empty_string(op.operation_name), + fields: operation.coordinates, + }, + ); + } + report.size += 1; + } + } + } + + report + } + + async fn send_report(&self, report: Report) -> Result<(), String> { + let client = reqwest::Client::new(); + let mut delay = Duration::from_millis(0); + let mut error_message = "Unexpected error".to_string(); + + for _ in 0..3 { + let resp = client + .post(self.endpoint.clone()) + .header( + reqwest::header::AUTHORIZATION, + format!("Bearer {}", self.token.clone()), + ) + .header( + reqwest::header::USER_AGENT, + format!("graphql-hive-router@{}", COMMIT.unwrap_or_else(|| "local")), + ) + .json(&report) + .send() + .await + .map_err(|e| e.to_string())?; + + match resp.status() { + reqwest::StatusCode::OK => { + return Ok(()); + } + reqwest::StatusCode::BAD_REQUEST => { + return Err("Token is missing".to_string()); + } + reqwest::StatusCode::FORBIDDEN => { + return Err("No access".to_string()); + } + _ => { + error_message = format!( + "Could not send usage report: ({}) {}", + resp.status().as_str(), + resp.text().await.unwrap_or_default() + ); + } + } + delay += Duration::from_millis(500); + tokio::time::sleep(delay).await; + } + + Err(error_message) + } + + async fn add_report(&mut self, execution_report: ExecutionReport) { + let size = self + .state + .lock() + .expect("lock state") + .push(execution_report); + self.flush_if_full(size).await; + } + + async fn flush_if_full(&mut self, size: usize) { + if size >= 5 { + self.flush().await; + } + } + + pub async fn flush(&mut self) { + let execution_reports = self.state.clone().lock().unwrap().drain(); + let size = execution_reports.len(); + + if size > 0 { + let report = self.produce_report(execution_reports); + match self.send_report(report).await { + Ok(_) => tracing::debug!("Reported {} operations", size), + Err(e) => tracing::error!("{}", e), + } + } + } +} diff --git a/packages/libraries/router/src/graphql.rs b/packages/libraries/router/src/graphql.rs new file mode 100644 index 000000000..6c963693a --- /dev/null +++ b/packages/libraries/router/src/graphql.rs @@ -0,0 +1,477 @@ +use graphql_tools::ast::ext::SchemaDocumentExtension; +use graphql_tools::ast::TypeDefinitionExtension; +use lru::LruCache; +use md5; +use std::cmp::Ordering; +use std::collections::BTreeMap; +use std::collections::HashMap; +use std::collections::HashSet; + +use graphql_parser::minify_query; +use graphql_parser::parse_query; +use graphql_parser::query::{ + Directive, Document, Field, FragmentDefinition, Number, Selection, SelectionSet, Text, Type, + Value, VariableDefinition, +}; +use graphql_parser::schema::{Document as SchemaDocument, TypeDefinition}; +use graphql_tools::ast::{ + visit_document, OperationTransformer, OperationVisitor, OperationVisitorContext, Transformed, + TransformedValue, +}; + +struct SchemaCoordinatesContext { + pub schema_coordinates: HashSet, + pub input_types_to_collect: HashSet, +} + +pub fn collect_schema_coordinates( + document: &Document<'static, String>, + schema: &SchemaDocument<'static, String>, +) -> HashSet { + let mut ctx = SchemaCoordinatesContext { + schema_coordinates: HashSet::new(), + input_types_to_collect: HashSet::new(), + }; + let mut visit_context = OperationVisitorContext::new(document, schema); + let mut visitor = SchemaCoordinatesVisitor {}; + + visit_document(&mut visitor, &document, &mut visit_context, &mut ctx); + + for input_type_name in ctx.input_types_to_collect { + let named_type = schema.type_by_name(&input_type_name).unwrap(); + match named_type { + TypeDefinition::InputObject(input_type) => { + for field in input_type.fields { + ctx.schema_coordinates + .insert(format!("{}.{}", input_type_name, field.name)); + } + } + _ => {} + } + } + + ctx.schema_coordinates +} + +struct SchemaCoordinatesVisitor {} + +impl SchemaCoordinatesVisitor { + fn resolve_type_name<'a>(&self, t: Type<'a, String>) -> String { + match t { + Type::NamedType(value) => return value, + Type::ListType(t) => return self.resolve_type_name(*t), + Type::NonNullType(t) => return self.resolve_type_name(*t), + } + } +} + +impl<'a> OperationVisitor<'a, SchemaCoordinatesContext> for SchemaCoordinatesVisitor { + fn enter_field( + &mut self, + info: &mut OperationVisitorContext<'a>, + ctx: &mut SchemaCoordinatesContext, + field: &Field<'static, String>, + ) { + let parent_name = info.current_parent_type().unwrap().name(); + let field_name = field.name.to_string(); + + ctx.schema_coordinates + .insert(format!("{}.{}", parent_name, field_name)); + } + + fn enter_variable_definition( + &mut self, + _: &mut OperationVisitorContext<'a>, + ctx: &mut SchemaCoordinatesContext, + var: &graphql_tools::static_graphql::query::VariableDefinition, + ) { + ctx.input_types_to_collect + .insert(self.resolve_type_name(var.var_type.clone())); + } + + fn enter_argument( + &mut self, + info: &mut OperationVisitorContext<'a>, + ctx: &mut SchemaCoordinatesContext, + arg: &(String, Value<'static, String>), + ) { + let type_name = info.current_parent_type().unwrap().name(); + let field = info.current_field(); + + if let Some(field) = field { + let field_name = field.name.clone(); + let arg_name = arg.0.clone(); + + ctx.schema_coordinates + .insert(format!("{type_name}.{field_name}.{arg_name}").to_string()); + + let arg_value = arg.1.clone(); + + match info.current_input_type() { + Some(input_type) => { + let input_type_name = input_type.name(); + match arg_value { + Value::Enum(value) => { + let value_str = value.to_string(); + ctx.schema_coordinates + .insert(format!("{input_type_name}.{value_str}").to_string()); + } + Value::List(_) => { + // handled by enter_list_value + } + Value::Object(_) => { + // handled by enter_object_field + } + _ => { + ctx.input_types_to_collect.insert(input_type_name); + } + } + } + None => {} + } + } + } + + fn enter_list_value( + &mut self, + info: &mut OperationVisitorContext<'a>, + ctx: &mut SchemaCoordinatesContext, + values: &Vec>, + ) { + if let Some(input_type) = info.current_input_type() { + for value in values { + match value { + Value::Object(_) => { + // object fields are handled by enter_object_field + } + _ => { + ctx.input_types_to_collect.insert(input_type.name()); + } + } + } + } + } + + fn enter_object_field( + &mut self, + info: &mut OperationVisitorContext<'a>, + ctx: &mut SchemaCoordinatesContext, + (name, value): &(String, Value<'static, String>), + ) { + let input_type = info.current_input_type(); + + if let Some(input_type) = input_type { + ctx.schema_coordinates + .insert(format!("{}.{}", input_type.name(), name)); + + let input_type_name = input_type.name(); + match value { + Value::Enum(value) => { + // Collect only a specific enum value + let value_str = value.to_string(); + ctx.schema_coordinates + .insert(format!("{input_type_name}.{value_str}").to_string()); + } + Value::List(_) => { + // handled by enter_list_value + } + Value::Object(_) => { + // handled by enter_object_field + } + _ => { + ctx.input_types_to_collect.insert(input_type_name); + } + } + } + } +} + +struct StripLiteralsTransformer {} + +impl<'a, T: Text<'a> + Clone> OperationTransformer<'a, T> for StripLiteralsTransformer { + fn transform_value(&mut self, node: &Value<'a, T>) -> TransformedValue> { + match node { + Value::Float(_) => TransformedValue::Replace(Value::Float(0.0)), + Value::Int(_) => TransformedValue::Replace(Value::Int(Number::from(0))), + Value::String(_) => TransformedValue::Replace(Value::String(String::from(""))), + Value::Variable(_) => TransformedValue::Keep, + Value::Boolean(_) => TransformedValue::Keep, + Value::Null => TransformedValue::Keep, + Value::Enum(_) => TransformedValue::Keep, + Value::List(val) => { + let items: Vec> = val + .iter() + .map(|item| self.transform_value(item).replace_or_else(|| item.clone())) + .collect(); + + TransformedValue::Replace(Value::List(items)) + } + Value::Object(fields) => { + let fields: BTreeMap> = fields + .iter() + .map(|field| { + let (name, value) = field; + let new_value = self + .transform_value(value) + .replace_or_else(|| value.clone()); + (name.clone(), new_value) + }) + .collect(); + + TransformedValue::Replace(Value::Object(fields)) + } + } + } + + fn transform_field( + &mut self, + field: &graphql_parser::query::Field<'a, T>, + ) -> Transformed> { + let selection_set = self.transform_selection_set(&field.selection_set); + let arguments = self.transform_arguments(&field.arguments); + let directives = self.transform_directives(&field.directives); + + Transformed::Replace(Selection::Field(Field { + arguments: arguments.replace_or_else(|| field.arguments.clone()), + directives: directives.replace_or_else(|| field.directives.clone()), + selection_set: SelectionSet { + items: selection_set.replace_or_else(|| field.selection_set.items.clone()), + span: field.selection_set.span, + }, + position: field.position, + alias: None, + name: field.name.clone(), + })) + } +} + +#[derive(Hash, Eq, PartialEq, Clone, Copy)] +pub struct PointerAddress(usize); + +impl PointerAddress { + pub fn new(ptr: &T) -> Self { + let ptr_address: usize = unsafe { std::mem::transmute(ptr) }; + Self(ptr_address) + } +} + +type Seen<'s, T> = HashMap>>; + +pub struct SortSelectionsTransform<'s, T: Text<'s> + Clone> { + seen: Seen<'s, T>, +} + +impl<'s, T: Text<'s> + Clone> SortSelectionsTransform<'s, T> { + pub fn new() -> Self { + Self { + seen: Default::default(), + } + } +} + +impl<'s, T: Text<'s> + Clone> OperationTransformer<'s, T> for SortSelectionsTransform<'s, T> { + fn transform_selection_set( + &mut self, + selections: &SelectionSet<'s, T>, + ) -> TransformedValue>> { + let mut next_selections = self + .transform_list(&selections.items, Self::transform_selection) + .replace_or_else(|| selections.items.to_vec()); + next_selections.sort_unstable_by(|a, b| self.compare_selections(a, b)); + TransformedValue::Replace(next_selections) + } + + fn transform_directives( + &mut self, + directives: &Vec>, + ) -> TransformedValue>> { + let mut next_directives = self + .transform_list(&directives, Self::transform_directive) + .replace_or_else(|| directives.to_vec()); + next_directives.sort_unstable_by(|a, b| self.compare_directives(a, b)); + TransformedValue::Replace(next_directives) + } + + fn transform_arguments( + &mut self, + arguments: &[(T::Value, Value<'s, T>)], + ) -> TransformedValue)>> { + let mut next_arguments = self + .transform_list(&arguments, Self::transform_argument) + .replace_or_else(|| arguments.to_vec()); + next_arguments.sort_unstable_by(|a, b| self.compare_arguments(a, b)); + TransformedValue::Replace(next_arguments) + } + + fn transform_variable_definitions( + &mut self, + variable_definitions: &Vec>, + ) -> TransformedValue>> { + let mut next_variable_definitions = self + .transform_list(&variable_definitions, Self::transform_variable_definition) + .replace_or_else(|| variable_definitions.to_vec()); + next_variable_definitions.sort_unstable_by(|a, b| self.compare_variable_definitions(a, b)); + TransformedValue::Replace(next_variable_definitions) + } + + fn transform_fragment( + &mut self, + fragment: &FragmentDefinition<'s, T>, + ) -> Transformed> { + let mut directives = fragment.directives.clone(); + directives.sort_unstable_by_key(|var| var.name.clone()); + + let selections = self.transform_selection_set(&fragment.selection_set); + + Transformed::Replace(FragmentDefinition { + selection_set: SelectionSet { + items: selections.replace_or_else(|| fragment.selection_set.items.clone()), + span: fragment.selection_set.span.clone(), + }, + directives, + name: fragment.name.clone(), + position: fragment.position.clone(), + type_condition: fragment.type_condition.clone(), + }) + } + + fn transform_selection( + &mut self, + selection: &Selection<'s, T>, + ) -> Transformed> { + match selection { + Selection::InlineFragment(selection) => { + let key = PointerAddress::new(selection); + if let Some(prev) = self.seen.get(&key) { + return prev.clone(); + } + let transformed = self.transform_inline_fragment(selection); + self.seen.insert(key, transformed.clone()); + transformed + } + Selection::Field(field) => { + let key = PointerAddress::new(field); + if let Some(prev) = self.seen.get(&key) { + return prev.clone(); + } + let transformed = self.transform_field(field); + self.seen.insert(key, transformed.clone()); + transformed + } + Selection::FragmentSpread(_) => Transformed::Keep, + } + } +} + +impl<'s, T: Text<'s> + Clone> SortSelectionsTransform<'s, T> { + fn compare_selections(&self, a: &Selection<'s, T>, b: &Selection<'s, T>) -> Ordering { + match (a, b) { + (Selection::Field(a), Selection::Field(b)) => a.name.cmp(&b.name), + (Selection::FragmentSpread(a), Selection::FragmentSpread(b)) => { + a.fragment_name.cmp(&b.fragment_name) + } + _ => { + let a_ordering = selection_kind_ordering(a); + let b_ordering = selection_kind_ordering(b); + assert!( + a_ordering != b_ordering, + "expected different ordering, got {} == {}", + a_ordering, + b_ordering + ); + a_ordering.cmp(&b_ordering) + } + } + } + fn compare_directives(&self, a: &Directive<'s, T>, b: &Directive<'s, T>) -> Ordering { + a.name.cmp(&b.name) + } + fn compare_arguments( + &self, + a: &(T::Value, Value<'s, T>), + b: &(T::Value, Value<'s, T>), + ) -> Ordering { + a.0.cmp(&b.0) + } + fn compare_variable_definitions( + &self, + a: &VariableDefinition<'s, T>, + b: &VariableDefinition<'s, T>, + ) -> Ordering { + a.name.cmp(&b.name) + } +} + +/// Assigns an order to different variants of Selection. +fn selection_kind_ordering<'s, T: Text<'s>>(selection: &Selection<'s, T>) -> u8 { + match selection { + Selection::FragmentSpread(_) => 1, + Selection::InlineFragment(_) => 2, + Selection::Field(_) => 3, + } +} + +#[derive(Clone)] +pub struct ProcessedOperation { + pub operation: String, + pub hash: String, + pub coordinates: Vec, +} + +pub struct OperationProcessor { + cache: LruCache, +} + +impl OperationProcessor { + pub fn new() -> OperationProcessor { + OperationProcessor { + cache: LruCache::new(1000), + } + } + + pub fn process( + &mut self, + query: &str, + schema: &SchemaDocument<'static, String>, + ) -> Result { + let key = query.to_string(); + if self.cache.contains(&key) { + Ok(self.cache.get(&key).expect("lock cache").clone()) + } else { + let result = self.transform(query, schema)?; + self.cache.put(key, result.clone()); + Ok(result) + } + } + + fn transform( + &self, + operation: &str, + schema: &SchemaDocument<'static, String>, + ) -> Result { + let mut strip_literals_transformer = StripLiteralsTransformer {}; + let parsed = parse_query(operation) + .map_err(|e| e.to_string())? + .into_static(); + + let schema_coordinates: Vec = + Vec::from_iter(collect_schema_coordinates(&parsed, schema)); + + let normalized = strip_literals_transformer + .transform_document(&parsed) + .replace_or_else(|| parsed.clone()); + + let normalized = SortSelectionsTransform::new() + .transform_document(&normalized) + .replace_or_else(|| normalized.clone()); + + let printed = minify_query(format!("{}", normalized.clone())).map_err(|e| e.to_string())?; + let hash = format!("{:x}", md5::compute(printed.clone())); + + Ok(ProcessedOperation { + operation: printed, + hash, + coordinates: schema_coordinates, + }) + } +} diff --git a/packages/libraries/router/src/lib.rs b/packages/libraries/router/src/lib.rs new file mode 100644 index 000000000..998984528 --- /dev/null +++ b/packages/libraries/router/src/lib.rs @@ -0,0 +1,3 @@ +mod agent; +mod graphql; +pub mod usage; diff --git a/packages/libraries/router/src/main.rs b/packages/libraries/router/src/main.rs new file mode 100644 index 000000000..38eee23cb --- /dev/null +++ b/packages/libraries/router/src/main.rs @@ -0,0 +1,24 @@ +use registry::HiveRegistry; + +mod agent; +mod graphql; +mod registry; +mod usage; + +fn main() { + match HiveRegistry::new() { + Ok(_) => {} + Err(e) => { + eprintln!("{}", e); + std::process::exit(1); + } + } + + match apollo_router::main() { + Ok(_) => {} + Err(e) => { + eprintln!("{}", e); + std::process::exit(1); + } + } +} diff --git a/packages/libraries/router/src/registry.rs b/packages/libraries/router/src/registry.rs new file mode 100644 index 000000000..6a5ba1596 --- /dev/null +++ b/packages/libraries/router/src/registry.rs @@ -0,0 +1,113 @@ +use anyhow::Result; +use sha2::Digest; +use sha2::Sha256; +use std::env; +use std::io::Write; +use std::thread; + +#[derive(Debug, Clone)] +pub struct HiveRegistry { + endpoint: String, + key: String, + file_name: String, +} + +impl HiveRegistry { + pub fn new() -> Result<(), String> { + let endpoint = env::var("HIVE_CDN_ENDPOINT").unwrap_or_default(); + let key = env::var("HIVE_CDN_KEY").unwrap_or_default(); + + //.map_err(|_| "environment variable HIVE_CDN_KEY not found")?; + // .map_err(|_| "environment variable HIVE_CDN_ENDPOINT not found")?; + if endpoint.is_empty() && key.is_empty() { + tracing::info!("You're not using GraphQL Hive as the source of schema."); + tracing::info!( + "Reason: could not find HIVE_CDN_KEY and HIVE_CDN_ENDPOINT environment variables." + ); + return Ok(()); + } + + if endpoint.is_empty() { + return Err("environment variable HIVE_CDN_ENDPOINT not found".to_string()); + } + + if key.is_empty() { + return Err("environment variable HIVE_CDN_KEY not found".to_string()); + } + + let file_name = "supergraph-schema.graphql".to_string(); + let poll_interval: u64 = env::var("HIVE_CDN_POLL_INTERVAL") + // .or_else::(Ok("10".to_string()))? + .unwrap_or_else(|_| "10".to_string()) + .parse() + .expect("failed to parse HIVE_CDN_POLL_INTERVAL"); + + env::set_var("APOLLO_ROUTER_SUPERGRAPH_PATH", file_name.clone()); + env::set_var("APOLLO_ROUTER_HOT_RELOAD", "true"); + + let registry = HiveRegistry { + endpoint, + key, + file_name, + }; + + match registry.initial_supergraph() { + Ok(_) => { + tracing::info!("Successfully fetched and saved supergraph"); + } + Err(e) => { + eprintln!("{}", e); + std::process::exit(1); + } + } + + thread::spawn(move || loop { + thread::sleep(std::time::Duration::from_secs(poll_interval)); + registry.poll() + }); + + Ok(()) + } + + fn fetch_supergraph(&self) -> Result { + let client = reqwest::blocking::Client::new(); + let resp = client + .get(format!("{}/supergraph", self.endpoint)) + .header("X-Hive-CDN-Key", self.key.to_string()) + .send() + .map_err(|e| e.to_string())?; + + Ok(resp.text().map_err(|e| e.to_string())?) + } + + fn initial_supergraph(&self) -> Result<(), String> { + let mut file = std::fs::File::create(self.file_name.clone()).map_err(|e| e.to_string())?; + let resp = self.fetch_supergraph()?; + file.write_all(resp.as_bytes()).map_err(|e| e.to_string())?; + Ok(()) + } + + fn poll(&self) { + let current_file = + std::fs::read_to_string(self.file_name.clone()).expect("Could not read file"); + let current_supergraph_hash = hash(current_file.as_bytes()); + + match self.fetch_supergraph() { + Ok(new_supergraph) => { + let new_supergraph_hash = hash(new_supergraph.as_bytes()); + if current_supergraph_hash != new_supergraph_hash { + tracing::info!("New supergraph detected!"); + std::fs::write(self.file_name.clone(), new_supergraph) + .expect("Could not write file"); + } + } + Err(e) => tracing::error!("{}", e), + } + } +} + +fn hash(bytes: &[u8]) -> String { + let mut hasher = Sha256::new(); + hasher.update(bytes); + format!("{:X}", hasher.finalize()) +} diff --git a/packages/libraries/router/src/usage.rs b/packages/libraries/router/src/usage.rs new file mode 100644 index 000000000..feb3b2839 --- /dev/null +++ b/packages/libraries/router/src/usage.rs @@ -0,0 +1,293 @@ +use apollo_router::layers::ServiceBuilderExt; +use apollo_router::plugin::Plugin; +use apollo_router::plugin::PluginInit; +use apollo_router::register_plugin; +use apollo_router::services::RouterRequest; +use apollo_router::services::RouterResponse; +use apollo_router::Context; +use core::ops::Drop; +use futures::StreamExt; +use http::HeaderValue; +use rand::Rng; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use std::collections::HashSet; +use std::env; +use std::time::Instant; +use std::time::{SystemTime, UNIX_EPOCH}; +use tokio::sync::mpsc; +use tokio::sync::oneshot; +use tower::util::BoxService; +use tower::BoxError; +use tower::ServiceBuilder; +use tower::ServiceExt; + +use crate::agent::{ExecutionReport, UsageAgent}; + +pub(crate) static OPERATION_CONTEXT: &str = "hive::operation_context"; + +#[derive(Serialize, Deserialize)] +struct OperationContext { + pub(crate) client_name: Option, + pub(crate) client_version: Option, + pub(crate) timestamp: u64, + pub(crate) operation_body: String, + pub(crate) operation_name: Option, + pub(crate) dropped: bool, +} + +struct UsagePlugin { + #[allow(dead_code)] + config: Config, + agent: UsageAgent, + shutdown_signal: Option>, +} + +#[derive(Clone, Debug, Deserialize, JsonSchema)] +struct Config { + /// Sample rate to determine sampling. + /// 0.0 = 0% chance of being sent + /// 1.0 = 100% chance of being sent. + /// Default: 1.0 + sample_rate: Option, + /// A list of operations (by name) to be ignored by Hive. + exclude: Option>, + client_name_header: Option, + client_version_header: Option, +} + +impl Default for Config { + fn default() -> Self { + Self { + sample_rate: Some(1.0), + exclude: None, + client_name_header: None, + client_version_header: None, + } + } +} + +impl UsagePlugin { + fn populate_context(config: Config, req: &RouterRequest) { + let context = &req.context; + let http_request = &req.originating_request; + let headers = http_request.headers(); + let client_name_header = config + .client_name_header + .unwrap_or("graphql-client-name".to_string()); + let client_version_header = config + .client_version_header + .unwrap_or("graphql-client-version".to_string()); + + let client_name = headers + .get(client_name_header) + .cloned() + .unwrap_or_else(|| HeaderValue::from_static("")) + .to_str() + .ok() + .map(|v| v.to_string()); + + let client_version = headers + .get(client_version_header) + .cloned() + .unwrap_or_else(|| HeaderValue::from_static("")) + .to_str() + .ok() + .map(|v| v.to_string()); + + let operation_name = req.originating_request.body().operation_name.clone(); + let operation_body = req + .originating_request + .body() + .query + .clone() + .expect("operation body"); + + let sample_rate = config.sample_rate.clone(); + let excluded_operation_names: HashSet = config + .exclude + .unwrap_or_else(|| vec![]) + .clone() + .into_iter() + .collect(); + + let mut rng = rand::thread_rng(); + let mut dropped = match sample_rate { + Some(rate) => { + let num: f64 = rng.gen(); + num <= rate + } + None => false, + }; + + if !dropped { + match operation_name.clone() { + Some(name) => { + if excluded_operation_names.contains(&name) { + dropped = true; + } + } + None => {} + } + } + + if dropped { + tracing::debug!("Dropped the operation"); + } + + let _ = context.insert( + OPERATION_CONTEXT, + OperationContext { + dropped, + client_name, + client_version, + operation_name, + operation_body, + timestamp: SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() + * 1000, + }, + ); + } + + pub fn add_report(sender: mpsc::Sender, report: ExecutionReport) { + if let Err(e) = sender.to_owned().try_send(report) { + tracing::error!("Failed to send report: {}", e); + } + } +} + +#[async_trait::async_trait] +impl Plugin for UsagePlugin { + type Config = Config; + + async fn new(init: PluginInit) -> Result { + tracing::debug!("Starting GraphQL Hive Usage plugin"); + let token = + env::var("HIVE_TOKEN").map_err(|_| "environment variable HIVE_TOKEN not found")?; + let endpoint = env::var("HIVE_ENDPOINT"); + let endpoint = match endpoint { + Ok(endpoint) => endpoint, + Err(_) => "https://app.graphql-hive.com/usage".to_string(), + }; + + let (shutdown_tx, shutdown_rx) = oneshot::channel::<()>(); + + Ok(UsagePlugin { + config: init.config, + agent: UsageAgent::new( + init.supergraph_sdl.to_string(), + token, + endpoint, + Some(shutdown_rx), + ), + shutdown_signal: Some(shutdown_tx), + }) + } + + fn router_service( + &self, + service: BoxService, + ) -> BoxService { + let config = self.config.clone(); + let report_sender = self.agent.sender.clone(); + + ServiceBuilder::new() + .map_future_with_context( + move |req: &RouterRequest| { + Self::populate_context(config.clone(), req); + req.context.clone() + }, + move |ctx: Context, fut| { + let start = Instant::now(); + let sender = report_sender.clone(); + + async move { + let operation_context = ctx + .get::<_, OperationContext>(OPERATION_CONTEXT) + .unwrap_or_default() + .unwrap(); + + if operation_context.dropped { + let result: Result = fut.await; + return result; + } + + let result: Result = fut.await; + let client_name = operation_context.client_name; + let client_version = operation_context.client_version; + let operation_name = operation_context.operation_name; + let operation_body = operation_context.operation_body; + let timestamp = operation_context.timestamp; + let duration = start.elapsed(); + + match result { + Err(e) => { + Self::add_report( + sender.clone(), + ExecutionReport { + client_name, + client_version, + timestamp, + duration, + ok: false, + errors: 1, + operation_body, + operation_name, + }, + ); + Err(e) + } + Ok(router_response) => { + let is_failure = !router_response.response.status().is_success(); + Ok(router_response.map(move |response_stream| { + let sender = sender.clone(); + let client_name = client_name.clone(); + let client_version = client_version.clone(); + let operation_body = operation_body.clone(); + let operation_name = operation_name.clone(); + + response_stream + .map(move |response| { + // make sure we send a single report, not for each chunk + let response_has_errors = !response.errors.is_empty(); + + Self::add_report( + sender.clone(), + ExecutionReport { + client_name: client_name.clone(), + client_version: client_version.clone(), + timestamp, + duration, + ok: !is_failure && !response_has_errors, + errors: response.errors.len(), + operation_body: operation_body.clone(), + operation_name: operation_name.clone(), + }, + ); + + response + }) + .boxed() + })) + } + } + } + }, + ) + .service(service) + .boxed() + } +} + +impl Drop for UsagePlugin { + fn drop(&mut self) { + if let Some(sender) = self.shutdown_signal.take() { + let _ = sender.send(()); + } + } +} + +register_plugin!("hive", "usage", UsagePlugin); diff --git a/packages/web/docs/pages/features/monitoring.mdx b/packages/web/docs/pages/features/monitoring.mdx index a54e7dc6b..0ccecc05f 100644 --- a/packages/web/docs/pages/features/monitoring.mdx +++ b/packages/web/docs/pages/features/monitoring.mdx @@ -65,6 +65,47 @@ const envelopProxy = envelop({ }) ``` +### Apollo Router + +GraphQL Hive ships a custom version of [Apollo Router](https://www.apollographql.com/docs/router/). The reason is that in order to extend Apollo Router, we need to write [a native Rust plugin](https://www.apollographql.com/docs/router/customizations/native). + +Download Apollo Router for Linux (x86_64), MacOS (x86_64) or Windows (x86_64): + +```bash +curl -fsSL https://graphql-hive.com/apollo-router-download.sh | bash +``` + +Write `router.yaml` file and enable `hive.usage` plugin: + +```yaml +plugins: + hive.usage: + {} + # Sample rate to determine sampling. + # 0.0 = 0% chance of being sent + # 1.0 = 100% chance of being sent. + # Default: 1.0 + # sample_rate: "0.5", + # + # A list of operations (by name) to be ignored by Hive. + # exclude: ["IntrospectionQuery", "MeQuery"], + # + # Uses graphql-client-name by default + # client_name_header: "x-client-name", + # Uses graphql-client-version by default + # client_version_header: "x-client-version", +``` + +You can also enable other feautes like sampling. + +Now, start the router: + +```bash +HIVE_TOKEN="your-token" ./router +``` + +If everything worked correctly, you should see the first operations in GraphQL Hive in 1-2 minutes. + ### Other servers The `createHive` function creates a generic Hive Client to be used with any GraphQL flow. diff --git a/packages/web/docs/pages/features/registry-usage.mdx b/packages/web/docs/pages/features/registry-usage.mdx index fa566504e..6245357ba 100644 --- a/packages/web/docs/pages/features/registry-usage.mdx +++ b/packages/web/docs/pages/features/registry-usage.mdx @@ -16,23 +16,24 @@ GraphQL Hive will now generate a unique key: ## Apollo Federation -You're a programmer (or if you prefer a Software Engineer) so no need to explain the code snippet below. Just two things: +There are gateways maintained by Apollo team, [Apollo Gateway](#apollo-gateway) and [Apollo Router](#apollo-router). GraphQL Hive supports both! + +### Apollo Gateway - `HIVE_CDN_ENDPOINT` - the endpoint Hive generated for you in the previous step - `HIVE_CDN_KEY` - the access key -The `experimental_pollInterval` value is up to you. Apollo Gateway uses 10s (10.000 ms) by default but we think it's better to fetch a supergraph more often. - ```typescript -import { createSupergraphSDLFetcher } from '@graphql-hive/client' +import { createSupergraphManager } from '@graphql-hive/client' import { ApolloGateway } from '@apollo/gateway' import { ApolloServer } from 'apollo-server' const gateway = new ApolloGateway({ - experimental_pollInterval: 10_000, // define the poll interval (in ms) - experimental_updateSupergraphSdl: createSupergraphFetcher({ - endpoint: HIVE_CDN_ENDPOINT, - key: HIVE_CDN_KEY + // Apollo Gateway will fetch Supergraph from GraphQL Hive CDN + supergraphSdl: createSupergraphManager({ + endpoint: process.env.HIVE_CDN_ENDPOINT, + key: process.env.HIVE_CDN_KEY, + pollIntervalInMs: 15_000 }) }) @@ -45,6 +46,27 @@ server.listen().then(({ url }) => { }) ``` +### Apollo Router + +GraphQL Hive ships a custom version of [Apollo Router](https://www.apollographql.com/docs/router/). The reason is that in order to extend Apollo Router, we need to write [a native Rust plugin](https://www.apollographql.com/docs/router/customizations/native). + +Download Apollo Router for Linux (x86_64), MacOS (x86_64) or Windows (x86_64): + +```bash +curl -fsSL https://graphql-hive.com/apollo-router-download.sh | bash +``` + +Start the router: + +```bash +HIVE_CDN_ENDPOINT="..." HIVE_CDN_KEY="..." ./router +``` + +- `HIVE_CDN_ENDPOINT` - the endpoint Hive generated for you in the previous step +- `HIVE_CDN_KEY` - the access key + +> Apollo Router polls schema from the registry every 10 seconds. In order to change it to 15 seconds pass: `HIVE_CDN_POLL_INTERVAL=15`. + ## Schema Stitching Stitching could be done in many ways, that's why `@graphql-hive/client` provides generic functions, not something dedicated for stitching. Unfortunately the implementation of gateway + polling is up to you. diff --git a/packages/web/landing-page/public/apollo-router-download.sh b/packages/web/landing-page/public/apollo-router-download.sh new file mode 100644 index 000000000..58df812fd --- /dev/null +++ b/packages/web/landing-page/public/apollo-router-download.sh @@ -0,0 +1,68 @@ +#!/bin/bash + +set -u + +COMMIT="latest" +OS="$(uname -s)" + +# Parse Flags +parse_args() { + while [[ $# -gt 0 ]]; do + key="$1" + + case $key in + -c | --commit) + COMMIT="$2" + shift # past commit argument + shift # past commit value + ;; + *) + echo "Unrecognized argument $key" + exit 1 + ;; + esac + done +} + +set_target() { + case "$OS" in + Linux) + TARGET="linux" + EXT="" + ;; + + Darwin) + TARGET=macos + EXT="" + ;; + + MINGW* | MSYS* | CYGWIN*) + TARGET=win + EXT=".exe" + ;; + + *) + echo "OS $OS is not supported." + echo "If you think that's a bug - please file an issue to https://github.com/kamilkisiela/graphql-hive/issues" + exit 1 + ;; + esac +} + +download() { + DOWNLOAD_DIR=$(mktemp -d) + + URL="https://apollo-router.theguild.workers.dev/$TARGET/$COMMIT" + echo "Downloading $URL" + + if ! curl --progress-bar --fail -L "$URL" -o "$DOWNLOAD_DIR/router.tar.gz"; then + echo "Download failed." + exit 1 + fi + + tar xzf "$DOWNLOAD_DIR/router.tar.gz" +} + +parse_args "$@" +set_target +download diff --git a/scripts/compress/Cargo.toml b/scripts/compress/Cargo.toml new file mode 100644 index 000000000..16542790b --- /dev/null +++ b/scripts/compress/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "compress" +version = "0.0.1" +authors = ["Kamil Kisiela "] +edition = "2021" +license = "MIT" +publish = false + +[[bin]] +name = "compress" +path = "src/main.rs" + +[dependencies] +flate2 = "1.0.24" +tar = "0.4" \ No newline at end of file diff --git a/scripts/compress/src/main.rs b/scripts/compress/src/main.rs new file mode 100644 index 000000000..2553302fc --- /dev/null +++ b/scripts/compress/src/main.rs @@ -0,0 +1,39 @@ +extern crate flate2; + +use flate2::write::GzEncoder; +use flate2::Compression; +use std::env::args; +use std::fs::File; +use std::io::BufWriter; +use std::path::Path; +use std::time::Instant; + +fn main() { + if args().len() != 3 { + eprintln!("Usage: ./compress `source` `target`"); + return; + } + + let start = Instant::now(); + let input_path = args().nth(1).unwrap(); + let output_path = args().nth(2).unwrap(); + let cloned_input_path = input_path.clone(); + let input_filename = Path::new(&cloned_input_path) + .file_name() + .unwrap() + .to_str() + .unwrap(); + + let mut input_file = File::open(input_path).expect("Failed to open the source file"); + + let mut file = GzEncoder::new( + BufWriter::new(File::create(&output_path).expect("Failed to create tgz")), + Compression::default(), + ); + let mut ar = tar::Builder::new(&mut file); + + ar.append_file(input_filename, &mut input_file) + .expect("Failed to add the source file"); + ar.finish().expect("Failed to archive"); + println!("Elapsed: {:?}", start.elapsed()); +}