graphql 1.10.4 → 1.10.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,108 +2,63 @@
2
2
  module GraphQL
3
3
  module StaticValidation
4
4
  module ArgumentLiteralsAreCompatible
5
- # TODO dedup with ArgumentsAreDefined
6
5
  def on_argument(node, parent)
7
- parent_defn = case parent
8
- when GraphQL::Language::Nodes::InputObject
9
- arg_defn = context.argument_definition
10
- if arg_defn.nil?
11
- nil
12
- else
13
- arg_ret_type = arg_defn.type.unwrap
14
- if !arg_ret_type.kind.input_object?
15
- nil
16
- else
17
- arg_ret_type
18
- end
19
- end
20
- when GraphQL::Language::Nodes::Directive
21
- context.schema.directives[parent.name]
22
- when GraphQL::Language::Nodes::Field
23
- context.field_definition
24
- else
25
- raise "Unexpected argument parent: #{parent.class} (##{parent})"
6
+ # Check the child arguments first;
7
+ # don't add a new error if one of them reports an error
8
+ super
9
+
10
+ # Don't validate variables here
11
+ if node.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
12
+ return
26
13
  end
27
14
 
28
- if parent_defn && !node.value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
29
- arg_defn = parent_defn.arguments[node.name]
30
- if arg_defn
31
- begin
32
- valid = context.valid_literal?(node.value, arg_defn.type)
33
- rescue GraphQL::CoercionError => err
34
- context.schema.error_bubbling
35
- if !context.schema.error_bubbling && !arg_defn.type.unwrap.kind.scalar?
36
- # if error bubbling is disabled and the arg that caused this error isn't a scalar then
37
- # short-circuit here so we avoid bubbling this up to whatever input_object / array contains us
38
- return super
39
- end
40
- error = GraphQL::StaticValidation::ArgumentLiteralsAreCompatibleError.new(err.message, nodes: parent, type: "CoercionError", extensions: err.extensions)
41
- rescue GraphQL::LiteralValidationError => err
42
- # check to see if the ast node that caused the error to be raised is
43
- # the same as the node we were checking here.
44
- arg_type = arg_defn.type
45
- if arg_type.kind.non_null?
46
- arg_type = arg_type.of_type
47
- end
15
+ if @context.schema.error_bubbling || context.errors.none? { |err| err.path.take(@path.size) == @path }
16
+ parent_defn = parent_definition(parent)
48
17
 
49
- matched = if arg_type.kind.list?
50
- # for a list we claim an error if the node is contained in our list
51
- Array(node.value).include?(err.ast_value)
52
- elsif arg_type.kind.input_object? && node.value.is_a?(GraphQL::Language::Nodes::InputObject)
53
- # for an input object we check the arguments
54
- node.value.arguments.include?(err.ast_value)
18
+ if parent_defn && (arg_defn = parent_defn.arguments[node.name])
19
+ validation_result = context.validate_literal(node.value, arg_defn.type)
20
+ if !validation_result.valid?
21
+ kind_of_node = node_type(parent)
22
+ error_arg_name = parent_name(parent, parent_defn)
23
+ string_value = if node.value == Float::INFINITY
24
+ ""
55
25
  else
56
- # otherwise we just check equality
57
- node.value == err.ast_value
26
+ " (#{GraphQL::Language::Printer.new.print(node.value)})"
58
27
  end
59
- if !matched
60
- # This node isn't the node that caused the error,
61
- # So halt this visit but continue visiting the rest of the tree
62
- return super
63
- end
64
- end
65
28
 
66
- if !valid
67
- error ||= begin
68
- kind_of_node = node_type(parent)
69
- error_arg_name = parent_name(parent, parent_defn)
70
- string_value = if node.value == Float::INFINITY
71
- ""
72
- else
73
- " (#{GraphQL::Language::Printer.new.print(node.value)})"
29
+ problems = validation_result.problems
30
+ first_problem = problems && problems.first
31
+ if first_problem
32
+ message = first_problem["message"]
33
+ # This is some legacy stuff from when `CoercionError` was raised thru the stack
34
+ if message
35
+ coerce_extensions = first_problem["extensions"] || {
36
+ "code" => "argumentLiteralsIncompatible"
37
+ }
74
38
  end
75
-
76
- GraphQL::StaticValidation::ArgumentLiteralsAreCompatibleError.new(
77
- "Argument '#{node.name}' on #{kind_of_node} '#{error_arg_name}' has an invalid value#{string_value}. Expected type '#{arg_defn.type.to_type_signature}'.",
78
- nodes: parent,
79
- type: kind_of_node,
80
- argument: node.name
81
- )
82
39
  end
83
- add_error(error)
84
- end
85
- end
86
- end
87
40
 
88
- super
89
- end
41
+ error_options = {
42
+ nodes: parent,
43
+ type: kind_of_node,
44
+ argument: node.name
45
+ }
46
+ if coerce_extensions
47
+ error_options[:coerce_extensions] = coerce_extensions
48
+ end
90
49
 
50
+ message ||= "Argument '#{node.name}' on #{kind_of_node} '#{error_arg_name}' has an invalid value#{string_value}. Expected type '#{arg_defn.type.to_type_signature}'."
91
51
 
92
- private
52
+ error = GraphQL::StaticValidation::ArgumentLiteralsAreCompatibleError.new(
53
+ message,
54
+ **error_options
55
+ )
93
56
 
94
- def parent_name(parent, type_defn)
95
- if parent.is_a?(GraphQL::Language::Nodes::Field)
96
- parent.alias || parent.name
97
- elsif parent.is_a?(GraphQL::Language::Nodes::InputObject)
98
- type_defn.name
99
- else
100
- parent.graphql_name
57
+ add_error(error)
58
+ end
59
+ end
101
60
  end
102
61
  end
103
-
104
- def node_type(parent)
105
- parent.class.name.split("::").last
106
- end
107
62
  end
108
63
  end
109
64
  end
@@ -5,19 +5,31 @@ module GraphQL
5
5
  attr_reader :type_name
6
6
  attr_reader :argument_name
7
7
 
8
- def initialize(message, path: nil, nodes: [], type:, argument: nil, extensions: nil)
8
+ def initialize(message, path: nil, nodes: [], type:, argument: nil, extensions: nil, coerce_extensions: nil)
9
9
  super(message, path: path, nodes: nodes)
10
10
  @type_name = type
11
11
  @argument_name = argument
12
12
  @extensions = extensions
13
+ @coerce_extensions = coerce_extensions
13
14
  end
14
15
 
15
16
  # A hash representation of this Message
16
17
  def to_h
17
- extensions = {
18
- "code" => code,
19
- "typeName" => type_name
20
- }.tap { |h| h["argumentName"] = argument_name unless argument_name.nil? }
18
+ if @coerce_extensions
19
+ extensions = @coerce_extensions
20
+ # This is for legacy compat -- but this key is supposed to be a GraphQL type name :confounded:
21
+ extensions["typeName"] = "CoercionError"
22
+ else
23
+ extensions = {
24
+ "code" => code,
25
+ "typeName" => type_name
26
+ }
27
+
28
+ if argument_name
29
+ extensions["argumentName"] = argument_name
30
+ end
31
+ end
32
+
21
33
  extensions.merge!(@extensions) unless @extensions.nil?
22
34
  super.merge({
23
35
  "extensions" => extensions
@@ -3,26 +3,7 @@ module GraphQL
3
3
  module StaticValidation
4
4
  module ArgumentsAreDefined
5
5
  def on_argument(node, parent)
6
- parent_defn = case parent
7
- when GraphQL::Language::Nodes::InputObject
8
- arg_defn = context.argument_definition
9
- if arg_defn.nil?
10
- nil
11
- else
12
- arg_ret_type = arg_defn.type.unwrap
13
- if arg_ret_type.kind.input_object?
14
- arg_ret_type
15
- else
16
- nil
17
- end
18
- end
19
- when GraphQL::Language::Nodes::Directive
20
- context.schema.directives[parent.name]
21
- when GraphQL::Language::Nodes::Field
22
- context.field_definition
23
- else
24
- raise "Unexpected argument parent: #{parent.class} (##{parent})"
25
- end
6
+ parent_defn = parent_definition(parent)
26
7
 
27
8
  if parent_defn && context.warden.arguments(parent_defn).any? { |arg| arg.name == node.name }
28
9
  super
@@ -44,6 +25,7 @@ module GraphQL
44
25
 
45
26
  private
46
27
 
28
+ # TODO smell: these methods are added to all visitors, since they're included in a module.
47
29
  def parent_name(parent, type_defn)
48
30
  case parent
49
31
  when GraphQL::Language::Nodes::Field
@@ -60,6 +42,29 @@ module GraphQL
60
42
  def node_type(parent)
61
43
  parent.class.name.split("::").last
62
44
  end
45
+
46
+ def parent_definition(parent)
47
+ case parent
48
+ when GraphQL::Language::Nodes::InputObject
49
+ arg_defn = context.argument_definition
50
+ if arg_defn.nil?
51
+ nil
52
+ else
53
+ arg_ret_type = arg_defn.type.unwrap
54
+ if arg_ret_type.kind.input_object?
55
+ arg_ret_type
56
+ else
57
+ nil
58
+ end
59
+ end
60
+ when GraphQL::Language::Nodes::Directive
61
+ context.schema.directives[parent.name]
62
+ when GraphQL::Language::Nodes::Field
63
+ context.field_definition
64
+ else
65
+ raise "Unexpected argument parent: #{parent.class} (##{parent})"
66
+ end
67
+ end
63
68
  end
64
69
  end
65
70
  end
@@ -17,22 +17,22 @@ module GraphQL
17
17
  if type.nil?
18
18
  # This is handled by another validator
19
19
  else
20
- begin
21
- valid = context.valid_literal?(value, type)
22
- rescue GraphQL::CoercionError => err
23
- error_message = err.message
24
- rescue GraphQL::LiteralValidationError
25
- # noop, we just want to stop any LiteralValidationError from propagating
26
- end
20
+ validation_result = context.validate_literal(value, type)
21
+
22
+ if !validation_result.valid?
23
+ problems = validation_result.problems
24
+ first_problem = problems && problems.first
25
+ if first_problem
26
+ error_message = first_problem["message"]
27
+ end
27
28
 
28
- if !valid
29
29
  error_message ||= "Default value for $#{node.name} doesn't match type #{type.to_type_signature}"
30
30
  add_error(GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTypedError.new(
31
31
  error_message,
32
32
  nodes: node,
33
33
  name: node.name,
34
34
  type: type.to_type_signature,
35
- error_type: VariableDefaultValuesAreCorrectlyTypedError::VIOLATIONS[:INVALID_TYPE]
35
+ error_type: VariableDefaultValuesAreCorrectlyTypedError::VIOLATIONS[:INVALID_TYPE],
36
36
  ))
37
37
  end
38
38
  end
@@ -35,7 +35,7 @@ module GraphQL
35
35
  @on_dependency_resolve_handlers << handler
36
36
  end
37
37
 
38
- def valid_literal?(ast_value, type)
38
+ def validate_literal(ast_value, type)
39
39
  @literal_validator.validate(ast_value, type)
40
40
  end
41
41
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.10.4"
3
+ VERSION = "1.10.5"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.4
4
+ version: 1.10.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-03 00:00:00.000000000 Z
11
+ date: 2020-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -482,7 +482,6 @@ files:
482
482
  - lib/graphql/language/token.rb
483
483
  - lib/graphql/language/visitor.rb
484
484
  - lib/graphql/list_type.rb
485
- - lib/graphql/literal_validation_error.rb
486
485
  - lib/graphql/load_application_object_failed_error.rb
487
486
  - lib/graphql/name_validator.rb
488
487
  - lib/graphql/non_null_type.rb
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- class LiteralValidationError < GraphQL::Error
4
- attr_accessor :ast_value
5
- end
6
- end