From b128a40c0b42a2eccace0e58081faba33dbe2d89 Mon Sep 17 00:00:00 2001 From: Avery Harnish Date: Thu, 3 Dec 2020 13:59:18 -0600 Subject: [PATCH] feat(rover): checks --- Cargo.lock | 126 +- Cargo.toml | 3 +- crates/rover-client/Cargo.toml | 1 + crates/rover-client/src/blocking/client.rs | 7 +- crates/rover-client/src/error.rs | 10 +- .../src/query/graph/check.graphql | 35 + crates/rover-client/src/query/graph/check.rs | 76 + .../src/query/{schema => graph}/get.graphql | 0 .../src/query/{schema => graph}/get.rs | 2 +- crates/rover-client/src/query/graph/mod.rs | 8 + .../src/query/{schema => graph}/push.graphql | 0 .../src/query/{schema => graph}/push.rs | 2 +- crates/rover-client/src/query/mod.rs | 8 +- crates/rover-client/src/query/partial/mod.rs | 5 - crates/rover-client/src/query/schema/mod.rs | 5 - .../{partial => subgraph}/delete.graphql | 0 .../src/query/{partial => subgraph}/delete.rs | 2 +- crates/rover-client/src/query/subgraph/mod.rs | 5 + .../query/{partial => subgraph}/push.graphql | 0 .../src/query/{partial => subgraph}/push.rs | 12 +- schema.graphql | 8602 +++++++++++++++++ src/command/graph/check.rs | 68 + src/command/graph/fetch.rs | 2 +- src/command/graph/mod.rs | 5 + src/command/graph/push.rs | 2 +- src/command/output.rs | 21 +- src/command/subgraph/check.rs | 36 + src/command/subgraph/delete.rs | 2 +- src/command/subgraph/mod.rs | 6 + src/command/subgraph/push.rs | 2 +- test.graphql | 80 + 31 files changed, 9094 insertions(+), 39 deletions(-) create mode 100644 crates/rover-client/src/query/graph/check.graphql create mode 100644 crates/rover-client/src/query/graph/check.rs rename crates/rover-client/src/query/{schema => graph}/get.graphql (100%) rename crates/rover-client/src/query/{schema => graph}/get.rs (98%) create mode 100644 crates/rover-client/src/query/graph/mod.rs rename crates/rover-client/src/query/{schema => graph}/push.graphql (100%) rename crates/rover-client/src/query/{schema => graph}/push.rs (99%) delete mode 100644 crates/rover-client/src/query/partial/mod.rs delete mode 100644 crates/rover-client/src/query/schema/mod.rs rename crates/rover-client/src/query/{partial => subgraph}/delete.graphql (100%) rename crates/rover-client/src/query/{partial => subgraph}/delete.rs (98%) create mode 100644 crates/rover-client/src/query/subgraph/mod.rs rename crates/rover-client/src/query/{partial => subgraph}/push.graphql (100%) rename crates/rover-client/src/query/{partial => subgraph}/push.rs (95%) create mode 100644 schema.graphql create mode 100644 src/command/graph/check.rs create mode 100644 src/command/subgraph/check.rs create mode 100644 test.graphql diff --git a/Cargo.lock b/Cargo.lock index 395f0f036a..dc62853b5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -48,6 +48,18 @@ version = "1.0.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf8dcb5b4bbaa28653b647d8c77bd4ed40183b48882e130c1f1ffb73de069fd7" +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + [[package]] name = "ascii" version = "0.9.3" @@ -118,6 +130,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "binstall" version = "0.1.0" @@ -137,6 +155,17 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.9.0" @@ -152,7 +181,10 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "473fc6b38233f9af7baa94fb5852dca389e3d95b8e21c8e3719301462c5d9faf" dependencies = [ + "lazy_static", "memchr", + "regex-automata", + "serde", ] [[package]] @@ -277,6 +309,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + [[package]] name = "core-foundation" version = "0.9.1" @@ -310,6 +348,39 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "csv" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d58633299b24b515ac72a3f869f8b91306a3cec616a602843a383acd6f9e97" +dependencies = [ + "bstr", + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +dependencies = [ + "memchr", +] + [[package]] name = "difference" version = "2.0.0" @@ -335,6 +406,17 @@ dependencies = [ "dirs-sys-next", ] +[[package]] +name = "dirs" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" +dependencies = [ + "libc", + "redox_users", + "winapi 0.3.9", +] + [[package]] name = "dirs-sys-next" version = "0.1.1" @@ -790,7 +872,7 @@ version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22dcbf2a4a289528dbef21686354904e1c694ac642610a9bff9e7df730d9ec72" dependencies = [ - "crossbeam-utils", + "crossbeam-utils 0.7.2", "globset", "lazy_static", "log", @@ -1283,6 +1365,20 @@ dependencies = [ "treeline", ] +[[package]] +name = "prettytable-rs" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fd04b170004fa2daccf418a7f8253aaf033c27760b5f225889024cf66d7ac2e" +dependencies = [ + "atty", + "csv", + "encode_unicode", + "lazy_static", + "term", + "unicode-width", +] + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -1380,6 +1476,7 @@ checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ "getrandom", "redox_syscall", + "rust-argon2", ] [[package]] @@ -1425,7 +1522,7 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9eaa17ac5d7b838b7503d118fa16ad88f440498bf9ffe5424e621f93190d61e" dependencies = [ - "base64", + "base64 0.12.3", "bytes", "encoding_rs", "futures-core", @@ -1480,6 +1577,7 @@ dependencies = [ "console", "houston", "predicates", + "prettytable-rs", "robot-panic", "rover-client", "serde", @@ -1503,6 +1601,19 @@ dependencies = [ "serde", "serde_json", "thiserror", + "tracing", +] + +[[package]] +name = "rust-argon2" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" +dependencies = [ + "base64 0.13.0", + "blake2b_simd", + "constant_time_eq", + "crossbeam-utils 0.8.1", ] [[package]] @@ -1810,6 +1921,17 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "term" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" +dependencies = [ + "byteorder", + "dirs", + "winapi 0.3.9", +] + [[package]] name = "termcolor" version = "1.1.2" diff --git a/Cargo.toml b/Cargo.toml index a34bc56fd7..d34096d069 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,11 +19,12 @@ binstall = { path = "./installers/binstall" } anyhow = "1.0.31" atty = "0.2.14" console = "0.13.0" +prettytable-rs = "0.8.0" serde = "1.0" serde_json = "1.0" structopt = "0.3.15" -url = "2.1.1" tracing = "0.1.21" +url = "2.1.1" [dev-dependencies] assert_cmd = "1.0.1" diff --git a/crates/rover-client/Cargo.toml b/crates/rover-client/Cargo.toml index a2039a6ab8..4eeac50ff8 100644 --- a/crates/rover-client/Cargo.toml +++ b/crates/rover-client/Cargo.toml @@ -11,5 +11,6 @@ graphql_client = "0.9" http = "0.2" reqwest = { version = "0.10", features = ["json", "blocking", "native-tls-vendored"] } thiserror = "1.0" +tracing = "0.1" serde = "1" serde_json = "1.0.57" diff --git a/crates/rover-client/src/blocking/client.rs b/crates/rover-client/src/blocking/client.rs index d6c9c62078..1c8188b514 100644 --- a/crates/rover-client/src/blocking/client.rs +++ b/crates/rover-client/src/blocking/client.rs @@ -46,12 +46,7 @@ impl Client { pub fn handle_response( response: reqwest::blocking::Response, ) -> Result { - let response_body: graphql_client::Response = - response - .json() - .map_err(|_| RoverClientError::HandleResponse { - msg: String::from("failed to parse response JSON"), - })?; + let response_body: graphql_client::Response = response.json()?; if let Some(errs) = response_body.errors { return Err(RoverClientError::GraphQL { diff --git a/crates/rover-client/src/error.rs b/crates/rover-client/src/error.rs index abda79ae17..5c1f37297d 100644 --- a/crates/rover-client/src/error.rs +++ b/crates/rover-client/src/error.rs @@ -15,6 +15,10 @@ pub enum RoverClientError { #[error("invalid header value")] InvalidHeaderValue(#[from] reqwest::header::InvalidHeaderValue), + /// Invalid JSON in response body. + #[error("could not parse JSON")] + InvalidJSON(#[from] serde_json::Error), + /// Encountered an error handling the received response. #[error("encountered an error handling the response: {msg}")] HandleResponse { @@ -32,9 +36,13 @@ pub enum RoverClientError { #[error("The response from the server was malformed. There was no data found in the reponse body. This is likely an error in GraphQL execution")] NoData, - /// when someone provides a bad service/variant combingation or isn't + /// when someone provides a bad service/variant combination or isn't /// validated properly, we don't know which reason is at fault for data.service /// being empty, so this error tells them to check both. #[error("No service found. Either the service/variant combination wasn't found or your API key is invalid.")] NoService, + + /// The API returned an invalid ChangeSeverity value + #[error("Invalid ChangeSeverity.")] + InvalidSeverity, } diff --git a/crates/rover-client/src/query/graph/check.graphql b/crates/rover-client/src/query/graph/check.graphql new file mode 100644 index 0000000000..6e56284593 --- /dev/null +++ b/crates/rover-client/src/query/graph/check.graphql @@ -0,0 +1,35 @@ +mutation CheckSchemaQuery( + $graphId: ID! + $variant: String + $schema: String + ) { + service(id: $graphId) { + checkSchema( + proposedSchemaDocument: $schema + baseSchemaTag: $variant + ) { + targetUrl + diffToPrevious { + severity + affectedClients { + __typename + } + affectedQueries { + __typename + } + numberOfCheckedOperations + changes { + severity + code + description + } + validationConfig { + from + to + queryCountThreshold + queryCountThresholdPercentage + } + } + } + } + } \ No newline at end of file diff --git a/crates/rover-client/src/query/graph/check.rs b/crates/rover-client/src/query/graph/check.rs new file mode 100644 index 0000000000..4e25acef99 --- /dev/null +++ b/crates/rover-client/src/query/graph/check.rs @@ -0,0 +1,76 @@ +use crate::blocking::StudioClient; +use crate::RoverClientError; +use graphql_client::*; + +use reqwest::Url; + +type Timestamp = String; + +#[derive(GraphQLQuery)] +// The paths are relative to the directory where your `Cargo.toml` is located. +// Both json and the GraphQL schema language are supported as sources for the schema +#[graphql( + query_path = "src/query/graph/check.graphql", + schema_path = "schema.graphql", + response_derives = "PartialEq, Debug, Serialize, Deserialize", + deprecated = "warn" +)] +/// This struct is used to generate the module containing `Variables` and +/// `ResponseData` structs. +/// Snake case of this name is the mod name. i.e. check_schema_query +pub struct CheckSchemaQuery; + +/// The main function to be used from this module. +/// This function takes a proposed schema and validates it against a pushed +/// schema. +pub fn run( + variables: check_schema_query::Variables, + client: &StudioClient, +) -> Result { + let data = client.post::(variables)?; + get_check_response_from_data(data) +} + +#[derive(Debug)] +pub struct CheckResponse { + pub target_url: Option, + pub number_of_checked_operations: i64, + pub change_severity: check_schema_query::ChangeSeverity, + pub changes: Vec, +} + +fn get_check_response_from_data( + data: check_schema_query::ResponseData, +) -> Result { + tracing::debug!("{:#?}", &data); + let service = data.service.ok_or(RoverClientError::NoService)?; + let target_url = get_url(service.check_schema.target_url); + + let diff_to_previous = service.check_schema.diff_to_previous; + + let number_of_checked_operations = diff_to_previous.number_of_checked_operations.unwrap_or(0); + + let change_severity = diff_to_previous.severity; + let changes = diff_to_previous.changes; + + Ok(CheckResponse { + target_url, + number_of_checked_operations, + change_severity, + changes, + }) +} + +fn get_url(url: Option) -> Option { + match url { + Some(url) => { + let url = Url::parse(&url); + match url { + Ok(url) => Some(url), + // if the API returns an invalid URL, don't put it in the response + Err(_) => None, + } + } + None => None, + } +} diff --git a/crates/rover-client/src/query/schema/get.graphql b/crates/rover-client/src/query/graph/get.graphql similarity index 100% rename from crates/rover-client/src/query/schema/get.graphql rename to crates/rover-client/src/query/graph/get.graphql diff --git a/crates/rover-client/src/query/schema/get.rs b/crates/rover-client/src/query/graph/get.rs similarity index 98% rename from crates/rover-client/src/query/schema/get.rs rename to crates/rover-client/src/query/graph/get.rs index f2dd9e8003..c110381cb1 100644 --- a/crates/rover-client/src/query/schema/get.rs +++ b/crates/rover-client/src/query/graph/get.rs @@ -10,7 +10,7 @@ type GraphQLDocument = String; // The paths are relative to the directory where your `Cargo.toml` is located. // Both json and the GraphQL schema language are supported as sources for the schema #[graphql( - query_path = "src/query/schema/get.graphql", + query_path = "src/query/graph/get.graphql", schema_path = "schema.graphql", response_derives = "PartialEq, Debug, Serialize, Deserialize", deprecated = "warn" diff --git a/crates/rover-client/src/query/graph/mod.rs b/crates/rover-client/src/query/graph/mod.rs new file mode 100644 index 0000000000..683621208c --- /dev/null +++ b/crates/rover-client/src/query/graph/mod.rs @@ -0,0 +1,8 @@ +/// "graph get" command execution +pub mod get; + +/// "graph push" command execution +pub mod push; + +/// "graph check" command exeuction +pub mod check; diff --git a/crates/rover-client/src/query/schema/push.graphql b/crates/rover-client/src/query/graph/push.graphql similarity index 100% rename from crates/rover-client/src/query/schema/push.graphql rename to crates/rover-client/src/query/graph/push.graphql diff --git a/crates/rover-client/src/query/schema/push.rs b/crates/rover-client/src/query/graph/push.rs similarity index 99% rename from crates/rover-client/src/query/schema/push.rs rename to crates/rover-client/src/query/graph/push.rs index 386e7f1bfa..1e37865db3 100644 --- a/crates/rover-client/src/query/schema/push.rs +++ b/crates/rover-client/src/query/graph/push.rs @@ -6,7 +6,7 @@ use graphql_client::*; // The paths are relative to the directory where your `Cargo.toml` is located. // Both json and the GraphQL schema language are supported as sources for the schema #[graphql( - query_path = "src/query/schema/push.graphql", + query_path = "src/query/graph/push.graphql", schema_path = "schema.graphql", response_derives = "PartialEq, Debug, Serialize, Deserialize", deprecated = "warn" diff --git a/crates/rover-client/src/query/mod.rs b/crates/rover-client/src/query/mod.rs index c156828984..c085c42bb0 100644 --- a/crates/rover-client/src/query/mod.rs +++ b/crates/rover-client/src/query/mod.rs @@ -1,5 +1,5 @@ -/// all rover-client functionality for the "schema" commands in rover -pub mod schema; +/// all rover-client functionality for the "graph" commands in rover +pub mod graph; -/// all rover-client functionality for the "partial" commands in rover -pub mod partial; +/// all rover-client functionality for the "subgraph" commands in rover +pub mod subgraph; diff --git a/crates/rover-client/src/query/partial/mod.rs b/crates/rover-client/src/query/partial/mod.rs deleted file mode 100644 index 5290ab6257..0000000000 --- a/crates/rover-client/src/query/partial/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -/// "partial push" command execution -pub mod push; - -/// "partial delete" command execution -pub mod delete; diff --git a/crates/rover-client/src/query/schema/mod.rs b/crates/rover-client/src/query/schema/mod.rs deleted file mode 100644 index d4c5419be9..0000000000 --- a/crates/rover-client/src/query/schema/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -/// "schema get" command execution -pub mod get; - -/// "schema push" command execution -pub mod push; diff --git a/crates/rover-client/src/query/partial/delete.graphql b/crates/rover-client/src/query/subgraph/delete.graphql similarity index 100% rename from crates/rover-client/src/query/partial/delete.graphql rename to crates/rover-client/src/query/subgraph/delete.graphql diff --git a/crates/rover-client/src/query/partial/delete.rs b/crates/rover-client/src/query/subgraph/delete.rs similarity index 98% rename from crates/rover-client/src/query/partial/delete.rs rename to crates/rover-client/src/query/subgraph/delete.rs index 6eeae3ab29..03511aaa3a 100644 --- a/crates/rover-client/src/query/partial/delete.rs +++ b/crates/rover-client/src/query/subgraph/delete.rs @@ -6,7 +6,7 @@ use graphql_client::*; // The paths are relative to the directory where your `Cargo.toml` is located. // Both json and the GraphQL schema language are supported as sources for the schema #[graphql( - query_path = "src/query/partial/delete.graphql", + query_path = "src/query/subgraph/delete.graphql", schema_path = "schema.graphql", response_derives = "PartialEq, Debug, Serialize, Deserialize", deprecated = "warn" diff --git a/crates/rover-client/src/query/subgraph/mod.rs b/crates/rover-client/src/query/subgraph/mod.rs new file mode 100644 index 0000000000..c941580cb4 --- /dev/null +++ b/crates/rover-client/src/query/subgraph/mod.rs @@ -0,0 +1,5 @@ +/// "subgraph push" command execution +pub mod push; + +/// "subgraph delete" command execution +pub mod delete; diff --git a/crates/rover-client/src/query/partial/push.graphql b/crates/rover-client/src/query/subgraph/push.graphql similarity index 100% rename from crates/rover-client/src/query/partial/push.graphql rename to crates/rover-client/src/query/subgraph/push.graphql diff --git a/crates/rover-client/src/query/partial/push.rs b/crates/rover-client/src/query/subgraph/push.rs similarity index 95% rename from crates/rover-client/src/query/partial/push.rs rename to crates/rover-client/src/query/subgraph/push.rs index f57cc143f5..aa1d5088e0 100644 --- a/crates/rover-client/src/query/partial/push.rs +++ b/crates/rover-client/src/query/subgraph/push.rs @@ -7,7 +7,7 @@ use graphql_client::*; // The paths are relative to the directory where your `Cargo.toml` is located. // Both json and the GraphQL schema language are supported as sources for the schema #[graphql( - query_path = "src/query/partial/push.graphql", + query_path = "src/query/subgraph/push.graphql", schema_path = "schema.graphql", response_derives = "PartialEq, Debug, Serialize, Deserialize", deprecated = "warn" @@ -31,7 +31,7 @@ pub fn run( ) -> Result { let data = client.post::(variables)?; let push_response = get_push_response_from_data(data)?; - build_response(push_response) + Ok(build_response(push_response)) } // alias this return type since it's disgusting @@ -48,9 +48,7 @@ fn get_push_response_from_data( Ok(service_data.upsert_implementing_service_and_trigger_composition) } -fn build_response( - push_response: UpdateResponse, -) -> Result { +fn build_response(push_response: UpdateResponse) -> PushPartialSchemaResponse { let composition_errors: Vec = push_response .errors .iter() @@ -67,7 +65,7 @@ fn build_response( None }; - Ok(PushPartialSchemaResponse { + PushPartialSchemaResponse { schema_hash: match push_response.composition_config { Some(config) => Some(config.schema_hash), None => None, @@ -75,7 +73,7 @@ fn build_response( did_update_gateway: push_response.did_update_gateway, service_was_created: push_response.service_was_created, composition_errors, - }) + } } #[cfg(test)] diff --git a/schema.graphql b/schema.graphql new file mode 100644 index 0000000000..355d5884a7 --- /dev/null +++ b/schema.graphql @@ -0,0 +1,8602 @@ +schema + @graph(name: "featureflags", url: "undefined") + @graph(name: "registry", url: "undefined") + @graph(name: "kotlin", url: "undefined") + @composedGraph(version: 1) +{ + query: Query + mutation: Mutation +} + +directive @composedGraph(version: Int!) on SCHEMA + +directive @graph(name: String!, url: String!) repeatable on SCHEMA + +directive @owner(graph: String!) on OBJECT + +directive @key(fields: String!, graph: String!) repeatable on OBJECT + +directive @resolve(graph: String!) on FIELD_DEFINITION + +directive @provides(fields: String!) on FIELD_DEFINITION + +directive @requires(fields: String!) on FIELD_DEFINITION + +type Account + @owner(graph: "kotlin") + @key(fields: "{ id }", graph: "kotlin") + @key(fields: "{ id }", graph: "featureflags") +{ + """ + Get an URL to which an avatar image can be uploaded. Client uploads by sending a PUT request + with the image data to MediaUploadInfo.url. Client SHOULD set the "Content-Type" header to the + browser-inferred MIME type, and SHOULD set the "x-apollo-content-filename" header to the + filename, if such information is available. Client MUST set the "x-apollo-csrf-token" header to + MediaUploadInfo.csrfToken. + """ + avatarUpload: AvatarUploadResult + + """ + Get an image URL for the account's avatar. Note that CORS is not enabled for these URLs. The size + argument is used for bandwidth reduction, and should be the size of the image as displayed in the + application. Apollo's media server will downscale larger images to at least the requested size, + but this will not happen for third-party media servers. + """ + avatarUrl(size: Int! = 40): String + billingInfo: BillingInfo + currentBillingMonth: BillingMonth + currentPlan: BillingPlan! + currentSubscription: BillingSubscription + defaultPermission: UserPermission @deprecated(reason: "Replaced with Account.inviteLink.role and Account.sso.defaultRole") + expiredTrialSubscription: BillingSubscription + hasBeenOnTrial: Boolean! + id: ID! + + """ + Internal immutable identifier for the account. Only visible to Apollo admins (because it really + shouldn't be used in normal client apps). + """ + internalID: ID! + invitations(includeAccepted: Boolean! = false): [AccountInvitation!] + + """A reusable invitation link for the organization.""" + inviteLink: OrganizationInviteLink + invoices: [Invoice!] + isOnTrial: Boolean! + + """ + Token allowing to join the account using mutation{join(accountId:,token:)}} + """ + joinToken: String @deprecated(reason: "Replaced with Account.inviteLink.joinToken") + memberships: [AccountMembership!] + name: String! + provisionedAt: Timestamp + recurlyEmail: String + requests(from: Timestamp!, to: Timestamp!): Long + requestsInCurrentBillingPeriod: Long + roles: AccountRoles + + """ + How many seats would be included in your next bill, as best estimated today + """ + seatCountForNextBill: Int + seats: Seats + secondaryIDs: [ID!]! + services(includeDeleted: Boolean): [Service!]! + + """ + If non-null, this organization tracks its members through an upstream, eg PingOne; + invitations are not possible on SSO-synchronized account. + """ + sso: OrganizationSSO + state: AccountState + stats( + from: Timestamp! + + """ + Granularity of buckets. Defaults to the entire range (aggregate all data into a single durationBucket) when null. + """ + resolution: Resolution + + """Defaults to the current time when null.""" + to: Timestamp + ): AccountStatsWindow! + subscriptions: [BillingSubscription!] + synchronized: Boolean! @deprecated(reason: "Replaced with Account.sso") + users: [User!]! @deprecated(reason: "Replaced with Account.memberships.user") + experimentalFeatures: AccountExperimentalFeatures! @resolve(graph: "featureflags") @requires(fields: "{ internalID }") +} + +"""Columns of AccountEdgeServerInfos.""" +enum AccountEdgeServerInfosColumn { + BOOT_ID + EXECUTABLE_SCHEMA_ID + LIBRARY_VERSION + PLATFORM + RUNTIME_VERSION + SCHEMA_TAG + SERVER_ID + SERVICE_ID + TIMESTAMP + USER_VERSION +} + +type AccountEdgeServerInfosDimensions { + bootId: ID + executableSchemaId: ID + libraryVersion: String + platform: String + runtimeVersion: String + schemaTag: String + serverId: ID + serviceId: ID + userVersion: String +} + +""" +Filter for data in AccountEdgeServerInfos. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input AccountEdgeServerInfosFilter { + and: [AccountEdgeServerInfosFilter!] + + """ + Selects rows whose bootId dimension equals the given value if not null. To + query for the null value, use {in: {bootId: [null]}} instead. + """ + bootId: ID + + """ + Selects rows whose executableSchemaId dimension equals the given value if not + null. To query for the null value, use {in: {executableSchemaId: [null]}} instead. + """ + executableSchemaId: ID + in: AccountEdgeServerInfosFilterIn + + """ + Selects rows whose libraryVersion dimension equals the given value if not + null. To query for the null value, use {in: {libraryVersion: [null]}} instead. + """ + libraryVersion: String + not: AccountEdgeServerInfosFilter + or: [AccountEdgeServerInfosFilter!] + + """ + Selects rows whose platform dimension equals the given value if not null. To + query for the null value, use {in: {platform: [null]}} instead. + """ + platform: String + + """ + Selects rows whose runtimeVersion dimension equals the given value if not + null. To query for the null value, use {in: {runtimeVersion: [null]}} instead. + """ + runtimeVersion: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serverId dimension equals the given value if not null. To + query for the null value, use {in: {serverId: [null]}} instead. + """ + serverId: ID + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose userVersion dimension equals the given value if not null. + To query for the null value, use {in: {userVersion: [null]}} instead. + """ + userVersion: String +} + +""" +Filter for data in AccountEdgeServerInfos. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountEdgeServerInfosFilterIn { + """ + Selects rows whose bootId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + bootId: [ID] + + """ + Selects rows whose executableSchemaId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + executableSchemaId: [ID] + + """ + Selects rows whose libraryVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + libraryVersion: [String] + + """ + Selects rows whose platform dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + platform: [String] + + """ + Selects rows whose runtimeVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + runtimeVersion: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serverId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serverId: [ID] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose userVersion dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + userVersion: [String] +} + +input AccountEdgeServerInfosOrderBySpec { + column: AccountEdgeServerInfosColumn! + direction: Ordering! +} + +type AccountEdgeServerInfosRecord { + """Dimensions of AccountEdgeServerInfos that can be grouped by.""" + groupBy: AccountEdgeServerInfosDimensions! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of AccountEnumStats.""" +enum AccountEnumStatsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ENUM_TYPE + ENUM_VALUE + QUERY_ID + QUERY_NAME + REQUEST_COUNT + RESPONSE_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP +} + +type AccountEnumStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + enumType: String + enumValue: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in AccountEnumStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input AccountEnumStatsFilter { + and: [AccountEnumStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose enumType dimension equals the given value if not null. To + query for the null value, use {in: {enumType: [null]}} instead. + """ + enumType: String + + """ + Selects rows whose enumValue dimension equals the given value if not null. To + query for the null value, use {in: {enumValue: [null]}} instead. + """ + enumValue: String + in: AccountEnumStatsFilterIn + not: AccountEnumStatsFilter + or: [AccountEnumStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in AccountEnumStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountEnumStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose enumType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + enumType: [String] + + """ + Selects rows whose enumValue dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + enumValue: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type AccountEnumStatsMetrics { + requestCount: Long! + responseCount: Long! +} + +input AccountEnumStatsOrderBySpec { + column: AccountEnumStatsColumn! + direction: Ordering! +} + +type AccountEnumStatsRecord { + """Dimensions of AccountEnumStats that can be grouped by.""" + groupBy: AccountEnumStatsDimensions! + + """Metrics of AccountEnumStats that can be aggregated over.""" + metrics: AccountEnumStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of AccountErrorStats.""" +enum AccountErrorStatsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ERRORS_COUNT + PATH + QUERY_ID + QUERY_NAME + REQUESTS_WITH_ERRORS_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP +} + +type AccountErrorStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + path: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in AccountErrorStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input AccountErrorStatsFilter { + and: [AccountErrorStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + in: AccountErrorStatsFilterIn + not: AccountErrorStatsFilter + or: [AccountErrorStatsFilter!] + + """ + Selects rows whose path dimension equals the given value if not null. To query + for the null value, use {in: {path: [null]}} instead. + """ + path: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in AccountErrorStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountErrorStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose path dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + path: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type AccountErrorStatsMetrics { + errorsCount: Long! + requestsWithErrorsCount: Long! +} + +input AccountErrorStatsOrderBySpec { + column: AccountErrorStatsColumn! + direction: Ordering! +} + +type AccountErrorStatsRecord { + """Dimensions of AccountErrorStats that can be grouped by.""" + groupBy: AccountErrorStatsDimensions! + + """Metrics of AccountErrorStats that can be aggregated over.""" + metrics: AccountErrorStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +type AccountExperimentalFeatures { + preRequestPreview: Boolean! +} + +"""Columns of AccountFieldStats.""" +enum AccountFieldStatsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ERRORS_COUNT + FIELD + FIELD_HISTOGRAM + QUERY_ID + QUERY_NAME + REQUEST_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP +} + +type AccountFieldStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + field: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in AccountFieldStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input AccountFieldStatsFilter { + and: [AccountFieldStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose field dimension equals the given value if not null. To + query for the null value, use {in: {field: [null]}} instead. + """ + field: String + in: AccountFieldStatsFilterIn + not: AccountFieldStatsFilter + or: [AccountFieldStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in AccountFieldStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountFieldStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose field dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + field: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type AccountFieldStatsMetrics { + errorsCount: Long! + fieldHistogram: DurationHistogram! + requestCount: Long! +} + +input AccountFieldStatsOrderBySpec { + column: AccountFieldStatsColumn! + direction: Ordering! +} + +type AccountFieldStatsRecord { + """Dimensions of AccountFieldStats that can be grouped by.""" + groupBy: AccountFieldStatsDimensions! + + """Metrics of AccountFieldStats that can be aggregated over.""" + metrics: AccountFieldStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of AccountInputStats.""" +enum AccountInputStatsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + FIELD_NAME + FIELD_TYPE + PARENT_TYPE + QUERY_ID + QUERY_NAME + REQUEST_COUNT + REQUEST_COUNT_NULL + REQUEST_COUNT_UNDEFINED + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP +} + +type AccountInputStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + fieldName: String + fieldType: String + parentType: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in AccountInputStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input AccountInputStatsFilter { + and: [AccountInputStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose fieldName dimension equals the given value if not null. To + query for the null value, use {in: {fieldName: [null]}} instead. + """ + fieldName: String + + """ + Selects rows whose fieldType dimension equals the given value if not null. To + query for the null value, use {in: {fieldType: [null]}} instead. + """ + fieldType: String + in: AccountInputStatsFilterIn + not: AccountInputStatsFilter + or: [AccountInputStatsFilter!] + + """ + Selects rows whose parentType dimension equals the given value if not null. To + query for the null value, use {in: {parentType: [null]}} instead. + """ + parentType: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in AccountInputStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountInputStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose fieldName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + fieldName: [String] + + """ + Selects rows whose fieldType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + fieldType: [String] + + """ + Selects rows whose parentType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + parentType: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type AccountInputStatsMetrics { + requestCount: Long! + requestCountNull: Long! + requestCountUndefined: Long! +} + +input AccountInputStatsOrderBySpec { + column: AccountInputStatsColumn! + direction: Ordering! +} + +type AccountInputStatsRecord { + """Dimensions of AccountInputStats that can be grouped by.""" + groupBy: AccountInputStatsDimensions! + + """Metrics of AccountInputStats that can be aggregated over.""" + metrics: AccountInputStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +type AccountInvitation { + """An accepted invitation cannot be used anymore""" + acceptedAt: Timestamp + + """Who accepted the invitation""" + acceptedBy: User + + """Time the invitation was created""" + createdAt: Timestamp! + + """Who created the invitation""" + createdBy: User + email: String! + id: ID! + + """Last time we sent an email for the invitation""" + lastSentAt: Timestamp + + """Access role for the invitee""" + role: UserPermission! +} + +type AccountMembership { + createdAt: Timestamp! + permission: UserPermission! + user: User! +} + +type AccountMutation { + """ + Changes an annual team subscription to a monthly team subscription when the current period expires. + (For monthly->annual changes, just use startTeamSubscription and the annual subscription will start + immediately; annual->monthly is special because monthly subscriptions all renew at the start of the month.) + """ + convertAnnualTeamSubscriptionToMonthlyAtNextPeriod: Account + + """ + Delete the account's avatar. Requires Account.canUpdateAvatar to be true. + """ + deleteAvatar: AvatarDeleteError + + """Acknowledge that a trial has expired and return to community""" + dismissExpiredTrial: Account + + """Apollo admins only: extend an ongoing trial""" + extendTrial(to: Timestamp!): Account + + """Hard delete an account and all associated services""" + hardDelete: Void + + """Send an invitation to join the account by E-mail""" + invite(email: String!, role: UserPermission): AccountInvitation + + """Refresh billing information from third-party billing service""" + refreshBilling: Void + + """Set the account-wide invitation token to a new random value""" + regenerateJoinToken: Account + + """Delete an invitation""" + removeInvitation(id: ID): Void + + """Remove a member of the account""" + removeMember(id: ID!): Account + + """Send a new E-mail for an existing invitation""" + resendInvitation(id: ID): AccountInvitation + + """Disable the account-wide join token""" + revokeJoinToken: Account + + """Apollo admins only: set the billing plan to an arbitrary plan""" + setPlan(id: ID!): Void + + """Start a new team subscription with the given billing period""" + startTeamSubscription(billingPeriod: BillingPeriod!): Account + + """Start a team trial""" + startTrial: Account + + """ + Apollo admins only: terminate any ongoing subscriptions in the account, without refunds + """ + terminateSubscriptions: Account + + """Update the billing address for a Recurly token""" + updateBillingAddress(billingAddress: BillingAddressInput!): Account + + """Update the billing information from a Recurly token""" + updateBillingInfo(token: String!): Void + + """Set the E-mail address of the account, used notably for billing""" + updateEmail(email: String!): Void + + """Update the account ID""" + updateID(id: ID!): Account + + """ + Updates the role used by the org's invite link and regenerates the join token. + """ + updateInviteLinkRole(role: UserPermission!): OrganizationInviteLink + + """Update the company name""" + updateName(name: String!): Void + + """Apollo admins only: enable or disable an account for PingOne SSO login""" + updatePingOneSSOIDPID(idpid: String): Account + + """Set the E-mail address in Recurly""" + updateRecurlyEmail(email: String!): Void @deprecated(reason: "Replaced with updateEmail") + + """Updates the role assigned to new SSO users.""" + updateSSODefaultRole(role: UserPermission!): OrganizationSSO + + """ + A (currently) internal to Apollo mutation to update a user's role within an organization + """ + updateUserPermission(permission: UserPermission!, userID: ID!): User +} + +"""Columns of AccountQueryStats.""" +enum AccountQueryStatsColumn { + CACHED_HISTOGRAM + CACHED_REQUESTS_COUNT + CACHE_TTL_HISTOGRAM + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + FORBIDDEN_OPERATION_COUNT + FROM_ENGINEPROXY + QUERY_ID + QUERY_NAME + REGISTERED_OPERATION_COUNT + REQUESTS_WITH_ERRORS_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP + UNCACHED_HISTOGRAM + UNCACHED_REQUESTS_COUNT +} + +type AccountQueryStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + fromEngineproxy: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in AccountQueryStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input AccountQueryStatsFilter { + and: [AccountQueryStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose fromEngineproxy dimension equals the given value if not + null. To query for the null value, use {in: {fromEngineproxy: [null]}} instead. + """ + fromEngineproxy: String + in: AccountQueryStatsFilterIn + not: AccountQueryStatsFilter + or: [AccountQueryStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in AccountQueryStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountQueryStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose fromEngineproxy dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + fromEngineproxy: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type AccountQueryStatsMetrics { + cacheTtlHistogram: DurationHistogram! + cachedHistogram: DurationHistogram! + cachedRequestsCount: Long! + forbiddenOperationCount: Long! + registeredOperationCount: Long! + requestsWithErrorsCount: Long! + totalLatencyHistogram: DurationHistogram! + totalRequestCount: Long! + uncachedHistogram: DurationHistogram! + uncachedRequestsCount: Long! +} + +input AccountQueryStatsOrderBySpec { + column: AccountQueryStatsColumn! + direction: Ordering! +} + +type AccountQueryStatsRecord { + """Dimensions of AccountQueryStats that can be grouped by.""" + groupBy: AccountQueryStatsDimensions! + + """Metrics of AccountQueryStats that can be aggregated over.""" + metrics: AccountQueryStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +type AccountRoles { + canAdminister: Boolean! @deprecated(reason: "Use canManageMembers instead") + canCreateDevGraph: Boolean! + canCreateService: Boolean! + canDelete: Boolean! + canDownloadInvoice: Boolean! @deprecated(reason: "Use canQueryBillingInfo instead") + canManageMembers: Boolean! + canModify: Boolean! @deprecated(reason: "Use canQuery instead") + canQuery: Boolean! + canQueryBillingInfo: Boolean! + canQueryInvoices: Boolean! @deprecated(reason: "Use canQueryBillingInfo instead") + canQueryJoinToken: Boolean! @deprecated(reason: "Use canManageMembers instead") + canQueryMembers: Boolean! + canQueryRecurlyInfo: Boolean! @deprecated(reason: "Use canQueryBillingInfo instead") + canRemoveMembers: Boolean! + canSetConstrainedPlan: Boolean! + canUpdateAvatar: Boolean! @deprecated(reason: "Use canUpdateMetadata instead") + canUpdateBillingInfo: Boolean! + canUpdateID: Boolean! @deprecated(reason: "Use canUpdateMetadata instead") + canUpdateMetadata: Boolean! +} + +enum AccountState { + ACTIVE + CLOSED + UNKNOWN + UNPROVISIONED +} + +"""A time window with a specified granularity over a given account.""" +type AccountStatsWindow { + edgeServerInfos( + """Filter to select what rows to return.""" + filter: AccountEdgeServerInfosFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order AccountEdgeServerInfos by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [AccountEdgeServerInfosOrderBySpec!] + ): [AccountEdgeServerInfosRecord!]! + enumStats( + """Filter to select what rows to return.""" + filter: AccountEnumStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order AccountEnumStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [AccountEnumStatsOrderBySpec!] + ): [AccountEnumStatsRecord!]! + errorStats( + """Filter to select what rows to return.""" + filter: AccountErrorStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order AccountErrorStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [AccountErrorStatsOrderBySpec!] + ): [AccountErrorStatsRecord!]! + fieldStats( + """Filter to select what rows to return.""" + filter: AccountFieldStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order AccountFieldStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [AccountFieldStatsOrderBySpec!] + ): [AccountFieldStatsRecord!]! + inputStats( + """Filter to select what rows to return.""" + filter: AccountInputStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order AccountInputStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [AccountInputStatsOrderBySpec!] + ): [AccountInputStatsRecord!]! + queryStats( + """Filter to select what rows to return.""" + filter: AccountQueryStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order AccountQueryStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [AccountQueryStatsOrderBySpec!] + ): [AccountQueryStatsRecord!]! + + """From field rounded down to the nearest resolution.""" + roundedDownFrom: Timestamp! + + """To field rounded up to the nearest resolution.""" + roundedUpTo: Timestamp! + tracePathErrorsRefs( + """Filter to select what rows to return.""" + filter: AccountTracePathErrorsRefsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order AccountTracePathErrorsRefs by. The earlier + an OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [AccountTracePathErrorsRefsOrderBySpec!] + ): [AccountTracePathErrorsRefsRecord!]! + traceRefs( + """Filter to select what rows to return.""" + filter: AccountTraceRefsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order AccountTraceRefs by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [AccountTraceRefsOrderBySpec!] + ): [AccountTraceRefsRecord!]! +} + +"""Columns of AccountTracePathErrorsRefs.""" +enum AccountTracePathErrorsRefsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + DURATION_BUCKET + ERRORS_COUNT_IN_PATH + ERRORS_COUNT_IN_TRACE + ERROR_MESSAGE + PATH + QUERY_ID + QUERY_NAME + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP + TRACE_HTTP_STATUS_CODE + TRACE_ID + TRACE_SIZE_BYTES + TRACE_STARTS_AT +} + +type AccountTracePathErrorsRefsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + durationBucket: Int + errorMessage: String + path: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String + traceHttpStatusCode: Int + traceId: ID + traceStartsAt: Timestamp +} + +""" +Filter for data in AccountTracePathErrorsRefs. Fields with dimension names +represent equality checks. All fields are implicitly ANDed together. +""" +input AccountTracePathErrorsRefsFilter { + and: [AccountTracePathErrorsRefsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose durationBucket dimension equals the given value if not + null. To query for the null value, use {in: {durationBucket: [null]}} instead. + """ + durationBucket: Int + + """ + Selects rows whose errorMessage dimension equals the given value if not null. + To query for the null value, use {in: {errorMessage: [null]}} instead. + """ + errorMessage: String + in: AccountTracePathErrorsRefsFilterIn + not: AccountTracePathErrorsRefsFilter + or: [AccountTracePathErrorsRefsFilter!] + + """ + Selects rows whose path dimension equals the given value if not null. To query + for the null value, use {in: {path: [null]}} instead. + """ + path: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String + + """ + Selects rows whose traceHttpStatusCode dimension equals the given value if not + null. To query for the null value, use {in: {traceHttpStatusCode: [null]}} instead. + """ + traceHttpStatusCode: Int + + """ + Selects rows whose traceId dimension equals the given value if not null. To + query for the null value, use {in: {traceId: [null]}} instead. + """ + traceId: ID +} + +""" +Filter for data in AccountTracePathErrorsRefs. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountTracePathErrorsRefsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose durationBucket dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + durationBucket: [Int] + + """ + Selects rows whose errorMessage dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + errorMessage: [String] + + """ + Selects rows whose path dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + path: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] + + """ + Selects rows whose traceHttpStatusCode dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + traceHttpStatusCode: [Int] + + """ + Selects rows whose traceId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + traceId: [ID] +} + +type AccountTracePathErrorsRefsMetrics { + errorsCountInPath: Long! + errorsCountInTrace: Long! + traceSizeBytes: Long! +} + +input AccountTracePathErrorsRefsOrderBySpec { + column: AccountTracePathErrorsRefsColumn! + direction: Ordering! +} + +type AccountTracePathErrorsRefsRecord { + """Dimensions of AccountTracePathErrorsRefs that can be grouped by.""" + groupBy: AccountTracePathErrorsRefsDimensions! + + """Metrics of AccountTracePathErrorsRefs that can be aggregated over.""" + metrics: AccountTracePathErrorsRefsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of AccountTraceRefs.""" +enum AccountTraceRefsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + DURATION_BUCKET + DURATION_NS + QUERY_ID + QUERY_NAME + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP + TRACE_ID + TRACE_SIZE_BYTES +} + +type AccountTraceRefsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + durationBucket: Int + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String + traceId: ID +} + +""" +Filter for data in AccountTraceRefs. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input AccountTraceRefsFilter { + and: [AccountTraceRefsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose durationBucket dimension equals the given value if not + null. To query for the null value, use {in: {durationBucket: [null]}} instead. + """ + durationBucket: Int + in: AccountTraceRefsFilterIn + not: AccountTraceRefsFilter + or: [AccountTraceRefsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String + + """ + Selects rows whose traceId dimension equals the given value if not null. To + query for the null value, use {in: {traceId: [null]}} instead. + """ + traceId: ID +} + +""" +Filter for data in AccountTraceRefs. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input AccountTraceRefsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose durationBucket dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + durationBucket: [Int] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] + + """ + Selects rows whose traceId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + traceId: [ID] +} + +type AccountTraceRefsMetrics { + durationNs: Long! + traceSizeBytes: Long! +} + +input AccountTraceRefsOrderBySpec { + column: AccountTraceRefsColumn! + direction: Ordering! +} + +type AccountTraceRefsRecord { + """Dimensions of AccountTraceRefs that can be grouped by.""" + groupBy: AccountTraceRefsDimensions! + + """Metrics of AccountTraceRefs that can be aggregated over.""" + metrics: AccountTraceRefsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +type Actor { + actorId: ID! + type: ActorType! +} + +enum ActorType { + ANONYMOUS_USER + BACKFILL + CRON + GRAPH + INTERNAL_IDENTITY + SYNCHRONIZATION + USER +} + +type AffectedClient { + """ + ID, often the name, of the client set by the user and reported alongside metrics + """ + clientReferenceId: ID + + """version of the client set by the user and reported alongside metrics""" + clientVersion: String +} + +type AffectedQuery { + id: ID! + + """First 128 characters of query signature for display""" + signature: String + name: String + + """Determines if this query validates against the proposed schema""" + isValid: Boolean + + """ + List of changes affecting this query. Returns null if queried from SchemaDiff.changes.affectedQueries.changes + """ + changes: [ChangeOnOperation!] + + """ + Whether this operation was ignored and its severity was downgraded for that reason + """ + markedAsIgnored: Boolean + + """ + Whether the changes were marked as safe and its severity was downgraded for that reason + """ + markedAsSafe: Boolean + + """ + If the operation would be approved if the check ran again. Returns null if + queried from SchemaDiff.changes.affectedQueries.alreadyApproved + """ + alreadyApproved: Boolean + + """If the operation would be ignored if the check ran again""" + alreadyIgnored: Boolean +} + +type ApiKey { + keyName: String + token: String! +} + +type ApiKeyProvision { + apiKey: ApiKey! + created: Boolean! +} + +type AvatarDeleteError { + clientMessage: String! + code: AvatarDeleteErrorCode! + serverMessage: String! +} + +enum AvatarDeleteErrorCode { + SSO_USERS_CANNOT_DELETE_SELF_AVATAR +} + +type AvatarUploadError { + clientMessage: String! + code: AvatarUploadErrorCode! + serverMessage: String! +} + +enum AvatarUploadErrorCode { + SSO_USERS_CANNOT_UPLOAD_SELF_AVATAR +} + +union AvatarUploadResult = AvatarUploadError | MediaUploadInfo + +type BillingAddress { + address1: String + address2: String + city: String + country: String + state: String + zip: String +} + +"""Billing address inpnut""" +input BillingAddressInput { + address1: String! + address2: String + city: String! + country: String! + state: String! + zip: String! +} + +type BillingInfo { + address: BillingAddress! + cardType: String + firstName: String + lastFour: Int + lastName: String + month: Int + year: Int +} + +enum BillingModel { + REQUEST_BASED + SEAT_BASED +} + +type BillingMonth { + end: Timestamp! + requests: Long! + start: Timestamp! +} + +enum BillingPeriod { + MONTHLY + QUARTERLY + YEARLY +} + +type BillingPlan { + addons: [BillingPlanAddon!]! + billingModel: BillingModel! + billingPeriod: BillingPeriod + capabilities: BillingPlanCapabilities! + description: String + id: ID! + isTrial: Boolean! + kind: BillingPlanKind! + name: String! + + """The price of every seat""" + pricePerSeatInUsdCents: Int + + """ + The price of subscribing to this plan with a quantity of 1 (currently always the case) + """ + pricePerUnitInUsdCents: Int! + + """ + Whether the plan is accessible by all users in QueryRoot.allPlans, QueryRoot.plan, or AccountMutation.setPlan + """ + public: Boolean! + tier: BillingPlanTier! +} + +type BillingPlanAddon { + id: ID! + pricePerUnitInUsdCents: Int! +} + +type BillingPlanCapabilities { + clients: Boolean! + datadog: Boolean! + errors: Boolean! + federation: Boolean! + maxRangeInDays: Int + maxRequestsPerMonth: Long + metrics: Boolean! + notifications: Boolean! + operationRegistry: Boolean! + ranges: [String!]! + schemaValidation: Boolean! + traces: Boolean! + userRoles: Boolean! +} + +enum BillingPlanKind { + COMMUNITY + ENTERPRISE_INTERNAL + ENTERPRISE_PAID + ENTERPRISE_PILOT + TEAM_PAID + TEAM_TRIAL +} + +enum BillingPlanTier { + COMMUNITY + ENTERPRISE + TEAM +} + +type BillingSubscription { + activatedAt: Timestamp! + addons: [BillingSubscriptionAddon!]! + autoRenew: Boolean! + + """ + The price of the subscription when ignoring add-ons (such as seats), ie quantity * pricePerUnitInUsdCents + """ + basePriceInUsdCents: Long! + canceledAt: Timestamp + currentPeriodEndsAt: Timestamp! + currentPeriodStartedAt: Timestamp! + expiresAt: Timestamp + plan: BillingPlan! + + """The price of every seat""" + pricePerSeatInUsdCents: Int + + """ + The price of every unit in the subscription (hence multiplied by quantity to get to the basePriceInUsdCents) + """ + pricePerUnitInUsdCents: Int! + quantity: Int! + + """ + Total price of the subscription when it next renews, including add-ons (such as seats) + """ + renewalTotalPriceInUsdCents: Long! + state: SubscriptionState! + + """Total price of the subscription, including add-ons (such as seats)""" + totalPriceInUsdCents: Long! + + """ + When this subscription's trial period expires (if it is a trial). Not the same as the + subscription's Recurly expiration). + """ + trialExpiresAt: Timestamp + uuid: ID! +} + +type BillingSubscriptionAddon { + id: ID! + pricePerUnitInUsdCents: Int! + quantity: Int! +} + +"""A blob (base64'ed in JSON & GraphQL)""" +scalar Blob + +enum CacheScope { + PRIVATE + PUBLIC + UNKNOWN + UNRECOGNIZED +} + +type Change { + """ + Indication of the success of the overall change, either failure, warning, or notice. + """ + type: ChangeType! @deprecated(reason: "use severity instead") + + """ + Indication of the success of the overall change, either failure, warning, or notice. + """ + severity: ChangeSeverity! + + """ + Indication of the kind of target and action of the change, e.g. 'TYPE_REMOVED'. + """ + code: String! + + """ + Indication of the category of the change (e.g. addition, removal, edit). + """ + category: ChangeCategory! + + """Explanation of both the target of the change and how it was changed.""" + description: String! @deprecated(reason: "generate this string from the code, parentNode, childNode, and argNode") + affectedQueries: [AffectedQuery!] + + """Top level node affected by the change""" + parentNode: NamedIntrospectionType + + """ + Node related to the top level node that was changed, such as a field in an object, + a value in an enum or the object of an interface + """ + childNode: NamedIntrospectionValue + + """Target arg of change made.""" + argNode: NamedIntrospectionArg +} + +""" +Defines a set of categories that a schema change +can be grouped by. +""" +enum ChangeCategory { + ADDITION + EDIT + REMOVAL + DEPRECATION +} + +""" +These schema change codes represent all of the possible changes that can +occur during the schema diff algorithm. +""" +enum ChangeCode { + """Field was removed from the type.""" + FIELD_REMOVED + + """Type (object or scalar) was removed from the schema.""" + TYPE_REMOVED + + """Argument to a field was removed.""" + ARG_REMOVED + + """Type is no longer included in the union.""" + TYPE_REMOVED_FROM_UNION + + """Field was removed from the input object.""" + FIELD_REMOVED_FROM_INPUT_OBJECT + + """Value was removed from the enum.""" + VALUE_REMOVED_FROM_ENUM + + """Type no longer implements the interface.""" + TYPE_REMOVED_FROM_INTERFACE + + """Non-nullable argument was added to the field.""" + REQUIRED_ARG_ADDED + + """Non-nullable field was added to the input object.""" + NON_NULLABLE_FIELD_ADDED_TO_INPUT_OBJECT + + """Return type for the field was changed.""" + FIELD_CHANGED_TYPE + + """Type of the field in the input object was changed.""" + FIELD_ON_INPUT_OBJECT_CHANGED_TYPE + + """ + Type was changed from one kind to another. + Ex: scalar to object or enum to union. + """ + TYPE_CHANGED_KIND + + """Type of the argument was changed.""" + ARG_CHANGED_TYPE + + """Argument was changed from nullable to non-nullable.""" + ARG_CHANGED_TYPE_OPTIONAL_TO_REQUIRED + + """A new value was added to the enum.""" + VALUE_ADDED_TO_ENUM + + """A new value was added to the enum.""" + TYPE_ADDED_TO_UNION + + """Type now implements the interface.""" + TYPE_ADDED_TO_INTERFACE + + """Default value added or changed for the argument.""" + ARG_DEFAULT_VALUE_CHANGE + + """Nullable argument was added to the field.""" + OPTIONAL_ARG_ADDED + + """Nullable field was added to the input type.""" + NULLABLE_FIELD_ADDED_TO_INPUT_OBJECT + + """Field was added to the type.""" + FIELD_ADDED + + """Type was added to the schema.""" + TYPE_ADDED + + """Enum was deprecated.""" + ENUM_DEPRECATED + + """Enum deprecation was removed.""" + ENUM_DEPRECATION_REMOVED + + """Reason for enum deprecation changed.""" + ENUM_DEPRECATED_REASON_CHANGE + + """Field was deprecated.""" + FIELD_DEPRECATED + + """Field deprecation removed.""" + FIELD_DEPRECATION_REMOVED + + """Reason for field deprecation changed.""" + FIELD_DEPRECATED_REASON_CHANGE + + """Description was added, removed, or updated for type.""" + TYPE_DESCRIPTION_CHANGE + + """Description was added, removed, or updated for field.""" + FIELD_DESCRIPTION_CHANGE + + """Description was added, removed, or updated for enum value.""" + ENUM_VALUE_DESCRIPTION_CHANGE + + """Description was added, removed, or updated for argument.""" + ARG_DESCRIPTION_CHANGE + + """Directive was removed.""" + DIRECTIVE_REMOVED + + """Argument to the directive was removed.""" + DIRECTIVE_ARG_REMOVED + + """Location of the directive was removed.""" + DIRECTIVE_LOCATION_REMOVED + + """Repeatable flag was removed for directive.""" + DIRECTIVE_REPEATABLE_REMOVED + + """Non-nullable argument added to directive.""" + REQUIRED_DIRECTIVE_ARG_ADDED +} + +""" +Represents the tuple of static information +about a particular kind of schema change. +""" +type ChangeDefinition { + code: ChangeCode! + defaultSeverity: ChangeSeverity! + category: ChangeCategory! +} + +"""Info about a change in the context of an operation it affects""" +type ChangeOnOperation { + """ + The semantic info about this change, i.e. info about the change that doesn't depend on the operation + """ + semanticChange: SemanticChange! + + """ + Human-readable explanation of the impact of this change on the operation + """ + impact: String +} + +enum ChangeSeverity { + FAILURE + NOTICE +} + +""" +Summary of the changes for a schema diff, computed by placing the changes into categories and then +counting the size of each category. This categorization can be done in different ways, and +accordingly there are multiple fields here for each type of categorization. + +Note that if an object or interface field is added/removed, there won't be any addition/removal +changes generated for its arguments or @deprecated usages. If an enum type is added/removed, there +will be addition/removal changes generated for its values, but not for those values' @deprecated +usages. Description changes won't be generated for a schema element if that element (or an +ancestor) was added/removed. +""" +type ChangeSummary { + """ + Counts for changes to non-field aspects of objects, input objects, and interfaces, + and all aspects of enums, unions, and scalars. + """ + type: TypeChangeSummaryCounts! + + """ + Counts for changes to fields of objects, input objects, and interfaces. + """ + field: FieldChangeSummaryCounts! + + """Counts for all changes.""" + total: TotalChangeSummaryCounts! +} + +type ChangeSummaryCounts { + """Number of changes for parent kind that are additions.""" + additions: Int! + + """Number of changes for parent kind that are removals.""" + removals: Int! + + """Number of changes for parent kind that are edits.""" + edits: Int! + + """Number of changes for parent kind that are deprecation-related.""" + deprecations: Int! +} + +enum ChangeType { + FAILURE + NOTICE +} + +"""Destination for notifications""" +interface Channel { + id: ID! + name: String +} + +type CheckConfiguration { + """ID of the check configuration""" + id: ID! + + """Graph that this check configuration belongs to""" + graphID: ID! + + """Operations to ignore during validation""" + excludedOperations: [ExcludedOperation!]! + + """Clients to ignore during validation""" + excludedClients: [ClientFilter!]! + + """Variant overrides for validation""" + includedVariants: [String!]! + + """Time when check configuration was created""" + createdAt: Timestamp! + + """Time when check configuration was last updated""" + updatedAt: Timestamp! + + """Identity of the last user to update the check configuration""" + updatedBy: Identity + + """ + Only check operations from the last seconds. + The default is 7 days (604,800 seconds). + """ + timeRangeSeconds: Long! + + """ + Minimum number of requests within the window for an operation to be considered. + """ + operationCountThreshold: Int! + + """ + Number of requests within the window for an operation to be considered, relative to + total request count. Expected values are between 0 and 0.05 (minimum 5% of + total request volume) + """ + operationCountThresholdPercentage: Float! + + """Default configuration to include operations on the base variant.""" + includeBaseVariant: Boolean! +} + +type CheckOperationsInChecksResult { + changes: [Change!]! +} + +type CheckPartialSchemaResult { + """Result of composition validation run before the schema check.""" + compositionValidationResult: CompositionValidationResult! + + """ + Result of traffic validation. This will be null if composition validation was unsuccessful. + """ + checkSchemaResult: CheckSchemaResult +} + +type CheckSchemaResult { + """Schema diff and affected operations generated by the schema check""" + diffToPrevious: SchemaDiff! + + """Generated url to view schema diff in Engine""" + targetUrl: String +} + +"""Client filter configuration for a graph.""" +type ClientFilter { + """ + ID, often the name, of the client set by the user and reported alongside metrics + """ + referenceID: ID + + """version of the client set by the user and reported alongside metrics""" + version: String + + """name of the client set by the user and reported alongside metrics""" + name: String +} + +""" +Options to filter by client reference ID, client name, and client version. +If passing client version, make sure to either provide a client reference ID or client name. +""" +input ClientFilterInput { + """ + ID, often the name, of the client set by the user and reported alongside metrics + """ + referenceID: ID + + """version of the client set by the user and reported alongside metrics""" + version: String + + """name of the client set by the user and reported alongside metrics""" + name: String +} + +""" +Filter options to exclude by client reference ID, client name, and client version. +""" +input ClientInfoFilter { + referenceID: ID + name: String + version: String +} + +""" +Filter options to exclude clients. Used as an output type for SchemaDiffValidationConfig. +""" +type ClientInfoFilterOutput { + referenceID: ID + name: String + version: String +} + +enum ComparisonOperator { + EQUALS + GREATER_THAN + GREATER_THAN_OR_EQUAL_TO + LESS_THAN + LESS_THAN_OR_EQUAL_TO + NOT_EQUALS + UNRECOGNIZED +} + +""" +Metadata about the result of composition run in the cloud, combined with removing an implementing service +""" +type CompositionAndRemoveResult { + """The produced composition config. Will be null if there are any errors""" + compositionConfig: CompositionConfig + + """ + List of errors during composition. Errors mean that Apollo was unable to compose the + graph's implementing services into a GraphQL schema. This partial schema should not be + published to the implementing service if there were any errors encountered. + """ + errors: [SchemaCompositionError]! + + """Whether the gateway link was updated, or would have been for dry runs.""" + updatedGateway: Boolean! + + """Whether the removed implementing service existed.""" + didExist: Boolean! + + """ID that points to the results of composition.""" + graphCompositionID: String! +} + +""" +Metadata about the result of composition run in the cloud, combined with implementing service upsert +""" +type CompositionAndUpsertResult { + """The produced composition config. Will be null if there are any errors""" + compositionConfig: CompositionConfig + + """ + List of errors during composition. Errors mean that Apollo was unable to compose the + graph's implementing services into a GraphQL schema. This partial schema should not be + published to the implementing service if there were any errors encountered + """ + errors: [SchemaCompositionError]! + + """Whether the gateway link was updated.""" + updatedGateway: Boolean! + + """Whether an implementingService was created as part of this mutation""" + wasCreated: Boolean! + + """ID that points to the results of composition.""" + graphCompositionID: String! + + """Whether an implementingService was updated as part of this mutation""" + wasUpdated: Boolean! +} + +"""The composition config exposed to the gateway""" +type CompositionConfig { + """List of implementing services that comprise a composed graph""" + implementingServiceLocations: [ImplementingServiceLocation!]! + + """Hash of the composed schema""" + schemaHash: String! +} + +"""Metadata about the result of composition run in the cloud""" +type CompositionPublishResult { + """The produced composition config. Will be null if there are any errors""" + compositionConfig: CompositionConfig + + """ + List of errors during composition. Errors mean that Apollo was unable to compose the + graph's implementing services into a GraphQL schema. This partial schema should not be + published to the implementing service if there were any errors encountered + """ + errors: [SchemaCompositionError!]! + + """Whether the gateway link was updated.""" + updatedGateway: Boolean! + + """ID that points to composition result.""" + graphCompositionID: String! +} + +""" +Result of a composition, either as the result of a composition validation or a publish. +""" +union CompositionResult = CompositionValidationResult | CompositionPublishResult + +"""The composition config exposed to the gateway""" +type CompositionValidationDetails { + """ + List of implementing service partial schemas that comprised the graph composed during validation + """ + implementingServices: [FederatedImplementingServicePartialSchema!]! + + """Hash of the composed schema""" + schemaHash: String +} + +"""Metadata about the result of compositions validation run in the cloud""" +type CompositionValidationResult { + """ + Akin to a composition config, represents the partial schemas and implementing services that were used + in running composition. Will be null if any errors are encountered. Also may contain a schema hash if + one could be computed, which can be used for schema validation. + """ + compositionValidationDetails: CompositionValidationDetails + + """ + The implementing service that was responsible for triggering the validation + """ + proposedImplementingService: FederatedImplementingServicePartialSchema! + + """ + List of errors during composition. Errors mean that Apollo was unable to compose the + graph's implementing services into a GraphQL schema. This partial schema should not be + published to the implementing service if there were any errors encountered + """ + errors: [SchemaCompositionError]! + + """Describes whether composition succeeded.""" + compositionSuccess: Boolean! + + """ID that points to the results of this composition.""" + graphCompositionID: String! +} + +type CronExecution { + completedAt: Timestamp + failure: String + id: ID! + job: CronJob! + resolvedAt: Timestamp + resolvedBy: Actor + schedule: String! + startedAt: Timestamp! +} + +type CronJob { + group: String! + name: String! + recentExecutions(n: Int): [CronExecution!]! +} + +enum DatadogApiRegion { + EU + US +} + +type DatadogMetricsConfig { + apiKey: String! + apiRegion: DatadogApiRegion! + enabled: Boolean! + legacyMetricNames: Boolean! +} + +type DeleteSchemaTagResult { + deleted: Boolean! + deletedSubscriptionIDs: [ID!]! +} + +enum DeletionTargetType { + ACCOUNT + USER +} + +type DurationHistogram { + averageDurationMs: Float + buckets: [DurationHistogramBucket!]! + durationMs( + """Percentile (between 0 and 1)""" + percentile: Float! + ): Float + + """ + Counts per durationBucket, where sequences of zeroes are replaced with the negative of their size + """ + sparseBuckets: [Long!]! + totalCount: Long! + totalDurationMs: Float! +} + +type DurationHistogramBucket { + count: Long! + index: Int! + rangeBeginMs: Float! + rangeEndMs: Float! +} + +"""Edge server info""" +input EdgeServerInfo { + """ + A randomly generated UUID, immutable for the lifetime of the edge server runtime. + """ + bootId: String! + + """ + A unique identifier for the executable GraphQL served by the edge server. length must be <= 64 characters. + """ + executableSchemaId: String! + + """The graph variant, defaults to 'current'""" + graphVariant: String! = "current" + + """ + The version of the edge server reporting agent, e.g. apollo-server-2.8, + graphql-java-3.1, etc. length must be <= 256 characters. + """ + libraryVersion: String + + """ + The infra environment in which this edge server is running, e.g. localhost, + Kubernetes, AWS Lambda, Google CloudRun, AWS ECS, etc. length must be <= 256 characters. + """ + platform: String + + """ + The runtime in which the edge server is running, e.g. node 12.03, + zulu8.46.0.19-ca-jdk8.0.252-macosx_x64, etc. length must be <= 256 characters. + """ + runtimeVersion: String + + """ + If available, an identifier for the edge server instance, such that when + restarting this instance it will have the same serverId, with a different + bootId. For example, in Kubernetes this might be the pod name. Length must be + <= 256 characters. + """ + serverId: String + + """ + An identifier used to distinguish the version (from the user's perspective) of + the edge server's code itself. For instance, the git sha of the server's + repository or the docker sha of the associated image this server runs with. + Length must be <= 256 characters. + """ + userVersion: String +} + +"""Columns of EdgeServerInfos.""" +enum EdgeServerInfosColumn { + BOOT_ID + EXECUTABLE_SCHEMA_ID + LIBRARY_VERSION + PLATFORM + RUNTIME_VERSION + SCHEMA_TAG + SERVER_ID + SERVICE_ID + TIMESTAMP + USER_VERSION +} + +type EdgeServerInfosDimensions { + bootId: ID + executableSchemaId: ID + libraryVersion: String + platform: String + runtimeVersion: String + schemaTag: String + serverId: ID + serviceId: ID + userVersion: String +} + +""" +Filter for data in EdgeServerInfos. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input EdgeServerInfosFilter { + and: [EdgeServerInfosFilter!] + + """ + Selects rows whose bootId dimension equals the given value if not null. To + query for the null value, use {in: {bootId: [null]}} instead. + """ + bootId: ID + + """ + Selects rows whose executableSchemaId dimension equals the given value if not + null. To query for the null value, use {in: {executableSchemaId: [null]}} instead. + """ + executableSchemaId: ID + in: EdgeServerInfosFilterIn + + """ + Selects rows whose libraryVersion dimension equals the given value if not + null. To query for the null value, use {in: {libraryVersion: [null]}} instead. + """ + libraryVersion: String + not: EdgeServerInfosFilter + or: [EdgeServerInfosFilter!] + + """ + Selects rows whose platform dimension equals the given value if not null. To + query for the null value, use {in: {platform: [null]}} instead. + """ + platform: String + + """ + Selects rows whose runtimeVersion dimension equals the given value if not + null. To query for the null value, use {in: {runtimeVersion: [null]}} instead. + """ + runtimeVersion: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serverId dimension equals the given value if not null. To + query for the null value, use {in: {serverId: [null]}} instead. + """ + serverId: ID + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose userVersion dimension equals the given value if not null. + To query for the null value, use {in: {userVersion: [null]}} instead. + """ + userVersion: String +} + +""" +Filter for data in EdgeServerInfos. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input EdgeServerInfosFilterIn { + """ + Selects rows whose bootId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + bootId: [ID] + + """ + Selects rows whose executableSchemaId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + executableSchemaId: [ID] + + """ + Selects rows whose libraryVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + libraryVersion: [String] + + """ + Selects rows whose platform dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + platform: [String] + + """ + Selects rows whose runtimeVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + runtimeVersion: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serverId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serverId: [ID] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose userVersion dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + userVersion: [String] +} + +input EdgeServerInfosOrderBySpec { + column: EdgeServerInfosColumn! + direction: Ordering! +} + +type EdgeServerInfosRecord { + """Dimensions of EdgeServerInfos that can be grouped by.""" + groupBy: EdgeServerInfosDimensions! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +enum EmailCategory { + EDUCATIONAL +} + +type EmailPreferences { + email: String! + subscriptions: [EmailCategory!]! + unsubscribedFromAll: Boolean! +} + +"""Columns of EnumStats.""" +enum EnumStatsColumn { + ACCOUNT_ID + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ENUM_TYPE + ENUM_VALUE + QUERY_ID + QUERY_NAME + REQUEST_COUNT + RESPONSE_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP +} + +type EnumStatsDimensions { + accountId: ID + clientName: String + clientReferenceId: ID + clientVersion: String + enumType: String + enumValue: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in EnumStats. Fields with dimension names represent equality +checks. All fields are implicitly ANDed together. +""" +input EnumStatsFilter { + """ + Selects rows whose accountId dimension equals the given value if not null. To + query for the null value, use {in: {accountId: [null]}} instead. + """ + accountId: ID + and: [EnumStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose enumType dimension equals the given value if not null. To + query for the null value, use {in: {enumType: [null]}} instead. + """ + enumType: String + + """ + Selects rows whose enumValue dimension equals the given value if not null. To + query for the null value, use {in: {enumValue: [null]}} instead. + """ + enumValue: String + in: EnumStatsFilterIn + not: EnumStatsFilter + or: [EnumStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in EnumStats. Fields match if the corresponding dimension's +value is in the given list. All fields are implicitly ANDed together. +""" +input EnumStatsFilterIn { + """ + Selects rows whose accountId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + accountId: [ID] + + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose enumType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + enumType: [String] + + """ + Selects rows whose enumValue dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + enumValue: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type EnumStatsMetrics { + requestCount: Long! + responseCount: Long! +} + +input EnumStatsOrderBySpec { + column: EnumStatsColumn! + direction: Ordering! +} + +type EnumStatsRecord { + """Dimensions of EnumStats that can be grouped by.""" + groupBy: EnumStatsDimensions! + + """Metrics of EnumStats that can be aggregated over.""" + metrics: EnumStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of ErrorStats.""" +enum ErrorStatsColumn { + ACCOUNT_ID + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ERRORS_COUNT + PATH + QUERY_ID + QUERY_NAME + REQUESTS_WITH_ERRORS_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP +} + +type ErrorStatsDimensions { + accountId: ID + clientName: String + clientReferenceId: ID + clientVersion: String + path: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in ErrorStats. Fields with dimension names represent equality +checks. All fields are implicitly ANDed together. +""" +input ErrorStatsFilter { + """ + Selects rows whose accountId dimension equals the given value if not null. To + query for the null value, use {in: {accountId: [null]}} instead. + """ + accountId: ID + and: [ErrorStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + in: ErrorStatsFilterIn + not: ErrorStatsFilter + or: [ErrorStatsFilter!] + + """ + Selects rows whose path dimension equals the given value if not null. To query + for the null value, use {in: {path: [null]}} instead. + """ + path: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in ErrorStats. Fields match if the corresponding dimension's +value is in the given list. All fields are implicitly ANDed together. +""" +input ErrorStatsFilterIn { + """ + Selects rows whose accountId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + accountId: [ID] + + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose path dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + path: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type ErrorStatsMetrics { + errorsCount: Long! + requestsWithErrorsCount: Long! +} + +input ErrorStatsOrderBySpec { + column: ErrorStatsColumn! + direction: Ordering! +} + +type ErrorStatsRecord { + """Dimensions of ErrorStats that can be grouped by.""" + groupBy: ErrorStatsDimensions! + + """Metrics of ErrorStats that can be aggregated over.""" + metrics: ErrorStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +""" Input parameters for run explorer operation event.""" +enum EventEnum { + CLICK_CHECK_LIST + RUN_EXPLORER_OPERATION +} + +"""Excluded operation for a graph.""" +type ExcludedOperation { + """Operation ID to exclude from schema check.""" + ID: ID! +} + +"""Option to filter by operation ID.""" +input ExcludedOperationInput { + """Operation ID to exclude from schema check.""" + ID: ID! +} + +type FederatedImplementingService { + """Name of the implementing service""" + name: String! + + """URL of the graphql endpoint of the implementing service""" + url: String + + """ + A way to capture some customer-specific way of tracking which version / edition + of the ImplementingService this is. Typically a Git SHA or docker image ID. + """ + revision: String! + + """ + Identifies which graph this implementing service belongs to. + Formerly known as "service_id" + """ + graphID: String! + + """ + Specifies which variant of a graph this implementing service belongs to". + Formerly known as "tag" + """ + graphVariant: String! + + """ + An implementing service could have multiple inactive partial schemas that were previously uploaded + activePartialSchema returns the one that is designated to be used for composition for a given graph-variant + """ + activePartialSchema: PartialSchema! + + """Timestamp of when this implementing service was created""" + createdAt: Timestamp! + + """Timestamp for when this implementing service was updated""" + updatedAt: Timestamp! +} + +""" +A minimal representation of a federated implementing service, using only a name and partial schema SDL +""" +type FederatedImplementingServicePartialSchema { + """The name of the implementing service""" + name: String! + + """The partial schema of the implementing service""" + sdl: String! +} + +"""List of federated implementing services that compose a graph""" +type FederatedImplementingServices { + services: [FederatedImplementingService!]! +} + +type FieldChangeSummaryCounts { + """ + Number of changes that are additions of fields to object and interface types. + """ + additions: Int! + + """ + Number of changes that are removals of fields from object and interface types. + """ + removals: Int! + + """ + Number of changes that are field edits. This includes fields changing type and any field + deprecation and description changes, but also includes any argument changes and any input object + field changes. + """ + edits: Int! +} + +"""Columns of FieldStats.""" +enum FieldStatsColumn { + ACCOUNT_ID + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ERRORS_COUNT + FIELD + FIELD_HISTOGRAM + QUERY_ID + QUERY_NAME + REQUEST_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP +} + +type FieldStatsDimensions { + accountId: ID + clientName: String + clientReferenceId: ID + clientVersion: String + field: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in FieldStats. Fields with dimension names represent equality +checks. All fields are implicitly ANDed together. +""" +input FieldStatsFilter { + """ + Selects rows whose accountId dimension equals the given value if not null. To + query for the null value, use {in: {accountId: [null]}} instead. + """ + accountId: ID + and: [FieldStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose field dimension equals the given value if not null. To + query for the null value, use {in: {field: [null]}} instead. + """ + field: String + in: FieldStatsFilterIn + not: FieldStatsFilter + or: [FieldStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in FieldStats. Fields match if the corresponding dimension's +value is in the given list. All fields are implicitly ANDed together. +""" +input FieldStatsFilterIn { + """ + Selects rows whose accountId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + accountId: [ID] + + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose field dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + field: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type FieldStatsMetrics { + errorsCount: Long! + fieldHistogram: DurationHistogram! + requestCount: Long! +} + +input FieldStatsOrderBySpec { + column: FieldStatsColumn! + direction: Ordering! +} + +type FieldStatsRecord { + """Dimensions of FieldStats that can be grouped by.""" + groupBy: FieldStatsDimensions! + + """Metrics of FieldStats that can be aggregated over.""" + metrics: FieldStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +type GitContext { + remoteUrl: String + remoteHost: GitRemoteHost + commit: ID + commitUrl: String + committer: String + message: String + branch: String +} + +"""This is stored with a schema when it is uploaded""" +input GitContextInput { + remoteUrl: String + commit: ID + committer: String + message: String + branch: String +} + +enum GitRemoteHost { + GITHUB + GITLAB + BITBUCKET +} + +""" +A union of all combinations that can comprise the implementingServices for a Service +""" +union GraphImplementors = NonFederatedImplementingService | FederatedImplementingServices + +"""A GraphQL document""" +scalar GraphQLDocument + +""" +A variant of a graph, also called a schema tag in parts of our product. +""" +type GraphVariant + @owner(graph: "registry") + @key(fields: "{ id graphId name }", graph: "registry") + @key(fields: "{ id graphId name }", graph: "kotlin") +{ + """Global identifier for the graph variant, in the form `graph@variant`.""" + id: ID! + + """Graph ID of the variant. Prefer using graph { id } when feasible.""" + graphId: String! + + """Graph the variant belongs to""" + graph: Service! + + """Name of the variant, like `variant`.""" + name: String! + + """URL where the graph can be queried.""" + url: String + + """If the graphql endpoint is set up to accept cookies""" + sendCookies: Boolean! + + """URL where the graph subscription can be queried.""" + subscriptionUrl: String + + """ + Explorer setting for preflight script to run before the actual GraphQL operations is run. + """ + preflightScript: String + + """Explorer setting for default headers for a graph""" + defaultHeaders: String + + """ + As new schema tags keep getting published, activeSchemaPublish refers to the latest. + """ + activeSchemaPublish: SchemaTag + + """ + Get most recent checks on a variant. If a branch filter is provided then all checks will come from that branch + """ + checks(limit: Int! = 100, branch: String): [SchemaCheck!]! + + """ + Get the most recent checks per branch. If branch is not set, then then those checks will not be grouped + """ + checksPerBranch(limit: Int! = 20): [SchemaCheck!]! + + """Get a single schema check by its id""" + check(id: ID!): SchemaCheck + autoPromotion: Boolean! @resolve(graph: "kotlin") + + """Is this variant one of the current user's favorite variants?""" + isFavoriteOfCurrentUser: Boolean! @resolve(graph: "kotlin") + + """The total number of requests for this variant in the last 24 hours""" + requestsInLastDay: Long @resolve(graph: "kotlin") + + """ + The last instant that usage information (e.g. operation stat, client stats) was reported for this variant + """ + usageLastReportedAt: Timestamp @resolve(graph: "kotlin") +} + +""" +Modifies a variant of a graph, also called a schema tag in parts of our product. +""" +type GraphVariantMutation + @owner(graph: "registry") + @key(fields: "{ id graphId name }", graph: "registry") + @key(fields: "{ id graphId name }", graph: "kotlin") +{ + """Global identifier for the graph variant, in the form `graph@variant`.""" + id: ID! + + """Graph ID of the variant""" + graphId: String! + + """Name of the variant, like `variant`.""" + name: String! + updateURL(url: String): GraphVariant + updateSubscriptionURL(subscriptionUrl: String): GraphVariant + updateSendCookies(sendCookies: Boolean!): GraphVariant + updatePreflightScript(preflightScript: String): GraphVariant + updateDefaultHeaders(defaultHeaders: String): GraphVariant + autoPromotion(enable: Boolean): Boolean! @resolve(graph: "kotlin") + setIsFavoriteOfCurrentUser(favorite: Boolean!): GraphVariant! @resolve(graph: "kotlin") +} + +input HistoricQueryParameters { + from: Timestamp = "-86400" + to: Timestamp = "-0" + + """ + Minimum number of requests within the window for a query to be considered. + """ + queryCountThreshold: Int = 1 + + """ + Number of requests within the window for a query to be considered, relative to + total request count. Expected values are between 0 and 0.05 (minimum 5% of total + request volume) + """ + queryCountThresholdPercentage: Float = 0 + + """A list of operation IDs to filter out during validation.""" + ignoredOperations: [ID!] + + """A list of clients to filter out during validation.""" + excludedClients: [ClientInfoFilter!] + + """ + A list of variants to include in the validation. If no variants are provided + then this defaults to the "current" variant along with the base variant. The + base variant indicates the schema that generates diff and marks the metrics that + are checked for broken queries. We union this base variant with the untagged values('', + same as null inside of `in`, and 'current') in this metrics fetch. This strategy + supports users who have not tagged their metrics or schema. + """ + includedVariants: [String!] +} + +enum HTTPMethod { + CONNECT + DELETE + GET + HEAD + OPTIONS + PATCH + POST + PUT + TRACE + UNKNOWN + UNRECOGNIZED +} + +interface Identity { + asActor: Actor! + id: ID! + name: String! +} + +""" +An actor's identity and info about the client they used to perform the action +""" +type IdentityAndClientInfo { + """Identity info about the actor""" + identity: Identity + + """ + The clientName given to Apollo Cloud when the actor performed the action + """ + clientName: String + + """ + The clientVersion given to Apollo Cloud when the actor performed the action + """ + clientVersion: String +} + +union IdentityMutation = ServiceMutation | UserMutation + +type IgnoreOperationsInChecksResult { + graph: Service! +} + +"""The location of the implementing service config file in storage""" +type ImplementingServiceLocation { + """The name of the implementing service""" + name: String! + + """The path in storage to access the implementing service config file""" + path: String! +} + +"""Columns of InputStats.""" +enum InputStatsColumn { + ACCOUNT_ID + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + FIELD_NAME + FIELD_TYPE + PARENT_TYPE + QUERY_ID + QUERY_NAME + REQUEST_COUNT + REQUEST_COUNT_NULL + REQUEST_COUNT_UNDEFINED + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP +} + +type InputStatsDimensions { + accountId: ID + clientName: String + clientReferenceId: ID + clientVersion: String + fieldName: String + fieldType: String + parentType: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in InputStats. Fields with dimension names represent equality +checks. All fields are implicitly ANDed together. +""" +input InputStatsFilter { + """ + Selects rows whose accountId dimension equals the given value if not null. To + query for the null value, use {in: {accountId: [null]}} instead. + """ + accountId: ID + and: [InputStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose fieldName dimension equals the given value if not null. To + query for the null value, use {in: {fieldName: [null]}} instead. + """ + fieldName: String + + """ + Selects rows whose fieldType dimension equals the given value if not null. To + query for the null value, use {in: {fieldType: [null]}} instead. + """ + fieldType: String + in: InputStatsFilterIn + not: InputStatsFilter + or: [InputStatsFilter!] + + """ + Selects rows whose parentType dimension equals the given value if not null. To + query for the null value, use {in: {parentType: [null]}} instead. + """ + parentType: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in InputStats. Fields match if the corresponding dimension's +value is in the given list. All fields are implicitly ANDed together. +""" +input InputStatsFilterIn { + """ + Selects rows whose accountId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + accountId: [ID] + + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose fieldName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + fieldName: [String] + + """ + Selects rows whose fieldType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + fieldType: [String] + + """ + Selects rows whose parentType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + parentType: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type InputStatsMetrics { + requestCount: Long! + requestCountNull: Long! + requestCountUndefined: Long! +} + +input InputStatsOrderBySpec { + column: InputStatsColumn! + direction: Ordering! +} + +type InputStatsRecord { + """Dimensions of InputStats that can be grouped by.""" + groupBy: InputStatsDimensions! + + """Metrics of InputStats that can be aggregated over.""" + metrics: InputStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +type InternalAdminUser { + role: InternalMdgAdminRole! + userID: String! +} + +type InternalIdentity implements Identity + @owner(graph: "kotlin") + @key(fields: "{ id }", graph: "kotlin") + @key(fields: "{ id }", graph: "registry") +{ + accounts: [Account!]! + asActor: Actor! + email: String + id: ID! + name: String! +} + +enum InternalMdgAdminRole { + INTERNAL_MDG_READ_ONLY + INTERNAL_MDG_SALES + INTERNAL_MDG_SUPER_ADMIN + INTERNAL_MDG_SUPPORT +} + +type IntrospectionDirective { + name: String! + description: String + locations: [IntrospectionDirectiveLocation!]! + args: [IntrospectionInputValue!]! +} + +input IntrospectionDirectiveInput { + name: String! + description: String + locations: [IntrospectionDirectiveLocation!]! + args: [IntrospectionInputValueInput!]! + isRepeatable: Boolean +} + +"""__DirectiveLocation introspection type""" +enum IntrospectionDirectiveLocation { + """Location adjacent to a query operation.""" + QUERY + + """Location adjacent to a mutation operation.""" + MUTATION + + """Location adjacent to a subscription operation.""" + SUBSCRIPTION + + """Location adjacent to a field.""" + FIELD + + """Location adjacent to a fragment definition.""" + FRAGMENT_DEFINITION + + """Location adjacent to a fragment spread.""" + FRAGMENT_SPREAD + + """Location adjacent to an inline fragment.""" + INLINE_FRAGMENT + + """Location adjacent to a variable definition.""" + VARIABLE_DEFINITION + + """Location adjacent to a schema definition.""" + SCHEMA + + """Location adjacent to a scalar definition.""" + SCALAR + + """Location adjacent to an object type definition.""" + OBJECT + + """Location adjacent to a field definition.""" + FIELD_DEFINITION + + """Location adjacent to an argument definition.""" + ARGUMENT_DEFINITION + + """Location adjacent to an interface definition.""" + INTERFACE + + """Location adjacent to a union definition.""" + UNION + + """Location adjacent to an enum definition.""" + ENUM + + """Location adjacent to an enum value definition.""" + ENUM_VALUE + + """Location adjacent to an input object type definition.""" + INPUT_OBJECT + + """Location adjacent to an input object field definition.""" + INPUT_FIELD_DEFINITION +} + +"""Values associated with introspection result for an enum value""" +type IntrospectionEnumValue { + name: String! + description: String + isDeprecated: Boolean! + depreactionReason: String @deprecated(reason: "Use deprecationReason instead") + deprecationReason: String +} + +"""__EnumValue introspection type""" +input IntrospectionEnumValueInput { + name: String! + description: String + isDeprecated: Boolean! + deprecationReason: String +} + +"""Values associated with introspection result for field""" +type IntrospectionField + @owner(graph: "registry") + @key(fields: "{ graphId schemaTag parentTypeName name }", graph: "registry") + @key(fields: "{ graphId schemaTag parentTypeName name }", graph: "kotlin") +{ + name: String! + + """This field is for internal use only""" + parentTypeName: String! + + """This field is for internal use only""" + schemaTag: String! + + """This field is for internal use only""" + graphId: String! + description: String + args: [IntrospectionInputValue!]! + type: IntrospectionType! + isDeprecated: Boolean! + deprecationReason: String + lastUsed(from: Timestamp!, to: Timestamp): Timestamp @resolve(graph: "kotlin") +} + +"""__Field introspection type""" +input IntrospectionFieldInput { + name: String! + description: String + args: [IntrospectionInputValueInput!]! + type: IntrospectionTypeInput! + isDeprecated: Boolean! + deprecationReason: String +} + +"""Values associated with introspection result for an input field""" +type IntrospectionInputValue { + name: String! + description: String + type: IntrospectionType! + defaultValue: String +} + +"""__Value introspection type""" +input IntrospectionInputValueInput { + name: String! + description: String + type: IntrospectionTypeInput! + defaultValue: String +} + +type IntrospectionSchema { + types(filter: TypeFilterConfig = {includeAbstractTypes: true, includeBuiltInTypes: true, includeIntrospectionTypes: true}): [IntrospectionType!]! + queryType: IntrospectionType! + mutationType: IntrospectionType + subscriptionType: IntrospectionType + directives: [IntrospectionDirective!]! +} + +"""__Schema introspection type""" +input IntrospectionSchemaInput { + types: [IntrospectionTypeInput!] + queryType: IntrospectionTypeRefInput! + mutationType: IntrospectionTypeRefInput + subscriptionType: IntrospectionTypeRefInput + directives: [IntrospectionDirectiveInput!]! + description: String +} + +"""Object containing all possible values for an introspectionType""" +type IntrospectionType { + kind: IntrospectionTypeKind + name: String + + """ + printed representation of type, including nested nullability and list ofTypes + """ + printed: String! + + """ + the base kind of the type this references, ignoring lists and nullability + """ + baseKind: IntrospectionTypeKind + description: String + fields: [IntrospectionField!] + interfaces: [IntrospectionType!] + possibleTypes: [IntrospectionType!] + enumValues(includeDeprecated: Boolean = false): [IntrospectionEnumValue!] + inputFields: [IntrospectionInputValue!] + ofType: IntrospectionType +} + +"""__Type introspection type""" +input IntrospectionTypeInput { + kind: IntrospectionTypeKind! + name: String + description: String + fields: [IntrospectionFieldInput!] + interfaces: [IntrospectionTypeInput!] + possibleTypes: [IntrospectionTypeInput!] + enumValues: [IntrospectionEnumValueInput!] + inputFields: [IntrospectionInputValueInput!] + ofType: IntrospectionTypeInput +} + +enum IntrospectionTypeKind { + """Indicates this type is a scalar.""" + SCALAR + + """ + Indicates this type is an object. 'fields' and 'interfaces' are valid fields. + """ + OBJECT + + """ + Indicates this type is an interface. 'fields' and 'possibleTypes' are valid + fields + """ + INTERFACE + + """Indicates this type is a union. 'possibleTypes' is a valid field.""" + UNION + + """Indicates this type is an enum. 'enumValues' is a valid field.""" + ENUM + + """ + Indicates this type is an input object. 'inputFields' is a valid field. + """ + INPUT_OBJECT + + """Indicates this type is a list. 'ofType' is a valid field.""" + LIST + + """Indicates this type is a non-null. 'ofType' is a valid field.""" + NON_NULL +} + +"""Shallow __Type introspection type""" +input IntrospectionTypeRefInput { + name: String! + kind: String +} + +type InvalidOperation { + signature: ID! + errors: [OperationValidationError!] +} + +type Invoice { + closedAt: Timestamp + collectionMethod: String + createdAt: Timestamp! + invoiceNumber: Int! + state: InvoiceState! + totalInCents: Int! + updatedAt: Timestamp! + uuid: ID! +} + +enum InvoiceState { + COLLECTED + FAILED + OPEN + PAST_DUE + UNKNOWN +} + +"""Long type""" +scalar Long + +type MarkChangesForOperationAsSafeResult { + success: Boolean! + message: String! + + """ + Nice to have for the frontend since the Apollo cache is already watching for AffectedQuery to update. + This might return null if no behavior changes were found for the affected operation ID. + This is a weird situation that should never happen. + """ + affectedOperation: AffectedQuery +} + +type MediaUploadInfo { + csrfToken: String! + maxContentLength: Int! + url: String! +} + +type Mutation { + account(id: ID!): AccountMutation @resolve(graph: "kotlin") + + """ + Finalize a password reset with a token included in the E-mail link, + returns the corresponding login email when successful + """ + finalizePasswordReset(newPassword: String!, resetToken: String!): String @resolve(graph: "kotlin") + + """Join an account with a token""" + joinAccount(accountId: ID!, joinToken: String!): Account @resolve(graph: "kotlin") + me: IdentityMutation @resolve(graph: "kotlin") + newAccount(id: ID!): Account @resolve(graph: "kotlin") + newService(accountId: ID!, hiddenFromUninvitedNonAdminAccountMembers: Boolean! = false, id: ID!, isDev: Boolean! = false, name: String, title: String): Service @resolve(graph: "kotlin") + + """Refresh all plans from third-party billing service""" + plansRefreshBilling: Void @resolve(graph: "kotlin") + + """Ask for a user's password to be reset by E-mail""" + resetPassword(email: String!): Void @resolve(graph: "kotlin") + resolveAllInternalCronExecutions(group: String, name: String): Void @resolve(graph: "kotlin") + resolveInternalCronExecution(id: ID!): CronExecution @resolve(graph: "kotlin") + service(id: ID!): ServiceMutation @resolve(graph: "kotlin") + + """Set the subscriptions for a given email""" + setSubscriptions(email: String!, subscriptions: [EmailCategory!]!, token: String!): EmailPreferences @resolve(graph: "kotlin") + + """Set the studio settings for the current user""" + setUserSettings(newSettings: UserSettingsInput): UserSettings @resolve(graph: "kotlin") + signUp(email: String!, fullName: String!, password: String!, referrer: String): User @resolve(graph: "kotlin") + + """ + This is called by the form shown to users after they delete their user or organization account. + """ + submitPostDeletionFeedback(feedback: String!, targetIdentifier: ID!, targetType: DeletionTargetType!): Void @resolve(graph: "kotlin") + + """Mutation for basic engagement tracking in studio""" + track(event: EventEnum!, graphID: String!, graphVariant: String! = "current"): Void @resolve(graph: "kotlin") + + """Unsubscribe a given email from all emails""" + unsubscribeFromAll(email: String!, token: String!): EmailPreferences @resolve(graph: "kotlin") + user(id: ID!): UserMutation @resolve(graph: "kotlin") +} + +type NamedIntrospectionArg { + name: String + description: String +} + +type NamedIntrospectionArgNoDescription { + name: String +} + +""" +The shared fields for a named introspection type. Currently this is returned for the +top level value affected by a change. In the future, we may update this +type to be an interface, which is extended by the more specific types: +scalar, object, input object, union, interface, and enum + +For an in-depth look at where these types come from, see: +https://github.com/DefinitelyTyped/DefinitelyTyped/blob/659eb50d3/types/graphql/utilities/introspectionQuery.d.ts#L31-L37 +""" +type NamedIntrospectionType { + kind: IntrospectionTypeKind + name: String + description: String +} + +type NamedIntrospectionTypeNoDescription { + name: String +} + +""" +Introspection values that can be children of other types for changes, such +as input fields, objects in interfaces, enum values. In the future, this +value could become an interface to allow fields specific to the types +returned. +""" +type NamedIntrospectionValue { + name: String + description: String + printedType: String +} + +type NamedIntrospectionValueNoDescription { + name: String + printedType: String +} + +"""A non-federated service for a monolithic graph""" +type NonFederatedImplementingService { + """Timestamp of when this implementing service was created""" + createdAt: Timestamp! + + """ + Identifies which graph this non-implementing service belongs to. + Formerly known as "service_id" + """ + graphID: String! + + """ + Specifies which variant of a graph this implementing service belongs to". + Formerly known as "tag" + """ + graphVariant: String! +} + +"""Arbitrary JSON object""" +scalar Object + +type Operation { + id: ID! + name: String + signature: String + truncated: Boolean! +} + +type OperationAcceptedChange { + id: ID! + graphID: ID! + checkID: ID! + operationID: String! + change: StoredApprovedChange! + acceptedAt: Timestamp! + acceptedBy: Identity! +} + +type OperationDocument { + """Operation document body""" + body: String! + + """Operation name""" + name: String +} + +input OperationDocumentInput { + """Operation document body""" + body: String! + + """Operation name""" + name: String +} + +type OperationValidationError { + message: String! +} + +enum Ordering { + ASCENDING + DESCENDING +} + +"""A reusable invite link for an organization.""" +type OrganizationInviteLink { + """ + A joinToken that can be passed to Mutation.joinAccount to join the organization. + """ + joinToken: String! + + """ + The role that the user will receive if they join the organization with this link. + """ + role: UserPermission! +} + +type OrganizationSSO { + defaultRole: UserPermission! + idpid: ID! + provider: OrganizationSSOProvider! +} + +enum OrganizationSSOProvider { + PINGONE +} + +"""PagerDuty notification channel""" +type PagerDutyChannel implements Channel { + id: ID! + name: String + routingKey: String! +} + +"""PagerDuty notification channel parameters""" +input PagerDutyChannelInput { + name: String + routingKey: String! +} + +"""Schema for an implementing service with associated metadata""" +type PartialSchema { + """The enriched sdl of a partial schema""" + sdl: String! + + """The path of deep storage to find the raw enriched partial schema file""" + sdlPath: String! + + """Timestamp for when the partial schema was created""" + createdAt: Timestamp! +} + +""" +Input for registering a partial schema to an implementing service. +One of the fields must be specified (validated server-side). + +If a new partialSchemaSDL is passed in, this operation will store it before +creating the association. + +If both the sdl and hash are specified, an error will be thrown if the provided +hash doesn't match our hash of the sdl contents +""" +input PartialSchemaInput { + """ + Contents of the partial schema in SDL syntax, but may reference types + that aren't defined in this document + """ + sdl: String + + """ + Hash of the partial schema to associate; error is thrown if only the hash is + specified and the hash has not been seen before + """ + hash: String +} + +type PromoteSchemaError { + code: PromoteSchemaErrorCode! + message: String! +} + +enum PromoteSchemaErrorCode { + CANNOT_PROMOTE_SCHEMA_FOR_FEDERATED_GRAPH +} + +type PromoteSchemaResponse { + code: PromoteSchemaResponseCode! + tag: SchemaTag! +} + +enum PromoteSchemaResponseCode { + PROMOTION_SUCCESS + NO_CHANGES_DETECTED +} + +union PromoteSchemaResponseOrError = PromoteSchemaResponse | PromoteSchemaError + +type Protobuf { + json: String + object: Object + raw: Blob! + text: String! +} + +type Query { + """Account by ID""" + account(id: ID!): Account @resolve(graph: "kotlin") + + """Whether an account ID is available for mutation{newAccount(id:)}""" + accountIDAvailable(id: ID!): Boolean! @resolve(graph: "kotlin") + + """All accounts""" + allAccounts(search: String, tier: BillingPlanTier): [Account!] @resolve(graph: "kotlin") + + """All available plans""" + allPlans: [BillingPlan!]! @resolve(graph: "kotlin") + + """All services""" + allServices(search: String): [Service!] @resolve(graph: "kotlin") + + """All timezones with their offsets from UTC""" + allTimezoneOffsets: [TimezoneOffset!]! @resolve(graph: "kotlin") + + """All users""" + allUsers(search: String): [User!] @resolve(graph: "kotlin") + + """ + If this is true, the user is an Apollo administrator who can ignore restrictions based purely on billing plan. + """ + canBypassPlanRestrictions: Boolean! @resolve(graph: "kotlin") + + """Get the unsubscribe settings for a given email.""" + emailPreferences(email: String!, token: String!): EmailPreferences @resolve(graph: "kotlin") + frontendUrlRoot: String! @resolve(graph: "kotlin") + internalActiveCronJobs: [CronJob!]! @resolve(graph: "kotlin") + internalAdminUsers: [InternalAdminUser!] @resolve(graph: "kotlin") + internalUnresolvedCronExecutionFailures: [CronExecution!]! @resolve(graph: "kotlin") + + """Current identity, null if not authenticated""" + me: Identity @resolve(graph: "kotlin") + + """Look up a plan by ID""" + plan(id: ID): BillingPlan @resolve(graph: "kotlin") + + """Service by ID""" + service(id: ID!): Service @resolve(graph: "kotlin") + + """ + Query statistics across all services. For admins only; normal users must go + through AccountsStatsWindow or ServiceStatsWindow. + """ + stats( + from: Timestamp! + + """ + Granularity of buckets. Defaults to the entire range (aggregate all data into a single durationBucket) when null. + """ + resolution: Resolution + + """Defaults to the current time when null.""" + to: Timestamp + ): StatsWindow! @resolve(graph: "kotlin") + + """Get the studio settings for the current user""" + studioSettings: UserSettings @resolve(graph: "kotlin") + + """The plan started by AccountMutation.startTeamSubscription""" + teamPlan(billingPeriod: BillingPeriod!): BillingPlan! @resolve(graph: "kotlin") + + """The plan started by AccountMutation.startTrial""" + trialPlan: BillingPlan! @resolve(graph: "kotlin") + + """User by ID""" + user(id: ID!): User @resolve(graph: "kotlin") +} + +"""query documents to validate against""" +input QueryDocumentInput { + document: String +} + +"""Columns of QueryStats.""" +enum QueryStatsColumn { + ACCOUNT_ID + CACHED_HISTOGRAM + CACHED_REQUESTS_COUNT + CACHE_TTL_HISTOGRAM + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + FORBIDDEN_OPERATION_COUNT + FROM_ENGINEPROXY + QUERY_ID + QUERY_NAME + REGISTERED_OPERATION_COUNT + REQUESTS_WITH_ERRORS_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP + UNCACHED_HISTOGRAM + UNCACHED_REQUESTS_COUNT +} + +type QueryStatsDimensions { + accountId: ID + clientName: String + clientReferenceId: ID + clientVersion: String + fromEngineproxy: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String +} + +""" +Filter for data in QueryStats. Fields with dimension names represent equality +checks. All fields are implicitly ANDed together. +""" +input QueryStatsFilter { + """ + Selects rows whose accountId dimension equals the given value if not null. To + query for the null value, use {in: {accountId: [null]}} instead. + """ + accountId: ID + and: [QueryStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose fromEngineproxy dimension equals the given value if not + null. To query for the null value, use {in: {fromEngineproxy: [null]}} instead. + """ + fromEngineproxy: String + in: QueryStatsFilterIn + not: QueryStatsFilter + or: [QueryStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in QueryStats. Fields match if the corresponding dimension's +value is in the given list. All fields are implicitly ANDed together. +""" +input QueryStatsFilterIn { + """ + Selects rows whose accountId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + accountId: [ID] + + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose fromEngineproxy dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + fromEngineproxy: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type QueryStatsMetrics { + cacheTtlHistogram: DurationHistogram! + cachedHistogram: DurationHistogram! + cachedRequestsCount: Long! + forbiddenOperationCount: Long! + registeredOperationCount: Long! + requestsWithErrorsCount: Long! + totalLatencyHistogram: DurationHistogram! + totalRequestCount: Long! + uncachedHistogram: DurationHistogram! + uncachedRequestsCount: Long! +} + +input QueryStatsOrderBySpec { + column: QueryStatsColumn! + direction: Ordering! +} + +type QueryStatsRecord { + """Dimensions of QueryStats that can be grouped by.""" + groupBy: QueryStatsDimensions! + + """Metrics of QueryStats that can be aggregated over.""" + metrics: QueryStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Query Trigger""" +type QueryTrigger { + channels: [Channel!] + comparisonOperator: ComparisonOperator! + enabled: Boolean + excludedOperationNames: [String!]! + id: ID! + metric: QueryTriggerMetric! + operationNames: [String!]! + percentile: Float + scope: QueryTriggerScope! + serviceId: String! + state: QueryTriggerState! + threshold: Float! + variant: String + window: QueryTriggerWindow! +} + +"""Query trigger""" +input QueryTriggerInput { + channelIds: [String!] + comparisonOperator: ComparisonOperator! + enabled: Boolean + excludedOperationNames: [String!] + metric: QueryTriggerMetric! + operationNames: [String!] + percentile: Float + scope: QueryTriggerScope + threshold: Float! + variant: String + window: QueryTriggerWindow! +} + +enum QueryTriggerMetric { + """ + Number of requests within the window that resulted in an error. Ignores `percentile`. + """ + ERROR_COUNT + + """ + Number of error requests divided by total number of requests. Ignores `percentile`. + """ + ERROR_PERCENTAGE + + """Number of requests within the window. Ignores `percentile`.""" + REQUEST_COUNT + + """Request latency in ms. Requires `percentile`.""" + REQUEST_SERVICE_TIME +} + +enum QueryTriggerScope { + ALL + ANY + UNRECOGNIZED +} + +"""Query trigger state""" +type QueryTriggerState { + evaluatedAt: Timestamp! + lastTriggeredAt: Timestamp + operations: [QueryTriggerStateOperation!]! + triggered: Boolean! +} + +type QueryTriggerStateOperation { + count: Long! + operation: String! + triggered: Boolean! + value: Float! +} + +enum QueryTriggerWindow { + FIFTEEN_MINUTES + FIVE_MINUTES + ONE_MINUTE + UNRECOGNIZED +} + +input RegisteredClientIdentityInput { + identifier: String! + name: String! + version: String +} + +type RegisteredOperation { + signature: ID! +} + +input RegisteredOperationInput { + signature: ID! + document: String + metadata: RegisteredOperationMetadataInput +} + +input RegisteredOperationMetadataInput { + """This will be used to link existing records in Engine to a new ID.""" + engineSignature: String +} + +type RegisterOperationsMutationResponse { + registrationSuccess: Boolean! + newOperations: [RegisteredOperation!] + invalidOperations: [InvalidOperation!] +} + +type RegistryApiKey { + keyName: String + token: String! +} + +type RegistrySubscription { + channel: Channel! + createdAt: Timestamp! + id: ID! + lastUpdatedAt: Timestamp! + options: SubscriptionOptions! + variant: String! +} + +type ReportServerInfoError implements ReportServerInfoResult { + code: ReportServerInfoErrorCode! + inSeconds: Int! + message: String! + withExecutableSchema: Boolean! +} + +enum ReportServerInfoErrorCode { + BOOT_ID_IS_NOT_VALID_UUID + BOOT_ID_IS_REQUIRED + EXECUTABLE_SCHEMA_ID_IS_NOT_SCHEMA_SHA256 + EXECUTABLE_SCHEMA_ID_IS_REQUIRED + EXECUTABLE_SCHEMA_ID_IS_TOO_LONG + GRAPH_VARIANT_DOES_NOT_MATCH_REGEX + GRAPH_VARIANT_IS_REQUIRED + LIBRARY_VERSION_IS_TOO_LONG + PLATFORM_IS_TOO_LONG + RUNTIME_VERSION_IS_TOO_LONG + SCHEMA_IS_NOT_PARSABLE + SCHEMA_IS_NOT_VALID + SERVER_ID_IS_TOO_LONG + USER_VERSION_IS_TOO_LONG +} + +type ReportServerInfoResponse implements ReportServerInfoResult { + inSeconds: Int! + withExecutableSchema: Boolean! +} + +interface ReportServerInfoResult { + inSeconds: Int! + withExecutableSchema: Boolean! +} + +enum Resolution { + R15M + R1D + R1H + R1M + R5M + R6H +} + +enum ResponseHints { + NONE + SAMPLE_RESPONSES + TIMINGS +} + +type RoleOverride { + graph: Service! + lastUpdatedAt: Timestamp! + role: UserPermission! + user: User! +} + +type ScheduledSummary { + channel: Channel + enabled: Boolean! + id: ID! + tag: String @deprecated(reason: "Use variant") + timezone: String! + variant: String +} + +type Schema { + hash: ID! + createdAt: Timestamp! + introspection: IntrospectionSchema! + gitContext: GitContext + + """ + The number of fields; this includes user defined fields only, excluding built-in types and fields + """ + fieldCount: Int! + + """ + The number of types; this includes user defined types only, excluding built-in types + """ + typeCount: Int! + document: GraphQLDocument! +} + +type SchemaCheck { + id: ID! + checkedSchema: Schema! + diff: SchemaDiff! + gitContext: GitContext + checkedAt: Timestamp! + compositionResult: CompositionResult + + """Checks created by re-running this check, most recent first.""" + reruns(limit: Int! = 20): [SchemaCheck!] + + """If this check was created by re-running, which check re-ran.""" + rerunOf: SchemaCheck + + """ + Other checks that have run against the same branch / implementing service, most recent first. + """ + relatedChecks(limit: Int! = 20): [SchemaCheck!] +} + +type SchemaCheckMutation { + """ + Re-run a check using the current configuration. A new check is created and returned. + """ + rerun: SchemaCheckRerunResult +} + +type SchemaCheckRerunResult { + """Schema check that was rerun.""" + source: SchemaCheck + + """Schema check created by re-running.""" + result: SchemaCheck +} + +""" +Represents an error from running schema composition on a list of service definitions. +""" +type SchemaCompositionError { + message: String! + locations: [SourceLocation]! +} + +type SchemaDiff { + type: ChangeType! @deprecated(reason: "use severity instead") + + """ + Indication of the success of the change, either failure, warning, or notice. + """ + severity: ChangeSeverity! + + """List of schema changes with associated affected clients and operations""" + changes: [Change!]! + + """Summary/counts for all changes in diff""" + changeSummary: ChangeSummary! + + """Operations affected by all changes in diff""" + affectedQueries: [AffectedQuery!] + + """Clients affected by all changes in diff""" + affectedClients: [AffectedClient!] @deprecated(reason: "Unsupported.") + + """Number of operations that were validated during schema diff""" + numberOfCheckedOperations: Int + + """Configuration of validation""" + validationConfig: SchemaDiffValidationConfig + + """The tag against which this diff was created""" + tag: String +} + +type SchemaDiffValidationConfig { + """ + delta in seconds from current time that determines the start of the window + for reported metrics included in a schema diff. A day window from the present + day would have a `from` value of -86400. In rare cases, this could be an ISO + timestamp if the user passed one in on diff creation + """ + from: Timestamp + + """ + delta in seconds from current time that determines the end of the + window for reported metrics included in a schema diff. A day window + from the present day would have a `to` value of -0. In rare + cases, this could be an ISO timestamp if the user passed one in on diff + creation + """ + to: Timestamp + + """ + Minimum number of requests within the window for a query to be considered. + """ + queryCountThreshold: Int + + """ + Number of requests within the window for a query to be considered, relative to + total request count. Expected values are between 0 and 0.05 (minimum 5% of + total request volume) + """ + queryCountThresholdPercentage: Float + + """Clients to ignore during validation.""" + excludedClients: [ClientInfoFilterOutput!] + + """Operation IDs to ignore during validation.""" + ignoredOperations: [ID!] + + """Variants to include during validation.""" + includedVariants: [String!] +} + +type SchemaTag { + """ + The identifier for this particular schema tag, which may be either a particular + run of a check or a specific publish. This ID can be used alongside `schemaTagByID` + in order to look up a particular entry. + """ + id: ID! + + """The graph variant this schema tag belongs to.""" + variant: GraphVariant! + tag: String! @deprecated(reason: "Please use variant { name } instead") + schema: Schema! + + """ + The composition result that corresponds to this schema repo tag, if it exists. + """ + compositionResult: CompositionResult + + """ + Indicates the schemaTag of the schema's original upload, null if this is the + first upload of the schema. + """ + reversionFrom: SchemaTag + createdAt: Timestamp! + + """ + Indicates this schema is "published" meaning that our users correspond this schema + with a long-running or permanent initiative. Published schemas appear in the UI + when exploring a service's schemas, and typically refer to either active environments + with metrics (e.g. "staging") or git branches that are constantly used as a base + (e.g. "main"). If this field is not found, the schema is "private" to Engine + and is uploaded but not promoted to published yet. The other benefit is this makes + for nice UX around publishing events + """ + publishedAt: Timestamp! + + """ + The Identity that published this schema and their client info, or null if this isn't + a publish. Sub-fields may be null if they weren't recorded. + """ + publishedBy: IdentityAndClientInfo + + """ + List of previously uploaded SchemaTags under the same tag name, starting with + the selected published schema record. Sorted in reverse chronological order + by creation date (newest publish first). + + Note: This does not include the history of checked schemas + """ + history(limit: Int! = 3, offset: Int = 0): [SchemaTag!]! + + """ + Number of tagged schemas created under the same tag name. + Also represents the maximum size of the history's limit argument. + """ + historyLength: Int! + + """ + Number of schemas tagged prior to this one under the same tag name, its position + in the tag history. + """ + historyOrder: Int! + diffToPrevious: SchemaDiff + gitContext: GitContext + slackNotificationBody(graphDisplayName: String!): String +} + +""" +How many seats of the given types does an organization have (regardless of plan type)? +""" +type Seats { + """How many members that are BILLING_MANAGERs in this organization.""" + free: Int! + + """How many members that are not BILLING_MANAGERs in this organization.""" + fullPrice: Int! +} + +type SemanticChange { + """Semantic metadata about the type of change""" + definition: ChangeDefinition! + + """Top level node affected by the change""" + parentNode: NamedIntrospectionType + + """ + Node related to the top level node that was changed, such as a field in an object, + a value in an enum or the object of an interface + """ + childNode: NamedIntrospectionValue + + """Target arg of change made.""" + argNode: NamedIntrospectionArg +} + +type Service implements Identity + @owner(graph: "kotlin") + @key(fields: "{ id }", graph: "kotlin") + @key(fields: "{ id }", graph: "registry") +{ + account: Account + accountId: ID + apiKeys: [ApiKey!] + asActor: Actor! + + """ + Get an URL to which an avatar image can be uploaded. Client uploads by sending a PUT request + with the image data to MediaUploadInfo.url. Client SHOULD set the "Content-Type" header to the + browser-inferred MIME type, and SHOULD set the "x-apollo-content-filename" header to the + filename, if such information is available. Client MUST set the "x-apollo-csrf-token" header to + MediaUploadInfo.csrfToken. + """ + avatarUpload: AvatarUploadResult + + """ + Get an image URL for the service's avatar. Note that CORS is not enabled for these URLs. The size + argument is used for bandwidth reduction, and should be the size of the image as displayed in the + application. Apollo's media server will downscale larger images to at least the requested size, + but this will not happen for third-party media servers. + """ + avatarUrl(size: Int! = 40): String + + """Get available notification endpoints""" + channels(channelIds: [ID!]): [Channel!] + createdAt: Timestamp! + datadogMetricsConfig: DatadogMetricsConfig + deletedAt: Timestamp + devGraphOwner: User + firstReportedAt: Timestamp + + """ + When this is true, this graph will be hidden from non-admin members of the org who haven't been explicitly assigned a + role on this graph. + """ + hiddenFromUninvitedNonAdminAccountMembers: Boolean! + id: ID! + lastReportedAt(graphVariant: String): Timestamp + + """Current identity, null if not authenticated.""" + me: Identity + name: String! @deprecated(reason: "Use Service.title") + + """ + Get query triggers for a given variant. If variant is null all the triggers for this service will be gotten. + """ + queryTriggers(graphVariant: String, operationNames: [String!]): [QueryTrigger!] + + """Subscription to registry updates for this subscription ID""" + registrySubscription(id: ID!): RegistrySubscription + + """ + Subscriptions to registry updates for this service. If no graphVariant is + passed, subscriptions across ALL variants will be returned. + """ + registrySubscriptions(graphVariant: String): [RegistrySubscription!] + + """ + Whether registry subscriptions (with any options) are enabled. If variant is + not passed, returns true if configuration is present for any variant + """ + registrySubscriptionsEnabled(graphVariant: String): Boolean! + reportingEnabled: Boolean! + + """ + The list of members that can access this graph, accounting for graph role overrides + """ + roleOverrides: [RoleOverride!] + + """ + Which permissions the current user has for interacting with this service + """ + roles: ServiceRoles + scheduledSummaries: [ScheduledSummary!]! + stats( + from: Timestamp! + + """ + Granularity of buckets. Defaults to the entire range (aggregate all data into a single durationBucket) when null. + """ + resolution: Resolution + + """Defaults to the current time when null.""" + to: Timestamp + ): ServiceStatsWindow! + title: String! + trace(id: ID!): Trace + traceStorageEnabled: Boolean! + + """The list of variants that exist for this graph""" + variants: [GraphVariant!]! + operation(id: ID!): Operation @resolve(graph: "registry") + + """Get a schema by hash OR current tag""" + schema(hash: ID, tag: String): Schema @resolve(graph: "registry") @requires(fields: "{ roles { canQuerySchemas canQueryImplementingServices } }") + + """ + Get schema tags, with optional filtering to a set of tags. Always sorted by creation + date in reverse chronological order. + """ + schemaTags(tags: [String!]): [SchemaTag!] @resolve(graph: "registry") @requires(fields: "{ roles { canQuerySchemas canQueryImplementingServices } }") + + """ + Get the schema tag created at or most recently before a specified date. Returns + latest tag by default. + """ + schemaTag(tag: String!, createdAt: Timestamp): SchemaTag @resolve(graph: "registry") @requires(fields: "{ roles { canQuerySchemas canQueryImplementingServices } }") + schemaTagById(id: ID!): SchemaTag @resolve(graph: "registry") @requires(fields: "{ roles { canQuerySchemas canQueryImplementingServices } }") + + """ + List of implementing services that comprise a graph. A non-federated graph should have a single implementing service. + Set includeDeleted to see deleted implementing services + """ + implementingServices(graphVariant: String!, includeDeleted: Boolean): GraphImplementors @resolve(graph: "registry") @requires(fields: "{ roles { canQuerySchemas canQueryImplementingServices canQueryDeletedImplementingServices } }") + + """ + This returns the composition result that was most recently published to the graph. + Only identities that canQuerySchemas and canQueryImplementingServices have access + to this field + """ + mostRecentCompositionPublish(graphVariant: String!): CompositionPublishResult @resolve(graph: "registry") @requires(fields: "{ id roles { canQuerySchemas canQueryImplementingServices } }") + + """ + Given a graphCompositionID, return the results of composition. This can represent either a validation or a publish. + """ + compositionResultById(id: ID!): CompositionResult @resolve(graph: "registry") @requires(fields: "{ id roles { canQuerySchemas canQueryImplementingServices } }") + + """ + A particular variant (sometimes called "tag") of the graph, often representing + a live traffic environment (such as "prod"). Each variant can represent a + specific URL or destination to query at, analytics, and its own schema history. + """ + variant(name: String!): GraphVariant @resolve(graph: "registry") + + """Get check configuration for this graph.""" + checkConfiguration: CheckConfiguration @resolve(graph: "registry") @requires(fields: "{ id roles { canQueryCheckConfiguration } account { currentPlan { capabilities { schemaValidation } } } }") + + """ + Gets the operations and their approved changes for this graph, checkID, and operationID. + """ + operationsAcceptedChanges(checkID: ID!, operationID: String!): [OperationAcceptedChange!]! @resolve(graph: "registry") @requires(fields: "{ id roles { canQueryCheckConfiguration } account { currentPlan { capabilities { schemaValidation } } } }") + + """Get a single schema check by its ID""" + check(id: ID!): SchemaCheck @resolve(graph: "registry") @requires(fields: "{ id roles { canCheckSchemas } account { currentPlan { capabilities { schemaValidation } } } }") +} + +"""Columns of ServiceEdgeServerInfos.""" +enum ServiceEdgeServerInfosColumn { + BOOT_ID + EXECUTABLE_SCHEMA_ID + LIBRARY_VERSION + PLATFORM + RUNTIME_VERSION + SCHEMA_TAG + SERVER_ID + TIMESTAMP + USER_VERSION +} + +type ServiceEdgeServerInfosDimensions { + bootId: ID + executableSchemaId: ID + libraryVersion: String + platform: String + runtimeVersion: String + schemaTag: String + serverId: ID + userVersion: String +} + +""" +Filter for data in ServiceEdgeServerInfos. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input ServiceEdgeServerInfosFilter { + and: [ServiceEdgeServerInfosFilter!] + + """ + Selects rows whose bootId dimension equals the given value if not null. To + query for the null value, use {in: {bootId: [null]}} instead. + """ + bootId: ID + + """ + Selects rows whose executableSchemaId dimension equals the given value if not + null. To query for the null value, use {in: {executableSchemaId: [null]}} instead. + """ + executableSchemaId: ID + in: ServiceEdgeServerInfosFilterIn + + """ + Selects rows whose libraryVersion dimension equals the given value if not + null. To query for the null value, use {in: {libraryVersion: [null]}} instead. + """ + libraryVersion: String + not: ServiceEdgeServerInfosFilter + or: [ServiceEdgeServerInfosFilter!] + + """ + Selects rows whose platform dimension equals the given value if not null. To + query for the null value, use {in: {platform: [null]}} instead. + """ + platform: String + + """ + Selects rows whose runtimeVersion dimension equals the given value if not + null. To query for the null value, use {in: {runtimeVersion: [null]}} instead. + """ + runtimeVersion: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serverId dimension equals the given value if not null. To + query for the null value, use {in: {serverId: [null]}} instead. + """ + serverId: ID + + """ + Selects rows whose userVersion dimension equals the given value if not null. + To query for the null value, use {in: {userVersion: [null]}} instead. + """ + userVersion: String +} + +""" +Filter for data in ServiceEdgeServerInfos. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceEdgeServerInfosFilterIn { + """ + Selects rows whose bootId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + bootId: [ID] + + """ + Selects rows whose executableSchemaId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + executableSchemaId: [ID] + + """ + Selects rows whose libraryVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + libraryVersion: [String] + + """ + Selects rows whose platform dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + platform: [String] + + """ + Selects rows whose runtimeVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + runtimeVersion: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serverId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serverId: [ID] + + """ + Selects rows whose userVersion dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + userVersion: [String] +} + +input ServiceEdgeServerInfosOrderBySpec { + column: ServiceEdgeServerInfosColumn! + direction: Ordering! +} + +type ServiceEdgeServerInfosRecord { + """Dimensions of ServiceEdgeServerInfos that can be grouped by.""" + groupBy: ServiceEdgeServerInfosDimensions! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of ServiceEnumStats.""" +enum ServiceEnumStatsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ENUM_TYPE + ENUM_VALUE + QUERY_ID + QUERY_NAME + REQUEST_COUNT + RESPONSE_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_VERSION + TIMESTAMP +} + +type ServiceEnumStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + enumType: String + enumValue: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceVersion: String +} + +""" +Filter for data in ServiceEnumStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input ServiceEnumStatsFilter { + and: [ServiceEnumStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose enumType dimension equals the given value if not null. To + query for the null value, use {in: {enumType: [null]}} instead. + """ + enumType: String + + """ + Selects rows whose enumValue dimension equals the given value if not null. To + query for the null value, use {in: {enumValue: [null]}} instead. + """ + enumValue: String + in: ServiceEnumStatsFilterIn + not: ServiceEnumStatsFilter + or: [ServiceEnumStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in ServiceEnumStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceEnumStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose enumType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + enumType: [String] + + """ + Selects rows whose enumValue dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + enumValue: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type ServiceEnumStatsMetrics { + requestCount: Long! + responseCount: Long! +} + +input ServiceEnumStatsOrderBySpec { + column: ServiceEnumStatsColumn! + direction: Ordering! +} + +type ServiceEnumStatsRecord { + """Dimensions of ServiceEnumStats that can be grouped by.""" + groupBy: ServiceEnumStatsDimensions! + + """Metrics of ServiceEnumStats that can be aggregated over.""" + metrics: ServiceEnumStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of ServiceErrorStats.""" +enum ServiceErrorStatsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ERRORS_COUNT + PATH + QUERY_ID + QUERY_NAME + REQUESTS_WITH_ERRORS_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_VERSION + TIMESTAMP +} + +type ServiceErrorStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + path: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceVersion: String +} + +""" +Filter for data in ServiceErrorStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input ServiceErrorStatsFilter { + and: [ServiceErrorStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + in: ServiceErrorStatsFilterIn + not: ServiceErrorStatsFilter + or: [ServiceErrorStatsFilter!] + + """ + Selects rows whose path dimension equals the given value if not null. To query + for the null value, use {in: {path: [null]}} instead. + """ + path: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in ServiceErrorStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceErrorStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose path dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + path: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type ServiceErrorStatsMetrics { + errorsCount: Long! + requestsWithErrorsCount: Long! +} + +input ServiceErrorStatsOrderBySpec { + column: ServiceErrorStatsColumn! + direction: Ordering! +} + +type ServiceErrorStatsRecord { + """Dimensions of ServiceErrorStats that can be grouped by.""" + groupBy: ServiceErrorStatsDimensions! + + """Metrics of ServiceErrorStats that can be aggregated over.""" + metrics: ServiceErrorStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of ServiceFieldStats.""" +enum ServiceFieldStatsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + ERRORS_COUNT + FIELD + FIELD_HISTOGRAM + QUERY_ID + QUERY_NAME + REQUEST_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_VERSION + TIMESTAMP +} + +type ServiceFieldStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + field: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceVersion: String +} + +""" +Filter for data in ServiceFieldStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input ServiceFieldStatsFilter { + and: [ServiceFieldStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose field dimension equals the given value if not null. To + query for the null value, use {in: {field: [null]}} instead. + """ + field: String + in: ServiceFieldStatsFilterIn + not: ServiceFieldStatsFilter + or: [ServiceFieldStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in ServiceFieldStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceFieldStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose field dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + field: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type ServiceFieldStatsMetrics { + errorsCount: Long! + fieldHistogram: DurationHistogram! + requestCount: Long! +} + +input ServiceFieldStatsOrderBySpec { + column: ServiceFieldStatsColumn! + direction: Ordering! +} + +type ServiceFieldStatsRecord { + """Dimensions of ServiceFieldStats that can be grouped by.""" + groupBy: ServiceFieldStatsDimensions! + + """Metrics of ServiceFieldStats that can be aggregated over.""" + metrics: ServiceFieldStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of ServiceInputStats.""" +enum ServiceInputStatsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + FIELD_NAME + FIELD_TYPE + PARENT_TYPE + QUERY_ID + QUERY_NAME + REQUEST_COUNT + REQUEST_COUNT_NULL + REQUEST_COUNT_UNDEFINED + SCHEMA_HASH + SCHEMA_TAG + SERVICE_VERSION + TIMESTAMP +} + +type ServiceInputStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + fieldName: String + fieldType: String + parentType: String + queryId: ID + queryName: String + schemaHash: String + schemaTag: String + serviceVersion: String +} + +""" +Filter for data in ServiceInputStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input ServiceInputStatsFilter { + and: [ServiceInputStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose fieldName dimension equals the given value if not null. To + query for the null value, use {in: {fieldName: [null]}} instead. + """ + fieldName: String + + """ + Selects rows whose fieldType dimension equals the given value if not null. To + query for the null value, use {in: {fieldType: [null]}} instead. + """ + fieldType: String + in: ServiceInputStatsFilterIn + not: ServiceInputStatsFilter + or: [ServiceInputStatsFilter!] + + """ + Selects rows whose parentType dimension equals the given value if not null. To + query for the null value, use {in: {parentType: [null]}} instead. + """ + parentType: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in ServiceInputStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceInputStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose fieldName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + fieldName: [String] + + """ + Selects rows whose fieldType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + fieldType: [String] + + """ + Selects rows whose parentType dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + parentType: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type ServiceInputStatsMetrics { + requestCount: Long! + requestCountNull: Long! + requestCountUndefined: Long! +} + +input ServiceInputStatsOrderBySpec { + column: ServiceInputStatsColumn! + direction: Ordering! +} + +type ServiceInputStatsRecord { + """Dimensions of ServiceInputStats that can be grouped by.""" + groupBy: ServiceInputStatsDimensions! + + """Metrics of ServiceInputStats that can be aggregated over.""" + metrics: ServiceInputStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +type ServiceMutation + @owner(graph: "kotlin") + @key(fields: "{ service { id } }", graph: "kotlin") + @key(fields: "{ service { id } }", graph: "registry") +{ + """ + Soft delete a graph. Data associated with the graph is not permanently deleted; Apollo support can undo. + """ + delete: Void + + """ + Delete the service's avatar. Requires Service.roles.canUpdateAvatar to be true. + """ + deleteAvatar: AvatarDeleteError + + """Delete an existing channel""" + deleteChannel(id: ID!): Boolean! + + """Delete an existing query trigger""" + deleteQueryTrigger(id: ID!): Boolean! + + """ + Deletes this service's current subscriptions specific to the ID, returns true if it existed + """ + deleteRegistrySubscription(id: ID!): Boolean! + + """ + Deletes this service's current registry subscription(s) specific to its graph variant, + returns a list of subscription IDs that were deleted. + """ + deleteRegistrySubscriptions(variant: String!): [ID!]! + deleteScheduledSummary(id: ID!): Boolean! + + """ + Given a UTC timestamp, delete all traces associated with this Service, on that + corresponding day. If a timestamp to is provided, deletes all days inclusive. + """ + deleteTraces(from: Timestamp!, to: Timestamp): Void + disableDatadogForwardingLegacyMetricNames: Service + + """ + Hard delete a graph and all data associated with it. Its ID cannot be reused. + """ + hardDelete: Void + id: ID! @deprecated(reason: "Use service.id") + newKey(keyName: String): ApiKey + + """Adds an override to the given users permission for this graph""" + overrideUserPermission(permission: UserPermission, userID: ID!): Service + removeKey( + """API key""" + key: String + + """Deprecated, use the 'key' argument instead""" + token: String + ): Void + rename(to: String!): Service @deprecated(reason: "Use updateTitle mutation") + renameKey( + key: String + newKeyName: String + + """Deprecated, use the 'key' argument instead""" + token: String + ): ApiKey + + """ + Report information about a running GraphQL server instance, used for automatic + schema reporting. This can optionally include an `executableSchema`, in the + form of a GraphQL document, and should only do so if requested explicitly in + response to a previous report that designates `withSchema: true` + """ + reportServerInfo( + """ + Only sent if previously requested i.e. received ReportServerInfoResult with + withExecutableSchema = true. An executable schema is a schema document that + describes the full GraphQL schema that an external client could execute + queries against. This must be a valid GraphQL schema document, as per the + GraphQL specification: https://spec.graphql.org/ + """ + executableSchema: String + + """ + Information about the edge server, see descriptions for individual fields. + """ + info: EdgeServerInfo! + ): ReportServerInfoResult + service: Service! + + """Test Slack notification channel""" + testSlackChannel(id: ID!, notification: SlackNotificationInput!): Void + transfer(to: String!): Service + undelete: Service + updateDatadogMetricsConfig(apiKey: String, apiRegion: DatadogApiRegion, enabled: Boolean): DatadogMetricsConfig + + """Update hiddenFromUninvitedNonAdminAccountMembers""" + updateHiddenFromUninvitedNonAdminAccountMembers(hiddenFromUninvitedNonAdminAccountMembers: Boolean!): Service + updateTitle(title: String!): Service + + """Create/update PagerDuty notification channel""" + upsertPagerDutyChannel(channel: PagerDutyChannelInput!, id: ID): PagerDutyChannel + upsertQueryTrigger(id: ID, trigger: QueryTriggerInput!): QueryTrigger + + """Create or update a subscription for a service.""" + upsertRegistrySubscription( + """ID of Slack channel for registry notification.""" + channelID: ID + + """ID of registry subscription""" + id: ID + + """Set of options/customization for notification.""" + options: SubscriptionOptionsInput + + """Variant to notify on.""" + variant: String + ): RegistrySubscription! + upsertScheduledSummary( + channelID: ID + enabled: Boolean + id: ID + + """Deprecated, use the 'variant' argument instead""" + tag: String + timezone: String + variant: String + ): ScheduledSummary + + """Create/update Slack notification channel""" + upsertSlackChannel(channel: SlackChannelInput!, id: ID): SlackChannel + + """ + Create a new API key and also write the storage secret for that API key. + The storage secret allows users to fetch files from GCS like operation manifests and composition artifacts for federation. + Storage secrets need to be accessible via a service's API key, so we need to + couple the creation of these files with API key creation + """ + createApiKeyAndWriteStorageSecret(keyName: String): RegistryApiKey @deprecated(reason: "use newKey instead") @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { maxRangeInDays } } } roles { canManageKeys } } }") + + """Make changes to a graph variant.""" + variant(name: String!): GraphVariantMutation @resolve(graph: "registry") + validateOperations(operations: [OperationDocumentInput!]!, tag: String = "current", gitContext: GitContextInput): ValidateOperationsResult! @resolve(graph: "registry") + registerOperationsWithResponse( + clientIdentity: RegisteredClientIdentityInput + gitContext: GitContextInput + operations: [RegisteredOperationInput!]! + manifestVersion: Int + + """ + Specifies which variant of a graph these operations belong to. + Formerly known as "tag" + Defaults to "current" + """ + graphVariant: String! = "current" + ): RegisterOperationsMutationResponse @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { operationRegistry } } } roles { canRegisterOperations } } }") + uploadSchema(schema: IntrospectionSchemaInput, tag: String!, gitContext: GitContextInput, historicParameters: HistoricQueryParameters, overrideComposedSchema: Boolean! = false, schemaDocument: String, errorOnBadRequest: Boolean! = true): UploadSchemaMutationResponse @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } me { asActor { type actorId } } roles { canPushSchemas } registrySubscriptionsEnabled } }") + + """ + Store a given introspection schema. This schema will be attached to the graph + but not be associated with any variant. On success, returns the schema hash. + """ + storeIntrospectionSchema(introspectionSchema: IntrospectionSchemaInput!): StoreSchemaResponseOrError! @resolve(graph: "registry") @requires(fields: "{ service { id roles { canPushSchemas } } }") + + """ + Store a given schema document. This schema will be attached to the graph but + not be associated with any variant. On success, returns the schema hash. + """ + storeSchemaDocument(schemaDocument: String!): StoreSchemaResponseOrError! @resolve(graph: "registry") @requires(fields: "{ service { id roles { canPushSchemas } } }") + + """ + Promote the schema with the given SHA-256 hash to active for the given variant/tag. + """ + promoteSchema(sha256: SHA256!, graphVariant: String!, historicParameters: HistoricQueryParameters, overrideComposedSchema: Boolean! = false): PromoteSchemaResponseOrError! @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } me { asActor { type actorId } } roles { canPushSchemas } registrySubscriptionsEnabled } }") + deleteSchema(schemaHash: String!): String! @resolve(graph: "registry") + + """ + Checks a proposed schema against the schema that has been published to + a particular tag, using metrics that have been published to the base tag. + Callers can set the historicParameters directly, which will be used if + provided. If useMaximumRetention is provided, but historicParameters is not, + then validation will use the maximum retention the graph has access to. + If neither historicParameters nor useMaximumRetention is provided, the + default time range of one week (7 days) will be used. + """ + checkSchema( + """ + Only one of proposedSchema, proposedSchemaDocument, and proposedSchemaHash + may be specified + """ + proposedSchema: IntrospectionSchemaInput + proposedSchemaDocument: String + proposedSchemaHash: String + baseSchemaTag: String = "current" + gitContext: GitContextInput + historicParameters: HistoricQueryParameters + useMaximumRetention: Boolean + + """Deprecated and ignored.""" + frontend: String + ): CheckSchemaResult! @resolve(graph: "registry") @requires(fields: "{ service { me { asActor { type actorId } } account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } roles { canCheckSchemas } } }") + + """Make changes to a schema check.""" + check(id: ID!): SchemaCheckMutation @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } roles { canCheckSchemas } } }") + deleteSchemaTag(tag: String!): DeleteSchemaTagResult! @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { maxRangeInDays } } } roles { canDeleteSchemas } registrySubscriptionsEnabled } }") + upsertImplementingServiceAndTriggerComposition(graphVariant: String!, name: String!, url: String!, revision: String!, activePartialSchema: PartialSchemaInput!): CompositionAndUpsertResult! @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } me { asActor { type actorId } } roles { canPushSchemas } registrySubscriptionsEnabled } }") + + """ + This mutation will not result in any changes to the implementing service + Run composition with the Implementing Service's partial schema replaced with the one provided + in the mutation's input. Store the composed schema, return the hash of the composed schema, + and any warnings and errors pertaining to composition. + This mutation will not run validation against operations. + """ + validatePartialSchemaOfImplementingServiceAgainstGraph(graphVariant: String!, implementingServiceName: String!, partialSchema: PartialSchemaInput!): CompositionValidationResult! @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { maxRangeInDays } } } roles { canCheckSchemas } } }") + removeImplementingServiceAndTriggerComposition( + graphVariant: String! + name: String! + + """ + Do not remove the service, but recompose without it and report any errors. + """ + dryRun: Boolean! = false + ): CompositionAndRemoveResult! @resolve(graph: "registry") @requires(fields: "{ service { account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } me { asActor { type actorId } } roles { canPushSchemas } registrySubscriptionsEnabled } }") + + """ + Compose an implementing service's partial schema, diff the composed schema, validate traffic against that schema, + and store the result so the details can be viewed by users in the UI. + This mutation will not mark the schema as "published". + """ + checkPartialSchema( + """Specifies which variant of a graph this mutation operates on.""" + graphVariant: String! + + """ + Name of the implementing service to validate the partial schema against + """ + implementingServiceName: String! + + """The partial schema to validate against an implementing service""" + partialSchema: PartialSchemaInput! + gitContext: GitContextInput + historicParameters: HistoricQueryParameters + + """Deprecated and ignored.""" + frontend: String + + """ + Whether to use the maximum retention for historical validation. This only takes + effect if historicParameters is null. + """ + useMaximumRetention: Boolean + ): CheckPartialSchemaResult! @resolve(graph: "registry") @requires(fields: "{ service { id me { asActor { type actorId } } account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } roles { canCheckSchemas } } }") + + """Update schema check configuration for a graph.""" + updateCheckConfiguration( + """Operations to ignore during validation.""" + excludedOperations: [ExcludedOperationInput!] + + """Clients to ignore during validation.""" + excludedClients: [ClientFilterInput!] + + """Variant overrides for validation.""" + includedVariants: [String!] + + """ + Only check operations from the last seconds. The default is 7 days (604,800 seconds). + """ + timeRangeSeconds: Long + + """ + Minimum number of requests within the window for a query to be considered. + """ + operationCountThreshold: Int + + """ + Number of requests within the window for a query to be considered, relative to + total request count. Expected values are between 0 and 0.05 (minimum 5% of + total request volume) + """ + operationCountThresholdPercentage: Float + + """Default configuration to include operations on the base variant.""" + includeBaseVariant: Boolean + ): CheckConfiguration! @resolve(graph: "registry") @requires(fields: "{ service { id me { asActor { type actorId } } account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } roles { canWriteCheckConfiguration } } }") + + """ + Mark the changeset that affects an operation in a given check instance as safe. + Note that only operations marked as behavior changes are allowed to be marked as safe. + """ + markChangesForOperationAsSafe( + """ID of the schema check.""" + checkID: ID! + + """ID of the operation to accept changes for.""" + operationID: ID! + ): MarkChangesForOperationAsSafeResult! @resolve(graph: "registry") @requires(fields: "{ service { id me { asActor { type actorId } } account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } roles { canWriteCheckConfiguration } } }") + + """Unmark changes for an operation as safe.""" + unmarkChangesForOperationAsSafe( + """ID of the schema check.""" + checkID: ID! + + """ID of the operation to unmark changes for.""" + operationID: ID! + ): MarkChangesForOperationAsSafeResult! @resolve(graph: "registry") @requires(fields: "{ service { id me { asActor { type actorId } } account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } roles { canWriteCheckConfiguration } } }") + + """ + Ignore an operation in future checks; + changes affecting it will be tracked, + but won't affect the outcome of the check. + Returns true if the operation is newly ignored, + false if it already was. + """ + ignoreOperationsInChecks(ids: [ID!]!): IgnoreOperationsInChecksResult @resolve(graph: "registry") @requires(fields: "{ service { id me { asActor { type actorId } } account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } roles { canWriteCheckConfiguration } } }") + + """ + Revert the effects of ignoreOperation. + Returns true if the operation is no longer ignored, + false if it wasn't. + """ + unignoreOperationsInChecks(ids: [ID!]!): UnignoreOperationsInChecksResult @resolve(graph: "registry") @requires(fields: "{ service { id me { asActor { type actorId } } account { currentPlan { capabilities { maxRangeInDays schemaValidation } } } roles { canWriteCheckConfiguration } } }") +} + +"""Columns of ServiceQueryStats.""" +enum ServiceQueryStatsColumn { + CACHED_HISTOGRAM + CACHED_REQUESTS_COUNT + CACHE_TTL_HISTOGRAM + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + FORBIDDEN_OPERATION_COUNT + FROM_ENGINEPROXY + QUERY_ID + QUERY_NAME + REGISTERED_OPERATION_COUNT + REQUESTS_WITH_ERRORS_COUNT + SCHEMA_HASH + SCHEMA_TAG + SERVICE_VERSION + TIMESTAMP + UNCACHED_HISTOGRAM + UNCACHED_REQUESTS_COUNT +} + +type ServiceQueryStatsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + fromEngineproxy: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceVersion: String +} + +""" +Filter for data in ServiceQueryStats. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input ServiceQueryStatsFilter { + and: [ServiceQueryStatsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose fromEngineproxy dimension equals the given value if not + null. To query for the null value, use {in: {fromEngineproxy: [null]}} instead. + """ + fromEngineproxy: String + in: ServiceQueryStatsFilterIn + not: ServiceQueryStatsFilter + or: [ServiceQueryStatsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String +} + +""" +Filter for data in ServiceQueryStats. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceQueryStatsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose fromEngineproxy dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + fromEngineproxy: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] +} + +type ServiceQueryStatsMetrics { + cacheTtlHistogram: DurationHistogram! + cachedHistogram: DurationHistogram! + cachedRequestsCount: Long! + forbiddenOperationCount: Long! + registeredOperationCount: Long! + requestsWithErrorsCount: Long! + totalLatencyHistogram: DurationHistogram! + totalRequestCount: Long! + uncachedHistogram: DurationHistogram! + uncachedRequestsCount: Long! +} + +input ServiceQueryStatsOrderBySpec { + column: ServiceQueryStatsColumn! + direction: Ordering! +} + +type ServiceQueryStatsRecord { + """Dimensions of ServiceQueryStats that can be grouped by.""" + groupBy: ServiceQueryStatsDimensions! + + """Metrics of ServiceQueryStats that can be aggregated over.""" + metrics: ServiceQueryStatsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +""" +A map from role (permission) String to boolean that the current user is allowed for the root service +""" +type ServiceRoles { + canCheckSchemas: Boolean! + canDelete: Boolean! + canDeleteSchemas: Boolean! + canManageAccess: Boolean! + canManageChannels: Boolean! + canManageDatadogMetricsConfig: Boolean! + canManageKeys: Boolean! + canManageQueryTriggers: Boolean! + canManageRegistrySubscription: Boolean! + canManageScheduledSummary: Boolean! + canManageVariants: Boolean! + canPushSchemas: Boolean! + canQueryChannels: Boolean! + canQueryCheckConfiguration: Boolean! + canQueryDatadogMetricsConfig: Boolean! + canQueryDeletedImplementingServices: Boolean! + canQueryImplementingServices: Boolean! + canQueryPrivateInfo: Boolean! + canQueryPublicInfo: Boolean! + canQueryRegistrySubscription: Boolean! + canQueryRoleOverrides: Boolean! + canQuerySchemas: Boolean! + canQueryTokens: Boolean! + canRegisterOperations: Boolean! + canRename: Boolean! @deprecated(reason: "Use canUpdateTitle") + canUndelete: Boolean! + canUpdateAvatar: Boolean! + canUpdateTitle: Boolean! + canVisualizeStats: Boolean! + canWriteCheckConfiguration: Boolean! + canWriteTraces: Boolean! +} + +"""A time window with a specified granularity over a given service.""" +type ServiceStatsWindow { + edgeServerInfos( + """Filter to select what rows to return.""" + filter: ServiceEdgeServerInfosFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ServiceEdgeServerInfos by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ServiceEdgeServerInfosOrderBySpec!] + ): [ServiceEdgeServerInfosRecord!]! + enumStats( + """Filter to select what rows to return.""" + filter: ServiceEnumStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ServiceEnumStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ServiceEnumStatsOrderBySpec!] + ): [ServiceEnumStatsRecord!]! + errorStats( + """Filter to select what rows to return.""" + filter: ServiceErrorStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ServiceErrorStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ServiceErrorStatsOrderBySpec!] + ): [ServiceErrorStatsRecord!]! + fieldStats( + """Filter to select what rows to return.""" + filter: ServiceFieldStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ServiceFieldStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ServiceFieldStatsOrderBySpec!] + ): [ServiceFieldStatsRecord!]! + inputStats( + """Filter to select what rows to return.""" + filter: ServiceInputStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ServiceInputStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ServiceInputStatsOrderBySpec!] + ): [ServiceInputStatsRecord!]! + queryStats( + """Filter to select what rows to return.""" + filter: ServiceQueryStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ServiceQueryStats by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ServiceQueryStatsOrderBySpec!] + ): [ServiceQueryStatsRecord!]! + + """From field rounded down to the nearest resolution.""" + roundedDownFrom: Timestamp! + + """To field rounded up to the nearest resolution.""" + roundedUpTo: Timestamp! + tracePathErrorsRefs( + """Filter to select what rows to return.""" + filter: ServiceTracePathErrorsRefsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ServiceTracePathErrorsRefs by. The earlier + an OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ServiceTracePathErrorsRefsOrderBySpec!] + ): [ServiceTracePathErrorsRefsRecord!]! + traceRefs( + """Filter to select what rows to return.""" + filter: ServiceTraceRefsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ServiceTraceRefs by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ServiceTraceRefsOrderBySpec!] + ): [ServiceTraceRefsRecord!]! +} + +"""Columns of ServiceTracePathErrorsRefs.""" +enum ServiceTracePathErrorsRefsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + DURATION_BUCKET + ERRORS_COUNT_IN_PATH + ERRORS_COUNT_IN_TRACE + ERROR_MESSAGE + PATH + QUERY_ID + QUERY_NAME + SCHEMA_HASH + SCHEMA_TAG + SERVICE_VERSION + TIMESTAMP + TRACE_HTTP_STATUS_CODE + TRACE_ID + TRACE_SIZE_BYTES + TRACE_STARTS_AT +} + +type ServiceTracePathErrorsRefsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + durationBucket: Int + errorMessage: String + path: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceVersion: String + traceHttpStatusCode: Int + traceId: ID + traceStartsAt: Timestamp +} + +""" +Filter for data in ServiceTracePathErrorsRefs. Fields with dimension names +represent equality checks. All fields are implicitly ANDed together. +""" +input ServiceTracePathErrorsRefsFilter { + and: [ServiceTracePathErrorsRefsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose durationBucket dimension equals the given value if not + null. To query for the null value, use {in: {durationBucket: [null]}} instead. + """ + durationBucket: Int + + """ + Selects rows whose errorMessage dimension equals the given value if not null. + To query for the null value, use {in: {errorMessage: [null]}} instead. + """ + errorMessage: String + in: ServiceTracePathErrorsRefsFilterIn + not: ServiceTracePathErrorsRefsFilter + or: [ServiceTracePathErrorsRefsFilter!] + + """ + Selects rows whose path dimension equals the given value if not null. To query + for the null value, use {in: {path: [null]}} instead. + """ + path: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String + + """ + Selects rows whose traceHttpStatusCode dimension equals the given value if not + null. To query for the null value, use {in: {traceHttpStatusCode: [null]}} instead. + """ + traceHttpStatusCode: Int + + """ + Selects rows whose traceId dimension equals the given value if not null. To + query for the null value, use {in: {traceId: [null]}} instead. + """ + traceId: ID +} + +""" +Filter for data in ServiceTracePathErrorsRefs. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceTracePathErrorsRefsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose durationBucket dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + durationBucket: [Int] + + """ + Selects rows whose errorMessage dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + errorMessage: [String] + + """ + Selects rows whose path dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + path: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] + + """ + Selects rows whose traceHttpStatusCode dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + traceHttpStatusCode: [Int] + + """ + Selects rows whose traceId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + traceId: [ID] +} + +type ServiceTracePathErrorsRefsMetrics { + errorsCountInPath: Long! + errorsCountInTrace: Long! + traceSizeBytes: Long! +} + +input ServiceTracePathErrorsRefsOrderBySpec { + column: ServiceTracePathErrorsRefsColumn! + direction: Ordering! +} + +type ServiceTracePathErrorsRefsRecord { + """Dimensions of ServiceTracePathErrorsRefs that can be grouped by.""" + groupBy: ServiceTracePathErrorsRefsDimensions! + + """Metrics of ServiceTracePathErrorsRefs that can be aggregated over.""" + metrics: ServiceTracePathErrorsRefsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of ServiceTraceRefs.""" +enum ServiceTraceRefsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + DURATION_BUCKET + DURATION_NS + QUERY_ID + QUERY_NAME + SCHEMA_HASH + SCHEMA_TAG + SERVICE_VERSION + TIMESTAMP + TRACE_ID + TRACE_SIZE_BYTES +} + +type ServiceTraceRefsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + durationBucket: Int + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceVersion: String + traceId: ID +} + +""" +Filter for data in ServiceTraceRefs. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input ServiceTraceRefsFilter { + and: [ServiceTraceRefsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose durationBucket dimension equals the given value if not + null. To query for the null value, use {in: {durationBucket: [null]}} instead. + """ + durationBucket: Int + in: ServiceTraceRefsFilterIn + not: ServiceTraceRefsFilter + or: [ServiceTraceRefsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String + + """ + Selects rows whose traceId dimension equals the given value if not null. To + query for the null value, use {in: {traceId: [null]}} instead. + """ + traceId: ID +} + +""" +Filter for data in ServiceTraceRefs. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input ServiceTraceRefsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose durationBucket dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + durationBucket: [Int] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] + + """ + Selects rows whose traceId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + traceId: [ID] +} + +type ServiceTraceRefsMetrics { + durationNs: Long! + traceSizeBytes: Long! +} + +input ServiceTraceRefsOrderBySpec { + column: ServiceTraceRefsColumn! + direction: Ordering! +} + +type ServiceTraceRefsRecord { + """Dimensions of ServiceTraceRefs that can be grouped by.""" + groupBy: ServiceTraceRefsDimensions! + + """Metrics of ServiceTraceRefs that can be aggregated over.""" + metrics: ServiceTraceRefsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""A lowercase hexadecimal SHA-256""" +scalar SHA256 + +"""Slack notification channel""" +type SlackChannel implements Channel { + id: ID! + name: String + url: String! +} + +"""Slack notification channel parameters""" +input SlackChannelInput { + name: String + url: String! +} + +input SlackNotificationField { + key: String! + value: String! +} + +"""Slack notification message""" +input SlackNotificationInput { + color: String + fallback: String! + fields: [SlackNotificationField!] + iconUrl: String + text: String + timestamp: Timestamp + title: String + titleLink: String + username: String +} + +type SourceLocation { + line: Int! + column: Int! +} + +"""A time window with a specified granularity.""" +type StatsWindow { + edgeServerInfos( + """Filter to select what rows to return.""" + filter: EdgeServerInfosFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order EdgeServerInfos by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [EdgeServerInfosOrderBySpec!] + ): [EdgeServerInfosRecord!]! + enumStats( + """Filter to select what rows to return.""" + filter: EnumStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order EnumStats by. The earlier an OrderBySpec + appears in the list, the higher priority it has in the final ordering. When + empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [EnumStatsOrderBySpec!] + ): [EnumStatsRecord!]! + errorStats( + """Filter to select what rows to return.""" + filter: ErrorStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order ErrorStats by. The earlier an OrderBySpec + appears in the list, the higher priority it has in the final ordering. When + empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [ErrorStatsOrderBySpec!] + ): [ErrorStatsRecord!]! + fieldStats( + """Filter to select what rows to return.""" + filter: FieldStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order FieldStats by. The earlier an OrderBySpec + appears in the list, the higher priority it has in the final ordering. When + empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [FieldStatsOrderBySpec!] + ): [FieldStatsRecord!]! + inputStats( + """Filter to select what rows to return.""" + filter: InputStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order InputStats by. The earlier an OrderBySpec + appears in the list, the higher priority it has in the final ordering. When + empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [InputStatsOrderBySpec!] + ): [InputStatsRecord!]! + queryStats( + """Filter to select what rows to return.""" + filter: QueryStatsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order QueryStats by. The earlier an OrderBySpec + appears in the list, the higher priority it has in the final ordering. When + empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [QueryStatsOrderBySpec!] + ): [QueryStatsRecord!]! + + """From field rounded down to the nearest resolution.""" + roundedDownFrom: Timestamp! + + """To field rounded up to the nearest resolution.""" + roundedUpTo: Timestamp! + tracePathErrorsRefs( + """Filter to select what rows to return.""" + filter: TracePathErrorsRefsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order TracePathErrorsRefs by. The earlier an + OrderBySpec appears in the list, the higher priority it has in the final + ordering. When empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [TracePathErrorsRefsOrderBySpec!] + ): [TracePathErrorsRefsRecord!]! + traceRefs( + """Filter to select what rows to return.""" + filter: TraceRefsFilter + + """The maximum number of entries to return, cannot be more than 15000.""" + limit: Int = 10000 + + """ + A list of OrderBySpecs to order TraceRefs by. The earlier an OrderBySpec + appears in the list, the higher priority it has in the final ordering. When + empty or null, defaults to sorting by ascending timestamp. + """ + orderBy: [TraceRefsOrderBySpec!] + ): [TraceRefsRecord!]! +} + +type StoredApprovedChange { + code: ChangeCode! + parentNode: NamedIntrospectionTypeNoDescription + childNode: NamedIntrospectionValueNoDescription + argNode: NamedIntrospectionArgNoDescription +} + +type StoreSchemaError { + code: StoreSchemaErrorCode! + message: String! +} + +enum StoreSchemaErrorCode { + SCHEMA_IS_NOT_PARSABLE + SCHEMA_IS_NOT_VALID +} + +type StoreSchemaResponse { + sha256: SHA256! +} + +union StoreSchemaResponseOrError = StoreSchemaResponse | StoreSchemaError + +scalar StringOrInt + +type StringToString { + key: String! + value: String! +} + +input StringToStringInput { + key: String! + value: String! +} + +type SubscriptionOptions { + """Enables notifications for schema updates""" + schemaUpdates: Boolean! +} + +input SubscriptionOptionsInput { + """Enables notifications for schema updates""" + schemaUpdates: Boolean! +} + +enum SubscriptionState { + ACTIVE + CANCELED + EXPIRED + FUTURE + PAST_DUE + PAUSED + PENDING + UNKNOWN +} + +enum ThemeName { + DARK + LIGHT +} + +""" +ISO 8601, extended format with nanoseconds, Zulu (or '[+-]seconds' for times relative to now) +""" +scalar Timestamp + +type TimezoneOffset { + minutesOffsetFromUTC: Int! + zoneID: String! +} + +type TotalChangeSummaryCounts { + """ + Number of changes that are additions. This includes adding types, adding fields to object, input + object, and interface types, adding values to enums, adding members to interfaces and unions, and + adding arguments. + """ + additions: Int! + + """ + Number of changes that are removals. This includes removing types, removing fields from object, + input object, and interface types, removing values from enums, removing members from interfaces + and unions, and removing arguments. This also includes removing @deprecated usages. + """ + removals: Int! + + """ + Number of changes that are edits. This includes types changing kind, fields and arguments + changing type, arguments changing default value, and any description changes. This also includes + edits to @deprecated reason strings. + """ + edits: Int! + + """Number of changes that are new usages of the @deprecated directive.""" + deprecations: Int! +} + +type Trace { + cacheMaxAgeMs: Float + cacheScope: CacheScope + clientName: String + clientReferenceId: ID + clientVersion: String + durationMs: Float! + endTime: Timestamp! + http: TraceHTTP + id: ID! + operationName: String + protobuf: Protobuf! + root: TraceNode! + signature: String! + signatureId: ID! + startTime: Timestamp! + variablesJSON: [StringToString!]! +} + +type TraceError { + json: String! + locations: [TraceSourceLocation!]! + message: String! + timestamp: Timestamp +} + +type TraceHTTP { + host: String + method: HTTPMethod! + path: String + protocol: String + requestHeaders: [StringToString!]! + responseHeaders: [StringToString!]! + secure: Boolean! + statusCode: Int! +} + +type TraceNode { + cacheMaxAgeMs: Float + cacheScope: CacheScope + children: [TraceNode!]! + childrenIds: [ID!]! + descendants: [TraceNode!]! + descendantsIds: [ID!]! + endTime: Timestamp! + errors: [TraceError!]! + id: ID! + key: StringOrInt + originalFieldName: String + parent: ID! + parentId: ID + path: [String!]! + startTime: Timestamp! + type: String +} + +"""Columns of TracePathErrorsRefs.""" +enum TracePathErrorsRefsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + DURATION_BUCKET + ERRORS_COUNT_IN_PATH + ERRORS_COUNT_IN_TRACE + ERROR_MESSAGE + PATH + QUERY_ID + QUERY_NAME + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP + TRACE_HTTP_STATUS_CODE + TRACE_ID + TRACE_SIZE_BYTES + TRACE_STARTS_AT +} + +type TracePathErrorsRefsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + durationBucket: Int + errorMessage: String + + """ + If metrics were collected from a federated service, this field will be prefixed with `service:.` + """ + path: String + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String + traceHttpStatusCode: Int + traceId: ID + traceStartsAt: Timestamp +} + +""" +Filter for data in TracePathErrorsRefs. Fields with dimension names represent +equality checks. All fields are implicitly ANDed together. +""" +input TracePathErrorsRefsFilter { + and: [TracePathErrorsRefsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose durationBucket dimension equals the given value if not + null. To query for the null value, use {in: {durationBucket: [null]}} instead. + """ + durationBucket: Int + + """ + Selects rows whose errorMessage dimension equals the given value if not null. + To query for the null value, use {in: {errorMessage: [null]}} instead. + """ + errorMessage: String + in: TracePathErrorsRefsFilterIn + not: TracePathErrorsRefsFilter + or: [TracePathErrorsRefsFilter!] + + """ + Selects rows whose path dimension equals the given value if not null. To query + for the null value, use {in: {path: [null]}} instead. + """ + path: String + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String + + """ + Selects rows whose traceHttpStatusCode dimension equals the given value if not + null. To query for the null value, use {in: {traceHttpStatusCode: [null]}} instead. + """ + traceHttpStatusCode: Int + + """ + Selects rows whose traceId dimension equals the given value if not null. To + query for the null value, use {in: {traceId: [null]}} instead. + """ + traceId: ID +} + +""" +Filter for data in TracePathErrorsRefs. Fields match if the corresponding +dimension's value is in the given list. All fields are implicitly ANDed together. +""" +input TracePathErrorsRefsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose durationBucket dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + durationBucket: [Int] + + """ + Selects rows whose errorMessage dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + errorMessage: [String] + + """ + Selects rows whose path dimension is in the given list. A null value in the list means a row with null for that dimension. + """ + path: [String] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] + + """ + Selects rows whose traceHttpStatusCode dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + traceHttpStatusCode: [Int] + + """ + Selects rows whose traceId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + traceId: [ID] +} + +type TracePathErrorsRefsMetrics { + errorsCountInPath: Long! + errorsCountInTrace: Long! + traceSizeBytes: Long! +} + +input TracePathErrorsRefsOrderBySpec { + column: TracePathErrorsRefsColumn! + direction: Ordering! +} + +type TracePathErrorsRefsRecord { + """Dimensions of TracePathErrorsRefs that can be grouped by.""" + groupBy: TracePathErrorsRefsDimensions! + + """Metrics of TracePathErrorsRefs that can be aggregated over.""" + metrics: TracePathErrorsRefsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +"""Columns of TraceRefs.""" +enum TraceRefsColumn { + CLIENT_NAME + CLIENT_REFERENCE_ID + CLIENT_VERSION + DURATION_BUCKET + DURATION_NS + QUERY_ID + QUERY_NAME + SCHEMA_HASH + SCHEMA_TAG + SERVICE_ID + SERVICE_VERSION + TIMESTAMP + TRACE_ID + TRACE_SIZE_BYTES +} + +type TraceRefsDimensions { + clientName: String + clientReferenceId: ID + clientVersion: String + durationBucket: Int + queryId: ID + queryName: String + querySignature: String + schemaHash: String + schemaTag: String + serviceId: ID + serviceVersion: String + traceId: ID +} + +""" +Filter for data in TraceRefs. Fields with dimension names represent equality +checks. All fields are implicitly ANDed together. +""" +input TraceRefsFilter { + and: [TraceRefsFilter!] + + """ + Selects rows whose clientName dimension equals the given value if not null. To + query for the null value, use {in: {clientName: [null]}} instead. + """ + clientName: String + + """ + Selects rows whose clientReferenceId dimension equals the given value if not + null. To query for the null value, use {in: {clientReferenceId: [null]}} instead. + """ + clientReferenceId: ID + + """ + Selects rows whose clientVersion dimension equals the given value if not null. + To query for the null value, use {in: {clientVersion: [null]}} instead. + """ + clientVersion: String + + """ + Selects rows whose durationBucket dimension equals the given value if not + null. To query for the null value, use {in: {durationBucket: [null]}} instead. + """ + durationBucket: Int + in: TraceRefsFilterIn + not: TraceRefsFilter + or: [TraceRefsFilter!] + + """ + Selects rows whose queryId dimension equals the given value if not null. To + query for the null value, use {in: {queryId: [null]}} instead. + """ + queryId: ID + + """ + Selects rows whose queryName dimension equals the given value if not null. To + query for the null value, use {in: {queryName: [null]}} instead. + """ + queryName: String + + """ + Selects rows whose schemaHash dimension equals the given value if not null. To + query for the null value, use {in: {schemaHash: [null]}} instead. + """ + schemaHash: String + + """ + Selects rows whose schemaTag dimension equals the given value if not null. To + query for the null value, use {in: {schemaTag: [null]}} instead. + """ + schemaTag: String + + """ + Selects rows whose serviceId dimension equals the given value if not null. To + query for the null value, use {in: {serviceId: [null]}} instead. + """ + serviceId: ID + + """ + Selects rows whose serviceVersion dimension equals the given value if not + null. To query for the null value, use {in: {serviceVersion: [null]}} instead. + """ + serviceVersion: String + + """ + Selects rows whose traceId dimension equals the given value if not null. To + query for the null value, use {in: {traceId: [null]}} instead. + """ + traceId: ID +} + +""" +Filter for data in TraceRefs. Fields match if the corresponding dimension's +value is in the given list. All fields are implicitly ANDed together. +""" +input TraceRefsFilterIn { + """ + Selects rows whose clientName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + clientName: [String] + + """ + Selects rows whose clientReferenceId dimension is in the given list. A null + value in the list means a row with null for that dimension. + """ + clientReferenceId: [ID] + + """ + Selects rows whose clientVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + clientVersion: [String] + + """ + Selects rows whose durationBucket dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + durationBucket: [Int] + + """ + Selects rows whose queryId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + queryId: [ID] + + """ + Selects rows whose queryName dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + queryName: [String] + + """ + Selects rows whose schemaHash dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaHash: [String] + + """ + Selects rows whose schemaTag dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + schemaTag: [String] + + """ + Selects rows whose serviceId dimension is in the given list. A null value in + the list means a row with null for that dimension. + """ + serviceId: [ID] + + """ + Selects rows whose serviceVersion dimension is in the given list. A null value + in the list means a row with null for that dimension. + """ + serviceVersion: [String] + + """ + Selects rows whose traceId dimension is in the given list. A null value in the + list means a row with null for that dimension. + """ + traceId: [ID] +} + +type TraceRefsMetrics { + durationNs: Long! + traceSizeBytes: Long! +} + +input TraceRefsOrderBySpec { + column: TraceRefsColumn! + direction: Ordering! +} + +type TraceRefsRecord { + """Dimensions of TraceRefs that can be grouped by.""" + groupBy: TraceRefsDimensions! + + """Metrics of TraceRefs that can be aggregated over.""" + metrics: TraceRefsMetrics! + + """Starting segment timestamp.""" + timestamp: Timestamp! +} + +type TraceSourceLocation { + column: Int! + line: Int! +} + +type TypeChangeSummaryCounts { + """Number of changes that are additions of types.""" + additions: Int! + + """Number of changes that are removals of types.""" + removals: Int! + + """ + Number of changes that are edits. This includes types changing kind and any type description + changes, but also includes adding/removing values from enums, adding/removing members from + interfaces and unions, and any enum value deprecation and description changes. + """ + edits: Int! +} + +""" +the TypeFilterConfig is used to isolate +types, and subsequent fields, through +various configuration settings. + +It defaults to filter towards user defined +types only +""" +input TypeFilterConfig { + """include abstract types (interfaces and unions)""" + includeAbstractTypes: Boolean = true + + """include built in scalars (i.e. Boolean, Int, etc)""" + includeBuiltInTypes: Boolean = false + + """include reserved introspection types (i.e. __Type)""" + includeIntrospectionTypes: Boolean = false +} + +type UnignoreOperationsInChecksResult { + graph: Service! +} + +type UploadSchemaMutationResponse { + code: String! + success: Boolean! + message: String! + tag: SchemaTag +} + +type URI { + """A GCS URI""" + gcs: String! +} + +type User implements Identity + @owner(graph: "kotlin") + @key(fields: "{ id }", graph: "kotlin") + @key(fields: "{ id }", graph: "featureflags") + @key(fields: "{ id }", graph: "registry") +{ + acceptedPrivacyPolicyAt: Timestamp + accounts: [Account!]! @deprecated(reason: "Replaced with User.memberships.account") + apiKeys(includeCookies: Boolean = false): [ApiKey!]! + asActor: Actor! + + """ + Get an URL to which an avatar image can be uploaded. Client uploads by sending a PUT request + with the image data to MediaUploadInfo.url. Client SHOULD set the "Content-Type" header to the + browser-inferred MIME type, and SHOULD set the "x-apollo-content-filename" header to the + filename, if such information is available. Client MUST set the "x-apollo-csrf-token" header to + MediaUploadInfo.csrfToken. + """ + avatarUpload: AvatarUploadResult + + """ + Get an image URL for the user's avatar. Note that CORS is not enabled for these URLs. The size + argument is used for bandwidth reduction, and should be the size of the image as displayed in the + application. Apollo's media server will downscale larger images to at least the requested size, + but this will not happen for third-party media servers. + """ + avatarUrl(size: Int! = 40): String + canUpdateAvatar: Boolean! + canUpdateEmail: Boolean! + canUpdateFullName: Boolean! + createdAt: Timestamp! + email: String + emailModifiedAt: Timestamp + emailVerified: Boolean! + fullName: String! + id: ID! + + """ + This role is reserved exclusively for internal MDG employees, and it controls what access they may have to other + organizations. Only admins are allowed to see this field. + """ + internalAdminRole: InternalMdgAdminRole + + """Last time any API token from this user was used against AGM services""" + lastAuthenticatedAt: Timestamp + logoutAfterIdleMs: Int + memberships: [UserMembership!]! + name: String! + synchronized: Boolean! + type: UserType! + experimentalFeatures: UserExperimentalFeatures! @resolve(graph: "featureflags") @requires(fields: "{ id }") +} + +type UserExperimentalFeatures { + exampleFeature: Boolean! +} + +type UserMembership { + account: Account! + createdAt: Timestamp! + permission: UserPermission! +} + +type UserMutation { + acceptPrivacyPolicy: Void + + """Change the user's password""" + changePassword(newPassword: String!, previousPassword: String!): Void + + """Delete the user's avatar. Requires User.canUpdateAvatar to be true.""" + deleteAvatar: AvatarDeleteError + + """ + Hard deletes the associated user. Throws an error otherwise with reason included. + """ + hardDelete: Void + + """Create a new API key for this user. Must take in a name for this key.""" + newKey(keyName: String!): ApiKey! + + """ + Create a new API key for this user if there are no current API keys. + If an API key already exists, this will return one at random and not create a new one. + """ + provisionKey(keyName: String! = "add-a-name"): ApiKeyProvision + + """ + Refresh information about the user from its upstream service (eg list of organizations from GitHub) + """ + refresh: User + + """ + Removes the given key from this user. Can be used to remove either a web cookie or a user API key. + """ + removeKey(key: String!): Void + + """Renames the given key to the new key name.""" + renameKey(key: String!, newKeyName: String!): ApiKey! + resendVerificationEmail: Void + + """Update information about a user; all arguments are optional""" + update(email: String, fullName: String, referrer: String): User + + """ + Update user to have the given internal mdg admin role. + It is necessary to be an MDG_INTERNAL_SUPER_ADMIN to perform update. + Additionally, upserting a null value explicitly revokes this user's + admin status. + """ + updateRole(newRole: InternalMdgAdminRole): User + user: User! + verifyEmail(token: String!): User +} + +enum UserPermission { + ADMIN + BILLING_MANAGER + CONSUMER + CONTRIBUTOR + STANDARD +} + +type UserSettings { + appNavCollapsed: Boolean! + autoManageVariables: Boolean! + id: String! + mockingResponses: Boolean! + preflightScriptEnabled: Boolean! + responseHints: ResponseHints! + tableMode: Boolean! + themeName: ThemeName! +} + +"""Explorer user settings input""" +input UserSettingsInput { + appNavCollapsed: Boolean + autoManageVariables: Boolean + mockingResponses: Boolean + preflightScriptEnabled: Boolean + responseHints: ResponseHints + tableMode: Boolean + themeName: ThemeName +} + +enum UserType { + APOLLO + GITHUB + SSO +} + +type ValidateOperationsResult { + validationResults: [ValidationResult!]! +} + +enum ValidationErrorCode { + NON_PARSEABLE_DOCUMENT + INVALID_OPERATION + DEPRECATED_FIELD +} + +enum ValidationErrorType { + FAILURE + WARNING + INVALID +} + +""" +Represents a single validation error, with information relating to the error +and its respective operation +""" +type ValidationResult { + """The type of validation error thrown - warning, failure, or invalid.""" + type: ValidationErrorType! + + """The validation result's error code""" + code: ValidationErrorCode! + + """Description of the validation error""" + description: String! + + """The operation related to this validation result""" + operation: OperationDocument! +} + +"""Always null""" +scalar Void + diff --git a/src/command/graph/check.rs b/src/command/graph/check.rs new file mode 100644 index 0000000000..19156ff534 --- /dev/null +++ b/src/command/graph/check.rs @@ -0,0 +1,68 @@ +use std::path::PathBuf; + +use anyhow::{Context, Result}; +use serde::Serialize; +use structopt::StructOpt; + +use rover_client::query::graph::check; + +use crate::client::get_studio_client; +use crate::command::RoverStdout; + +#[derive(Debug, Serialize, StructOpt)] +pub struct Check { + /// ID of graph in Apollo Studio to fetch from + #[structopt(name = "GRAPH_NAME")] + #[serde(skip_serializing)] + graph_name: String, + + /// Name of graph variant in Apollo Studio to fetch from + #[structopt(long, default_value = "current")] + #[serde(skip_serializing)] + variant: String, + + /// Name of configuration profile to use + #[structopt(long = "profile", default_value = "default")] + #[serde(skip_serializing)] + profile_name: String, + + /// Path of .graphql/.gql schema file to push + #[structopt(long, short = "s")] + #[serde(skip_serializing)] + schema: PathBuf, +} + +impl Check { + pub fn run(&self) -> Result { + let client = + get_studio_client(&self.profile_name).context("Failed to get studio client")?; + let schema = std::fs::read_to_string(&self.schema).with_context(|| format!("Could not read file `{}`", &self.schema.display()))?; + let res = check::run( + check::check_schema_query::Variables { + graph_id: self.graph_name.clone(), + variant: Some(self.variant.clone()), + schema: Some(schema), + }, + &client, + ) + .context("Failed to validate schema")?; + + tracing::info!( + "Validated schema against metrics from variant {} on graph {}", + &self.variant, + &self.graph_name + ); + tracing::info!( + "Compared {} schema changes against {} operations", + res.changes.len(), + res.number_of_checked_operations + ); + + if let Some(url) = res.target_url { + tracing::info!("View full details here"); + tracing::info!("{}", url.to_string()); + } + + Ok(RoverStdout::Checks(res.changes)) + } +} diff --git a/src/command/graph/fetch.rs b/src/command/graph/fetch.rs index 2bad5173a6..91fac0b2be 100644 --- a/src/command/graph/fetch.rs +++ b/src/command/graph/fetch.rs @@ -2,7 +2,7 @@ use anyhow::{Context, Result}; use serde::Serialize; use structopt::StructOpt; -use rover_client::query::schema::get; +use rover_client::query::graph::get; use crate::client::get_studio_client; use crate::command::RoverStdout; diff --git a/src/command/graph/mod.rs b/src/command/graph/mod.rs index 38a0494a26..ee264d7583 100644 --- a/src/command/graph/mod.rs +++ b/src/command/graph/mod.rs @@ -1,3 +1,4 @@ +mod check; mod fetch; mod push; @@ -20,6 +21,9 @@ pub enum Command { /// ⬆️ Push a schema to Apollo Studio from a local file Push(push::Push), + + /// Validate changes to a schema + Check(check::Check), } impl<'a> Graph { @@ -27,6 +31,7 @@ impl<'a> Graph { match &self.command { Command::Fetch(command) => command.run(), Command::Push(command) => command.run(), + Command::Check(command) => command.run(), } } } diff --git a/src/command/graph/push.rs b/src/command/graph/push.rs index a21a5efe29..6c8f0bfb9f 100644 --- a/src/command/graph/push.rs +++ b/src/command/graph/push.rs @@ -4,7 +4,7 @@ use anyhow::{Context, Result}; use serde::Serialize; use structopt::StructOpt; -use rover_client::query::schema::push; +use rover_client::query::graph::push; use crate::client::get_studio_client; use crate::command::RoverStdout; diff --git a/src/command/output.rs b/src/command/output.rs index cdabd23cf3..81b3f22c0a 100644 --- a/src/command/output.rs +++ b/src/command/output.rs @@ -1,4 +1,7 @@ use atty::{self, Stream}; +use prettytable::{cell, row, Table}; + +use rover_client::query::graph::check::check_schema_query; /// RoverStdout defines all of the different types of data that are printed /// to `stdout`. Every one of Rover's commands should return `anyhow::Result` @@ -8,10 +11,11 @@ use atty::{self, Stream}; /// Not all commands will output machine readable information, and those should /// return `Ok(RoverStdout::None)`. If a new command is added and it needs to /// return something that is not described well in this enum, it should be added. -#[derive(Clone, PartialEq, Debug)] +#[derive(Debug)] pub enum RoverStdout { SDL(String), SchemaHash(String), + Checks(Vec), None, } @@ -36,6 +40,21 @@ impl RoverStdout { } println!("{}", &hash); } + RoverStdout::Checks(checks) => { + let mut table = Table::new(); + + table.add_row(row!["Change", "Code", "Description"]); + for check in checks { + let change = match check.severity { + check_schema_query::ChangeSeverity::NOTICE => "PASS", + check_schema_query::ChangeSeverity::FAILURE => "FAIL", + _ => "UNKNOWN", + }; + table.add_row(row![change, check.code, check.description]); + } + + table.printstd(); + } RoverStdout::None => (), } } diff --git a/src/command/subgraph/check.rs b/src/command/subgraph/check.rs new file mode 100644 index 0000000000..0b98a3b65c --- /dev/null +++ b/src/command/subgraph/check.rs @@ -0,0 +1,36 @@ +use std::path::PathBuf; + +use anyhow::Result; +use serde::Serialize; +use structopt::StructOpt; + +use crate::command::RoverStdout; + +#[derive(Debug, Serialize, StructOpt)] +pub struct Check { + /// ID of graph in Apollo Studio to fetch from + #[structopt(name = "GRAPH_NAME")] + #[serde(skip_serializing)] + graph_name: String, + + /// Name of graph variant in Apollo Studio to fetch from + #[structopt(long, default_value = "current")] + #[serde(skip_serializing)] + variant: String, + + /// Name of configuration profile to use + #[structopt(long = "profile", default_value = "default")] + #[serde(skip_serializing)] + profile_name: String, + + /// Path of .graphql/.gql schema file to push + #[structopt(long, short = "s")] + #[serde(skip_serializing)] + schema: PathBuf, +} + +impl Check { + pub fn run(&self) -> Result { + Ok(RoverStdout::None) + } +} diff --git a/src/command/subgraph/delete.rs b/src/command/subgraph/delete.rs index 328c391912..ce0c16aba0 100644 --- a/src/command/subgraph/delete.rs +++ b/src/command/subgraph/delete.rs @@ -1,7 +1,7 @@ use crate::client::get_studio_client; use crate::command::RoverStdout; use anyhow::Result; -use rover_client::query::partial::delete::{self, DeleteServiceResponse}; +use rover_client::query::subgraph::delete::{self, DeleteServiceResponse}; use serde::Serialize; use structopt::StructOpt; diff --git a/src/command/subgraph/mod.rs b/src/command/subgraph/mod.rs index 9162df9fd3..8ad00eb66e 100644 --- a/src/command/subgraph/mod.rs +++ b/src/command/subgraph/mod.rs @@ -1,3 +1,4 @@ +mod check; mod delete; mod push; @@ -17,8 +18,12 @@ pub struct Subgraph { pub enum Command { /// ⬆️ Push an implementing service schema from a local file Push(push::Push), + /// 🗑 Delete an implementing service and trigger composition Delete(delete::Delete), + + /// Validate changes to an implementing service + Check(check::Check), } impl Subgraph { @@ -26,6 +31,7 @@ impl Subgraph { match &self.command { Command::Push(command) => command.run(), Command::Delete(command) => command.run(), + Command::Check(command) => command.run(), } } } diff --git a/src/command/subgraph/push.rs b/src/command/subgraph/push.rs index 4afac599a0..4a51c5e4b6 100644 --- a/src/command/subgraph/push.rs +++ b/src/command/subgraph/push.rs @@ -1,5 +1,5 @@ use anyhow::{Context, Result}; -use rover_client::query::partial::push::{self, PushPartialSchemaResponse}; +use rover_client::query::subgraph::push::{self, PushPartialSchemaResponse}; use serde::Serialize; use std::path::{Path, PathBuf}; use structopt::StructOpt; diff --git a/test.graphql b/test.graphql new file mode 100644 index 0000000000..661300b565 --- /dev/null +++ b/test.graphql @@ -0,0 +1,80 @@ +directive @cacheControl(maxAge: Int, scope: CacheControlScope) on FIELD_DEFINITION | OBJECT | INTERFACE + +enum CacheControlScope { + PUBLIC + PRIVATE +} + +type Launch { + id: ID! + siteeee: String + mission: Mission + rocket: Rocket + isBooked: Boolean! +} + +""" +Simple wrapper around our list of launches that contains a cursor to the +last item in the list. Pass this cursor to the launches query to fetch results +after these. +""" +type LaunchConnection { + cursor: String! + hasMore: Boolean! + launches: [Launch]! +} + +type Mission { + name: String + missionPatch(size: PatchSize): String +} + +type Mutation { + bookTrips(launchIds: [ID]!): TripUpdateResponse! + cancelTrip(launchId: ID!): TripUpdateResponse! + login(email: String): String + uploadProfileImage(file: Upload!): User +} + +enum PatchSize { + SMALL + LARGE +} + +type Query { + launches( + """The number of results to show. Must be >= 1. Default = 20""" + pageSize: Int + + """ + If you add a cursor here, it will only return results _after_ this cursor + """ + after: String + ): LaunchConnection! + launch(id: ID!): Launch + me: User +} + +type Rocket { + id: ID! + name: String + type: String +} + +type TripUpdateResponse { + success: Boolean! + message: String + launches: [Launch] +} + +"""The `Upload` scalar type represents a file upload.""" +scalar Upload + +type User { + id: ID! + email: String! + profileImage: String + trips: [Launch]! + token: String +} +