graphql 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql.rb +10 -0
- data/lib/graphql/base_type.rb +8 -5
- data/lib/graphql/compatibility.rb +3 -0
- data/lib/graphql/compatibility/execution_specification.rb +414 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +117 -0
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +81 -0
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +78 -0
- data/lib/graphql/compatibility/schema_parser_specification.rb +239 -0
- data/lib/graphql/define/instance_definable.rb +53 -21
- data/lib/graphql/directive.rb +1 -1
- data/lib/graphql/enum_type.rb +31 -8
- data/lib/graphql/execution/directive_checks.rb +0 -6
- data/lib/graphql/input_object_type.rb +6 -4
- data/lib/graphql/introspection/arguments_field.rb +3 -1
- data/lib/graphql/introspection/enum_values_field.rb +10 -5
- data/lib/graphql/introspection/fields_field.rb +1 -1
- data/lib/graphql/introspection/input_fields_field.rb +2 -2
- data/lib/graphql/introspection/interfaces_field.rb +7 -1
- data/lib/graphql/introspection/possible_types_field.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +1 -1
- data/lib/graphql/introspection/type_by_name_field.rb +4 -2
- data/lib/graphql/introspection/type_type.rb +7 -6
- data/lib/graphql/language/lexer.rl +0 -4
- data/lib/graphql/language/parser.rb +1 -1
- data/lib/graphql/language/parser.y +1 -1
- data/lib/graphql/list_type.rb +3 -4
- data/lib/graphql/non_null_type.rb +4 -8
- data/lib/graphql/object_type.rb +5 -3
- data/lib/graphql/query.rb +48 -12
- data/lib/graphql/query/context.rb +7 -1
- data/lib/graphql/query/serial_execution/execution_context.rb +8 -3
- data/lib/graphql/query/serial_execution/field_resolution.rb +8 -5
- data/lib/graphql/query/serial_execution/operation_resolution.rb +2 -2
- data/lib/graphql/query/serial_execution/selection_resolution.rb +4 -21
- data/lib/graphql/query/serial_execution/value_resolution.rb +59 -99
- data/lib/graphql/query/variables.rb +7 -2
- data/lib/graphql/scalar_type.rb +1 -1
- data/lib/graphql/schema.rb +49 -18
- data/lib/graphql/schema/build_from_definition.rb +248 -0
- data/lib/graphql/schema/instrumented_field_map.rb +23 -0
- data/lib/graphql/schema/loader.rb +4 -11
- data/lib/graphql/schema/possible_types.rb +4 -2
- data/lib/graphql/schema/printer.rb +1 -1
- data/lib/graphql/schema/type_expression.rb +4 -4
- data/lib/graphql/schema/type_map.rb +1 -1
- data/lib/graphql/schema/validation.rb +4 -0
- data/lib/graphql/schema/warden.rb +114 -0
- data/lib/graphql/static_validation/literal_validator.rb +10 -7
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -3
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -14
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +3 -4
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +2 -1
- data/lib/graphql/static_validation/validation_context.rb +7 -1
- data/lib/graphql/union_type.rb +6 -3
- data/lib/graphql/unresolved_type_error.rb +1 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -5
- data/spec/graphql/compatibility/execution_specification_spec.rb +3 -0
- data/spec/graphql/compatibility/query_parser_specification_spec.rb +5 -0
- data/spec/graphql/compatibility/schema_parser_specification_spec.rb +5 -0
- data/spec/graphql/define/instance_definable_spec.rb +20 -0
- data/spec/graphql/directive_spec.rb +11 -0
- data/spec/graphql/enum_type_spec.rb +20 -1
- data/spec/graphql/input_object_type_spec.rb +9 -9
- data/spec/graphql/introspection/directive_type_spec.rb +4 -4
- data/spec/graphql/introspection/input_value_type_spec.rb +6 -6
- data/spec/graphql/introspection/type_type_spec.rb +28 -26
- data/spec/graphql/language/parser_spec.rb +27 -17
- data/spec/graphql/list_type_spec.rb +2 -2
- data/spec/graphql/query/variables_spec.rb +1 -0
- data/spec/graphql/scalar_type_spec.rb +3 -3
- data/spec/graphql/schema/build_from_definition_spec.rb +693 -0
- data/spec/graphql/schema/type_expression_spec.rb +3 -3
- data/spec/graphql/schema/validation_spec.rb +7 -3
- data/spec/graphql/schema/warden_spec.rb +510 -0
- data/spec/graphql/schema_spec.rb +129 -0
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +1 -1
- data/spec/graphql/static_validation/type_stack_spec.rb +3 -3
- data/spec/spec_helper.rb +27 -1
- data/spec/support/dairy_app.rb +8 -5
- metadata +21 -3
- data/lib/graphql/language/parser_tests.rb +0 -809
data/lib/graphql/object_type.rb
CHANGED
@@ -46,9 +46,11 @@ module GraphQL
|
|
46
46
|
def interfaces
|
47
47
|
@clean_interfaces ||= begin
|
48
48
|
ensure_defined
|
49
|
-
@dirty_interfaces.map
|
50
|
-
|
51
|
-
|
49
|
+
if @dirty_interfaces.respond_to?(:map)
|
50
|
+
@dirty_interfaces.map { |i_type| GraphQL::BaseType.resolve_related_type(i_type) }
|
51
|
+
else
|
52
|
+
@dirty_interfaces
|
53
|
+
end
|
52
54
|
end
|
53
55
|
end
|
54
56
|
|
data/lib/graphql/query.rb
CHANGED
@@ -17,7 +17,15 @@ module GraphQL
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
module NullExcept
|
21
|
+
module_function
|
22
|
+
|
23
|
+
def call(member)
|
24
|
+
false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :schema, :document, :context, :fragments, :operations, :root_value, :max_depth, :query_string, :warden
|
21
29
|
|
22
30
|
# Prepare query `query_string` on `schema`
|
23
31
|
# @param schema [GraphQL::Schema]
|
@@ -28,10 +36,12 @@ module GraphQL
|
|
28
36
|
# @param root_value [Object] the object used to resolve fields on the root type
|
29
37
|
# @param max_depth [Numeric] the maximum number of nested selections allowed for this query (falls back to schema-level value)
|
30
38
|
# @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value)
|
31
|
-
|
39
|
+
# @param except [<#call(schema_member)>] If provided, objects will be hidden from the schema when `.call(schema_member)` returns truthy
|
40
|
+
def initialize(schema, query_string = nil, document: nil, context: nil, variables: {}, validate: true, operation_name: nil, root_value: nil, max_depth: nil, max_complexity: nil, except: NullExcept)
|
32
41
|
fail ArgumentError, "a query string or document is required" unless query_string || document
|
33
42
|
|
34
43
|
@schema = schema
|
44
|
+
@warden = GraphQL::Schema::Warden.new(schema, except)
|
35
45
|
@max_depth = max_depth || schema.max_depth
|
36
46
|
@max_complexity = max_complexity || schema.max_complexity
|
37
47
|
@query_analyzers = schema.query_analyzers.dup
|
@@ -81,16 +91,9 @@ module GraphQL
|
|
81
91
|
# Get the result for this query, executing it once
|
82
92
|
def result
|
83
93
|
@result ||= begin
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
{ "errors" => all_errors.map(&:to_h) }
|
88
|
-
else
|
89
|
-
nil
|
90
|
-
end
|
91
|
-
else
|
92
|
-
Executor.new(self).result
|
93
|
-
end
|
94
|
+
instrumenters = @schema.instrumenters[:query]
|
95
|
+
execution_call = ExecutionCall.new(self, instrumenters)
|
96
|
+
execution_call.call
|
94
97
|
end
|
95
98
|
end
|
96
99
|
|
@@ -110,6 +113,7 @@ module GraphQL
|
|
110
113
|
@variables ||= begin
|
111
114
|
vars = GraphQL::Query::Variables.new(
|
112
115
|
@schema,
|
116
|
+
@warden,
|
113
117
|
@ast_variables,
|
114
118
|
@provided_variables,
|
115
119
|
)
|
@@ -198,5 +202,37 @@ module GraphQL
|
|
198
202
|
operations[operation_name]
|
199
203
|
end
|
200
204
|
end
|
205
|
+
|
206
|
+
class ExecutionCall
|
207
|
+
def initialize(query, instrumenters)
|
208
|
+
@query = query
|
209
|
+
@instrumenters = instrumenters
|
210
|
+
end
|
211
|
+
|
212
|
+
# Check if the query is valid, and if it is,
|
213
|
+
# execute it, calling instrumenters along the way
|
214
|
+
# @return [Hash] The GraphQL response
|
215
|
+
def call
|
216
|
+
@instrumenters.each { |i| i.before_query(@query) }
|
217
|
+
result = get_result
|
218
|
+
@instrumenters.each { |i| i.after_query(@query) }
|
219
|
+
result
|
220
|
+
end
|
221
|
+
|
222
|
+
private
|
223
|
+
|
224
|
+
def get_result
|
225
|
+
if !@query.valid?
|
226
|
+
all_errors = @query.validation_errors + @query.analysis_errors
|
227
|
+
if all_errors.any?
|
228
|
+
{ "errors" => all_errors.map(&:to_h) }
|
229
|
+
else
|
230
|
+
nil
|
231
|
+
end
|
232
|
+
else
|
233
|
+
Executor.new(@query).result
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
201
237
|
end
|
202
238
|
end
|
@@ -6,7 +6,9 @@ module GraphQL
|
|
6
6
|
attr_accessor :execution_strategy
|
7
7
|
|
8
8
|
# @return [GraphQL::Language::Nodes::Field] The AST node for the currently-executing field
|
9
|
-
|
9
|
+
def ast_node
|
10
|
+
irep_node.ast_node
|
11
|
+
end
|
10
12
|
|
11
13
|
# @return [GraphQL::InternalRepresentation::Node] The internal representation for this query node
|
12
14
|
attr_accessor :irep_node
|
@@ -20,6 +22,9 @@ module GraphQL
|
|
20
22
|
# @return [GraphQL::Schema]
|
21
23
|
attr_reader :schema
|
22
24
|
|
25
|
+
# @return [GraphQL::Schema::Mask::Warden]
|
26
|
+
attr_reader :warden
|
27
|
+
|
23
28
|
# Make a new context which delegates key lookup to `values`
|
24
29
|
# @param query [GraphQL::Query] the query who owns this context
|
25
30
|
# @param values [Hash] A hash of arbitrary values which will be accessible at query-time
|
@@ -28,6 +33,7 @@ module GraphQL
|
|
28
33
|
@schema = query.schema
|
29
34
|
@values = values || {}
|
30
35
|
@errors = []
|
36
|
+
@warden = query.warden
|
31
37
|
end
|
32
38
|
|
33
39
|
# Lookup `key` from the hash passed to {Schema#execute} as `context:`
|
@@ -8,10 +8,11 @@ module GraphQL
|
|
8
8
|
@query = query
|
9
9
|
@schema = query.schema
|
10
10
|
@strategy = strategy
|
11
|
+
@warden = query.warden
|
11
12
|
end
|
12
13
|
|
13
|
-
def get_type(
|
14
|
-
@
|
14
|
+
def get_type(type_name)
|
15
|
+
@warden.get_type(type_name)
|
15
16
|
end
|
16
17
|
|
17
18
|
def get_fragment(name)
|
@@ -20,7 +21,11 @@ module GraphQL
|
|
20
21
|
|
21
22
|
def get_field(type, irep_node)
|
22
23
|
# fall back for dynamic fields (eg __typename)
|
23
|
-
irep_node.definitions[type] || @
|
24
|
+
irep_node.definitions[type] || @warden.get_field(type, irep_node.definition_name) || raise("No field found on #{type.name} for '#{irep_node.definition_name}' (#{irep_node.ast_node.name})")
|
25
|
+
end
|
26
|
+
|
27
|
+
def possible_types(type)
|
28
|
+
@warden.possible_types(type)
|
24
29
|
end
|
25
30
|
|
26
31
|
def add_error(err)
|
@@ -40,10 +40,15 @@ module GraphQL
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
strategy_class = GraphQL::Query::SerialExecution::ValueResolution.get_strategy_for_kind(field.type.kind)
|
44
|
-
result_strategy = strategy_class.new(raw_value, field.type, target, parent_type, irep_node, execution_context)
|
45
43
|
begin
|
46
|
-
|
44
|
+
GraphQL::Query::SerialExecution::ValueResolution.resolve(
|
45
|
+
parent_type,
|
46
|
+
field,
|
47
|
+
field.type,
|
48
|
+
raw_value,
|
49
|
+
irep_node,
|
50
|
+
execution_context,
|
51
|
+
)
|
47
52
|
rescue GraphQL::InvalidNullError => err
|
48
53
|
if field.type.kind.non_null?
|
49
54
|
raise(err)
|
@@ -63,7 +68,6 @@ module GraphQL
|
|
63
68
|
middlewares = execution_context.query.schema.middleware
|
64
69
|
query_context = execution_context.query.context
|
65
70
|
# setup
|
66
|
-
query_context.ast_node = @irep_node.ast_node
|
67
71
|
query_context.irep_node = @irep_node
|
68
72
|
|
69
73
|
resolve_arguments = [parent_type, target, field, arguments, query_context]
|
@@ -84,7 +88,6 @@ module GraphQL
|
|
84
88
|
end
|
85
89
|
ensure
|
86
90
|
# teardown
|
87
|
-
query_context.ast_node = nil
|
88
91
|
query_context.irep_node = nil
|
89
92
|
resolve_value
|
90
93
|
end
|
@@ -11,12 +11,12 @@ module GraphQL
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def result
|
14
|
-
execution_context.strategy.selection_resolution.
|
14
|
+
execution_context.strategy.selection_resolution.resolve(
|
15
15
|
execution_context.query.root_value,
|
16
16
|
target,
|
17
17
|
irep_node,
|
18
18
|
execution_context
|
19
|
-
)
|
19
|
+
)
|
20
20
|
rescue GraphQL::InvalidNullError => err
|
21
21
|
err.parent_error? || execution_context.add_error(err)
|
22
22
|
nil
|
@@ -1,22 +1,13 @@
|
|
1
1
|
module GraphQL
|
2
2
|
class Query
|
3
3
|
class SerialExecution
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(target, type, irep_node, execution_context)
|
8
|
-
@target = target
|
9
|
-
@type = type
|
10
|
-
@irep_node = irep_node
|
11
|
-
@execution_context = execution_context
|
12
|
-
end
|
13
|
-
|
14
|
-
def result
|
4
|
+
module SelectionResolution
|
5
|
+
def self.resolve(target, current_type, irep_node, execution_context)
|
15
6
|
irep_node.children.each_with_object({}) do |(name, irep_node), memo|
|
16
|
-
if irep_node.included? &&
|
7
|
+
if irep_node.included? && irep_node.definitions.any? { |potential_type, field_defn| GraphQL::Execution::Typecast.compatible?(current_type, potential_type, execution_context.query.context) }
|
17
8
|
field_result = execution_context.strategy.field_resolution.new(
|
18
9
|
irep_node,
|
19
|
-
|
10
|
+
current_type,
|
20
11
|
target,
|
21
12
|
execution_context
|
22
13
|
).result
|
@@ -24,14 +15,6 @@ module GraphQL
|
|
24
15
|
end
|
25
16
|
end
|
26
17
|
end
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def applies_to_type?(irep_node, current_type)
|
31
|
-
irep_node.definitions.any? { |potential_type, field_defn|
|
32
|
-
GraphQL::Execution::Typecast.compatible?(current_type, potential_type, execution_context.query.context)
|
33
|
-
}
|
34
|
-
end
|
35
18
|
end
|
36
19
|
end
|
37
20
|
end
|
@@ -2,112 +2,72 @@ module GraphQL
|
|
2
2
|
class Query
|
3
3
|
class SerialExecution
|
4
4
|
module ValueResolution
|
5
|
-
def self.
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
class BaseResolution
|
10
|
-
attr_reader :value, :field_type, :target, :parent_type,
|
11
|
-
:irep_node, :execution_context
|
12
|
-
def initialize(value, field_type, target, parent_type, irep_node, execution_context)
|
13
|
-
@value = value
|
14
|
-
@field_type = field_type
|
15
|
-
@target = target
|
16
|
-
@parent_type = parent_type
|
17
|
-
@irep_node = irep_node
|
18
|
-
@execution_context = execution_context
|
19
|
-
end
|
20
|
-
|
21
|
-
def result
|
22
|
-
if value.nil? || value.is_a?(GraphQL::ExecutionError)
|
23
|
-
nil
|
5
|
+
def self.resolve(parent_type, field_defn, field_type, value, irep_node, execution_context)
|
6
|
+
if value.nil? || value.is_a?(GraphQL::ExecutionError)
|
7
|
+
if field_type.kind.non_null?
|
8
|
+
raise GraphQL::InvalidNullError.new(parent_type.name, field_defn.name, value)
|
24
9
|
else
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def non_null_result
|
30
|
-
raise NotImplementedError, "Should return a value based on initialization params"
|
31
|
-
end
|
32
|
-
|
33
|
-
def get_strategy_for_kind(*args)
|
34
|
-
GraphQL::Query::SerialExecution::ValueResolution.get_strategy_for_kind(*args)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
class ScalarResolution < BaseResolution
|
39
|
-
# Apply the scalar's defined `coerce_result` method to the value
|
40
|
-
def non_null_result
|
41
|
-
field_type.coerce_result(value)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
class ListResolution < BaseResolution
|
46
|
-
# For each item in the list,
|
47
|
-
# Resolve it with the "wrapped" type of this list
|
48
|
-
def non_null_result
|
49
|
-
wrapped_type = field_type.of_type
|
50
|
-
strategy_class = get_strategy_for_kind(wrapped_type.kind)
|
51
|
-
result = value.each_with_index.map do |item, index|
|
52
|
-
irep_node.index = index
|
53
|
-
inner_strategy = strategy_class.new(item, wrapped_type, target, parent_type, irep_node, execution_context)
|
54
|
-
inner_strategy.result
|
55
|
-
end
|
56
|
-
irep_node.index = nil
|
57
|
-
result
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
class HasPossibleTypeResolution < BaseResolution
|
62
|
-
def non_null_result
|
63
|
-
resolved_type = execution_context.schema.resolve_type(value, execution_context.query.context)
|
64
|
-
possible_types = execution_context.schema.possible_types(field_type)
|
65
|
-
|
66
|
-
unless resolved_type.is_a?(GraphQL::ObjectType) && possible_types.include?(resolved_type)
|
67
|
-
raise GraphQL::UnresolvedTypeError.new(irep_node.definition_name, execution_context.schema, field_type, parent_type, resolved_type)
|
10
|
+
nil
|
68
11
|
end
|
12
|
+
else
|
13
|
+
case field_type.kind
|
14
|
+
when GraphQL::TypeKinds::SCALAR
|
15
|
+
field_type.coerce_result(value)
|
16
|
+
when GraphQL::TypeKinds::ENUM
|
17
|
+
field_type.coerce_result(value, execution_context.query.warden)
|
18
|
+
when GraphQL::TypeKinds::LIST
|
19
|
+
wrapped_type = field_type.of_type
|
20
|
+
result = value.each_with_index.map do |inner_value, index|
|
21
|
+
irep_node.index = index
|
22
|
+
resolve(
|
23
|
+
parent_type,
|
24
|
+
field_defn,
|
25
|
+
wrapped_type,
|
26
|
+
inner_value,
|
27
|
+
irep_node,
|
28
|
+
execution_context,
|
29
|
+
)
|
30
|
+
end
|
31
|
+
irep_node.index = nil
|
32
|
+
result
|
33
|
+
when GraphQL::TypeKinds::NON_NULL
|
34
|
+
wrapped_type = field_type.of_type
|
35
|
+
resolve(
|
36
|
+
parent_type,
|
37
|
+
field_defn,
|
38
|
+
wrapped_type,
|
39
|
+
value,
|
40
|
+
irep_node,
|
41
|
+
execution_context,
|
42
|
+
)
|
43
|
+
when GraphQL::TypeKinds::OBJECT
|
44
|
+
execution_context.strategy.selection_resolution.resolve(
|
45
|
+
value,
|
46
|
+
field_type,
|
47
|
+
irep_node,
|
48
|
+
execution_context
|
49
|
+
)
|
50
|
+
when GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE
|
51
|
+
resolved_type = execution_context.schema.resolve_type(value, execution_context.query.context)
|
52
|
+
possible_types = execution_context.possible_types(field_type)
|
69
53
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
irep_node,
|
83
|
-
execution_context
|
84
|
-
).result
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
class NonNullResolution < BaseResolution
|
89
|
-
# Get the "wrapped" type and resolve the value according to that type
|
90
|
-
def result
|
91
|
-
if value.nil? || value.is_a?(GraphQL::ExecutionError)
|
92
|
-
raise GraphQL::InvalidNullError.new(parent_type.name, irep_node.definition_name, value)
|
54
|
+
if !possible_types.include?(resolved_type)
|
55
|
+
raise GraphQL::UnresolvedTypeError.new(irep_node.definition_name, field_type, parent_type, resolved_type, possible_types)
|
56
|
+
else
|
57
|
+
resolve(
|
58
|
+
parent_type,
|
59
|
+
field_defn,
|
60
|
+
resolved_type,
|
61
|
+
value,
|
62
|
+
irep_node,
|
63
|
+
execution_context,
|
64
|
+
)
|
65
|
+
end
|
93
66
|
else
|
94
|
-
|
95
|
-
strategy_class = get_strategy_for_kind(wrapped_type.kind)
|
96
|
-
inner_strategy = strategy_class.new(value, wrapped_type, target, parent_type, irep_node, execution_context)
|
97
|
-
inner_strategy.result
|
67
|
+
raise("Unknown type kind: #{field_type.kind}")
|
98
68
|
end
|
99
69
|
end
|
100
70
|
end
|
101
|
-
|
102
|
-
TYPE_KIND_STRATEGIES = {
|
103
|
-
GraphQL::TypeKinds::SCALAR => ScalarResolution,
|
104
|
-
GraphQL::TypeKinds::LIST => ListResolution,
|
105
|
-
GraphQL::TypeKinds::OBJECT => ObjectResolution,
|
106
|
-
GraphQL::TypeKinds::ENUM => ScalarResolution,
|
107
|
-
GraphQL::TypeKinds::NON_NULL => NonNullResolution,
|
108
|
-
GraphQL::TypeKinds::INTERFACE => HasPossibleTypeResolution,
|
109
|
-
GraphQL::TypeKinds::UNION => HasPossibleTypeResolution,
|
110
|
-
}
|
111
71
|
end
|
112
72
|
end
|
113
73
|
end
|
@@ -2,11 +2,14 @@ module GraphQL
|
|
2
2
|
class Query
|
3
3
|
# Read-only access to query variables, applying default values if needed.
|
4
4
|
class Variables
|
5
|
+
extend Forwardable
|
6
|
+
|
5
7
|
# @return [Array<GraphQL::Query::VariableValidationError>] Any errors encountered when parsing the provided variables and literal values
|
6
8
|
attr_reader :errors
|
7
9
|
|
8
|
-
def initialize(schema, ast_variables, provided_variables)
|
10
|
+
def initialize(schema, warden, ast_variables, provided_variables)
|
9
11
|
@schema = schema
|
12
|
+
@warden = warden
|
10
13
|
@provided_variables = provided_variables
|
11
14
|
@errors = []
|
12
15
|
@storage = ast_variables.each_with_object({}) do |ast_variable, memo|
|
@@ -19,6 +22,8 @@ module GraphQL
|
|
19
22
|
@storage.fetch(key)
|
20
23
|
end
|
21
24
|
|
25
|
+
def_delegators :@storage, :length
|
26
|
+
|
22
27
|
private
|
23
28
|
|
24
29
|
# Find the right value for this variable:
|
@@ -31,7 +36,7 @@ module GraphQL
|
|
31
36
|
default_value = ast_variable.default_value
|
32
37
|
provided_value = @provided_variables[variable_name]
|
33
38
|
|
34
|
-
validation_result = variable_type.validate_input(provided_value)
|
39
|
+
validation_result = variable_type.validate_input(provided_value, @warden)
|
35
40
|
if !validation_result.valid?
|
36
41
|
@errors << GraphQL::Query::VariableValidationError.new(ast_variable, variable_type, provided_value, validation_result)
|
37
42
|
elsif provided_value.nil?
|