graphql 1.6.8 → 1.7.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 +5 -0
- data/lib/graphql/analysis/analyze_query.rb +21 -17
- data/lib/graphql/argument.rb +6 -2
- data/lib/graphql/backtrace.rb +50 -0
- data/lib/graphql/backtrace/inspect_result.rb +51 -0
- data/lib/graphql/backtrace/table.rb +120 -0
- data/lib/graphql/backtrace/traced_error.rb +55 -0
- data/lib/graphql/backtrace/tracer.rb +50 -0
- data/lib/graphql/enum_type.rb +1 -10
- data/lib/graphql/execution.rb +1 -2
- data/lib/graphql/execution/execute.rb +98 -89
- data/lib/graphql/execution/flatten.rb +40 -0
- data/lib/graphql/execution/lazy/resolve.rb +7 -7
- data/lib/graphql/execution/multiplex.rb +29 -29
- data/lib/graphql/field.rb +5 -1
- data/lib/graphql/internal_representation/node.rb +16 -0
- data/lib/graphql/invalid_name_error.rb +11 -0
- data/lib/graphql/language/parser.rb +11 -5
- data/lib/graphql/language/parser.y +11 -5
- data/lib/graphql/name_validator.rb +16 -0
- data/lib/graphql/object_type.rb +5 -0
- data/lib/graphql/query.rb +28 -7
- data/lib/graphql/query/context.rb +155 -52
- data/lib/graphql/query/literal_input.rb +36 -9
- data/lib/graphql/query/null_context.rb +7 -1
- data/lib/graphql/query/result.rb +63 -0
- data/lib/graphql/query/serial_execution/field_resolution.rb +3 -4
- data/lib/graphql/query/serial_execution/value_resolution.rb +3 -4
- data/lib/graphql/query/variables.rb +1 -1
- data/lib/graphql/schema.rb +31 -0
- data/lib/graphql/schema/traversal.rb +16 -1
- data/lib/graphql/schema/warden.rb +40 -4
- data/lib/graphql/static_validation/validator.rb +20 -18
- data/lib/graphql/subscriptions.rb +129 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +122 -0
- data/lib/graphql/subscriptions/event.rb +52 -0
- data/lib/graphql/subscriptions/instrumentation.rb +68 -0
- data/lib/graphql/tracing.rb +80 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +31 -0
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/graphql/analysis/analyze_query_spec.rb +19 -0
- data/spec/graphql/argument_spec.rb +28 -0
- data/spec/graphql/backtrace_spec.rb +144 -0
- data/spec/graphql/define/assign_argument_spec.rb +12 -0
- data/spec/graphql/enum_type_spec.rb +1 -1
- data/spec/graphql/execution/execute_spec.rb +66 -0
- data/spec/graphql/execution/lazy_spec.rb +4 -3
- data/spec/graphql/language/parser_spec.rb +16 -0
- data/spec/graphql/object_type_spec.rb +14 -0
- data/spec/graphql/query/context_spec.rb +134 -27
- data/spec/graphql/query/result_spec.rb +29 -0
- data/spec/graphql/query/variables_spec.rb +13 -0
- data/spec/graphql/query_spec.rb +22 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +2 -0
- data/spec/graphql/schema/traversal_spec.rb +70 -12
- data/spec/graphql/schema/warden_spec.rb +67 -1
- data/spec/graphql/schema_spec.rb +29 -0
- data/spec/graphql/static_validation/validator_spec.rb +16 -0
- data/spec/graphql/subscriptions_spec.rb +331 -0
- data/spec/graphql/tracing/active_support_notifications_tracing_spec.rb +57 -0
- data/spec/graphql/tracing_spec.rb +47 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/star_wars/schema.rb +39 -0
- metadata +27 -4
- data/lib/graphql/execution/field_result.rb +0 -54
- data/lib/graphql/execution/selection_result.rb +0 -90
data/lib/graphql/enum_type.rb
CHANGED
@@ -141,13 +141,7 @@ module GraphQL
|
|
141
141
|
|
142
142
|
def name=(new_name)
|
143
143
|
# Validate that the name is correct
|
144
|
-
|
145
|
-
raise(
|
146
|
-
GraphQL::EnumType::InvalidEnumNameError,
|
147
|
-
"Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but '#{new_name}' does not"
|
148
|
-
)
|
149
|
-
end
|
150
|
-
|
144
|
+
GraphQL::NameValidator.validate!(new_name)
|
151
145
|
@name = new_name
|
152
146
|
end
|
153
147
|
end
|
@@ -155,9 +149,6 @@ module GraphQL
|
|
155
149
|
class UnresolvedValueError < GraphQL::Error
|
156
150
|
end
|
157
151
|
|
158
|
-
class InvalidEnumNameError < GraphQL::Error
|
159
|
-
end
|
160
|
-
|
161
152
|
private
|
162
153
|
|
163
154
|
# Get the underlying value for this enum value
|
data/lib/graphql/execution.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "graphql/execution/directive_checks"
|
3
3
|
require "graphql/execution/execute"
|
4
|
-
require "graphql/execution/
|
4
|
+
require "graphql/execution/flatten"
|
5
5
|
require "graphql/execution/lazy"
|
6
6
|
require "graphql/execution/multiplex"
|
7
|
-
require "graphql/execution/selection_result"
|
8
7
|
require "graphql/execution/typecast"
|
@@ -13,104 +13,126 @@ module GraphQL
|
|
13
13
|
SKIP = Skip.new
|
14
14
|
|
15
15
|
# @api private
|
16
|
-
|
16
|
+
class PropagateNull
|
17
|
+
end
|
18
|
+
# @api private
|
19
|
+
PROPAGATE_NULL = PropagateNull.new
|
17
20
|
|
18
21
|
def execute(ast_operation, root_type, query)
|
19
|
-
result =
|
20
|
-
|
21
|
-
|
22
|
-
query.irep_selection,
|
23
|
-
query.context,
|
24
|
-
mutation: query.mutation?
|
25
|
-
)
|
26
|
-
|
27
|
-
GraphQL::Execution::Lazy.resolve(result)
|
28
|
-
|
29
|
-
result.to_h
|
22
|
+
result = resolve_root_selection(query)
|
23
|
+
lazy_resolve_root_selection(result, {query: query})
|
24
|
+
GraphQL::Execution::Flatten.call(query.context)
|
30
25
|
end
|
31
26
|
|
32
27
|
# @api private
|
33
28
|
module ExecutionFunctions
|
34
29
|
module_function
|
35
30
|
|
36
|
-
def
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
query_ctx
|
31
|
+
def resolve_root_selection(query)
|
32
|
+
GraphQL::Tracing.trace("execute_query", query: query) do
|
33
|
+
operation = query.selected_operation
|
34
|
+
op_type = operation.operation_type
|
35
|
+
root_type = query.root_type_for_operation(op_type)
|
36
|
+
resolve_selection(
|
37
|
+
query.root_value,
|
38
|
+
root_type,
|
39
|
+
query.context,
|
40
|
+
mutation: query.mutation?
|
47
41
|
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def lazy_resolve_root_selection(result, query: nil, queries: nil)
|
46
|
+
if query.nil? && queries.length == 1
|
47
|
+
query = queries[0]
|
48
|
+
end
|
49
|
+
|
50
|
+
GraphQL::Tracing.trace("execute_query_lazy", {queries: queries, query: query}) do
|
51
|
+
GraphQL::Execution::Lazy.resolve(result)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def resolve_selection(object, current_type, current_ctx, mutation: false )
|
56
|
+
# Assign this _before_ resolving the children
|
57
|
+
# so that when a child propagates null, the selection result is
|
58
|
+
# ready for it.
|
59
|
+
current_ctx.value = {}
|
60
|
+
|
61
|
+
selections_on_type = current_ctx.irep_node.typed_children[current_type]
|
62
|
+
|
63
|
+
selections_on_type.each do |name, child_irep_node|
|
64
|
+
field_ctx = current_ctx.spawn_child(
|
65
|
+
key: name,
|
66
|
+
object: object,
|
67
|
+
irep_node: child_irep_node,
|
68
|
+
)
|
69
|
+
|
70
|
+
field_result = GraphQL::Tracing.trace("execute_field", { context: field_ctx }) do
|
71
|
+
resolve_field(
|
72
|
+
object,
|
73
|
+
field_ctx
|
74
|
+
)
|
75
|
+
end
|
48
76
|
|
49
77
|
if field_result.is_a?(Skip)
|
50
78
|
next
|
51
79
|
end
|
52
80
|
|
53
81
|
if mutation
|
54
|
-
GraphQL::Execution::Lazy.resolve(
|
82
|
+
GraphQL::Execution::Lazy.resolve(field_ctx)
|
55
83
|
end
|
56
84
|
|
57
|
-
selection_result.set(name, field_result)
|
58
85
|
|
59
86
|
# If the last subselection caused a null to propagate to _this_ selection,
|
60
87
|
# then we may as well quit executing fields because they
|
61
88
|
# won't be in the response
|
62
|
-
if
|
89
|
+
if current_ctx.invalid_null?
|
63
90
|
break
|
91
|
+
else
|
92
|
+
current_ctx.value[name] = field_ctx
|
64
93
|
end
|
65
94
|
end
|
66
95
|
|
67
|
-
|
96
|
+
current_ctx.value
|
68
97
|
end
|
69
98
|
|
70
|
-
def resolve_field(
|
71
|
-
query =
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
key: selection.name,
|
76
|
-
selection: selection,
|
77
|
-
)
|
99
|
+
def resolve_field(object, field_ctx)
|
100
|
+
query = field_ctx.query
|
101
|
+
irep_node = field_ctx.irep_node
|
102
|
+
parent_type = irep_node.owner_type
|
103
|
+
field = field_ctx.field
|
78
104
|
|
79
105
|
raw_value = begin
|
80
|
-
arguments = query.arguments_for(
|
81
|
-
|
106
|
+
arguments = query.arguments_for(irep_node, field)
|
107
|
+
field_ctx.schema.middleware.invoke([parent_type, object, field, arguments, field_ctx])
|
82
108
|
rescue GraphQL::ExecutionError => err
|
83
109
|
err
|
84
110
|
end
|
85
111
|
|
86
|
-
|
87
|
-
|
88
|
-
|
112
|
+
# If the returned object is lazy (unfinished),
|
113
|
+
# assign the lazy object to `.value=` so we can resolve it later.
|
114
|
+
# When we resolve it later, reassign it to `.value=` so that
|
115
|
+
# the finished value replaces the unfinished one.
|
116
|
+
#
|
117
|
+
# If the returned object is finished, continue to coerce
|
118
|
+
# and resolve child fields
|
119
|
+
if query.schema.lazy?(raw_value)
|
120
|
+
field_ctx.value = field.prepare_lazy(raw_value, arguments, field_ctx).then { |inner_value|
|
121
|
+
field_ctx.value = continue_resolve_field(inner_value, field_ctx)
|
89
122
|
}
|
90
123
|
elsif raw_value.is_a?(GraphQL::Execution::Lazy)
|
91
124
|
# It came from a connection resolve, assume it was already instrumented
|
92
|
-
raw_value.then { |inner_value|
|
93
|
-
continue_resolve_field(
|
125
|
+
field_ctx.value = raw_value.then { |inner_value|
|
126
|
+
field_ctx.value = continue_resolve_field(inner_value, field_ctx)
|
94
127
|
}
|
95
128
|
else
|
96
|
-
continue_resolve_field(
|
97
|
-
end
|
98
|
-
|
99
|
-
case result
|
100
|
-
when PROPAGATE_NULL, GraphQL::Execution::Lazy, SelectionResult
|
101
|
-
FieldResult.new(
|
102
|
-
owner: owner,
|
103
|
-
type: field.type,
|
104
|
-
value: result,
|
105
|
-
)
|
106
|
-
else
|
107
|
-
result
|
129
|
+
field_ctx.value = continue_resolve_field(raw_value, field_ctx)
|
108
130
|
end
|
109
131
|
end
|
110
132
|
|
111
|
-
def continue_resolve_field(
|
112
|
-
if
|
113
|
-
return
|
133
|
+
def continue_resolve_field(raw_value, field_ctx)
|
134
|
+
if field_ctx.parent.invalid_null?
|
135
|
+
return nil
|
114
136
|
end
|
115
137
|
query = field_ctx.query
|
116
138
|
|
@@ -131,19 +153,18 @@ module GraphQL
|
|
131
153
|
end
|
132
154
|
|
133
155
|
resolve_value(
|
134
|
-
owner,
|
135
|
-
parent_type,
|
136
|
-
field,
|
137
|
-
field.type,
|
138
156
|
raw_value,
|
139
|
-
|
157
|
+
field_ctx.type,
|
140
158
|
field_ctx,
|
141
159
|
)
|
142
160
|
end
|
143
161
|
|
144
|
-
def resolve_value(
|
162
|
+
def resolve_value(value, field_type, field_ctx)
|
163
|
+
field_defn = field_ctx.field
|
164
|
+
|
145
165
|
if value.nil?
|
146
166
|
if field_type.kind.non_null?
|
167
|
+
parent_type = field_ctx.irep_node.owner_type
|
147
168
|
type_error = GraphQL::InvalidNullError.new(parent_type, field_defn, value)
|
148
169
|
field_ctx.schema.type_error(type_error, field_ctx)
|
149
170
|
PROPAGATE_NULL
|
@@ -157,55 +178,46 @@ module GraphQL
|
|
157
178
|
nil
|
158
179
|
end
|
159
180
|
elsif value.is_a?(Skip)
|
160
|
-
value
|
181
|
+
field_ctx.value = value
|
161
182
|
else
|
162
183
|
case field_type.kind
|
163
|
-
when GraphQL::TypeKinds::SCALAR
|
164
|
-
field_type.coerce_result(value, field_ctx)
|
165
|
-
when GraphQL::TypeKinds::ENUM
|
184
|
+
when GraphQL::TypeKinds::SCALAR, GraphQL::TypeKinds::ENUM
|
166
185
|
field_type.coerce_result(value, field_ctx)
|
167
186
|
when GraphQL::TypeKinds::LIST
|
168
187
|
inner_type = field_type.of_type
|
169
188
|
i = 0
|
170
189
|
result = []
|
190
|
+
field_ctx.value = result
|
191
|
+
|
171
192
|
value.each do |inner_value|
|
172
|
-
inner_ctx = field_ctx.
|
193
|
+
inner_ctx = field_ctx.spawn_child(
|
173
194
|
key: i,
|
174
|
-
|
175
|
-
|
176
|
-
field: field_defn,
|
195
|
+
object: inner_value,
|
196
|
+
irep_node: field_ctx.irep_node,
|
177
197
|
)
|
178
198
|
|
179
199
|
inner_result = resolve_value(
|
180
|
-
owner,
|
181
|
-
parent_type,
|
182
|
-
field_defn,
|
183
|
-
inner_type,
|
184
200
|
inner_value,
|
185
|
-
|
201
|
+
inner_type,
|
186
202
|
inner_ctx,
|
187
203
|
)
|
188
204
|
|
189
|
-
|
205
|
+
inner_ctx.value = inner_result
|
206
|
+
result << inner_ctx
|
190
207
|
i += 1
|
191
208
|
end
|
192
209
|
result
|
193
210
|
when GraphQL::TypeKinds::NON_NULL
|
194
|
-
|
211
|
+
inner_type = field_type.of_type
|
195
212
|
resolve_value(
|
196
|
-
owner,
|
197
|
-
parent_type,
|
198
|
-
field_defn,
|
199
|
-
wrapped_type,
|
200
213
|
value,
|
201
|
-
|
214
|
+
inner_type,
|
202
215
|
field_ctx,
|
203
216
|
)
|
204
217
|
when GraphQL::TypeKinds::OBJECT
|
205
218
|
resolve_selection(
|
206
219
|
value,
|
207
220
|
field_type,
|
208
|
-
selection,
|
209
221
|
field_ctx
|
210
222
|
)
|
211
223
|
when GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE
|
@@ -214,17 +226,14 @@ module GraphQL
|
|
214
226
|
possible_types = query.possible_types(field_type)
|
215
227
|
|
216
228
|
if !possible_types.include?(resolved_type)
|
229
|
+
parent_type = field_ctx.irep_node.owner_type
|
217
230
|
type_error = GraphQL::UnresolvedTypeError.new(value, field_defn, parent_type, resolved_type, possible_types)
|
218
231
|
field_ctx.schema.type_error(type_error, field_ctx)
|
219
232
|
PROPAGATE_NULL
|
220
233
|
else
|
221
234
|
resolve_value(
|
222
|
-
owner,
|
223
|
-
parent_type,
|
224
|
-
field_defn,
|
225
|
-
resolved_type,
|
226
235
|
value,
|
227
|
-
|
236
|
+
resolved_type,
|
228
237
|
field_ctx,
|
229
238
|
)
|
230
239
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Execution
|
4
|
+
# Starting from a root context,
|
5
|
+
# create a hash out of the context tree.
|
6
|
+
# @api private
|
7
|
+
module Flatten
|
8
|
+
def self.call(ctx)
|
9
|
+
flatten(ctx)
|
10
|
+
end
|
11
|
+
|
12
|
+
class << self
|
13
|
+
private
|
14
|
+
|
15
|
+
def flatten(obj)
|
16
|
+
case obj
|
17
|
+
when Hash
|
18
|
+
flattened = {}
|
19
|
+
obj.each do |key, val|
|
20
|
+
flattened[key] = flatten(val)
|
21
|
+
end
|
22
|
+
flattened
|
23
|
+
when Array
|
24
|
+
obj.map { |v| flatten(v) }
|
25
|
+
when Query::Context::SharedMethods
|
26
|
+
if obj.invalid_null?
|
27
|
+
nil
|
28
|
+
elsif obj.skipped? && obj.value.empty?
|
29
|
+
nil
|
30
|
+
else
|
31
|
+
flatten(obj.value)
|
32
|
+
end
|
33
|
+
else
|
34
|
+
obj
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -36,10 +36,10 @@ module GraphQL
|
|
36
36
|
Lazy::NullResult
|
37
37
|
else
|
38
38
|
Lazy.new {
|
39
|
-
acc.each_with_index { |
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
acc.each_with_index { |ctx, idx|
|
40
|
+
acc[idx] = GraphQL::Tracing.trace("execute_field_lazy", { context: ctx }) do
|
41
|
+
ctx.value.value
|
42
|
+
end
|
43
43
|
}
|
44
44
|
resolve_in_place(acc)
|
45
45
|
}
|
@@ -52,7 +52,7 @@ module GraphQL
|
|
52
52
|
# @return [void]
|
53
53
|
def self.each_lazy(acc, value)
|
54
54
|
case value
|
55
|
-
when
|
55
|
+
when Hash
|
56
56
|
value.each do |key, field_result|
|
57
57
|
acc = each_lazy(acc, field_result)
|
58
58
|
end
|
@@ -60,12 +60,12 @@ module GraphQL
|
|
60
60
|
value.each do |field_result|
|
61
61
|
acc = each_lazy(acc, field_result)
|
62
62
|
end
|
63
|
-
when
|
63
|
+
when Query::Context::SharedMethods
|
64
64
|
field_value = value.value
|
65
65
|
case field_value
|
66
66
|
when Lazy
|
67
67
|
acc = acc << value
|
68
|
-
when
|
68
|
+
when Enumerable # shortcut for Hash & Array
|
69
69
|
acc = each_lazy(acc, field_value)
|
70
70
|
end
|
71
71
|
end
|
@@ -46,19 +46,21 @@ module GraphQL
|
|
46
46
|
# @param max_complexity [Integer, nil]
|
47
47
|
# @return [Array<Hash>] One result per query
|
48
48
|
def run_queries(schema, queries, context: {}, max_complexity: schema.max_complexity)
|
49
|
-
|
50
|
-
|
51
|
-
if
|
52
|
-
|
49
|
+
multiplex = self.new(schema: schema, queries: queries, context: context)
|
50
|
+
GraphQL::Tracing.trace("execute_multiplex", { multiplex: multiplex }) do
|
51
|
+
if has_custom_strategy?(schema)
|
52
|
+
if queries.length != 1
|
53
|
+
raise ArgumentError, "Multiplexing doesn't support custom execution strategies, run one query at a time instead"
|
54
|
+
else
|
55
|
+
with_instrumentation(multiplex, max_complexity: max_complexity) do
|
56
|
+
[run_one_legacy(schema, queries.first)]
|
57
|
+
end
|
58
|
+
end
|
53
59
|
else
|
54
|
-
with_instrumentation(
|
55
|
-
|
60
|
+
with_instrumentation(multiplex, max_complexity: max_complexity) do
|
61
|
+
run_as_multiplex(queries)
|
56
62
|
end
|
57
63
|
end
|
58
|
-
else
|
59
|
-
with_instrumentation(schema, queries, context: context, max_complexity: max_complexity) do
|
60
|
-
run_as_multiplex(queries)
|
61
|
-
end
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
@@ -71,12 +73,14 @@ module GraphQL
|
|
71
73
|
end
|
72
74
|
|
73
75
|
# Then, work through lazy results in a breadth-first way
|
74
|
-
GraphQL::Execution::
|
76
|
+
GraphQL::Execution::Execute::ExecutionFunctions.lazy_resolve_root_selection(results, { queries: queries })
|
75
77
|
|
76
78
|
# Then, find all errors and assign the result to the query object
|
77
79
|
results.each_with_index.map do |data_result, idx|
|
78
80
|
query = queries[idx]
|
79
81
|
finish_query(data_result, query)
|
82
|
+
# Get the Query::Result, not the Hash
|
83
|
+
query.result
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
@@ -88,18 +92,10 @@ module GraphQL
|
|
88
92
|
NO_OPERATION
|
89
93
|
else
|
90
94
|
begin
|
91
|
-
|
92
|
-
root_type = query.root_type_for_operation(op_type)
|
93
|
-
GraphQL::Execution::Execute::ExecutionFunctions.resolve_selection(
|
94
|
-
query.root_value,
|
95
|
-
root_type,
|
96
|
-
query.irep_selection,
|
97
|
-
query.context,
|
98
|
-
mutation: query.mutation?
|
99
|
-
)
|
95
|
+
GraphQL::Execution::Execute::ExecutionFunctions.resolve_root_selection(query)
|
100
96
|
rescue GraphQL::ExecutionError => err
|
101
97
|
query.context.errors << err
|
102
|
-
|
98
|
+
NO_OPERATION
|
103
99
|
end
|
104
100
|
end
|
105
101
|
end
|
@@ -109,17 +105,20 @@ module GraphQL
|
|
109
105
|
# @return [Hash] final result of this query, including all values and errors
|
110
106
|
def finish_query(data_result, query)
|
111
107
|
# Assign the result so that it can be accessed in instrumentation
|
112
|
-
query.
|
108
|
+
query.result_values = if data_result.equal?(NO_OPERATION)
|
113
109
|
if !query.valid?
|
114
110
|
{ "errors" => query.static_errors.map(&:to_h) }
|
115
111
|
else
|
116
|
-
|
112
|
+
data_result
|
117
113
|
end
|
118
114
|
else
|
119
|
-
|
120
|
-
|
115
|
+
# Use `context.value` which was assigned during execution
|
116
|
+
result = {
|
117
|
+
"data" => Execution::Flatten.call(query.context)
|
118
|
+
}
|
121
119
|
|
122
|
-
if
|
120
|
+
if query.context.errors.any?
|
121
|
+
error_result = query.context.errors.map(&:to_h)
|
123
122
|
result["errors"] = error_result
|
124
123
|
end
|
125
124
|
|
@@ -129,7 +128,7 @@ module GraphQL
|
|
129
128
|
|
130
129
|
# use the old `query_execution_strategy` etc to run this query
|
131
130
|
def run_one_legacy(schema, query)
|
132
|
-
query.
|
131
|
+
query.result_values = if !query.valid?
|
133
132
|
all_errors = query.validation_errors + query.analysis_errors + query.context.errors
|
134
133
|
if all_errors.any?
|
135
134
|
{ "errors" => all_errors.map(&:to_h) }
|
@@ -150,10 +149,11 @@ module GraphQL
|
|
150
149
|
# Apply multiplex & query instrumentation to `queries`.
|
151
150
|
#
|
152
151
|
# It yields when the queries should be executed, then runs teardown.
|
153
|
-
def with_instrumentation(
|
152
|
+
def with_instrumentation(multiplex, max_complexity:)
|
153
|
+
schema = multiplex.schema
|
154
|
+
queries = multiplex.queries
|
154
155
|
query_instrumenters = schema.instrumenters[:query]
|
155
156
|
multiplex_instrumenters = schema.instrumenters[:multiplex]
|
156
|
-
multiplex = self.new(schema: schema, queries: queries, context: context)
|
157
157
|
|
158
158
|
# First, run multiplex instrumentation, then query instrumentation for each query
|
159
159
|
multiplex_instrumenters.each { |i| i.before_multiplex(multiplex) }
|