graphql 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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?
|