From 683bc053a5b813909cc7689fbc0ee3ff8d7a75b3 Mon Sep 17 00:00:00 2001 From: Nicholas Cioli Date: Thu, 19 Dec 2024 16:01:32 -0500 Subject: [PATCH 1/3] remove router-bridge Now that the router has updated its MSRV to a version which is not supported by deno, keeping `router-bridge` around breaks the release process for `apollo-composition`. This commit removes it entirely while also bumping the version of rust used by circleci to the latest stable version. --- .circleci/config.yml | 38 +- Cargo.lock | 1477 +------- Cargo.toml | 2 +- router-bridge/.gitignore | 4 - router-bridge/Cargo.toml | 65 - router-bridge/LICENSE | 95 - router-bridge/README.md | 3 - router-bridge/RELEASE_CHECKLIST.md | 53 - router-bridge/benches/query.graphql | 8 - router-bridge/benches/query_planning.rs | 33 - router-bridge/benches/schema.graphql | 275 -- router-bridge/build.rs | 124 - router-bridge/esbuild/buffer_shim.js | 1 - router-bridge/esbuild/bundler.js | 33 - router-bridge/esbuild/url_shim.js | 1 - router-bridge/js-src/api_schema.ts | 52 - router-bridge/js-src/do_api_schema.ts | 24 - router-bridge/js-src/do_introspect.ts | 29 - router-bridge/js-src/index.ts | 3 - router-bridge/js-src/introspection.ts | 104 - router-bridge/js-src/plan.ts | 335 -- router-bridge/js-src/plan_worker.ts | 397 -- router-bridge/js-src/runtime.js | 37 - router-bridge/js-src/supported_features.ts | 36 - .../js-src/test_get_random_values.ts | 26 - router-bridge/js-src/test_logger_worker.ts | 89 - router-bridge/js-src/test_url.ts | 13 - router-bridge/js-src/types.ts | 19 - router-bridge/package-lock.json | 2089 ----------- router-bridge/package.json | 52 - router-bridge/snapshots/.gitignore | 2 - router-bridge/src/api_schema.rs | 84 - router-bridge/src/error.rs | 39 - router-bridge/src/introspect.rs | 320 -- router-bridge/src/js.rs | 186 - router-bridge/src/lib.rs | 13 - router-bridge/src/planner.rs | 2481 ------------- ...r_bridge__api_schema__tests__it_works.snap | 41 - ...pect__tests__defer_in_introspection-2.snap | 6 - ...ospect__tests__defer_in_introspection.snap | 6 - ...r_bridge__introspect__tests__it_works.snap | 7 - .../router_bridge__plan__tests__it_works.snap | 18 - ...nner__error_display__defer_query_plan.snap | 107 - ...r__error_display__defer_with_fragment.snap | 33 - ...display__propagate_internal_qp_errors.snap | 15 - ...nner__error_display__subgraphWithCost.snap | 112 - ...__error_display__subgraphWithListSize.snap | 96 - ...yped_condition_field_merging_disabled.snap | 59 - ...typed_condition_field_merging_enabled.snap | 101 - ...anner__tests__anonymous_query_works-2.snap | 28 - ...planner__tests__anonymous_query_works.snap | 18 - ...er_bridge__planner__tests__api_schema.snap | 205 -- ...ate_query_fragments_defaults_to_false.snap | 19 - ...nerate_query_fragments_explicit_false.snap | 19 - ..._tests__generate_query_fragments_true.snap | 19 - ...anner__tests__get_operation_signature.snap | 6 - ...er_bridge__planner__tests__introspect.snap | 3262 ----------------- ...med_query_with_operation_name_works-2.snap | 28 - ...named_query_with_operation_name_works.snap | 19 - ...ed_query_with_several_choices_works-2.snap | 27 - ...amed_query_with_several_choices_works.snap | 19 - ...__planner__tests__named_query_works-2.snap | 28 - ...ge__planner__tests__named_query_works.snap | 19 - ...dge__planner__tests__planner_update-2.snap | 204 -- ...dge__planner__tests__planner_update-3.snap | 84 - ...dge__planner__tests__planner_update-4.snap | 205 -- ...ridge__planner__tests__planner_update.snap | 24 - ...lanner__tests__progressive_override-2.snap | 53 - ..._planner__tests__progressive_override.snap | 19 - ...euse_query_fragments_defaults_to_true.snap | 18 - ...__reuse_query_fragments_explicit_true.snap | 18 - ...r__tests__reuse_query_fragments_false.snap | 18 - ...r_bridge__planner__tests__subgraphs-2.snap | 154 - ...r_bridge__planner__tests__subgraphs-3.snap | 116 - ...r_bridge__planner__tests__subgraphs-4.snap | 155 - ...r_bridge__planner__tests__subgraphs-5.snap | 205 -- ...r_bridge__planner__tests__subgraphs-6.snap | 221 -- ...ter_bridge__planner__tests__subgraphs.snap | 145 - .../src/testdata/contract_schema.graphql | 64 - .../src/testdata/core_in_v0.1.graphql | 35 - .../src/testdata/custom_cost_schema.graphql | 154 - .../src/testdata/named_query.graphql | 8 - .../src/testdata/no_operation.graphql | 3 - .../src/testdata/progressive_override.graphql | 57 - router-bridge/src/testdata/query.graphql | 8 - router-bridge/src/testdata/query2.graphql | 7 - .../query_generate_query_fragments.graphql | 17 - .../query_reuse_query_fragments.graphql | 15 - ...with_multiple_anonymous_operations.graphql | 16 - .../query_with_multiple_operations.graphql | 16 - router-bridge/src/testdata/schema.graphql | 275 -- .../schema_generate_query_fragments.graphql | 94 - .../schema_reuse_query_fragments.graphql | 60 - .../schema_without_review_body.graphql | 274 -- .../src/testdata/typed_conditions.graphql | 92 - .../src/testdata/unsupported_feature.graphql | 47 - .../unsupported_feature_for_execution.graphql | 49 - .../unsupported_feature_for_security.graphql | 61 - router-bridge/src/worker.rs | 454 --- router-bridge/tsconfig.json | 28 - 100 files changed, 40 insertions(+), 16392 deletions(-) delete mode 100644 router-bridge/.gitignore delete mode 100644 router-bridge/Cargo.toml delete mode 100644 router-bridge/LICENSE delete mode 100644 router-bridge/README.md delete mode 100644 router-bridge/RELEASE_CHECKLIST.md delete mode 100644 router-bridge/benches/query.graphql delete mode 100644 router-bridge/benches/query_planning.rs delete mode 100644 router-bridge/benches/schema.graphql delete mode 100644 router-bridge/build.rs delete mode 100644 router-bridge/esbuild/buffer_shim.js delete mode 100644 router-bridge/esbuild/bundler.js delete mode 100644 router-bridge/esbuild/url_shim.js delete mode 100644 router-bridge/js-src/api_schema.ts delete mode 100644 router-bridge/js-src/do_api_schema.ts delete mode 100644 router-bridge/js-src/do_introspect.ts delete mode 100644 router-bridge/js-src/index.ts delete mode 100644 router-bridge/js-src/introspection.ts delete mode 100644 router-bridge/js-src/plan.ts delete mode 100644 router-bridge/js-src/plan_worker.ts delete mode 100644 router-bridge/js-src/runtime.js delete mode 100644 router-bridge/js-src/supported_features.ts delete mode 100644 router-bridge/js-src/test_get_random_values.ts delete mode 100644 router-bridge/js-src/test_logger_worker.ts delete mode 100644 router-bridge/js-src/test_url.ts delete mode 100644 router-bridge/js-src/types.ts delete mode 100644 router-bridge/package-lock.json delete mode 100644 router-bridge/package.json delete mode 100644 router-bridge/snapshots/.gitignore delete mode 100644 router-bridge/src/api_schema.rs delete mode 100644 router-bridge/src/error.rs delete mode 100644 router-bridge/src/introspect.rs delete mode 100644 router-bridge/src/js.rs delete mode 100644 router-bridge/src/lib.rs delete mode 100644 router-bridge/src/planner.rs delete mode 100644 router-bridge/src/snapshots/router_bridge__api_schema__tests__it_works.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__introspect__tests__defer_in_introspection-2.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__introspect__tests__defer_in_introspection.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__introspect__tests__it_works.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__plan__tests__it_works.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__error_display__defer_query_plan.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__error_display__defer_with_fragment.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__error_display__propagate_internal_qp_errors.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__error_display__subgraphWithCost.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__error_display__subgraphWithListSize.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__error_display__typed_condition_field_merging_disabled.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__error_display__typed_condition_field_merging_enabled.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__anonymous_query_works-2.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__anonymous_query_works.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__api_schema.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_defaults_to_false.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_explicit_false.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_true.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__get_operation_signature.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__introspect.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_operation_name_works-2.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_operation_name_works.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_several_choices_works-2.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_several_choices_works.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__named_query_works-2.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__named_query_works.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-2.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-3.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-4.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__planner_update.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__progressive_override-2.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__progressive_override.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_defaults_to_true.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_explicit_true.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_false.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-2.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-3.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-4.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-5.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-6.snap delete mode 100644 router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs.snap delete mode 100644 router-bridge/src/testdata/contract_schema.graphql delete mode 100644 router-bridge/src/testdata/core_in_v0.1.graphql delete mode 100644 router-bridge/src/testdata/custom_cost_schema.graphql delete mode 100644 router-bridge/src/testdata/named_query.graphql delete mode 100644 router-bridge/src/testdata/no_operation.graphql delete mode 100644 router-bridge/src/testdata/progressive_override.graphql delete mode 100644 router-bridge/src/testdata/query.graphql delete mode 100644 router-bridge/src/testdata/query2.graphql delete mode 100644 router-bridge/src/testdata/query_generate_query_fragments.graphql delete mode 100644 router-bridge/src/testdata/query_reuse_query_fragments.graphql delete mode 100644 router-bridge/src/testdata/query_with_multiple_anonymous_operations.graphql delete mode 100644 router-bridge/src/testdata/query_with_multiple_operations.graphql delete mode 100644 router-bridge/src/testdata/schema.graphql delete mode 100644 router-bridge/src/testdata/schema_generate_query_fragments.graphql delete mode 100644 router-bridge/src/testdata/schema_reuse_query_fragments.graphql delete mode 100644 router-bridge/src/testdata/schema_without_review_body.graphql delete mode 100644 router-bridge/src/testdata/typed_conditions.graphql delete mode 100644 router-bridge/src/testdata/unsupported_feature.graphql delete mode 100644 router-bridge/src/testdata/unsupported_feature_for_execution.graphql delete mode 100644 router-bridge/src/testdata/unsupported_feature_for_security.graphql delete mode 100644 router-bridge/src/worker.rs delete mode 100644 router-bridge/tsconfig.json diff --git a/.circleci/config.yml b/.circleci/config.yml index c46e22a38..4fb53b42e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,7 @@ release: &release branches: ignore: /.*/ tags: # To trigger a release, push a tag with the format `package-name@vversion`. Like `apollo-composition@v0.1.0` - only: /(apollo-federation-types@v.*)|(router-bridge@v.*)|(apollo-composition@v.*)/ + only: /(apollo-federation-types@v.*)|(apollo-composition@v.*)/ parameters: # we can't easily pin on osx @@ -76,9 +76,6 @@ jobs: - run: name: Check Rust lints command: cargo clippy -- -D warnings - - run: - name: Lint JavaScript - command: npm run --prefix router-bridge lint test: parameters: @@ -97,37 +94,13 @@ jobs: executor: minimal_linux steps: - checkout - # this is run in order to create the JavaScript bundles - # that are needed by `cargo publish`, which is only necessary for router-bridge - - when: - condition: - matches: - pattern: ^router-bridge@.* - value: << pipeline.git.tag >> - steps: - - install_system_deps: - platform: minimal_linux - - run: - command: cargo build --release --target $RUSTUP_TARGET - - when: # Don't need Node stuff, just install Rust - condition: - not: - matches: - pattern: ^router-bridge@.* - value: << pipeline.git.tag >> - steps: - - rust/install + - rust/install - run: name: Publish to crates.io command: | # The tag looks like `@v`, but cargo wants `@` CARGO_VERSION=$(echo $CIRCLE_TAG | sed 's/@v/@/') - # If this is router-bridge, we need to `--allow-dirty` for the JavaScript bundle - if [ "$PACKAGE_NAME" == "router-bridge"* ]; then - cargo publish -p $CARGO_VERSION --allow-dirty - else - cargo publish -p $CARGO_VERSION - fi + cargo publish -p $CARGO_VERSION # The machines we use to run our workflows on executors: @@ -212,7 +185,6 @@ commands: command: rustup target add $RUSTUP_TARGET - run: name: Set default rustc version - # router-bridge does not currently work on newer Rust versions command: | - rustup install 1.76.0 - rustup default 1.76.0 \ No newline at end of file + rustup install stable + rustup default stable diff --git a/Cargo.lock b/Cargo.lock index cc44d8170..9f5203b90 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,21 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +version = 4 [[package]] name = "ahash" @@ -45,24 +30,12 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "anes" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" - [[package]] name = "anstyle" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" -[[package]] -name = "anyhow" -version = "1.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" - [[package]] name = "apollo-compiler" version = "1.0.0-beta.24" @@ -104,7 +77,7 @@ dependencies = [ "hashbrown 0.15.2", "http", "indexmap 2.2.6", - "itertools 0.13.0", + "itertools", "lazy_static", "line-col", "multimap", @@ -116,8 +89,8 @@ dependencies = [ "serde", "serde_json", "serde_json_bytes", - "strum 0.26.2", - "strum_macros 0.26.4", + "strum", + "strum_macros", "thiserror", "time", "tracing", @@ -132,7 +105,7 @@ dependencies = [ "log", "rstest", "schemars", - "semver 1.0.17", + "semver", "serde", "serde_json", "serde_with", @@ -160,7 +133,7 @@ checksum = "44055e597c674aef7cb903b2b9f6e4cba1277ed0d2d61dae7cd52d7ffa81f8e2" dependencies = [ "concolor", "unicode-width", - "yansi 1.0.1", + "yansi", ] [[package]] @@ -178,70 +151,12 @@ dependencies = [ "tempfile", ] -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-trait" -version = "0.1.80" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" -dependencies = [ - "addr2line", - "cc", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", -] - -[[package]] -name = "base64-simd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" -dependencies = [ - "outref", - "vsimd", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -285,93 +200,18 @@ version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "bytes" version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" -[[package]] -name = "cast" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" - -[[package]] -name = "cc" -version = "1.0.97" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" - [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "ciborium" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c137568cc60b904a7724001b35ce2630fd00d5d84805fbb608ab89509d788f" -dependencies = [ - "ciborium-io", - "ciborium-ll", - "serde", -] - -[[package]] -name = "ciborium-io" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346de753af073cc87b52b2083a506b38ac176a44cfb05497b622e27be899b369" - -[[package]] -name = "ciborium-ll" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213030a2b5a4e0c0892b6652260cf6ccac84827b83a85a534e178e3906c4cf1b" -dependencies = [ - "ciborium-io", - "half", -] - -[[package]] -name = "clap" -version = "3.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" -dependencies = [ - "bitflags 1.3.2", - "clap_lex", - "indexmap 1.9.2", - "textwrap", -] - -[[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 = "cmake" -version = "0.1.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" -dependencies = [ - "cc", -] - [[package]] name = "concolor" version = "0.1.1" @@ -392,27 +232,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "concurrent-queue" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "console" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "windows-sys 0.42.0", -] - [[package]] name = "convert_case" version = "0.4.0" @@ -434,96 +253,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "criterion" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c76e09c1aae2bc52b3d2f29e13c6572553b30c4aa1b8a49fd70de6412654cb" -dependencies = [ - "anes", - "atty", - "cast", - "ciborium", - "clap", - "criterion-plot", - "futures", - "itertools 0.10.5", - "lazy_static", - "num-traits", - "oorandom", - "plotters", - "rayon", - "regex", - "serde", - "serde_derive", - "serde_json", - "tinytemplate", - "tokio", - "walkdir", -] - -[[package]] -name = "criterion-plot" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" -dependencies = [ - "cast", - "itertools 0.10.5", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2dd04ddaf88237dc3b8d8f9a3c1004b506b54b3313403944054d23c0870c521" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "715e8152b692bba2d374b53d4875445368fdf21a94751410af607a5ac677d1fc" -dependencies = [ - "cfg-if", - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a" -dependencies = [ - "autocfg", - "cfg-if", - "crossbeam-utils", - "memoffset 0.7.1", - "scopeguard", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f" -dependencies = [ - "cfg-if", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -569,138 +298,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "data-encoding" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" - -[[package]] -name = "debugid" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" -dependencies = [ - "serde", - "uuid", -] - -[[package]] -name = "deno-proc-macro-rules" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c65c2ffdafc1564565200967edc4851c7b55422d3913466688907efd05ea26f" -dependencies = [ - "deno-proc-macro-rules-macros", - "proc-macro2", - "syn 2.0.48", -] - -[[package]] -name = "deno-proc-macro-rules-macros" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3047b312b7451e3190865713a4dd6e1f821aed614ada219766ebc3024a690435" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "deno_console" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ab05b798826985966deb29fc6773ed29570de2f2147a30c4289c7cdf635214" -dependencies = [ - "deno_core", -] - -[[package]] -name = "deno_core" -version = "0.200.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8ba264b90ceb6e95b39d82e674d8ecae86ca012f900338ea50d1a077d9d75fd" -dependencies = [ - "anyhow", - "bytes", - "deno_ops", - "futures", - "indexmap 1.9.2", - "libc", - "log", - "once_cell", - "parking_lot", - "pin-project", - "serde", - "serde_json", - "serde_v8", - "smallvec", - "sourcemap", - "tokio", - "url", - "v8", -] - -[[package]] -name = "deno_ops" -version = "0.78.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffd1c83b1fd465ee0156f2917c9af9ca09fe2bf54052a2cae1a8dcbc7b89aefc" -dependencies = [ - "deno-proc-macro-rules", - "lazy-regex", - "once_cell", - "pmutil", - "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "regex", - "strum 0.25.0", - "strum_macros 0.25.2", - "syn 1.0.107", - "syn 2.0.48", - "thiserror", -] - -[[package]] -name = "deno_url" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20490fff3b0f8c176a815e26371ff23313ea7f39cd51057701524c5b6fc36f6c" -dependencies = [ - "deno_core", - "serde", - "urlpattern", -] - -[[package]] -name = "deno_web" -version = "0.146.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dc8dda6e1337d4739ae9e94d75521689824d82a7deb154a2972b6eedac64507" -dependencies = [ - "async-trait", - "base64-simd", - "deno_core", - "encoding_rs", - "flate2", - "serde", - "tokio", - "uuid", - "windows-sys 0.48.0", -] - -[[package]] -name = "deno_webidl" -version = "0.115.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73159d81053ead02e938b46d4bb7224c8e7cf25273ac16a250fb45bb09af7635" -dependencies = [ - "deno_core", -] - [[package]] name = "deranged" version = "0.3.11" @@ -719,16 +316,10 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", + "rustc_version", "syn 1.0.107", ] -[[package]] -name = "diff" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" - [[package]] name = "difflib" version = "0.4.0" @@ -763,21 +354,6 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - -[[package]] -name = "encoding_rs" -version = "0.8.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" -dependencies = [ - "cfg-if", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -794,12 +370,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - [[package]] name = "fastrand" version = "2.1.0" @@ -812,17 +382,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" -[[package]] -name = "flate2" -version = "1.0.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010" -dependencies = [ - "crc32fast", - "libz-ng-sys", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -844,16 +403,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fslock" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57eafdd0c16f57161105ae1b98a1238f97645f2f588438b2949c99a2af9616bf" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "futures" version = "0.3.29" @@ -972,12 +521,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "gimli" -version = "0.28.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" - [[package]] name = "glob" version = "0.3.1" @@ -1008,12 +551,6 @@ dependencies = [ "walkdir", ] -[[package]] -name = "half" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" - [[package]] name = "hashbrown" version = "0.12.3" @@ -1037,61 +574,18 @@ dependencies = [ "foldhash", ] -[[package]] -name = "hdrhistogram" -version = "7.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" -dependencies = [ - "byteorder", - "num-traits", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" -dependencies = [ - "libc", -] - [[package]] name = "hermit-abi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" -[[package]] -name = "home" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" -dependencies = [ - "windows-sys 0.48.0", -] - [[package]] name = "http" version = "0.2.12" @@ -1119,12 +613,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "if_chain" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb56e1aa765b4b4f3aadfab769793b7087bb03a4ea4920644a6d238e2df5b9ed" - [[package]] name = "ignore" version = "0.4.20" @@ -1163,40 +651,17 @@ dependencies = [ "serde", ] -[[package]] -name = "insta" -version = "1.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d64600be34b2fcfc267740a243fa7744441bb4947a619ac4e5bb6507f35fbfc" -dependencies = [ - "console", - "lazy_static", - "linked-hash-map", - "serde", - "similar", - "yaml-rust", -] - [[package]] name = "is-terminal" version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" dependencies = [ - "hermit-abi 0.3.9", + "hermit-abi", "libc", "windows-sys 0.52.0", ] -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - [[package]] name = "itertools" version = "0.13.0" @@ -1234,29 +699,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "lazy-regex" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff63c423c68ea6814b7da9e88ce585f793c87ddd9e78f646970891769c8235d4" -dependencies = [ - "lazy-regex-proc_macros", - "once_cell", - "regex", -] - -[[package]] -name = "lazy-regex-proc_macros" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edfc11b8f56ce85e207e62ea21557cfa09bb24a8f6b04ae181b086ff8611c22" -dependencies = [ - "proc-macro2", - "quote", - "regex", - "syn 1.0.107", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -1269,16 +711,6 @@ version = "0.2.155" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" -[[package]] -name = "libz-ng-sys" -version = "1.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6409efc61b12687963e602df8ecf70e8ddacf95bc6576bcf16e3ac6328083c5" -dependencies = [ - "cmake", - "libc", -] - [[package]] name = "line-col" version = "0.2.1" @@ -1297,80 +729,32 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" -[[package]] -name = "lock_api" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" -[[package]] -name = "matchers" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" -dependencies = [ - "regex-automata 0.1.10", -] - [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" -[[package]] -name = "memoffset" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" -dependencies = [ - "autocfg", -] - [[package]] name = "memoffset" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[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.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ - "adler", + "autocfg", ] [[package]] -name = "mio" -version = "0.8.10" +name = "minimal-lexical" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" -dependencies = [ - "libc", - "wasi", - "windows-sys 0.48.0", -] +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "multimap" @@ -1402,63 +786,12 @@ dependencies = [ "nom", ] -[[package]] -name = "nu-ansi-term" -version = "0.46.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" -dependencies = [ - "overload", - "winapi", -] - -[[package]] -name = "num-bigint" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", - "rand", -] - [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[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-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.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" -dependencies = [ - "hermit-abi 0.2.6", - "libc", -] - [[package]] name = "num_threads" version = "0.1.7" @@ -1468,68 +801,12 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.32.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "oorandom" -version = "11.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" - -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - -[[package]] -name = "outref" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" - -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - -[[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.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-sys 0.42.0", -] - [[package]] name = "percent-encoding" version = "2.2.0" @@ -1593,26 +870,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "pin-project" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.107", -] - [[package]] name = "pin-project-lite" version = "0.2.13" @@ -1625,57 +882,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "plotters" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2538b639e642295546c50fcd545198c9d64ee2a38620a628724a3b266d5fbf97" -dependencies = [ - "num-traits", - "plotters-backend", - "plotters-svg", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "plotters-backend" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193228616381fecdc1224c62e96946dfbc73ff4384fba576e052ff8c1bea8142" - -[[package]] -name = "plotters-svg" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a81d2759aae1dae668f783c308bc5c8ebd191ff4184aaa1b37f65a6ae5a56f" -dependencies = [ - "plotters-backend", -] - -[[package]] -name = "pmutil" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a40bc70c2c58040d2d8b167ba9a5ff59fc9dab7ad44771cfde3dcfde7a09c6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "powerfmt" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "ppv-lite86" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" - [[package]] name = "predicates" version = "3.1.0" @@ -1703,33 +915,13 @@ dependencies = [ "termtree", ] -[[package]] -name = "pretty_assertions" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" -dependencies = [ - "diff", - "yansi 0.5.1", -] - -[[package]] -name = "proc-macro-crate" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" -dependencies = [ - "once_cell", - "toml_edit 0.19.9", -] - [[package]] name = "proc-macro-crate" version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] @@ -1750,67 +942,6 @@ 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.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rayon" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "regex" version = "1.11.1" @@ -1819,17 +950,8 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", -] - -[[package]] -name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.28", + "regex-automata", + "regex-syntax", ] [[package]] @@ -1840,15 +962,9 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] -[[package]] -name = "regex-syntax" -version = "0.6.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" - [[package]] name = "regex-syntax" version = "0.8.5" @@ -1861,33 +977,6 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" -[[package]] -name = "router-bridge" -version = "0.6.2+v2.9.1" -dependencies = [ - "anyhow", - "async-channel", - "criterion", - "deno_console", - "deno_core", - "deno_url", - "deno_web", - "deno_webidl", - "futures", - "insta", - "pretty_assertions", - "rand", - "serde", - "serde_json", - "thiserror", - "tokio", - "tower", - "tower-service", - "tracing", - "tracing-test", - "which", -] - [[package]] name = "rowan" version = "0.15.15" @@ -1896,7 +985,7 @@ checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" dependencies = [ "countme", "hashbrown 0.14.3", - "memoffset 0.9.1", + "memoffset", "rustc-hash", "text-size", ] @@ -1910,7 +999,7 @@ dependencies = [ "futures", "futures-timer", "rstest_macros", - "rustc_version 0.4.0", + "rustc_version", ] [[package]] @@ -1921,44 +1010,29 @@ checksum = "4165dfae59a39dd41d8dec720d3cbfbc71f69744efb480a3920f5d4e0cc6798d" dependencies = [ "cfg-if", "glob", - "proc-macro-crate 3.1.0", + "proc-macro-crate", "proc-macro2", "quote", "regex", "relative-path", - "rustc_version 0.4.0", + "rustc_version", "syn 2.0.48", "unicode-ident", ] -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - [[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.17", + "semver", ] [[package]] @@ -2020,21 +1094,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - -[[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.17" @@ -2044,12 +1103,6 @@ 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.202" @@ -2059,15 +1112,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde_bytes" -version = "0.11.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718dc5fff5b36f99093fc49b280cfc96ce6fc824317783bff5a1fed0c7a64819" -dependencies = [ - "serde", -] - [[package]] name = "serde_derive" version = "1.0.202" @@ -2117,22 +1161,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "serde_v8" -version = "0.111.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "309b3060a9627882514f3a3ce3cc08ceb347a76aeeadc58f138c3f189cf88b71" -dependencies = [ - "bytes", - "derive_more", - "num-bigint", - "serde", - "serde_bytes", - "smallvec", - "thiserror", - "v8", -] - [[package]] name = "serde_with" version = "3.9.0" @@ -2169,79 +1197,23 @@ dependencies = [ ] [[package]] -name = "sha2" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" -dependencies = [ - "cfg-if", - "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 = "similar" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf" - -[[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.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" - -[[package]] -name = "socket2" -version = "0.5.5" +name = "sha2" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ - "libc", - "windows-sys 0.48.0", + "cfg-if", + "cpufeatures", + "digest", ] [[package]] -name = "sourcemap" -version = "6.4.1" +name = "slab" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4cbf65ca7dc576cf50e21f8d0712d96d4fcfd797389744b7b222a85cdf5bd90" +checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" dependencies = [ - "data-encoding", - "debugid", - "if_chain", - "rustc_version 0.2.3", - "serde", - "serde_json", - "unicode-id", - "url", + "autocfg", ] [[package]] @@ -2256,41 +1228,19 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "strum" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" -dependencies = [ - "strum_macros 0.25.2", -] - [[package]] name = "strum" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" -[[package]] -name = "strum_macros" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8d03b598d3d0fff69bf533ee3ef19b8eeb342729596df84bcc7e1f96ec4059" -dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.48", -] - [[package]] name = "strum_macros" version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", @@ -2343,12 +1293,6 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" -[[package]] -name = "textwrap" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "222a222a5bfe1bba4a77b45ec488a741b3cb8872e5e499451fd7d0129c9c7c3d" - [[package]] name = "thiserror" version = "1.0.56" @@ -2399,16 +1343,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" -[[package]] -name = "tinytemplate" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "tinyvec" version = "1.6.0" @@ -2424,66 +1358,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" -[[package]] -name = "tokio" -version = "1.37.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" -dependencies = [ - "backtrace", - "bytes", - "libc", - "mio", - "num_cpus", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.48.0", -] - -[[package]] -name = "tokio-macros" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - -[[package]] -name = "tokio-util" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - [[package]] name = "toml_datetime" version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" -[[package]] -name = "toml_edit" -version = "0.19.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d964908cec0d030b812013af25a0e57fddfadb1e066ecc6681d86253129d4f" -dependencies = [ - "indexmap 1.9.2", - "toml_datetime", - "winnow 0.4.6", -] - [[package]] name = "toml_edit" version = "0.21.1" @@ -2492,49 +1372,15 @@ checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ "indexmap 2.2.6", "toml_datetime", - "winnow 0.5.40", -] - -[[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 1.9.2", - "pin-project", - "pin-project-lite", - "rand", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", + "winnow", ] -[[package]] -name = "tower-layer" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" - -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - [[package]] name = "tracing" version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ - "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -2558,59 +1404,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", - "valuable", -] - -[[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-subscriber" -version = "0.3.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70" -dependencies = [ - "matchers", - "nu-ansi-term", - "once_cell", - "regex", - "sharded-slab", - "smallvec", - "thread_local", - "tracing", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "tracing-test" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e3d272c44878d2bbc9f4a20ad463724f03e19dbc667c6e84ac433ab7ffcc70b" -dependencies = [ - "lazy_static", - "tracing-core", - "tracing-subscriber", - "tracing-test-macro", -] - -[[package]] -name = "tracing-test-macro" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744324b12d69a9fc1edea4b38b7b1311295b662d161ad5deac17bb1358224a08" -dependencies = [ - "lazy_static", - "quote", - "syn 1.0.107", ] [[package]] @@ -2641,59 +1434,12 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-ucd-ident" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - [[package]] name = "unicode-bidi" version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d54675592c1dbefd78cbd98db9bacd89886e1ca50692a0692baefffdeb92dd58" -[[package]] -name = "unicode-id" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b6def86329695390197b82c1e244a54a131ceb66c996f2088a3876e2ae083f" - [[package]] name = "unicode-ident" version = "1.0.6" @@ -2727,19 +1473,6 @@ dependencies = [ "serde", ] -[[package]] -name = "urlpattern" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9bd5ff03aea02fa45b13a7980151fe45009af1980ba69f651ec367121a31609" -dependencies = [ - "derive_more", - "regex", - "serde", - "unic-ucd-ident", - "url", -] - [[package]] name = "uuid" version = "1.8.0" @@ -2751,36 +1484,12 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "v8" -version = "0.74.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eedac634b8dd39b889c5b62349cbc55913780226239166435c5cf66771792ea" -dependencies = [ - "bitflags 1.3.2", - "fslock", - "once_cell", - "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 = "vsimd" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" - [[package]] name = "walkdir" version = "2.3.2" @@ -2852,28 +1561,6 @@ version = "0.2.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" -[[package]] -name = "web-sys" -version = "0.3.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "which" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" -dependencies = [ - "either", - "home", - "once_cell", - "rustix", -] - [[package]] name = "winapi" version = "0.3.9" @@ -2905,21 +1592,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -2929,15 +1601,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.0", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -2962,21 +1625,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", -] - [[package]] name = "windows-targets" version = "0.52.0" @@ -2998,12 +1646,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.0" @@ -3016,12 +1658,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - [[package]] name = "windows_aarch64_msvc" version = "0.52.0" @@ -3034,12 +1670,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - [[package]] name = "windows_i686_gnu" version = "0.52.0" @@ -3052,12 +1682,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - [[package]] name = "windows_i686_msvc" version = "0.52.0" @@ -3070,12 +1694,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - [[package]] name = "windows_x86_64_gnu" version = "0.52.0" @@ -3088,12 +1706,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.0" @@ -3106,27 +1718,12 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - [[package]] name = "windows_x86_64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" -[[package]] -name = "winnow" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.5.40" @@ -3145,12 +1742,6 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "yansi" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" - [[package]] name = "yansi" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 7065b4c47..ed9d71b99 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,3 +1,3 @@ [workspace] -members = ["apollo-federation-types", "apollo-composition", "router-bridge"] +members = ["apollo-federation-types", "apollo-composition"] resolver = "2" diff --git a/router-bridge/.gitignore b/router-bridge/.gitignore deleted file mode 100644 index 874afaf00..000000000 --- a/router-bridge/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -js-dist/ -bundled/ -node_modules/ -tsconfig.tsbuildinfo diff --git a/router-bridge/Cargo.toml b/router-bridge/Cargo.toml deleted file mode 100644 index 5ccfb0fb6..000000000 --- a/router-bridge/Cargo.toml +++ /dev/null @@ -1,65 +0,0 @@ -[package] -name = "router-bridge" -version = "0.6.2+v2.9.1" -authors = ["Apollo "] -edition = "2018" -description = "JavaScript bridge for the Apollo Router" -homepage = "https://www.apollographql.com/apollo-federation/" -documentation = "https://apollographql.com/docs/federation/" -repository = "https://github.com/apollographql/federation/" - -license = "Elastic-2.0" -readme = "README.md" - -include = [ - "bundled/**/*", - "src/**/*", - "benches/", - "Cargo.toml", - "build.rs", - "LICENSE", -] - -[dependencies] -anyhow = "1.0.79" -async-channel = "1.9.0" -deno_console = "0.115.0" -deno_core = "0.200.0" -deno_url = "0.115.0" -deno_web = "0.146.0" -deno_webidl = "0.115.0" -rand = "0.8.5" -serde = { version = "1.0.195", features = ["derive"] } -serde_json = { version = "1.0.111", features = ["preserve_order"] } -thiserror = "1.0.56" -tokio = { version = "1.35.1", features = ["full"] } -tower = { version = "0.4.13", features = ["full"] } -tower-service = "0.3.2" -tracing = "0.1.33" - -[dev-dependencies] -futures = "0.3.29" -insta = { version = "1.34.0", features = ["json"] } -pretty_assertions = "1.4.0" -tracing-test = "0.2.1" -criterion = { version = "0.4", features = ["async_tokio", "async_futures"] } - -[build-dependencies] -deno_console = "0.115.0" -deno_core = "0.200.0" -deno_url = "0.115.0" -deno_web = "0.146.0" -deno_webidl = "0.115.0" -which = "4.4.2" - -[features] -# "fake" feature to disable V8 usage when building on docs.rs -# See ./build.rs -docs_rs = [] - -[package.metadata.docs.rs] -features = ["docs_rs"] - -[[bench]] -name = "query_planning" -harness = false diff --git a/router-bridge/LICENSE b/router-bridge/LICENSE deleted file mode 100644 index a52b6ff1a..000000000 --- a/router-bridge/LICENSE +++ /dev/null @@ -1,95 +0,0 @@ -Copyright 2021 Apollo Graph, Inc. - -Elastic License 2.0 - -## Acceptance - -By using the software, you agree to all of the terms and conditions below. - -## Copyright License - -The licensor grants you a non-exclusive, royalty-free, worldwide, -non-sublicensable, non-transferable license to use, copy, distribute, make -available, and prepare derivative works of the software, in each case subject to -the limitations and conditions below. - -## Limitations - -You may not provide the software to third parties as a hosted or managed -service, where the service provides users with access to any substantial set of -the features or functionality of the software. - -You may not move, change, disable, or circumvent the license key functionality -in the software, and you may not remove or obscure any functionality in the -software that is protected by the license key. - -You may not alter, remove, or obscure any licensing, copyright, or other notices -of the licensor in the software. Any use of the licensor’s trademarks is subject -to applicable law. - -## Patents - -The licensor grants you a license, under any patent claims the licensor can -license, or becomes able to license, to make, have made, use, sell, offer for -sale, import and have imported the software, in each case subject to the -limitations and conditions in this license. This license does not cover any -patent claims that you cause to be infringed by modifications or additions to -the software. If you or your company make any written claim that the software -infringes or contributes to infringement of any patent, your patent license for -the software granted under these terms ends immediately. If your company makes -such a claim, your patent license ends immediately for work on behalf of your -company. - -## Notices - -You must ensure that anyone who gets a copy of any part of the software from you -also gets a copy of these terms. - -If you modify the software, you must include in any modified copies of the -software prominent notices stating that you have modified the software. - -## No Other Rights - -These terms do not imply any licenses other than those expressly granted in -these terms. - -## Termination - -If you use the software in violation of these terms, such use is not licensed, -and your licenses will automatically terminate. If the licensor provides you -with a notice of your violation, and you cease all violation of this license no -later than 30 days after you receive that notice, your licenses will be -reinstated retroactively. However, if you violate these terms after such -reinstatement, any additional violation of these terms will cause your licenses -to terminate automatically and permanently. - -## No Liability - -*As far as the law allows, the software comes as is, without any warranty or -condition, and the licensor will not be liable to you for any damages arising -out of these terms or the use or nature of the software, under any kind of -legal claim.* - -## Definitions - -The **licensor** is the entity offering these terms, and the **software** is the -software the licensor makes available under these terms, including any portion -of it. - -**you** refers to the individual or entity agreeing to these terms. - -**your company** is any legal entity, sole proprietorship, or other kind of -organization that you work for, plus all organizations that have control over, -are under the control of, or are under common control with that -organization. **control** means ownership of substantially all the assets of an -entity, or the power to direct its management and policies by vote, contract, or -otherwise. Control can be direct or indirect. - -**your licenses** are all the licenses granted to you for the software under -these terms. - -**use** means anything you do with the software requiring one of your licenses. - -**trademark** means trademarks, service marks, and similar rights. - --------------------------------------------------------------------------------- diff --git a/router-bridge/README.md b/router-bridge/README.md deleted file mode 100644 index cb67be0f1..000000000 --- a/router-bridge/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# router-bridge - -This crate is not intended for public consumption. diff --git a/router-bridge/RELEASE_CHECKLIST.md b/router-bridge/RELEASE_CHECKLIST.md deleted file mode 100644 index 81b79625f..000000000 --- a/router-bridge/RELEASE_CHECKLIST.md +++ /dev/null @@ -1,53 +0,0 @@ -# Release Checklist - -This is a list of the things that need to happen when publishing `router-bridge`. - -## Build a Release - -### Changelog - -None of the `federation-rs` packages currently maintain changelogs as they are largely mirrors of upstream packages. -You're off the hook! - -### Start a release PR - -1. Make sure you have both `npm` and `cargo` installed on your machine and in your `PATH`. -1. Run `ROUTERBRIDGE_RELEASE_VERSION=router-bridge@v{version}` where `{version}` is the new version you're bumping to. -1. Run `git checkout main && git stash && git pull && git checkout -b $ROUTERBRIDGE_RELEASE_VERSION`. -1. Update the version of `@apollo/federation-internals` and `@apollo/query-planner` in the `package.json`. -1. Then run `npm install` from the `router-bridge` directory to let it update the `package-lock.json`. -1. Update the version of `router-bridge` in `Cargo.toml` -1. Run `cargo build -p router-bridge` -1. Push up a commit containing the version bumps with the - message `Automated PR for router-bridge release: $ROUTERBRIDGE_RELEASE_VERSION` -1. Wait for tests to pass on the PR -1. Merge your PR to `main` - -### Build and tag release - -1. Once merged, run `git checkout main && git pull` -2. Return to the root of the repository if you're not already there. -3. Run `git tag -a $ROUTERBRIDGE_RELEASE_VERSION -m $ROUTERBRIDGE_RELEASE_VERSION` -4. Run `git push origin /refs/tags/$ROUTERBRIDGE_RELEASE_VERSION` -5. Wait for CI to build and publish `router-bridge` to crates.io. - -## Troubleshooting a release - -Mistakes happen. Most of these release steps are recoverable if you mess up. - -### I pushed the wrong tag - -Tags and releases can be removed in GitHub. -First, [remove the remote tag](https://stackoverflow.com/questions/5480258/how-to-delete-a-remote-tag): - -```console -git push --delete origin $ROUTERBRIDGE_RELEASE_VERSION -``` - -This will turn the release into a `draft` and you can delete it from the edit page. - -Make sure you also delete the local tag: - -```console -git tag --delete $ROUTERBRIDGE_RELEASE_VERSION -``` diff --git a/router-bridge/benches/query.graphql b/router-bridge/benches/query.graphql deleted file mode 100644 index 3e1ed3803..000000000 --- a/router-bridge/benches/query.graphql +++ /dev/null @@ -1,8 +0,0 @@ -query { - me { - name { - first - last - } - } -} diff --git a/router-bridge/benches/query_planning.rs b/router-bridge/benches/query_planning.rs deleted file mode 100644 index a8ec2ae7a..000000000 --- a/router-bridge/benches/query_planning.rs +++ /dev/null @@ -1,33 +0,0 @@ -use criterion::criterion_group; -use criterion::criterion_main; -use criterion::Criterion; -use router_bridge::planner::PlanOptions; -use router_bridge::planner::Planner; -use router_bridge::planner::QueryPlannerConfig; - -const QUERY: &str = include_str!("query.graphql"); -const SCHEMA: &str = include_str!("schema.graphql"); - -fn from_elem(c: &mut Criterion) { - c.bench_function("query_planning", move |b| { - let runtime = tokio::runtime::Runtime::new().unwrap(); - - let planner = runtime.block_on(async { - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap() - }); - - b.to_async(runtime).iter(|| async { - planner - .plan(QUERY.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap(); - }); - }); -} - -criterion_group!(benches, from_elem); -criterion_main!(benches); diff --git a/router-bridge/benches/schema.graphql b/router-bridge/benches/schema.graphql deleted file mode 100644 index 229cac4eb..000000000 --- a/router-bridge/benches/schema.graphql +++ /dev/null @@ -1,275 +0,0 @@ -schema - @core(feature: "https://specs.apollo.dev/core/v0.1") - @core(feature: "https://specs.apollo.dev/join/v0.1") { - query: Query - mutation: Mutation -} - -directive @core(feature: String!) repeatable on SCHEMA - -directive @join__field( - graph: join__Graph - requires: join__FieldSet - provides: join__FieldSet -) on FIELD_DEFINITION - -directive @join__type( - graph: join__Graph! - key: join__FieldSet -) repeatable on OBJECT | INTERFACE - -directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -union AccountType = PasswordAccount | SMSAccount - -type Amazon { - referrer: String -} - -union Body = Image | Text - -type Book implements Product - @join__owner(graph: BOOKS) - @join__type(graph: BOOKS, key: "isbn") - @join__type(graph: INVENTORY, key: "isbn") - @join__type(graph: PRODUCT, key: "isbn") - @join__type(graph: REVIEWS, key: "isbn") { - isbn: String! @join__field(graph: BOOKS) - title: String @join__field(graph: BOOKS) - year: Int @join__field(graph: BOOKS) - similarBooks: [Book]! @join__field(graph: BOOKS) - metadata: [MetadataOrError] @join__field(graph: BOOKS) - inStock: Boolean @join__field(graph: INVENTORY) - isCheckedOut: Boolean @join__field(graph: INVENTORY) - upc: String! @join__field(graph: PRODUCT) - sku: String! @join__field(graph: PRODUCT) - name(delimeter: String = " "): String - @join__field(graph: PRODUCT, requires: "title year") - price: String @join__field(graph: PRODUCT) - details: ProductDetailsBook @join__field(graph: PRODUCT) - reviews: [Review] @join__field(graph: REVIEWS) - relatedReviews: [Review!]! - @join__field(graph: REVIEWS, requires: "similarBooks{isbn}") -} - -union Brand = Ikea | Amazon - -type Car implements Vehicle - @join__owner(graph: PRODUCT) - @join__type(graph: PRODUCT, key: "id") - @join__type(graph: REVIEWS, key: "id") { - id: String! @join__field(graph: PRODUCT) - description: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - retailPrice: String @join__field(graph: REVIEWS, requires: "price") -} - -type Error { - code: Int - message: String -} - -type Furniture implements Product - @join__owner(graph: PRODUCT) - @join__type(graph: PRODUCT, key: "upc") - @join__type(graph: PRODUCT, key: "sku") - @join__type(graph: INVENTORY, key: "sku") - @join__type(graph: REVIEWS, key: "upc") { - upc: String! @join__field(graph: PRODUCT) - sku: String! @join__field(graph: PRODUCT) - name: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - brand: Brand @join__field(graph: PRODUCT) - metadata: [MetadataOrError] @join__field(graph: PRODUCT) - details: ProductDetailsFurniture @join__field(graph: PRODUCT) - inStock: Boolean @join__field(graph: INVENTORY) - isHeavy: Boolean @join__field(graph: INVENTORY) - reviews: [Review] @join__field(graph: REVIEWS) -} - -type Ikea { - asile: Int -} - -type Image implements NamedObject { - name: String! - attributes: ImageAttributes! -} - -type ImageAttributes { - url: String! -} - -scalar join__FieldSet - -enum join__Graph { - ACCOUNTS @join__graph(name: "accounts", url: "") - BOOKS @join__graph(name: "books", url: "") - DOCUMENTS @join__graph(name: "documents", url: "") - INVENTORY @join__graph(name: "inventory", url: "") - PRODUCT @join__graph(name: "product", url: "") - REVIEWS @join__graph(name: "reviews", url: "") -} - -type KeyValue { - key: String! - value: String! -} - -type Library - @join__owner(graph: BOOKS) - @join__type(graph: BOOKS, key: "id") - @join__type(graph: ACCOUNTS, key: "id") { - id: ID! @join__field(graph: BOOKS) - name: String @join__field(graph: BOOKS) - userAccount(id: ID! = 1): User @join__field(graph: ACCOUNTS, requires: "name") -} - -union MetadataOrError = KeyValue | Error - -type Mutation { - login(username: String!, password: String!): User - @join__field(graph: ACCOUNTS) - reviewProduct(upc: String!, body: String!): Product - @join__field(graph: REVIEWS) - updateReview(review: UpdateReviewInput!): Review @join__field(graph: REVIEWS) - deleteReview(id: ID!): Boolean @join__field(graph: REVIEWS) -} - -type Name { - first: String - last: String -} - -interface NamedObject { - name: String! -} - -type PasswordAccount - @join__owner(graph: ACCOUNTS) - @join__type(graph: ACCOUNTS, key: "email") { - email: String! @join__field(graph: ACCOUNTS) -} - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean - reviews: [Review] -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String - pages: Int -} - -type ProductDetailsFurniture implements ProductDetails { - country: String - color: String -} - -type Query { - user(id: ID!): User @join__field(graph: ACCOUNTS) - me: User @join__field(graph: ACCOUNTS) - book(isbn: String!): Book @join__field(graph: BOOKS) - books: [Book] @join__field(graph: BOOKS) - library(id: ID!): Library @join__field(graph: BOOKS) - body: Body! @join__field(graph: DOCUMENTS) - product(upc: String!): Product @join__field(graph: PRODUCT) - vehicle(id: String!): Vehicle @join__field(graph: PRODUCT) - topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCT) - topCars(first: Int = 5): [Car] @join__field(graph: PRODUCT) - topReviews(first: Int = 5): [Review] @join__field(graph: REVIEWS) -} - -type Review - @join__owner(graph: REVIEWS) - @join__type(graph: REVIEWS, key: "id") { - id: ID! @join__field(graph: REVIEWS) - body(format: Boolean = false): String @join__field(graph: REVIEWS) - author: User @join__field(graph: REVIEWS, provides: "username") - product: Product @join__field(graph: REVIEWS) - metadata: [MetadataOrError] @join__field(graph: REVIEWS) -} - -type SMSAccount - @join__owner(graph: ACCOUNTS) - @join__type(graph: ACCOUNTS, key: "number") { - number: String @join__field(graph: ACCOUNTS) -} - -type Text implements NamedObject { - name: String! - attributes: TextAttributes! -} - -type TextAttributes { - bold: Boolean - text: String -} - -union Thing = Car | Ikea - -input UpdateReviewInput { - id: ID! - body: String -} - -type User - @join__owner(graph: ACCOUNTS) - @join__type(graph: ACCOUNTS, key: "id") - @join__type(graph: ACCOUNTS, key: "username name{first last}") - @join__type(graph: INVENTORY, key: "id") - @join__type(graph: PRODUCT, key: "id") - @join__type(graph: REVIEWS, key: "id") { - id: ID! @join__field(graph: ACCOUNTS) - name: Name @join__field(graph: ACCOUNTS) - username: String @join__field(graph: ACCOUNTS) - birthDate(locale: String): String @join__field(graph: ACCOUNTS) - account: AccountType @join__field(graph: ACCOUNTS) - metadata: [UserMetadata] @join__field(graph: ACCOUNTS) - goodDescription: Boolean - @join__field(graph: INVENTORY, requires: "metadata{description}") - vehicle: Vehicle @join__field(graph: PRODUCT) - thing: Thing @join__field(graph: PRODUCT) - reviews: [Review] @join__field(graph: REVIEWS) - numberOfReviews: Int! @join__field(graph: REVIEWS) - goodAddress: Boolean - @join__field(graph: REVIEWS, requires: "metadata{address}") -} - -type UserMetadata { - name: String - address: String - description: String -} - -type Van implements Vehicle - @join__owner(graph: PRODUCT) - @join__type(graph: PRODUCT, key: "id") - @join__type(graph: REVIEWS, key: "id") { - id: String! @join__field(graph: PRODUCT) - description: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - retailPrice: String @join__field(graph: REVIEWS, requires: "price") -} - -interface Vehicle { - id: String! - description: String - price: String - retailPrice: String -} diff --git a/router-bridge/build.rs b/router-bridge/build.rs deleted file mode 100644 index 9cfa28f92..000000000 --- a/router-bridge/build.rs +++ /dev/null @@ -1,124 +0,0 @@ -use std::path::{Path, PathBuf}; -use std::process::Command; - -fn main() { - // only do `npm` related stuff if we're _not_ publishing to crates.io - if std::fs::metadata("./package.json").is_ok() { - println!("cargo:rerun-if-changed=js-src"); - - let current_dir = std::env::current_dir().unwrap(); - - update_bridge(¤t_dir); - } else { - // the crate has been published, no need to rerun - println!("cargo:rerun-if-changed=build.rs"); - } - - let out_dir: PathBuf = std::env::var_os("OUT_DIR") - .expect("$OUT_DIR not set.") - .into(); - - create_snapshot(&out_dir); -} - -fn update_bridge(current_dir: &Path) { - println!("cargo:warning=Updating router-bridge"); - let npm = which::which("npm").expect("'npm' is not available"); - - if cfg!(debug_assertions) { - // in debug mode we want to update the package-lock.json - // so we run `npm install` - println!("cargo:warning=running `npm install`"); - assert!(Command::new(&npm) - .current_dir(current_dir) - .args(["install"]) - .status() - .unwrap() - .success()); - } else { - // in release mode, we're probably running in CI - // and want the version we publish to match - // the git source - // so we run `npm ci`. - println!("cargo:warning=running `npm ci`"); - assert!(Command::new(&npm) - .current_dir(current_dir) - .args(["ci"]) - .status() - .unwrap() - .success()); - } - - println!("cargo:warning=running `npm run format`"); - assert!(Command::new(&npm) - .current_dir(current_dir) - .args(["run", "format"]) - .status() - .unwrap() - .success()); - - println!("cargo:warning=running `npm run build`"); - assert!(Command::new(&npm) - .current_dir(current_dir) - .args(["run", "build"]) - .status() - .unwrap() - .success()); -} - -#[cfg(any(feature = "docs_rs", all(target_os = "macos", target_arch = "x86_64")))] -fn create_snapshot(out_dir: &Path) { - // If we're building on docs.rs we just create - // an empty snapshot file and return, because `rusty_v8` - // doesn't actually compile on docs.rs - std::fs::write(out_dir.join("query_runtime.snap"), []).unwrap(); -} - -#[cfg(not(any(feature = "docs_rs", all(target_os = "macos", target_arch = "x86_64"))))] -fn create_snapshot(out_dir: &Path) { - use deno_core::{JsRuntimeForSnapshot, RuntimeOptions}; - use std::fs::{read_to_string, File}; - use std::io::Write; - - let options = RuntimeOptions { - extensions: vec![ - deno_webidl::deno_webidl::init_ops(), - deno_console::deno_console::init_ops(), - deno_url::deno_url::init_ops(), - deno_web::deno_web::init_ops::(Default::default(), Default::default()), - ], - ..Default::default() - }; - let mut runtime = JsRuntimeForSnapshot::new(options); - - // The runtime automatically contains a Deno.core object with several - // functions for interacting with it. - let runtime_str = read_to_string("bundled/runtime.js").unwrap(); - runtime - .execute_script("", deno_core::FastString::Owned(runtime_str.into())) - .expect("unable to initialize router bridge runtime environment"); - - // Load the composition library. - let bridge_str = read_to_string("bundled/bridge.js").unwrap(); - runtime - .execute_script("bridge.js", deno_core::FastString::Owned(bridge_str.into())) - .expect("unable to evaluate bridge module"); - - // Create our base query snapshot which will be included in - // src/js.rs to initialise our JsRuntime(). - let mut snap = File::create(out_dir.join("query_runtime.snap")).unwrap(); - snap.write_all(&runtime.snapshot()).unwrap(); -} - -#[derive(Clone)] -struct Permissions; - -impl deno_web::TimersPermission for Permissions { - fn allow_hrtime(&mut self) -> bool { - unreachable!("snapshotting!") - } - - fn check_unstable(&self, _state: &deno_core::OpState, _api_name: &'static str) { - unreachable!("snapshotting!") - } -} diff --git a/router-bridge/esbuild/buffer_shim.js b/router-bridge/esbuild/buffer_shim.js deleted file mode 100644 index b8ae18fa1..000000000 --- a/router-bridge/esbuild/buffer_shim.js +++ /dev/null @@ -1 +0,0 @@ -globalThis.buffer_shim = require("buffer").Buffer; diff --git a/router-bridge/esbuild/bundler.js b/router-bridge/esbuild/bundler.js deleted file mode 100644 index 1dd9a3aac..000000000 --- a/router-bridge/esbuild/bundler.js +++ /dev/null @@ -1,33 +0,0 @@ -let denoFsPlugin = { - name: "fs", - setup(build) { - // Intercept require("fs") and replace it with shims - build.onResolve({ filter: /^fs$/ }, (args) => ({ - path: args.path, - namespace: "deno-fs", - })); - - build.onLoad({ filter: /.*/, namespace: "deno-fs" }, () => ({ - contents: - "module.exports = { existsSync: Deno.ensureFileSync, writeFileSync: Deno.writeTextFile }", - loader: "js", - })); - }, -}; - -// all paths are relative to package.json when run with `npm run build` -require("esbuild") - .build({ - entryPoints: ["./js-dist/index.js"], - bundle: true, - minify: true, - sourcemap: true, - target: "es2020", - globalName: "bridge", - outfile: "./bundled/bridge.js", - format: "iife", - plugins: [denoFsPlugin], - define: { Buffer: "buffer_shim" }, - inject: ["./esbuild/buffer_shim.js", "./esbuild/url_shim.js"], - }) - .catch(() => process.exit(1)); diff --git a/router-bridge/esbuild/url_shim.js b/router-bridge/esbuild/url_shim.js deleted file mode 100644 index 160142b5f..000000000 --- a/router-bridge/esbuild/url_shim.js +++ /dev/null @@ -1 +0,0 @@ -globalThis.URL = require("url").URL; diff --git a/router-bridge/js-src/api_schema.ts b/router-bridge/js-src/api_schema.ts deleted file mode 100644 index 3fa71145f..000000000 --- a/router-bridge/js-src/api_schema.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { - buildSchema as buildGraphqlSchema, - ExecutionResult, - GraphQLError, - printSchema, -} from "graphql"; - -import { Supergraph } from "@apollo/federation-internals"; -import { ROUTER_SUPPORTED_SUPERGRAPH_FEATURES } from "./supported_features"; - -export interface ApiSchemaOptions { - graphqlValidation?: boolean; -} - -export function apiSchema( - sdl: string, - options: ApiSchemaOptions = {} -): ExecutionResult { - let schema: String; - - const validate = options.graphqlValidation ?? true; - if (validate) { - try { - // First go through regular schema parsing - buildGraphqlSchema(sdl); - } catch (e) { - return { - errors: [e], - }; - } - } - - try { - // Now try to get the API schema - let supergraph = Supergraph.build(sdl, { - supportedFeatures: ROUTER_SUPPORTED_SUPERGRAPH_FEATURES, - }); - - let apiSchema = supergraph.apiSchema(); - schema = printSchema(apiSchema.toGraphQLJSSchema()); - } catch (e) { - return { - errors: [e], - }; - } - if (!schema) { - return { - errors: [new GraphQLError("couldn't build api schema from SDL")], - }; - } - return { data: schema, errors: [] }; -} diff --git a/router-bridge/js-src/do_api_schema.ts b/router-bridge/js-src/do_api_schema.ts deleted file mode 100644 index 4d5d17f60..000000000 --- a/router-bridge/js-src/do_api_schema.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { apiSchema } from "."; -import type { OperationResult } from "./types"; - -/** - * There are several global properties that we make available in our V8 runtime - * and these are the types for those that we expect to use within this script. - * They'll be stripped in the emitting of this file as JS, of course. - */ -declare let bridge: { apiSchema: typeof apiSchema }; - -declare let sdl: string; -declare let graphqlValidation: boolean | undefined; - -const result = bridge.apiSchema(sdl, { graphqlValidation }); - -let opResult: OperationResult; -if (result.errors?.length > 0) { - opResult = { Err: result.errors }; -} else { - opResult = { Ok: result.data }; -} -// The JsRuntime::execute_script Rust function will return this top-level value, -// because it is the final completion value of the current script. -opResult; diff --git a/router-bridge/js-src/do_introspect.ts b/router-bridge/js-src/do_introspect.ts deleted file mode 100644 index 153eab8bc..000000000 --- a/router-bridge/js-src/do_introspect.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { batchIntrospect } from "."; -import type { OperationResult, QueryPlannerConfigExt } from "./types"; - -/** - * There are several global properties that we make available in our V8 runtime - * and these are the types for those that we expect to use within this script. - * They'll be stripped in the emitting of this file as JS, of course. - */ -declare let bridge: { batchIntrospect: typeof batchIntrospect }; - -declare let sdl: string; -declare let queries: string[]; -declare let config: QueryPlannerConfigExt; - -let opResult: OperationResult; -if (!sdl) { - opResult = { - Err: [{ message: "Error in JS-Rust-land: SDL is empty." }], - }; -} else { - try { - opResult = { Ok: bridge.batchIntrospect(sdl, queries, config) }; - } catch (err) { - opResult = { Err: err }; - } -} -// The JsRuntime::execute_script Rust function will return this top-level value, -// because it is the final completion value of the current script. -opResult; diff --git a/router-bridge/js-src/index.ts b/router-bridge/js-src/index.ts deleted file mode 100644 index 3f35cbe3c..000000000 --- a/router-bridge/js-src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export { apiSchema } from "./api_schema"; -export { introspect, batchIntrospect } from "./introspection"; -export { BridgeQueryPlanner } from "./plan"; diff --git a/router-bridge/js-src/introspection.ts b/router-bridge/js-src/introspection.ts deleted file mode 100644 index 9821c60f0..000000000 --- a/router-bridge/js-src/introspection.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { - buildSchema as gqlBuildSchema, - ExecutionResult, - GraphQLError, - GraphQLSchema, - graphqlSync, -} from "graphql"; - -import { buildSchema } from "@apollo/federation-internals"; -import { QueryPlannerConfigExt } from "./types"; - -export function batchIntrospect( - sdl: string, - queries: string[], - options: QueryPlannerConfigExt -): ExecutionResult[] { - let schema: GraphQLSchema; - - const validate = options.graphqlValidation ?? true; - if (validate) { - try { - // First go through regular schema parsing - gqlBuildSchema(sdl); - } catch (err) { - return Array(queries.length).fill({ - errors: [Object.assign(err, { validationError: true })], - }); - } - } - - try { - // First go through regular schema parsing - gqlBuildSchema(sdl); - - // Now try to get the API schema - let composedSchema = buildSchema(sdl); - let apiSchema = composedSchema.toAPISchema(); - schema = apiSchema.toGraphQLJSSchema({ - includeDefer: options.incrementalDelivery?.enableDefer, - }); - } catch (e) { - return Array(queries.length).fill({ - errors: [e], - }); - } - if (!schema) { - return Array(queries.length).fill({ - errors: [new Error(`couldn't build schema from SDL`)], - }); - } - return queries.map((query) => introspectOne(schema, query)); -} - -export function introspect( - sdl: string, - query: string, - options: QueryPlannerConfigExt -): ExecutionResult { - let schema: GraphQLSchema; - - const validate = options.graphqlValidation ?? true; - if (validate) { - try { - // First go through regular schema parsing - gqlBuildSchema(sdl); - } catch (err) { - return { - errors: [Object.assign(err, { validationError: true })], - }; - } - } - - try { - // Now try to get the API schema - let composedSchema = buildSchema(sdl); - let apiSchema = composedSchema.toAPISchema(); - schema = apiSchema.toGraphQLJSSchema({ - includeDefer: options.incrementalDelivery?.enableDefer, - }); - } catch (e) { - return { - errors: [e], - }; - } - if (!schema) { - return { - errors: [new GraphQLError("couldn't build schema from SDL")], - }; - } - return introspectOne(schema, query); -} - -const introspectOne = ( - schema: GraphQLSchema, - query: string -): ExecutionResult => { - const { data, errors } = graphqlSync({ schema, source: query }); - - if (errors) { - return { data, errors: [...errors] }; - } else { - return { data, errors: [] }; - } -}; diff --git a/router-bridge/js-src/plan.ts b/router-bridge/js-src/plan.ts deleted file mode 100644 index 31a65de74..000000000 --- a/router-bridge/js-src/plan.ts +++ /dev/null @@ -1,335 +0,0 @@ -import { - prettyFormatQueryPlan, - QueryPlan, - QueryPlanner, - QueryPlannerConfig, -} from "@apollo/query-planner"; -import { - DocumentNode, - ExecutionResult, - GraphQLError, - GraphQLSchema, - parse, - validate, - printSchema, - graphqlSync, -} from "graphql"; - -import { - Operation, - operationFromDocument, - printSchema as printSchemaWithDirectives, - Supergraph, -} from "@apollo/federation-internals"; -import { - calculateReferencedFieldsByType, - usageReportingSignature, -} from "@apollo/utils.usagereporting"; -import { ReferencedFieldsForType } from "@apollo/usage-reporting-protobuf"; -import { QueryPlannerConfigExt } from "./types"; -import { ROUTER_SUPPORTED_SUPERGRAPH_FEATURES } from "./supported_features"; - -const PARSE_FAILURE: string = "## GraphQLParseFailure\n"; -const PARSE_FAILURE_EXT_CODE: string = "GRAPHQL_PARSE_FAILED"; -const VALIDATION_FAILURE: string = "## GraphQLValidationFailure\n"; -const VALIDATION_FAILURE_EXT_CODE: string = "GRAPHQL_VALIDATION_FAILED"; -const UNKNOWN_OPERATION: string = "## GraphQLUnknownOperationName\n"; - -export type ReferencedFieldsByType = Record; - -export type UsageReporting = { - statsReportKey: string; - referencedFieldsByType: ReferencedFieldsByType; -}; - -export interface ExecutionResultWithUsageReporting - extends ExecutionResult { - usageReporting: UsageReporting; -} - -export interface QueryPlanResult { - formattedQueryPlan: string; - queryPlan: QueryPlan; - evaluatedPlanCount: number; -} - -export interface PlanOptions { - // We receive these across the bridge as an array of strings, - // but ultimately build a Map object out of it for use in the planner. - overrideConditions?: string[]; -} - -export class BridgeQueryPlanner { - private readonly supergraph: Supergraph; - private readonly apiSchema: GraphQLSchema; - private readonly planner: QueryPlanner; - - constructor( - public readonly schemaString: string, - public readonly options: QueryPlannerConfigExt - ) { - this.supergraph = Supergraph.build(schemaString, { - supportedFeatures: ROUTER_SUPPORTED_SUPERGRAPH_FEATURES, - }); - const apiSchema = this.supergraph.schema.toAPISchema(); - this.apiSchema = apiSchema.toGraphQLJSSchema({ - includeDefer: options.incrementalDelivery?.enableDefer, - }); - this.planner = new QueryPlanner(this.supergraph, options); - } - - plan( - operationString: string, - providedOperationName?: string, - options?: PlanOptions - ): ExecutionResultWithUsageReporting { - let operationResult = this.operation( - operationString, - providedOperationName - ); - if (operationResult.errors != null) { - return { - usageReporting: operationResult.usageReporting, - errors: operationResult.errors, - }; - } - let usageReporting = operationResult.usageReporting; - let operation = operationResult.data; - const operationName = operation?.name; - const buildQueryPlanOptions = options - ? { - overrideConditions: new Map( - options.overrideConditions.map((override) => [override, true]) - ), - } - : undefined; - - const queryPlan = this.planner.buildQueryPlan( - operation, - buildQueryPlanOptions - ); - let formattedQueryPlan: string | null; - try { - formattedQueryPlan = prettyFormatQueryPlan(queryPlan); - } catch (err) { - // We have decided that since we HAVE a query plan (above), there is - // absolutely no reason to interrupt the ability to proceed just because - // we wanted a pretty-printed version of the query planner here. Therefore - // we will just proceed without the pretty printed bits. - logger.warn( - `Couldn't generate pretty query plan for ${ - operationName ? "operation " + operationName : "anonymous operation" - }: ${err}` - ); - formattedQueryPlan = null; - } - - let statistics = this.planner.lastGeneratedPlanStatistics(); - return { - usageReporting, - data: { - queryPlan, - formattedQueryPlan, - evaluatedPlanCount: statistics.evaluatedPlanCount, - }, - }; - } - - operation( - operationString: string, - providedOperationName?: string - ): ExecutionResultWithUsageReporting { - let document: DocumentNode; - - try { - document = parse(operationString); - } catch (parseError) { - // parse throws GraphQLError - return { - usageReporting: { - statsReportKey: PARSE_FAILURE, - referencedFieldsByType: {}, - }, - errors: [ - { - ...parseError, - extensions: { - code: PARSE_FAILURE_EXT_CODE, - }, - }, - ], - }; - } - - // Federation does some validation, but not all. We need to do - // all default validations that are provided by GraphQL. - const validationErrors = - this.options.graphqlValidation === false - ? [] - : validate(this.apiSchema, document); - if (validationErrors.length > 0) { - return { - usageReporting: { - statsReportKey: VALIDATION_FAILURE, - referencedFieldsByType: {}, - }, - errors: validationErrors.map((error) => { - if ( - error.extensions == null || - Object.keys(error.extensions).length === 0 - ) { - error = new GraphQLError(error.message, { - extensions: { - code: VALIDATION_FAILURE_EXT_CODE, - }, - path: error.path, - nodes: error.nodes, - originalError: error.originalError, - positions: error.positions, - source: error.source, - }); - } - - return Object.assign(error, { validationError: true }); - }), - }; - } - - let operation: Operation; - try { - operation = operationFromDocument(this.supergraph.schema, document, { - operationName: providedOperationName, - }); - } catch (e) { - // operationFromDocument throws GraphQLError - - let statsReportKey = VALIDATION_FAILURE; - - if ( - e.message.startsWith("Unknown operation named") || - e.message.startsWith("Must provide operation name") - ) { - statsReportKey = UNKNOWN_OPERATION; - } - - return { - usageReporting: { - statsReportKey, - referencedFieldsByType: {}, - }, - errors: [ - { - ...e, - extensions: { - code: VALIDATION_FAILURE_EXT_CODE, - }, - }, - ], - }; - } - - // Adapted from here - // https://github.com/apollographql/apollo-server/blob/444c403011209023b5d3b5162b8fb81991046b23/packages/apollo-server-core/src/requestPipeline.ts#L303 - const operationName = operation?.name; - - // I double checked, this function doesn't throw - const operationDerivedData = getOperationDerivedData({ - schema: this.apiSchema, - document, - operationName, - }); - - const statsReportKey = `# ${operationName || "-"}\n${ - operationDerivedData.signature - }`; - - return { - usageReporting: { - statsReportKey, - referencedFieldsByType: operationDerivedData.referencedFieldsByType, - }, - data: operation, - }; - } - - getApiSchema(): string { - return printSchema(this.apiSchema); - } - - introspect(query: string): ExecutionResult { - const { data, errors } = graphqlSync({ - schema: this.apiSchema, - source: query, - }); - - if (errors) { - return { data, errors: [...errors] }; - } else { - return { data, errors: [] }; - } - } - - operationSignature( - operationString: string, - providedOperationName?: string - ): string { - let operationResult = this.operation( - operationString, - providedOperationName - ); - return operationResult.usageReporting.statsReportKey; - } - - subgraphs(): Map { - let subgraphs = this.supergraph.subgraphs(); - let result = new Map(); - - subgraphs.names().forEach((name) => { - let sdl = printSchemaWithDirectives(subgraphs.get(name).schema); - result.set(name, sdl); - }); - - return result; - } -} - -export function queryPlanner( - schemaString: string, - options: QueryPlannerConfig -): BridgeQueryPlanner { - return new BridgeQueryPlanner(schemaString, options); -} - -// --------------------- - -// Interface definition copied from here -// https://github.com/apollographql/apollo-server/blob/d75c6cf3360a46ebcd944b2113438be8f549ae6f/packages/apollo-server-core/src/plugin/usageReporting/operationDerivedDataCache.ts#L5 -export interface OperationDerivedData { - signature: string; - referencedFieldsByType: ReferencedFieldsByType; -} - -function getOperationDerivedData({ - schema, - document, - operationName, -}: { - schema: GraphQLSchema; - document: DocumentNode; - operationName: string; -}): OperationDerivedData { - const generatedSignature = usageReportingSignature( - document, - operationName || "" - ); - - const generatedOperationDerivedData: OperationDerivedData = { - signature: generatedSignature, - referencedFieldsByType: calculateReferencedFieldsByType({ - document, - schema, - resolvedOperationName: operationName ?? null, - }), - }; - return generatedOperationDerivedData; -} diff --git a/router-bridge/js-src/plan_worker.ts b/router-bridge/js-src/plan_worker.ts deleted file mode 100644 index 858691dac..000000000 --- a/router-bridge/js-src/plan_worker.ts +++ /dev/null @@ -1,397 +0,0 @@ -import { GraphQLErrorExt } from "@apollo/core-schema/dist/error"; -import { ASTNode, Source, SourceLocation, ExecutionResult } from "graphql"; -import { - BridgeQueryPlanner, - ExecutionResultWithUsageReporting, - PlanOptions, - QueryPlanResult, -} from "./plan"; -import { QueryPlannerConfigExt } from "./types"; -declare let bridge: { BridgeQueryPlanner: typeof BridgeQueryPlanner }; -declare namespace Deno { - namespace core { - function opAsync(opName: string, ...args: any[]): Promise; - const ops: Record any>; - } -} - -function memoryUsage(): MemoryUsage { - return Deno.core.ops.op_runtime_memory_usage(); -} - -let logFunction: (message: string) => void; -declare let logger: { - trace: typeof logFunction; - debug: typeof logFunction; - info: typeof logFunction; - warn: typeof logFunction; - error: typeof logFunction; -}; - -export interface MemoryUsage { - /** The total size of the heap for V8, in bytes. */ - heapTotal: number; - /** The amount of the heap used for V8, in bytes. */ - heapUsed: number; - /** Memory, in bytes, associated with JavaScript objects outside of the - * JavaScript isolate. */ - external: number; -} - -enum PlannerEventKind { - UpdateSchema = "UpdateSchema", - Plan = "Plan", - Exit = "Exit", - ApiSchema = "ApiSchema", - Introspect = "Introspect", - Signature = "Signature", - Subgraphs = "Subgraphs", - GetHeapStatistics = "GetHeapStatistics", -} - -interface UpdateSchemaEvent { - kind: PlannerEventKind.UpdateSchema; - schema: string; - config: QueryPlannerConfigExt; - schemaId: number; -} - -interface PlanEvent { - kind: PlannerEventKind.Plan; - query: string; - operationName?: string; - schemaId: number; - options?: PlanOptions; -} -interface ApiSchemaEvent { - kind: PlannerEventKind.ApiSchema; - schemaId: number; -} - -interface IntrospectEvent { - kind: PlannerEventKind.Introspect; - query: string; - schemaId: number; -} - -interface SignatureEvent { - kind: PlannerEventKind.Signature; - query: string; - operationName?: string; - schemaId: number; -} - -interface SubgraphsEvent { - kind: PlannerEventKind.Subgraphs; - schemaId: number; -} - -interface Exit { - kind: PlannerEventKind.Exit; - schemaId: number; -} - -interface GetHeapStatisticsEvent { - kind: PlannerEventKind.GetHeapStatistics; -} - -type PlannerEvent = - | UpdateSchemaEvent - | PlanEvent - | ApiSchemaEvent - | IntrospectEvent - | SignatureEvent - | SubgraphsEvent - | GetHeapStatisticsEvent - | Exit; -type PlannerEventWithId = { - id: string; - payload: PlannerEvent; -}; - -type WorkerResultWithId = { - id?: string; - payload: WorkerResult; -}; - -type WorkerResult = - | PlanResult - | ApiSchemaResult - | ExecutionResult - | Map - | String - | MemoryUsageResult; -// Plan result -type PlanResult = - | ExecutionResultWithUsageReporting - | FatalError; -type ApiSchemaResult = { - schema: string; -}; -type MemoryUsageResult = { - heapTotal: number; - heapUsed: number; - external: number; -}; - -type FatalError = { - errors: (JsError | WorkerGraphQLError)[]; -}; - -type JsError = { - name: string; - message: string; - stack?: string; - validationError?: boolean; -}; - -type CauseError = { - message: string; - locations?: ReadonlyArray; - extensions: { - [key: string]: unknown; - }; -}; - -type WorkerGraphQLError = { - name: string; - message: string; - locations?: ReadonlyArray; - path?: ReadonlyArray; - extensions: { - [key: string]: unknown; - }; - nodes?: ReadonlyArray | ASTNode; - source?: Source; - positions?: ReadonlyArray; - originalError?: Error; - causes?: CauseError[]; - validationError?: boolean; -}; -const isGraphQLErrorExt = (error: any): error is GraphQLErrorExt => - error.name === "GraphQLError" || error.name === "CheckFailed"; - -const intoSerializableError = (error: Error): JsError => { - const { - name, - message, - stack, - validationError = false, - } = error as Error & { validationError?: boolean }; - return { - name, - message, - stack, - validationError, - }; -}; - -const intoCauseError = (error: any): CauseError => { - const { locations, message, extensions } = error; - return { - locations, - message, - extensions, - }; -}; - -const intoSerializableGraphQLErrorExt = ( - error: GraphQLErrorExt & { validationError?: boolean } -): WorkerGraphQLError => { - const { message, locations, path, extensions } = error.toJSON(); - const { - nodes, - source, - positions, - originalError, - name, - validationError = false, - } = error; - const causes = (error as any).causes; - return { - name, - message, - locations, - path, - extensions, - nodes, - source, - positions, - originalError: - originalError === undefined - ? originalError - : intoSerializableError(originalError), - causes: causes === undefined ? causes : causes.map(intoCauseError), - validationError, - }; -}; - -const send = async (payload: WorkerResultWithId): Promise => { - logger.trace(`plan_worker: sending payload ${JSON.stringify(payload)}`); - await Deno.core.ops.send(payload); -}; -const receive = async (): Promise => - await Deno.core.ops.receive(); - -let planners = new Map(); - -const updateQueryPlanner = ( - schema: string, - options: QueryPlannerConfigExt, - schemaId: number -): WorkerResult => { - try { - planners.set(schemaId, new bridge.BridgeQueryPlanner(schema, options)); - // This will be interpreted as a correct Update - return { - data: { - queryPlan: { kind: "QueryPlan", node: null }, - formattedQueryPlan: "QueryPlan {}", - }, - usageReporting: { - statsReportKey: "", - referencedFieldsByType: {}, - }, - }; - } catch (err) { - // The error that has been thrown needs to be sent back - // to the rust runtime. In order to do so, it will be serialized. - // The code below will allow us to build an object that is JSON serializable, - // yet contains all of the information we need - const errorArray = Array.isArray(err) ? err : [err]; - const errors = errorArray.map((err) => { - if (isGraphQLErrorExt(err)) { - return intoSerializableGraphQLErrorExt(err); - } else { - return intoSerializableError(err); - } - }); - - return { errors }; - } -}; - -async function run() { - while (true) { - // If an Exception is raised, - // there won't be any messageId to send a payload back to the router, - // unless we keep it in this scope. - let messageId = ""; - try { - const { id, payload: event } = await receive(); - messageId = id; - - try { - switch (event?.kind) { - case PlannerEventKind.UpdateSchema: - const updateResult = updateQueryPlanner( - event.schema, - event.config, - event.schemaId - ); - await send({ id, payload: updateResult }); - break; - case PlannerEventKind.Plan: - const planResult = planners - .get(event.schemaId) - .plan(event.query, event.operationName, event.options); - await send({ id, payload: planResult }); - break; - case PlannerEventKind.ApiSchema: - const apiSchemaResult = planners.get(event.schemaId).getApiSchema(); - const payload: ApiSchemaResult = { schema: apiSchemaResult }; - await send({ id, payload }); - break; - case PlannerEventKind.Introspect: - const introspectResult = planners - .get(event.schemaId) - .introspect(event.query); - await send({ id, payload: introspectResult }); - break; - case PlannerEventKind.Signature: - const signature = planners - .get(event.schemaId) - .operationSignature(event.query, event.operationName); - await send({ id, payload: signature }); - break; - case PlannerEventKind.Subgraphs: - const subgraphs = planners.get(event.schemaId).subgraphs(); - - await send({ id, payload: subgraphs }); - break; - case PlannerEventKind.GetHeapStatistics: - const mem = memoryUsage(); - - const result: MemoryUsageResult = { - heapTotal: mem.heapTotal, - heapUsed: mem.heapUsed, - external: mem.external, - }; - - await send({ id, payload: result }); - break; - case PlannerEventKind.Exit: - planners.delete(event.schemaId); - if (planners.size == 0) { - return; - } else { - break; - } - default: - logger.warn(`unknown message received: ${JSON.stringify(event)}\n`); - break; - } - } catch (e) { - logger.warn(`an error happened in the worker runtime ${e}\n`); - - const unexpectedError = { - name: e.name || "unknown", - message: e.message || "", - extensions: { - code: "QUERY_PLANNING_FAILED", - exception: { - stacktrace: e.toString(), - }, - }, - }; - - await send({ - id, - payload: { - errors: [unexpectedError], - usageReporting: { - statsReportKey: "", - referencedFieldsByType: {}, - }, - }, - }); - } - } catch (e) { - logger.warn(`plan_worker: an unknown error occurred ${e}\n`); - - const unexpectedError = { - name: e.name || "unknown", - message: e.message || "", - extensions: { - code: "QUERY_PLANNING_FAILED", - exception: { - stacktrace: e.toString(), - }, - }, - }; - - await send({ - id: messageId, - payload: { - errors: [unexpectedError], - usageReporting: { - statsReportKey: "", - referencedFieldsByType: {}, - }, - }, - }); - } - } -} - -run(); diff --git a/router-bridge/js-src/runtime.js b/router-bridge/js-src/runtime.js deleted file mode 100644 index 3938bdbd8..000000000 --- a/router-bridge/js-src/runtime.js +++ /dev/null @@ -1,37 +0,0 @@ -// We define logging capabilities, which can be gathered by tracing -logger = { - trace: (message) => Deno.core.ops.log_trace(`${message.toString()}\n`), - debug: (message) => Deno.core.ops.log_debug(`${message.toString()}\n`), - info: (message) => Deno.core.ops.log_info(`${message.toString()}\n`), - warn: (message) => Deno.core.ops.log_warn(`${message.toString()}\n`), - error: (message) => Deno.core.ops.log_error(`${message.toString()}\n`), -}; - -// We define a print function that uses -// Deno's print function to display the stringified argument. -function print(value) { - Deno.core.print(`${value.toString()}\n`); -} - -crypto = { - getRandomValues: (arg) => { - Deno.core.ops.op_crypto_get_random_values(arg); - return arg; - }, -}; - -// We build some of the preliminary objects that our Rollup-built package is -// expecting to be present in the environment. -// node_fetch_1 is an unused external dependency we don't bundle. See the -// configuration in this package's 'rollup.config.js' for where this is marked -// as an external dependency and thus not packaged into the bundle. -node_fetch_1 = {}; -// 'process' is a Node.js ism. We rely on process.env.NODE_ENV, in -// particular, to determine whether or not we are running in a debug -// mode. For the purposes of harmonizer, we don't gain anything from -// running in such a mode. -process = { argv: [], env: { NODE_ENV: "production" } }; -// Some JS runtime implementation specific bits that we rely on that -// need to be initialized as empty objects. -global = {}; -exports = {}; diff --git a/router-bridge/js-src/supported_features.ts b/router-bridge/js-src/supported_features.ts deleted file mode 100644 index a375258be..000000000 --- a/router-bridge/js-src/supported_features.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { - AUTHENTICATED_VERSIONS, - DEFAULT_SUPPORTED_SUPERGRAPH_FEATURES, - FeatureDefinition, - FeatureDefinitions, - POLICY_VERSIONS, - REQUIRES_SCOPES_VERSIONS, - SOURCE_VERSIONS, - CONTEXT_VERSIONS, - COST_VERSIONS, -} from "@apollo/federation-internals"; - -export const ROUTER_SUPPORTED_SUPERGRAPH_FEATURES: Set = new Set( - DEFAULT_SUPPORTED_SUPERGRAPH_FEATURES -); - -function addToRouterFeatures( - definitions: FeatureDefinitions -) { - definitions.versions().forEach((version) => { - const feature = definitions.find(version); - if (!feature) { - throw Error( - `Federation package unexpectedly did not contain feature spec ${definitions.identity}/${version}` - ); - } - ROUTER_SUPPORTED_SUPERGRAPH_FEATURES.add(feature.toString()); - }); -} - -addToRouterFeatures(AUTHENTICATED_VERSIONS); -addToRouterFeatures(REQUIRES_SCOPES_VERSIONS); -addToRouterFeatures(POLICY_VERSIONS); -addToRouterFeatures(SOURCE_VERSIONS); -addToRouterFeatures(CONTEXT_VERSIONS); -addToRouterFeatures(COST_VERSIONS); diff --git a/router-bridge/js-src/test_get_random_values.ts b/router-bridge/js-src/test_get_random_values.ts deleted file mode 100644 index 32558b92e..000000000 --- a/router-bridge/js-src/test_get_random_values.ts +++ /dev/null @@ -1,26 +0,0 @@ -declare namespace crypto { - function getRandomValues< - T extends - | Int8Array - | Int16Array - | Int32Array - | Uint8Array - | Uint16Array - | Uint32Array - | Uint8ClampedArray - | Float32Array - | Float64Array - | BigInt64Array - | BigUint64Array - | DataView - | null - >(array: T): T; -} - -const rnds8 = new Uint8Array(16); - -const randomValue = crypto.getRandomValues(rnds8); - -if (!randomValue) { - throw "couldn't use crypto.getRandomValues"; -} diff --git a/router-bridge/js-src/test_logger_worker.ts b/router-bridge/js-src/test_logger_worker.ts deleted file mode 100644 index 5fb61072e..000000000 --- a/router-bridge/js-src/test_logger_worker.ts +++ /dev/null @@ -1,89 +0,0 @@ -declare namespace Deno { - namespace core { - function opAsync(opName: string, ...args: any[]): Promise; - const ops: Record any>; - } -} - -let logFunction: (message: string) => void; -declare let logger: { - trace: typeof logFunction; - debug: typeof logFunction; - info: typeof logFunction; - warn: typeof logFunction; - error: typeof logFunction; -}; - -enum CommandKind { - Trace = "Trace", - Debug = "Debug", - Info = "Info", - Warn = "Warn", - Error = "Error", - Exit = "Exit", -} - -type Payload = { - kind: CommandKind; - message?: string; -}; - -type Command = { - id: string; - payload: Payload; -}; - -type CommandResult = { - id: string; - payload: boolean; -}; - -const send = async (result: CommandResult): Promise => { - await Deno.core.opAsync("send", result); -}; -const receive = async (): Promise => - await Deno.core.opAsync("receive"); - -async function run() { - while (true) { - try { - const event = await receive(); - const { - id, - payload: { kind, message }, - } = event; - switch (kind) { - case CommandKind.Trace: - logger.trace(message); - await send({ id, payload: true }); - break; - case CommandKind.Debug: - logger.debug(message); - await send({ id, payload: true }); - break; - case CommandKind.Info: - logger.info(message); - await send({ id, payload: true }); - break; - case CommandKind.Warn: - logger.warn(message); - await send({ id, payload: true }); - break; - case CommandKind.Error: - logger.error(message); - await send({ id, payload: true }); - break; - case CommandKind.Exit: - await send({ id, payload: true }); - return; - default: - logger.error(`unknown message received: ${JSON.stringify(event)}\n`); - break; - } - } catch (e) { - logger.error(`an unknown error occured ${e}\n`); - } - } -} - -run(); diff --git a/router-bridge/js-src/test_url.ts b/router-bridge/js-src/test_url.ts deleted file mode 100644 index a89dec5e2..000000000 --- a/router-bridge/js-src/test_url.ts +++ /dev/null @@ -1,13 +0,0 @@ -// @ts-nocheck - -const assertEq = (a: unknown, b: unknown) => { - if (a !== b) { - throw `${a} is not equal to ${b}`; - } -}; - -const url = new URL("https://www.test.com/test2"); - -assertEq("/test2", url.pathname); -assertEq("www.test.com", url.hostname); -assertEq("https", url.scheme); diff --git a/router-bridge/js-src/types.ts b/router-bridge/js-src/types.ts deleted file mode 100644 index 1914d22b6..000000000 --- a/router-bridge/js-src/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { QueryPlannerConfig } from "@apollo/query-planner"; - -export type OperationResult = - | { Ok: any; Err?: undefined } - | { Ok?: undefined; Err: any }; - -export interface QueryPlannerConfigExt extends QueryPlannerConfig { - graphqlValidation?: boolean; - typeConditionedFetching?: boolean; -} - -// `lru-cache` (in our dependencies) uses the global `AbortSignal` type -// which isn't readily available in our global types, though it is available -// in deno. -// https://github.com/isaacs/node-lru-cache/pull/247#issuecomment-1204481394 -// https://deno.land/api@v1.29.2?s=AbortSignal -declare global { - type AbortSignal = any; -} diff --git a/router-bridge/package-lock.json b/router-bridge/package-lock.json deleted file mode 100644 index 1cbfa37aa..000000000 --- a/router-bridge/package-lock.json +++ /dev/null @@ -1,2089 +0,0 @@ -{ - "name": "@apollo/router-bridge", - "version": "2.9.1", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "@apollo/router-bridge", - "version": "2.9.1", - "license": "Elastic-2.0", - "dependencies": { - "@apollo/core-schema": "^0.3.0", - "@apollo/federation-internals": "^2.9.1", - "@apollo/query-planner": "^2.9.1", - "@apollo/usage-reporting-protobuf": "^4.0.0", - "@apollo/utils.usagereporting": "^3.0.0", - "graphql": "16.6.0" - }, - "devDependencies": { - "buffer": "^6.0.3", - "console-polyfill": "^0.3.0", - "esbuild": "^0.17.0", - "make-dir-cli": "^3.0.0", - "path-browserify": "^1.0.1", - "prettier": "^2.5.1", - "typescript": "^5.0.2", - "universal-url": "^2.0.0", - "util": "^0.12.4" - }, - "engines": { - "node": ">=12.13.0 <17.0", - "npm": ">=7 <10" - } - }, - "node_modules/@apollo/core-schema": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@apollo/core-schema/-/core-schema-0.3.0.tgz", - "integrity": "sha512-v+Ys6+W1pDQu+XwP++tI5y4oZdzKrEuVXwsEenOmg2FO/3/G08C+qMhQ9YQ9Ug34rvQGQtgbIDssHEVk4YZS7g==", - "dependencies": { - "@protoplasm/recall": "^0.2" - }, - "engines": { - "node": ">=12.13.0" - }, - "peerDependencies": { - "graphql": "^15 || ^16" - } - }, - "node_modules/@apollo/federation-internals": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@apollo/federation-internals/-/federation-internals-2.9.1.tgz", - "integrity": "sha512-UWTInasu/equZa95jJixeRgstK8cf+mh6MG23eoIpNHpekG26/HBGI+mMAYCWO8969k+IiyN0RPcRlhIVYy86A==", - "dependencies": { - "@types/uuid": "^9.0.0", - "chalk": "^4.1.0", - "js-levenshtein": "^1.1.6", - "uuid": "^9.0.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "graphql": "^16.5.0" - } - }, - "node_modules/@apollo/protobufjs": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.7.tgz", - "integrity": "sha512-Lahx5zntHPZia35myYDBRuF58tlwPskwHc5CWBZC/4bMKB6siTBWwtMrkqXcsNwQiFSzSx5hKdRPUmemrEp3Gg==", - "hasInstallScript": true, - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "long": "^4.0.0" - }, - "bin": { - "apollo-pbjs": "bin/pbjs", - "apollo-pbts": "bin/pbts" - } - }, - "node_modules/@apollo/query-graphs": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@apollo/query-graphs/-/query-graphs-2.9.1.tgz", - "integrity": "sha512-Iq4esyt3ck6pYfwoukZJ3cmMCatOw27xfeK3R0us4TMNHiaXWGu1TO5Jnl/u9W25LGwe0nnVk+jYSlOCICsB6w==", - "dependencies": { - "@apollo/federation-internals": "2.9.1", - "deep-equal": "^2.0.5", - "ts-graphviz": "^1.5.4", - "uuid": "^9.0.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "graphql": "^16.5.0" - } - }, - "node_modules/@apollo/query-planner": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/@apollo/query-planner/-/query-planner-2.9.1.tgz", - "integrity": "sha512-LFi7IbShCeyFPfiX5FerUx3PNlBeFOW2z6/mNlFcFJeI9kTj+FG8gb9mrBkN9rY6VfLs3Myw4V8pmNXqXxzxpQ==", - "dependencies": { - "@apollo/federation-internals": "2.9.1", - "@apollo/query-graphs": "2.9.1", - "@apollo/utils.keyvaluecache": "^2.1.0", - "chalk": "^4.1.0", - "deep-equal": "^2.0.5", - "pretty-format": "^29.0.0" - }, - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "graphql": "^16.5.0" - } - }, - "node_modules/@apollo/usage-reporting-protobuf": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@apollo/usage-reporting-protobuf/-/usage-reporting-protobuf-4.1.0.tgz", - "integrity": "sha512-hXouMuw5pQVkzi8dgMybmr6Y11+eRmMQVoB5TF0HyTwAg9SOq/v3OCuiYqcVUKdBcskU9Msp+XvjAk0GKpWCwQ==", - "dependencies": { - "@apollo/protobufjs": "1.2.7" - } - }, - "node_modules/@apollo/utils.dropunuseddefinitions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.dropunuseddefinitions/-/utils.dropunuseddefinitions-3.0.0.tgz", - "integrity": "sha512-FT6HO0mjRhvyTHFU3EcInNIGO8SzEM1wCSX1GBdojUuGIaGi+/UiItAKT5fCqG00MsiV4ZW0UL+Of2vCPU9ErA==", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "graphql": "14.x || 15.x || 16.x" - } - }, - "node_modules/@apollo/utils.keyvaluecache": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@apollo/utils.keyvaluecache/-/utils.keyvaluecache-2.1.1.tgz", - "integrity": "sha512-qVo5PvUUMD8oB9oYvq4ViCjYAMWnZ5zZwEjNF37L2m1u528x5mueMlU+Cr1UinupCgdB78g+egA1G98rbJ03Vw==", - "dependencies": { - "@apollo/utils.logger": "^2.0.1", - "lru-cache": "^7.14.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@apollo/utils.keyvaluecache/node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "engines": { - "node": ">=12" - } - }, - "node_modules/@apollo/utils.logger": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@apollo/utils.logger/-/utils.logger-2.0.1.tgz", - "integrity": "sha512-YuplwLHaHf1oviidB7MxnCXAdHp3IqYV8n0momZ3JfLniae92eYqMIx+j5qJFX6WKJPs6q7bczmV4lXIsTu5Pg==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@apollo/utils.printwithreducedwhitespace": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.printwithreducedwhitespace/-/utils.printwithreducedwhitespace-3.0.0.tgz", - "integrity": "sha512-LEj2+zCM8qZTLJrHF2Hh55VxWrakr7NQGVWjwo7HMThi2YxDWUDDkqaXDhPshTB57cjH9LTybvnwV8mEl+ypWQ==", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "graphql": "14.x || 15.x || 16.x" - } - }, - "node_modules/@apollo/utils.removealiases": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.removealiases/-/utils.removealiases-3.0.0.tgz", - "integrity": "sha512-UNAgcvME7hS0P3mgg7qrdS3p4WHNXKDy5qQhiGrmVtpwMa3COlcWHVF0LxkHgb2U2pIiPT7dcOBQGFJLVwSO6g==", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "graphql": "14.x || 15.x || 16.x" - } - }, - "node_modules/@apollo/utils.sortast": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.sortast/-/utils.sortast-3.0.0.tgz", - "integrity": "sha512-qZG5L95wnvYD8Nsh+kKvtTDomn76wOC8H1KJGsxMTifXyY5M+PdKeAJVfPkyw11Pkq7sGVg96vk2BZ6pdFP/QA==", - "dependencies": { - "lodash.sortby": "^4.7.0" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "graphql": "14.x || 15.x || 16.x" - } - }, - "node_modules/@apollo/utils.stripsensitiveliterals": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.stripsensitiveliterals/-/utils.stripsensitiveliterals-3.0.0.tgz", - "integrity": "sha512-oVflmYj2e0ascz2X/nu2qaUo/y56gJIZII4YAMeBjFWDeh/wj+gSxWwCdy2PM6MRR3epGMSJG8Qk+0fYTLBnTw==", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "graphql": "14.x || 15.x || 16.x" - } - }, - "node_modules/@apollo/utils.usagereporting": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@apollo/utils.usagereporting/-/utils.usagereporting-3.1.0.tgz", - "integrity": "sha512-ABVQALn8vAo2XiOnSZGhEY2JtXjqJ82nxtwi+qhXzyJ86W8lsnRbrAbhphHNZsRix8K4NPFUNeUdqpwyT8uxTA==", - "dependencies": { - "@apollo/usage-reporting-protobuf": "^4.1.0", - "@apollo/utils.dropunuseddefinitions": "^3.0.0", - "@apollo/utils.printwithreducedwhitespace": "^3.0.0", - "@apollo/utils.removealiases": "3.0.0", - "@apollo/utils.sortast": "^3.0.0", - "@apollo/utils.stripsensitiveliterals": "^3.0.0" - }, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "graphql": "14.x || 15.x || 16.x" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", - "dev": true, - "dependencies": { - "@babel/highlight": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", - "dev": true, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", - "dev": true, - "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", - "dependencies": { - "@sinclair/typebox": "^0.24.1" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "node_modules/@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "node_modules/@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "node_modules/@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "node_modules/@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "node_modules/@protoplasm/recall": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/@protoplasm/recall/-/recall-0.2.2.tgz", - "integrity": "sha512-grQIYNd3UsFjHXL1g5Qw5MdUNAddEcD1KfqiO6WeMOQHgIgECXo7r4jfcXGIh37q17HoGQgq/G4guMGkzQ+UOA==", - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==" - }, - "node_modules/@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "node_modules/@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "dev": true - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, - "node_modules/@types/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==" - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz", - "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==", - "dev": true, - "dependencies": { - "camelcase": "^6.3.0", - "map-obj": "^4.1.0", - "quick-lru": "^5.1.1", - "type-fest": "^1.2.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/console-polyfill": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/console-polyfill/-/console-polyfill-0.3.0.tgz", - "integrity": "sha512-w+JSDZS7XML43Xnwo2x5O5vxB0ID7T5BdqDtyqT6uiCAX2kZAgcWxNaGqT97tZfSHzfOcvrfsDAodKcJ3UvnXQ==", - "dev": true - }, - "node_modules/decamelize": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", - "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", - "dev": true, - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/deep-equal": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz", - "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==", - "dependencies": { - "array-buffer-byte-length": "^1.0.0", - "call-bind": "^1.0.5", - "es-get-iterator": "^1.1.3", - "get-intrinsic": "^1.2.2", - "is-arguments": "^1.1.1", - "is-array-buffer": "^3.0.2", - "is-date-object": "^1.0.5", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "isarray": "^2.0.5", - "object-is": "^1.1.5", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.5.1", - "side-channel": "^1.0.4", - "which-boxed-primitive": "^1.0.2", - "which-collection": "^1.0.1", - "which-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-get-iterator": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", - "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.17.15", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.15.tgz", - "integrity": "sha512-LBUV2VsUIc/iD9ME75qhT4aJj0r75abCVS0jakhFzOtR7TQsqQA5w0tZ+KTKnwl3kXE0MhskNdHDh/I5aCR1Zw==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.17.15", - "@esbuild/android-arm64": "0.17.15", - "@esbuild/android-x64": "0.17.15", - "@esbuild/darwin-arm64": "0.17.15", - "@esbuild/darwin-x64": "0.17.15", - "@esbuild/freebsd-arm64": "0.17.15", - "@esbuild/freebsd-x64": "0.17.15", - "@esbuild/linux-arm": "0.17.15", - "@esbuild/linux-arm64": "0.17.15", - "@esbuild/linux-ia32": "0.17.15", - "@esbuild/linux-loong64": "0.17.15", - "@esbuild/linux-mips64el": "0.17.15", - "@esbuild/linux-ppc64": "0.17.15", - "@esbuild/linux-riscv64": "0.17.15", - "@esbuild/linux-s390x": "0.17.15", - "@esbuild/linux-x64": "0.17.15", - "@esbuild/netbsd-x64": "0.17.15", - "@esbuild/openbsd-x64": "0.17.15", - "@esbuild/sunos-x64": "0.17.15", - "@esbuild/win32-arm64": "0.17.15", - "@esbuild/win32-ia32": "0.17.15", - "@esbuild/win32-x64": "0.17.15" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graphql": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz", - "integrity": "sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw==", - "engines": { - "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" - } - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", - "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", - "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hasurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hasurl/-/hasurl-1.0.0.tgz", - "integrity": "sha512-43ypUd3DbwyCT01UYpA99AEZxZ4aKtRxWGBHEIbjcOsUghd9YUON0C+JF6isNjaiwC/UF5neaUudy6JS9jZPZQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/indent-string": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz", - "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-arguments": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", - "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", - "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", - "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-set": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", - "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz", - "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakmap": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", - "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz", - "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/js-levenshtein": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", - "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "node_modules/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir-cli": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir-cli/-/make-dir-cli-3.0.0.tgz", - "integrity": "sha512-8yCjIAOQ8tezWRJWUG3tbvN2I19hiVr8K5DPDVl8fECS3qz0ZbeL194ZGRdf8K3LgvbjDCTadge6NrN/I4XrNw==", - "dev": true, - "dependencies": { - "make-dir": "^3.1.0", - "meow": "^10.0.0" - }, - "bin": { - "make-dir": "cli.js" - }, - "engines": { - "node": ">=12.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.2.tgz", - "integrity": "sha512-zbuAlN+V/sXlbGchNS9WTWjUzeamwMt/BApKCJi7B0QyZstZaMx0n4Unll/fg0njGtMdC9UP5SAscvOCLYdM+Q==", - "dev": true, - "dependencies": { - "@types/minimist": "^1.2.2", - "camelcase-keys": "^7.0.0", - "decamelize": "^5.0.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.2", - "read-pkg-up": "^8.0.0", - "redent": "^4.0.0", - "trim-newlines": "^4.0.2", - "type-fest": "^1.2.2", - "yargs-parser": "^20.2.9" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-is": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz", - "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-format": { - "version": "29.3.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", - "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", - "dependencies": { - "@jest/schemas": "^29.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" - }, - "node_modules/read-pkg": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz", - "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==", - "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^3.0.2", - "parse-json": "^5.2.0", - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-pkg-up": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz", - "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==", - "dev": true, - "dependencies": { - "find-up": "^5.0.0", - "read-pkg": "^6.0.0", - "type-fest": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/redent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", - "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==", - "dev": true, - "dependencies": { - "indent-string": "^5.0.0", - "strip-indent": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/set-function-length": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.1.tgz", - "integrity": "sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==", - "dependencies": { - "define-data-property": "^1.1.2", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "node_modules/stop-iteration-iterator": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", - "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==", - "dependencies": { - "internal-slot": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/strip-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz", - "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==", - "dev": true, - "dependencies": { - "min-indent": "^1.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/trim-newlines": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.0.2.tgz", - "integrity": "sha512-GJtWyq9InR/2HRiLZgpIKv+ufIKrVrvjQWEj7PxAXNc5dwbNJkqhAUoAGgzRmULAnoOM5EIpveYd3J2VeSAIew==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ts-graphviz": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/ts-graphviz/-/ts-graphviz-1.8.2.tgz", - "integrity": "sha512-5YhbFoHmjxa7pgQLkB07MtGnGJ/yhvjmc9uhsnDBEICME6gkPf83SBwLDQqGDoCa3XzUMWLk1AU2Wn1u1naDtA==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/ts-graphviz" - } - }, - "node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz", - "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/universal-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universal-url/-/universal-url-2.0.0.tgz", - "integrity": "sha512-3DLtXdm/G1LQMCnPj+Aw7uDoleQttNHp2g5FnNQKR6cP6taNWS1b/Ehjjx4PVyvejKi3TJyu8iBraKM4q3JQPg==", - "dev": true, - "dependencies": { - "hasurl": "^1.0.0", - "whatwg-url": "^7.0.0" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/universal-url/node_modules/webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true - }, - "node_modules/universal-url/node_modules/whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "dev": true, - "dependencies": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, - "node_modules/uuid": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", - "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-collection": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", - "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", - "dependencies": { - "is-map": "^2.0.3", - "is-set": "^2.0.3", - "is-weakmap": "^2.0.2", - "is-weakset": "^2.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", - "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.4", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/router-bridge/package.json b/router-bridge/package.json deleted file mode 100644 index 561aa8483..000000000 --- a/router-bridge/package.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "name": "@apollo/router-bridge", - "private": true, - "version": "2.9.1", - "description": "Apollo Router JS Bridge Entrypoint", - "scripts": { - "build": "make-dir bundled js-dist && rm -f tsconfig.tsbuildinfo && tsc --build --verbose && node esbuild/bundler.js && cp js-dist/runtime.js js-dist/do_api_schema.js js-dist/do_introspect.js js-dist/plan_worker.js js-dist/test_logger_worker.js js-dist/test_get_random_values.js js-dist/test_url.js bundled/", - "clean": "rm -rf ./node_modules ./js-dist ./bundled ./tsconfig.tsbuildinfo", - "lint": "prettier --check ./esbuild/**/*.js ./js-src/**/*.ts ./js-src/**/*.js", - "format": "prettier --write ./esbuild/**/*.js ./js-src/**/*.ts ./js-src/**/*.js" - }, - "browser": { - "util": "util", - "url": "universal-url", - "console": "console-polyfill", - "path": "path-browserify" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/apollographql/federation.git", - "directory": "router-bridge/" - }, - "author": "Apollo ", - "license": "Elastic-2.0", - "engines": { - "node": ">=12.13.0 <17.0", - "npm": ">=7 <10" - }, - "dependencies": { - "@apollo/core-schema": "^0.3.0", - "@apollo/federation-internals": "^2.9.1", - "@apollo/query-planner": "^2.9.1", - "@apollo/usage-reporting-protobuf": "^4.0.0", - "@apollo/utils.usagereporting": "^3.0.0", - "graphql": "16.6.0" - }, - "devDependencies": { - "buffer": "^6.0.3", - "console-polyfill": "^0.3.0", - "esbuild": "^0.17.0", - "make-dir-cli": "^3.0.0", - "path-browserify": "^1.0.1", - "prettier": "^2.5.1", - "typescript": "^5.0.2", - "universal-url": "^2.0.0", - "util": "^0.12.4" - }, - "volta": { - "node": "16.20.0", - "npm": "9.7.1" - } -} diff --git a/router-bridge/snapshots/.gitignore b/router-bridge/snapshots/.gitignore deleted file mode 100644 index c96a04f00..000000000 --- a/router-bridge/snapshots/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore \ No newline at end of file diff --git a/router-bridge/src/api_schema.rs b/router-bridge/src/api_schema.rs deleted file mode 100644 index 831dc40b2..000000000 --- a/router-bridge/src/api_schema.rs +++ /dev/null @@ -1,84 +0,0 @@ -/*! -# Generate an API schema from an sdl. -*/ - -use crate::error::Error; -use crate::js::Js; -use serde::{Deserialize, Serialize}; -use std::fmt::Display; -use thiserror::Error; - -/// An error which occurred during JavaScript api schema generation. -/// -/// The shape of this error is meant to mimick that of the error created within -/// JavaScript, which is a [`GraphQLError`] from the [`graphql-js`] library. -/// -/// [`graphql-js']: https://npm.im/graphql -/// [`GraphQLError`]: https://github.com/graphql/graphql-js/blob/3869211/src/error/GraphQLError.js#L18-L75 -#[derive(Debug, Error, Serialize, Deserialize, PartialEq, Eq, Clone)] -pub struct ApiSchemaError { - /// A human-readable description of the error that prevented api schema generation. - pub message: Option, -} - -impl Display for ApiSchemaError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(self.message.as_deref().unwrap_or("UNKNOWN")) - } -} - -/// Options for generating the API schema. -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct ApiSchemaOptions { - /// Whether to validate the GraphQL input string. - pub graphql_validation: bool, -} - -/// The type returned when invoking `api_schema` -pub type ApiSchemaResult = Result>; - -/// The `api_schema` function receives a [`string`] representing the SDL and invokes JavaScript -/// functions to parse, convert to apiSchema and print to string. -pub fn api_schema(sdl: &str, options: ApiSchemaOptions) -> Result { - Js::new("api_schema".to_string()) - .with_parameter("sdl", sdl)? - .with_parameter("graphqlValidation", options.graphql_validation)? - .execute::("do_api_schema", include_str!("../bundled/do_api_schema.js")) -} - -#[cfg(test)] -mod tests { - use crate::api_schema::{api_schema, ApiSchemaError, ApiSchemaOptions}; - - #[test] - fn it_works() { - let raw_sdl = include_str!("testdata/contract_schema.graphql"); - - let api_schema = api_schema( - raw_sdl, - ApiSchemaOptions { - graphql_validation: true, - }, - ) - .unwrap(); - insta::assert_snapshot!(&api_schema.unwrap()); - } - - #[test] - fn invalid_sdl() { - let expected_error = ApiSchemaError { - message: Some(r#"Unknown type "Query"."#.to_string()), - }; - let response = api_schema( - "schema { - query: Query - }", - ApiSchemaOptions { - graphql_validation: true, - }, - ) - .expect("an uncaught deno error occured"); - - assert_eq!(response.err().unwrap(), vec![expected_error]); - } -} diff --git a/router-bridge/src/error.rs b/router-bridge/src/error.rs deleted file mode 100644 index 4c822d213..000000000 --- a/router-bridge/src/error.rs +++ /dev/null @@ -1,39 +0,0 @@ -/*! -# Errors raised by the `router-bridge` when trying to run `javascript`. -*/ - -use serde::{Deserialize, Serialize}; -use thiserror::Error; - -#[derive(Error, Serialize, Deserialize, Debug, Clone)] -/// An error which occurred within the bridge. -/// -/// This does not include JS domain related errors, such as [`GraphQLError`]. -pub enum Error { - /// An uncaught error was raised when invoking a custom script. - /// - /// This contains the script invocation error message. - #[error("the deno runtime raised an error: `{0}`")] - DenoRuntime(String), - /// An uncaught error was raised when trying to serialize a parameter before sending it to the javascript worker. - /// - /// This contains the serialization error message, and the payload name. - #[error("couldn't serialize parameter `{name}`: `{message}`.")] - ParameterSerialization { - /// The underlying serialization error. - message: String, - /// The name of the parameter we tried to serialize. - name: String, - }, - - /// An uncaught error was raised when trying to deserialize a payload. - /// - /// This contains the deserialization error message, and the payload. - #[error("couldn't deserialize payload `{id}`: `{message}`.")] - ParameterDeserialization { - /// The underlying serialization error. - message: String, - /// The deno response id we tried to deserialize. - id: String, - }, -} diff --git a/router-bridge/src/introspect.rs b/router-bridge/src/introspect.rs deleted file mode 100644 index b18427553..000000000 --- a/router-bridge/src/introspect.rs +++ /dev/null @@ -1,320 +0,0 @@ -/*! -# Run introspection against a GraphQL schema and obtain the result -*/ - -use crate::js::Js; -use crate::{error::Error, planner::QueryPlannerConfig}; -use serde::{Deserialize, Serialize}; -use std::fmt::Display; -use thiserror::Error; - -/// An error which occurred during JavaScript introspection. -/// -/// The shape of this error is meant to mimick that of the error created within -/// JavaScript, which is a [`GraphQLError`] from the [`graphql-js`] library. -/// -/// [`graphql-js']: https://npm.im/graphql -/// [`GraphQLError`]: https://github.com/graphql/graphql-js/blob/3869211/src/error/GraphQLError.js#L18-L75 -#[derive(Debug, Error, Serialize, Deserialize, PartialEq, Eq, Clone)] -pub struct IntrospectionError { - /// A human-readable description of the error that prevented introspection. - pub message: Option, -} - -impl Display for IntrospectionError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_str(self.message.as_deref().unwrap_or("UNKNOWN")) - } -} - -/// If `batch_introspect` succeeds, it returns a `Vec`. -/// -/// `IntrospectionResponse` contains data, and a vec of eventual errors. -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] -pub struct IntrospectionResponse { - /// The introspection response if batch_introspect succeeded - #[serde(default)] - data: Option, - /// The errors raised on this specific query if any - #[serde(default)] - errors: Option>, -} - -/// In some (rare) cases, executing a GraphQL query can return both errors and data. -/// -/// This impl allows you to turn it into either data or errors, or get a reference to both. -impl IntrospectionResponse { - /// `data` returns a reference to the underlying data - /// - /// use `into_result` if you don't want to use both data and errors. - pub fn data(&self) -> Option<&serde_json::Value> { - self.data.as_ref() - } - - /// `errors` returns a reference to the underlying errors - /// - /// use `into_result` if you don't want to use both data and errors. - pub fn errors(&self) -> Option<&Vec> { - self.errors.as_ref() - } - - /// `into_result` will turn an IntrospectionResponse into either Ok(data) or Err(errors) - pub fn into_result(self) -> Result> { - match (self.data, self.errors) { - (Some(_), Some(errors)) if !errors.is_empty() => Err(errors), - (Some(data), Some(errors)) if errors.is_empty() => Ok(data), - (Some(data), None) => Ok(data), - (None, Some(errors)) => Err(errors), - _ => Err(vec![IntrospectionError { - message: Some("neither data nor errors could be found".to_string()), - }]), - } - } -} - -/// The type returned when invoking `batch_introspect` -/// -/// A global introspect error would be raised here, often meaning the sdl is invalid. -/// A successful call to `batch_introspect` doesn't mean each query succeeded, -/// refer to `IntrospectionResponse` to make sure each query ran successfully. -pub type IntrospectionResult = Result, IntrospectionError>; - -/// The `batch_introspect` function receives a [`string`] representing the SDL and invokes JavaScript -/// introspection on it, with the `queries` to run against the SDL. -/// -pub fn batch_introspect( - sdl: &str, - queries: Vec, - config: QueryPlannerConfig, -) -> Result { - Js::new("introspect".to_string()) - .with_parameter("sdl", sdl)? - .with_parameter("queries", queries)? - .with_parameter("config", config)? - .execute::( - "do_introspect", - include_str!("../bundled/do_introspect.js"), - ) -} - -#[cfg(test)] -mod tests { - use crate::{ - introspect::batch_introspect, - planner::{IncrementalDeliverySupport, QueryPlannerConfig}, - }; - #[test] - fn it_works() { - let raw_sdl = r#"schema - { - query: Query - } - - type Query { - hello: String - } - "#; - - let introspected = batch_introspect( - raw_sdl, - vec![DEFAULT_INTROSPECTION_QUERY.to_string()], - QueryPlannerConfig::default(), - ) - .unwrap(); - insta::assert_snapshot!(serde_json::to_string(&introspected).unwrap()); - } - - #[test] - fn invalid_sdl() { - use crate::introspect::IntrospectionError; - let expected_error = IntrospectionError { - message: Some(r#"Unknown type "Query"."#.to_string()), - }; - let response = batch_introspect( - "schema { - query: Query - }", - vec![DEFAULT_INTROSPECTION_QUERY.to_string()], - QueryPlannerConfig::default(), - ) - .expect("an uncaught deno error occured") - .expect("a javascript land error happened"); - - assert_eq!(vec![expected_error], response[0].clone().errors.unwrap()); - } - - #[test] - fn missing_introspection_query() { - use crate::introspect::IntrospectionError; - let expected_error = IntrospectionError { - message: Some(r#"Unknown type "Query"."#.to_string()), - }; - let response = batch_introspect( - "schema { - query: Query - }", - vec![DEFAULT_INTROSPECTION_QUERY.to_string()], - QueryPlannerConfig::default(), - ) - .expect("an uncaught deno error occured") - .expect("a javascript land error happened"); - assert_eq!(expected_error, response[0].clone().errors.unwrap()[0]); - } - // This string is the result of calling getIntrospectionQuery() from the 'graphql' js package. - static DEFAULT_INTROSPECTION_QUERY: &str = r#" -query IntrospectionQuery { - __schema { - queryType { - name - } - mutationType { - name - } - subscriptionType { - name - } - types { - ...FullType - } - directives { - name - description - locations - args { - ...InputValue - } - } - } -} - -fragment FullType on __Type { - kind - name - description - - fields(includeDeprecated: true) { - name - description - args { - ...InputValue - } - type { - ...TypeRef - } - isDeprecated - deprecationReason - } - inputFields { - ...InputValue - } - interfaces { - ...TypeRef - } - enumValues(includeDeprecated: true) { - name - description - isDeprecated - deprecationReason - } - possibleTypes { - ...TypeRef - } -} - -fragment InputValue on __InputValue { - name - description - type { - ...TypeRef - } - defaultValue -} - -fragment TypeRef on __Type { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - } - } - } - } - } - } - } -} -"#; - - #[test] - fn defer_in_introspection() { - let raw_sdl = r#"schema - { - query: Query - } - - type Query { - hello: String - } - "#; - - let introspected = batch_introspect( - raw_sdl, - vec![r#"query { - __schema { - directives { - name - locations - } - } - }"# - .to_string()], - QueryPlannerConfig::default(), - ) - .unwrap(); - insta::assert_snapshot!(serde_json::to_string(&introspected).unwrap()); - - let introspected = batch_introspect( - raw_sdl, - vec![r#"query { - __schema { - directives { - name - locations - } - } - }"# - .to_string()], - QueryPlannerConfig { - incremental_delivery: Some(IncrementalDeliverySupport { - enable_defer: Some(true), - }), - graphql_validation: true, - reuse_query_fragments: None, - generate_query_fragments: None, - debug: Default::default(), - type_conditioned_fetching: false, - }, - ) - .unwrap(); - insta::assert_snapshot!(serde_json::to_string(&introspected).unwrap()); - } -} diff --git a/router-bridge/src/js.rs b/router-bridge/src/js.rs deleted file mode 100644 index 1341a2afd..000000000 --- a/router-bridge/src/js.rs +++ /dev/null @@ -1,186 +0,0 @@ -use crate::error::Error; -#[cfg(not(all(target_os = "macos", target_arch = "x86_64")))] -use deno_core::Snapshot; -/// Wraps creating the Deno Js runtime collecting parameters and executing a script. -use deno_core::{Extension, JsRuntime, RuntimeOptions}; -use serde::de::DeserializeOwned; -use serde::Serialize; - -// A reasonable default starting limit for our deno heap. -const APOLLO_ROUTER_BRIDGE_EXPERIMENTAL_V8_INITIAL_HEAP_SIZE_DEFAULT: &str = "256"; - -pub(crate) struct Js { - name: String, - parameters: Vec<(&'static str, String)>, -} - -impl Js { - pub(crate) fn new(name: String) -> Js { - Js { - name, - parameters: Vec::new(), - } - } - - pub(crate) fn with_parameter( - mut self, - name: &'static str, - param: T, - ) -> Result { - let serialized = format!( - "{} = {}", - name, - serde_json::to_string(¶m).map_err(|error| Error::ParameterSerialization { - name: name.to_string(), - message: error.to_string() - })? - ); - self.parameters.push((name, serialized)); - Ok(self) - } - - pub(crate) fn execute( - &self, - name: &'static str, - source: &'static str, - ) -> Result { - let noop_ext = Extension { - name: env!("CARGO_PKG_NAME"), - ..Default::default() - }; - - let mut runtime = self.build_js_runtime(noop_ext); - - for parameter in self.parameters.iter() { - runtime - .execute_script( - parameter.0, - deno_core::FastString::Owned(parameter.1.clone().into()), - ) - .expect("unable to evaluate service list in JavaScript runtime"); - } - - match runtime.execute_script(name, deno_core::FastString::Static(source)) { - Ok(execute_result) => { - let scope = &mut runtime.handle_scope(); - let local = deno_core::v8::Local::new(scope, execute_result); - match deno_core::serde_v8::from_v8::(scope, local) { - Ok(result) => Ok(result), - Err(e) => Err(Error::DenoRuntime(format!( - "unable to deserialize result of `{name}` in JavaScript runtime \n error: \n {e:?}" - ))), - } - } - Err(e) => { - let message = - format!("unable to invoke `{name}` in JavaScript runtime \n error: \n {e:?}"); - Err(Error::DenoRuntime(message)) - } - } - } - - pub(crate) fn build_js_runtime(&self, my_ext: Extension) -> JsRuntime { - // Initialize a runtime instance - let buffer = include_bytes!(concat!(env!("OUT_DIR"), "/query_runtime.snap")); - - let heap_size = - match std::env::var("APOLLO_ROUTER_BRIDGE_EXPERIMENTAL_V8_INITIAL_HEAP_SIZE") { - Ok(v) => v, - Err(_e) => { - APOLLO_ROUTER_BRIDGE_EXPERIMENTAL_V8_INITIAL_HEAP_SIZE_DEFAULT.to_string() - } - }; - - // The first flag is argv[0], so provide an ignorable value - let flags = vec![ - "--ignored".to_string(), - "--max-heap-size".to_string(), - heap_size, - ]; - - // Deno will warn us if we supply flags it doesn't recognise. - // We ignore "--ignored" and report any others as warnings - let ignored: Vec<_> = deno_core::v8_set_flags(flags) - .into_iter() - .filter(|x| x != "--ignored") - .collect(); - if !ignored.is_empty() { - tracing::warn!("deno ignored these flags: {:?}", ignored); - } - - #[derive(Clone)] - struct Permissions; - - impl deno_web::TimersPermission for Permissions { - fn allow_hrtime(&mut self) -> bool { - // not needed in the planner - false - } - - fn check_unstable(&self, _state: &deno_core::OpState, _api_name: &'static str) { - unreachable!("not needed in the planner") - } - } - - #[cfg(not(all(target_os = "macos", target_arch = "x86_64")))] - let mut js_runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![ - deno_webidl::deno_webidl::init_ops(), - deno_console::deno_console::init_ops(), - deno_url::deno_url::init_ops(), - deno_web::deno_web::init_ops::(Default::default(), Default::default()), - my_ext, - ], - startup_snapshot: Some(Snapshot::Static(buffer)), - ..Default::default() - }); - - #[cfg(all(target_os = "macos", target_arch = "x86_64"))] - let mut js_runtime = { - let mut js_runtime = JsRuntime::new(RuntimeOptions { - extensions: vec![ - deno_webidl::deno_webidl::init_ops(), - deno_console::deno_console::init_ops(), - deno_url::deno_url::init_ops(), - deno_web::deno_web::init_ops::( - Default::default(), - Default::default(), - ), - my_ext, - ], - ..Default::default() - }); - - // The runtime automatically contains a Deno.core object with several - // functions for interacting with it. - let runtime_str = include_str!("../bundled/runtime.js"); - js_runtime - .execute_script("", deno_core::FastString::Owned(runtime_str.into())) - .expect("unable to initialize router bridge runtime environment"); - - // Load the composition library. - let bridge_str = include_str!("../bundled/bridge.js"); - js_runtime - .execute_script("bridge.js", deno_core::FastString::Owned(bridge_str.into())) - .expect("unable to evaluate bridge module"); - js_runtime - }; - - // Add a callback that expands our heap by 1.25 each time - // it is invoked. There is no limit, since we rely on the - // execution environment (OS) to provide that. - let name = self.name.clone(); - js_runtime.add_near_heap_limit_callback(move |current, initial| { - let new = current * 5 / 4; - tracing::info!( - "deno heap expansion({}): initial: {}, current: {}, new: {}", - name, - initial, - current, - new - ); - new - }); - js_runtime - } -} diff --git a/router-bridge/src/lib.rs b/router-bridge/src/lib.rs deleted file mode 100644 index 928afe79d..000000000 --- a/router-bridge/src/lib.rs +++ /dev/null @@ -1,13 +0,0 @@ -/*! -# Introspection -*/ - -#![forbid(unsafe_code)] -#![deny(missing_debug_implementations, nonstandard_style)] -#![warn(missing_docs, future_incompatible, unreachable_pub, rust_2018_idioms)] -pub mod api_schema; -pub mod error; -pub mod introspect; -mod js; -pub mod planner; -mod worker; diff --git a/router-bridge/src/planner.rs b/router-bridge/src/planner.rs deleted file mode 100644 index 008f7bf7c..000000000 --- a/router-bridge/src/planner.rs +++ /dev/null @@ -1,2481 +0,0 @@ -/*! - * Instantiate a QueryPlanner from a schema, and perform query planning -*/ -use std::collections::HashMap; -use std::fmt::Debug; -use std::fmt::Display; -use std::fmt::Formatter; -use std::marker::PhantomData; -use std::sync::Arc; - -use serde::de::DeserializeOwned; -use serde::Deserialize; -use serde::Serialize; -use thiserror::Error; - -use crate::introspect::IntrospectionResponse; -use crate::worker::JsWorker; - -// ------------------------------------ - -#[derive(Debug, Serialize)] -#[serde(rename_all = "camelCase")] -/// Options for the query plan -pub struct QueryPlanOptions { - /// Use auto fragmentation - pub auto_fragmentization: bool, -} - -/// Default options for query planning -impl Default for QueryPlanOptions { - /// Default query plan options - fn default() -> Self { - Self { - auto_fragmentization: false, - } - } -} - -#[derive(Debug, Serialize)] -#[serde(rename_all = "camelCase")] -/// This is the context which provides -/// all the information to plan a query against a schema -pub struct OperationalContext { - /// The graphQL schema - pub schema: String, - /// The graphQL query - pub query: String, - /// The operation name - pub operation_name: String, -} - -/// An error which occurred during JavaScript planning. -/// -/// The shape of this error is meant to mimic that of the error created within -/// JavaScript, which is a [`GraphQLError`] from the [`graphql-js`] library. -/// -/// [`graphql-js`]: https://npm.im/graphql -/// [`GraphQLError`]: https://github.com/graphql/graphql-js/blob/3869211/src/error/GraphQLError.js#L18-L75 -#[derive(Debug, Error, Serialize, Deserialize, PartialEq, Eq, Clone)] -#[serde(rename_all = "camelCase")] -pub struct PlanError { - /// A human-readable description of the error that prevented planning. - pub message: Option, - /// [`PlanErrorExtensions`] - #[serde(deserialize_with = "none_only_if_value_is_null_or_empty_object")] - pub extensions: Option, - /// True if the error came from GraphQL validation. The router can use this to compare - /// results between JS and Rust validation implementations. - #[serde(skip_serializing, default)] - pub validation_error: bool, -} - -/// `none_only_if_value_is_null_or_empty_object` -/// -/// This function returns Ok(Some(T)) if a T can be deserialized, -/// -/// Ok(None) if data contains Null or an empty object, -/// And fails otherwise, including if the key is missing. -fn none_only_if_value_is_null_or_empty_object<'de, D, T>(data: D) -> Result, D::Error> -where - D: serde::de::Deserializer<'de>, - T: serde::Deserialize<'de>, -{ - #[derive(Deserialize)] - #[serde(untagged)] - enum OptionOrValue { - Opt(Option), - Val(serde_json::value::Value), - } - - let as_option_or_value: Result, D::Error> = - serde::Deserialize::deserialize(data); - - match as_option_or_value { - Ok(OptionOrValue::Opt(t)) => Ok(t), - Ok(OptionOrValue::Val(obj)) => { - if let serde_json::value::Value::Object(o) = &obj { - if o.is_empty() { - return Ok(None); - } - } - - Err(serde::de::Error::custom(format!( - "invalid neither null nor empty object: found {obj:?}" - ))) - } - Err(e) => Err(e), - } -} - -impl Display for PlanError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let Some(msg) = &self.message { - f.write_fmt(format_args!("{code}: {msg}", code = self.code(), msg = msg)) - } else { - f.write_str(self.code()) - } - } -} - -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] -/// Error codes -pub struct PlanErrorExtensions { - /// The error code - pub code: String, - #[serde(skip_serializing_if = "Option::is_none")] - /// The stacktrace if we have one - pub exception: Option, -} - -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] -/// stacktrace in error extensions -pub struct ExtensionsException { - /// The stacktrace generated in JavaScript - pub stacktrace: String, -} - -/// An error that was received during planning within JavaScript. -impl PlanError { - /// Retrieve the error code from an error received during planning. - pub fn code(&self) -> &str { - match self.extensions { - Some(ref ext) => &ext.code, - None => "UNKNOWN", - } - } -} - -// ------------------------------------ - -#[derive(Deserialize, Debug)] -/// The result of a router bridge invocation -pub struct BridgeSetupResult { - /// The data if setup happened successfully - pub data: Option, - /// The errors if the query failed - pub errors: Option>, -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -#[serde(rename_all = "camelCase")] -/// The error location -pub struct Location { - /// The line number - pub line: u32, - /// The column number - pub column: u32, -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -#[serde(untagged)] -/// This contains the set of all errors that can be thrown from deno -pub enum PlannerError { - /// The deno GraphQLError counterpart - WorkerGraphQLError(WorkerGraphQLError), - /// The deno Error counterpart - WorkerError(WorkerError), -} - -impl PlannerError { - /// Return true if the error was a GraphQL validation error. - pub fn is_validation_error(&self) -> bool { - let PlannerError::WorkerGraphQLError(err) = self else { - return false; - }; - err.validation_error - } -} - -impl From for PlannerError { - fn from(e: WorkerGraphQLError) -> Self { - Self::WorkerGraphQLError(e) - } -} - -impl From for PlannerError { - fn from(e: WorkerError) -> Self { - Self::WorkerError(e) - } -} - -impl std::fmt::Display for PlannerError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - Self::WorkerGraphQLError(graphql_error) => { - write!(f, "{graphql_error}") - } - Self::WorkerError(error) => { - write!(f, "{error}") - } - } - } -} - -/// WorkerError represents the non GraphQLErrors the deno worker can throw. -/// We try to get as much data out of them. -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -pub struct WorkerError { - /// The error message - pub message: Option, - /// The error kind - pub name: Option, - /// A stacktrace if applicable - pub stack: Option, - /// [`PlanErrorExtensions`] - pub extensions: Option, - /// If an error can be associated to a particular point in the requested - /// GraphQL document, it should contain a list of locations. - #[serde(default)] - pub locations: Vec, -} - -impl std::fmt::Display for WorkerError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}", - self.message - .clone() - .unwrap_or_else(|| "unknown error".to_string()) - ) - } -} - -/// WorkerGraphQLError represents the GraphQLErrors the deno worker can throw. -/// We try to get as much data out of them. -/// While they mostly represent GraphQLErrors, they sometimes don't. -/// See [`WorkerError`] -#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)] -#[serde(rename_all = "camelCase")] -pub struct WorkerGraphQLError { - /// The error kind - pub name: String, - /// A short, human-readable summary of the problem that **SHOULD NOT** change - /// from occurrence to occurrence of the problem, except for purposes of - /// localization. - pub message: String, - /// If an error can be associated to a particular point in the requested - /// GraphQL document, it should contain a list of locations. - #[serde(default)] - pub locations: Vec, - /// [`PlanErrorExtensions`] - pub extensions: Option, - /// The original error thrown from a field resolver during execution. - pub original_error: Option>, - /// The reasons why the error was triggered (useful for schema checks) - #[serde(default)] - pub causes: Vec>, - /// Set if the error was thrown by GraphQL spec validation. - #[serde(default, skip_serializing)] - pub validation_error: bool, -} - -impl std::fmt::Display for WorkerGraphQLError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!( - f, - "{}\ncaused by\n{}", - self.message, - self.causes - .iter() - .map(std::string::ToString::to_string) - .collect::>() - .join("\n") - ) - } -} - -#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] -#[serde(rename_all = "camelCase")] -/// A list of fields that will be resolved -/// for a given type -pub struct ReferencedFieldsForType { - /// names of the fields queried - #[serde(default)] - pub field_names: Vec, - /// whether the field is an interface - #[serde(default)] - pub is_interface: bool, -} - -#[derive(Deserialize, Serialize, Debug, PartialEq, Eq, Clone)] -#[serde(rename_all = "camelCase")] -/// UsageReporting fields, that will be used -/// to send stats to uplink/studio -pub struct UsageReporting { - /// The `stats_report_key` is a unique identifier derived from schema and query. - /// Metric data sent to Studio must be aggregated - /// via grouped key of (`client_name`, `client_version`, `stats_report_key`). - pub stats_report_key: String, - /// a list of all types and fields referenced in the query - #[serde(default)] - pub referenced_fields_by_type: HashMap, -} - -#[derive(Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -/// The result of a router bridge plan_worker invocation -pub struct PlanResult { - /// The data if the query was successfully run - pub data: Option, - /// Usage reporting related data such as the - /// operation signature and referenced fields - pub usage_reporting: UsageReporting, - /// The errors if the query failed - pub errors: Option>, -} - -/// The payload if the plan_worker invocation succeeded -#[derive(Debug)] -pub struct PlanSuccess { - /// The payload you're looking for - pub data: T, - /// Usage reporting related data such as the - /// operation signature and referenced fields - pub usage_reporting: UsageReporting, -} - -#[derive(Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -/// The result of a router bridge API schema invocation -pub struct ApiSchema { - /// The data if the query was successfully run - pub schema: String, -} - -/// The payload if the plan_worker invocation failed -#[derive(Debug, Clone)] -pub struct PlanErrors { - /// The errors the plan_worker invocation failed with - pub errors: Arc>, - /// Usage reporting related data such as the - /// operation signature and referenced fields - pub usage_reporting: UsageReporting, -} - -impl std::fmt::Display for PlanErrors { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.write_fmt(format_args!( - "query validation errors: {}", - self.errors - .iter() - .map(|e| e - .message - .clone() - .unwrap_or_else(|| "UNKNWON ERROR".to_string())) - .collect::>() - .join(", ") - )) - } -} - -impl PlanResult -where - T: DeserializeOwned + Send + Debug + 'static, -{ - /// Turn a BridgeResult into an actual Result - pub fn into_result(self) -> Result, PlanErrors> { - let usage_reporting = self.usage_reporting; - if let Some(data) = self.data { - Ok(PlanSuccess { - data, - usage_reporting, - }) - } else { - let errors = Arc::new(self.errors.unwrap_or_else(|| { - vec![PlanError { - message: Some("an unknown error occured".to_string()), - extensions: None, - validation_error: false, - }] - })); - Err(PlanErrors { - errors, - usage_reporting, - }) - } - } -} - -#[derive(Deserialize, Debug)] -#[serde(rename_all = "camelCase")] -/// deno's heap statistics -pub struct HeapStatistics { - /// total size of the heap for V8, in bytes - pub heap_total: u64, - /// amount of the heap used for V8, in bytes - pub heap_used: u64, - /// emory, in bytes, associated with JavaScript objects outside of the JavaScript isolate - pub external: u64, -} - -/// A Deno worker backed query Planner. - -pub struct Planner -where - T: DeserializeOwned + Send + Debug + 'static, -{ - worker: Arc, - schema_id: u64, - t: PhantomData, -} - -impl Debug for Planner -where - T: DeserializeOwned + Send + Debug + 'static, -{ - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("Planner") - .field("schema_id", &self.schema_id) - .finish() - } -} - -impl Planner -where - T: DeserializeOwned + Send + Debug + 'static, -{ - /// Instantiate a `Planner` from a schema string - pub async fn new( - schema: String, - config: QueryPlannerConfig, - ) -> Result> { - let schema_id: u64 = rand::random(); - let worker = JsWorker::new(include_str!("../bundled/plan_worker.js")); - let worker_is_set_up = worker - .request::>(PlanCmd::UpdateSchema { - schema, - config, - schema_id, - }) - .await - .map_err(|e| { - vec![WorkerError { - name: Some("planner setup error".to_string()), - message: Some(e.to_string()), - stack: None, - extensions: None, - locations: Default::default(), - } - .into()] - }); - - // Both cases below the mean schema update failed. - // We need to pay attention here. - // returning early will drop the worker, which will join the jsruntime thread. - // however the event loop will run for ever. We need to let the worker know it needs to exit, - // before we drop the worker - match worker_is_set_up { - Err(setup_error) => { - let _ = worker - .request::(PlanCmd::Exit { schema_id }) - .await; - return Err(setup_error); - } - Ok(setup) => { - if let Some(error) = setup.errors { - let _ = worker.send(None, PlanCmd::Exit { schema_id }).await; - return Err(error); - } - } - } - - let worker = Arc::new(worker); - - Ok(Self { - worker, - schema_id, - t: PhantomData, - }) - } - - /// Update `Planner` from a schema string - pub async fn update( - &self, - schema: String, - config: QueryPlannerConfig, - ) -> Result> { - let schema_id: u64 = rand::random(); - - let worker_is_set_up = self - .worker - .request::>(PlanCmd::UpdateSchema { - schema, - config, - schema_id, - }) - .await - .map_err(|e| { - vec![WorkerError { - name: Some("planner setup error".to_string()), - message: Some(e.to_string()), - stack: None, - extensions: None, - locations: Default::default(), - } - .into()] - }); - - // If the update failed, we keep the existing schema in place - match worker_is_set_up { - Err(setup_error) => { - return Err(setup_error); - } - Ok(setup) => { - if let Some(error) = setup.errors { - return Err(error); - } - } - } - - Ok(Self { - worker: self.worker.clone(), - schema_id, - t: PhantomData, - }) - } - - /// Plan a query against an instantiated query planner - pub async fn plan( - &self, - query: String, - operation_name: Option, - options: PlanOptions, - ) -> Result, crate::error::Error> { - self.worker - .request(PlanCmd::Plan { - query, - operation_name, - schema_id: self.schema_id, - options, - }) - .await - } - - /// Generate the API schema from the current schema - pub async fn api_schema(&self) -> Result { - self.worker - .request(PlanCmd::ApiSchema { - schema_id: self.schema_id, - }) - .await - } - - /// Generate the introspection response for this query - pub async fn introspect( - &self, - query: String, - ) -> Result { - self.worker - .request(PlanCmd::Introspect { - query, - schema_id: self.schema_id, - }) - .await - } - - /// Get the operation signature for a query - pub async fn operation_signature( - &self, - query: String, - operation_name: Option, - ) -> Result { - self.worker - .request(PlanCmd::Signature { - query, - operation_name, - schema_id: self.schema_id, - }) - .await - } - - /// Extract the subgraph schemas from the supergraph schema - pub async fn subgraphs(&self) -> Result, crate::error::Error> { - self.worker - .request(PlanCmd::Subgraphs { - schema_id: self.schema_id, - }) - .await - } - - /// Get deno's heap statistics - pub async fn get_heap_statistics(&self) -> Result { - self.worker.request(PlanCmd::GetHeapStatistics).await - } -} - -impl Drop for Planner -where - T: DeserializeOwned + Send + Debug + 'static, -{ - fn drop(&mut self) { - // Send a PlanCmd::Exit signal - let worker_clone = self.worker.clone(); - let schema_id = self.schema_id; - let _ = std::thread::spawn(move || { - let runtime = tokio::runtime::Builder::new_current_thread() - .build() - .unwrap(); - - let _ = runtime.block_on(async move { - worker_clone.send(None, PlanCmd::Exit { schema_id }).await - }); - }) - .join(); - } -} - -/// Options for planning a query -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, Default)] -#[serde(rename_all = "camelCase")] -pub struct PlanOptions { - /// Which labels to override during query planning - pub override_conditions: Vec, -} - -#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)] -#[serde(tag = "kind")] -enum PlanCmd { - #[serde(rename_all = "camelCase")] - UpdateSchema { - schema: String, - config: QueryPlannerConfig, - schema_id: u64, - }, - #[serde(rename_all = "camelCase")] - Plan { - query: String, - operation_name: Option, - schema_id: u64, - options: PlanOptions, - }, - #[serde(rename_all = "camelCase")] - ApiSchema { schema_id: u64 }, - #[serde(rename_all = "camelCase")] - Introspect { query: String, schema_id: u64 }, - #[serde(rename_all = "camelCase")] - Signature { - query: String, - operation_name: Option, - schema_id: u64, - }, - #[serde(rename_all = "camelCase")] - Subgraphs { schema_id: u64 }, - #[serde(rename_all = "camelCase")] - Exit { schema_id: u64 }, - #[serde(rename_all = "camelCase")] - GetHeapStatistics, -} - -#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)] -#[serde(rename_all = "camelCase")] -/// Query planner configuration -pub struct QueryPlannerConfig { - //exposeDocumentNodeInFetchNode?: boolean; - - // Side-note: implemented as an object instead of single boolean because we expect to add more to this soon - // enough. In particular, once defer-passthrough to subgraphs is implemented, the idea would be to add a - // new `passthroughSubgraphs` option that is the list of subgraph to which we can pass-through some @defer - // (and it would be empty by default). Similarly, once we support @stream, grouping the options here will - // make sense too. - /// Option for `@defer` directive support - pub incremental_delivery: Option, - /// Whether to validate GraphQL schema and query text - pub graphql_validation: bool, - /// Whether the query planner should try to reused the named fragments of the planned query in subgraph fetches. - /// - /// This is often a good idea as it can prevent very large subgraph queries in some cases (named fragments can - /// make some relatively small queries (using said fragments) expand to a very large query if all the spreads - /// are inline). However, due to architecture of the query planner, this optimization is done as an additional - /// pass on the subgraph queries of the generated plan and can thus increase the latency of building a plan. - /// As long as query plans are sufficiently cached, this should not be a problem, which is why this option is - /// enabled by default, but if the distribution of inbound queries prevents efficient caching of query plans, - /// this may become an undesirable trade-off and can be disabled in that case. - /// - /// Defaults to `true` in the JS query planner. Defaults to `None` here in order to defer to the JS query - /// planner's default. - pub reuse_query_fragments: Option, - - /// If enabled, the query planner will extract inline fragments into - /// fragment definitions before sending queries to subgraphs. This can - /// significantly reduce the size of the query sent to subgraphs, but may - /// increase the time it takes to plan the query. - pub generate_query_fragments: Option, - - /// A sub-set of configurations that are meant for debugging or testing. All the configurations in this - /// sub-set are provided without guarantees of stability (they may be dangerous) or continued support (they - /// may be removed without warning). - pub debug: Option, - /// Enables type conditioned fetching. - /// This flag is a workaround, which may yield significant - /// performance degradation when computing query plans, - /// and increase query plan size. - /// - /// If you aren't aware of this flag, you probably don't need it. - /// Defaults to false. - pub type_conditioned_fetching: bool, -} - -impl Default for QueryPlannerConfig { - fn default() -> Self { - Self { - incremental_delivery: Some(IncrementalDeliverySupport { - enable_defer: Some(false), - }), - graphql_validation: true, - reuse_query_fragments: None, - generate_query_fragments: None, - debug: Default::default(), - type_conditioned_fetching: false, - } - } -} - -#[derive(Serialize, Debug, Clone, PartialEq, Eq, Hash)] -#[serde(rename_all = "camelCase")] -/// Option for `@defer` directive support -pub struct IncrementalDeliverySupport { - /// Enables @defer support by the query planner. - /// - /// If set, then the query plan for queries having some @defer will contains some `DeferNode` (see `QueryPlan.ts`). - /// - /// Defaults to false (meaning that the @defer are ignored). - #[serde(default)] - pub enable_defer: Option, -} - -#[derive(Serialize, Debug, Clone, Default, PartialEq, Eq, Hash)] -#[serde(rename_all = "camelCase")] -/// Query planner debug configuration -pub struct QueryPlannerDebugConfig { - /// If used and the supergraph is built from a single subgraph, then user queries do not go through the - /// normal query planning and instead a fetch to the one subgraph is built directly from the input query. - pub bypass_planner_for_single_subgraph: Option, - - /// Query planning is an exploratory process. Depending on the specificities and feature used by - /// subgraphs, there could exist may different theoretical valid (if not always efficient) plans - /// for a given query, and at a high level, the query planner generates those possible choices, - /// evaluate them, and return the best one. In some complex cases however, the number of - /// theoretically possible plans can be very large, and to keep query planning time acceptable, - /// the query planner cap the maximum number of plans it evaluates. This config allows to configure - /// that cap. Note if planning a query hits that cap, then the planner will still always return a - /// "correct" plan, but it may not return _the_ optimal one, so this config can be considered a - /// trade-off between the worst-time for query planning computation processing, and the risk of - /// having non-optimal query plans (impacting query runtimes). - /// - /// This value currently defaults to 10 000, but this default is considered an implementation - /// detail and is subject to change. We do not recommend setting this value unless it is to - /// debug a specific issue (with unexpectedly slow query planning for instance). Remember that - /// setting this value too low can negatively affect query runtime (due to the use of sub-optimal - /// query plans). - pub max_evaluated_plans: Option, - - /// Before creating query plans, for each path of fields in the query we compute all the - /// possible options to traverse that path via the subgraphs. Multiple options can arise because - /// fields in the path can be provided by multiple subgraphs, and abstract types (i.e. unions - /// and interfaces) returned by fields sometimes require the query planner to traverse through - /// each constituent object type. The number of options generated in this computation can grow - /// large if the schema or query are sufficiently complex, and that will increase the time spent - /// planning. - /// - /// This config allows specifying a per-path limit to the number of options considered. If any - /// path's options exceeds this limit, query planning will abort and the operation will fail. - /// - /// The default value is None, which specifies no limit. - pub paths_limit: Option, -} -#[cfg(test)] -mod tests { - use futures::stream; - use futures::stream::StreamExt; - - use std::collections::BTreeMap; - - use super::*; - - const QUERY: &str = include_str!("testdata/query.graphql"); - const QUERY2: &str = include_str!("testdata/query2.graphql"); - const MULTIPLE_QUERIES: &str = include_str!("testdata/query_with_multiple_operations.graphql"); - const NO_OPERATION: &str = include_str!("testdata/no_operation.graphql"); - const QUERY_REUSE_QUERY_FRAGMENTS: &str = - include_str!("testdata/query_reuse_query_fragments.graphql"); - const QUERY_GENERATE_QUERY_FRAGMENTS: &str = - include_str!("testdata/query_generate_query_fragments.graphql"); - - const MULTIPLE_ANONYMOUS_QUERIES: &str = - include_str!("testdata/query_with_multiple_anonymous_operations.graphql"); - const NAMED_QUERY: &str = include_str!("testdata/named_query.graphql"); - const SCHEMA: &str = include_str!("testdata/schema.graphql"); - const SCHEMA_WITHOUT_REVIEW_BODY: &str = - include_str!("testdata/schema_without_review_body.graphql"); - const SCHEMA_REUSE_QUERY_FRAGMENTS: &str = - include_str!("testdata/schema_reuse_query_fragments.graphql"); - const SCHEMA_GENERATE_QUERY_FRAGMENTS: &str = - include_str!("testdata/schema_generate_query_fragments.graphql"); - const CORE_IN_V0_1: &str = include_str!("testdata/core_in_v0.1.graphql"); - const UNSUPPORTED_FEATURE: &str = include_str!("testdata/unsupported_feature.graphql"); - const UNSUPPORTED_FEATURE_FOR_EXECUTION: &str = - include_str!("testdata/unsupported_feature_for_execution.graphql"); - const UNSUPPORTED_FEATURE_FOR_SECURITY: &str = - include_str!("testdata/unsupported_feature_for_security.graphql"); - const PROGRESSIVE_OVERRIDE: &str = include_str!("testdata/progressive_override.graphql"); - - #[tokio::test] - async fn anonymous_query_works() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan(QUERY.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - insta::with_settings!({sort_maps => true}, { - insta::assert_json_snapshot!(payload.usage_reporting); - }); - } - - // This test runs the same query twice, but provides an override label on - // the first run. The resulting snapshots should show the difference in the - // query plans. - #[tokio::test] - async fn progressive_override() { - let query = "{ t { a } }"; - let planner = Planner::::new( - PROGRESSIVE_OVERRIDE.to_string(), - QueryPlannerConfig::default(), - ) - .await - .unwrap(); - - let payload1 = planner - .plan( - query.to_string(), - None, - PlanOptions { - override_conditions: vec!["foo".to_string()], - }, - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload1.data).unwrap()); - - let payload2 = planner - .plan(query.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload2.data).unwrap()); - } - - #[tokio::test] - async fn named_query_works() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan(NAMED_QUERY.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - insta::with_settings!({sort_maps => true}, { - insta::assert_json_snapshot!(payload.usage_reporting); - }); - } - - #[tokio::test] - async fn named_query_with_several_choices_works() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan( - MULTIPLE_QUERIES.to_string(), - Some("MyFirstName".to_string()), - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - insta::with_settings!({sort_maps => true}, { - insta::assert_json_snapshot!(payload.usage_reporting); - }); - } - - #[tokio::test] - async fn named_query_with_operation_name_works() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan( - NAMED_QUERY.to_string(), - Some("MyFirstAndLastName".to_string()), - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - } - - #[tokio::test] - async fn reuse_query_fragments_defaults_to_true() { - let planner = Planner::::new( - SCHEMA_REUSE_QUERY_FRAGMENTS.to_string(), - QueryPlannerConfig::default(), - ) - .await - .unwrap(); - - let payload = planner - .plan( - QUERY_REUSE_QUERY_FRAGMENTS.to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - } - - #[tokio::test] - async fn reuse_query_fragments_explicit_true() { - let planner = Planner::::new( - SCHEMA_REUSE_QUERY_FRAGMENTS.to_string(), - QueryPlannerConfig { - generate_query_fragments: Default::default(), - reuse_query_fragments: Some(true), - ..Default::default() - }, - ) - .await - .unwrap(); - - let payload = planner - .plan( - QUERY_REUSE_QUERY_FRAGMENTS.to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - } - - #[tokio::test] - async fn reuse_query_fragments_false() { - let planner = Planner::::new( - SCHEMA_REUSE_QUERY_FRAGMENTS.to_string(), - QueryPlannerConfig { - generate_query_fragments: Default::default(), - reuse_query_fragments: Some(false), - ..Default::default() - }, - ) - .await - .unwrap(); - - let payload = planner - .plan( - QUERY_REUSE_QUERY_FRAGMENTS.to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - } - - #[tokio::test] - async fn generate_query_fragments_defaults_to_false() { - let planner = Planner::::new( - SCHEMA_GENERATE_QUERY_FRAGMENTS.to_string(), - QueryPlannerConfig::default(), - ) - .await - .unwrap(); - - let payload = planner - .plan( - QUERY_GENERATE_QUERY_FRAGMENTS.to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - } - - #[tokio::test] - async fn generate_query_fragments_explicit_false() { - let planner = Planner::::new( - SCHEMA_GENERATE_QUERY_FRAGMENTS.to_string(), - QueryPlannerConfig { - generate_query_fragments: Some(false), - ..Default::default() - }, - ) - .await - .unwrap(); - - let payload = planner - .plan( - QUERY_GENERATE_QUERY_FRAGMENTS.to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - } - - #[tokio::test] - async fn generate_query_fragments_true() { - let planner = Planner::::new( - SCHEMA_GENERATE_QUERY_FRAGMENTS.to_string(), - QueryPlannerConfig { - generate_query_fragments: Some(true), - ..Default::default() - }, - ) - .await - .unwrap(); - - let payload = planner - .plan( - QUERY_GENERATE_QUERY_FRAGMENTS.to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&payload.data).unwrap()); - } - - #[tokio::test] - async fn parse_errors_return_the_right_usage_reporting_data() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan( - "this query will definitely not parse".to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap_err(); - - assert_eq!( - "Syntax Error: Unexpected Name \"this\".", - payload.errors[0].message.as_ref().unwrap() - ); - assert_eq!( - "## GraphQLParseFailure\n", - payload.usage_reporting.stats_report_key - ); - } - - #[tokio::test] - async fn validation_errors_return_the_right_usage_reporting_data() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan( - // These two fragments will spread themselves into a cycle, which is invalid per NoFragmentCyclesRule. - "\ - fragment thatUserFragment1 on User { - id - ...thatUserFragment2 - } - fragment thatUserFragment2 on User { - id - ...thatUserFragment1 - } - query { me { id ...thatUserFragment1 } }" - .to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap_err(); - - assert_eq!( - "Cannot spread fragment \"thatUserFragment1\" within itself via \"thatUserFragment2\".", - payload.errors[0].message.as_ref().unwrap() - ); - assert_eq!( - "## GraphQLValidationFailure\n", - payload.usage_reporting.stats_report_key - ); - } - - #[tokio::test] - async fn unknown_operation_name_errors_return_the_right_usage_reporting_data() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan( - QUERY.to_string(), - Some("ThisOperationNameDoesntExist".to_string()), - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap_err(); - - assert_eq!( - "Unknown operation named \"ThisOperationNameDoesntExist\"", - payload.errors[0].message.as_ref().unwrap() - ); - assert_eq!( - "## GraphQLUnknownOperationName\n", - payload.usage_reporting.stats_report_key - ); - } - - #[tokio::test] - async fn must_provide_operation_name_errors_return_the_right_usage_reporting_data() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan(MULTIPLE_QUERIES.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap_err(); - - assert_eq!( - "Must provide operation name if query contains multiple operations.", - payload.errors[0].message.as_ref().unwrap() - ); - assert_eq!( - "## GraphQLUnknownOperationName\n", - payload.usage_reporting.stats_report_key - ); - } - - #[tokio::test] - async fn multiple_anonymous_queries_return_the_expected_usage_reporting_data() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan( - MULTIPLE_ANONYMOUS_QUERIES.to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .into_result() - .unwrap_err(); - - assert_eq!( - "This anonymous operation must be the only defined operation.", - payload.errors[0].message.as_ref().unwrap() - ); - assert_eq!( - "## GraphQLValidationFailure\n", - payload.usage_reporting.stats_report_key - ); - } - - #[tokio::test] - async fn no_operation_in_document() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let payload = planner - .plan(NO_OPERATION.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap_err(); - - assert_eq!( - "Fragment \"thatUserFragment1\" is never used.", - payload.errors[0].message.as_ref().unwrap() - ); - assert_eq!( - "## GraphQLValidationFailure\n", - payload.usage_reporting.stats_report_key - ); - } - - #[tokio::test] - // A series of queries that should fail graphql-js's validate function. The federation - // query planning logic automatically does some validation in order to do its duties. - // Some, but not all, of that validation is also handled by the graphql-js validator. - // However, we are trying to assert that we are testing graphql-js validation, not - // Federation's query planner validation. So we run a few validations which we do not - // expect to every show up in Federation's query planner validation. - // This one is for the NoFragmentCyclesRule in graphql/validate - async fn invalid_graphql_validation_1_is_caught() { - let errors= vec![PlanError { - message: Some("Cannot spread fragment \"thatUserFragment1\" within itself via \"thatUserFragment2\".".to_string()), - extensions: Some(PlanErrorExtensions { - code: String::from("GRAPHQL_VALIDATION_FAILED"), - exception: None, - }), - validation_error: true, - }]; - - assert_errors( - errors, - // These two fragments will spread themselves into a cycle, which is invalid per NoFragmentCyclesRule. - "\ - fragment thatUserFragment1 on User { - id - ...thatUserFragment2 - } - fragment thatUserFragment2 on User { - id - ...thatUserFragment1 - } - query { me { id ...thatUserFragment1 } }" - .to_string(), - None, - ) - .await; - } - - #[tokio::test] - // A series of queries that should fail graphql-js's validate function. The federation - // query planning logic automatically does some validation in order to do its duties. - // Some, but not all, of that validation is also handled by the graphql-js validator. - // However, we are trying to assert that we are testing graphql-js validation, not - // Federation's query planner validation. So we run a few validations which we do not - // expect to every show up in Federation's query planner validation. - // This one is for the ScalarLeafsRule in graphql/validate - async fn invalid_graphql_validation_2_is_caught() { - let errors = vec![PlanError { - message: Some( - "Field \"id\" must not have a selection since type \"ID!\" has no subfields." - .to_string(), - ), - extensions: Some(PlanErrorExtensions { - code: String::from("GRAPHQL_VALIDATION_FAILED"), - exception: None, - }), - validation_error: true, - }]; - - assert_errors( - errors, - // This Book resolver requires a selection set, per the schema. - "{ me { id { absolutelyNotAcceptableLeaf } } }".to_string(), - None, - ) - .await; - } - - #[tokio::test] - // A series of queries that should fail graphql-js's validate function. The federation - // query planning logic automatically does some validation in order to do its duties. - // Some, but not all, of that validation is also handled by the graphql-js validator. - // However, we are trying to assert that we are testing graphql-js validation, not - // Federation's query planner validation. So we run a few validations which we do not - // expect to every show up in Federation's query planner validation. - // This one is for NoUnusedFragmentsRule in graphql/validate - async fn invalid_graphql_validation_3_is_caught() { - let errors = vec![PlanError { - message: Some("Fragment \"UnusedTestFragment\" is never used.".to_string()), - extensions: Some(PlanErrorExtensions { - code: String::from("GRAPHQL_VALIDATION_FAILED"), - exception: None, - }), - validation_error: true, - }]; - - assert_errors( - errors, - // This Book resolver requires a selection set, per the schema. - "fragment UnusedTestFragment on User { id } query { me { id } }".to_string(), - None, - ) - .await; - } - - #[tokio::test] - async fn invalid_federation_validation_is_caught() { - let errors = vec![PlanError { - message: Some( - "Must provide operation name if query contains multiple operations.".to_string(), - ), - extensions: Some(PlanErrorExtensions { - code: "GRAPHQL_VALIDATION_FAILED".to_string(), - exception: None, - }), - validation_error: false, - }]; - - assert_errors( - errors, // This requires passing an operation name (because there are multiple operations) - // but we have not done that! Therefore, we expect a validation error from planning. - "query Operation1 { me { id } } query Operation2 { me { id } }".to_string(), - None, - ) - .await; - } - - #[tokio::test] - async fn invalid_schema_is_caught() { - let expected_errors: Vec = vec![WorkerGraphQLError { - name: "GraphQLError".to_string(), - message: "Syntax Error: Unexpected Name \"Garbage\".".to_string(), - extensions: None, - locations: vec![Location { line: 1, column: 1 }], - original_error: None, - causes: vec![], - validation_error: false, - } - .into()]; - - let actual_error = - Planner::::new("Garbage".to_string(), QueryPlannerConfig::default()) - .await - .unwrap_err(); - - assert_eq!(expected_errors, actual_error); - } - - #[tokio::test] - async fn syntactically_incorrect_query_is_caught() { - let errors = vec![PlanError { - message: Some("Syntax Error: Unexpected Name \"Garbage\".".to_string()), - extensions: Some(PlanErrorExtensions { - code: String::from("GRAPHQL_PARSE_FAILED"), - exception: None, - }), - validation_error: false, - }]; - - assert_errors(errors, "Garbage".to_string(), None).await; - } - - #[tokio::test] - async fn query_missing_subfields() { - let expected_error_message = r#"Field "reviews" of type "[Review]" must have a selection of subfields. Did you mean "reviews { ... }"?"#; - - let errors = vec![PlanError { - message: Some(expected_error_message.to_string()), - extensions: Some(PlanErrorExtensions { - code: String::from("GRAPHQL_VALIDATION_FAILED"), - exception: None, - }), - validation_error: true, - }]; - - assert_errors( - errors, - // This query contains reviews, which requires subfields - "query ExampleQuery { me { id reviews } }".to_string(), - None, - ) - .await; - } - - #[tokio::test] - async fn query_field_that_doesnt_exist() { - let expected_error_message = r#"Cannot query field "thisDoesntExist" on type "Query"."#; - let errors = vec![PlanError { - message: Some(expected_error_message.to_string()), - extensions: Some(PlanErrorExtensions { - code: String::from("GRAPHQL_VALIDATION_FAILED"), - exception: None, - }), - validation_error: true, - }]; - - assert_errors( - errors, - // This query contains reviews, which requires subfields - "query ExampleQuery { thisDoesntExist }".to_string(), - None, - ) - .await; - } - - async fn assert_errors( - expected_errors: Vec, - query: String, - operation_name: Option, - ) { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let actual = planner - .plan(query, operation_name, PlanOptions::default()) - .await - .unwrap(); - - assert_eq!(expected_errors, actual.errors.unwrap()); - } - - #[tokio::test] - async fn it_doesnt_race() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let query_1_response = planner - .plan(QUERY.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .data - .unwrap(); - - let query_2_response = planner - .plan(QUERY2.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .data - .unwrap(); - - let all_futures = stream::iter((0..1000).map(|i| { - let (query, fut) = if i % 2 == 0 { - ( - QUERY, - planner.plan(QUERY.to_string(), None, PlanOptions::default()), - ) - } else { - ( - QUERY2, - planner.plan(QUERY2.to_string(), None, PlanOptions::default()), - ) - }; - - async move { (query, fut.await.unwrap()) } - })); - - all_futures - .for_each_concurrent(None, |fut| async { - let (query, plan_result) = fut.await; - if query == QUERY { - assert_eq!(query_1_response, plan_result.data.unwrap()); - } else { - assert_eq!(query_2_response, plan_result.data.unwrap()); - } - }) - .await; - } - - #[tokio::test] - async fn error_on_core_in_v0_1() { - let expected_errors: Vec = vec![ - WorkerGraphQLError { - name: "GraphQLError".to_string(), - message: r#"one or more checks failed. Caused by: -the `for:` argument is unsupported by version v0.1 of the core spec. Please upgrade to at least @core v0.2 (https://specs.apollo.dev/core/v0.2). - -GraphQL request:2:1 -1 | schema -2 | @core(feature: "https://specs.apollo.dev/core/v0.1") - | ^ -3 | @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) - -GraphQL request:3:1 -2 | @core(feature: "https://specs.apollo.dev/core/v0.1") -3 | @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) - | ^ -4 | @core( - -GraphQL request:4:1 -3 | @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) -4 | @core( - | ^ -5 | feature: "https://specs.apollo.dev/something-unsupported/v0.1" - -feature https://specs.apollo.dev/something-unsupported/v0.1 is for: SECURITY but is unsupported - -GraphQL request:4:1 -3 | @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) -4 | @core( - | ^ -5 | feature: "https://specs.apollo.dev/something-unsupported/v0.1""#.to_string(), - locations: Default::default(), - extensions: Some(PlanErrorExtensions { - code: "CheckFailed".to_string(), - exception: None - }), - original_error: None, - causes: vec![ - Box::new(WorkerError { - message: Some("the `for:` argument is unsupported by version v0.1 of the core spec. Please upgrade to at least @core v0.2 (https://specs.apollo.dev/core/v0.2).".to_string()), - name: None, - stack: None, - extensions: Some(PlanErrorExtensions { code: "UNSUPPORTED_LINKED_FEATURE".to_string(), exception: None }), - locations: vec![Location { line: 2, column: 1 }, Location { line: 3, column: 1 }, Location { line: 4, column: 1 }] - }), - Box::new(WorkerError { - message: Some("feature https://specs.apollo.dev/something-unsupported/v0.1 is for: SECURITY but is unsupported".to_string()), - name: None, - stack: None, - extensions: Some(PlanErrorExtensions { code: "UNSUPPORTED_LINKED_FEATURE".to_string(), exception: None }), - locations: vec![Location { line: 4, column: 1 }] - }) - ], - validation_error: false, - }.into() - ]; - let actual_errors = Planner::::new( - CORE_IN_V0_1.to_string(), - QueryPlannerConfig::default(), - ) - .await - .unwrap_err(); - - pretty_assertions::assert_eq!(expected_errors, actual_errors); - } - - #[tokio::test] - async fn unsupported_feature_without_for() { - // this should not return an error - // see gateway test "it doesn't throw errors when using unsupported features which have no `for:` argument" - Planner::::new( - UNSUPPORTED_FEATURE.to_string(), - QueryPlannerConfig::default(), - ) - .await - .unwrap(); - } - - #[tokio::test] - async fn unsupported_feature_for_execution() { - let expected_errors: Vec = vec![ - WorkerGraphQLError { - name: "GraphQLError".to_string(), - message: r#"one or more checks failed. Caused by: -feature https://specs.apollo.dev/unsupported-feature/v0.1 is for: EXECUTION but is unsupported - -GraphQL request:4:9 -3 | @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) -4 | @core( - | ^ -5 | feature: "https://specs.apollo.dev/unsupported-feature/v0.1""#.to_string(), - locations: Default::default(), - extensions: Some(PlanErrorExtensions { - code: "CheckFailed".to_string(), - exception: None - }), - original_error: None, - causes: vec![ - Box::new(WorkerError { - message: Some("feature https://specs.apollo.dev/unsupported-feature/v0.1 is for: EXECUTION but is unsupported".to_string()), - name: None, - stack: None, - extensions: Some(PlanErrorExtensions { code: "UNSUPPORTED_LINKED_FEATURE".to_string(), exception: None }), - locations: vec![Location { line: 4, column: 9 }] - }), - ], - validation_error: false, - }.into() - ]; - let actual_errors = Planner::::new( - UNSUPPORTED_FEATURE_FOR_EXECUTION.to_string(), - QueryPlannerConfig::default(), - ) - .await - .unwrap_err(); - - pretty_assertions::assert_eq!(expected_errors, actual_errors); - } - - #[tokio::test] - async fn unsupported_feature_for_security() { - let expected_errors: Vec = vec![WorkerGraphQLError { - name:"GraphQLError".into(), - message: r#"one or more checks failed. Caused by: -feature https://specs.apollo.dev/unsupported-feature/v0.1 is for: SECURITY but is unsupported - -GraphQL request:4:9 -3 | @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) -4 | @core( - | ^ -5 | feature: "https://specs.apollo.dev/unsupported-feature/v0.1""#.to_string(), - locations: vec![], - extensions: Some(PlanErrorExtensions { - code: "CheckFailed".to_string(), - exception: None - }), - original_error: None, - causes: vec![Box::new(WorkerError { - message: Some("feature https://specs.apollo.dev/unsupported-feature/v0.1 is for: SECURITY but is unsupported".to_string()), - extensions: Some(PlanErrorExtensions { - code: "UNSUPPORTED_LINKED_FEATURE".to_string(), - exception: None - }), - name: None, - stack: None, - locations: vec![Location { line: 4, column: 9 }] - })], - validation_error: false, - } - .into()]; - let actual_errors = Planner::::new( - UNSUPPORTED_FEATURE_FOR_SECURITY.to_string(), - QueryPlannerConfig::default(), - ) - .await - .unwrap_err(); - - pretty_assertions::assert_eq!(expected_errors, actual_errors); - } - - #[tokio::test] - async fn api_schema() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let api_schema = planner.api_schema().await.unwrap(); - insta::assert_snapshot!(api_schema.schema); - } - // This string is the result of calling getIntrospectionQuery() from the 'graphql' js package. - static INTROSPECTION: &str = r#" -query IntrospectionQuery { -__schema { - queryType { - name - } - mutationType { - name - } - subscriptionType { - name - } - types { - ...FullType - } - directives { - name - description - locations - args { - ...InputValue - } - } -} -} - -fragment FullType on __Type { -kind -name -description - -fields(includeDeprecated: true) { - name - description - args { - ...InputValue - } - type { - ...TypeRef - } - isDeprecated - deprecationReason -} -inputFields { - ...InputValue -} -interfaces { - ...TypeRef -} -enumValues(includeDeprecated: true) { - name - description - isDeprecated - deprecationReason -} -possibleTypes { - ...TypeRef -} -} - -fragment InputValue on __InputValue { -name -description -type { - ...TypeRef -} -defaultValue -} - -fragment TypeRef on __Type { -kind -name -ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - ofType { - kind - name - } - } - } - } - } - } -} -} -"#; - #[tokio::test] - async fn introspect() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let introspection_response = planner.introspect(INTROSPECTION.to_string()).await.unwrap(); - insta::assert_json_snapshot!(serde_json::to_value(introspection_response).unwrap()); - } - - #[tokio::test] - async fn planner_update() { - let query = "{ me { id name {first } reviews { id author { name { first } } body } } }"; - let planner = Planner::::new( - SCHEMA_WITHOUT_REVIEW_BODY.to_string(), - QueryPlannerConfig::default(), - ) - .await - .unwrap(); - let query_plan1 = planner - .plan(query.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap_err(); - insta::assert_snapshot!(&format!("{query_plan1:#?}")); - let api_schema1 = planner.api_schema().await.unwrap(); - insta::assert_snapshot!(api_schema1.schema); - let introspected_schema1 = planner.introspect(INTROSPECTION.to_string()).await.unwrap(); - - let updated_planner = planner - .update(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - let query_plan2 = updated_planner - .plan(query.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap(); - insta::assert_snapshot!(serde_json::to_string_pretty(&query_plan2.data).unwrap()); - let api_schema2 = updated_planner.api_schema().await.unwrap(); - insta::assert_snapshot!(api_schema2.schema); - - // we should still be able to call the old planner, and it must have kept the same schema - assert_eq!( - planner.introspect(INTROSPECTION.to_string()).await.unwrap(), - introspected_schema1 - ); - - let introspected_schema2 = updated_planner - .introspect(INTROSPECTION.to_string()) - .await - .unwrap(); - assert_ne!(introspected_schema1, introspected_schema2); - - // Now we drop the old planner. The updated planner should still work - drop(planner); - - assert_eq!( - query_plan2.data, - updated_planner - .plan(query.to_string(), None, PlanOptions::default()) - .await - .unwrap() - .into_result() - .unwrap() - .data - ); - } - - #[tokio::test] - async fn get_operation_signature() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let signature = planner - .operation_signature(NAMED_QUERY.to_string(), None) - .await - .unwrap(); - insta::assert_snapshot!(signature); - } - - #[tokio::test] - async fn subgraphs() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let subgraphs = planner.subgraphs().await.unwrap(); - let subgraphs: BTreeMap = subgraphs.into_iter().collect(); - for schema in subgraphs.values() { - insta::assert_snapshot!(schema); - } - } - - #[tokio::test] - async fn heap_statistics() { - let planner = - Planner::::new(SCHEMA.to_string(), QueryPlannerConfig::default()) - .await - .unwrap(); - - let _subgraphs = planner.subgraphs().await.unwrap(); - let statistics = planner.get_heap_statistics().await.unwrap(); - - println!("statistics: {statistics:?}"); - } -} - -#[cfg(test)] -mod planning_error { - use std::collections::HashMap; - - use crate::planner::PlanError; - use crate::planner::PlanErrorExtensions; - use crate::planner::ReferencedFieldsForType; - use crate::planner::UsageReporting; - - #[test] - #[should_panic( - expected = "Result::unwrap()` on an `Err` value: Error(\"missing field `extensions`\", line: 1, column: 2)" - )] - fn deserialize_empty_planning_error() { - let raw = "{}"; - serde_json::from_str::(raw).unwrap(); - } - - #[test] - #[should_panic( - expected = "Result::unwrap()` on an `Err` value: Error(\"missing field `extensions`\", line: 1, column: 44)" - )] - fn deserialize_planning_error_missing_extension() { - let raw = r#"{ "message": "something terrible happened" }"#; - serde_json::from_str::(raw).unwrap(); - } - - #[test] - fn deserialize_planning_error_with_extension() { - let raw = r#"{ - "message": "something terrible happened", - "extensions": { - "code": "E_TEST_CASE" - } - }"#; - - let expected = PlanError { - message: Some("something terrible happened".to_string()), - extensions: Some(PlanErrorExtensions { - code: "E_TEST_CASE".to_string(), - exception: None, - }), - validation_error: false, - }; - - assert_eq!(expected, serde_json::from_str(raw).unwrap()); - } - - #[test] - fn deserialize_planning_error_with_empty_object_extension() { - let raw = r#"{ - "extensions": {} - }"#; - let expected = PlanError { - message: None, - extensions: None, - validation_error: false, - }; - - assert_eq!(expected, serde_json::from_str(raw).unwrap()); - } - - #[test] - fn deserialize_planning_error_with_null_extension() { - let raw = r#"{ - "extensions": null - }"#; - let expected = PlanError { - message: None, - extensions: None, - validation_error: false, - }; - - assert_eq!(expected, serde_json::from_str(raw).unwrap()); - } - - #[test] - fn deserialize_referenced_fields_for_type_defaults() { - let raw = r#"{}"#; - let expected = ReferencedFieldsForType { - field_names: Vec::new(), - is_interface: false, - }; - - assert_eq!(expected, serde_json::from_str(raw).unwrap()); - } - - #[test] - fn deserialize_usage_reporting_with_defaults() { - let raw = r#"{ - "statsReportKey": "thisIsAtest" - }"#; - let expected = UsageReporting { - stats_report_key: "thisIsAtest".to_string(), - referenced_fields_by_type: HashMap::new(), - }; - - assert_eq!(expected, serde_json::from_str(raw).unwrap()); - } -} - -#[cfg(test)] -mod error_display { - use super::*; - - #[test] - fn error_on_core_in_v0_1_display() { - let expected = r#"one or more checks failed -caused by -the `for:` argument is unsupported by version v0.1 of the core spec. Please upgrade to at least @core v0.2 (https://specs.apollo.dev/core/v0.2). -feature https://specs.apollo.dev/something-unsupported/v0.1 is for: SECURITY but is unsupported"#; - - let error_to_display: PlannerError = WorkerGraphQLError { - name: "CheckFailed".to_string(), - message: "one or more checks failed".to_string(), - locations: Default::default(), - extensions: Some(PlanErrorExtensions { - code: "CheckFailed".to_string(), - exception: None - }), - original_error: None, - causes: vec![ - Box::new(WorkerError { - message: Some("the `for:` argument is unsupported by version v0.1 of the core spec. Please upgrade to at least @core v0.2 (https://specs.apollo.dev/core/v0.2).".to_string()), - name: None, - stack: None, - extensions: Some(PlanErrorExtensions { code: "ForUnsupported".to_string(), exception: None }), - locations: vec![Location { line: 2, column: 1 }, Location { line: 3, column: 1 }, Location { line: 4, column: 1 }] - }), - Box::new(WorkerError { - message: Some("feature https://specs.apollo.dev/something-unsupported/v0.1 is for: SECURITY but is unsupported".to_string()), - name: None, - stack: None, - extensions: Some(PlanErrorExtensions { code: "UnsupportedFeature".to_string(), exception: None }), - locations: vec![Location { line: 4, column: 1 }] - }) - ], - validation_error: false, - }.into(); - - assert_eq!(expected.to_string(), error_to_display.to_string()); - } - - #[test] - fn unsupported_feature_for_execution_display() { - let expected = r#"one or more checks failed -caused by -feature https://specs.apollo.dev/unsupported-feature/v0.1 is for: EXECUTION but is unsupported"#; - - let error_to_display: PlannerError = WorkerGraphQLError { - name: "CheckFailed".to_string(), - message: "one or more checks failed".to_string(), - locations: Default::default(), - extensions: Some(PlanErrorExtensions { - code: "CheckFailed".to_string(), - exception: None - }), - original_error: None, - causes: vec![ - Box::new(WorkerError { - message: Some("feature https://specs.apollo.dev/unsupported-feature/v0.1 is for: EXECUTION but is unsupported".to_string()), - name: None, - stack: None, - extensions: Some(PlanErrorExtensions { code: "UnsupportedFeature".to_string(), exception: None }), - locations: vec![Location { line: 4, column: 9 }] - }), - ], - validation_error: false, - }.into(); - - assert_eq!(expected.to_string(), error_to_display.to_string()); - } - - #[test] - fn unsupported_feature_for_security_display() { - let expected = r#"one or more checks failed -caused by -feature https://specs.apollo.dev/unsupported-feature/v0.1 is for: SECURITY but is unsupported"#; - - let error_to_display: PlannerError = WorkerGraphQLError { - name: "CheckFailed".into(), - message: "one or more checks failed".to_string(), - locations: vec![], - extensions: Some(PlanErrorExtensions { - code: "CheckFailed".to_string(), - exception: None - }), - original_error: None, - causes: vec![Box::new(WorkerError { - message: Some("feature https://specs.apollo.dev/unsupported-feature/v0.1 is for: SECURITY but is unsupported".to_string()), - extensions: Some(PlanErrorExtensions { - code: "UnsupportedFeature".to_string(), - exception: None - }), - name: None, - stack: None, - locations: vec![Location { line: 4, column: 9 }] - })], - validation_error: false, - } - .into(); - - assert_eq!(expected.to_string(), error_to_display.to_string()); - } - - #[tokio::test] - async fn defer_with_fragment() { - let schema = r#" - schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.2", for: EXECUTION) - { - query: Query - } - - directive @join__field(graph: join__Graph!, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - directive @join__graph(name: String!, url: String!) on ENUM_VALUE - directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE - directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR - directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - - scalar link__Import - enum link__Purpose { - SECURITY - EXECUTION - } - - type Computer - @join__type(graph: COMPUTERS) - { - id: ID! - errorField: String - nonNullErrorField: String! - } - - scalar join__FieldSet - - enum join__Graph { - COMPUTERS @join__graph(name: "computers", url: "http://localhost:4001/") - } - - - type Query - @join__type(graph: COMPUTERS) - { - computer(id: ID!): Computer - }"#; - - let planner = Planner::::new( - schema.to_string(), - QueryPlannerConfig { - generate_query_fragments: Default::default(), - incremental_delivery: Some(IncrementalDeliverySupport { - enable_defer: Some(true), - }), - graphql_validation: true, - reuse_query_fragments: None, - debug: Default::default(), - type_conditioned_fetching: false, - }, - ) - .await - .unwrap(); - - let plan_response = planner - .plan( - r#"query { - computer(id: "Computer1") { - id - ...ComputerErrorField @defer - } - } - fragment ComputerErrorField on Computer { - errorField - }"# - .to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .data - .unwrap(); - - insta::assert_snapshot!(serde_json::to_string_pretty(&plan_response).unwrap()); - } - - #[tokio::test] - async fn defer_query_plan() { - let schema = r#"schema - @core(feature: "https://specs.apollo.dev/core/v0.1") - @core(feature: "https://specs.apollo.dev/join/v0.1") - @core(feature: "https://specs.apollo.dev/inaccessible/v0.1") - { - query: Query - } - directive @core(feature: String!) repeatable on SCHEMA - directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet) on FIELD_DEFINITION - directive @join__type(graph: join__Graph!, key: join__FieldSet) repeatable on OBJECT | INTERFACE - directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE - directive @join__graph(name: String!, url: String!) on ENUM_VALUE - directive @inaccessible on OBJECT | FIELD_DEFINITION | INTERFACE | UNION - scalar join__FieldSet - enum join__Graph { - USER @join__graph(name: "user", url: "http://localhost:4001/graphql") - ORGA @join__graph(name: "orga", url: "http://localhost:4002/graphql") - } - type Query { - currentUser: User @join__field(graph: USER) - } - type User - @join__owner(graph: USER) - @join__type(graph: ORGA, key: "id") - @join__type(graph: USER, key: "id"){ - id: ID! - name: String - activeOrganization: Organization - } - type Organization - @join__owner(graph: ORGA) - @join__type(graph: ORGA, key: "id") - @join__type(graph: USER, key: "id") { - id: ID - creatorUser: User - name: String - nonNullId: ID! - suborga: [Organization] - }"#; - - let planner = Planner::::new( - schema.to_string(), - QueryPlannerConfig { - generate_query_fragments: Default::default(), - incremental_delivery: Some(IncrementalDeliverySupport { - enable_defer: Some(true), - }), - graphql_validation: true, - reuse_query_fragments: None, - debug: Default::default(), - type_conditioned_fetching: false, - }, - ) - .await - .unwrap(); - - insta::assert_snapshot!(serde_json::to_string_pretty(&planner - .plan( - "query { currentUser { activeOrganization { id suborga { id ...@defer { nonNullId } } } } }" - .to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .data - .unwrap()).unwrap()); - } - - #[tokio::test] - async fn propagate_internal_qp_errors() { - let schema = r#" - schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.2", for: EXECUTION) - { - query: Query - subscription: Subscription - } - - directive @join__field(graph: join__Graph!, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - directive @join__graph(name: String!, url: String!) on ENUM_VALUE - directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE - directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR - directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - - scalar link__Import - enum link__Purpose { - SECURITY - EXECUTION - } - - type Computer - @join__type(graph: COMPUTERS) - { - id: ID! - errorField: String - nonNullErrorField: String! - gpus: [GPU] - } - - type GPU @join__type(graph: COMPUTERS) @join__type(graph: GPUS) { - id: ID! - wattage: Int! @join__field(graph: GPUS) - } - - scalar join__FieldSet - - enum join__Graph { - COMPUTERS @join__graph(name: "computers", url: "http://localhost:4001/") - GPUS @join__graph(name: "gpus", url: "http://localhost:4002/") - } - - - type Query - @join__type(graph: COMPUTERS) - { - computer(id: ID!): Computer - } - type Subscription @join__type(graph: COMPUTERS) { - computer(id: ID!): Computer - }"#; - - let planner = Planner::::new( - schema.to_string(), - QueryPlannerConfig { - incremental_delivery: Some(IncrementalDeliverySupport { - enable_defer: Some(true), - }), - graphql_validation: true, - reuse_query_fragments: None, - generate_query_fragments: None, - debug: Default::default(), - type_conditioned_fetching: false, - }, - ) - .await - .unwrap(); - - insta::assert_snapshot!(serde_json::to_string_pretty( - &planner - .plan( - "subscription { computer(id: 1) { ... @defer { gpus { wattage } } } }" - .to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .errors - .unwrap() - ) - .unwrap()); - } - - static TYPED_CONDITION_SCHEMA: &str = include_str!("testdata/typed_conditions.graphql"); - - #[tokio::test] - async fn typed_condition_field_merging_disabled() { - let planner = Planner::::new( - TYPED_CONDITION_SCHEMA.to_string(), - QueryPlannerConfig { - generate_query_fragments: Default::default(), - incremental_delivery: Some(IncrementalDeliverySupport { - enable_defer: Some(true), - }), - graphql_validation: true, - reuse_query_fragments: None, - debug: Default::default(), - type_conditioned_fetching: false, - }, - ) - .await - .unwrap(); - - insta::assert_snapshot!(serde_json::to_string_pretty( - &planner - .plan( - "query Search($movieParams: String, $articleParams: String) { - search { - __typename - ... on MovieResult { - id - sections { - ... on EntityCollectionSection { - id - artwork(params: $movieParams) - } - } - } - ... on ArticleResult { - id - sections { - ... on EntityCollectionSection { - id - artwork(params: $articleParams) - title - } - } - } - } - }" - .to_string(), - None, - PlanOptions::default(), - ) - .await - .unwrap() - .data - .unwrap() - ) - .unwrap()); - } - #[tokio::test] - async fn typed_condition_field_merging_enabled() { - let planner = Planner::::new( - TYPED_CONDITION_SCHEMA.to_string(), - QueryPlannerConfig { - generate_query_fragments: Default::default(), - incremental_delivery: Some(IncrementalDeliverySupport { - enable_defer: Some(true), - }), - graphql_validation: true, - reuse_query_fragments: None, - debug: Default::default(), - type_conditioned_fetching: true, - }, - ) - .await - .unwrap(); - - insta::assert_snapshot!(serde_json::to_string_pretty( - &planner - .plan( - "query Search($movieParams: String, $articleParams: String) { - search { - __typename - ... on MovieResult { - id - sections { - ... on EntityCollectionSection { - id - artwork(params: $movieParams) - } - } - } - ... on ArticleResult { - id - sections { - ... on EntityCollectionSection { - id - artwork(params: $articleParams) - title - } - } - } - } - }" - .to_string(), - None, - PlanOptions { - ..Default::default() - }, - ) - .await - .unwrap() - .data - .unwrap() - ) - .unwrap()); - } - - #[tokio::test] - async fn extracts_cost_directives() { - let schema = include_str!("testdata/custom_cost_schema.graphql"); - let planner = Planner::::new(schema.to_string(), Default::default()) - .await - .expect("can create planner"); - let subgraphs = planner.subgraphs().await.expect("can extract subgraphs"); - - for (name, schema) in subgraphs { - insta::assert_snapshot!(name, schema); - } - } -} diff --git a/router-bridge/src/snapshots/router_bridge__api_schema__tests__it_works.snap b/router-bridge/src/snapshots/router_bridge__api_schema__tests__it_works.snap deleted file mode 100644 index 561ca4e3f..000000000 --- a/router-bridge/src/snapshots/router_bridge__api_schema__tests__it_works.snap +++ /dev/null @@ -1,41 +0,0 @@ ---- -source: router-bridge/src/api_schema.rs -assertion_line: 60 -expression: "&api_schema.unwrap()" - ---- -directive @apollo_studio_metadata(launchId: String, buildId: String, checkId: String) on SCHEMA - -type Mutation { - createProduct(name: String, upc: ID!): Product - createReview(body: String, id: ID!, upc: ID!): Review -} - -type Product { - name: String - price: Int - reviews: [Review] - reviewsForAuthor(authorID: ID!): [Review] - shippingEstimate: Int - upc: String! - weight: Int -} - -type Query { - me: User - topProducts(first: Int = 5): [Product] -} - -type Review { - author: User - body: String - id: ID! - product: Product -} - -type User { - id: ID! - name: String - reviews: [Review] - username: String -} diff --git a/router-bridge/src/snapshots/router_bridge__introspect__tests__defer_in_introspection-2.snap b/router-bridge/src/snapshots/router_bridge__introspect__tests__defer_in_introspection-2.snap deleted file mode 100644 index ca0b7aa50..000000000 --- a/router-bridge/src/snapshots/router_bridge__introspect__tests__defer_in_introspection-2.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: router-bridge/src/introspect.rs -assertion_line: 313 -expression: "serde_json::to_string(&introspected).unwrap()" ---- -{"Ok":[{"data":{"__schema":{"directives":[{"name":"defer","locations":["FRAGMENT_SPREAD","INLINE_FRAGMENT"]},{"name":"include","locations":["FIELD","FRAGMENT_SPREAD","INLINE_FRAGMENT"]},{"name":"skip","locations":["FIELD","FRAGMENT_SPREAD","INLINE_FRAGMENT"]},{"name":"deprecated","locations":["FIELD_DEFINITION","ARGUMENT_DEFINITION","INPUT_FIELD_DEFINITION","ENUM_VALUE"]},{"name":"specifiedBy","locations":["SCALAR"]}]}},"errors":[]}]} diff --git a/router-bridge/src/snapshots/router_bridge__introspect__tests__defer_in_introspection.snap b/router-bridge/src/snapshots/router_bridge__introspect__tests__defer_in_introspection.snap deleted file mode 100644 index 6826caf1f..000000000 --- a/router-bridge/src/snapshots/router_bridge__introspect__tests__defer_in_introspection.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: router-bridge/src/introspect.rs -assertion_line: 290 -expression: "serde_json::to_string(&introspected).unwrap()" ---- -{"Ok":[{"data":{"__schema":{"directives":[{"name":"include","locations":["FIELD","FRAGMENT_SPREAD","INLINE_FRAGMENT"]},{"name":"skip","locations":["FIELD","FRAGMENT_SPREAD","INLINE_FRAGMENT"]},{"name":"deprecated","locations":["FIELD_DEFINITION","ARGUMENT_DEFINITION","INPUT_FIELD_DEFINITION","ENUM_VALUE"]},{"name":"specifiedBy","locations":["SCALAR"]}]}},"errors":[]}]} diff --git a/router-bridge/src/snapshots/router_bridge__introspect__tests__it_works.snap b/router-bridge/src/snapshots/router_bridge__introspect__tests__it_works.snap deleted file mode 100644 index 21e051a7f..000000000 --- a/router-bridge/src/snapshots/router_bridge__introspect__tests__it_works.snap +++ /dev/null @@ -1,7 +0,0 @@ ---- -source: router-bridge/src/introspect.rs -assertion_line: 112 -expression: "serde_json::to_string(&introspected).unwrap()" - ---- -{"Ok":[{"data":{"__schema":{"queryType":{"name":"Query"},"mutationType":null,"subscriptionType":null,"types":[{"kind":"OBJECT","name":"Query","description":null,"fields":[{"name":"hello","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null}],"inputFields":null,"interfaces":[],"enumValues":null,"possibleTypes":null},{"kind":"SCALAR","name":"String","description":"The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.","fields":null,"inputFields":null,"interfaces":null,"enumValues":null,"possibleTypes":null},{"kind":"SCALAR","name":"Boolean","description":"The `Boolean` scalar type represents `true` or `false`.","fields":null,"inputFields":null,"interfaces":null,"enumValues":null,"possibleTypes":null},{"kind":"OBJECT","name":"__Schema","description":"A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.","fields":[{"name":"description","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"types","description":"A list of all types supported by this server.","args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__Type","ofType":null}}}},"isDeprecated":false,"deprecationReason":null},{"name":"queryType","description":"The type that query operations will be rooted at.","args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__Type","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"mutationType","description":"If this server supports mutation, the type that mutation operations will be rooted at.","args":[],"type":{"kind":"OBJECT","name":"__Type","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"subscriptionType","description":"If this server support subscription, the type that subscription operations will be rooted at.","args":[],"type":{"kind":"OBJECT","name":"__Type","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"directives","description":"A list of all directives supported by this server.","args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__Directive","ofType":null}}}},"isDeprecated":false,"deprecationReason":null}],"inputFields":null,"interfaces":[],"enumValues":null,"possibleTypes":null},{"kind":"OBJECT","name":"__Type","description":"The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\n\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name, description and optional `specifiedByURL`, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.","fields":[{"name":"kind","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"ENUM","name":"__TypeKind","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"name","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"description","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"specifiedByURL","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"fields","description":null,"args":[{"name":"includeDeprecated","description":null,"type":{"kind":"SCALAR","name":"Boolean","ofType":null},"defaultValue":"false"}],"type":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__Field","ofType":null}}},"isDeprecated":false,"deprecationReason":null},{"name":"interfaces","description":null,"args":[],"type":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__Type","ofType":null}}},"isDeprecated":false,"deprecationReason":null},{"name":"possibleTypes","description":null,"args":[],"type":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__Type","ofType":null}}},"isDeprecated":false,"deprecationReason":null},{"name":"enumValues","description":null,"args":[{"name":"includeDeprecated","description":null,"type":{"kind":"SCALAR","name":"Boolean","ofType":null},"defaultValue":"false"}],"type":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__EnumValue","ofType":null}}},"isDeprecated":false,"deprecationReason":null},{"name":"inputFields","description":null,"args":[{"name":"includeDeprecated","description":null,"type":{"kind":"SCALAR","name":"Boolean","ofType":null},"defaultValue":"false"}],"type":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__InputValue","ofType":null}}},"isDeprecated":false,"deprecationReason":null},{"name":"ofType","description":null,"args":[],"type":{"kind":"OBJECT","name":"__Type","ofType":null},"isDeprecated":false,"deprecationReason":null}],"inputFields":null,"interfaces":[],"enumValues":null,"possibleTypes":null},{"kind":"ENUM","name":"__TypeKind","description":"An enum describing what kind of type a given `__Type` is.","fields":null,"inputFields":null,"interfaces":null,"enumValues":[{"name":"SCALAR","description":"Indicates this type is a scalar.","isDeprecated":false,"deprecationReason":null},{"name":"OBJECT","description":"Indicates this type is an object. `fields` and `interfaces` are valid fields.","isDeprecated":false,"deprecationReason":null},{"name":"INTERFACE","description":"Indicates this type is an interface. `fields`, `interfaces`, and `possibleTypes` are valid fields.","isDeprecated":false,"deprecationReason":null},{"name":"UNION","description":"Indicates this type is a union. `possibleTypes` is a valid field.","isDeprecated":false,"deprecationReason":null},{"name":"ENUM","description":"Indicates this type is an enum. `enumValues` is a valid field.","isDeprecated":false,"deprecationReason":null},{"name":"INPUT_OBJECT","description":"Indicates this type is an input object. `inputFields` is a valid field.","isDeprecated":false,"deprecationReason":null},{"name":"LIST","description":"Indicates this type is a list. `ofType` is a valid field.","isDeprecated":false,"deprecationReason":null},{"name":"NON_NULL","description":"Indicates this type is a non-null. `ofType` is a valid field.","isDeprecated":false,"deprecationReason":null}],"possibleTypes":null},{"kind":"OBJECT","name":"__Field","description":"Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.","fields":[{"name":"name","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"String","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"description","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"args","description":null,"args":[{"name":"includeDeprecated","description":null,"type":{"kind":"SCALAR","name":"Boolean","ofType":null},"defaultValue":"false"}],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__InputValue","ofType":null}}}},"isDeprecated":false,"deprecationReason":null},{"name":"type","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__Type","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"isDeprecated","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"deprecationReason","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null}],"inputFields":null,"interfaces":[],"enumValues":null,"possibleTypes":null},{"kind":"OBJECT","name":"__InputValue","description":"Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.","fields":[{"name":"name","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"String","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"description","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"type","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__Type","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"defaultValue","description":"A GraphQL-formatted string representing the default value for this input value.","args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"isDeprecated","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"deprecationReason","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null}],"inputFields":null,"interfaces":[],"enumValues":null,"possibleTypes":null},{"kind":"OBJECT","name":"__EnumValue","description":"One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.","fields":[{"name":"name","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"String","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"description","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"isDeprecated","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"deprecationReason","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null}],"inputFields":null,"interfaces":[],"enumValues":null,"possibleTypes":null},{"kind":"OBJECT","name":"__Directive","description":"A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.","fields":[{"name":"name","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"String","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"description","description":null,"args":[],"type":{"kind":"SCALAR","name":"String","ofType":null},"isDeprecated":false,"deprecationReason":null},{"name":"isRepeatable","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"isDeprecated":false,"deprecationReason":null},{"name":"locations","description":null,"args":[],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"ENUM","name":"__DirectiveLocation","ofType":null}}}},"isDeprecated":false,"deprecationReason":null},{"name":"args","description":null,"args":[{"name":"includeDeprecated","description":null,"type":{"kind":"SCALAR","name":"Boolean","ofType":null},"defaultValue":"false"}],"type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"LIST","name":null,"ofType":{"kind":"NON_NULL","name":null,"ofType":{"kind":"OBJECT","name":"__InputValue","ofType":null}}}},"isDeprecated":false,"deprecationReason":null}],"inputFields":null,"interfaces":[],"enumValues":null,"possibleTypes":null},{"kind":"ENUM","name":"__DirectiveLocation","description":"A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.","fields":null,"inputFields":null,"interfaces":null,"enumValues":[{"name":"QUERY","description":"Location adjacent to a query operation.","isDeprecated":false,"deprecationReason":null},{"name":"MUTATION","description":"Location adjacent to a mutation operation.","isDeprecated":false,"deprecationReason":null},{"name":"SUBSCRIPTION","description":"Location adjacent to a subscription operation.","isDeprecated":false,"deprecationReason":null},{"name":"FIELD","description":"Location adjacent to a field.","isDeprecated":false,"deprecationReason":null},{"name":"FRAGMENT_DEFINITION","description":"Location adjacent to a fragment definition.","isDeprecated":false,"deprecationReason":null},{"name":"FRAGMENT_SPREAD","description":"Location adjacent to a fragment spread.","isDeprecated":false,"deprecationReason":null},{"name":"INLINE_FRAGMENT","description":"Location adjacent to an inline fragment.","isDeprecated":false,"deprecationReason":null},{"name":"VARIABLE_DEFINITION","description":"Location adjacent to a variable definition.","isDeprecated":false,"deprecationReason":null},{"name":"SCHEMA","description":"Location adjacent to a schema definition.","isDeprecated":false,"deprecationReason":null},{"name":"SCALAR","description":"Location adjacent to a scalar definition.","isDeprecated":false,"deprecationReason":null},{"name":"OBJECT","description":"Location adjacent to an object type definition.","isDeprecated":false,"deprecationReason":null},{"name":"FIELD_DEFINITION","description":"Location adjacent to a field definition.","isDeprecated":false,"deprecationReason":null},{"name":"ARGUMENT_DEFINITION","description":"Location adjacent to an argument definition.","isDeprecated":false,"deprecationReason":null},{"name":"INTERFACE","description":"Location adjacent to an interface definition.","isDeprecated":false,"deprecationReason":null},{"name":"UNION","description":"Location adjacent to a union definition.","isDeprecated":false,"deprecationReason":null},{"name":"ENUM","description":"Location adjacent to an enum definition.","isDeprecated":false,"deprecationReason":null},{"name":"ENUM_VALUE","description":"Location adjacent to an enum value definition.","isDeprecated":false,"deprecationReason":null},{"name":"INPUT_OBJECT","description":"Location adjacent to an input object type definition.","isDeprecated":false,"deprecationReason":null},{"name":"INPUT_FIELD_DEFINITION","description":"Location adjacent to an input object field definition.","isDeprecated":false,"deprecationReason":null}],"possibleTypes":null}],"directives":[{"name":"include","description":"Directs the executor to include this field or fragment only when the `if` argument is true.","locations":["FIELD","FRAGMENT_SPREAD","INLINE_FRAGMENT"],"args":[{"name":"if","description":"Included when true.","type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"defaultValue":null}]},{"name":"skip","description":"Directs the executor to skip this field or fragment when the `if` argument is true.","locations":["FIELD","FRAGMENT_SPREAD","INLINE_FRAGMENT"],"args":[{"name":"if","description":"Skipped when true.","type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"Boolean","ofType":null}},"defaultValue":null}]},{"name":"deprecated","description":"Marks an element of a GraphQL schema as no longer supported.","locations":["FIELD_DEFINITION","ARGUMENT_DEFINITION","INPUT_FIELD_DEFINITION","ENUM_VALUE"],"args":[{"name":"reason","description":"Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted using the Markdown syntax, as specified by [CommonMark](https://commonmark.org/).","type":{"kind":"SCALAR","name":"String","ofType":null},"defaultValue":"\"No longer supported\""}]},{"name":"specifiedBy","description":"Exposes a URL that specifies the behavior of this scalar.","locations":["SCALAR"],"args":[{"name":"url","description":"The URL that specifies the behavior of this scalar.","type":{"kind":"NON_NULL","name":null,"ofType":{"kind":"SCALAR","name":"String","ofType":null}},"defaultValue":null}]}]}},"errors":[]}]} diff --git a/router-bridge/src/snapshots/router_bridge__plan__tests__it_works.snap b/router-bridge/src/snapshots/router_bridge__plan__tests__it_works.snap deleted file mode 100644 index b13d9d581..000000000 --- a/router-bridge/src/snapshots/router_bridge__plan__tests__it_works.snap +++ /dev/null @@ -1,18 +0,0 @@ ---- -source: router-bridge/src/plan.rs -assertion_line: 174 -expression: "serde_json::to_string_pretty(&plan::(OperationalContext{schema:\n SCHEMA.to_string(),\n query:\n QUERY.to_string(),\n operation_name:\n \"\".to_string(),},\n QueryPlanOptions::default()).unwrap()).unwrap()" - ---- -{ - "Ok": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "accounts", - "variableUsages": [], - "operation": "{me{name{first last}}}", - "operationKind": "query" - } - } -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__error_display__defer_query_plan.snap b/router-bridge/src/snapshots/router_bridge__planner__error_display__defer_query_plan.snap deleted file mode 100644 index 4433c7f11..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__error_display__defer_query_plan.snap +++ /dev/null @@ -1,107 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&planner.plan(\"query { currentUser { activeOrganization { id suborga { id ...@defer { nonNullId } } } } }\".to_string(),\n None,\n PlanOptions::default()).await.unwrap().data.unwrap()).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Defer", - "primary": { - "subselection": "{ currentUser { activeOrganization { id suborga { id } } } }", - "node": { - "kind": "Sequence", - "nodes": [ - { - "kind": "Fetch", - "serviceName": "user", - "variableUsages": [], - "operation": "{currentUser{activeOrganization{__typename id}}}", - "operationKind": "query" - }, - { - "kind": "Flatten", - "path": [ - "currentUser", - "activeOrganization" - ], - "node": { - "kind": "Fetch", - "id": "0", - "serviceName": "orga", - "requires": [ - { - "kind": "InlineFragment", - "typeCondition": "Organization", - "selections": [ - { - "kind": "Field", - "name": "__typename" - }, - { - "kind": "Field", - "name": "id" - } - ] - } - ], - "variableUsages": [], - "operation": "query($representations:[_Any!]!){_entities(representations:$representations){...on Organization{suborga{__typename id}}}}", - "operationKind": "query" - } - } - ] - } - }, - "deferred": [ - { - "depends": [ - { - "id": "0" - } - ], - "queryPath": [ - "currentUser", - "activeOrganization", - "suborga" - ], - "subselection": "{ nonNullId }", - "node": { - "kind": "Flatten", - "path": [ - "currentUser", - "activeOrganization", - "suborga", - "@" - ], - "node": { - "kind": "Fetch", - "serviceName": "orga", - "requires": [ - { - "kind": "InlineFragment", - "typeCondition": "Organization", - "selections": [ - { - "kind": "Field", - "name": "__typename" - }, - { - "kind": "Field", - "name": "id" - } - ] - } - ], - "variableUsages": [], - "operation": "query($representations:[_Any!]!){_entities(representations:$representations){...on Organization{nonNullId}}}", - "operationKind": "query" - } - } - } - ] - } - }, - "formattedQueryPlan": "QueryPlan {\n Defer {\n Primary {\n {\n currentUser {\n activeOrganization {\n id\n suborga {\n id\n }\n }\n }\n }:\n Sequence {\n Fetch(service: \"user\") {\n {\n currentUser {\n activeOrganization {\n __typename\n id\n }\n }\n }\n },\n Flatten(path: \"currentUser.activeOrganization\") {\n Fetch(service: \"orga\", id: 0) {\n {\n ... on Organization {\n __typename\n id\n }\n } =>\n {\n ... on Organization {\n suborga {\n __typename\n id\n }\n }\n }\n },\n },\n }\n }, [\n Deferred(depends: [0], path: \"currentUser/activeOrganization/suborga\") {\n {\n nonNullId\n }:\n Flatten(path: \"currentUser.activeOrganization.suborga.@\") {\n Fetch(service: \"orga\") {\n {\n ... on Organization {\n __typename\n id\n }\n } =>\n {\n ... on Organization {\n nonNullId\n }\n }\n },\n }\n },\n ]\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__error_display__defer_with_fragment.snap b/router-bridge/src/snapshots/router_bridge__planner__error_display__defer_with_fragment.snap deleted file mode 100644 index 167118179..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__error_display__defer_with_fragment.snap +++ /dev/null @@ -1,33 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&plan_response).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Defer", - "primary": { - "subselection": "{ computer(id: \"Computer1\") { id } }", - "node": { - "kind": "Fetch", - "serviceName": "computers", - "variableUsages": [], - "operation": "{computer(id:\"Computer1\"){id errorField}}", - "operationKind": "query" - } - }, - "deferred": [ - { - "depends": [], - "queryPath": [ - "computer" - ], - "subselection": "{ ... on Computer { errorField } }" - } - ] - } - }, - "formattedQueryPlan": "QueryPlan {\n Defer {\n Primary {\n {\n computer(id: \"Computer1\") {\n id\n }\n }:\n Fetch(service: \"computers\") {\n {\n computer(id: \"Computer1\") {\n id\n errorField\n }\n }\n }\n }, [\n Deferred(depends: [], path: \"computer\") {\n {\n ... on Computer {\n errorField\n }\n }:\n },\n ]\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__error_display__propagate_internal_qp_errors.snap b/router-bridge/src/snapshots/router_bridge__planner__error_display__propagate_internal_qp_errors.snap deleted file mode 100644 index 6d18432ca..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__error_display__propagate_internal_qp_errors.snap +++ /dev/null @@ -1,15 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&planner.plan(\"subscription { computer(id: 1) { ... @defer { gpus { wattage } } } }\".to_string(),\n None,\n PlanOptions::default()).await.unwrap().errors.unwrap()).unwrap()" ---- -[ - { - "message": "@defer is not supported on subscriptions", - "extensions": { - "code": "QUERY_PLANNING_FAILED", - "exception": { - "stacktrace": "Error: @defer is not supported on subscriptions" - } - } - } -] diff --git a/router-bridge/src/snapshots/router_bridge__planner__error_display__subgraphWithCost.snap b/router-bridge/src/snapshots/router_bridge__planner__error_display__subgraphWithCost.snap deleted file mode 100644 index 56a2d5334..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__error_display__subgraphWithCost.snap +++ /dev/null @@ -1,112 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: schema ---- -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"]) -{ - query: Query -} - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE - -directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @external(reason: String) on OBJECT | FIELD_DEFINITION - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA - -directive @extends on OBJECT | INTERFACE - -directive @shareable repeatable on OBJECT | FIELD_DEFINITION - -directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - -directive @override(from: String!, label: String) on FIELD_DEFINITION - -directive @composeDirective(name: String) repeatable on SCHEMA - -directive @interfaceObject on OBJECT - -directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__policy(policies: [[federation__Policy!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__sourceAPI repeatable on SCHEMA - -directive @federation__sourceType repeatable on OBJECT | INTERFACE - -directive @federation__sourceField repeatable on FIELD_DEFINITION - -directive @federation__context(name: String!) repeatable on INTERFACE | OBJECT | UNION - -directive @federation__fromContext(field: federation__ContextFieldValue) on ARGUMENT_DEFINITION - -directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -scalar link__Import - -scalar federation__FieldSet - -scalar federation__Scope - -scalar federation__Policy - -scalar federation__ContextFieldValue - -enum AorB - @federation__cost(weight: 15) -{ - A - B -} - -scalar ExpensiveInt - @federation__cost(weight: 30) - -type ExpensiveObject - @federation__cost(weight: 40) -{ - id: ID -} - -input InputTypeWithCost { - somethingWithCost: Int @federation__cost(weight: 20) -} - -type Query { - fieldWithCost: Int @federation__cost(weight: 5) - argWithCost(arg: Int @federation__cost(weight: 10)): Int - enumWithCost: AorB - inputWithCost(someInput: InputTypeWithCost): Int - scalarWithCost: ExpensiveInt - objectWithCost: ExpensiveObject - _service: _Service! -} - -scalar _Any - -type _Service { - sdl: String -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__error_display__subgraphWithListSize.snap b/router-bridge/src/snapshots/router_bridge__planner__error_display__subgraphWithListSize.snap deleted file mode 100644 index 59c1a205d..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__error_display__subgraphWithListSize.snap +++ /dev/null @@ -1,96 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: schema ---- -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"]) -{ - query: Query -} - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE - -directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @external(reason: String) on OBJECT | FIELD_DEFINITION - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA - -directive @extends on OBJECT | INTERFACE - -directive @shareable repeatable on OBJECT | FIELD_DEFINITION - -directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - -directive @override(from: String!, label: String) on FIELD_DEFINITION - -directive @composeDirective(name: String) repeatable on SCHEMA - -directive @interfaceObject on OBJECT - -directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__policy(policies: [[federation__Policy!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__sourceAPI repeatable on SCHEMA - -directive @federation__sourceType repeatable on OBJECT | INTERFACE - -directive @federation__sourceField repeatable on FIELD_DEFINITION - -directive @federation__context(name: String!) repeatable on INTERFACE | OBJECT | UNION - -directive @federation__fromContext(field: federation__ContextFieldValue) on ARGUMENT_DEFINITION - -directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -scalar link__Import - -scalar federation__FieldSet - -scalar federation__Scope - -scalar federation__Policy - -scalar federation__ContextFieldValue - -type A { - id: ID -} - -type Query { - fieldWithListSize: [String!] @federation__listSize(assumedSize: 2000, requireOneSlicingArgument: false) - fieldWithDynamicListSize(first: Int = 10): SizedField @federation__listSize(slicingArguments: ["first"], sizedFields: ["items"], requireOneSlicingArgument: true) - _service: _Service! -} - -type SizedField { - items: [A] -} - -scalar _Any - -type _Service { - sdl: String -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__error_display__typed_condition_field_merging_disabled.snap b/router-bridge/src/snapshots/router_bridge__planner__error_display__typed_condition_field_merging_disabled.snap deleted file mode 100644 index 4c3483ff8..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__error_display__typed_condition_field_merging_disabled.snap +++ /dev/null @@ -1,59 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&planner.plan(\"query Search($movieParams: String, $articleParams: String) {\n search {\n __typename\n ... on MovieResult {\n id\n sections {\n ... on EntityCollectionSection {\n id\n artwork(params: $movieParams)\n }\n }\n }\n ... on ArticleResult {\n id\n sections {\n ... on EntityCollectionSection {\n id\n artwork(params: $articleParams)\n title\n }\n }\n }\n }\n }\".to_string(),\n None,\n PlanOptions::default()).await.unwrap().data.unwrap()).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Sequence", - "nodes": [ - { - "kind": "Fetch", - "serviceName": "searchSubgraph", - "variableUsages": [], - "operation": "query Search__searchSubgraph__0{search{__typename ...on MovieResult{id sections{__typename ...on EntityCollectionSection{__typename id}}}...on ArticleResult{id sections{__typename ...on EntityCollectionSection{__typename id}}}}}", - "operationKind": "query", - "operationName": "Search__searchSubgraph__0" - }, - { - "kind": "Flatten", - "path": [ - "search", - "@", - "sections", - "@" - ], - "node": { - "kind": "Fetch", - "serviceName": "artworkSubgraph", - "requires": [ - { - "kind": "InlineFragment", - "typeCondition": "EntityCollectionSection", - "selections": [ - { - "kind": "Field", - "name": "__typename" - }, - { - "kind": "Field", - "name": "id" - } - ] - } - ], - "variableUsages": [ - "movieParams" - ], - "operation": "query Search__artworkSubgraph__1($representations:[_Any!]!$movieParams:String){_entities(representations:$representations){...on EntityCollectionSection{artwork(params:$movieParams)title}}}", - "operationKind": "query", - "operationName": "Search__artworkSubgraph__1" - } - } - ] - } - }, - "formattedQueryPlan": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ... on MovieResult {\n id\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Flatten(path: \"search.@.sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n artwork(params: $movieParams)\n title\n }\n }\n },\n },\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__error_display__typed_condition_field_merging_enabled.snap b/router-bridge/src/snapshots/router_bridge__planner__error_display__typed_condition_field_merging_enabled.snap deleted file mode 100644 index f91c9a26e..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__error_display__typed_condition_field_merging_enabled.snap +++ /dev/null @@ -1,101 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&planner.plan(\"query Search($movieParams: String, $articleParams: String) {\n search {\n __typename\n ... on MovieResult {\n id\n sections {\n ... on EntityCollectionSection {\n id\n artwork(params: $movieParams)\n }\n }\n }\n ... on ArticleResult {\n id\n sections {\n ... on EntityCollectionSection {\n id\n artwork(params: $articleParams)\n title\n }\n }\n }\n }\n }\".to_string(),\n None,\n PlanOptions {\n ..Default::default()\n }).await.unwrap().data.unwrap()).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Sequence", - "nodes": [ - { - "kind": "Fetch", - "serviceName": "searchSubgraph", - "variableUsages": [], - "operation": "query Search__searchSubgraph__0{search{__typename ...on MovieResult{id sections{__typename ...on EntityCollectionSection{__typename id}}}...on ArticleResult{id sections{__typename ...on EntityCollectionSection{__typename id}}}}}", - "operationKind": "query", - "operationName": "Search__searchSubgraph__0" - }, - { - "kind": "Parallel", - "nodes": [ - { - "kind": "Flatten", - "path": [ - "", - "search", - "@|[MovieResult]", - "sections", - "@" - ], - "node": { - "kind": "Fetch", - "serviceName": "artworkSubgraph", - "requires": [ - { - "kind": "InlineFragment", - "typeCondition": "EntityCollectionSection", - "selections": [ - { - "kind": "Field", - "name": "__typename" - }, - { - "kind": "Field", - "name": "id" - } - ] - } - ], - "variableUsages": [ - "movieParams" - ], - "operation": "query Search__artworkSubgraph__1($representations:[_Any!]!$movieParams:String){_entities(representations:$representations){...on EntityCollectionSection{artwork(params:$movieParams)}}}", - "operationKind": "query", - "operationName": "Search__artworkSubgraph__1" - } - }, - { - "kind": "Flatten", - "path": [ - "", - "search", - "@|[ArticleResult]", - "sections", - "@" - ], - "node": { - "kind": "Fetch", - "serviceName": "artworkSubgraph", - "requires": [ - { - "kind": "InlineFragment", - "typeCondition": "EntityCollectionSection", - "selections": [ - { - "kind": "Field", - "name": "__typename" - }, - { - "kind": "Field", - "name": "id" - } - ] - } - ], - "variableUsages": [ - "articleParams" - ], - "operation": "query Search__artworkSubgraph__2($representations:[_Any!]!$articleParams:String){_entities(representations:$representations){...on EntityCollectionSection{artwork(params:$articleParams)title}}}", - "operationKind": "query", - "operationName": "Search__artworkSubgraph__2" - } - } - ] - } - ] - } - }, - "formattedQueryPlan": "QueryPlan {\n Sequence {\n Fetch(service: \"searchSubgraph\") {\n {\n search {\n __typename\n ... on MovieResult {\n id\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n ... on ArticleResult {\n id\n sections {\n __typename\n ... on EntityCollectionSection {\n __typename\n id\n }\n }\n }\n }\n }\n },\n Parallel {\n Flatten(path: \".search.@|[MovieResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n artwork(params: $movieParams)\n }\n }\n },\n },\n Flatten(path: \".search.@|[ArticleResult].sections.@\") {\n Fetch(service: \"artworkSubgraph\") {\n {\n ... on EntityCollectionSection {\n __typename\n id\n }\n } =>\n {\n ... on EntityCollectionSection {\n artwork(params: $articleParams)\n title\n }\n }\n },\n },\n },\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__anonymous_query_works-2.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__anonymous_query_works-2.snap deleted file mode 100644 index 5693c8149..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__anonymous_query_works-2.snap +++ /dev/null @@ -1,28 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: payload.usage_reporting ---- -{ - "statsReportKey": "# -\n{me{name{first last}}}", - "referencedFieldsByType": { - "Name": { - "fieldNames": [ - "first", - "last" - ], - "isInterface": false - }, - "Query": { - "fieldNames": [ - "me" - ], - "isInterface": false - }, - "User": { - "fieldNames": [ - "name" - ], - "isInterface": false - } - } -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__anonymous_query_works.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__anonymous_query_works.snap deleted file mode 100644 index 186a845fc..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__anonymous_query_works.snap +++ /dev/null @@ -1,18 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "accounts", - "variableUsages": [], - "operation": "{me{name{first last}}}", - "operationKind": "query" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"accounts\") {\n {\n me {\n name {\n first\n last\n }\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__api_schema.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__api_schema.snap deleted file mode 100644 index 2550f9f47..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__api_schema.snap +++ /dev/null @@ -1,205 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: api_schema.schema ---- -directive @transform(from: String!) on FIELD - -union AccountType = PasswordAccount | SMSAccount - -type Amazon { - referrer: String -} - -union Body = Image | Text - -type Book implements Product { - isbn: String! - title: String - year: Int - similarBooks: [Book]! - metadata: [MetadataOrError] - inStock: Boolean - isCheckedOut: Boolean - upc: String! - sku: String! - name(delimeter: String = " "): String - price: String - details: ProductDetailsBook - reviews: [Review] - relatedReviews: [Review!]! -} - -union Brand = Ikea | Amazon - -type Car implements Vehicle { - id: String! - description: String - price: String - retailPrice: String -} - -type Error { - code: Int - message: String -} - -type Furniture implements Product { - upc: String! - sku: String! - name: String - price: String - brand: Brand - metadata: [MetadataOrError] - details: ProductDetailsFurniture - inStock: Boolean - isHeavy: Boolean - reviews: [Review] -} - -type Ikea { - asile: Int -} - -type Image implements NamedObject { - name: String! - attributes: ImageAttributes! -} - -type ImageAttributes { - url: String! -} - -type KeyValue { - key: String! - value: String! -} - -type Library { - id: ID! - name: String - userAccount(id: ID! = 1): User -} - -union MetadataOrError = KeyValue | Error - -type Mutation { - login(username: String!, password: String!): User - reviewProduct(upc: String!, body: String!): Product - updateReview(review: UpdateReviewInput!): Review - deleteReview(id: ID!): Boolean -} - -type Name { - first: String - last: String -} - -interface NamedObject { - name: String! -} - -type PasswordAccount { - email: String! -} - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean - reviews: [Review] -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String - pages: Int -} - -type ProductDetailsFurniture implements ProductDetails { - country: String - color: String -} - -type Query { - user(id: ID!): User - me: User - book(isbn: String!): Book - books: [Book] - library(id: ID!): Library - body: Body! - product(upc: String!): Product - vehicle(id: String!): Vehicle - topProducts(first: Int = 5): [Product] - topCars(first: Int = 5): [Car] - topReviews(first: Int = 5): [Review] -} - -type Review { - id: ID! - body(format: Boolean = false): String - author: User - product: Product - metadata: [MetadataOrError] -} - -type SMSAccount { - number: String -} - -type Text implements NamedObject { - name: String! - attributes: TextAttributes! -} - -type TextAttributes { - bold: Boolean - text: String -} - -union Thing = Car | Ikea - -input UpdateReviewInput { - id: ID! - body: String -} - -type User { - id: ID! - name: Name - username: String - birthDate(locale: String): String - account: AccountType - metadata: [UserMetadata] - goodDescription: Boolean - vehicle: Vehicle - thing: Thing - reviews: [Review] - numberOfReviews: Int! - goodAddress: Boolean -} - -type UserMetadata { - name: String - address: String - description: String -} - -type Van implements Vehicle { - id: String! - description: String - price: String - retailPrice: String -} - -interface Vehicle { - id: String! - description: String - price: String - retailPrice: String -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_defaults_to_false.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_defaults_to_false.snap deleted file mode 100644 index 875fa8d4c..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_defaults_to_false.snap +++ /dev/null @@ -1,19 +0,0 @@ ---- -source: router-bridge/src/planner.rs -assertion_line: 1003 -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "Subgraph1", - "variableUsages": [], - "operation": "{t{__typename ...on A{x y t{__typename ...on A{x y}...on B{z}}}}}", - "operationKind": "query" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n ... on A {\n x\n y\n t {\n __typename\n ... on A {\n x\n y\n }\n ... on B {\n z\n }\n }\n }\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_explicit_false.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_explicit_false.snap deleted file mode 100644 index 99af6edeb..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_explicit_false.snap +++ /dev/null @@ -1,19 +0,0 @@ ---- -source: router-bridge/src/planner.rs -assertion_line: 1028 -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "Subgraph1", - "variableUsages": [], - "operation": "{t{__typename ...on A{x y t{__typename ...on A{x y}...on B{z}}}}}", - "operationKind": "query" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n ... on A {\n x\n y\n t {\n __typename\n ... on A {\n x\n y\n }\n ... on B {\n z\n }\n }\n }\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_true.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_true.snap deleted file mode 100644 index 6fb7a0faf..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__generate_query_fragments_true.snap +++ /dev/null @@ -1,19 +0,0 @@ ---- -source: router-bridge/src/planner.rs -assertion_line: 1054 -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "Subgraph1", - "variableUsages": [], - "operation": "{t{__typename ..._generated_onA3_0}}fragment _generated_onA2_0 on A{x y}fragment _generated_onA3_0 on A{x y t{__typename ..._generated_onA2_0 ...on B{z}}}", - "operationKind": "query" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n ..._generated_onA3_0\n }\n }\n \n fragment _generated_onA2_0 on A {\n x\n y\n }\n \n fragment _generated_onA3_0 on A {\n x\n y\n t {\n __typename\n ..._generated_onA2_0\n ... on B {\n z\n }\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__get_operation_signature.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__get_operation_signature.snap deleted file mode 100644 index 8b4f98ae1..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__get_operation_signature.snap +++ /dev/null @@ -1,6 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: signature ---- -# MyFirstAndLastName -query MyFirstAndLastName{me{name{first last}}} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__introspect.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__introspect.snap deleted file mode 100644 index 8722152ea..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__introspect.snap +++ /dev/null @@ -1,3262 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_value(introspection_response).unwrap()" ---- -{ - "data": { - "__schema": { - "queryType": { - "name": "Query" - }, - "mutationType": { - "name": "Mutation" - }, - "subscriptionType": null, - "types": [ - { - "kind": "UNION", - "name": "AccountType", - "description": null, - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "PasswordAccount", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "SMSAccount", - "ofType": null - } - ] - }, - { - "kind": "OBJECT", - "name": "Amazon", - "description": null, - "fields": [ - { - "name": "referrer", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "SCALAR", - "name": "String", - "description": "The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "UNION", - "name": "Body", - "description": null, - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "Image", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "Text", - "ofType": null - } - ] - }, - { - "kind": "OBJECT", - "name": "Book", - "description": null, - "fields": [ - { - "name": "isbn", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "title", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "year", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "similarBooks", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Book", - "ofType": null - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "metadata", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "UNION", - "name": "MetadataOrError", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "inStock", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "isCheckedOut", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "upc", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "sku", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "name", - "description": null, - "args": [ - { - "name": "delimeter", - "description": null, - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "defaultValue": "\" \"" - } - ], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "price", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "details", - "description": null, - "args": [], - "type": { - "kind": "OBJECT", - "name": "ProductDetailsBook", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "reviews", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Review", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "relatedReviews", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Review", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "Product", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "SCALAR", - "name": "Int", - "description": "The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "SCALAR", - "name": "Boolean", - "description": "The `Boolean` scalar type represents `true` or `false`.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "UNION", - "name": "Brand", - "description": null, - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "Ikea", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "Amazon", - "ofType": null - } - ] - }, - { - "kind": "OBJECT", - "name": "Car", - "description": null, - "fields": [ - { - "name": "id", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "price", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "retailPrice", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "Vehicle", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Error", - "description": null, - "fields": [ - { - "name": "code", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "message", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Furniture", - "description": null, - "fields": [ - { - "name": "upc", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "sku", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "price", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "brand", - "description": null, - "args": [], - "type": { - "kind": "UNION", - "name": "Brand", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "metadata", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "UNION", - "name": "MetadataOrError", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "details", - "description": null, - "args": [], - "type": { - "kind": "OBJECT", - "name": "ProductDetailsFurniture", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "inStock", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "isHeavy", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "reviews", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Review", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "Product", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Ikea", - "description": null, - "fields": [ - { - "name": "asile", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Image", - "description": null, - "fields": [ - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "attributes", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "ImageAttributes", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "NamedObject", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "ImageAttributes", - "description": null, - "fields": [ - { - "name": "url", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "KeyValue", - "description": null, - "fields": [ - { - "name": "key", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "value", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Library", - "description": null, - "fields": [ - { - "name": "id", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "userAccount", - "description": null, - "args": [ - { - "name": "id", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "defaultValue": "1" - } - ], - "type": { - "kind": "OBJECT", - "name": "User", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "SCALAR", - "name": "ID", - "description": "The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"4\"`) or integer (such as `4`) input value will be accepted as an ID.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "UNION", - "name": "MetadataOrError", - "description": null, - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "KeyValue", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "Error", - "ofType": null - } - ] - }, - { - "kind": "OBJECT", - "name": "Mutation", - "description": null, - "fields": [ - { - "name": "login", - "description": null, - "args": [ - { - "name": "username", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - }, - { - "name": "password", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "OBJECT", - "name": "User", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "reviewProduct", - "description": null, - "args": [ - { - "name": "upc", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - }, - { - "name": "body", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "INTERFACE", - "name": "Product", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "updateReview", - "description": null, - "args": [ - { - "name": "review", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "INPUT_OBJECT", - "name": "UpdateReviewInput", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "OBJECT", - "name": "Review", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "deleteReview", - "description": null, - "args": [ - { - "name": "id", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Name", - "description": null, - "fields": [ - { - "name": "first", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "last", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "INTERFACE", - "name": "NamedObject", - "description": null, - "fields": [ - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "Image", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "Text", - "ofType": null - } - ] - }, - { - "kind": "OBJECT", - "name": "PasswordAccount", - "description": null, - "fields": [ - { - "name": "email", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "INTERFACE", - "name": "Product", - "description": null, - "fields": [ - { - "name": "upc", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "sku", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "price", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "details", - "description": null, - "args": [], - "type": { - "kind": "INTERFACE", - "name": "ProductDetails", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "inStock", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "reviews", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Review", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "Book", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "Furniture", - "ofType": null - } - ] - }, - { - "kind": "INTERFACE", - "name": "ProductDetails", - "description": null, - "fields": [ - { - "name": "country", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "ProductDetailsBook", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "ProductDetailsFurniture", - "ofType": null - } - ] - }, - { - "kind": "OBJECT", - "name": "ProductDetailsBook", - "description": null, - "fields": [ - { - "name": "country", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "pages", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "ProductDetails", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "ProductDetailsFurniture", - "description": null, - "fields": [ - { - "name": "country", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "color", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "ProductDetails", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Query", - "description": null, - "fields": [ - { - "name": "user", - "description": null, - "args": [ - { - "name": "id", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "OBJECT", - "name": "User", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "me", - "description": null, - "args": [], - "type": { - "kind": "OBJECT", - "name": "User", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "book", - "description": null, - "args": [ - { - "name": "isbn", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "OBJECT", - "name": "Book", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "books", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Book", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "library", - "description": null, - "args": [ - { - "name": "id", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "OBJECT", - "name": "Library", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "body", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "UNION", - "name": "Body", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "product", - "description": null, - "args": [ - { - "name": "upc", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "INTERFACE", - "name": "Product", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "vehicle", - "description": null, - "args": [ - { - "name": "id", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - } - ], - "type": { - "kind": "INTERFACE", - "name": "Vehicle", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "topProducts", - "description": null, - "args": [ - { - "name": "first", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": "5" - } - ], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "INTERFACE", - "name": "Product", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "topCars", - "description": null, - "args": [ - { - "name": "first", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": "5" - } - ], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Car", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "topReviews", - "description": null, - "args": [ - { - "name": "first", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - }, - "defaultValue": "5" - } - ], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Review", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Review", - "description": null, - "fields": [ - { - "name": "id", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "body", - "description": null, - "args": [ - { - "name": "format", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "defaultValue": "false" - } - ], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "author", - "description": null, - "args": [], - "type": { - "kind": "OBJECT", - "name": "User", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "product", - "description": null, - "args": [], - "type": { - "kind": "INTERFACE", - "name": "Product", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "metadata", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "UNION", - "name": "MetadataOrError", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "SMSAccount", - "description": null, - "fields": [ - { - "name": "number", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Text", - "description": null, - "fields": [ - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "attributes", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "TextAttributes", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "NamedObject", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "TextAttributes", - "description": null, - "fields": [ - { - "name": "bold", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "text", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "UNION", - "name": "Thing", - "description": null, - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "Car", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "Ikea", - "ofType": null - } - ] - }, - { - "kind": "INPUT_OBJECT", - "name": "UpdateReviewInput", - "description": null, - "fields": null, - "inputFields": [ - { - "name": "id", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "defaultValue": null - }, - { - "name": "body", - "description": null, - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "defaultValue": null - } - ], - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "User", - "description": null, - "fields": [ - { - "name": "id", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "ID", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "OBJECT", - "name": "Name", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "username", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "birthDate", - "description": null, - "args": [ - { - "name": "locale", - "description": null, - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "defaultValue": null - } - ], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "account", - "description": null, - "args": [], - "type": { - "kind": "UNION", - "name": "AccountType", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "metadata", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "UserMetadata", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "goodDescription", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "vehicle", - "description": null, - "args": [], - "type": { - "kind": "INTERFACE", - "name": "Vehicle", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "thing", - "description": null, - "args": [], - "type": { - "kind": "UNION", - "name": "Thing", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "reviews", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "Review", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "numberOfReviews", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Int", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "goodAddress", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "UserMetadata", - "description": null, - "fields": [ - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "address", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "Van", - "description": null, - "fields": [ - { - "name": "id", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "price", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "retailPrice", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [ - { - "kind": "INTERFACE", - "name": "Vehicle", - "ofType": null - } - ], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "INTERFACE", - "name": "Vehicle", - "description": null, - "fields": [ - { - "name": "id", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "price", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "retailPrice", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": [ - { - "kind": "OBJECT", - "name": "Car", - "ofType": null - }, - { - "kind": "OBJECT", - "name": "Van", - "ofType": null - } - ] - }, - { - "kind": "OBJECT", - "name": "__Schema", - "description": "A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.", - "fields": [ - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "types", - "description": "A list of all types supported by this server.", - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "queryType", - "description": "The type that query operations will be rooted at.", - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "mutationType", - "description": "If this server supports mutation, the type that mutation operations will be rooted at.", - "args": [], - "type": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "subscriptionType", - "description": "If this server support subscription, the type that subscription operations will be rooted at.", - "args": [], - "type": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "directives", - "description": "A list of all directives supported by this server.", - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__Directive", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "__Type", - "description": "The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\n\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name, description and optional `specifiedByURL`, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.", - "fields": [ - { - "name": "kind", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "ENUM", - "name": "__TypeKind", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "specifiedByURL", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "fields", - "description": null, - "args": [ - { - "name": "includeDeprecated", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "defaultValue": "false" - } - ], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__Field", - "ofType": null - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "interfaces", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "possibleTypes", - "description": null, - "args": [], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "enumValues", - "description": null, - "args": [ - { - "name": "includeDeprecated", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "defaultValue": "false" - } - ], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__EnumValue", - "ofType": null - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "inputFields", - "description": null, - "args": [ - { - "name": "includeDeprecated", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "defaultValue": "false" - } - ], - "type": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__InputValue", - "ofType": null - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "ofType", - "description": null, - "args": [], - "type": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "ENUM", - "name": "__TypeKind", - "description": "An enum describing what kind of type a given `__Type` is.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": [ - { - "name": "SCALAR", - "description": "Indicates this type is a scalar.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "OBJECT", - "description": "Indicates this type is an object. `fields` and `interfaces` are valid fields.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "INTERFACE", - "description": "Indicates this type is an interface. `fields`, `interfaces`, and `possibleTypes` are valid fields.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "UNION", - "description": "Indicates this type is a union. `possibleTypes` is a valid field.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "ENUM", - "description": "Indicates this type is an enum. `enumValues` is a valid field.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "INPUT_OBJECT", - "description": "Indicates this type is an input object. `inputFields` is a valid field.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "LIST", - "description": "Indicates this type is a list. `ofType` is a valid field.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "NON_NULL", - "description": "Indicates this type is a non-null. `ofType` is a valid field.", - "isDeprecated": false, - "deprecationReason": null - } - ], - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "__Field", - "description": "Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.", - "fields": [ - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "args", - "description": null, - "args": [ - { - "name": "includeDeprecated", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "defaultValue": "false" - } - ], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__InputValue", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "type", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "isDeprecated", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "deprecationReason", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "__InputValue", - "description": "Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.", - "fields": [ - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "type", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__Type", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "defaultValue", - "description": "A GraphQL-formatted string representing the default value for this input value.", - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "isDeprecated", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "deprecationReason", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "__EnumValue", - "description": "One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.", - "fields": [ - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "isDeprecated", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "deprecationReason", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "OBJECT", - "name": "__Directive", - "description": "A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.", - "fields": [ - { - "name": "name", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "description", - "description": null, - "args": [], - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "isRepeatable", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "locations", - "description": null, - "args": [], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "ENUM", - "name": "__DirectiveLocation", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "args", - "description": null, - "args": [ - { - "name": "includeDeprecated", - "description": null, - "type": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - }, - "defaultValue": "false" - } - ], - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "LIST", - "name": null, - "ofType": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "OBJECT", - "name": "__InputValue", - "ofType": null - } - } - } - }, - "isDeprecated": false, - "deprecationReason": null - } - ], - "inputFields": null, - "interfaces": [], - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "ENUM", - "name": "__DirectiveLocation", - "description": "A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.", - "fields": null, - "inputFields": null, - "interfaces": null, - "enumValues": [ - { - "name": "QUERY", - "description": "Location adjacent to a query operation.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "MUTATION", - "description": "Location adjacent to a mutation operation.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "SUBSCRIPTION", - "description": "Location adjacent to a subscription operation.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "FIELD", - "description": "Location adjacent to a field.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "FRAGMENT_DEFINITION", - "description": "Location adjacent to a fragment definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "FRAGMENT_SPREAD", - "description": "Location adjacent to a fragment spread.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "INLINE_FRAGMENT", - "description": "Location adjacent to an inline fragment.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "VARIABLE_DEFINITION", - "description": "Location adjacent to a variable definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "SCHEMA", - "description": "Location adjacent to a schema definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "SCALAR", - "description": "Location adjacent to a scalar definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "OBJECT", - "description": "Location adjacent to an object type definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "FIELD_DEFINITION", - "description": "Location adjacent to a field definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "ARGUMENT_DEFINITION", - "description": "Location adjacent to an argument definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "INTERFACE", - "description": "Location adjacent to an interface definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "UNION", - "description": "Location adjacent to a union definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "ENUM", - "description": "Location adjacent to an enum definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "ENUM_VALUE", - "description": "Location adjacent to an enum value definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "INPUT_OBJECT", - "description": "Location adjacent to an input object type definition.", - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "INPUT_FIELD_DEFINITION", - "description": "Location adjacent to an input object field definition.", - "isDeprecated": false, - "deprecationReason": null - } - ], - "possibleTypes": null - } - ], - "directives": [ - { - "name": "transform", - "description": null, - "locations": [ - "FIELD" - ], - "args": [ - { - "name": "from", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - } - ] - }, - { - "name": "include", - "description": "Directs the executor to include this field or fragment only when the `if` argument is true.", - "locations": [ - "FIELD", - "FRAGMENT_SPREAD", - "INLINE_FRAGMENT" - ], - "args": [ - { - "name": "if", - "description": "Included when true.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "defaultValue": null - } - ] - }, - { - "name": "skip", - "description": "Directs the executor to skip this field or fragment when the `if` argument is true.", - "locations": [ - "FIELD", - "FRAGMENT_SPREAD", - "INLINE_FRAGMENT" - ], - "args": [ - { - "name": "if", - "description": "Skipped when true.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "Boolean", - "ofType": null - } - }, - "defaultValue": null - } - ] - }, - { - "name": "deprecated", - "description": "Marks an element of a GraphQL schema as no longer supported.", - "locations": [ - "FIELD_DEFINITION", - "ARGUMENT_DEFINITION", - "INPUT_FIELD_DEFINITION", - "ENUM_VALUE" - ], - "args": [ - { - "name": "reason", - "description": "Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted using the Markdown syntax, as specified by [CommonMark](https://commonmark.org/).", - "type": { - "kind": "SCALAR", - "name": "String", - "ofType": null - }, - "defaultValue": "\"No longer supported\"" - } - ] - }, - { - "name": "specifiedBy", - "description": "Exposes a URL that specifies the behavior of this scalar.", - "locations": [ - "SCALAR" - ], - "args": [ - { - "name": "url", - "description": "The URL that specifies the behavior of this scalar.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null - } - ] - } - ] - } - }, - "errors": [] -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_operation_name_works-2.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_operation_name_works-2.snap deleted file mode 100644 index 5da33d34f..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_operation_name_works-2.snap +++ /dev/null @@ -1,28 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: payload.usage_reporting ---- -{ - "statsReportKey": "# MyFirstAndLastName\nquery MyFirstAndLastName{me{name{first last}}}", - "referencedFieldsByType": { - "Name": { - "fieldNames": [ - "first", - "last" - ], - "isInterface": false - }, - "Query": { - "fieldNames": [ - "me" - ], - "isInterface": false - }, - "User": { - "fieldNames": [ - "name" - ], - "isInterface": false - } - } -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_operation_name_works.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_operation_name_works.snap deleted file mode 100644 index 83cddc5b9..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_operation_name_works.snap +++ /dev/null @@ -1,19 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "accounts", - "variableUsages": [], - "operation": "query MyFirstAndLastName__accounts__0{me{name{first last}}}", - "operationKind": "query", - "operationName": "MyFirstAndLastName__accounts__0" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"accounts\") {\n {\n me {\n name {\n first\n last\n }\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_several_choices_works-2.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_several_choices_works-2.snap deleted file mode 100644 index 4d2b34d4f..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_several_choices_works-2.snap +++ /dev/null @@ -1,27 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: payload.usage_reporting ---- -{ - "statsReportKey": "# MyFirstName\nquery MyFirstName{me{name{first}}}", - "referencedFieldsByType": { - "Name": { - "fieldNames": [ - "first" - ], - "isInterface": false - }, - "Query": { - "fieldNames": [ - "me" - ], - "isInterface": false - }, - "User": { - "fieldNames": [ - "name" - ], - "isInterface": false - } - } -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_several_choices_works.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_several_choices_works.snap deleted file mode 100644 index ca8b1d299..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_with_several_choices_works.snap +++ /dev/null @@ -1,19 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "accounts", - "variableUsages": [], - "operation": "query MyFirstName__accounts__0{me{name{first}}}", - "operationKind": "query", - "operationName": "MyFirstName__accounts__0" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"accounts\") {\n {\n me {\n name {\n first\n }\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_works-2.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_works-2.snap deleted file mode 100644 index 5da33d34f..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_works-2.snap +++ /dev/null @@ -1,28 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: payload.usage_reporting ---- -{ - "statsReportKey": "# MyFirstAndLastName\nquery MyFirstAndLastName{me{name{first last}}}", - "referencedFieldsByType": { - "Name": { - "fieldNames": [ - "first", - "last" - ], - "isInterface": false - }, - "Query": { - "fieldNames": [ - "me" - ], - "isInterface": false - }, - "User": { - "fieldNames": [ - "name" - ], - "isInterface": false - } - } -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_works.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_works.snap deleted file mode 100644 index 83cddc5b9..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__named_query_works.snap +++ /dev/null @@ -1,19 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "accounts", - "variableUsages": [], - "operation": "query MyFirstAndLastName__accounts__0{me{name{first last}}}", - "operationKind": "query", - "operationName": "MyFirstAndLastName__accounts__0" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"accounts\") {\n {\n me {\n name {\n first\n last\n }\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-2.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-2.snap deleted file mode 100644 index 9824d83ab..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-2.snap +++ /dev/null @@ -1,204 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: api_schema1.schema ---- -directive @transform(from: String!) on FIELD - -union AccountType = PasswordAccount | SMSAccount - -type Amazon { - referrer: String -} - -union Body = Image | Text - -type Book implements Product { - isbn: String! - title: String - year: Int - similarBooks: [Book]! - metadata: [MetadataOrError] - inStock: Boolean - isCheckedOut: Boolean - upc: String! - sku: String! - name(delimeter: String = " "): String - price: String - details: ProductDetailsBook - reviews: [Review] - relatedReviews: [Review!]! -} - -union Brand = Ikea | Amazon - -type Car implements Vehicle { - id: String! - description: String - price: String - retailPrice: String -} - -type Error { - code: Int - message: String -} - -type Furniture implements Product { - upc: String! - sku: String! - name: String - price: String - brand: Brand - metadata: [MetadataOrError] - details: ProductDetailsFurniture - inStock: Boolean - isHeavy: Boolean - reviews: [Review] -} - -type Ikea { - asile: Int -} - -type Image implements NamedObject { - name: String! - attributes: ImageAttributes! -} - -type ImageAttributes { - url: String! -} - -type KeyValue { - key: String! - value: String! -} - -type Library { - id: ID! - name: String - userAccount(id: ID! = 1): User -} - -union MetadataOrError = KeyValue | Error - -type Mutation { - login(username: String!, password: String!): User - reviewProduct(upc: String!, body: String!): Product - updateReview(review: UpdateReviewInput!): Review - deleteReview(id: ID!): Boolean -} - -type Name { - first: String - last: String -} - -interface NamedObject { - name: String! -} - -type PasswordAccount { - email: String! -} - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean - reviews: [Review] -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String - pages: Int -} - -type ProductDetailsFurniture implements ProductDetails { - country: String - color: String -} - -type Query { - user(id: ID!): User - me: User - book(isbn: String!): Book - books: [Book] - library(id: ID!): Library - body: Body! - product(upc: String!): Product - vehicle(id: String!): Vehicle - topProducts(first: Int = 5): [Product] - topCars(first: Int = 5): [Car] - topReviews(first: Int = 5): [Review] -} - -type Review { - id: ID! - author: User - product: Product - metadata: [MetadataOrError] -} - -type SMSAccount { - number: String -} - -type Text implements NamedObject { - name: String! - attributes: TextAttributes! -} - -type TextAttributes { - bold: Boolean - text: String -} - -union Thing = Car | Ikea - -input UpdateReviewInput { - id: ID! - body: String -} - -type User { - id: ID! - name: Name - username: String - birthDate(locale: String): String - account: AccountType - metadata: [UserMetadata] - goodDescription: Boolean - vehicle: Vehicle - thing: Thing - reviews: [Review] - numberOfReviews: Int! - goodAddress: Boolean -} - -type UserMetadata { - name: String - address: String - description: String -} - -type Van implements Vehicle { - id: String! - description: String - price: String - retailPrice: String -} - -interface Vehicle { - id: String! - description: String - price: String - retailPrice: String -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-3.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-3.snap deleted file mode 100644 index b2cc808d8..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-3.snap +++ /dev/null @@ -1,84 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&query_plan2.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Sequence", - "nodes": [ - { - "kind": "Fetch", - "serviceName": "accounts", - "variableUsages": [], - "operation": "{me{__typename id name{first}}}", - "operationKind": "query" - }, - { - "kind": "Flatten", - "path": [ - "me" - ], - "node": { - "kind": "Fetch", - "serviceName": "reviews", - "requires": [ - { - "kind": "InlineFragment", - "typeCondition": "User", - "selections": [ - { - "kind": "Field", - "name": "__typename" - }, - { - "kind": "Field", - "name": "id" - } - ] - } - ], - "variableUsages": [], - "operation": "query($representations:[_Any!]!){_entities(representations:$representations){...on User{reviews{id author{__typename id}body}}}}", - "operationKind": "query" - } - }, - { - "kind": "Flatten", - "path": [ - "me", - "reviews", - "@", - "author" - ], - "node": { - "kind": "Fetch", - "serviceName": "accounts", - "requires": [ - { - "kind": "InlineFragment", - "typeCondition": "User", - "selections": [ - { - "kind": "Field", - "name": "__typename" - }, - { - "kind": "Field", - "name": "id" - } - ] - } - ], - "variableUsages": [], - "operation": "query($representations:[_Any!]!){_entities(representations:$representations){...on User{name{first}}}}", - "operationKind": "query" - } - } - ] - } - }, - "formattedQueryPlan": "QueryPlan {\n Sequence {\n Fetch(service: \"accounts\") {\n {\n me {\n __typename\n id\n name {\n first\n }\n }\n }\n },\n Flatten(path: \"me\") {\n Fetch(service: \"reviews\") {\n {\n ... on User {\n __typename\n id\n }\n } =>\n {\n ... on User {\n reviews {\n id\n author {\n __typename\n id\n }\n body\n }\n }\n }\n },\n },\n Flatten(path: \"me.reviews.@.author\") {\n Fetch(service: \"accounts\") {\n {\n ... on User {\n __typename\n id\n }\n } =>\n {\n ... on User {\n name {\n first\n }\n }\n }\n },\n },\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-4.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-4.snap deleted file mode 100644 index b5152ca37..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update-4.snap +++ /dev/null @@ -1,205 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: api_schema2.schema ---- -directive @transform(from: String!) on FIELD - -union AccountType = PasswordAccount | SMSAccount - -type Amazon { - referrer: String -} - -union Body = Image | Text - -type Book implements Product { - isbn: String! - title: String - year: Int - similarBooks: [Book]! - metadata: [MetadataOrError] - inStock: Boolean - isCheckedOut: Boolean - upc: String! - sku: String! - name(delimeter: String = " "): String - price: String - details: ProductDetailsBook - reviews: [Review] - relatedReviews: [Review!]! -} - -union Brand = Ikea | Amazon - -type Car implements Vehicle { - id: String! - description: String - price: String - retailPrice: String -} - -type Error { - code: Int - message: String -} - -type Furniture implements Product { - upc: String! - sku: String! - name: String - price: String - brand: Brand - metadata: [MetadataOrError] - details: ProductDetailsFurniture - inStock: Boolean - isHeavy: Boolean - reviews: [Review] -} - -type Ikea { - asile: Int -} - -type Image implements NamedObject { - name: String! - attributes: ImageAttributes! -} - -type ImageAttributes { - url: String! -} - -type KeyValue { - key: String! - value: String! -} - -type Library { - id: ID! - name: String - userAccount(id: ID! = 1): User -} - -union MetadataOrError = KeyValue | Error - -type Mutation { - login(username: String!, password: String!): User - reviewProduct(upc: String!, body: String!): Product - updateReview(review: UpdateReviewInput!): Review - deleteReview(id: ID!): Boolean -} - -type Name { - first: String - last: String -} - -interface NamedObject { - name: String! -} - -type PasswordAccount { - email: String! -} - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean - reviews: [Review] -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String - pages: Int -} - -type ProductDetailsFurniture implements ProductDetails { - country: String - color: String -} - -type Query { - user(id: ID!): User - me: User - book(isbn: String!): Book - books: [Book] - library(id: ID!): Library - body: Body! - product(upc: String!): Product - vehicle(id: String!): Vehicle - topProducts(first: Int = 5): [Product] - topCars(first: Int = 5): [Car] - topReviews(first: Int = 5): [Review] -} - -type Review { - id: ID! - body(format: Boolean = false): String - author: User - product: Product - metadata: [MetadataOrError] -} - -type SMSAccount { - number: String -} - -type Text implements NamedObject { - name: String! - attributes: TextAttributes! -} - -type TextAttributes { - bold: Boolean - text: String -} - -union Thing = Car | Ikea - -input UpdateReviewInput { - id: ID! - body: String -} - -type User { - id: ID! - name: Name - username: String - birthDate(locale: String): String - account: AccountType - metadata: [UserMetadata] - goodDescription: Boolean - vehicle: Vehicle - thing: Thing - reviews: [Review] - numberOfReviews: Int! - goodAddress: Boolean -} - -type UserMetadata { - name: String - address: String - description: String -} - -type Van implements Vehicle { - id: String! - description: String - price: String - retailPrice: String -} - -interface Vehicle { - id: String! - description: String - price: String - retailPrice: String -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update.snap deleted file mode 100644 index 73b35fec1..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__planner_update.snap +++ /dev/null @@ -1,24 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "&format!(\"{query_plan1:#?}\")" ---- -PlanErrors { - errors: [ - PlanError { - message: Some( - "Cannot query field \"body\" on type \"Review\".", - ), - extensions: Some( - PlanErrorExtensions { - code: "GRAPHQL_VALIDATION_FAILED", - exception: None, - }, - ), - validation_error: true, - }, - ], - usage_reporting: UsageReporting { - stats_report_key: "## GraphQLValidationFailure\n", - referenced_fields_by_type: {}, - }, -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__progressive_override-2.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__progressive_override-2.snap deleted file mode 100644 index 3f6d76c05..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__progressive_override-2.snap +++ /dev/null @@ -1,53 +0,0 @@ ---- -source: router-bridge/src/planner.rs -assertion_line: 833 -expression: "serde_json::to_string_pretty(&payload2.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Sequence", - "nodes": [ - { - "kind": "Fetch", - "serviceName": "Subgraph1", - "variableUsages": [], - "operation": "{t{__typename k}}", - "operationKind": "query" - }, - { - "kind": "Flatten", - "path": [ - "t" - ], - "node": { - "kind": "Fetch", - "serviceName": "Subgraph2", - "requires": [ - { - "kind": "InlineFragment", - "typeCondition": "T", - "selections": [ - { - "kind": "Field", - "name": "__typename" - }, - { - "kind": "Field", - "name": "k" - } - ] - } - ], - "variableUsages": [], - "operation": "query($representations:[_Any!]!){_entities(representations:$representations){...on T{a}}}", - "operationKind": "query" - } - } - ] - } - }, - "formattedQueryPlan": "QueryPlan {\n Sequence {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n __typename\n k\n }\n }\n },\n Flatten(path: \"t\") {\n Fetch(service: \"Subgraph2\") {\n {\n ... on T {\n __typename\n k\n }\n } =>\n {\n ... on T {\n a\n }\n }\n },\n },\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__progressive_override.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__progressive_override.snap deleted file mode 100644 index 74fe8fdca..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__progressive_override.snap +++ /dev/null @@ -1,19 +0,0 @@ ---- -source: router-bridge/src/planner.rs -assertion_line: 825 -expression: "serde_json::to_string_pretty(&payload1.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "Subgraph1", - "variableUsages": [], - "operation": "{t{a}}", - "operationKind": "query" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n a\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_defaults_to_true.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_defaults_to_true.snap deleted file mode 100644 index 117a24d65..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_defaults_to_true.snap +++ /dev/null @@ -1,18 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "Subgraph1", - "variableUsages": [], - "operation": "{t{a1{...Selection}a2{...Selection}}}fragment Selection on A{x y}", - "operationKind": "query" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n a1 {\n ...Selection\n }\n a2 {\n ...Selection\n }\n }\n }\n \n fragment Selection on A {\n x\n y\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_explicit_true.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_explicit_true.snap deleted file mode 100644 index 117a24d65..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_explicit_true.snap +++ /dev/null @@ -1,18 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "Subgraph1", - "variableUsages": [], - "operation": "{t{a1{...Selection}a2{...Selection}}}fragment Selection on A{x y}", - "operationKind": "query" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n a1 {\n ...Selection\n }\n a2 {\n ...Selection\n }\n }\n }\n \n fragment Selection on A {\n x\n y\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_false.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_false.snap deleted file mode 100644 index a7c351c39..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__reuse_query_fragments_false.snap +++ /dev/null @@ -1,18 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: "serde_json::to_string_pretty(&payload.data).unwrap()" ---- -{ - "queryPlan": { - "kind": "QueryPlan", - "node": { - "kind": "Fetch", - "serviceName": "Subgraph1", - "variableUsages": [], - "operation": "{t{a1{x y}a2{x y}}}", - "operationKind": "query" - } - }, - "formattedQueryPlan": "QueryPlan {\n Fetch(service: \"Subgraph1\") {\n {\n t {\n a1 {\n x\n y\n }\n a2 {\n x\n y\n }\n }\n }\n },\n}", - "evaluatedPlanCount": 1 -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-2.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-2.snap deleted file mode 100644 index 5c0461a5d..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-2.snap +++ /dev/null @@ -1,154 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: schema ---- -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"]) -{ - query: Query -} - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE - -directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @external(reason: String) on OBJECT | FIELD_DEFINITION - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA - -directive @extends on OBJECT | INTERFACE - -directive @shareable repeatable on OBJECT | FIELD_DEFINITION - -directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - -directive @override(from: String!, label: String) on FIELD_DEFINITION - -directive @composeDirective(name: String) repeatable on SCHEMA - -directive @interfaceObject on OBJECT - -directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__policy(policies: [[federation__Policy!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__sourceAPI repeatable on SCHEMA - -directive @federation__sourceType repeatable on OBJECT | INTERFACE - -directive @federation__sourceField repeatable on FIELD_DEFINITION - -directive @federation__context(name: String!) repeatable on INTERFACE | OBJECT | UNION - -directive @federation__fromContext(field: federation__ContextFieldValue) on ARGUMENT_DEFINITION - -directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -scalar link__Import - -scalar federation__FieldSet - -scalar federation__Scope - -scalar federation__Policy - -scalar federation__ContextFieldValue - -type Book implements Product - @key(fields: "isbn") -{ - isbn: String! - title: String - year: Int - similarBooks: [Book]! - metadata: [MetadataOrError] - upc: String! @external - sku: String! @external - name: String @external - price: String @external - details: ProductDetails @external - inStock: Boolean @external -} - -type Error { - code: Int @shareable - message: String @shareable -} - -type KeyValue { - key: String! @shareable - value: String! @shareable -} - -type Library - @key(fields: "id") -{ - id: ID! - name: String -} - -union MetadataOrError = KeyValue | Error - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String @shareable - pages: Int @shareable -} - -type ProductDetailsFurniture implements ProductDetails { - country: String @shareable - color: String @shareable -} - -type Query { - book(isbn: String!): Book - books: [Book] - library(id: ID!): Library - _entities(representations: [_Any!]!): [_Entity]! - _service: _Service! -} - -scalar _Any - -type _Service { - sdl: String -} - -union _Entity = Book | Library diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-3.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-3.snap deleted file mode 100644 index 85ccff517..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-3.snap +++ /dev/null @@ -1,116 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: schema ---- -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"]) -{ - query: Query -} - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE - -directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @external(reason: String) on OBJECT | FIELD_DEFINITION - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA - -directive @extends on OBJECT | INTERFACE - -directive @shareable repeatable on OBJECT | FIELD_DEFINITION - -directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - -directive @override(from: String!, label: String) on FIELD_DEFINITION - -directive @composeDirective(name: String) repeatable on SCHEMA - -directive @interfaceObject on OBJECT - -directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__policy(policies: [[federation__Policy!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__sourceAPI repeatable on SCHEMA - -directive @federation__sourceType repeatable on OBJECT | INTERFACE - -directive @federation__sourceField repeatable on FIELD_DEFINITION - -directive @federation__context(name: String!) repeatable on INTERFACE | OBJECT | UNION - -directive @federation__fromContext(field: federation__ContextFieldValue) on ARGUMENT_DEFINITION - -directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -scalar link__Import - -scalar federation__FieldSet - -scalar federation__Scope - -scalar federation__Policy - -scalar federation__ContextFieldValue - -union Body = Image | Text - -type Image implements NamedObject { - name: String! - attributes: ImageAttributes! -} - -type ImageAttributes { - url: String! -} - -interface NamedObject { - name: String! -} - -type Query { - body: Body! - _service: _Service! -} - -type Text implements NamedObject { - name: String! - attributes: TextAttributes! -} - -type TextAttributes { - bold: Boolean - text: String -} - -scalar _Any - -type _Service { - sdl: String -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-4.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-4.snap deleted file mode 100644 index a80f0cb31..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-4.snap +++ /dev/null @@ -1,155 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: schema ---- -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"]) -{ - query: Query -} - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE - -directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @external(reason: String) on OBJECT | FIELD_DEFINITION - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA - -directive @extends on OBJECT | INTERFACE - -directive @shareable repeatable on OBJECT | FIELD_DEFINITION - -directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - -directive @override(from: String!, label: String) on FIELD_DEFINITION - -directive @composeDirective(name: String) repeatable on SCHEMA - -directive @interfaceObject on OBJECT - -directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__policy(policies: [[federation__Policy!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__sourceAPI repeatable on SCHEMA - -directive @federation__sourceType repeatable on OBJECT | INTERFACE - -directive @federation__sourceField repeatable on FIELD_DEFINITION - -directive @federation__context(name: String!) repeatable on INTERFACE | OBJECT | UNION - -directive @federation__fromContext(field: federation__ContextFieldValue) on ARGUMENT_DEFINITION - -directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -scalar link__Import - -scalar federation__FieldSet - -scalar federation__Scope - -scalar federation__Policy - -scalar federation__ContextFieldValue - -type Book implements Product - @key(fields: "isbn") -{ - inStock: Boolean - isCheckedOut: Boolean - isbn: String! - upc: String! @external - sku: String! @external - name: String @external - price: String @external - details: ProductDetails @external -} - -type Furniture implements Product - @key(fields: "sku") -{ - inStock: Boolean - isHeavy: Boolean - sku: String! - upc: String! @external - name: String @external - price: String @external - details: ProductDetails @external -} - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String @shareable - pages: Int @shareable -} - -type ProductDetailsFurniture implements ProductDetails { - country: String @shareable - color: String @shareable -} - -type User - @key(fields: "id") -{ - goodDescription: Boolean @requires(fields: "metadata{description}") - id: ID! - metadata: [UserMetadata] @external -} - -type UserMetadata { - name: String @shareable - address: String @shareable - description: String @shareable -} - -scalar _Any - -type _Service { - sdl: String -} - -union _Entity = Book | Furniture | User - -type Query { - _entities(representations: [_Any!]!): [_Entity]! - _service: _Service! -} diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-5.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-5.snap deleted file mode 100644 index 88d87a499..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-5.snap +++ /dev/null @@ -1,205 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: schema ---- -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"]) -{ - query: Query -} - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE - -directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @external(reason: String) on OBJECT | FIELD_DEFINITION - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA - -directive @extends on OBJECT | INTERFACE - -directive @shareable repeatable on OBJECT | FIELD_DEFINITION - -directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - -directive @override(from: String!, label: String) on FIELD_DEFINITION - -directive @composeDirective(name: String) repeatable on SCHEMA - -directive @interfaceObject on OBJECT - -directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__policy(policies: [[federation__Policy!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__sourceAPI repeatable on SCHEMA - -directive @federation__sourceType repeatable on OBJECT | INTERFACE - -directive @federation__sourceField repeatable on FIELD_DEFINITION - -directive @federation__context(name: String!) repeatable on INTERFACE | OBJECT | UNION - -directive @federation__fromContext(field: federation__ContextFieldValue) on ARGUMENT_DEFINITION - -directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -scalar link__Import - -scalar federation__FieldSet - -scalar federation__Scope - -scalar federation__Policy - -scalar federation__ContextFieldValue - -type Amazon { - referrer: String -} - -type Book implements Product - @key(fields: "isbn") -{ - upc: String! - sku: String! - name(delimeter: String = " "): String @requires(fields: "title year") - price: String - details: ProductDetailsBook - isbn: String! - title: String @external - year: Int @external - inStock: Boolean @external -} - -union Brand = Ikea | Amazon - -type Car implements Vehicle - @key(fields: "id") -{ - id: String! - description: String - price: String - retailPrice: String @external -} - -type Error { - code: Int @shareable - message: String @shareable -} - -type Furniture implements Product - @key(fields: "upc") - @key(fields: "sku") -{ - upc: String! - sku: String! - name: String - price: String - brand: Brand - metadata: [MetadataOrError] - details: ProductDetailsFurniture - inStock: Boolean @external -} - -type Ikea { - asile: Int -} - -type KeyValue { - key: String! @shareable - value: String! @shareable -} - -union MetadataOrError = KeyValue | Error - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String @shareable - pages: Int @shareable -} - -type ProductDetailsFurniture implements ProductDetails { - country: String @shareable - color: String @shareable -} - -type Query { - product(upc: String!): Product - vehicle(id: String!): Vehicle - topProducts(first: Int = 5): [Product] - topCars(first: Int = 5): [Car] - _entities(representations: [_Any!]!): [_Entity]! - _service: _Service! -} - -union Thing = Car | Ikea - -type User - @key(fields: "id") -{ - vehicle: Vehicle - thing: Thing - id: ID! -} - -type Van implements Vehicle - @key(fields: "id") -{ - id: String! - description: String - price: String - retailPrice: String @external -} - -interface Vehicle { - id: String! - description: String - price: String - retailPrice: String -} - -scalar _Any - -type _Service { - sdl: String -} - -union _Entity = Book | Car | Furniture | User | Van diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-6.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-6.snap deleted file mode 100644 index 2b8190f97..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs-6.snap +++ /dev/null @@ -1,221 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: schema ---- -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"]) -{ - query: Query - mutation: Mutation -} - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE - -directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @external(reason: String) on OBJECT | FIELD_DEFINITION - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA - -directive @extends on OBJECT | INTERFACE - -directive @shareable repeatable on OBJECT | FIELD_DEFINITION - -directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - -directive @override(from: String!, label: String) on FIELD_DEFINITION - -directive @composeDirective(name: String) repeatable on SCHEMA - -directive @interfaceObject on OBJECT - -directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__policy(policies: [[federation__Policy!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__sourceAPI repeatable on SCHEMA - -directive @federation__sourceType repeatable on OBJECT | INTERFACE - -directive @federation__sourceField repeatable on FIELD_DEFINITION - -directive @federation__context(name: String!) repeatable on INTERFACE | OBJECT | UNION - -directive @federation__fromContext(field: federation__ContextFieldValue) on ARGUMENT_DEFINITION - -directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -scalar link__Import - -scalar federation__FieldSet - -scalar federation__Scope - -scalar federation__Policy - -scalar federation__ContextFieldValue - -type Book implements Product - @key(fields: "isbn") -{ - reviews: [Review] - relatedReviews: [Review!]! @requires(fields: "similarBooks{isbn}") - isbn: String! - similarBooks: [Book]! @external - upc: String! @external - sku: String! @external - name: String @external - price: String @external - details: ProductDetails @external - inStock: Boolean @external -} - -type Car implements Vehicle - @key(fields: "id") -{ - retailPrice: String @requires(fields: "price") - id: String! - price: String @external - description: String @external -} - -type Error { - code: Int @shareable - message: String @shareable -} - -type Furniture implements Product - @key(fields: "upc") -{ - reviews: [Review] - upc: String! - sku: String! @external - name: String @external - price: String @external - details: ProductDetails @external - inStock: Boolean @external -} - -type KeyValue { - key: String! @shareable - value: String! @shareable -} - -union MetadataOrError = KeyValue | Error - -type Mutation { - reviewProduct(upc: String!, body: String!): Product - updateReview(review: UpdateReviewInput!): Review - deleteReview(id: ID!): Boolean -} - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean - reviews: [Review] -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String @shareable - pages: Int @shareable -} - -type ProductDetailsFurniture implements ProductDetails { - country: String @shareable - color: String @shareable -} - -type Query { - topReviews(first: Int = 5): [Review] - _entities(representations: [_Any!]!): [_Entity]! - _service: _Service! -} - -type Review - @key(fields: "id") -{ - id: ID! - body(format: Boolean = false): String - author: User @provides(fields: "username") - product: Product - metadata: [MetadataOrError] -} - -input UpdateReviewInput { - id: ID! - body: String -} - -type User - @key(fields: "id") -{ - reviews: [Review] - numberOfReviews: Int! - goodAddress: Boolean @requires(fields: "metadata{address}") - username: String @external - id: ID! - metadata: [UserMetadata] @external -} - -type UserMetadata { - name: String @shareable - address: String @shareable - description: String @shareable -} - -type Van implements Vehicle - @key(fields: "id") -{ - retailPrice: String @requires(fields: "price") - id: String! - price: String @external - description: String @external -} - -interface Vehicle { - id: String! - description: String - price: String - retailPrice: String -} - -scalar _Any - -type _Service { - sdl: String -} - -union _Entity = Book | Car | Furniture | Review | User | Van diff --git a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs.snap b/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs.snap deleted file mode 100644 index 6b07112e3..000000000 --- a/router-bridge/src/snapshots/router_bridge__planner__tests__subgraphs.snap +++ /dev/null @@ -1,145 +0,0 @@ ---- -source: router-bridge/src/planner.rs -expression: schema ---- -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/federation/v2.9", import: ["@key", "@requires", "@provides", "@external", "@tag", "@extends", "@shareable", "@inaccessible", "@override", "@composeDirective", "@interfaceObject"]) -{ - query: Query - mutation: Mutation -} - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -directive @key(fields: federation__FieldSet!, resolvable: Boolean = true) repeatable on OBJECT | INTERFACE - -directive @requires(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @provides(fields: federation__FieldSet!) on FIELD_DEFINITION - -directive @external(reason: String) on OBJECT | FIELD_DEFINITION - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION | SCHEMA - -directive @extends on OBJECT | INTERFACE - -directive @shareable repeatable on OBJECT | FIELD_DEFINITION - -directive @inaccessible on FIELD_DEFINITION | OBJECT | INTERFACE | UNION | ARGUMENT_DEFINITION | SCALAR | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION - -directive @override(from: String!, label: String) on FIELD_DEFINITION - -directive @composeDirective(name: String) repeatable on SCHEMA - -directive @interfaceObject on OBJECT - -directive @federation__authenticated on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__requiresScopes(scopes: [[federation__Scope!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__policy(policies: [[federation__Policy!]!]!) on FIELD_DEFINITION | OBJECT | INTERFACE | SCALAR | ENUM - -directive @federation__sourceAPI repeatable on SCHEMA - -directive @federation__sourceType repeatable on OBJECT | INTERFACE - -directive @federation__sourceField repeatable on FIELD_DEFINITION - -directive @federation__context(name: String!) repeatable on INTERFACE | OBJECT | UNION - -directive @federation__fromContext(field: federation__ContextFieldValue) on ARGUMENT_DEFINITION - -directive @federation__cost(weight: Int!) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @federation__listSize(assumedSize: Int, slicingArguments: [String!], sizedFields: [String!], requireOneSlicingArgument: Boolean = true) on FIELD_DEFINITION - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -scalar link__Import - -scalar federation__FieldSet - -scalar federation__Scope - -scalar federation__Policy - -scalar federation__ContextFieldValue - -union AccountType = PasswordAccount | SMSAccount - -type Library - @key(fields: "id") -{ - userAccount(id: ID! = 1): User @requires(fields: "name") - id: ID! - name: String @external -} - -type Mutation { - login(username: String!, password: String!): User -} - -type Name { - first: String - last: String -} - -type PasswordAccount - @key(fields: "email") -{ - email: String! -} - -type Query { - user(id: ID!): User - me: User - _entities(representations: [_Any!]!): [_Entity]! - _service: _Service! -} - -type SMSAccount - @key(fields: "number") -{ - number: String -} - -type User - @key(fields: "id") - @key(fields: "username name{first last}") -{ - id: ID! - name: Name - username: String - birthDate(locale: String): String - account: AccountType - metadata: [UserMetadata] -} - -type UserMetadata { - name: String @shareable - address: String @shareable - description: String @shareable -} - -scalar _Any - -type _Service { - sdl: String -} - -union _Entity = Library | PasswordAccount | SMSAccount | User diff --git a/router-bridge/src/testdata/contract_schema.graphql b/router-bridge/src/testdata/contract_schema.graphql deleted file mode 100644 index 74db321db..000000000 --- a/router-bridge/src/testdata/contract_schema.graphql +++ /dev/null @@ -1,64 +0,0 @@ -schema @core(feature: "https://specs.apollo.dev/core/v0.1") @core(feature: "https://specs.apollo.dev/join/v0.1") @core(feature: "https://specs.apollo.dev/tag/v0.1") @apollo_studio_metadata(launchId: "2396d4fb-a1e4-457d-8da4-347479b852f1", buildId: "2396d4fb-a1e4-457d-8da4-347479b852f1", checkId: null) @core(feature: "https://specs.apollo.dev/inaccessible/v0.1") { - query: Query - mutation: Mutation -} - -directive @core(feature: String!) repeatable on SCHEMA - -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet) on FIELD_DEFINITION - -directive @join__type(graph: join__Graph!, key: join__FieldSet) repeatable on OBJECT | INTERFACE - -directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @tag(name: String!) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION - -directive @apollo_studio_metadata(launchId: String, buildId: String, checkId: String) on SCHEMA - -directive @inaccessible on OBJECT | FIELD_DEFINITION | INTERFACE | UNION - -scalar join__FieldSet - -enum join__Graph { - ACCOUNTS @join__graph(name: "accounts", url: "http://accounts.demo.starstuff.dev/graphql") - INVENTORY @join__graph(name: "inventory", url: "http://inventory.demo.starstuff.dev/graphql") - PRODUCTS @join__graph(name: "products", url: "http://products.demo.starstuff.dev/graphql") - REVIEWS @join__graph(name: "reviews", url: "http://reviews.demo.starstuff.dev/graphql") -} - -type Mutation { - createProduct(name: String, upc: ID!): Product @join__field(graph: PRODUCTS) - createReview(body: String, id: ID!, upc: ID!): Review @join__field(graph: REVIEWS) -} - -type Product @join__owner(graph: PRODUCTS) @join__type(graph: PRODUCTS, key: "upc") @join__type(graph: REVIEWS, key: "upc") @join__type(graph: INVENTORY, key: "upc") { - inStock: Boolean @join__field(graph: INVENTORY) @tag(name: "private") @inaccessible - name: String @join__field(graph: PRODUCTS) - price: Int @join__field(graph: PRODUCTS) - reviews: [Review] @join__field(graph: REVIEWS) - reviewsForAuthor(authorID: ID!): [Review] @join__field(graph: REVIEWS) - shippingEstimate: Int @join__field(graph: INVENTORY, requires: "price weight") - upc: String! @join__field(graph: PRODUCTS) - weight: Int @join__field(graph: PRODUCTS) -} - -type Query { - me: User @join__field(graph: ACCOUNTS) - topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCTS) -} - -type Review @join__owner(graph: REVIEWS) @join__type(graph: REVIEWS, key: "id") { - author: User @join__field(graph: REVIEWS, provides: "username") - body: String @join__field(graph: REVIEWS) - id: ID! @join__field(graph: REVIEWS) - product: Product @join__field(graph: REVIEWS) -} - -type User @join__owner(graph: ACCOUNTS) @join__type(graph: ACCOUNTS, key: "id") @join__type(graph: REVIEWS, key: "id") { - id: ID! @join__field(graph: ACCOUNTS) - name: String @join__field(graph: ACCOUNTS) - reviews: [Review] @join__field(graph: REVIEWS) - username: String @join__field(graph: ACCOUNTS) -} diff --git a/router-bridge/src/testdata/core_in_v0.1.graphql b/router-bridge/src/testdata/core_in_v0.1.graphql deleted file mode 100644 index 43a253893..000000000 --- a/router-bridge/src/testdata/core_in_v0.1.graphql +++ /dev/null @@ -1,35 +0,0 @@ -schema -@core(feature: "https://specs.apollo.dev/core/v0.1") -@core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) -@core( - feature: "https://specs.apollo.dev/something-unsupported/v0.1" - for: SECURITY -) { -query: Query -} -directive @core(feature: String!) repeatable on SCHEMA -directive @join__field( -graph: join__Graph -requires: join__FieldSet -provides: join__FieldSet -) on FIELD_DEFINITION -directive @join__type( -graph: join__Graph! -key: join__FieldSet -) repeatable on OBJECT | INTERFACE -directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE -directive @join__graph(name: String!, url: String!) on ENUM_VALUE -directive @tag( -name: String! -) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION -enum CacheControlScope { -PRIVATE -PUBLIC -} -scalar join__FieldSet -enum join__Graph { -WORLD @join__graph(name: "world", url: "https://world.api.com") -} -type Query { -hello: String! @join__field(graph: WORLD) -} \ No newline at end of file diff --git a/router-bridge/src/testdata/custom_cost_schema.graphql b/router-bridge/src/testdata/custom_cost_schema.graphql deleted file mode 100644 index d966512be..000000000 --- a/router-bridge/src/testdata/custom_cost_schema.graphql +++ /dev/null @@ -1,154 +0,0 @@ -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.5", for: EXECUTION) - @link( - url: "https://specs.apollo.dev/cost/v0.1" - import: ["@cost", "@listSize"] - ) { - query: Query -} - -directive @cost( - weight: Int! -) on ARGUMENT_DEFINITION | ENUM | FIELD_DEFINITION | INPUT_FIELD_DEFINITION | OBJECT | SCALAR - -directive @cost__listSize( - assumedSize: Int - slicingArguments: [String!] - sizedFields: [String!] - requireOneSlicingArgument: Boolean = true -) on FIELD_DEFINITION - -directive @join__directive( - graphs: [join__Graph!] - name: String! - args: join__DirectiveArguments -) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION - -directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE - -directive @join__field( - graph: join__Graph - requires: join__FieldSet - provides: join__FieldSet - type: String - external: Boolean - override: String - usedOverridden: Boolean - overrideLabel: String - contextArguments: [join__ContextArgument!] -) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @join__implements( - graph: join__Graph! - interface: String! -) repeatable on OBJECT | INTERFACE - -directive @join__type( - graph: join__Graph! - key: join__FieldSet - extension: Boolean! = false - resolvable: Boolean! = true - isInterfaceObject: Boolean! = false -) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR - -directive @join__unionMember( - graph: join__Graph! - member: String! -) repeatable on UNION - -directive @link( - url: String - as: String - for: link__Purpose - import: [link__Import] -) repeatable on SCHEMA - -directive @listSize( - assumedSize: Int - slicingArguments: [String!] - sizedFields: [String!] - requireOneSlicingArgument: Boolean = true -) on FIELD_DEFINITION - -type A @join__type(graph: SUBGRAPHWITHLISTSIZE) { - id: ID -} - -enum AorB @join__type(graph: SUBGRAPHWITHCOST) @cost(weight: 15) { - A @join__enumValue(graph: SUBGRAPHWITHCOST) - B @join__enumValue(graph: SUBGRAPHWITHCOST) -} - -scalar ExpensiveInt @join__type(graph: SUBGRAPHWITHCOST) @cost(weight: 30) - -type ExpensiveObject @join__type(graph: SUBGRAPHWITHCOST) @cost(weight: 40) { - id: ID -} - -input InputTypeWithCost @join__type(graph: SUBGRAPHWITHCOST) { - somethingWithCost: Int @cost(weight: 20) -} - -input join__ContextArgument { - name: String! - type: String! - context: String! - selection: join__FieldValue! -} - -scalar join__DirectiveArguments - -scalar join__FieldSet - -scalar join__FieldValue - -enum join__Graph { - SUBGRAPHWITHCOST - @join__graph(name: "subgraphWithCost", url: "http://localhost:4001") - SUBGRAPHWITHLISTSIZE - @join__graph(name: "subgraphWithListSize", url: "http://localhost:4002") -} - -scalar link__Import - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -type Query - @join__type(graph: SUBGRAPHWITHCOST) - @join__type(graph: SUBGRAPHWITHLISTSIZE) { - fieldWithCost: Int @join__field(graph: SUBGRAPHWITHCOST) @cost(weight: 5) - argWithCost(arg: Int @cost(weight: 10)): Int - @join__field(graph: SUBGRAPHWITHCOST) - enumWithCost: AorB @join__field(graph: SUBGRAPHWITHCOST) - inputWithCost(someInput: InputTypeWithCost): Int - @join__field(graph: SUBGRAPHWITHCOST) - scalarWithCost: ExpensiveInt @join__field(graph: SUBGRAPHWITHCOST) - objectWithCost: ExpensiveObject @join__field(graph: SUBGRAPHWITHCOST) - fieldWithListSize: [String!] - @join__field(graph: SUBGRAPHWITHLISTSIZE) - @listSize(assumedSize: 2000, requireOneSlicingArgument: false) - fieldWithDynamicListSize(first: Int = 10): SizedField - @join__field(graph: SUBGRAPHWITHLISTSIZE) - @listSize( - slicingArguments: ["first"] - sizedFields: ["items"] - requireOneSlicingArgument: true - ) -} - -type SizedField @join__type(graph: SUBGRAPHWITHLISTSIZE) { - items: [A] -} diff --git a/router-bridge/src/testdata/named_query.graphql b/router-bridge/src/testdata/named_query.graphql deleted file mode 100644 index 0df1e032b..000000000 --- a/router-bridge/src/testdata/named_query.graphql +++ /dev/null @@ -1,8 +0,0 @@ -query MyFirstAndLastName { - me { - name { - first - last - } - } -} diff --git a/router-bridge/src/testdata/no_operation.graphql b/router-bridge/src/testdata/no_operation.graphql deleted file mode 100644 index 552a330a0..000000000 --- a/router-bridge/src/testdata/no_operation.graphql +++ /dev/null @@ -1,3 +0,0 @@ -fragment thatUserFragment1 on User { - id -} diff --git a/router-bridge/src/testdata/progressive_override.graphql b/router-bridge/src/testdata/progressive_override.graphql deleted file mode 100644 index 51d51867f..000000000 --- a/router-bridge/src/testdata/progressive_override.graphql +++ /dev/null @@ -1,57 +0,0 @@ -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) -{ - query: Query -} - -directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE - -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean, overrideLabel: String) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE - -directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR - -directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -scalar join__FieldSet - -enum join__Graph { - SUBGRAPH1 @join__graph(name: "Subgraph1", url: "https://Subgraph1") - SUBGRAPH2 @join__graph(name: "Subgraph2", url: "https://Subgraph2") -} - -scalar link__Import - -enum link__Purpose { - """ - \`SECURITY\` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - \`EXECUTION\` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -type Query - @join__type(graph: SUBGRAPH1) - @join__type(graph: SUBGRAPH2) -{ - t: T @join__field(graph: SUBGRAPH1) -} - -type T - @join__type(graph: SUBGRAPH1, key: "k") - @join__type(graph: SUBGRAPH2, key: "k") -{ - k: ID - a: Int @join__field(graph: SUBGRAPH1, override: "Subgraph2", overrideLabel: "foo") @join__field(graph: SUBGRAPH2, overrideLabel: "foo") - b: Int @join__field(graph: SUBGRAPH2) -} \ No newline at end of file diff --git a/router-bridge/src/testdata/query.graphql b/router-bridge/src/testdata/query.graphql deleted file mode 100644 index 3e1ed3803..000000000 --- a/router-bridge/src/testdata/query.graphql +++ /dev/null @@ -1,8 +0,0 @@ -query { - me { - name { - first - last - } - } -} diff --git a/router-bridge/src/testdata/query2.graphql b/router-bridge/src/testdata/query2.graphql deleted file mode 100644 index 5c58d7739..000000000 --- a/router-bridge/src/testdata/query2.graphql +++ /dev/null @@ -1,7 +0,0 @@ -query { - me { - name { - last - } - } -} diff --git a/router-bridge/src/testdata/query_generate_query_fragments.graphql b/router-bridge/src/testdata/query_generate_query_fragments.graphql deleted file mode 100644 index 2812eea60..000000000 --- a/router-bridge/src/testdata/query_generate_query_fragments.graphql +++ /dev/null @@ -1,17 +0,0 @@ -query { - t { - ... on A { - x - y - t { - ... on A { - x - y - } - ... on B { - z - } - } - } - } -} diff --git a/router-bridge/src/testdata/query_reuse_query_fragments.graphql b/router-bridge/src/testdata/query_reuse_query_fragments.graphql deleted file mode 100644 index e1121daca..000000000 --- a/router-bridge/src/testdata/query_reuse_query_fragments.graphql +++ /dev/null @@ -1,15 +0,0 @@ -query { - t { - a1 { - ...Selection - } - a2 { - ...Selection - } - } -} - -fragment Selection on A { - x - y -} \ No newline at end of file diff --git a/router-bridge/src/testdata/query_with_multiple_anonymous_operations.graphql b/router-bridge/src/testdata/query_with_multiple_anonymous_operations.graphql deleted file mode 100644 index 3412e7804..000000000 --- a/router-bridge/src/testdata/query_with_multiple_anonymous_operations.graphql +++ /dev/null @@ -1,16 +0,0 @@ -query { - me { - name { - first - last - } - } -} - -query { - me { - name { - first - } - } -} diff --git a/router-bridge/src/testdata/query_with_multiple_operations.graphql b/router-bridge/src/testdata/query_with_multiple_operations.graphql deleted file mode 100644 index ef6b4f22a..000000000 --- a/router-bridge/src/testdata/query_with_multiple_operations.graphql +++ /dev/null @@ -1,16 +0,0 @@ -query MyFullName { - me { - name { - first - last - } - } -} - -query MyFirstName { - me { - name { - first - } - } -} diff --git a/router-bridge/src/testdata/schema.graphql b/router-bridge/src/testdata/schema.graphql deleted file mode 100644 index fdae5cec6..000000000 --- a/router-bridge/src/testdata/schema.graphql +++ /dev/null @@ -1,275 +0,0 @@ -schema -@core(feature: "https://specs.apollo.dev/core/v0.1") -@core(feature: "https://specs.apollo.dev/join/v0.1") { - query: Query - mutation: Mutation -} - -directive @core(feature: String!) repeatable on SCHEMA - -directive @join__field( - graph: join__Graph - requires: join__FieldSet - provides: join__FieldSet -) on FIELD_DEFINITION - -directive @join__type( - graph: join__Graph! - key: join__FieldSet -) repeatable on OBJECT | INTERFACE - -directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -union AccountType = PasswordAccount | SMSAccount - -type Amazon { - referrer: String -} - -union Body = Image | Text - -type Book implements Product -@join__owner(graph: BOOKS) -@join__type(graph: BOOKS, key: "isbn") -@join__type(graph: INVENTORY, key: "isbn") -@join__type(graph: PRODUCT, key: "isbn") -@join__type(graph: REVIEWS, key: "isbn") { - isbn: String! @join__field(graph: BOOKS) - title: String @join__field(graph: BOOKS) - year: Int @join__field(graph: BOOKS) - similarBooks: [Book]! @join__field(graph: BOOKS) - metadata: [MetadataOrError] @join__field(graph: BOOKS) - inStock: Boolean @join__field(graph: INVENTORY) - isCheckedOut: Boolean @join__field(graph: INVENTORY) - upc: String! @join__field(graph: PRODUCT) - sku: String! @join__field(graph: PRODUCT) - name(delimeter: String = " "): String - @join__field(graph: PRODUCT, requires: "title year") - price: String @join__field(graph: PRODUCT) - details: ProductDetailsBook @join__field(graph: PRODUCT) - reviews: [Review] @join__field(graph: REVIEWS) - relatedReviews: [Review!]! - @join__field(graph: REVIEWS, requires: "similarBooks{isbn}") -} - -union Brand = Ikea | Amazon - -type Car implements Vehicle -@join__owner(graph: PRODUCT) -@join__type(graph: PRODUCT, key: "id") -@join__type(graph: REVIEWS, key: "id") { - id: String! @join__field(graph: PRODUCT) - description: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - retailPrice: String @join__field(graph: REVIEWS, requires: "price") -} - -type Error { - code: Int - message: String -} - -type Furniture implements Product -@join__owner(graph: PRODUCT) -@join__type(graph: PRODUCT, key: "upc") -@join__type(graph: PRODUCT, key: "sku") -@join__type(graph: INVENTORY, key: "sku") -@join__type(graph: REVIEWS, key: "upc") { - upc: String! @join__field(graph: PRODUCT) - sku: String! @join__field(graph: PRODUCT) - name: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - brand: Brand @join__field(graph: PRODUCT) - metadata: [MetadataOrError] @join__field(graph: PRODUCT) - details: ProductDetailsFurniture @join__field(graph: PRODUCT) - inStock: Boolean @join__field(graph: INVENTORY) - isHeavy: Boolean @join__field(graph: INVENTORY) - reviews: [Review] @join__field(graph: REVIEWS) -} - -type Ikea { - asile: Int -} - -type Image implements NamedObject { - name: String! - attributes: ImageAttributes! -} - -type ImageAttributes { - url: String! -} - -scalar join__FieldSet - -enum join__Graph { - ACCOUNTS @join__graph(name: "accounts", url: "") - BOOKS @join__graph(name: "books", url: "") - DOCUMENTS @join__graph(name: "documents", url: "") - INVENTORY @join__graph(name: "inventory", url: "") - PRODUCT @join__graph(name: "product", url: "") - REVIEWS @join__graph(name: "reviews", url: "") -} - -type KeyValue { - key: String! - value: String! -} - -type Library -@join__owner(graph: BOOKS) -@join__type(graph: BOOKS, key: "id") -@join__type(graph: ACCOUNTS, key: "id") { - id: ID! @join__field(graph: BOOKS) - name: String @join__field(graph: BOOKS) - userAccount(id: ID! = 1): User @join__field(graph: ACCOUNTS, requires: "name") -} - -union MetadataOrError = KeyValue | Error - -type Mutation { - login(username: String!, password: String!): User - @join__field(graph: ACCOUNTS) - reviewProduct(upc: String!, body: String!): Product - @join__field(graph: REVIEWS) - updateReview(review: UpdateReviewInput!): Review @join__field(graph: REVIEWS) - deleteReview(id: ID!): Boolean @join__field(graph: REVIEWS) -} - -type Name { - first: String - last: String -} - -interface NamedObject { - name: String! -} - -type PasswordAccount -@join__owner(graph: ACCOUNTS) -@join__type(graph: ACCOUNTS, key: "email") { - email: String! @join__field(graph: ACCOUNTS) -} - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean - reviews: [Review] -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String - pages: Int -} - -type ProductDetailsFurniture implements ProductDetails { - country: String - color: String -} - -type Query { - user(id: ID!): User @join__field(graph: ACCOUNTS) - me: User @join__field(graph: ACCOUNTS) - book(isbn: String!): Book @join__field(graph: BOOKS) - books: [Book] @join__field(graph: BOOKS) - library(id: ID!): Library @join__field(graph: BOOKS) - body: Body! @join__field(graph: DOCUMENTS) - product(upc: String!): Product @join__field(graph: PRODUCT) - vehicle(id: String!): Vehicle @join__field(graph: PRODUCT) - topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCT) - topCars(first: Int = 5): [Car] @join__field(graph: PRODUCT) - topReviews(first: Int = 5): [Review] @join__field(graph: REVIEWS) -} - -type Review -@join__owner(graph: REVIEWS) -@join__type(graph: REVIEWS, key: "id") { - id: ID! @join__field(graph: REVIEWS) - body(format: Boolean = false): String @join__field(graph: REVIEWS) - author: User @join__field(graph: REVIEWS, provides: "username") - product: Product @join__field(graph: REVIEWS) - metadata: [MetadataOrError] @join__field(graph: REVIEWS) -} - -type SMSAccount -@join__owner(graph: ACCOUNTS) -@join__type(graph: ACCOUNTS, key: "number") { - number: String @join__field(graph: ACCOUNTS) -} - -type Text implements NamedObject { - name: String! - attributes: TextAttributes! -} - -type TextAttributes { - bold: Boolean - text: String -} - -union Thing = Car | Ikea - -input UpdateReviewInput { - id: ID! - body: String -} - -type User -@join__owner(graph: ACCOUNTS) -@join__type(graph: ACCOUNTS, key: "id") -@join__type(graph: ACCOUNTS, key: "username name{first last}") -@join__type(graph: INVENTORY, key: "id") -@join__type(graph: PRODUCT, key: "id") -@join__type(graph: REVIEWS, key: "id") { - id: ID! @join__field(graph: ACCOUNTS) - name: Name @join__field(graph: ACCOUNTS) - username: String @join__field(graph: ACCOUNTS) - birthDate(locale: String): String @join__field(graph: ACCOUNTS) - account: AccountType @join__field(graph: ACCOUNTS) - metadata: [UserMetadata] @join__field(graph: ACCOUNTS) - goodDescription: Boolean - @join__field(graph: INVENTORY, requires: "metadata{description}") - vehicle: Vehicle @join__field(graph: PRODUCT) - thing: Thing @join__field(graph: PRODUCT) - reviews: [Review] @join__field(graph: REVIEWS) - numberOfReviews: Int! @join__field(graph: REVIEWS) - goodAddress: Boolean - @join__field(graph: REVIEWS, requires: "metadata{address}") -} - -type UserMetadata { - name: String - address: String - description: String -} - -type Van implements Vehicle -@join__owner(graph: PRODUCT) -@join__type(graph: PRODUCT, key: "id") -@join__type(graph: REVIEWS, key: "id") { - id: String! @join__field(graph: PRODUCT) - description: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - retailPrice: String @join__field(graph: REVIEWS, requires: "price") -} - -interface Vehicle { - id: String! - description: String - price: String - retailPrice: String -} diff --git a/router-bridge/src/testdata/schema_generate_query_fragments.graphql b/router-bridge/src/testdata/schema_generate_query_fragments.graphql deleted file mode 100644 index adff902ab..000000000 --- a/router-bridge/src/testdata/schema_generate_query_fragments.graphql +++ /dev/null @@ -1,94 +0,0 @@ -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.4", for: EXECUTION) { - query: Query -} - -directive @join__directive( - graphs: [join__Graph!] - name: String! - args: join__DirectiveArguments -) repeatable on SCHEMA | OBJECT | INTERFACE | FIELD_DEFINITION - -directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE - -directive @join__field( - graph: join__Graph - requires: join__FieldSet - provides: join__FieldSet - type: String - external: Boolean - override: String - usedOverridden: Boolean - overrideLabel: String -) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @join__implements( - graph: join__Graph! - interface: String! -) repeatable on OBJECT | INTERFACE - -directive @join__type( - graph: join__Graph! - key: join__FieldSet - extension: Boolean! = false - resolvable: Boolean! = true - isInterfaceObject: Boolean! = false -) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR - -directive @join__unionMember( - graph: join__Graph! - member: String! -) repeatable on UNION - -directive @link( - url: String - as: String - for: link__Purpose - import: [link__Import] -) repeatable on SCHEMA - -type A @join__type(graph: SUBGRAPH1) { - x: Int - y: Int - t: T -} - -type B @join__type(graph: SUBGRAPH1) { - z: Int -} - -scalar join__DirectiveArguments - -scalar join__FieldSet - -enum join__Graph { - SUBGRAPH1 @join__graph(name: "Subgraph1", url: "") -} - -scalar link__Import - -enum link__Purpose { - """ - \`SECURITY\` features provide metadata necessary to securely resolve fields. - """ - SECURITY - """ - \`EXECUTION\` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -type Query @join__type(graph: SUBGRAPH1) { - t: T - t2: T -} - -union T - @join__type(graph: SUBGRAPH1) - @join__unionMember(graph: SUBGRAPH1, member: "A") - @join__unionMember(graph: SUBGRAPH1, member: "B") = - A - | B diff --git a/router-bridge/src/testdata/schema_reuse_query_fragments.graphql b/router-bridge/src/testdata/schema_reuse_query_fragments.graphql deleted file mode 100644 index 1979302dd..000000000 --- a/router-bridge/src/testdata/schema_reuse_query_fragments.graphql +++ /dev/null @@ -1,60 +0,0 @@ -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) -{ - query: Query -} - -directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE - -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE - -directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR - -directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -type A - @join__type(graph: SUBGRAPH1) -{ - x: Int - y: Int -} - -scalar join__FieldSet - -enum join__Graph { - SUBGRAPH1 @join__graph(name: "Subgraph1", url: "") -} - -scalar link__Import - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -type Query - @join__type(graph: SUBGRAPH1) -{ - t: T -} - -type T - @join__type(graph: SUBGRAPH1) -{ - a1: A - a2: A -} diff --git a/router-bridge/src/testdata/schema_without_review_body.graphql b/router-bridge/src/testdata/schema_without_review_body.graphql deleted file mode 100644 index 81f99788d..000000000 --- a/router-bridge/src/testdata/schema_without_review_body.graphql +++ /dev/null @@ -1,274 +0,0 @@ -schema -@core(feature: "https://specs.apollo.dev/core/v0.1") -@core(feature: "https://specs.apollo.dev/join/v0.1") { - query: Query - mutation: Mutation -} - -directive @core(feature: String!) repeatable on SCHEMA - -directive @join__field( - graph: join__Graph - requires: join__FieldSet - provides: join__FieldSet -) on FIELD_DEFINITION - -directive @join__type( - graph: join__Graph! - key: join__FieldSet -) repeatable on OBJECT | INTERFACE - -directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @stream on FIELD - -directive @transform(from: String!) on FIELD - -union AccountType = PasswordAccount | SMSAccount - -type Amazon { - referrer: String -} - -union Body = Image | Text - -type Book implements Product -@join__owner(graph: BOOKS) -@join__type(graph: BOOKS, key: "isbn") -@join__type(graph: INVENTORY, key: "isbn") -@join__type(graph: PRODUCT, key: "isbn") -@join__type(graph: REVIEWS, key: "isbn") { - isbn: String! @join__field(graph: BOOKS) - title: String @join__field(graph: BOOKS) - year: Int @join__field(graph: BOOKS) - similarBooks: [Book]! @join__field(graph: BOOKS) - metadata: [MetadataOrError] @join__field(graph: BOOKS) - inStock: Boolean @join__field(graph: INVENTORY) - isCheckedOut: Boolean @join__field(graph: INVENTORY) - upc: String! @join__field(graph: PRODUCT) - sku: String! @join__field(graph: PRODUCT) - name(delimeter: String = " "): String - @join__field(graph: PRODUCT, requires: "title year") - price: String @join__field(graph: PRODUCT) - details: ProductDetailsBook @join__field(graph: PRODUCT) - reviews: [Review] @join__field(graph: REVIEWS) - relatedReviews: [Review!]! - @join__field(graph: REVIEWS, requires: "similarBooks{isbn}") -} - -union Brand = Ikea | Amazon - -type Car implements Vehicle -@join__owner(graph: PRODUCT) -@join__type(graph: PRODUCT, key: "id") -@join__type(graph: REVIEWS, key: "id") { - id: String! @join__field(graph: PRODUCT) - description: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - retailPrice: String @join__field(graph: REVIEWS, requires: "price") -} - -type Error { - code: Int - message: String -} - -type Furniture implements Product -@join__owner(graph: PRODUCT) -@join__type(graph: PRODUCT, key: "upc") -@join__type(graph: PRODUCT, key: "sku") -@join__type(graph: INVENTORY, key: "sku") -@join__type(graph: REVIEWS, key: "upc") { - upc: String! @join__field(graph: PRODUCT) - sku: String! @join__field(graph: PRODUCT) - name: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - brand: Brand @join__field(graph: PRODUCT) - metadata: [MetadataOrError] @join__field(graph: PRODUCT) - details: ProductDetailsFurniture @join__field(graph: PRODUCT) - inStock: Boolean @join__field(graph: INVENTORY) - isHeavy: Boolean @join__field(graph: INVENTORY) - reviews: [Review] @join__field(graph: REVIEWS) -} - -type Ikea { - asile: Int -} - -type Image implements NamedObject { - name: String! - attributes: ImageAttributes! -} - -type ImageAttributes { - url: String! -} - -scalar join__FieldSet - -enum join__Graph { - ACCOUNTS @join__graph(name: "accounts", url: "") - BOOKS @join__graph(name: "books", url: "") - DOCUMENTS @join__graph(name: "documents", url: "") - INVENTORY @join__graph(name: "inventory", url: "") - PRODUCT @join__graph(name: "product", url: "") - REVIEWS @join__graph(name: "reviews", url: "") -} - -type KeyValue { - key: String! - value: String! -} - -type Library -@join__owner(graph: BOOKS) -@join__type(graph: BOOKS, key: "id") -@join__type(graph: ACCOUNTS, key: "id") { - id: ID! @join__field(graph: BOOKS) - name: String @join__field(graph: BOOKS) - userAccount(id: ID! = 1): User @join__field(graph: ACCOUNTS, requires: "name") -} - -union MetadataOrError = KeyValue | Error - -type Mutation { - login(username: String!, password: String!): User - @join__field(graph: ACCOUNTS) - reviewProduct(upc: String!, body: String!): Product - @join__field(graph: REVIEWS) - updateReview(review: UpdateReviewInput!): Review @join__field(graph: REVIEWS) - deleteReview(id: ID!): Boolean @join__field(graph: REVIEWS) -} - -type Name { - first: String - last: String -} - -interface NamedObject { - name: String! -} - -type PasswordAccount -@join__owner(graph: ACCOUNTS) -@join__type(graph: ACCOUNTS, key: "email") { - email: String! @join__field(graph: ACCOUNTS) -} - -interface Product { - upc: String! - sku: String! - name: String - price: String - details: ProductDetails - inStock: Boolean - reviews: [Review] -} - -interface ProductDetails { - country: String -} - -type ProductDetailsBook implements ProductDetails { - country: String - pages: Int -} - -type ProductDetailsFurniture implements ProductDetails { - country: String - color: String -} - -type Query { - user(id: ID!): User @join__field(graph: ACCOUNTS) - me: User @join__field(graph: ACCOUNTS) - book(isbn: String!): Book @join__field(graph: BOOKS) - books: [Book] @join__field(graph: BOOKS) - library(id: ID!): Library @join__field(graph: BOOKS) - body: Body! @join__field(graph: DOCUMENTS) - product(upc: String!): Product @join__field(graph: PRODUCT) - vehicle(id: String!): Vehicle @join__field(graph: PRODUCT) - topProducts(first: Int = 5): [Product] @join__field(graph: PRODUCT) - topCars(first: Int = 5): [Car] @join__field(graph: PRODUCT) - topReviews(first: Int = 5): [Review] @join__field(graph: REVIEWS) -} - -type Review -@join__owner(graph: REVIEWS) -@join__type(graph: REVIEWS, key: "id") { - id: ID! @join__field(graph: REVIEWS) - author: User @join__field(graph: REVIEWS, provides: "username") - product: Product @join__field(graph: REVIEWS) - metadata: [MetadataOrError] @join__field(graph: REVIEWS) -} - -type SMSAccount -@join__owner(graph: ACCOUNTS) -@join__type(graph: ACCOUNTS, key: "number") { - number: String @join__field(graph: ACCOUNTS) -} - -type Text implements NamedObject { - name: String! - attributes: TextAttributes! -} - -type TextAttributes { - bold: Boolean - text: String -} - -union Thing = Car | Ikea - -input UpdateReviewInput { - id: ID! - body: String -} - -type User -@join__owner(graph: ACCOUNTS) -@join__type(graph: ACCOUNTS, key: "id") -@join__type(graph: ACCOUNTS, key: "username name{first last}") -@join__type(graph: INVENTORY, key: "id") -@join__type(graph: PRODUCT, key: "id") -@join__type(graph: REVIEWS, key: "id") { - id: ID! @join__field(graph: ACCOUNTS) - name: Name @join__field(graph: ACCOUNTS) - username: String @join__field(graph: ACCOUNTS) - birthDate(locale: String): String @join__field(graph: ACCOUNTS) - account: AccountType @join__field(graph: ACCOUNTS) - metadata: [UserMetadata] @join__field(graph: ACCOUNTS) - goodDescription: Boolean - @join__field(graph: INVENTORY, requires: "metadata{description}") - vehicle: Vehicle @join__field(graph: PRODUCT) - thing: Thing @join__field(graph: PRODUCT) - reviews: [Review] @join__field(graph: REVIEWS) - numberOfReviews: Int! @join__field(graph: REVIEWS) - goodAddress: Boolean - @join__field(graph: REVIEWS, requires: "metadata{address}") -} - -type UserMetadata { - name: String - address: String - description: String -} - -type Van implements Vehicle -@join__owner(graph: PRODUCT) -@join__type(graph: PRODUCT, key: "id") -@join__type(graph: REVIEWS, key: "id") { - id: String! @join__field(graph: PRODUCT) - description: String @join__field(graph: PRODUCT) - price: String @join__field(graph: PRODUCT) - retailPrice: String @join__field(graph: REVIEWS, requires: "price") -} - -interface Vehicle { - id: String! - description: String - price: String - retailPrice: String -} diff --git a/router-bridge/src/testdata/typed_conditions.graphql b/router-bridge/src/testdata/typed_conditions.graphql deleted file mode 100644 index 69a5b7571..000000000 --- a/router-bridge/src/testdata/typed_conditions.graphql +++ /dev/null @@ -1,92 +0,0 @@ -schema - @link(url: "https://specs.apollo.dev/link/v1.0") - @link(url: "https://specs.apollo.dev/join/v0.3", for: EXECUTION) -{ - query: Query -} - -directive @join__enumValue(graph: join__Graph!) repeatable on ENUM_VALUE - -directive @join__field(graph: join__Graph, requires: join__FieldSet, provides: join__FieldSet, type: String, external: Boolean, override: String, usedOverridden: Boolean) repeatable on FIELD_DEFINITION | INPUT_FIELD_DEFINITION - -directive @join__graph(name: String!, url: String!) on ENUM_VALUE - -directive @join__implements(graph: join__Graph!, interface: String!) repeatable on OBJECT | INTERFACE - -directive @join__type(graph: join__Graph!, key: join__FieldSet, extension: Boolean! = false, resolvable: Boolean! = true, isInterfaceObject: Boolean! = false) repeatable on OBJECT | INTERFACE | UNION | ENUM | INPUT_OBJECT | SCALAR - -directive @join__unionMember(graph: join__Graph!, member: String!) repeatable on UNION - -directive @link(url: String, as: String, for: link__Purpose, import: [link__Import]) repeatable on SCHEMA - -type ArticleResult - @join__type(graph: SEARCHSUBGRAPH, key: "id") -{ - id: ID! - sections: [Section] -} - -type EntityCollectionSection - @join__type(graph: ARTWORKSUBGRAPH, key: "id") - @join__type(graph: SEARCHSUBGRAPH, key: "id") -{ - id: ID! - title: String @join__field(graph: ARTWORKSUBGRAPH) - artwork(params: String): String @join__field(graph: ARTWORKSUBGRAPH) -} - -type GallerySection - @join__type(graph: ARTWORKSUBGRAPH, key: "id") - @join__type(graph: SEARCHSUBGRAPH, key: "id") -{ - id: ID! - artwork(params: String): String @join__field(graph: ARTWORKSUBGRAPH) -} - -scalar join__FieldSet - -enum join__Graph { - ARTWORKSUBGRAPH @join__graph(name: "artworkSubgraph", url: "http://localhost:4042") - SEARCHSUBGRAPH @join__graph(name: "searchSubgraph", url: "http://localhost:4041") -} - -scalar link__Import - -enum link__Purpose { - """ - `SECURITY` features provide metadata necessary to securely resolve fields. - """ - SECURITY - - """ - `EXECUTION` features provide metadata necessary for operation execution. - """ - EXECUTION -} - -type MovieResult - @join__type(graph: SEARCHSUBGRAPH, key: "id") -{ - id: ID! - sections: [Section] -} - -type Query - @join__type(graph: ARTWORKSUBGRAPH) - @join__type(graph: SEARCHSUBGRAPH) -{ - me: String @join__field(graph: ARTWORKSUBGRAPH) - search: [SearchResult] @join__field(graph: SEARCHSUBGRAPH) -} - -union SearchResult - @join__type(graph: SEARCHSUBGRAPH) - @join__unionMember(graph: SEARCHSUBGRAPH, member: "MovieResult") - @join__unionMember(graph: SEARCHSUBGRAPH, member: "ArticleResult") - = MovieResult | ArticleResult - -union Section - @join__type(graph: SEARCHSUBGRAPH) - @join__unionMember(graph: SEARCHSUBGRAPH, member: "EntityCollectionSection") - @join__unionMember(graph: SEARCHSUBGRAPH, member: "GallerySection") - = EntityCollectionSection | GallerySection diff --git a/router-bridge/src/testdata/unsupported_feature.graphql b/router-bridge/src/testdata/unsupported_feature.graphql deleted file mode 100644 index e10e031a2..000000000 --- a/router-bridge/src/testdata/unsupported_feature.graphql +++ /dev/null @@ -1,47 +0,0 @@ - schema - @core(feature: "https://specs.apollo.dev/core/v0.2") - @core(feature: "https://specs.apollo.dev/tag/v0.1") - @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) - @core(feature: "https://specs.apollo.dev/unsupported-feature/v0.1") { - query: Query - } - directive @core( - feature: String! - as: String - for: core__Purpose - ) repeatable on SCHEMA - directive @join__field( - graph: join__Graph - requires: join__FieldSet - provides: join__FieldSet - ) on FIELD_DEFINITION - directive @join__type( - graph: join__Graph! - key: join__FieldSet - ) repeatable on OBJECT | INTERFACE - directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE - directive @join__graph(name: String!, url: String!) on ENUM_VALUE - directive @tag( - name: String! - ) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION - enum CacheControlScope { - PRIVATE - PUBLIC - } - enum core__Purpose { - """ - \`EXECUTION\` features provide metadata necessary to for operation execution. - """ - EXECUTION - """ - \`SECURITY\` features provide metadata necessary to securely resolve fields. - """ - SECURITY - } - scalar join__FieldSet - enum join__Graph { - WORLD @join__graph(name: "world", url: "https://world.api.com") - } - type Query { - hello: String! @join__field(graph: WORLD) - } \ No newline at end of file diff --git a/router-bridge/src/testdata/unsupported_feature_for_execution.graphql b/router-bridge/src/testdata/unsupported_feature_for_execution.graphql deleted file mode 100644 index 04f40d7f8..000000000 --- a/router-bridge/src/testdata/unsupported_feature_for_execution.graphql +++ /dev/null @@ -1,49 +0,0 @@ -schema - @core(feature: "https://specs.apollo.dev/core/v0.2") - @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) - @core( - feature: "https://specs.apollo.dev/unsupported-feature/v0.1" - for: EXECUTION - ) { - query: Query - } - directive @core( - feature: String! - as: String - for: core__Purpose - ) repeatable on SCHEMA - directive @join__field( - graph: join__Graph - requires: join__FieldSet - provides: join__FieldSet - ) on FIELD_DEFINITION - directive @join__type( - graph: join__Graph! - key: join__FieldSet - ) repeatable on OBJECT | INTERFACE - directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE - directive @join__graph(name: String!, url: String!) on ENUM_VALUE - directive @tag( - name: String! - ) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION - enum CacheControlScope { - PRIVATE - PUBLIC - } - enum core__Purpose { - """ - \`EXECUTION\` features provide metadata necessary to for operation execution. - """ - EXECUTION - """ - \`SECURITY\` features provide metadata necessary to securely resolve fields. - """ - SECURITY - } - scalar join__FieldSet - enum join__Graph { - WORLD @join__graph(name: "world", url: "https://world.api.com") - } - type Query { - hello: String! @join__field(graph: WORLD) - } \ No newline at end of file diff --git a/router-bridge/src/testdata/unsupported_feature_for_security.graphql b/router-bridge/src/testdata/unsupported_feature_for_security.graphql deleted file mode 100644 index e73a0f286..000000000 --- a/router-bridge/src/testdata/unsupported_feature_for_security.graphql +++ /dev/null @@ -1,61 +0,0 @@ -schema - @core(feature: "https://specs.apollo.dev/core/v0.2") - @core(feature: "https://specs.apollo.dev/join/v0.1", for: EXECUTION) - @core( - feature: "https://specs.apollo.dev/unsupported-feature/v0.1" - for: SECURITY - ) { - query: Query - } - - directive @core( - feature: String! - as: String - for: core__Purpose - ) repeatable on SCHEMA - - directive @join__field( - graph: join__Graph - requires: join__FieldSet - provides: join__FieldSet - ) on FIELD_DEFINITION - - directive @join__type( - graph: join__Graph! - key: join__FieldSet - ) repeatable on OBJECT | INTERFACE - - directive @join__owner(graph: join__Graph!) on OBJECT | INTERFACE - - directive @join__graph(name: String!, url: String!) on ENUM_VALUE - - directive @tag( - name: String! - ) repeatable on FIELD_DEFINITION | INTERFACE | OBJECT | UNION - - enum CacheControlScope { - PRIVATE - PUBLIC - } - - enum core__Purpose { - """ - \`EXECUTION\` features provide metadata necessary to for operation execution. - """ - EXECUTION - - """ - \`SECURITY\` features provide metadata necessary to securely resolve fields. - """ - SECURITY - } - - scalar join__FieldSet - - enum join__Graph { - WORLD @join__graph(name: "world", url: "https://world.api.com.invalid") - } - - type Query { - hello: String! @join__field(graph: WORLD) - } \ No newline at end of file diff --git a/router-bridge/src/worker.rs b/router-bridge/src/worker.rs deleted file mode 100644 index 8f9af1484..000000000 --- a/router-bridge/src/worker.rs +++ /dev/null @@ -1,454 +0,0 @@ -use crate::error::Error; -use async_channel::{bounded, Receiver, Sender}; -use deno_core::{op, Extension, OpState}; -use deno_core::{v8, Op}; -use rand::rngs::StdRng; -use rand::{thread_rng, Rng}; -use serde::de::DeserializeOwned; -use serde::Deserialize; -use serde::Serialize; -use std::borrow::Cow; -use std::cell::RefCell; -use std::collections::hash_map::DefaultHasher; -use std::collections::HashMap; -use std::convert::TryFrom; -use std::fmt::Debug; -use std::hash::Hasher; -use std::rc::Rc; -use std::sync::Arc; -use std::thread::JoinHandle; -use tokio::sync::{oneshot, Mutex}; - -#[derive(Serialize, Deserialize, Debug)] -struct JsonPayload { - id: String, - payload: serde_json::Value, -} - -pub(crate) struct JsWorker { - response_senders: Arc>>>, - response_receivers: Arc>>>, - sender: Sender, - handle: Option>, - unsent_plans: Arc>>, -} - -impl JsWorker { - pub(crate) fn new(worker_source_code: &'static str) -> Self { - let response_senders: Arc>>> = - Default::default(); - - let cloned_senders = response_senders.clone(); - - let (response_sender, receiver) = bounded::(10_000); - let (sender, request_receiver) = bounded::(10_000); - - let unsent_plans = Arc::new(Mutex::new(HashMap::new())); - let my_unsent_plans = unsent_plans.clone(); - - tokio::spawn(async move { - while let Ok(json_payload) = receiver.recv().await { - if let Some(sender) = cloned_senders.lock().await.remove(&json_payload.id) { - if let Err(e) = sender.send(json_payload.payload.clone()) { - // Keep our plan in our failed plan cache. Someone else might want it. - tracing::error!("jsworker: couldn't send json response: {:?}", e); - my_unsent_plans - .lock() - .await - .insert(json_payload.id, json_payload.payload); - } - } else { - tracing::error!( - "jsworker: couldn't find sender for payload id {}", - &json_payload.id - ); - } - } - tracing::debug!("deno runtime shutdown successfully"); - }); - - let handle = std::thread::spawn(move || { - let my_ext = Extension { - name: concat!(env!("CARGO_PKG_NAME"), "_worker"), - ops: Cow::Borrowed(&[ - send::DECL, - receive::DECL, - log_trace::DECL, - log_debug::DECL, - log_info::DECL, - log_warn::DECL, - log_error::DECL, - op_crypto_get_random_values::DECL, - op_runtime_memory_usage::DECL, - ]), - op_state_fn: Some(Box::new(move |state| { - state.put(response_sender.clone()); - state.put(request_receiver); - })), - ..Default::default() - }; - - let mut js_runtime = - crate::js::Js::new("query planner".to_string()).build_js_runtime(my_ext); - - let runtime = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap(); - - let future = async move { - js_runtime - .execute_script_static("worker.js", worker_source_code) - .unwrap(); - js_runtime.run_event_loop(false).await - }; - runtime.block_on(future).unwrap(); - }); - - Self { - sender, - handle: Some(handle), - response_receivers: Default::default(), - response_senders, - unsent_plans, - } - } - - pub(crate) async fn request( - &self, - command: Request, - ) -> Result - where - Request: std::hash::Hash + Serialize + Send + Debug + 'static, - Response: DeserializeOwned + Send + Debug + 'static, - { - // Let's see if we already have this query plan in our failed delivery cache - let mut hasher = DefaultHasher::new(); - command.hash(&mut hasher); - // JavaScript can't process 64 bit numbers, so convert our hash to a string... - let id = hasher.finish().to_string(); - - if let Some(payload) = self.unsent_plans.lock().await.remove(&id) { - serde_json::from_value(payload).map_err(|e| Error::ParameterDeserialization { - message: format!("deno: couldn't deserialize response : `{e:?}`"), - id, - }) - } else { - self.send(Some(id.clone()), command) - .await - .map_err(|e| Error::DenoRuntime(format!("couldn't send request {e}")))?; - self.receive(id) - .await - .map_err(|e| Error::DenoRuntime(format!("request: couldn't receive response {e}"))) - } - } - - pub(crate) async fn send( - &self, - id_opt: Option, - request: Request, - ) -> Result - where - Request: std::hash::Hash + Serialize + Send + Debug + 'static, - { - let id = match id_opt { - Some(id) => id, - None => { - let mut hasher = DefaultHasher::new(); - request.hash(&mut hasher); - // JavaScript can't process 64 bit numbers, so convert our hash to a string... - hasher.finish().to_string() - } - }; - - let (sender, receiver) = oneshot::channel(); - { - self.response_senders - .lock() - .await - .insert(id.clone(), sender); - self.response_receivers - .lock() - .await - .insert(id.clone(), receiver); - } - let json_payload = JsonPayload { - id: id.clone(), - payload: serde_json::to_value(request).map_err(|e| Error::ParameterSerialization { - message: format!("deno: couldn't serialize request : `{e:?}`"), - name: "request".to_string(), - })?, - }; - - self.sender - .send(json_payload) - .await - .map_err(|e| Error::DenoRuntime(format!("send: couldn't send request {e}")))?; - Ok(id) - } - - async fn receive(&self, id: String) -> Result - where - Response: DeserializeOwned + Send + Debug + 'static, - { - let receiver = self - .response_receivers - .lock() - .await - .remove(&id) - .expect("couldn't find id in response_receivers"); - let payload = receiver.await.map_err(|e| { - Error::DenoRuntime(format!("request: couldn't receive response: {e:?}")) - })?; - - serde_json::from_value(payload).map_err(|e| Error::ParameterDeserialization { - message: format!("deno: couldn't deserialize response : `{e:?}`"), - id, - }) - } - - fn quit(&mut self) -> Result<(), Error> { - if let Some(handle) = self.handle.take() { - handle.join().map_err(|_| { - Error::DenoRuntime("couldn't wait for JsRuntime to finish".to_string()) - }) - } else { - Ok(()) - } - } -} - -impl Drop for JsWorker { - fn drop(&mut self) { - self.quit().unwrap_or_else(|e| eprintln!("{e}")); - } -} - -// Logging capabilities -#[op] -fn log_trace(_: &mut OpState, message: String) -> Result<(), anyhow::Error> { - tracing::trace!("{message}"); - Ok(()) -} - -#[op] -fn log_debug(_: &mut OpState, message: String) -> Result<(), anyhow::Error> { - tracing::debug!("{message}"); - Ok(()) -} - -#[op] -fn log_info(_: &mut OpState, message: String) -> Result<(), anyhow::Error> { - tracing::info!("{message}"); - Ok(()) -} - -#[op] -fn log_warn(_: &mut OpState, message: String) -> Result<(), anyhow::Error> { - tracing::warn!("{message}"); - Ok(()) -} - -#[op] -fn log_error(_: &mut OpState, message: String) -> Result<(), anyhow::Error> { - tracing::error!("{message}"); - Ok(()) -} - -#[op] -async fn send(state: Rc>, payload: JsonPayload) -> Result<(), anyhow::Error> { - let sender = { - let state = state.borrow(); - // we're cloning here because we don't wanna keep the borrow across an await point - state.borrow::>().clone() - }; - - sender - .send(payload) - .await - .map_err(|e| anyhow::anyhow!("couldn't send response {e}")) -} - -#[op] -async fn receive(state: Rc>) -> Result { - let receiver = { - let state = state.borrow(); - state.borrow::>().clone() - }; - - receiver - .recv() - .await - .map_err(|e| anyhow::anyhow!("op_receive: couldn't send response {e}")) -} - -// function presence tested in router-bridge/js-src/test_get_random_values.ts -#[op(fast)] -fn op_crypto_get_random_values(state: &mut OpState, out: &mut [u8]) -> Result<(), anyhow::Error> { - if out.len() > 65536 { - return Err( - deno_web::DomExceptionQuotaExceededError::new(&format!("The ArrayBufferView's byte length ({}) exceeds the number of bytes of entropy available via this API (65536)", out.len())) - .into(), - ); - } - - let maybe_seeded_rng = state.try_borrow_mut::(); - if let Some(seeded_rng) = maybe_seeded_rng { - seeded_rng.fill(out); - } else { - let mut rng = thread_rng(); - rng.fill(out); - } - - Ok(()) -} - -// HeapStats stores values from a isolate.get_heap_statistics() call -#[derive(Serialize)] -#[serde(rename_all = "camelCase")] -struct MemoryUsage { - //rss: usize, - heap_total: usize, - heap_used: usize, - external: usize, -} - -// from https://github.com/denoland/deno/blob/897159dc6e1b2319cf2f5f09d8d6cecc0d3175fa/runtime/ops/os/mod.rs#L329 -// tested in planner.rs -#[op(v8)] -fn op_runtime_memory_usage(scope: &mut v8::HandleScope<'_>) -> MemoryUsage { - let mut s = v8::HeapStatistics::default(); - scope.get_heap_statistics(&mut s); - MemoryUsage { - //rss: rss(), - heap_total: s.total_heap_size(), - heap_used: s.used_heap_size(), - external: s.external_memory(), - } -} - -#[cfg(test)] -mod worker_tests { - use super::JsWorker; - use serde::{Deserialize, Serialize}; - - #[tokio::test] - #[tracing_test::traced_test] - async fn logging_works() { - let expected_present_logs = [ - "TRACE router_bridge::worker: this is a Trace level log", - "DEBUG router_bridge::worker: this is a Debug level log", - "INFO router_bridge::worker: this is an Info level log", - "WARN router_bridge::worker: this is a Warn level log", - "ERROR router_bridge::worker: this is an Error level log", - ]; - run_logger().await; - logs_assert(|lines: &[&str]| { - for log in expected_present_logs { - assert!( - lines.iter().any(|line| line.ends_with(log)), - "couldn't find log `{}` in the traced logs:\n{}", - log, - lines.join("\n") - ); - } - - Ok(()) - }); - } - - async fn run_logger() { - #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] - enum Kind { - Trace, - Debug, - Info, - Warn, - Error, - Exit, - } - - #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash)] - struct Command { - kind: Kind, - message: Option, - } - let worker = JsWorker::new(include_str!("../bundled/test_logger_worker.js")); - - let trace_succeeded: bool = worker - .request(Command { - kind: Kind::Trace, - message: Some("this is a Trace level log".to_string()), - }) - .await - .unwrap(); - - let debug_succeeded: bool = worker - .request(Command { - kind: Kind::Debug, - message: Some("this is a Debug level log".to_string()), - }) - .await - .unwrap(); - - let info_succeeded: bool = worker - .request(Command { - kind: Kind::Info, - message: Some("this is an Info level log".to_string()), - }) - .await - .unwrap(); - - let warn_succeeded: bool = worker - .request(Command { - kind: Kind::Warn, - message: Some("this is a Warn level log".to_string()), - }) - .await - .unwrap(); - - let error_succeeded: bool = worker - .request(Command { - kind: Kind::Error, - message: Some("this is an Error level log".to_string()), - }) - .await - .unwrap(); - - // let's shutdown the js worker before we run assertions, - // to prevent a potential hang - let shutdown_succeeded: bool = worker - .request(Command { - kind: Kind::Exit, - message: None, - }) - .await - .unwrap(); - - assert!(warn_succeeded, "couldn't send warn log command"); - assert!(info_succeeded, "couldn't send info log command"); - assert!(debug_succeeded, "couldn't send debug log command"); - assert!(trace_succeeded, "couldn't send trace log command"); - assert!(error_succeeded, "couldn't send error log command"); - assert!(shutdown_succeeded, "couldn't send shutdown command"); - } - - #[tokio::test] - // This test ensures crypto.getRandomValues can be called. - // the uuid dependency relies on it since v9.0 - async fn test_get_random_values() { - let mut worker = JsWorker::new(include_str!("../bundled/test_get_random_values.js")); - - worker.quit().unwrap(); - } - - #[tokio::test] - // This test ensures the URL api is available. - // federation relies on it since 2.7 - async fn test_url() { - let mut worker = JsWorker::new(include_str!("../bundled/test_get_random_values.js")); - - JsWorker::new(include_str!("../bundled/test_url.js")); - worker.quit().unwrap(); - } -} diff --git a/router-bridge/tsconfig.json b/router-bridge/tsconfig.json deleted file mode 100644 index 13083ea1e..000000000 --- a/router-bridge/tsconfig.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "target": "es2019", - "module": "commonjs", - "moduleResolution": "node", - "esModuleInterop": true, - "sourceMap": true, - "declaration": true, - "declarationMap": true, - "removeComments": true, - "noImplicitAny": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "noUnusedParameters": true, - "noUnusedLocals": true, - "useUnknownInCatchVariables": false, - "forceConsistentCasingInFileNames": true, - "lib": ["es2021", "esnext.asynciterable"], - "rootDir": "./js-src", - "outDir": "./js-dist", - "types": [], - "allowJs": true, - "strict": false, - }, - "include": ["./js-src/**/*"], - "exclude": ["**/__tests__"] -} From 7fa6fb9e59c0b8bb0a2d477984b47fe2740f014e Mon Sep 17 00:00:00 2001 From: Nicholas Cioli Date: Thu, 19 Dec 2024 16:06:49 -0500 Subject: [PATCH 2/3] fix clippy --- apollo-federation-types/src/config/version.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apollo-federation-types/src/config/version.rs b/apollo-federation-types/src/config/version.rs index 74231d200..27fdc8b46 100644 --- a/apollo-federation-types/src/config/version.rs +++ b/apollo-federation-types/src/config/version.rs @@ -224,7 +224,7 @@ impl<'de> Deserialize<'de> for FederationVersion { { struct Visitor; - impl<'de> serde::de::Visitor<'de> for Visitor { + impl serde::de::Visitor<'_> for Visitor { type Value = FederationVersion; fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result { From 0bef5db6a34950dc8afb378ecf9dbc454214adc4 Mon Sep 17 00:00:00 2001 From: Nicholas Cioli Date: Thu, 19 Dec 2024 16:59:06 -0500 Subject: [PATCH 3/3] remove npm dependency entirely for ci --- .circleci/config.yml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 4fb53b42e..90eef6ea4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -152,28 +152,6 @@ commands: - install_rust_toolchain: platform: << parameters.platform >> - - install_volta: - platform: << parameters.platform >> - - install_volta: - parameters: - platform: - type: executor - steps: - - run: - name: Install volta - command: | - curl https://get.volta.sh | bash -s -- --skip-setup - echo 'export VOLTA_HOME=$HOME/.volta' >> $BASH_ENV - echo 'export PATH=$VOLTA_HOME/bin:$PATH' >> $BASH_ENV - - - run: - name: Install default versions of npm and node - command: | - volta install node@16 - volta install npm@8 - - install_rust_toolchain: parameters: platform: