diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md index 75210006..3af51898 100644 --- a/juniper/CHANGELOG.md +++ b/juniper/CHANGELOG.md @@ -2,9 +2,15 @@ - No changes yet +# [[0.14.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.14.0) + +- Require `url` 2.x if `url` feature is enabled. +- Improve lookahead visitability. +- Add ability to parse 'subscription'. + # [[0.13.1] 2019-07-29](https://github.com/graphql-rust/juniper/releases/tag/juniper-0.13.1) -- Fix a regression when using lookaheads with fragments containing nested types [#404](https://github.com/graphql-rust/juniper/pull/404) +- Fix a regression when using lookaheads with fragments containing nested types [#404](https://github.com/graphql-rust/juniper/pull/404) - Allow `mut` arguments for resolver functions in `#[object]` macros [#402](https://github.com/graphql-rust/juniper/pull/402) @@ -15,7 +21,7 @@ See [#345](https://github.com/graphql-rust/juniper/pull/345). The newtype pattern can now be used with the `GraphQLScalarValue` custom derive -to easily implement custom scalar values that just wrap another scalar, +to easily implement custom scalar values that just wrap another scalar, similar to serdes `#[serde(transparent)]` functionality. Example: @@ -34,7 +40,7 @@ struct UserId(i32); ### object macro -The `graphql_object!` macro is deprecated and will be removed in the future. +The `graphql_object!` macro is deprecated and will be removed in the future. It is replaced by the new [object](https://docs.rs/juniper/latest/juniper/macro.object.html) procedural macro. [#333](https://github.com/graphql-rust/juniper/pull/333) @@ -53,7 +59,7 @@ This should not have any impact on your code, since juniper already was 2018 com - The `GraphQLType` impl for () was removed to improve compile time safefty. [#355](https://github.com/graphql-rust/juniper/pull/355) - The `ScalarValue` custom derive has been renamed to `GraphQLScalarValue`. - Added built-in support for the canonical schema introspection query via - `juniper::introspect()`. + `juniper::introspect()`. [#307](https://github.com/graphql-rust/juniper/issues/307) - Fix introspection query validity The DirectiveLocation::InlineFragment had an invalid literal value, diff --git a/juniper/Cargo.toml b/juniper/Cargo.toml index b7d62c94..f981af04 100644 --- a/juniper/Cargo.toml +++ b/juniper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper" -version = "0.13.1" +version = "0.14.0" authors = [ "Magnus Hallin ", "Christoph Herzog ", @@ -33,7 +33,7 @@ default = [ ] [dependencies] -juniper_codegen = { version = "0.13.2", path = "../juniper_codegen" } +juniper_codegen = { version = "0.14.0", path = "../juniper_codegen" } fnv = "1.0.3" indexmap = { version = "1.0.0", features = ["serde-1"] } @@ -42,7 +42,7 @@ serde_derive = { version = "1.0.2" } chrono = { version = "0.4.0", optional = true } serde_json = { version="1.0.2", optional = true } -url = { version = "1.5.1", optional = true } +url = { version = "2", optional = true } uuid = { version = "0.7", optional = true } futures-preview = { version = "=0.3.0-alpha.19", optional = true } diff --git a/juniper/src/ast.rs b/juniper/src/ast.rs index e27f733e..0a99c724 100644 --- a/juniper/src/ast.rs +++ b/juniper/src/ast.rs @@ -116,6 +116,7 @@ pub struct Directive<'a, S> { pub enum OperationType { Query, Mutation, + Subscription, } #[derive(Clone, PartialEq, Debug)] diff --git a/juniper/src/executor/look_ahead.rs b/juniper/src/executor/look_ahead.rs index e4e4fe4f..3c8fd7e4 100644 --- a/juniper/src/executor/look_ahead.rs +++ b/juniper/src/executor/look_ahead.rs @@ -88,6 +88,11 @@ where } } + /// The argument's name + pub fn name(&'a self) -> &str { + &self.name + } + /// The value of the argument pub fn value(&'a self) -> &LookAheadValue<'a, S> { &self.value @@ -347,6 +352,12 @@ pub trait LookAheadMethods { self.select_child(name).is_some() } + /// Does the current node have any arguments? + fn has_arguments(&self) -> bool; + + /// Does the current node have any children? + fn has_children(&self) -> bool; + /// Get the top level arguments for the current selection fn arguments(&self) -> &[LookAheadArgument]; @@ -354,6 +365,9 @@ pub trait LookAheadMethods { fn argument(&self, name: &str) -> Option<&LookAheadArgument> { self.arguments().iter().find(|a| a.name == name) } + + /// Get the top level children for the current selection + fn child_names(&self) -> Vec<&str>; } impl<'a, S> LookAheadMethods for ConcreteLookAheadSelection<'a, S> { @@ -368,6 +382,21 @@ impl<'a, S> LookAheadMethods for ConcreteLookAheadSelection<'a, S> { fn arguments(&self) -> &[LookAheadArgument] { &self.arguments } + + fn child_names(&self) -> Vec<&str> { + self.children + .iter() + .map(|c| c.alias.unwrap_or(c.name)) + .collect() + } + + fn has_arguments(&self) -> bool { + !self.arguments.is_empty() + } + + fn has_children(&self) -> bool { + !self.children.is_empty() + } } impl<'a, S> LookAheadMethods for LookAheadSelection<'a, S> { @@ -385,6 +414,21 @@ impl<'a, S> LookAheadMethods for LookAheadSelection<'a, S> { fn arguments(&self) -> &[LookAheadArgument] { &self.arguments } + + fn child_names(&self) -> Vec<&str> { + self.children + .iter() + .map(|c| c.inner.alias.unwrap_or(c.inner.name)) + .collect() + } + + fn has_arguments(&self) -> bool { + !self.arguments.is_empty() + } + + fn has_children(&self) -> bool { + !self.children.is_empty() + } } #[cfg(test)] @@ -1399,4 +1443,59 @@ fragment heroFriendNames on Hero { panic!("No Operation found"); } } + + #[test] + fn check_visitability() { + let docs = parse_document_source::( + " +query Hero { + hero(episode: EMPIRE) { + name + friends { + name + } + } +} + ", + ) + .unwrap(); + let fragments = extract_fragments(&docs); + + if let crate::ast::Definition::Operation(ref op) = docs[0] { + let vars = Variables::default(); + let look_ahead = LookAheadSelection::build_from_selection( + &op.item.selection_set[0], + &vars, + &fragments, + ) + .unwrap(); + + assert_eq!(look_ahead.field_name(), "hero"); + + assert!(look_ahead.has_arguments()); + let args = look_ahead.arguments(); + assert_eq!(args[0].name(), "episode"); + assert_eq!(args[0].value(), &LookAheadValue::Enum("EMPIRE")); + + assert!(look_ahead.has_children()); + assert_eq!(look_ahead.child_names(), vec!["name", "friends"]); + + let child0 = look_ahead.select_child("name").unwrap(); + assert_eq!(child0.field_name(), "name"); + assert!(!child0.has_arguments()); + assert!(!child0.has_children()); + + let child1 = look_ahead.select_child("friends").unwrap(); + assert_eq!(child1.field_name(), "friends"); + assert!(!child1.has_arguments()); + assert!(child1.has_children()); + assert_eq!(child1.child_names(), vec!["name"]); + + let child2 = child1.select_child("name").unwrap(); + assert!(!child2.has_arguments()); + assert!(!child2.has_children()); + } else { + panic!("No Operation found"); + } + } } diff --git a/juniper/src/executor/mod.rs b/juniper/src/executor/mod.rs index bbabc037..27300882 100644 --- a/juniper/src/executor/mod.rs +++ b/juniper/src/executor/mod.rs @@ -713,6 +713,121 @@ where None => return Err(GraphQLError::UnknownOperationName), }; + if op.item.operation_type == OperationType::Subscription { + return Err(GraphQLError::IsSubscription); + } + + let default_variable_values = op.item.variable_definitions.map(|defs| { + defs.item + .items + .iter() + .filter_map(|&(ref name, ref def)| { + def.default_value + .as_ref() + .map(|i| (name.item.to_owned(), i.item.clone())) + }) + .collect::>>() + }); + + let errors = RwLock::new(Vec::new()); + let value; + + { + let mut all_vars; + let mut final_vars = variables; + + if let Some(defaults) = default_variable_values { + all_vars = variables.clone(); + + for (name, value) in defaults { + all_vars.entry(name).or_insert(value); + } + + final_vars = &all_vars; + } + + let root_type = match op.item.operation_type { + OperationType::Query => root_node.schema.query_type(), + OperationType::Mutation => root_node + .schema + .mutation_type() + .expect("No mutation type found"), + OperationType::Subscription => unreachable!(), + }; + + let executor = Executor { + fragments: &fragments + .iter() + .map(|f| (f.item.name.item, &f.item)) + .collect(), + variables: final_vars, + current_selection_set: Some(&op.item.selection_set[..]), + parent_selection_set: None, + current_type: root_type, + schema: &root_node.schema, + context, + errors: &errors, + field_path: FieldPath::Root(op.start), + }; + + value = match op.item.operation_type { + OperationType::Query => executor.resolve_into_value(&root_node.query_info, &root_node), + OperationType::Mutation => { + executor.resolve_into_value(&root_node.mutation_info, &root_node.mutation_type) + } + OperationType::Subscription => unreachable!(), + }; + } + + let mut errors = errors.into_inner().unwrap(); + errors.sort(); + + Ok((value, errors)) +} + +#[cfg(feature = "async")] +pub async fn execute_validated_query_async<'a, QueryT, MutationT, CtxT, S>( + document: Document<'a, S>, + operation_name: Option<&str>, + root_node: &RootNode<'a, QueryT, MutationT, S>, + variables: &Variables, + context: &CtxT, +) -> Result<(Value, Vec>), GraphQLError<'a>> +where + S: ScalarValue + Send + Sync, + QueryT: crate::GraphQLTypeAsync + Send + Sync, + QueryT::TypeInfo: Send + Sync, + MutationT: crate::GraphQLTypeAsync + Send + Sync, + MutationT::TypeInfo: Send + Sync, + CtxT: Send + Sync, + for<'b> &'b S: ScalarRefValue<'b>, +{ + let mut fragments = vec![]; + let mut operation = None; + + for def in document { + match def { + Definition::Operation(op) => { + if operation_name.is_none() && operation.is_some() { + return Err(GraphQLError::MultipleOperationsProvided); + } + + let move_op = operation_name.is_none() + || op.item.name.as_ref().map(|s| s.item) == operation_name; + + if move_op { + operation = Some(op); + } + } + Definition::Fragment(f) => fragments.push(f), + }; + } + + let op = match operation { + Some(op) => op, + None => return Err(GraphQLError::UnknownOperationName), + }; + let default_variable_values = op.item.variable_definitions.map(|defs| { defs.item .items @@ -766,9 +881,15 @@ where }; value = match op.item.operation_type { - OperationType::Query => executor.resolve_into_value(&root_node.query_info, &root_node), + OperationType::Query => { + executor + .resolve_into_value_async(&root_node.query_info, &root_node) + .await + } OperationType::Mutation => { - executor.resolve_into_value(&root_node.mutation_info, &root_node.mutation_type) + executor + .resolve_into_value_async(&root_node.mutation_info, &root_node.mutation_type) + .await } }; } diff --git a/juniper/src/integrations/serde.rs b/juniper/src/integrations/serde.rs index 558ce108..c91c5262 100644 --- a/juniper/src/integrations/serde.rs +++ b/juniper/src/integrations/serde.rs @@ -70,6 +70,10 @@ impl<'a> ser::Serialize for GraphQLError<'a> { message: "Unknown operation", }] .serialize(serializer), + GraphQLError::IsSubscription => [SerializeHelper { + message: "Expected query, got subscription", + }] + .serialize(serializer), } } } diff --git a/juniper/src/lib.rs b/juniper/src/lib.rs index f1c7c2a1..2d553896 100644 --- a/juniper/src/lib.rs +++ b/juniper/src/lib.rs @@ -88,8 +88,7 @@ Juniper has not reached 1.0 yet, thus some API instability should be expected. [chrono]: https://crates.io/crates/chrono */ - -#![doc(html_root_url = "https://docs.rs/juniper/0.13.1")] +#![doc(html_root_url = "https://docs.rs/juniper/0.14.0")] #![warn(missing_docs)] #[doc(hidden)] @@ -191,6 +190,7 @@ pub enum GraphQLError<'a> { NoOperationProvided, MultipleOperationsProvided, UnknownOperationName, + IsSubscription, } /// Execute a query in a provided schema diff --git a/juniper/src/parser/document.rs b/juniper/src/parser/document.rs index 091fdea1..4e851a91 100644 --- a/juniper/src/parser/document.rs +++ b/juniper/src/parser/document.rs @@ -56,9 +56,12 @@ where S: ScalarValue, { match parser.peek().item { - Token::CurlyOpen | Token::Name("query") | Token::Name("mutation") => Ok( - Definition::Operation(parse_operation_definition(parser, schema)?), - ), + Token::CurlyOpen + | Token::Name("query") + | Token::Name("mutation") + | Token::Name("subscription") => Ok(Definition::Operation(parse_operation_definition( + parser, schema, + )?)), Token::Name("fragment") => Ok(Definition::Fragment(parse_fragment_definition( parser, schema, )?)), @@ -95,6 +98,7 @@ where let op = match operation_type.item { OperationType::Query => Some(schema.concrete_query_type()), OperationType::Mutation => schema.concrete_mutation_type(), + OperationType::Subscription => schema.concrete_subscription_type(), }; let fields = op.and_then(|m| m.fields(schema)); let fields = fields.as_ref().map(|c| c as &[_]); @@ -394,6 +398,7 @@ fn parse_operation_type<'a>(parser: &mut Parser<'a>) -> ParseResult<'a, Operatio match parser.peek().item { Token::Name("query") => Ok(parser.next()?.map(|_| OperationType::Query)), Token::Name("mutation") => Ok(parser.next()?.map(|_| OperationType::Mutation)), + Token::Name("subscription") => Ok(parser.next()?.map(|_| OperationType::Subscription)), _ => Err(parser.next()?.map(ParseError::UnexpectedToken)), } } diff --git a/juniper/src/schema/model.rs b/juniper/src/schema/model.rs index f3007b5b..a1c003d7 100644 --- a/juniper/src/schema/model.rs +++ b/juniper/src/schema/model.rs @@ -65,6 +65,7 @@ pub struct DirectiveType<'a, S> { pub enum DirectiveLocation { Query, Mutation, + Subscription, Field, #[graphql(name = "FRAGMENT_DEFINITION")] FragmentDefinition, @@ -243,6 +244,18 @@ impl<'a, S> SchemaType<'a, S> { }) } + pub fn subscription_type(&self) -> Option> { + // subscription is not yet in `RootNode`, + // so return `None` for now + None + } + + pub fn concrete_subscription_type(&self) -> Option<&MetaType> { + // subscription is not yet in `RootNode`, + // so return `None` for now + None + } + pub fn type_list(&self) -> Vec> { self.types.values().map(|t| TypeType::Concrete(t)).collect() } @@ -452,6 +465,7 @@ impl fmt::Display for DirectiveLocation { f.write_str(match *self { DirectiveLocation::Query => "query", DirectiveLocation::Mutation => "mutation", + DirectiveLocation::Subscription => "subscription", DirectiveLocation::Field => "field", DirectiveLocation::FragmentDefinition => "fragment definition", DirectiveLocation::FragmentSpread => "fragment spread", diff --git a/juniper/src/schema/schema.rs b/juniper/src/schema/schema.rs index 5d0b0274..14c3f2c2 100644 --- a/juniper/src/schema/schema.rs +++ b/juniper/src/schema/schema.rs @@ -138,9 +138,8 @@ where self.mutation_type() } - // Included for compatibility with the introspection query in GraphQL.js fn subscription_type(&self) -> Option> { - None + self.subscription_type() } fn directives(&self) -> Vec<&DirectiveType> { diff --git a/juniper/src/tests/schema_introspection.rs b/juniper/src/tests/schema_introspection.rs index 86b4dd13..4303c676 100644 --- a/juniper/src/tests/schema_introspection.rs +++ b/juniper/src/tests/schema_introspection.rs @@ -997,6 +997,12 @@ pub(crate) fn schema_introspection_result() -> value::Value { "isDeprecated": false, "deprecationReason": Null }, + { + "name": "SUBSCRIPTION", + "description": Null, + "isDeprecated": false, + "deprecationReason": Null + }, { "name": "FIELD", "description": Null, @@ -2204,6 +2210,11 @@ pub(crate) fn schema_introspection_result_without_descriptions() -> value::Value "isDeprecated": false, "deprecationReason": Null }, + { + "name": "SUBSCRIPTION", + "isDeprecated": false, + "deprecationReason": Null + }, { "name": "FIELD", "isDeprecated": false, diff --git a/juniper/src/validation/rules/known_directives.rs b/juniper/src/validation/rules/known_directives.rs index 541c0daf..902bb48b 100644 --- a/juniper/src/validation/rules/known_directives.rs +++ b/juniper/src/validation/rules/known_directives.rs @@ -28,6 +28,7 @@ where self.location_stack.push(match op.item.operation_type { OperationType::Query => DirectiveLocation::Query, OperationType::Mutation => DirectiveLocation::Mutation, + OperationType::Subscription => DirectiveLocation::Subscription, }); } @@ -37,7 +38,11 @@ where _: &'a Spanning>, ) { let top = self.location_stack.pop(); - assert!(top == Some(DirectiveLocation::Query) || top == Some(DirectiveLocation::Mutation)); + assert!( + top == Some(DirectiveLocation::Query) + || top == Some(DirectiveLocation::Mutation) + || top == Some(DirectiveLocation::Subscription) + ); } fn enter_field(&mut self, _: &mut ValidatorContext<'a, S>, _: &'a Spanning>) { diff --git a/juniper/src/validation/visitor.rs b/juniper/src/validation/visitor.rs index 05aa4037..255cee43 100644 --- a/juniper/src/validation/visitor.rs +++ b/juniper/src/validation/visitor.rs @@ -64,6 +64,17 @@ fn visit_definitions<'a, S, V>( .schema .concrete_mutation_type() .map(|t| Type::NonNullNamed(Cow::Borrowed(t.name().unwrap()))), + Definition::Operation(Spanning { + item: + Operation { + operation_type: OperationType::Subscription, + .. + }, + .. + }) => ctx + .schema + .concrete_subscription_type() + .map(|t| Type::NonNullNamed(Cow::Borrowed(t.name().unwrap()))), }; ctx.with_pushed_type(def_type.as_ref(), |ctx| { diff --git a/juniper_codegen/Cargo.toml b/juniper_codegen/Cargo.toml index c8dc7d0a..d8c83e1b 100644 --- a/juniper_codegen/Cargo.toml +++ b/juniper_codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_codegen" -version = "0.13.2" +version = "0.14.0" authors = [ "Magnus Hallin ", "Christoph Herzog ", @@ -21,11 +21,9 @@ async = [] proc-macro2 = "1.0.1" syn = { version = "1.0.3", features = ["full", "extra-traits", "parsing"] } quote = "1.0.2" -regex = "1" -lazy_static = "1.0.0" [dev-dependencies] -juniper = { version = "0.13.1", path = "../juniper" } +juniper = { version = "0.14.0", path = "../juniper" } [badges] travis-ci = { repository = "graphql-rust/juniper" } diff --git a/juniper_codegen/src/lib.rs b/juniper_codegen/src/lib.rs index 934a713c..d977fe02 100644 --- a/juniper_codegen/src/lib.rs +++ b/juniper_codegen/src/lib.rs @@ -4,7 +4,7 @@ //! You should not depend on juniper_codegen directly. //! You only need the `juniper` crate. -#![doc(html_root_url = "https://docs.rs/juniper_codegen/0.13.2")] +#![doc(html_root_url = "https://docs.rs/juniper_codegen/0.14.0")] #![recursion_limit = "1024"] extern crate proc_macro; diff --git a/juniper_codegen/src/util.rs b/juniper_codegen/src/util.rs index 1f1a4d66..875b0df6 100644 --- a/juniper_codegen/src/util.rs +++ b/juniper_codegen/src/util.rs @@ -1,5 +1,4 @@ use quote::quote; -use regex::Regex; use std::collections::HashMap; use syn::{ parse, parse_quote, punctuated::Punctuated, Attribute, Lit, Meta, MetaList, MetaNameValue, @@ -279,10 +278,16 @@ pub(crate) fn to_upper_snake_case(s: &str) -> String { #[doc(hidden)] pub fn is_valid_name(field_name: &str) -> bool { - lazy_static::lazy_static! { - static ref GRAPHQL_NAME_SPEC: Regex = Regex::new("^[_A-Za-z][_0-9A-Za-z]*$").unwrap(); - } - GRAPHQL_NAME_SPEC.is_match(field_name) + let mut chars = field_name.chars(); + + match chars.next() { + // first char can't be a digit + Some(c) if c.is_ascii_alphabetic() || c == '_' => (), + // can't be an empty string or any other character + _ => return false, + }; + + chars.all(|c| c.is_ascii_alphanumeric() || c == '_') } #[derive(Default, Debug)] diff --git a/juniper_hyper/CHANGELOG.md b/juniper_hyper/CHANGELOG.md index ed180033..d51be2c4 100644 --- a/juniper_hyper/CHANGELOG.md +++ b/juniper_hyper/CHANGELOG.md @@ -2,6 +2,10 @@ - Compatibility with the latest `juniper`. +# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.5.0) + +- Compatibility with the latest `juniper`. + # [[0.4.1] 2019-07-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_hyper-0.4.1) - Compatibility with the latest `juniper`. diff --git a/juniper_hyper/Cargo.toml b/juniper_hyper/Cargo.toml index eecc445a..28525061 100644 --- a/juniper_hyper/Cargo.toml +++ b/juniper_hyper/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_hyper" -version = "0.4.1" +version = "0.5.0" authors = ["Damir Vandic "] description = "Juniper GraphQL integration with Hyper" license = "BSD-2-Clause" @@ -12,8 +12,8 @@ edition = "2018" serde = "1.0" serde_json = "1.0" serde_derive = "1.0" -url = "1.7" -juniper = { version = "0.13.1" , default-features = false, path = "../juniper"} +url = "2" +juniper = { version = "0.14.0", default-features = false, path = "../juniper"} futures = "0.1" tokio = "0.1.8" @@ -25,6 +25,6 @@ pretty_env_logger = "0.2" reqwest = "0.9" [dev-dependencies.juniper] -version = "0.13.1" +version = "0.14.0" features = ["expose-test-schema", "serde_json"] path = "../juniper" diff --git a/juniper_hyper/examples/hyper_server.rs b/juniper_hyper/examples/hyper_server.rs index 208f8e1b..802131e5 100644 --- a/juniper_hyper/examples/hyper_server.rs +++ b/juniper_hyper/examples/hyper_server.rs @@ -27,7 +27,7 @@ fn main() { let new_service = move || { let root_node = root_node.clone(); let ctx = db.clone(); - service_fn(move |req| -> Box + Send> { + service_fn(move |req| -> Box + Send> { let root_node = root_node.clone(); let ctx = ctx.clone(); match (req.method(), req.uri().path()) { diff --git a/juniper_iron/CHANGELOG.md b/juniper_iron/CHANGELOG.md index 1d9bc15c..60c8be81 100644 --- a/juniper_iron/CHANGELOG.md +++ b/juniper_iron/CHANGELOG.md @@ -2,6 +2,10 @@ - Compatibility with the latest `juniper`. +# [[0.6.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.6.0) + +- Compatibility with the latest `juniper`. + # [[0.5.1] 2019-07-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_iron-0.5.1) - Compatibility with the latest `juniper`. diff --git a/juniper_iron/Cargo.toml b/juniper_iron/Cargo.toml index 510537f7..81ad40c2 100644 --- a/juniper_iron/Cargo.toml +++ b/juniper_iron/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_iron" -version = "0.5.1" +version = "0.6.0" authors = [ "Magnus Hallin ", "Christoph Herzog ", @@ -15,7 +15,7 @@ edition = "2018" serde = { version = "1.0.2" } serde_json = { version = "1.0.2" } serde_derive = { version = "1.0.2" } -juniper = { version = "0.13.1", path = "../juniper" } +juniper = { version = "0.14.0", path = "../juniper" } urlencoded = { version = ">= 0.5, < 0.7" } iron = ">= 0.5, < 0.7" @@ -25,9 +25,10 @@ iron-test = "0.6" router = "0.6" mount = "0.4" logger = "0.4" -url = "1.7.1" +url = "2" +percent-encoding = "2" [dev-dependencies.juniper] -version = "0.13.1" +version = "0.14.0" features = ["expose-test-schema", "serde_json"] path = "../juniper" diff --git a/juniper_iron/src/lib.rs b/juniper_iron/src/lib.rs index 20215fbb..678226fe 100644 --- a/juniper_iron/src/lib.rs +++ b/juniper_iron/src/lib.rs @@ -431,7 +431,7 @@ mod tests { use super::*; use iron::{Handler, Headers, Url}; use iron_test::{request, response}; - use url::percent_encoding::{utf8_percent_encode, DEFAULT_ENCODE_SET}; + use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; use juniper::{ http::tests as http_tests, @@ -441,6 +441,9 @@ mod tests { use super::GraphQLHandler; + /// https://url.spec.whatwg.org/#query-state + const QUERY_ENCODE_SET: &AsciiSet = &CONTROLS.add(b' ').add(b'"').add(b'#').add(b'<').add(b'>'); + // This is ugly but it works. `iron_test` just dumps the path/url in headers // and newer `hyper` doesn't allow unescaped "{" or "}". fn fixup_url(url: &str) -> String { @@ -454,7 +457,7 @@ mod tests { format!( "http://localhost:3000{}?{}", path, - utf8_percent_encode(url.query().unwrap_or(""), DEFAULT_ENCODE_SET) + utf8_percent_encode(url.query().unwrap_or(""), QUERY_ENCODE_SET) ) } @@ -521,7 +524,7 @@ mod tests { } } - fn make_handler() -> Box { + fn make_handler() -> Box { Box::new(GraphQLHandler::new( context_factory, Query, diff --git a/juniper_rocket/CHANGELOG.md b/juniper_rocket/CHANGELOG.md index 67cf230e..fd9e102e 100644 --- a/juniper_rocket/CHANGELOG.md +++ b/juniper_rocket/CHANGELOG.md @@ -2,6 +2,10 @@ - Compatibility with the latest `juniper`. +# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_rocket-0.5.0) + +- Compatibility with the latest `juniper`. + # [[0.4.1] 2019-07-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_rocket-0.4.1) - Compatibility with the latest `juniper`. diff --git a/juniper_rocket/Cargo.toml b/juniper_rocket/Cargo.toml index cad056bc..ad4cc5bc 100644 --- a/juniper_rocket/Cargo.toml +++ b/juniper_rocket/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_rocket" -version = "0.4.1" +version = "0.5.0" authors = [ "Magnus Hallin ", "Christoph Herzog ", @@ -18,13 +18,13 @@ async = [ "juniper/async" ] serde = { version = "1.0.2" } serde_json = { version = "1.0.2" } serde_derive = { version = "1.0.2" } -juniper = { version = "0.13.1" , default-features = false, path = "../juniper"} +juniper = { version = "0.14.0", default-features = false, path = "../juniper"} futures03 = { version = "=0.3.0-alpha.19", package = "futures-preview", features = ["compat"] } rocket = { git = "https://github.com/SergioBenitez/Rocket", branch = "async" } tokio = "=0.2.0-alpha.6" [dev-dependencies.juniper] -version = "0.13.1" +version = "0.14.0" features = ["expose-test-schema", "serde_json"] path = "../juniper" diff --git a/juniper_warp/CHANGELOG.md b/juniper_warp/CHANGELOG.md index 46041b5b..eee06a3e 100644 --- a/juniper_warp/CHANGELOG.md +++ b/juniper_warp/CHANGELOG.md @@ -2,6 +2,10 @@ - Compatibility with the latest `juniper`. +# [[0.5.0] 2019-09-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.5.0) + +- Compatibility with the latest `juniper`. + # [[0.4.1] 2019-07-29](https://github.com/graphql-rust/juniper/releases/tag/juniper_warp-0.4.1) - Compatibility with the latest `juniper`. diff --git a/juniper_warp/Cargo.toml b/juniper_warp/Cargo.toml index 72b48689..a1c1907c 100644 --- a/juniper_warp/Cargo.toml +++ b/juniper_warp/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "juniper_warp" -version = "0.4.1" +version = "0.5.0" authors = ["Tom Houlé "] description = "Juniper GraphQL integration with Warp" license = "BSD-2-Clause" @@ -13,7 +13,7 @@ async = [ "juniper/async", "futures03" ] [dependencies] warp = "0.1.8" -juniper = { version = "0.13.1", path = "../juniper" } +juniper = { version = "0.14.0", path = "../juniper", default-features = false } serde_json = "1.0.24" serde_derive = "1.0.75" failure = "0.1.2" @@ -24,7 +24,7 @@ tokio-threadpool = "0.1.7" futures03 = { version = "=0.3.0-alpha.19", optional = true, package = "futures-preview", features = ["compat"] } [dev-dependencies] -juniper = { version = "0.13.1", path = "../juniper", features = ["expose-test-schema", "serde_json"] } +juniper = { version = "0.14.0", path = "../juniper", features = ["expose-test-schema", "serde_json"] } env_logger = "0.5.11" log = "0.4.3" percent-encoding = "1.0"