From 81ab582ab3a4e8615c1165a9b1af75d1db2c5306 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 18:54:00 +0000 Subject: [PATCH 01/16] fix(deps): update rust crate anyhow to v1.0.83 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1bb07488a3..85d9b4344d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -142,9 +142,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.82" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" [[package]] name = "anymap2" From dc5046f6e8cbb3e12ca9582856b3026a5ef11280 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 03:07:03 +0000 Subject: [PATCH 02/16] fix(deps): update rust crate thiserror to v1.0.60 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85d9b4344d..34c6c913f7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5292,18 +5292,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", From 447410661ca623336608e30b33bf8e9853ebdc35 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 03:06:53 +0000 Subject: [PATCH 03/16] fix(deps): update rust crate syn to v2.0.61 --- Cargo.lock | 72 +++++++++++++++++++++++++++--------------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 34c6c913f7..ce95d752c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -291,7 +291,7 @@ dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", "strum 0.26.2", - "syn 2.0.60", + "syn 2.0.61", "thiserror", ] @@ -445,7 +445,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -513,7 +513,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -530,7 +530,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -896,7 +896,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -1170,7 +1170,7 @@ dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", "strsim 0.10.0", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -1192,7 +1192,7 @@ checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" dependencies = [ "darling_core 0.20.8", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -1275,7 +1275,7 @@ dependencies = [ "darling 0.20.8", "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -1661,7 +1661,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -2793,7 +2793,7 @@ dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", "regex-syntax 0.6.29", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -2808,7 +2808,7 @@ dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", "regex-syntax 0.8.3", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -2933,7 +2933,7 @@ checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3455,7 +3455,7 @@ dependencies = [ "pest_meta", "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3560,7 +3560,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3680,7 +3680,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" dependencies = [ "proc-macro2 1.0.81", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -3777,7 +3777,7 @@ dependencies = [ "prost", "prost-types", "regex", - "syn 2.0.60", + "syn 2.0.61", "tempfile", ] @@ -3791,7 +3791,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -4290,7 +4290,7 @@ dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", "rquickjs-core", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -4493,7 +4493,7 @@ dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", "serde_derive_internals", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -4605,7 +4605,7 @@ checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -4616,7 +4616,7 @@ checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -4910,7 +4910,7 @@ dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", "rustversion", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -4923,7 +4923,7 @@ dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", "rustversion", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -4956,9 +4956,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.60" +version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", @@ -5181,7 +5181,7 @@ version = "0.1.0" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -5307,7 +5307,7 @@ checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -5431,7 +5431,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -5551,7 +5551,7 @@ dependencies = [ "proc-macro2 1.0.81", "prost-build", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -5564,7 +5564,7 @@ dependencies = [ "proc-macro2 1.0.81", "prost-build", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -5662,7 +5662,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -5977,7 +5977,7 @@ dependencies = [ "once_cell", "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", "wasm-bindgen-shared", ] @@ -6011,7 +6011,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6344,7 +6344,7 @@ dependencies = [ "async-trait", "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-macro-support", @@ -6372,7 +6372,7 @@ dependencies = [ "darling 0.20.8", "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] @@ -6398,7 +6398,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2 1.0.81", "quote 1.0.36", - "syn 2.0.60", + "syn 2.0.61", ] [[package]] From 57bf119c18ad021c4a619f8ff24dd4f42d85aa31 Mon Sep 17 00:00:00 2001 From: shylock Date: Tue, 7 May 2024 15:25:57 +0800 Subject: [PATCH 04/16] refactor: drop type variants (#1857) Co-authored-by: Tushar Mathur --- generated/.tailcallrc.schema.json | 40 ++++++++---- src/blueprint/definitions.rs | 45 +++++++------ src/blueprint/from_config.rs | 26 ++++---- src/blueprint/into_schema.rs | 3 + src/blueprint/schema.rs | 3 +- src/config/config.rs | 26 ++++++-- src/config/from_document.rs | 64 ++++++++++++------- src/config/into_document.rs | 35 ++++++---- src/config/source.rs | 15 +++++ src/document.rs | 11 +++- src/generator/from_proto.rs | 17 ++--- ...nerator__from_proto__test__from_proto.snap | 5 ++ ...ution_spec__test-enum-empty.md_errors.snap | 11 ++++ .../snapshots/test-enum-description.md_0.snap | 16 +++++ .../snapshots/test-enum-description.md_1.snap | 16 +++++ .../snapshots/test-enum-description.md_2.snap | 28 ++++++++ .../test-enum-description.md_client.snap | 32 ++++++++++ .../test-enum-description.md_merged.snap | 20 ++++++ tests/core/spec.rs | 8 +-- tests/execution/test-enum-description.md | 40 ++++++++++++ tests/execution/test-enum-empty.md | 44 +++++++++++++ 21 files changed, 400 insertions(+), 105 deletions(-) create mode 100644 tests/core/snapshots/execution_spec__test-enum-empty.md_errors.snap create mode 100644 tests/core/snapshots/test-enum-description.md_0.snap create mode 100644 tests/core/snapshots/test-enum-description.md_1.snap create mode 100644 tests/core/snapshots/test-enum-description.md_2.snap create mode 100644 tests/core/snapshots/test-enum-description.md_client.snap create mode 100644 tests/core/snapshots/test-enum-description.md_merged.snap create mode 100644 tests/execution/test-enum-description.md create mode 100644 tests/execution/test-enum-empty.md diff --git a/generated/.tailcallrc.schema.json b/generated/.tailcallrc.schema.json index 5357369acd..a39e72e028 100644 --- a/generated/.tailcallrc.schema.json +++ b/generated/.tailcallrc.schema.json @@ -6,6 +6,13 @@ "schema" ], "properties": { + "enums": { + "description": "A map of all the enum types in the schema", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Enum" + } + }, "links": { "description": "A list of all links in the schema.", "type": "array", @@ -333,6 +340,28 @@ "ApplicationXWwwFormUrlencoded" ] }, + "Enum": { + "description": "Definition of GraphQL enum type", + "type": "object", + "required": [ + "variants" + ], + "properties": { + "doc": { + "type": [ + "string", + "null" + ] + }, + "variants": { + "type": "array", + "items": { + "type": "string" + }, + "uniqueItems": true + } + } + }, "Expr": { "description": "The `@expr` operators allows you to specify an expression that can evaluate to a value. The expression can be a static value or built form a Mustache template. schema.", "type": "object", @@ -1221,17 +1250,6 @@ "null" ] }, - "enum": { - "description": "Variants for the type if it's an enum", - "type": [ - "array", - "null" - ], - "items": { - "type": "string" - }, - "uniqueItems": true - }, "fields": { "description": "A map of field name and its definition.", "type": "object", diff --git a/src/blueprint/definitions.rs b/src/blueprint/definitions.rs index fe5126b2dc..7a7fdb1991 100644 --- a/src/blueprint/definitions.rs +++ b/src/blueprint/definitions.rs @@ -1,11 +1,9 @@ -use std::collections::BTreeSet; - use async_graphql_value::ConstValue; use regex::Regex; use crate::blueprint::Type::ListType; use crate::blueprint::*; -use crate::config::{Config, Field, GraphQLOperationType, Protected, Union}; +use crate::config::{Config, Enum, Field, GraphQLOperationType, Protected, Union}; use crate::directive::DirectiveCodec; use crate::lambda::{Cache, Context, Expression}; use crate::try_fold::TryFold; @@ -226,16 +224,13 @@ fn process_path(context: ProcessPathContext) -> Valid { Valid::succeed(to_type(field, Some(is_required))) } -fn to_enum_type_definition( - name: &str, - type_: &config::Type, - variants: &BTreeSet, -) -> Valid { - let enum_type_definition = Definition::Enum(EnumTypeDefinition { - name: name.to_string(), +fn to_enum_type_definition((name, eu): (&String, &Enum)) -> Definition { + Definition::Enum(EnumTypeDefinition { + name: name.to_owned(), directives: Vec::new(), - description: type_.doc.clone(), - enum_values: variants + description: eu.doc.to_owned(), + enum_values: eu + .variants .iter() .map(|variant| EnumValueDefinition { description: None, @@ -243,8 +238,7 @@ fn to_enum_type_definition( directives: Vec::new(), }) .collect(), - }); - Valid::succeed(enum_type_definition) + }) } fn to_object_type_definition( @@ -525,13 +519,7 @@ pub fn to_definitions<'a>() -> TryFold<'a, ConfigModule, Vec, String Valid::from_iter(config_module.types.iter(), |(name, type_)| { let dbl_usage = input_types.contains(name) && output_types.contains(name); - if let Some(variants) = &type_.variants { - if !variants.is_empty() { - to_enum_type_definition(name, type_, variants).trace(name) - } else { - Valid::fail("No variants found for enum".to_string()) - } - } else if type_.scalar() { + if type_.scalar() { to_scalar_type_definition(name).trace(name) } else if dbl_usage { Valid::fail("type is used in input and output".to_string()).trace(name) @@ -556,5 +544,20 @@ pub fn to_definitions<'a>() -> TryFold<'a, ConfigModule, Vec, String types.extend(config_module.unions.iter().map(to_union_type_definition)); types }) + .fuse(Valid::from_iter( + config_module.enums.iter(), + |(name, type_)| { + if type_.variants.is_empty() { + Valid::fail("No variants found for enum".to_string()) + } else { + Valid::succeed(to_enum_type_definition((name, type_))) + } + }, + )) + .map(|tp| { + let mut v = tp.0; + v.extend(tp.1); + v + }) }) } diff --git a/src/blueprint/from_config.rs b/src/blueprint/from_config.rs index f786a56802..6bfa9d9761 100644 --- a/src/blueprint/from_config.rs +++ b/src/blueprint/from_config.rs @@ -86,27 +86,25 @@ where let list = field.list(); let required = field.non_null(); let type_ = config.find_type(type_of); - let schema = match type_ { - Some(type_) => { - if let Some(variants) = type_.variants.clone() { - JsonSchema::Enum(variants) - } else { - let mut schema_fields = HashMap::new(); - for (name, field) in type_.fields.iter() { - if field.script.is_none() && field.http.is_none() { - schema_fields.insert(name.clone(), to_json_schema_for_field(field, config)); - } - } - JsonSchema::Obj(schema_fields) + let type_enum_ = config.find_enum(type_of); + let schema = if let Some(type_) = type_ { + let mut schema_fields = HashMap::new(); + for (name, field) in type_.fields.iter() { + if field.script.is_none() && field.http.is_none() { + schema_fields.insert(name.clone(), to_json_schema_for_field(field, config)); } } - None => match type_of { + JsonSchema::Obj(schema_fields) + } else if let Some(type_enum_) = type_enum_ { + JsonSchema::Enum(type_enum_.variants.to_owned()) + } else { + match type_of { "String" => JsonSchema::Str {}, "Int" => JsonSchema::Num {}, "Boolean" => JsonSchema::Bool {}, "JSON" => JsonSchema::Obj(HashMap::new()), _ => JsonSchema::Str {}, - }, + } }; if !required { diff --git a/src/blueprint/into_schema.rs b/src/blueprint/into_schema.rs index 7892bc564b..5b0b5600b8 100644 --- a/src/blueprint/into_schema.rs +++ b/src/blueprint/into_schema.rs @@ -137,6 +137,9 @@ fn to_type(def: &Definition) -> dynamic::Type { for value in def.enum_values.iter() { enum_type = enum_type.item(dynamic::EnumItem::new(value.name.clone())); } + if let Some(desc) = def.description.clone() { + enum_type = enum_type.description(desc); + } dynamic::Type::Enum(enum_type) } Definition::Union(def) => { diff --git a/src/blueprint/schema.rs b/src/blueprint/schema.rs index 9ba08bad55..409ed20071 100644 --- a/src/blueprint/schema.rs +++ b/src/blueprint/schema.rs @@ -50,8 +50,7 @@ pub fn validate_field_has_resolver( if !field.has_resolver() { let type_name = &field.type_of; if let Some(ty) = types.get(type_name) { - // It's an enum - if ty.variants.is_some() || ty.scalar() { + if ty.scalar() { return true; } let res = validate_type_has_resolvers(type_name, ty, types); diff --git a/src/config/config.rs b/src/config/config.rs index 0188a2b06e..a2478f37e7 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -63,6 +63,11 @@ pub struct Config { #[serde(default, skip_serializing_if = "is_default")] pub unions: BTreeMap, + /// + /// A map of all the enum types in the schema + #[serde(default, skip_serializing_if = "is_default")] + pub enums: BTreeMap, + /// /// A list of all links in the schema. #[serde(default, skip_serializing_if = "is_default")] @@ -94,10 +99,6 @@ pub struct Type { /// /// Interfaces that the type implements. pub implements: BTreeSet, - #[serde(rename = "enum", default, skip_serializing_if = "is_default")] - /// - /// Variants for the type if it's an enum - pub variants: Option>, #[serde(default, skip_serializing_if = "is_default")] /// /// Setting to indicate if the type can be cached. @@ -123,7 +124,7 @@ impl Type { } pub fn scalar(&self) -> bool { - self.fields.is_empty() && self.variants.is_none() + self.fields.is_empty() } } @@ -393,6 +394,13 @@ pub struct Union { pub doc: Option, } +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, schemars::JsonSchema, MergeRight)] +/// Definition of GraphQL enum type +pub struct Enum { + pub variants: BTreeSet, + pub doc: Option, +} + #[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, schemars::JsonSchema)] #[serde(deny_unknown_fields)] /// The @http operator indicates that a field or node is backed by a REST API. @@ -609,6 +617,10 @@ impl Config { self.unions.get(name) } + pub fn find_enum(&self, name: &str) -> Option<&Enum> { + self.enums.get(name) + } + pub fn to_yaml(&self) -> Result { Ok(serde_yaml::to_string(self)?) } @@ -645,7 +657,9 @@ impl Config { } pub fn contains(&self, name: &str) -> bool { - self.types.contains_key(name) || self.unions.contains_key(name) + self.types.contains_key(name) + || self.unions.contains_key(name) + || self.enums.contains_key(name) } pub fn from_json(json: &str) -> Result { diff --git a/src/config/from_document.rs b/src/config/from_document.rs index 1068b65855..f4cfbef5fc 100644 --- a/src/config/from_document.rs +++ b/src/config/from_document.rs @@ -11,8 +11,8 @@ use async_graphql::Name; use super::telemetry::Telemetry; use super::{Tag, JS}; use crate::config::{ - self, Cache, Call, Config, GraphQL, Grpc, Link, Modify, Omit, Protected, RootSchema, Server, - Union, Upstream, + self, Cache, Call, Config, Enum, GraphQL, Grpc, Link, Modify, Omit, Protected, RootSchema, + Server, Union, Upstream, }; use crate::directive::DirectiveCodec; use crate::valid::{Valid, Validator}; @@ -37,21 +37,24 @@ pub fn from_document(doc: ServiceDocument) -> Valid { let types = to_types(&type_definitions); let unions = to_union_types(&type_definitions); + let enums = to_enum_types(&type_definitions); let schema = schema_definition(&doc).map(to_root_schema); schema_definition(&doc).and_then(|sd| { server(sd) .fuse(upstream(sd)) .fuse(types) .fuse(unions) + .fuse(enums) .fuse(schema) .fuse(links(sd)) .fuse(telemetry(sd)) .map( - |(server, upstream, types, unions, schema, links, telemetry)| Config { + |(server, upstream, types, unions, enums, schema, links, telemetry)| Config { server, upstream, types, unions, + enums, schema, links, telemetry, @@ -155,7 +158,7 @@ fn to_types( &type_definition.node.directives, ) .some(), - TypeKind::Enum(enum_type) => Valid::succeed(Some(to_enum(enum_type))), + TypeKind::Enum(_) => Valid::none(), TypeKind::InputObject(input_object_type) => { to_input_object(input_object_type, &type_definition.node.directives).some() } @@ -199,6 +202,31 @@ fn to_union_types( ) } +fn to_enum_types( + type_definitions: &[&Positioned], +) -> Valid, String> { + Valid::succeed( + type_definitions + .iter() + .filter_map(|type_definition| { + let type_name = pos_name_to_string(&type_definition.node.name); + let type_opt = match type_definition.node.kind.clone() { + TypeKind::Enum(enum_type) => to_enum( + enum_type, + type_definition + .node + .description + .to_owned() + .map(|pos| pos.node), + ), + _ => return None, + }; + Some((type_name, type_opt)) + }) + .collect(), + ) +} + #[allow(clippy::too_many_arguments)] fn to_object_type( object: &T, @@ -219,26 +247,9 @@ where let doc = description.to_owned().map(|pos| pos.node); let implements = implements.iter().map(|pos| pos.node.to_string()).collect(); let added_fields = to_add_fields_from_directives(directives); - config::Type { - fields, - added_fields, - doc, - implements, - cache, - protected, - tag, - ..Default::default() - } + config::Type { fields, added_fields, doc, implements, cache, protected, tag } }) } -fn to_enum(enum_type: EnumType) -> config::Type { - let variants = enum_type - .values - .iter() - .map(|value| value.node.value.to_string()) - .collect(); - config::Type { variants: Some(variants), ..Default::default() } -} fn to_input_object( input_object_type: InputObjectType, directives: &[Positioned], @@ -375,6 +386,15 @@ fn to_union(union_type: UnionType, doc: &Option) -> Union { .collect(); Union { types, doc: doc.clone() } } + +fn to_enum(enum_type: EnumType, doc: Option) -> Enum { + let variants = enum_type + .values + .iter() + .map(|member| member.node.value.node.as_str().to_owned()) + .collect(); + Enum { variants, doc } +} fn to_const_field(directives: &[Positioned]) -> Option { directives.iter().find_map(|directive| { if directive.node.name.node == config::Expr::directive_name() { diff --git a/src/config/into_document.rs b/src/config/into_document.rs index 99792a426c..dac3992ab7 100644 --- a/src/config/into_document.rs +++ b/src/config/into_document.rs @@ -86,19 +86,6 @@ fn config_document(config: &ConfigModule) -> ServiceDocument { }) .collect::>>(), }) - } else if let Some(variants) = &type_def.variants { - TypeKind::Enum(EnumType { - values: variants - .iter() - .map(|value| { - pos(EnumValueDefinition { - description: None, - value: pos(Name::new(value.clone())), - directives: Vec::new(), - }) - }) - .collect(), - }) } else if config.input_types.contains(type_name) { TypeKind::InputObject(InputObjectType { fields: type_def @@ -242,6 +229,28 @@ fn config_document(config: &ConfigModule) -> ServiceDocument { }))); } + for (name, values) in config.enums.iter() { + definitions.push(TypeSystemDefinition::Type(pos(TypeDefinition { + extend: false, + description: values.doc.clone().map(pos), + name: pos(Name::new(name)), + directives: Vec::new(), + kind: TypeKind::Enum(EnumType { + values: values + .variants + .iter() + .map(|variant| { + pos(EnumValueDefinition { + description: None, + value: pos(Name::new(variant)), + directives: Vec::new(), + }) + }) + .collect(), + }), + }))); + } + ServiceDocument { definitions } } diff --git a/src/config/source.rs b/src/config/source.rs index 8bcc03b09a..e13d1241c4 100644 --- a/src/config/source.rs +++ b/src/config/source.rs @@ -1,6 +1,7 @@ use thiserror::Error; use super::Config; +use crate::valid::{ValidationError, Validator}; #[derive(Clone, Default)] pub enum Source { @@ -33,6 +34,7 @@ impl std::str::FromStr for Source { } impl Source { + /// Get the file extension for the given format pub fn ext(&self) -> &'static str { match self { Source::Json => JSON_EXT, @@ -45,12 +47,14 @@ impl Source { file.ends_with(&format!(".{}", self.ext())) } + /// Detect the config format from the file name pub fn detect(name: &str) -> Result { ALL.into_iter() .find(|format| format.ends_with(name)) .ok_or(UnsupportedConfigFormat(name.to_string())) } + /// Encode the config to the given format pub fn encode(&self, config: &Config) -> Result { match self { Source::Yml => Ok(config.to_yaml()?), @@ -58,4 +62,15 @@ impl Source { Source::Json => Ok(config.to_json(true)?), } } + + /// Decode the config from the given data + pub fn decode(&self, data: &str) -> Result> { + match self { + Source::Yml => Config::from_yaml(data).map_err(|e| ValidationError::new(e.to_string())), + Source::GraphQL => Config::from_sdl(data).to_result(), + Source::Json => { + Config::from_json(data).map_err(|e| ValidationError::new(e.to_string())) + } + } + } } diff --git a/src/document.rs b/src/document.rs index a2e776b94c..83754eac80 100644 --- a/src/document.rs +++ b/src/document.rs @@ -160,7 +160,7 @@ fn print_type_def(type_def: &TypeDefinition) -> String { } TypeKind::Enum(en) => { let directives = print_directives(&type_def.directives); - format!( + let enum_def = format!( "enum {} {}{{\n{}\n}}\n", type_def.name.node, directives, @@ -169,7 +169,14 @@ fn print_type_def(type_def: &TypeDefinition) -> String { .map(|v| format!(" {}", v.node.value)) .collect::>() .join("\n") - ) + ); + + if let Some(desc) = &type_def.description { + let ds = format!("\"\"\"\n{}\n\"\"\"\n", desc.node.as_str()); + ds + &enum_def + } else { + enum_def + } } // Handle other type kinds... } } diff --git a/src/generator/from_proto.rs b/src/generator/from_proto.rs index d86bcfa958..a7c670dad0 100644 --- a/src/generator/from_proto.rs +++ b/src/generator/from_proto.rs @@ -6,7 +6,7 @@ use prost_reflect::prost_types::{ }; use crate::blueprint::GrpcMethod; -use crate::config::{Arg, Config, Field, Grpc, Tag, Type}; +use crate::config::{Arg, Config, Enum, Field, Grpc, Tag, Type}; use crate::generator::GraphQLType; /// Assists in the mapping and retrieval of proto type names to custom formatted @@ -41,10 +41,7 @@ impl Context { /// Processes proto enum types. fn append_enums(mut self, enums: &Vec) -> Self { for enum_ in enums { - let mut ty = Type::default(); - let enum_name = enum_.name(); - ty.tag = Some(Tag { id: enum_name.to_string() }); let variants = enum_ .value @@ -57,10 +54,14 @@ impl Context { }) .collect::>(); - ty.variants = Some(variants); - - let type_name = GraphQLType::new(enum_name).as_enum().unwrap().to_string(); - self = self.insert_type(type_name, ty); + let type_name = GraphQLType::new(enum_name) + .package(&self.package) + .as_enum() + .unwrap() + .to_string(); + self.config + .enums + .insert(type_name, Enum { variants, doc: None }); } self } diff --git a/src/generator/snapshots/tailcall__generator__from_proto__test__from_proto.snap b/src/generator/snapshots/tailcall__generator__from_proto__test__from_proto.snap index 06dd410dba..0ecde2d9b1 100644 --- a/src/generator/snapshots/tailcall__generator__from_proto__test__from_proto.snap +++ b/src/generator/snapshots/tailcall__generator__from_proto__test__from_proto.snap @@ -36,6 +36,11 @@ input NEWS_NEWS_ID @tag(id: "news.NewsId") { id: Int } +enum NEWS_STATUS { + DRAFT + PUBLISHED +} + type GREETINGS_A_B_HELLO_REPLY @tag(id: "greetings_a.b.HelloReply") { message: String } diff --git a/tests/core/snapshots/execution_spec__test-enum-empty.md_errors.snap b/tests/core/snapshots/execution_spec__test-enum-empty.md_errors.snap new file mode 100644 index 0000000000..1d843257e5 --- /dev/null +++ b/tests/core/snapshots/execution_spec__test-enum-empty.md_errors.snap @@ -0,0 +1,11 @@ +--- +source: tests/core/spec.rs +expression: errors +--- +[ + { + "message": "No variants found for enum", + "trace": [], + "description": null + } +] diff --git a/tests/core/snapshots/test-enum-description.md_0.snap b/tests/core/snapshots/test-enum-description.md_0.snap new file mode 100644 index 0000000000..387e1bdea3 --- /dev/null +++ b/tests/core/snapshots/test-enum-description.md_0.snap @@ -0,0 +1,16 @@ +--- +source: tests/core/spec.rs +assertion_line: 203 +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "foo": "BAR" + } + } +} diff --git a/tests/core/snapshots/test-enum-description.md_1.snap b/tests/core/snapshots/test-enum-description.md_1.snap new file mode 100644 index 0000000000..20605473af --- /dev/null +++ b/tests/core/snapshots/test-enum-description.md_1.snap @@ -0,0 +1,16 @@ +--- +source: tests/core/spec.rs +assertion_line: 203 +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "foo": "BAZ" + } + } +} diff --git a/tests/core/snapshots/test-enum-description.md_2.snap b/tests/core/snapshots/test-enum-description.md_2.snap new file mode 100644 index 0000000000..2d7f027fd0 --- /dev/null +++ b/tests/core/snapshots/test-enum-description.md_2.snap @@ -0,0 +1,28 @@ +--- +source: tests/core/spec.rs +assertion_line: 203 +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": null, + "errors": [ + { + "message": "internal: invalid item for enum \"Foo\"", + "locations": [ + { + "line": 1, + "column": 9 + } + ], + "path": [ + "foo" + ] + } + ] + } +} diff --git a/tests/core/snapshots/test-enum-description.md_client.snap b/tests/core/snapshots/test-enum-description.md_client.snap new file mode 100644 index 0000000000..6386550a39 --- /dev/null +++ b/tests/core/snapshots/test-enum-description.md_client.snap @@ -0,0 +1,32 @@ +--- +source: tests/core/spec.rs +assertion_line: 273 +expression: client +--- +scalar Date + +scalar Email + +scalar Empty + +""" +Description of enum Foo +""" +enum Foo { + BAR + BAZ +} + +scalar JSON + +scalar PhoneNumber + +type Query { + foo(val: String!): Foo +} + +scalar Url + +schema { + query: Query +} diff --git a/tests/core/snapshots/test-enum-description.md_merged.snap b/tests/core/snapshots/test-enum-description.md_merged.snap new file mode 100644 index 0000000000..2af5958e3d --- /dev/null +++ b/tests/core/snapshots/test-enum-description.md_merged.snap @@ -0,0 +1,20 @@ +--- +source: tests/core/spec.rs +assertion_line: 234 +expression: merged +--- +schema @server @upstream(baseURL: "http://localhost:8080") { + query: Query +} + +""" +Description of enum Foo +""" +enum Foo { + BAR + BAZ +} + +type Query { + foo(val: String!): Foo @expr(body: "{{.args.val}}") +} diff --git a/tests/core/spec.rs b/tests/core/spec.rs index e93aeb28dd..f54f7b6de4 100644 --- a/tests/core/spec.rs +++ b/tests/core/spec.rs @@ -17,7 +17,7 @@ use tailcall::config::{Config, ConfigModule, Source}; use tailcall::http::{handle_request, AppContext}; use tailcall::merge_right::MergeRight; use tailcall::print_schema::print_schema; -use tailcall::valid::{Cause, ValidationError, Validator as _}; +use tailcall::valid::{Cause, ValidationError}; use super::file::File; use super::http::Http; @@ -57,11 +57,7 @@ async fn is_sdl_error(spec: ExecutionSpec, mock_http_client: Arc) -> bool // errors: errors are expected, make sure they match let (source, content) = &spec.server[0]; - if !matches!(source, Source::GraphQL) { - panic!("Cannot use \"sdl error\" directive with a non-GraphQL server block."); - } - - let config = Config::from_sdl(content).to_result(); + let config = source.decode(content); let config = match config { Ok(config) => { diff --git a/tests/execution/test-enum-description.md b/tests/execution/test-enum-description.md new file mode 100644 index 0000000000..6011cc6ac0 --- /dev/null +++ b/tests/execution/test-enum-description.md @@ -0,0 +1,40 @@ +--- +check_identity: true +--- + +# test-enum-description + +```graphql @server +schema @server @upstream(baseURL: "http://localhost:8080") { + query: Query +} + +""" +Description of enum Foo +""" +enum Foo { + BAR + BAZ +} + +type Query { + foo(val: String!): Foo @expr(body: "{{.args.val}}") +} +``` + +```yml @test +- method: POST + url: http://localhost:8080/graphql + body: + query: 'query { foo(val: "BAR") }' + +- method: POST + url: http://localhost:8080/graphql + body: + query: 'query { foo(val: "BAZ") }' + +- method: POST + url: http://localhost:8080/graphql + body: + query: 'query { foo(val: "INVALID") }' +``` diff --git a/tests/execution/test-enum-empty.md b/tests/execution/test-enum-empty.md new file mode 100644 index 0000000000..7ead01394a --- /dev/null +++ b/tests/execution/test-enum-empty.md @@ -0,0 +1,44 @@ +--- +expect_validation_error: true +--- + +# test-enum-empty + +```json @server +{ + "server": {}, + "upstream": { + "baseURL": "http://localhost:8080" + }, + "schema": { + "query": "Query" + }, + "types": { + "Query": { + "fields": { + "foo": { + "type": "Foo", + "args": { + "val": { + "type": "String", + "required": true + } + }, + "expr": { + "body": "{{.args.val}}" + }, + "cache": null, + "protected": null + } + }, + "protected": null + } + }, + "enums": { + "Foo": { + "variants": [], + "doc": null + } + } +} +``` From 7dc619139e6a73073740e951001d87a88290efe9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 07:27:11 +0000 Subject: [PATCH 05/16] fix(deps): update rust crate proc-macro2 to v1.0.82 --- Cargo.lock | 82 +++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ce95d752c4..61a4b6be5c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -288,7 +288,7 @@ dependencies = [ "async-graphql-parser", "darling 0.20.8", "proc-macro-crate", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "strum 0.26.2", "syn 2.0.61", @@ -443,7 +443,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -511,7 +511,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -528,7 +528,7 @@ version = "0.1.80" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -894,7 +894,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ "heck 0.5.0", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -1153,7 +1153,7 @@ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "strsim 0.10.0", "syn 1.0.109", @@ -1167,7 +1167,7 @@ checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "strsim 0.10.0", "syn 2.0.61", @@ -1251,7 +1251,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4ec317cc3e7ef0928b0ca6e4a634a4d6c001672ae210438cf114a83e56b018d" dependencies = [ "darling 0.14.4", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 1.0.109", ] @@ -1273,7 +1273,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e8ef033054e131169b8f0f9a7af8f5533a9436fadf3c500ed547f730f07090d" dependencies = [ "darling 0.20.8", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -1659,7 +1659,7 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -2790,7 +2790,7 @@ checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" dependencies = [ "beef", "fnv", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "regex-syntax 0.6.29", "syn 2.0.61", @@ -2805,7 +2805,7 @@ dependencies = [ "beef", "fnv", "lazy_static", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "regex-syntax 0.8.3", "syn 2.0.61", @@ -2931,7 +2931,7 @@ version = "7.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -3453,7 +3453,7 @@ checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -3558,7 +3558,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -3679,7 +3679,7 @@ version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "syn 2.0.61", ] @@ -3700,7 +3700,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 1.0.109", "version_check", @@ -3712,7 +3712,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "version_check", ] @@ -3728,9 +3728,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -3789,7 +3789,7 @@ checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" dependencies = [ "anyhow", "itertools 0.11.0", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -4018,7 +4018,7 @@ version = "1.0.36" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", ] [[package]] @@ -4287,7 +4287,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro-crate", "proc-macro-error", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "rquickjs-core", "syn 2.0.61", @@ -4490,7 +4490,7 @@ version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83263746fe5e32097f06356968a077f96089739c927a61450efa069905eec108" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "serde_derive_internals", "syn 2.0.61", @@ -4603,7 +4603,7 @@ version = "1.0.200" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -4614,7 +4614,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -4907,7 +4907,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "rustversion", "syn 2.0.61", @@ -4920,7 +4920,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "rustversion", "syn 2.0.61", @@ -4949,7 +4949,7 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "unicode-ident", ] @@ -4960,7 +4960,7 @@ version = "2.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "unicode-ident", ] @@ -5179,7 +5179,7 @@ dependencies = [ name = "tailcall-macros" version = "0.1.0" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -5305,7 +5305,7 @@ version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -5429,7 +5429,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -5548,7 +5548,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889" dependencies = [ "prettyplease", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "prost-build", "quote 1.0.36", "syn 2.0.61", @@ -5561,7 +5561,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be4ef6dd70a610078cb4e338a0f79d06bc759ff1b22d2120c2ff02ae264ba9c2" dependencies = [ "prettyplease", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "prost-build", "quote 1.0.36", "syn 2.0.61", @@ -5660,7 +5660,7 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -5975,7 +5975,7 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", "wasm-bindgen-shared", @@ -6009,7 +6009,7 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", "wasm-bindgen-backend", @@ -6342,7 +6342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a0f7f15151a77dca96813d0eff10ab9b29114533fae0267d00c466c13081e69" dependencies = [ "async-trait", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", "wasm-bindgen", @@ -6370,7 +6370,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a76ff259533532054cfbaefb115c613203c73707017459206380f03b3b3f266e" dependencies = [ "darling 0.20.8", - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] @@ -6396,7 +6396,7 @@ version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ - "proc-macro2 1.0.81", + "proc-macro2 1.0.82", "quote 1.0.36", "syn 2.0.61", ] From 5e3ca1d90577cf3838ed5fb145cc29b4ecab1b74 Mon Sep 17 00:00:00 2001 From: Kiryl Mialeshka <8974488+meskill@users.noreply.github.com> Date: Tue, 7 May 2024 09:59:59 +0200 Subject: [PATCH 06/16] chore: upgrade rustc version (#1874) Co-authored-by: Tushar Mathur --- .nightly/rust-toolchain.toml | 2 +- rust-toolchain.toml | 2 +- src/cli/javascript/request_filter.rs | 2 +- src/cli/javascript/runtime.rs | 72 +++++++++++-------- src/config/config_module.rs | 6 +- src/config/reader.rs | 4 +- src/data_loader/data_loader.rs | 16 ----- src/generator/from_proto.rs | 2 +- src/proto_reader/reader.rs | 2 +- tailcall-upstream-grpc/src/main.rs | 6 +- .../test-js-request-response-2.md_0.snap | 16 +++++ ...test-js-request-response-2.md_client.snap} | 0 ...test-js-request-response-2.md_merged.snap} | 0 ...nap => test-js-request-response.md_0.snap} | 3 +- .../test-js-request-response.md_client.snap | 24 +++++++ .../test-js-request-response.md_merged.snap | 12 ++++ tests/execution/test-js-request-response-2.md | 52 ++++++++++++++ ...reponse.md => test-js-request-response.md} | 4 +- 18 files changed, 163 insertions(+), 62 deletions(-) create mode 100644 tests/core/snapshots/test-js-request-response-2.md_0.snap rename tests/core/snapshots/{test-js-request-reponse.md_client.snap => test-js-request-response-2.md_client.snap} (100%) rename tests/core/snapshots/{test-js-request-reponse.md_merged.snap => test-js-request-response-2.md_merged.snap} (100%) rename tests/core/snapshots/{test-js-request-reponse.md_0.snap => test-js-request-response.md_0.snap} (76%) create mode 100644 tests/core/snapshots/test-js-request-response.md_client.snap create mode 100644 tests/core/snapshots/test-js-request-response.md_merged.snap create mode 100644 tests/execution/test-js-request-response-2.md rename tests/execution/{test-js-request-reponse.md => test-js-request-response.md} (94%) diff --git a/.nightly/rust-toolchain.toml b/.nightly/rust-toolchain.toml index 3a456d0670..3be5860d8f 100644 --- a/.nightly/rust-toolchain.toml +++ b/.nightly/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-02-01" +channel = "nightly-2024-05-06" profile = "default" diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 749af9f5d2..2c1a03c1ae 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "1.75" +channel = "1.78" profile = "default" diff --git a/src/cli/javascript/request_filter.rs b/src/cli/javascript/request_filter.rs index 3afe7f93d9..5cb6b653d1 100644 --- a/src/cli/javascript/request_filter.rs +++ b/src/cli/javascript/request_filter.rs @@ -53,7 +53,7 @@ pub struct RequestFilter { impl RequestFilter { pub fn new( - client: Arc, + client: Arc, worker: Arc>, ) -> Self { Self { worker, client } diff --git a/src/cli/javascript/runtime.rs b/src/cli/javascript/runtime.rs index a7211d3d5b..3f2c5cf7b0 100644 --- a/src/cli/javascript/runtime.rs +++ b/src/cli/javascript/runtime.rs @@ -10,20 +10,10 @@ use crate::{blueprint, WorkerIO}; struct LocalRuntime(Context); thread_local! { - // Practically only one JS runtime is created because CHANNEL_RUNTIME is single threaded. - // TODO: that is causing issues in `execution_spec` tests because the runtime - // is initialized only once and that implementation will be reused by all the tests + // Practically only one JS runtime is created for every Runtime because tokio_runtime is single threaded. static LOCAL_RUNTIME: RefCell> = const { RefCell::new(OnceCell::new()) }; } -// Single threaded JS runtime, that's shared across all tokio workers. -lazy_static::lazy_static! { - static ref CHANNEL_RUNTIME: tokio::runtime::Runtime = tokio::runtime::Builder::new_multi_thread() - .worker_threads(1) - .build() - .expect("JS runtime not initialized"); -} - #[rquickjs::function] fn qjs_print(msg: String, is_err: bool) { if is_err { @@ -57,11 +47,29 @@ impl LocalRuntime { pub struct Runtime { script: blueprint::Script, + // Single threaded JS runtime, that's shared across all tokio workers. + tokio_runtime: Option, } impl Runtime { pub fn new(script: blueprint::Script) -> Self { - Self { script } + let tokio_runtime = tokio::runtime::Builder::new_multi_thread() + .worker_threads(1) + .build() + .expect("JS runtime not initialized"); + + Self { script, tokio_runtime: Some(tokio_runtime) } + } +} + +impl Drop for Runtime { + fn drop(&mut self) { + // implicit call implementation to shutdown the tokio runtime + // without blocking. Otherwise it will panic on an attempt to + // drop AppContext in async runtime (e.g. in tests at least) + if let Some(runtime) = self.tokio_runtime.take() { + runtime.shutdown_background(); + } } } @@ -69,27 +77,31 @@ impl Runtime { impl WorkerIO for Runtime { async fn call(&self, name: String, event: Event) -> anyhow::Result> { let script = self.script.clone(); - CHANNEL_RUNTIME - .spawn(async move { - // initialize runtime if this is the first call - // exit if failed to initialize - LOCAL_RUNTIME.with(move |cell| { - if cell.borrow().get().is_none() { - LocalRuntime::try_new(script).and_then(|runtime| { - cell.borrow().set(runtime).map_err(|_| { - anyhow::anyhow!( + if let Some(runtime) = &self.tokio_runtime { + runtime + .spawn(async move { + // initialize runtime if this is the first call + // exit if failed to initialize + LOCAL_RUNTIME.with(move |cell| { + if cell.borrow().get().is_none() { + LocalRuntime::try_new(script).and_then(|runtime| { + cell.borrow().set(runtime).map_err(|_| { + anyhow::anyhow!( "trying to reinitialize an already initialized QuickJS runtime" ) + }) }) - }) - } else { - Ok(()) - } - })?; - - call(name, event) - }) - .await? + } else { + Ok(()) + } + })?; + + call(name, event) + }) + .await? + } else { + anyhow::bail!("JS Runtime is stopped") + } } } diff --git a/src/config/config_module.rs b/src/config/config_module.rs index f7299f2260..d750e1c702 100644 --- a/src/config/config_module.rs +++ b/src/config/config_module.rs @@ -181,14 +181,14 @@ impl ConfigModule { for field in ty.fields.values_mut() { if let Some(resolution) = resolution_map.get(&field.type_of) { if self.output_types.contains(&k) { - field.type_of = resolution.output.clone(); + field.type_of.clone_from(&resolution.output); } else if self.input_types.contains(&k) { - field.type_of = resolution.input.clone(); + field.type_of.clone_from(&resolution.input); } } for arg in field.args.values_mut() { if let Some(resolution) = resolution_map.get(&arg.type_of) { - arg.type_of = resolution.input.clone(); + arg.type_of.clone_from(&resolution.input); } } } diff --git a/src/config/reader.rs b/src/config/reader.rs index 2cebbe477e..c8a827e9a2 100644 --- a/src/config/reader.rs +++ b/src/config/reader.rs @@ -35,10 +35,10 @@ impl ConfigReader { /// Reads the links in a Config and fill the content #[async_recursion::async_recursion] - async fn ext_links<'a: 'async_recursion>( + async fn ext_links( &self, mut config_module: ConfigModule, - parent_dir: Option<&'a Path>, + parent_dir: Option<&'async_recursion Path>, ) -> anyhow::Result { let links: Vec = config_module .config diff --git a/src/data_loader/data_loader.rs b/src/data_loader/data_loader.rs index 65187d11f0..77472564e5 100644 --- a/src/data_loader/data_loader.rs +++ b/src/data_loader/data_loader.rs @@ -8,10 +8,6 @@ use std::time::Duration; use futures_channel::oneshot; use futures_timer::Delay; -#[cfg(feature = "tracing")] -use tracing::{info_span, instrument, Instrument}; -#[cfg(feature = "tracing")] -use tracinglib as tracing; pub use super::cache::NoCache; pub use super::factory::CacheFactory; @@ -108,7 +104,6 @@ where } /// Use this `DataLoader` load a data. - #[cfg_attr(feature = "tracing", instrument(skip_all))] pub async fn load_one(&self, key: K) -> Result, T::Error> where K: Send + Sync + Hash + Eq + Clone + 'static, @@ -119,7 +114,6 @@ where } /// Use this `DataLoader` to load some data. - #[cfg_attr(feature = "tracing", instrument(skip_all))] pub async fn load_many(&self, keys: I) -> Result, T::Error> where K: Send + Sync + Hash + Eq + Clone + 'static, @@ -182,10 +176,6 @@ where let inner = self.inner.clone(); let disable_cache = self.disable_cache.load(Ordering::SeqCst); let task = async move { inner.do_load(disable_cache, keys).await }; - #[cfg(feature = "tracing")] - let task = task - .instrument(info_span!("immediate_load")) - .in_current_span(); #[cfg(not(target_arch = "wasm32"))] tokio::spawn(Box::pin(task)); @@ -209,8 +199,6 @@ where inner.do_load(disable_cache, keys).await } }; - #[cfg(feature = "tracing")] - let task = task.instrument(info_span!("start_fetch")).in_current_span(); #[cfg(not(target_arch = "wasm32"))] tokio::spawn(Box::pin(task)); #[cfg(target_arch = "wasm32")] @@ -226,7 +214,6 @@ where /// /// **NOTE: If the cache type is [NoCache], this function will not take /// effect. ** - #[cfg_attr(feature = "tracing", instrument(skip_all))] pub async fn feed_many(&self, values: I) where K: Send + Sync + Hash + Eq + Clone + 'static, @@ -245,7 +232,6 @@ where /// /// **NOTE: If the cache type is [NoCache], this function will not take /// effect. ** - #[cfg_attr(feature = "tracing", instrument(skip_all))] pub async fn feed_one(&self, key: K, value: T::Value) where K: Send + Sync + Hash + Eq + Clone + 'static, @@ -258,7 +244,6 @@ where /// /// **NOTE: If the cache type is [NoCache], this function will not take /// effect. ** - #[cfg_attr(feature = "tracing", instrument(skip_all))] pub fn clear(&self) where K: Send + Sync + Hash + Eq + Clone + 'static, @@ -339,7 +324,6 @@ where T: Loader, C: CacheFactory, { - #[cfg_attr(feature = "tracing", instrument(skip_all))] async fn do_load(&self, disable_cache: bool, (keys, senders): KeysAndSender) where K: Send + Sync + Hash + Eq + Clone + 'static, diff --git a/src/generator/from_proto.rs b/src/generator/from_proto.rs index a7c670dad0..5bfe367df9 100644 --- a/src/generator/from_proto.rs +++ b/src/generator/from_proto.rs @@ -178,7 +178,7 @@ impl Context { cfg_field.type_of = output_ty; cfg_field.required = true; - grpc_method.service = service_name.clone(); + grpc_method.service.clone_from(&service_name); grpc_method.name = field_name.to_string(); cfg_field.grpc = Some(Grpc { diff --git a/src/proto_reader/reader.rs b/src/proto_reader/reader.rs index 8b3327f06a..464d5f029f 100644 --- a/src/proto_reader/reader.rs +++ b/src/proto_reader/reader.rs @@ -93,7 +93,7 @@ impl ProtoReader { for result in results { let proto = result?; - if descriptors.get(proto.name()).is_none() { + if !descriptors.contains_key(proto.name()) { queue.push_back(proto.clone()); descriptors.insert(proto.name().to_string(), proto); } diff --git a/tailcall-upstream-grpc/src/main.rs b/tailcall-upstream-grpc/src/main.rs index 707aa3f437..d82e3e9a52 100644 --- a/tailcall-upstream-grpc/src/main.rs +++ b/tailcall-upstream-grpc/src/main.rs @@ -140,9 +140,9 @@ impl NewsService for MyNewsService { let new_news = request.into_inner(); let mut lock = self.news.lock().unwrap(); if let Some(news) = lock.iter_mut().find(|n| n.id == new_news.id) { - news.title = new_news.title.clone(); - news.body = new_news.body.clone(); - news.post_image = new_news.post_image.clone(); + news.title.clone_from(&new_news.title); + news.body.clone_from(&new_news.body); + news.post_image.clone_from(&new_news.post_image); return Ok(Response::new(new_news)); } Err(Status::not_found("News not found")) diff --git a/tests/core/snapshots/test-js-request-response-2.md_0.snap b/tests/core/snapshots/test-js-request-response-2.md_0.snap new file mode 100644 index 0000000000..e06b77077f --- /dev/null +++ b/tests/core/snapshots/test-js-request-response-2.md_0.snap @@ -0,0 +1,16 @@ +--- +source: tests/core/spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "hello": "darkness", + "hi": "I've come to talk with you again" + } + } +} diff --git a/tests/core/snapshots/test-js-request-reponse.md_client.snap b/tests/core/snapshots/test-js-request-response-2.md_client.snap similarity index 100% rename from tests/core/snapshots/test-js-request-reponse.md_client.snap rename to tests/core/snapshots/test-js-request-response-2.md_client.snap diff --git a/tests/core/snapshots/test-js-request-reponse.md_merged.snap b/tests/core/snapshots/test-js-request-response-2.md_merged.snap similarity index 100% rename from tests/core/snapshots/test-js-request-reponse.md_merged.snap rename to tests/core/snapshots/test-js-request-response-2.md_merged.snap diff --git a/tests/core/snapshots/test-js-request-reponse.md_0.snap b/tests/core/snapshots/test-js-request-response.md_0.snap similarity index 76% rename from tests/core/snapshots/test-js-request-reponse.md_0.snap rename to tests/core/snapshots/test-js-request-response.md_0.snap index feebdc4cda..e5cf278cca 100644 --- a/tests/core/snapshots/test-js-request-reponse.md_0.snap +++ b/tests/core/snapshots/test-js-request-response.md_0.snap @@ -9,7 +9,8 @@ expression: response }, "body": { "data": { - "hi": "hello world" + "hello": "hello world", + "hi": "bye world" } } } diff --git a/tests/core/snapshots/test-js-request-response.md_client.snap b/tests/core/snapshots/test-js-request-response.md_client.snap new file mode 100644 index 0000000000..234db86478 --- /dev/null +++ b/tests/core/snapshots/test-js-request-response.md_client.snap @@ -0,0 +1,24 @@ +--- +source: tests/core/spec.rs +expression: client +--- +scalar Date + +scalar Email + +scalar Empty + +scalar JSON + +scalar PhoneNumber + +type Query { + hello: String + hi: String +} + +scalar Url + +schema { + query: Query +} diff --git a/tests/core/snapshots/test-js-request-response.md_merged.snap b/tests/core/snapshots/test-js-request-response.md_merged.snap new file mode 100644 index 0000000000..74acf0b4ff --- /dev/null +++ b/tests/core/snapshots/test-js-request-response.md_merged.snap @@ -0,0 +1,12 @@ +--- +source: tests/core/spec.rs +expression: merged +--- +schema @server @upstream @link(src: "test.js", type: Script) { + query: Query +} + +type Query { + hello: String @http(baseURL: "http://localhost:3000", path: "/hello") + hi: String @http(baseURL: "http://localhost:3000", path: "/hi") +} diff --git a/tests/execution/test-js-request-response-2.md b/tests/execution/test-js-request-response-2.md new file mode 100644 index 0000000000..30ede242c7 --- /dev/null +++ b/tests/execution/test-js-request-response-2.md @@ -0,0 +1,52 @@ +# Js Request Response Hello World + +This test is just a mirror of existing `test-js-request-response.md` but with changed values. It exists to test that js runtime is created separately for every app_ctx and they not interfere with each other. + +```js @file:test.js +function onRequest({request}) { + if (request.uri.path.endsWith("/hello")) { + return { + response: { + status: 200, + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify("darkness"), + }, + } + } else if (request.uri.path.endsWith("/hi")) { + request.uri.path = "/old-friend" + console.log({request}) + return {request} + } else { + return {request} + } +} +``` + +```graphql @server +schema @server @link(type: Script, src: "test.js") { + query: Query +} + +type Query { + hello: String @http(baseURL: "http://localhost:3000", path: "/hello") + hi: String @http(baseURL: "http://localhost:3000", path: "/hi") +} +``` + +```yml @mock +- request: + method: GET + url: http://localhost:3000/old-friend + response: + status: 200 + body: I've come to talk with you again +``` + +```yml @test +- method: POST + url: http://localhost:8080/graphql + body: + query: query { hello hi } +``` diff --git a/tests/execution/test-js-request-reponse.md b/tests/execution/test-js-request-response.md similarity index 94% rename from tests/execution/test-js-request-reponse.md rename to tests/execution/test-js-request-response.md index 6ed9a02701..9e61ecf008 100644 --- a/tests/execution/test-js-request-reponse.md +++ b/tests/execution/test-js-request-response.md @@ -39,12 +39,12 @@ type Query { url: http://localhost:3000/bye response: status: 200 - body: hello world + body: bye world ``` ```yml @test - method: POST url: http://localhost:8080/graphql body: - query: query { hi } + query: query { hello hi } ``` From 1f96a3f35b623e402c98b4a70ec275086ef712f3 Mon Sep 17 00:00:00 2001 From: Tushar Mathur Date: Tue, 7 May 2024 14:12:29 +0530 Subject: [PATCH 07/16] chore: update test file names --- ...md_errors.snap => auth-protected-without-auth.md_error.snap} | 0 ...md_errors.snap => cors-invalid-expose-headers.md_error.snap} | 0 ...eaders.md_errors.snap => cors-invalid-headers.md_error.snap} | 0 ...ethods.md_errors.snap => cors-invalid-methods.md_error.snap} | 0 ...rigins.md_errors.snap => cors-invalid-origins.md_error.snap} | 0 ....md_errors.snap => experimental-headers-error.md_error.snap} | 0 ....md_errors.snap => input-type-protected-error.md_error.snap} | 0 ...-error.md_errors.snap => test-add-field-error.md_error.snap} | 0 ...s.md_errors.snap => test-all-blueprint-errors.md_error.snap} | 0 ...st.md_errors.snap => test-batch-operator-post.md_error.snap} | 0 ...s.md_errors.snap => test-call-operator-errors.md_error.snap} | 0 ...ge-many.md_errors.snap => test-dbl-usage-many.md_error.snap} | 0 ...st-dbl-usage.md_errors.snap => test-dbl-usage.md_error.snap} | 0 ...ors.snap => test-directives-undef-null-fields.md_error.snap} | 0 ...d-link.md_errors.snap => test-duplicated-link.md_error.snap} | 0 ...-empty-link.md_errors.snap => test-empty-link.md_error.snap} | 0 ...-enum-empty.md_errors.snap => test-enum-empty.md_error.snap} | 0 ...-expr-error.md_errors.snap => test-expr-error.md_error.snap} | 0 ...ld.md_errors.snap => test-expr-with-add-field.md_error.snap} | 0 ...nline.md_errors.snap => test-expr-with-inline.md_error.snap} | 0 ...test-field-already-implemented-from-Interface.md_error.snap} | 0 ...errors.snap => test-graphqlsource-no-base-url.md_error.snap} | 0 ..._errors.snap => test-groupby-without-batching.md_error.snap} | 0 ...group-by.md_errors.snap => test-grpc-group-by.md_error.snap} | 0 ...rrors.snap => test-grpc-invalid-method-format.md_error.snap} | 0 ....md_errors.snap => test-grpc-invalid-proto-id.md_error.snap} | 0 ...ds.md_errors.snap => test-grpc-missing-fields.md_error.snap} | 0 ...-data.md_errors.snap => test-grpc-nested-data.md_error.snap} | 0 ...l.md_errors.snap => test-grpc-nested-optional.md_error.snap} | 0 ...optional.md_errors.snap => test-grpc-optional.md_error.snap} | 0 ...o-path.md_errors.snap => test-grpc-proto-path.md_error.snap} | 0 ...od.md_errors.snap => test-grpc-service-method.md_error.snap} | 0 ...c-service.md_errors.snap => test-grpc-service.md_error.snap} | 0 ...liure.md_errors.snap => test-hostname-faliure.md_error.snap} | 0 ...ld.md_errors.snap => test-http-with-add-field.md_error.snap} | 0 ...nline.md_errors.snap => test-http-with-inline.md_error.snap} | 0 ...ine-error.md_errors.snap => test-inline-error.md_error.snap} | 0 ....md_errors.snap => test-invalid-query-in-http.md_error.snap} | 0 ...-server.md_errors.snap => test-invalid-server.md_error.snap} | 0 ...ts.md_errors.snap => test-js-multiple-scripts.md_error.snap} | 0 ...resolver.md_errors.snap => test-lack-resolver.md_error.snap} | 0 ...nap => test-missing-argument-on-all-resolvers.md_error.snap} | 0 ...errors.snap => test-missing-mutation-resolver.md_error.snap} | 0 ...md_errors.snap => test-missing-query-resolver.md_error.snap} | 0 ...pes.md_errors.snap => test-missing-root-types.md_error.snap} | 0 ...y.md_errors.snap => test-missing-schema-query.md_error.snap} | 0 ... test-multiple-resolvable-directives-on-field.md_error.snap} | 0 ...o-base-url.md_errors.snap => test-no-base-url.md_error.snap} | 0 ....md_errors.snap => test-response-header-value.md_error.snap} | 0 ...md_errors.snap => test-response-headers-multi.md_error.snap} | 0 ....md_errors.snap => test-response-headers-name.md_error.snap} | 0 ...-query.md_errors.snap => test-undefined-query.md_error.snap} | 0 ...md_errors.snap => undeclared-type-no-base-url.md_error.snap} | 0 ...clared-type.md_errors.snap => undeclared-type.md_error.snap} | 0 tests/core/spec.rs | 2 +- 55 files changed, 1 insertion(+), 1 deletion(-) rename tests/core/snapshots/{execution_spec__auth-protected-without-auth.md_errors.snap => auth-protected-without-auth.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__cors-invalid-expose-headers.md_errors.snap => cors-invalid-expose-headers.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__cors-invalid-headers.md_errors.snap => cors-invalid-headers.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__cors-invalid-methods.md_errors.snap => cors-invalid-methods.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__cors-invalid-origins.md_errors.snap => cors-invalid-origins.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__experimental-headers-error.md_errors.snap => experimental-headers-error.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__input-type-protected-error.md_errors.snap => input-type-protected-error.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-add-field-error.md_errors.snap => test-add-field-error.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-all-blueprint-errors.md_errors.snap => test-all-blueprint-errors.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-batch-operator-post.md_errors.snap => test-batch-operator-post.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-call-operator-errors.md_errors.snap => test-call-operator-errors.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-dbl-usage-many.md_errors.snap => test-dbl-usage-many.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-dbl-usage.md_errors.snap => test-dbl-usage.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-directives-undef-null-fields.md_errors.snap => test-directives-undef-null-fields.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-duplicated-link.md_errors.snap => test-duplicated-link.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-empty-link.md_errors.snap => test-empty-link.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-enum-empty.md_errors.snap => test-enum-empty.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-expr-error.md_errors.snap => test-expr-error.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-expr-with-add-field.md_errors.snap => test-expr-with-add-field.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-expr-with-inline.md_errors.snap => test-expr-with-inline.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-field-already-implemented-from-Interface.md_errors.snap => test-field-already-implemented-from-Interface.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-graphqlsource-no-base-url.md_errors.snap => test-graphqlsource-no-base-url.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-groupby-without-batching.md_errors.snap => test-groupby-without-batching.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-group-by.md_errors.snap => test-grpc-group-by.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-invalid-method-format.md_errors.snap => test-grpc-invalid-method-format.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-invalid-proto-id.md_errors.snap => test-grpc-invalid-proto-id.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-missing-fields.md_errors.snap => test-grpc-missing-fields.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-nested-data.md_errors.snap => test-grpc-nested-data.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-nested-optional.md_errors.snap => test-grpc-nested-optional.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-optional.md_errors.snap => test-grpc-optional.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-proto-path.md_errors.snap => test-grpc-proto-path.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-service-method.md_errors.snap => test-grpc-service-method.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-grpc-service.md_errors.snap => test-grpc-service.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-hostname-faliure.md_errors.snap => test-hostname-faliure.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-http-with-add-field.md_errors.snap => test-http-with-add-field.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-http-with-inline.md_errors.snap => test-http-with-inline.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-inline-error.md_errors.snap => test-inline-error.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-invalid-query-in-http.md_errors.snap => test-invalid-query-in-http.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-invalid-server.md_errors.snap => test-invalid-server.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-js-multiple-scripts.md_errors.snap => test-js-multiple-scripts.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-lack-resolver.md_errors.snap => test-lack-resolver.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-missing-argument-on-all-resolvers.md_errors.snap => test-missing-argument-on-all-resolvers.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-missing-mutation-resolver.md_errors.snap => test-missing-mutation-resolver.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-missing-query-resolver.md_errors.snap => test-missing-query-resolver.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-missing-root-types.md_errors.snap => test-missing-root-types.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-missing-schema-query.md_errors.snap => test-missing-schema-query.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-multiple-resolvable-directives-on-field.md_errors.snap => test-multiple-resolvable-directives-on-field.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-no-base-url.md_errors.snap => test-no-base-url.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-response-header-value.md_errors.snap => test-response-header-value.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-response-headers-multi.md_errors.snap => test-response-headers-multi.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-response-headers-name.md_errors.snap => test-response-headers-name.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__test-undefined-query.md_errors.snap => test-undefined-query.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__undeclared-type-no-base-url.md_errors.snap => undeclared-type-no-base-url.md_error.snap} (100%) rename tests/core/snapshots/{execution_spec__undeclared-type.md_errors.snap => undeclared-type.md_error.snap} (100%) diff --git a/tests/core/snapshots/execution_spec__auth-protected-without-auth.md_errors.snap b/tests/core/snapshots/auth-protected-without-auth.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__auth-protected-without-auth.md_errors.snap rename to tests/core/snapshots/auth-protected-without-auth.md_error.snap diff --git a/tests/core/snapshots/execution_spec__cors-invalid-expose-headers.md_errors.snap b/tests/core/snapshots/cors-invalid-expose-headers.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__cors-invalid-expose-headers.md_errors.snap rename to tests/core/snapshots/cors-invalid-expose-headers.md_error.snap diff --git a/tests/core/snapshots/execution_spec__cors-invalid-headers.md_errors.snap b/tests/core/snapshots/cors-invalid-headers.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__cors-invalid-headers.md_errors.snap rename to tests/core/snapshots/cors-invalid-headers.md_error.snap diff --git a/tests/core/snapshots/execution_spec__cors-invalid-methods.md_errors.snap b/tests/core/snapshots/cors-invalid-methods.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__cors-invalid-methods.md_errors.snap rename to tests/core/snapshots/cors-invalid-methods.md_error.snap diff --git a/tests/core/snapshots/execution_spec__cors-invalid-origins.md_errors.snap b/tests/core/snapshots/cors-invalid-origins.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__cors-invalid-origins.md_errors.snap rename to tests/core/snapshots/cors-invalid-origins.md_error.snap diff --git a/tests/core/snapshots/execution_spec__experimental-headers-error.md_errors.snap b/tests/core/snapshots/experimental-headers-error.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__experimental-headers-error.md_errors.snap rename to tests/core/snapshots/experimental-headers-error.md_error.snap diff --git a/tests/core/snapshots/execution_spec__input-type-protected-error.md_errors.snap b/tests/core/snapshots/input-type-protected-error.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__input-type-protected-error.md_errors.snap rename to tests/core/snapshots/input-type-protected-error.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-add-field-error.md_errors.snap b/tests/core/snapshots/test-add-field-error.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-add-field-error.md_errors.snap rename to tests/core/snapshots/test-add-field-error.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-all-blueprint-errors.md_errors.snap b/tests/core/snapshots/test-all-blueprint-errors.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-all-blueprint-errors.md_errors.snap rename to tests/core/snapshots/test-all-blueprint-errors.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-batch-operator-post.md_errors.snap b/tests/core/snapshots/test-batch-operator-post.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-batch-operator-post.md_errors.snap rename to tests/core/snapshots/test-batch-operator-post.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-call-operator-errors.md_errors.snap b/tests/core/snapshots/test-call-operator-errors.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-call-operator-errors.md_errors.snap rename to tests/core/snapshots/test-call-operator-errors.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-dbl-usage-many.md_errors.snap b/tests/core/snapshots/test-dbl-usage-many.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-dbl-usage-many.md_errors.snap rename to tests/core/snapshots/test-dbl-usage-many.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-dbl-usage.md_errors.snap b/tests/core/snapshots/test-dbl-usage.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-dbl-usage.md_errors.snap rename to tests/core/snapshots/test-dbl-usage.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-directives-undef-null-fields.md_errors.snap b/tests/core/snapshots/test-directives-undef-null-fields.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-directives-undef-null-fields.md_errors.snap rename to tests/core/snapshots/test-directives-undef-null-fields.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-duplicated-link.md_errors.snap b/tests/core/snapshots/test-duplicated-link.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-duplicated-link.md_errors.snap rename to tests/core/snapshots/test-duplicated-link.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-empty-link.md_errors.snap b/tests/core/snapshots/test-empty-link.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-empty-link.md_errors.snap rename to tests/core/snapshots/test-empty-link.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-enum-empty.md_errors.snap b/tests/core/snapshots/test-enum-empty.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-enum-empty.md_errors.snap rename to tests/core/snapshots/test-enum-empty.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-expr-error.md_errors.snap b/tests/core/snapshots/test-expr-error.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-expr-error.md_errors.snap rename to tests/core/snapshots/test-expr-error.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-expr-with-add-field.md_errors.snap b/tests/core/snapshots/test-expr-with-add-field.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-expr-with-add-field.md_errors.snap rename to tests/core/snapshots/test-expr-with-add-field.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-expr-with-inline.md_errors.snap b/tests/core/snapshots/test-expr-with-inline.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-expr-with-inline.md_errors.snap rename to tests/core/snapshots/test-expr-with-inline.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-field-already-implemented-from-Interface.md_errors.snap b/tests/core/snapshots/test-field-already-implemented-from-Interface.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-field-already-implemented-from-Interface.md_errors.snap rename to tests/core/snapshots/test-field-already-implemented-from-Interface.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-graphqlsource-no-base-url.md_errors.snap b/tests/core/snapshots/test-graphqlsource-no-base-url.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-graphqlsource-no-base-url.md_errors.snap rename to tests/core/snapshots/test-graphqlsource-no-base-url.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-groupby-without-batching.md_errors.snap b/tests/core/snapshots/test-groupby-without-batching.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-groupby-without-batching.md_errors.snap rename to tests/core/snapshots/test-groupby-without-batching.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-group-by.md_errors.snap b/tests/core/snapshots/test-grpc-group-by.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-group-by.md_errors.snap rename to tests/core/snapshots/test-grpc-group-by.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-invalid-method-format.md_errors.snap b/tests/core/snapshots/test-grpc-invalid-method-format.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-invalid-method-format.md_errors.snap rename to tests/core/snapshots/test-grpc-invalid-method-format.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-invalid-proto-id.md_errors.snap b/tests/core/snapshots/test-grpc-invalid-proto-id.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-invalid-proto-id.md_errors.snap rename to tests/core/snapshots/test-grpc-invalid-proto-id.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-missing-fields.md_errors.snap b/tests/core/snapshots/test-grpc-missing-fields.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-missing-fields.md_errors.snap rename to tests/core/snapshots/test-grpc-missing-fields.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-nested-data.md_errors.snap b/tests/core/snapshots/test-grpc-nested-data.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-nested-data.md_errors.snap rename to tests/core/snapshots/test-grpc-nested-data.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-nested-optional.md_errors.snap b/tests/core/snapshots/test-grpc-nested-optional.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-nested-optional.md_errors.snap rename to tests/core/snapshots/test-grpc-nested-optional.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-optional.md_errors.snap b/tests/core/snapshots/test-grpc-optional.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-optional.md_errors.snap rename to tests/core/snapshots/test-grpc-optional.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-proto-path.md_errors.snap b/tests/core/snapshots/test-grpc-proto-path.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-proto-path.md_errors.snap rename to tests/core/snapshots/test-grpc-proto-path.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-service-method.md_errors.snap b/tests/core/snapshots/test-grpc-service-method.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-service-method.md_errors.snap rename to tests/core/snapshots/test-grpc-service-method.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-grpc-service.md_errors.snap b/tests/core/snapshots/test-grpc-service.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-grpc-service.md_errors.snap rename to tests/core/snapshots/test-grpc-service.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-hostname-faliure.md_errors.snap b/tests/core/snapshots/test-hostname-faliure.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-hostname-faliure.md_errors.snap rename to tests/core/snapshots/test-hostname-faliure.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-http-with-add-field.md_errors.snap b/tests/core/snapshots/test-http-with-add-field.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-http-with-add-field.md_errors.snap rename to tests/core/snapshots/test-http-with-add-field.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-http-with-inline.md_errors.snap b/tests/core/snapshots/test-http-with-inline.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-http-with-inline.md_errors.snap rename to tests/core/snapshots/test-http-with-inline.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-inline-error.md_errors.snap b/tests/core/snapshots/test-inline-error.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-inline-error.md_errors.snap rename to tests/core/snapshots/test-inline-error.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-invalid-query-in-http.md_errors.snap b/tests/core/snapshots/test-invalid-query-in-http.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-invalid-query-in-http.md_errors.snap rename to tests/core/snapshots/test-invalid-query-in-http.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-invalid-server.md_errors.snap b/tests/core/snapshots/test-invalid-server.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-invalid-server.md_errors.snap rename to tests/core/snapshots/test-invalid-server.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-js-multiple-scripts.md_errors.snap b/tests/core/snapshots/test-js-multiple-scripts.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-js-multiple-scripts.md_errors.snap rename to tests/core/snapshots/test-js-multiple-scripts.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-lack-resolver.md_errors.snap b/tests/core/snapshots/test-lack-resolver.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-lack-resolver.md_errors.snap rename to tests/core/snapshots/test-lack-resolver.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-missing-argument-on-all-resolvers.md_errors.snap b/tests/core/snapshots/test-missing-argument-on-all-resolvers.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-missing-argument-on-all-resolvers.md_errors.snap rename to tests/core/snapshots/test-missing-argument-on-all-resolvers.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-missing-mutation-resolver.md_errors.snap b/tests/core/snapshots/test-missing-mutation-resolver.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-missing-mutation-resolver.md_errors.snap rename to tests/core/snapshots/test-missing-mutation-resolver.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-missing-query-resolver.md_errors.snap b/tests/core/snapshots/test-missing-query-resolver.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-missing-query-resolver.md_errors.snap rename to tests/core/snapshots/test-missing-query-resolver.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-missing-root-types.md_errors.snap b/tests/core/snapshots/test-missing-root-types.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-missing-root-types.md_errors.snap rename to tests/core/snapshots/test-missing-root-types.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-missing-schema-query.md_errors.snap b/tests/core/snapshots/test-missing-schema-query.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-missing-schema-query.md_errors.snap rename to tests/core/snapshots/test-missing-schema-query.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-multiple-resolvable-directives-on-field.md_errors.snap b/tests/core/snapshots/test-multiple-resolvable-directives-on-field.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-multiple-resolvable-directives-on-field.md_errors.snap rename to tests/core/snapshots/test-multiple-resolvable-directives-on-field.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-no-base-url.md_errors.snap b/tests/core/snapshots/test-no-base-url.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-no-base-url.md_errors.snap rename to tests/core/snapshots/test-no-base-url.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-response-header-value.md_errors.snap b/tests/core/snapshots/test-response-header-value.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-response-header-value.md_errors.snap rename to tests/core/snapshots/test-response-header-value.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-response-headers-multi.md_errors.snap b/tests/core/snapshots/test-response-headers-multi.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-response-headers-multi.md_errors.snap rename to tests/core/snapshots/test-response-headers-multi.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-response-headers-name.md_errors.snap b/tests/core/snapshots/test-response-headers-name.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-response-headers-name.md_errors.snap rename to tests/core/snapshots/test-response-headers-name.md_error.snap diff --git a/tests/core/snapshots/execution_spec__test-undefined-query.md_errors.snap b/tests/core/snapshots/test-undefined-query.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__test-undefined-query.md_errors.snap rename to tests/core/snapshots/test-undefined-query.md_error.snap diff --git a/tests/core/snapshots/execution_spec__undeclared-type-no-base-url.md_errors.snap b/tests/core/snapshots/undeclared-type-no-base-url.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__undeclared-type-no-base-url.md_errors.snap rename to tests/core/snapshots/undeclared-type-no-base-url.md_error.snap diff --git a/tests/core/snapshots/execution_spec__undeclared-type.md_errors.snap b/tests/core/snapshots/undeclared-type.md_error.snap similarity index 100% rename from tests/core/snapshots/execution_spec__undeclared-type.md_errors.snap rename to tests/core/snapshots/undeclared-type.md_error.snap diff --git a/tests/core/spec.rs b/tests/core/spec.rs index f54f7b6de4..e39c3e1002 100644 --- a/tests/core/spec.rs +++ b/tests/core/spec.rs @@ -84,7 +84,7 @@ async fn is_sdl_error(spec: ExecutionSpec, mock_http_client: Arc) -> bool let errors: Vec = cause.as_vec().iter().map(|e| e.to_owned().into()).collect(); - let snapshot_name = format!("execution_spec__{}_errors", spec.safe_name); + let snapshot_name = format!("{}_error", spec.safe_name); insta::assert_json_snapshot!(snapshot_name, errors); } From e77b43e528dc4c0eca6f14e3b0f77628e8777da9 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 10:13:37 +0000 Subject: [PATCH 08/16] fix(deps): update rust crate rustls-pki-types to v1.6.0 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 61a4b6be5c..7f74825761 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4417,9 +4417,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.5.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" +checksum = "51f344d206c5e1b010eec27349b815a4805f70a778895959d70b74b9b529b30a" [[package]] name = "rustls-webpki" From 756a56f7c35967e671fb4d7990d9d6d000600ff1 Mon Sep 17 00:00:00 2001 From: Amit Singh Date: Tue, 7 May 2024 20:12:20 +0530 Subject: [PATCH 09/16] fix: track usage metrics (#1875) Co-authored-by: Tushar Mathur --- Cargo.lock | 280 ++++++++++++++++++++++++- Cargo.toml | 9 +- src/cli/command.rs | 3 +- src/cli/tc.rs | 15 ++ tailcall-tracker/Cargo.toml | 17 ++ tailcall-tracker/src/check_tracking.rs | 52 +++++ tailcall-tracker/src/event.rs | 52 +++++ tailcall-tracker/src/lib.rs | 4 + tailcall-tracker/src/tracker.rs | 76 +++++++ 9 files changed, 499 insertions(+), 9 deletions(-) create mode 100644 tailcall-tracker/Cargo.toml create mode 100644 tailcall-tracker/src/check_tracking.rs create mode 100644 tailcall-tracker/src/event.rs create mode 100644 tailcall-tracker/src/lib.rs create mode 100644 tailcall-tracker/src/tracker.rs diff --git a/Cargo.lock b/Cargo.lock index 7f74825761..ef92e52f36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -815,6 +815,7 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-targets 0.52.5", ] @@ -1301,6 +1302,7 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "crypto-common", + "subtle", ] [[package]] @@ -1557,6 +1559,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2038,6 +2055,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hmac" version = "0.10.1" @@ -2048,6 +2071,15 @@ dependencies = [ "digest 0.9.0", ] +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "home" version = "0.5.9" @@ -2317,6 +2349,19 @@ dependencies = [ "tokio-io-timeout", ] +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.28", + "native-tls", + "tokio", + "tokio-native-tls", +] + [[package]] name = "hyper-util" version = "0.1.3" @@ -2856,6 +2901,26 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "machineid-rs" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ceb4d434d69d7199abc3036541ba6ef86767a4356e3077d5a3419f85b70b14" +dependencies = [ + "hex", + "hmac 0.12.1", + "md-5 0.10.6", + "serde", + "serde_json", + "sha-1 0.10.1", + "sha2 0.10.8", + "sysinfo 0.29.11", + "uuid", + "whoami", + "winreg 0.11.0", + "wmi", +] + [[package]] name = "maplit" version = "1.0.2" @@ -3036,6 +3101,24 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3181,12 +3264,50 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.36", + "syn 2.0.61", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "opentelemetry" version = "0.21.0" @@ -3321,7 +3442,7 @@ dependencies = [ "indexmap 1.9.3", "nvml-wrapper", "opentelemetry 0.22.0", - "sysinfo", + "sysinfo 0.29.11", "tracing", ] @@ -3586,6 +3707,12 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + [[package]] name = "plotters" version = "0.3.5" @@ -3961,10 +4088,10 @@ checksum = "419a3ad8fa9f9d445e69d9b185a24878ae6e6f55c96e4512f4a0e28cd3bc5c56" dependencies = [ "blowfish 0.7.0", "byteorder", - "hmac", + "hmac 0.10.1", "md-5 0.9.1", "rand", - "sha-1", + "sha-1 0.9.8", "sha2 0.9.9", ] @@ -4178,11 +4305,13 @@ dependencies = [ "http-body 0.4.6", "hyper 0.14.28", "hyper-rustls 0.24.2", + "hyper-tls", "ipnet", "js-sys", "log", "mime", "mime_guess", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -4194,6 +4323,7 @@ dependencies = [ "sync_wrapper", "system-configuration", "tokio", + "tokio-native-tls", "tokio-rustls 0.24.1", "tower-service", "url", @@ -4201,7 +4331,7 @@ dependencies = [ "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg", + "winreg 0.50.0", ] [[package]] @@ -4700,6 +4830,17 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + [[package]] name = "sha1" version = "0.10.6" @@ -4986,6 +5127,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "sysinfo" +version = "0.30.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732ffa00f53e6b2af46208fba5718d9662a421049204e156328b66791ffa15ae" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows 0.52.0", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -5097,6 +5253,7 @@ dependencies = [ "tailcall-fixtures", "tailcall-macros", "tailcall-prettier", + "tailcall-tracker", "temp-env", "tempfile", "thiserror", @@ -5194,6 +5351,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "tailcall-tracker" +version = "0.1.0" +dependencies = [ + "anyhow", + "lazy_static", + "machineid-rs", + "reqwest", + "serde", + "serde_json", + "sysinfo 0.30.12", + "tokio", + "tracing", +] + [[package]] name = "tailcall-upstream-grpc" version = "0.1.0" @@ -5434,6 +5606,16 @@ dependencies = [ "syn 2.0.61", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -5919,6 +6101,12 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.4" @@ -5956,6 +6144,12 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" version = "0.2.92" @@ -6085,6 +6279,17 @@ dependencies = [ "winsafe", ] +[[package]] +name = "whoami" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall", + "wasite", + "web-sys", +] + [[package]] name = "winapi" version = "0.3.9" @@ -6116,6 +6321,27 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -6125,6 +6351,28 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "windows-implement" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.36", + "syn 1.0.109", +] + +[[package]] +name = "windows-interface" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.36", + "syn 1.0.109", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -6273,6 +6521,16 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a1a57ff50e9b408431e8f97d5456f2807f8eb2a2cd79b06068fc87f8ecf189" +dependencies = [ + "cfg-if", + "winapi", +] + [[package]] name = "winreg" version = "0.50.0" @@ -6289,6 +6547,20 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" +[[package]] +name = "wmi" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daffb44abb7d2e87a1233aa17fdbde0d55b890b32a23a1f908895b87fa6f1a00" +dependencies = [ + "chrono", + "futures", + "log", + "serde", + "thiserror", + "windows 0.48.0", +] + [[package]] name = "worker" version = "0.2.0" diff --git a/Cargo.toml b/Cargo.toml index 3fcf38d835..f25e78cd80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -142,14 +142,14 @@ dotenvy = "0.15.7" convert_case = "0.6.0" rand = "0.8.5" tailcall-macros = { path = "tailcall-macros" } +tailcall-tracker = { path = "tailcall-tracker", optional = true } tonic-types = "0.11.0" datatest-stable = "0.2.9" tokio-test = "0.4.4" base64 = "0.22.1" - [dev-dependencies] -tailcall-prettier = {path = "tailcall-prettier"} +tailcall-prettier = { path = "tailcall-prettier" } criterion = "0.5.1" httpmock = "0.7.0" pretty_assertions = "1.4.0" @@ -185,6 +185,7 @@ cli = [ "opentelemetry_sdk/rt-tokio", "dep:opentelemetry-otlp", "dep:opentelemetry-system-metrics", + "dep:tailcall-tracker" ] # Feature flag to enable all default features. @@ -203,8 +204,8 @@ members = [ "tailcall-prettier", "tailcall-query-plan", "tailcall-fixtures", - "tailcall-upstream-grpc" -] + "tailcall-upstream-grpc", + "tailcall-tracker"] # Boost execution_spec snapshot diffing performance [profile.dev.package] diff --git a/src/cli/command.rs b/src/cli/command.rs index c79fe9efbb..7b89104e2d 100644 --- a/src/cli/command.rs +++ b/src/cli/command.rs @@ -1,4 +1,5 @@ use clap::{Parser, Subcommand}; +use strum_macros::Display; use crate::{config, generator}; @@ -20,7 +21,7 @@ pub struct Cli { pub command: Command, } -#[derive(Subcommand)] +#[derive(Subcommand, Display)] pub enum Command { /// Starts the GraphQL server on the configured port Start { diff --git a/src/cli/tc.rs b/src/cli/tc.rs index 95998eeb5c..304445c34d 100644 --- a/src/cli/tc.rs +++ b/src/cli/tc.rs @@ -3,8 +3,10 @@ use std::path::Path; use anyhow::Result; use clap::Parser; +use convert_case::{Case, Casing}; use dotenvy::dotenv; use inquire::Confirm; +use lazy_static::lazy_static; use stripmargin::StripMargin; use super::command::{Cli, Command}; @@ -23,6 +25,9 @@ const FILE_NAME: &str = ".tailcallrc.graphql"; const YML_FILE_NAME: &str = ".graphqlrc.yml"; const JSON_FILE_NAME: &str = ".tailcallrc.schema.json"; +lazy_static! { + static ref TRACKER: tailcall_tracker::Tracker = tailcall_tracker::Tracker::default(); +} pub async fn run() -> Result<()> { if let Ok(path) = dotenv() { tracing::info!("Env file: {:?} loaded", path); @@ -31,6 +36,16 @@ pub async fn run() -> Result<()> { update_checker::check_for_update().await; let runtime = cli::runtime::init(&Blueprint::default()); let config_reader = ConfigReader::init(runtime.clone()); + + // Initialize ping event every 60 seconds + let _ = TRACKER + .init_ping(tokio::time::Duration::from_secs(60)) + .await; + + // Dispatch the command as an event + let _ = TRACKER + .dispatch(cli.command.to_string().to_case(Case::Snake).as_str()) + .await; match cli.command { Command::Start { file_paths } => { let config_module = config_reader.read_all(&file_paths).await?; diff --git a/tailcall-tracker/Cargo.toml b/tailcall-tracker/Cargo.toml new file mode 100644 index 0000000000..d068f81cd8 --- /dev/null +++ b/tailcall-tracker/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "tailcall-tracker" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +reqwest = { version = "0.11", features = ["json", "rustls-tls"] } +anyhow = "1.0.82" +lazy_static = "1.4.0" +serde = { version = "1.0.200", features = ["derive"] } +serde_json = { version = "1.0.82", features = ["preserve_order"] } +machineid-rs = "1.2.4" +tokio = { version = "1.0.1", features = ["rt", "time"] } +tracing = "0.1.40" +sysinfo = "0.30.12" diff --git a/tailcall-tracker/src/check_tracking.rs b/tailcall-tracker/src/check_tracking.rs new file mode 100644 index 0000000000..0da3349945 --- /dev/null +++ b/tailcall-tracker/src/check_tracking.rs @@ -0,0 +1,52 @@ +use std::env; + +const LONG_ENV_FILTER_VAR_NAME: &str = "TAILCALL_TRACKER"; +const SHORT_ENV_FILTER_VAR_NAME: &str = "TC_TRACKER"; +const VERSION: &str = match option_env!("APP_VERSION") { + Some(version) => version, + _ => "0.1.0-dev", +}; + +/// Checks if tracking is enabled +pub fn check_tracking() -> bool { + let is_prod = !VERSION.contains("dev"); + let usage_enabled = env::var(LONG_ENV_FILTER_VAR_NAME) + .or(env::var(SHORT_ENV_FILTER_VAR_NAME)) + .map(|v| !v.eq_ignore_ascii_case("false")) + .ok(); + check_tracking_inner(is_prod, usage_enabled) +} + +fn check_tracking_inner(is_prod_build: bool, tracking_enabled: Option) -> bool { + if let Some(usage_enabled) = tracking_enabled { + usage_enabled + } else { + is_prod_build + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn usage_enabled_true() { + assert!(check_tracking_inner(true, Some(true))); + assert!(check_tracking_inner(false, Some(true))); + } + + #[test] + fn usage_enabled_false() { + assert!(!check_tracking_inner(true, Some(false))); + assert!(!check_tracking_inner(false, Some(false))); + } + + #[test] + fn usage_enabled_none_is_prod_true() { + assert!(check_tracking_inner(true, None)); + } + + #[test] + fn usage_enabled_none_is_prod_false() { + assert!(!check_tracking_inner(false, None)); + } +} diff --git a/tailcall-tracker/src/event.rs b/tailcall-tracker/src/event.rs new file mode 100644 index 0000000000..0ae3dd9d59 --- /dev/null +++ b/tailcall-tracker/src/event.rs @@ -0,0 +1,52 @@ +use machineid_rs::{Encryption, HWIDComponent, IdBuilder}; +use serde::{Deserialize, Serialize}; +use sysinfo::System; + +const PARAPHRASE: &str = "tc_key"; +const DEFAULT_CLIENT_ID: &str = ""; + +#[derive(Debug, Serialize, Deserialize)] +struct Params { + cpu_cores: String, + os_name: String, +} + +#[derive(Debug, Serialize, Deserialize)] +struct EventValue { + name: String, + params: Params, +} + +impl EventValue { + fn new(name: &str) -> EventValue { + let sys = System::new_all(); + let cores = sys.physical_core_count().unwrap_or(2).to_string(); + let os_name = System::long_os_version().unwrap_or("Unknown".to_string()); + EventValue { + name: name.to_string(), + params: Params { cpu_cores: cores, os_name }, + } + } +} + +/// Event structure to be sent to GA +#[derive(Debug, Serialize, Deserialize)] +pub struct Event { + client_id: String, + events: Vec, +} + +impl Event { + pub fn new(name: &str) -> Self { + let mut builder = IdBuilder::new(Encryption::SHA256); + builder + .add_component(HWIDComponent::SystemID) + .add_component(HWIDComponent::CPUCores); + + let id = builder + .build(PARAPHRASE) + .unwrap_or(DEFAULT_CLIENT_ID.to_string()); + + Self { client_id: id, events: vec![EventValue::new(name)] } + } +} diff --git a/tailcall-tracker/src/lib.rs b/tailcall-tracker/src/lib.rs new file mode 100644 index 0000000000..4a8bd0635f --- /dev/null +++ b/tailcall-tracker/src/lib.rs @@ -0,0 +1,4 @@ +mod check_tracking; +mod event; +mod tracker; +pub use tracker::Tracker; diff --git a/tailcall-tracker/src/tracker.rs b/tailcall-tracker/src/tracker.rs new file mode 100644 index 0000000000..a50d570177 --- /dev/null +++ b/tailcall-tracker/src/tracker.rs @@ -0,0 +1,76 @@ +use reqwest::header::{HeaderName, HeaderValue}; + +use crate::check_tracking::check_tracking; +use crate::event::Event; + +const API_SECRET: &str = "GVaEzXFeRkCI9YBIylbEjQ"; +const MEASUREMENT_ID: &str = "G-JEP3QDWT0G"; +const BASE_URL: &str = "https://www.google-analytics.com"; + +/// +/// Base structure to track usage of the CLI application +#[derive(Debug, Clone)] +pub struct Tracker { + base_url: String, + api_secret: String, + measurement_id: String, + is_tracking: bool, +} + +impl Default for Tracker { + fn default() -> Self { + Self { + base_url: BASE_URL.to_string(), + api_secret: API_SECRET.to_string(), + measurement_id: MEASUREMENT_ID.to_string(), + is_tracking: check_tracking(), + } + } +} + +impl Tracker { + /// Initializes the ping event to be sent after the provided duration + pub async fn init_ping(&'static self, duration: tokio::time::Duration) { + if self.is_tracking { + let mut interval = tokio::time::interval(duration); + tokio::task::spawn(async move { + loop { + interval.tick().await; + let _ = self.dispatch("ping").await; + } + }); + } + } + + fn create_request(&self, event_name: &str) -> anyhow::Result { + let event = Event::new(event_name); + tracing::debug!("Sending event: {:?}", event); + let mut url = reqwest::Url::parse(self.base_url.as_str())?; + url.set_path("/mp/collect"); + url.query_pairs_mut() + .append_pair("api_secret", self.api_secret.as_str()) + .append_pair("measurement_id", self.measurement_id.as_str()); + let mut request = reqwest::Request::new(reqwest::Method::POST, url); + let header_name = HeaderName::from_static("content-type"); + let header_value = HeaderValue::from_str("application/json")?; + request.headers_mut().insert(header_name, header_value); + + let _ = request + .body_mut() + .insert(reqwest::Body::from(serde_json::to_string(&event)?)); + Ok(request) + } + + pub async fn dispatch(&'static self, name: &str) -> anyhow::Result<()> { + if self.is_tracking { + let request = self.create_request(name)?; + let client = reqwest::Client::new(); + let response = client.execute(request).await?; + let status = response.status(); + let text = response.text().await?; + tracing::debug!("Tracker: {}, message: {:?}", status.as_str(), text); + } + + Ok(()) + } +} From 3ad5e922062cf627e287eaa4fab1e1c4e3b3b5ec Mon Sep 17 00:00:00 2001 From: Amit Singh Date: Tue, 7 May 2024 20:43:46 +0530 Subject: [PATCH 10/16] fix: build failures (#1888) --- Cargo.lock | 109 ------------------------------------ Cargo.toml | 22 +++++--- tailcall-tracker/Cargo.toml | 14 ++--- 3 files changed, 21 insertions(+), 124 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ef92e52f36..952dd2f0db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1559,21 +1559,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2349,19 +2334,6 @@ dependencies = [ "tokio-io-timeout", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper 0.14.28", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "hyper-util" version = "0.1.3" @@ -3101,24 +3073,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3264,50 +3218,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" -[[package]] -name = "openssl" -version = "0.10.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" -dependencies = [ - "bitflags 2.5.0", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2 1.0.82", - "quote 1.0.36", - "syn 2.0.61", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-sys" -version = "0.9.102" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "opentelemetry" version = "0.21.0" @@ -3707,12 +3623,6 @@ dependencies = [ "futures-io", ] -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - [[package]] name = "plotters" version = "0.3.5" @@ -4305,13 +4215,11 @@ dependencies = [ "http-body 0.4.6", "hyper 0.14.28", "hyper-rustls 0.24.2", - "hyper-tls", "ipnet", "js-sys", "log", "mime", "mime_guess", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite", @@ -4323,7 +4231,6 @@ dependencies = [ "sync_wrapper", "system-configuration", "tokio", - "tokio-native-tls", "tokio-rustls 0.24.1", "tower-service", "url", @@ -5606,16 +5513,6 @@ dependencies = [ "syn 2.0.61", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.24.1" @@ -6101,12 +5998,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74797339c3b98616c009c7c3eb53a0ce41e85c8ec66bd3db96ed132d20cfdee8" -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - [[package]] name = "version_check" version = "0.9.4" diff --git a/Cargo.toml b/Cargo.toml index f25e78cd80..36d4dda135 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,15 @@ futures-util = { version = "0.3.30" } indexmap = "2.2.6" insta = { version = "1.38.0", features = ["json"] } tokio = { version = "1.37.0", features = ["rt", "time"] } +reqwest = { version = "0.11", features = [ + "json", + "rustls-tls", +], default-features = false } +tracing = "0.1.40" +lazy_static = "1.4.0" +serde_json = { version = "1.0.116", features = ["preserve_order"] } +serde = { version = "1.0.200", features = ["derive"] } + [dependencies] # dependencies specific to CLI must have optional = true and the dep should be added to default feature. @@ -48,18 +57,15 @@ schemars = { version = "0.8.17", features = ["derive"] } hyper = { version = "0.14.28", features = ["server"], default-features = false } tokio = { workspace = true } anyhow = { workspace = true } +reqwest = { workspace = true } derive_setters = "0.1.6" thiserror = "1.0.59" -serde_json = { version = "1.0.116", features = ["preserve_order"] } -serde = { version = "1.0.200", features = ["derive"] } +serde_json = { workspace = true } +serde = { workspace = true } serde_qs = "0.13" serde_yaml = "0.9.34" serde_urlencoded = "0.7.1" url = { version = "2.5.0", features = ["serde"] } -reqwest = { version = "0.11", features = [ - "json", - "rustls-tls", -], default-features = false } indexmap = { workspace = true } once_cell = "1.19.0" clap = { version = "4.5.4", features = ["derive"] } @@ -92,14 +98,14 @@ update-informer = { version = "1.1.0", default-features = false, features = [ "github", "reqwest", ], optional = true } -lazy_static = "1.4.0" +lazy_static = { workspace = true } which = { version = "6.0.1", optional = true } async-recursion = "1.1.1" tempfile = "3.10.1" rquickjs = { "version" = "0.5.1", optional = true, features = ["full"] } strum_macros = "0.26.2" # TODO: disable some levels with features? -tracing = "0.1.40" +tracing = { workspace = true } tracing-subscriber = { version = "0.3.18", features = [ "default", "fmt", diff --git a/tailcall-tracker/Cargo.toml b/tailcall-tracker/Cargo.toml index d068f81cd8..9261ff8a7f 100644 --- a/tailcall-tracker/Cargo.toml +++ b/tailcall-tracker/Cargo.toml @@ -6,12 +6,12 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -reqwest = { version = "0.11", features = ["json", "rustls-tls"] } -anyhow = "1.0.82" -lazy_static = "1.4.0" -serde = { version = "1.0.200", features = ["derive"] } -serde_json = { version = "1.0.82", features = ["preserve_order"] } +reqwest = { workspace = true } +anyhow = { workspace = true } +lazy_static = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } machineid-rs = "1.2.4" -tokio = { version = "1.0.1", features = ["rt", "time"] } -tracing = "0.1.40" +tokio = { workspace = true } +tracing = { workspace = true } sysinfo = "0.30.12" From 1689a9267dc0c88879f024e32e2414499a1fe9f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 22:33:28 +0000 Subject: [PATCH 11/16] fix(deps): update rust crate rustls-pki-types to v1.7.0 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 952dd2f0db..49a0b30c92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4454,9 +4454,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51f344d206c5e1b010eec27349b815a4805f70a778895959d70b74b9b529b30a" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" [[package]] name = "rustls-webpki" From 50ee24a7de961501822b48428298aa8833734f57 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 00:09:57 +0000 Subject: [PATCH 12/16] fix(deps): update rust crate serde to v1.0.201 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 49a0b30c92..72477efbb5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4586,9 +4586,9 @@ checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" [[package]] name = "serde" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] @@ -4636,9 +4636,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2 1.0.82", "quote 1.0.36", From 389359a6ffba1351de7b3c162de42fbcd6af0341 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 03:39:37 +0000 Subject: [PATCH 13/16] fix(deps): update rust crate serde_json to v1.0.117 --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 72477efbb5..2723021b11 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4658,9 +4658,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "indexmap 2.2.6", "itoa", From 9e31dda41c847fd8fefc6ab3a43ceb957a0be7ee Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 04:31:17 +0000 Subject: [PATCH 14/16] fix(deps): update rust crate lambda_http to v0.11.2 --- Cargo.lock | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2723021b11..e9890fb459 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2265,7 +2265,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.6", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -2586,12 +2586,12 @@ dependencies = [ [[package]] name = "lambda_http" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ebde9aedfdf8c2bac4365d9adafae6ca6d631b0ea221734ac802595fcd141cb" +checksum = "cfbe291122ade1f6a119c94496da02d989888f97d5bea2a0bd9bcbc6d0a0af43" dependencies = [ "aws_lambda_events", - "base64 0.21.7", + "base64 0.22.1", "bytes", "encoding_rs", "futures", @@ -2613,12 +2613,12 @@ dependencies = [ [[package]] name = "lambda_runtime" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276c835f2217fac810a97f2ed8eabfe9be71afe4f3ffd8671b05cb528e95ff8a" +checksum = "ae4606aea513f0e614497c0c4556d0e39f51a8434d9d97e592d32f9e615d4232" dependencies = [ "async-stream", - "base64 0.21.7", + "base64 0.22.1", "bytes", "futures", "http 1.1.0", @@ -2641,9 +2641,9 @@ dependencies = [ [[package]] name = "lambda_runtime_api_client" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "722b02764422524d3f49a934b570f7c567f811eda1f9c4bdebebcfae1bad4f23" +checksum = "c90a10f094475a34a04da2be11686c4dcfe214d93413162db9ffdff3d3af293a" dependencies = [ "bytes", "futures-channel", From 2a12794216c3ba5e0ddae76ced6a1fda023f651e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 8 May 2024 05:03:41 +0000 Subject: [PATCH 15/16] fix(deps): update rust crate schemars to v0.8.19 --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9890fb459..75a6ac7a8e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4511,9 +4511,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f55c82c700538496bdc329bb4918a81f87cc8888811bd123cf325a0f2f8d309" +checksum = "fc6e7ed6919cb46507fb01ff1654309219f62b4d603822501b0b80d42f6f21ef" dependencies = [ "dyn-clone", "schemars_derive", @@ -4523,9 +4523,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83263746fe5e32097f06356968a077f96089739c927a61450efa069905eec108" +checksum = "185f2b7aa7e02d418e453790dde16890256bbd2bcd04b7dc5348811052b53f49" dependencies = [ "proc-macro2 1.0.82", "quote 1.0.36", From 940513f07cd61033a44a962a4614a329d518dde3 Mon Sep 17 00:00:00 2001 From: amit Date: Wed, 8 May 2024 10:45:39 +0530 Subject: [PATCH 16/16] style: lint --- generated/.tailcallrc.schema.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/generated/.tailcallrc.schema.json b/generated/.tailcallrc.schema.json index a39e72e028..9824e8f0ba 100644 --- a/generated/.tailcallrc.schema.json +++ b/generated/.tailcallrc.schema.json @@ -489,7 +489,6 @@ }, "protected": { "description": "Marks field as protected by auth provider", - "default": null, "anyOf": [ { "$ref": "#/definitions/Protected" @@ -1267,7 +1266,6 @@ }, "protected": { "description": "Marks field as protected by auth providers", - "default": null, "anyOf": [ { "$ref": "#/definitions/Protected"