graphql 2.4.2 → 2.5.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/analysis/analyzer.rb +2 -1
- data/lib/graphql/analysis/visitor.rb +38 -41
- data/lib/graphql/analysis.rb +15 -12
- data/lib/graphql/autoload.rb +38 -0
- data/lib/graphql/backtrace/table.rb +118 -55
- data/lib/graphql/backtrace.rb +1 -19
- data/lib/graphql/current.rb +6 -1
- data/lib/graphql/dashboard/detailed_traces.rb +47 -0
- data/lib/graphql/dashboard/installable.rb +22 -0
- data/lib/graphql/dashboard/limiters.rb +93 -0
- data/lib/graphql/dashboard/operation_store.rb +199 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
- data/lib/graphql/dashboard/statics/charts.min.css +1 -0
- data/lib/graphql/dashboard/statics/dashboard.css +30 -0
- data/lib/graphql/dashboard/statics/dashboard.js +143 -0
- data/lib/graphql/dashboard/statics/header-icon.png +0 -0
- data/lib/graphql/dashboard/statics/icon.png +0 -0
- data/lib/graphql/dashboard/subscriptions.rb +96 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/detailed_traces/traces/index.html.erb +45 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/limiters/limiters/show.html.erb +62 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/not_installed.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/_form.html.erb +23 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/edit.html.erb +21 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/index.html.erb +69 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/clients/new.html.erb +7 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/index.html.erb +39 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/index_entries/show.html.erb +32 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/index.html.erb +81 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/operation_store/operations/show.html.erb +71 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/subscriptions/show.html.erb +41 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/index.html.erb +55 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/subscriptions/topics/show.html.erb +40 -0
- data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +108 -0
- data/lib/graphql/dashboard.rb +158 -0
- data/lib/graphql/dataloader/active_record_association_source.rb +64 -0
- data/lib/graphql/dataloader/active_record_source.rb +26 -0
- data/lib/graphql/dataloader/async_dataloader.rb +21 -9
- data/lib/graphql/dataloader/null_dataloader.rb +1 -1
- data/lib/graphql/dataloader/source.rb +3 -3
- data/lib/graphql/dataloader.rb +43 -14
- data/lib/graphql/execution/interpreter/resolve.rb +3 -3
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +11 -4
- data/lib/graphql/execution/interpreter/runtime.rb +78 -41
- data/lib/graphql/execution/interpreter.rb +16 -7
- data/lib/graphql/execution/lookahead.rb +8 -1
- data/lib/graphql/execution/multiplex.rb +1 -5
- data/lib/graphql/introspection/directive_location_enum.rb +1 -1
- data/lib/graphql/invalid_name_error.rb +1 -1
- data/lib/graphql/invalid_null_error.rb +5 -15
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/document_from_schema_definition.rb +8 -7
- data/lib/graphql/language/lexer.rb +11 -4
- data/lib/graphql/language/nodes.rb +3 -0
- data/lib/graphql/language/parser.rb +15 -8
- data/lib/graphql/language/printer.rb +8 -8
- data/lib/graphql/language/static_visitor.rb +37 -33
- data/lib/graphql/language/visitor.rb +59 -55
- data/lib/graphql/pagination/connection.rb +1 -1
- data/lib/graphql/query/context/scoped_context.rb +1 -1
- data/lib/graphql/query/context.rb +6 -5
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query.rb +19 -23
- data/lib/graphql/railtie.rb +7 -0
- data/lib/graphql/schema/addition.rb +1 -1
- data/lib/graphql/schema/argument.rb +7 -8
- data/lib/graphql/schema/build_from_definition.rb +99 -53
- data/lib/graphql/schema/directive/flagged.rb +1 -1
- data/lib/graphql/schema/directive.rb +2 -2
- data/lib/graphql/schema/enum.rb +36 -1
- data/lib/graphql/schema/enum_value.rb +1 -1
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +12 -12
- data/lib/graphql/schema/field_extension.rb +1 -1
- data/lib/graphql/schema/has_single_input_argument.rb +3 -1
- data/lib/graphql/schema/input_object.rb +76 -39
- data/lib/graphql/schema/interface.rb +3 -2
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/member/has_arguments.rb +25 -17
- data/lib/graphql/schema/member/has_dataloader.rb +60 -0
- data/lib/graphql/schema/member/has_directives.rb +4 -4
- data/lib/graphql/schema/member/has_fields.rb +19 -1
- data/lib/graphql/schema/member/has_interfaces.rb +5 -5
- data/lib/graphql/schema/member/has_validators.rb +1 -1
- data/lib/graphql/schema/member/scoped.rb +1 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
- data/lib/graphql/schema/member.rb +1 -0
- data/lib/graphql/schema/object.rb +25 -8
- data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
- data/lib/graphql/schema/resolver.rb +11 -10
- data/lib/graphql/schema/subscription.rb +52 -6
- data/lib/graphql/schema/union.rb +1 -1
- data/lib/graphql/schema/validator/required_validator.rb +23 -6
- data/lib/graphql/schema/validator.rb +1 -1
- data/lib/graphql/schema/visibility/migration.rb +1 -0
- data/lib/graphql/schema/visibility/profile.rb +69 -237
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +184 -28
- data/lib/graphql/schema/warden.rb +18 -5
- data/lib/graphql/schema.rb +94 -45
- data/lib/graphql/static_validation/all_rules.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/not_single_subscription_error.rb +25 -0
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/subscription_root_exists_and_single_subscription_selection.rb +26 -0
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -1
- data/lib/graphql/static_validation/validation_context.rb +1 -0
- data/lib/graphql/static_validation/validator.rb +6 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +1 -1
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +12 -10
- data/lib/graphql/subscriptions/event.rb +12 -1
- data/lib/graphql/subscriptions/serialize.rb +1 -1
- data/lib/graphql/subscriptions.rb +1 -1
- data/lib/graphql/testing/helpers.rb +7 -4
- data/lib/graphql/tracing/active_support_notifications_trace.rb +14 -3
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +1 -1
- data/lib/graphql/tracing/appoptics_trace.rb +9 -1
- data/lib/graphql/tracing/appoptics_tracing.rb +7 -0
- data/lib/graphql/tracing/appsignal_trace.rb +32 -55
- data/lib/graphql/tracing/appsignal_tracing.rb +2 -0
- data/lib/graphql/tracing/call_legacy_tracers.rb +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +46 -158
- data/lib/graphql/tracing/data_dog_tracing.rb +2 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
- data/lib/graphql/tracing/detailed_trace.rb +93 -0
- data/lib/graphql/tracing/legacy_hooks_trace.rb +1 -0
- data/lib/graphql/tracing/legacy_trace.rb +4 -61
- data/lib/graphql/tracing/monitor_trace.rb +285 -0
- data/lib/graphql/tracing/new_relic_trace.rb +47 -54
- data/lib/graphql/tracing/new_relic_tracing.rb +2 -0
- data/lib/graphql/tracing/notifications_trace.rb +182 -34
- data/lib/graphql/tracing/notifications_tracing.rb +2 -0
- data/lib/graphql/tracing/null_trace.rb +9 -0
- data/lib/graphql/tracing/perfetto_trace/trace.proto +141 -0
- data/lib/graphql/tracing/perfetto_trace/trace_pb.rb +33 -0
- data/lib/graphql/tracing/perfetto_trace.rb +734 -0
- data/lib/graphql/tracing/platform_trace.rb +5 -0
- data/lib/graphql/tracing/prometheus_trace/graphql_collector.rb +2 -0
- data/lib/graphql/tracing/prometheus_trace.rb +72 -68
- data/lib/graphql/tracing/prometheus_tracing.rb +2 -0
- data/lib/graphql/tracing/scout_trace.rb +32 -55
- data/lib/graphql/tracing/scout_tracing.rb +2 -0
- data/lib/graphql/tracing/sentry_trace.rb +63 -94
- data/lib/graphql/tracing/statsd_trace.rb +33 -41
- data/lib/graphql/tracing/statsd_tracing.rb +2 -0
- data/lib/graphql/tracing/trace.rb +111 -1
- data/lib/graphql/tracing.rb +31 -30
- data/lib/graphql/types/relay/connection_behaviors.rb +3 -3
- data/lib/graphql/types/relay/edge_behaviors.rb +2 -2
- data/lib/graphql/types.rb +18 -11
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +55 -47
- metadata +146 -11
- data/lib/graphql/backtrace/inspect_result.rb +0 -38
- data/lib/graphql/backtrace/trace.rb +0 -93
- data/lib/graphql/backtrace/tracer.rb +0 -80
- data/lib/graphql/schema/null_mask.rb +0 -11
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +0 -17
data/lib/graphql/dataloader.rb
CHANGED
|
@@ -4,6 +4,8 @@ require "graphql/dataloader/null_dataloader"
|
|
|
4
4
|
require "graphql/dataloader/request"
|
|
5
5
|
require "graphql/dataloader/request_all"
|
|
6
6
|
require "graphql/dataloader/source"
|
|
7
|
+
require "graphql/dataloader/active_record_association_source"
|
|
8
|
+
require "graphql/dataloader/active_record_source"
|
|
7
9
|
|
|
8
10
|
module GraphQL
|
|
9
11
|
# This plugin supports Fiber-based concurrency, along with {GraphQL::Dataloader::Source}.
|
|
@@ -78,10 +80,7 @@ module GraphQL
|
|
|
78
80
|
def get_fiber_variables
|
|
79
81
|
fiber_vars = {}
|
|
80
82
|
Thread.current.keys.each do |fiber_var_key|
|
|
81
|
-
|
|
82
|
-
if fiber_var_key != :__graphql_runtime_info
|
|
83
|
-
fiber_vars[fiber_var_key] = Thread.current[fiber_var_key]
|
|
84
|
-
end
|
|
83
|
+
fiber_vars[fiber_var_key] = Thread.current[fiber_var_key]
|
|
85
84
|
end
|
|
86
85
|
fiber_vars
|
|
87
86
|
end
|
|
@@ -132,8 +131,11 @@ module GraphQL
|
|
|
132
131
|
# Dataloader will resume the fiber after the requested data has been loaded (by another Fiber).
|
|
133
132
|
#
|
|
134
133
|
# @return [void]
|
|
135
|
-
def yield
|
|
134
|
+
def yield(source = Fiber[:__graphql_current_dataloader_source])
|
|
135
|
+
trace = Fiber[:__graphql_current_multiplex]&.current_trace
|
|
136
|
+
trace&.dataloader_fiber_yield(source)
|
|
136
137
|
Fiber.yield
|
|
138
|
+
trace&.dataloader_fiber_resume(source)
|
|
137
139
|
nil
|
|
138
140
|
end
|
|
139
141
|
|
|
@@ -187,6 +189,7 @@ module GraphQL
|
|
|
187
189
|
end
|
|
188
190
|
|
|
189
191
|
def run
|
|
192
|
+
trace = Fiber[:__graphql_current_multiplex]&.current_trace
|
|
190
193
|
jobs_fiber_limit, total_fiber_limit = calculate_fiber_limit
|
|
191
194
|
job_fibers = []
|
|
192
195
|
next_job_fibers = []
|
|
@@ -194,10 +197,11 @@ module GraphQL
|
|
|
194
197
|
next_source_fibers = []
|
|
195
198
|
first_pass = true
|
|
196
199
|
manager = spawn_fiber do
|
|
197
|
-
|
|
200
|
+
trace&.begin_dataloader(self)
|
|
201
|
+
while first_pass || !job_fibers.empty?
|
|
198
202
|
first_pass = false
|
|
199
203
|
|
|
200
|
-
while (f = (job_fibers.shift || (((next_job_fibers.size + job_fibers.size) < jobs_fiber_limit) && spawn_job_fiber)))
|
|
204
|
+
while (f = (job_fibers.shift || (((next_job_fibers.size + job_fibers.size) < jobs_fiber_limit) && spawn_job_fiber(trace))))
|
|
201
205
|
if f.alive?
|
|
202
206
|
finished = run_fiber(f)
|
|
203
207
|
if !finished
|
|
@@ -207,8 +211,8 @@ module GraphQL
|
|
|
207
211
|
end
|
|
208
212
|
join_queues(job_fibers, next_job_fibers)
|
|
209
213
|
|
|
210
|
-
while (source_fibers.
|
|
211
|
-
while (f = source_fibers.shift || (((job_fibers.size + source_fibers.size + next_source_fibers.size + next_job_fibers.size) < total_fiber_limit) && spawn_source_fiber))
|
|
214
|
+
while (!source_fibers.empty? || @source_cache.each_value.any? { |group_sources| group_sources.each_value.any?(&:pending?) })
|
|
215
|
+
while (f = source_fibers.shift || (((job_fibers.size + source_fibers.size + next_source_fibers.size + next_job_fibers.size) < total_fiber_limit) && spawn_source_fiber(trace)))
|
|
212
216
|
if f.alive?
|
|
213
217
|
finished = run_fiber(f)
|
|
214
218
|
if !finished
|
|
@@ -219,6 +223,8 @@ module GraphQL
|
|
|
219
223
|
join_queues(source_fibers, next_source_fibers)
|
|
220
224
|
end
|
|
221
225
|
end
|
|
226
|
+
|
|
227
|
+
trace&.end_dataloader(self)
|
|
222
228
|
end
|
|
223
229
|
|
|
224
230
|
run_fiber(manager)
|
|
@@ -227,12 +233,13 @@ module GraphQL
|
|
|
227
233
|
raise "Invariant: Manager fiber didn't terminate properly."
|
|
228
234
|
end
|
|
229
235
|
|
|
230
|
-
if job_fibers.
|
|
236
|
+
if !job_fibers.empty?
|
|
231
237
|
raise "Invariant: job fibers should have exited but #{job_fibers.size} remained"
|
|
232
238
|
end
|
|
233
|
-
if source_fibers.
|
|
239
|
+
if !source_fibers.empty?
|
|
234
240
|
raise "Invariant: source fibers should have exited but #{source_fibers.size} remained"
|
|
235
241
|
end
|
|
242
|
+
|
|
236
243
|
rescue UncaughtThrowError => e
|
|
237
244
|
throw e.tag, e.value
|
|
238
245
|
end
|
|
@@ -250,6 +257,22 @@ module GraphQL
|
|
|
250
257
|
}
|
|
251
258
|
end
|
|
252
259
|
|
|
260
|
+
# Pre-warm the Dataloader cache with ActiveRecord objects which were loaded elsewhere.
|
|
261
|
+
# These will be used by {Dataloader::ActiveRecordSource}, {Dataloader::ActiveRecordAssociationSource} and their helper
|
|
262
|
+
# methods, `dataload_record` and `dataload_association`.
|
|
263
|
+
# @param records [Array<ActiveRecord::Base>] Already-loaded records to warm the cache with
|
|
264
|
+
# @param index_by [Symbol] The attribute to use as the cache key. (Should match `find_by:` when using {ActiveRecordSource})
|
|
265
|
+
# @return [void]
|
|
266
|
+
def merge_records(records, index_by: :id)
|
|
267
|
+
records_by_class = Hash.new { |h, k| h[k] = {} }
|
|
268
|
+
records.each do |r|
|
|
269
|
+
records_by_class[r.class][r.public_send(index_by)] = r
|
|
270
|
+
end
|
|
271
|
+
records_by_class.each do |r_class, records|
|
|
272
|
+
with(ActiveRecordSource, r_class).merge(records)
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
253
276
|
private
|
|
254
277
|
|
|
255
278
|
def calculate_fiber_limit
|
|
@@ -269,17 +292,19 @@ module GraphQL
|
|
|
269
292
|
new_queue.clear
|
|
270
293
|
end
|
|
271
294
|
|
|
272
|
-
def spawn_job_fiber
|
|
273
|
-
if
|
|
295
|
+
def spawn_job_fiber(trace)
|
|
296
|
+
if !@pending_jobs.empty?
|
|
274
297
|
spawn_fiber do
|
|
298
|
+
trace&.dataloader_spawn_execution_fiber(@pending_jobs)
|
|
275
299
|
while job = @pending_jobs.shift
|
|
276
300
|
job.call
|
|
277
301
|
end
|
|
302
|
+
trace&.dataloader_fiber_exit
|
|
278
303
|
end
|
|
279
304
|
end
|
|
280
305
|
end
|
|
281
306
|
|
|
282
|
-
def spawn_source_fiber
|
|
307
|
+
def spawn_source_fiber(trace)
|
|
283
308
|
pending_sources = nil
|
|
284
309
|
@source_cache.each_value do |source_by_batch_params|
|
|
285
310
|
source_by_batch_params.each_value do |source|
|
|
@@ -292,10 +317,14 @@ module GraphQL
|
|
|
292
317
|
|
|
293
318
|
if pending_sources
|
|
294
319
|
spawn_fiber do
|
|
320
|
+
trace&.dataloader_spawn_source_fiber(pending_sources)
|
|
295
321
|
pending_sources.each do |source|
|
|
296
322
|
Fiber[:__graphql_current_dataloader_source] = source
|
|
323
|
+
trace&.begin_dataloader_source(source)
|
|
297
324
|
source.run_pending_keys
|
|
325
|
+
trace&.end_dataloader_source(source)
|
|
298
326
|
end
|
|
327
|
+
trace&.dataloader_fiber_exit
|
|
299
328
|
end
|
|
300
329
|
end
|
|
301
330
|
end
|
|
@@ -22,7 +22,7 @@ module GraphQL
|
|
|
22
22
|
|
|
23
23
|
if smallest_depth
|
|
24
24
|
lazies = lazies_at_depth.delete(smallest_depth)
|
|
25
|
-
if lazies.
|
|
25
|
+
if !lazies.empty?
|
|
26
26
|
dataloader.append_job {
|
|
27
27
|
lazies.each(&:value) # resolve these Lazy instances
|
|
28
28
|
}
|
|
@@ -55,7 +55,7 @@ module GraphQL
|
|
|
55
55
|
# these approaches.
|
|
56
56
|
dataloader.run
|
|
57
57
|
next_results = []
|
|
58
|
-
while results.
|
|
58
|
+
while !results.empty?
|
|
59
59
|
result_value = results.shift
|
|
60
60
|
if result_value.is_a?(Runtime::GraphQLResultHash) || result_value.is_a?(Hash)
|
|
61
61
|
results.concat(result_value.values)
|
|
@@ -81,7 +81,7 @@ module GraphQL
|
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
if next_results.
|
|
84
|
+
if !next_results.empty?
|
|
85
85
|
# Any pending data loader jobs may populate the
|
|
86
86
|
# resutl arrays or result hashes accumulated in
|
|
87
87
|
# `next_results``. Run those **to completion**
|
|
@@ -5,7 +5,10 @@ module GraphQL
|
|
|
5
5
|
class Interpreter
|
|
6
6
|
class Runtime
|
|
7
7
|
module GraphQLResult
|
|
8
|
-
def initialize(result_name, result_type, application_value, parent_result, is_non_null_in_parent, selections, is_eager)
|
|
8
|
+
def initialize(result_name, result_type, application_value, parent_result, is_non_null_in_parent, selections, is_eager, ast_node, graphql_arguments, graphql_field) # rubocop:disable Metrics/ParameterLists
|
|
9
|
+
@ast_node = ast_node
|
|
10
|
+
@graphql_arguments = graphql_arguments
|
|
11
|
+
@graphql_field = graphql_field
|
|
9
12
|
@graphql_parent = parent_result
|
|
10
13
|
@graphql_application_value = application_value
|
|
11
14
|
@graphql_result_type = result_type
|
|
@@ -31,14 +34,14 @@ module GraphQL
|
|
|
31
34
|
|
|
32
35
|
attr_accessor :graphql_dead
|
|
33
36
|
attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent,
|
|
34
|
-
:graphql_application_value, :graphql_result_type, :graphql_selections, :graphql_is_eager
|
|
37
|
+
:graphql_application_value, :graphql_result_type, :graphql_selections, :graphql_is_eager, :ast_node, :graphql_arguments, :graphql_field
|
|
35
38
|
|
|
36
39
|
# @return [Hash] Plain-Ruby result data (`@graphql_metadata` contains Result wrapper objects)
|
|
37
40
|
attr_accessor :graphql_result_data
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
class GraphQLResultHash
|
|
41
|
-
def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager)
|
|
44
|
+
def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager, _ast_node, _graphql_arguments, graphql_field) # rubocop:disable Metrics/ParameterLists
|
|
42
45
|
super
|
|
43
46
|
@graphql_result_data = {}
|
|
44
47
|
end
|
|
@@ -126,7 +129,7 @@ module GraphQL
|
|
|
126
129
|
class GraphQLResultArray
|
|
127
130
|
include GraphQLResult
|
|
128
131
|
|
|
129
|
-
def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager)
|
|
132
|
+
def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager, _ast_node, _graphql_arguments, graphql_field) # rubocop:disable Metrics/ParameterLists
|
|
130
133
|
super
|
|
131
134
|
@graphql_result_data = []
|
|
132
135
|
end
|
|
@@ -168,6 +171,10 @@ module GraphQL
|
|
|
168
171
|
def values
|
|
169
172
|
(@graphql_metadata || @graphql_result_data)
|
|
170
173
|
end
|
|
174
|
+
|
|
175
|
+
def [](idx)
|
|
176
|
+
(@graphql_metadata || @graphql_result_data)[idx]
|
|
177
|
+
end
|
|
171
178
|
end
|
|
172
179
|
end
|
|
173
180
|
end
|
|
@@ -74,7 +74,7 @@ module GraphQL
|
|
|
74
74
|
runtime_object = root_type.wrap(query.root_value, context)
|
|
75
75
|
runtime_object = schema.sync_lazy(runtime_object)
|
|
76
76
|
is_eager = root_op_type == "mutation"
|
|
77
|
-
@response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false, root_operation.selections, is_eager)
|
|
77
|
+
@response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false, root_operation.selections, is_eager, root_operation, nil, nil)
|
|
78
78
|
st = get_current_runtime_state
|
|
79
79
|
st.current_result = @response
|
|
80
80
|
|
|
@@ -85,7 +85,7 @@ module GraphQL
|
|
|
85
85
|
call_method_on_directives(:resolve, runtime_object, root_operation.directives) do # execute query level directives
|
|
86
86
|
each_gathered_selections(@response) do |selections, is_selection_array|
|
|
87
87
|
if is_selection_array
|
|
88
|
-
selection_response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false, selections, is_eager)
|
|
88
|
+
selection_response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false, selections, is_eager, root_operation, nil, nil)
|
|
89
89
|
final_response = @response
|
|
90
90
|
else
|
|
91
91
|
selection_response = @response
|
|
@@ -142,7 +142,7 @@ module GraphQL
|
|
|
142
142
|
end
|
|
143
143
|
else
|
|
144
144
|
# This is an InlineFragment or a FragmentSpread
|
|
145
|
-
if
|
|
145
|
+
if !@runtime_directive_names.empty? && node.directives.any? { |d| @runtime_directive_names.include?(d.name) }
|
|
146
146
|
next_selections = {}
|
|
147
147
|
next_selections[:graphql_directives] = node.directives
|
|
148
148
|
if selections_to_run
|
|
@@ -218,8 +218,10 @@ module GraphQL
|
|
|
218
218
|
result_name, field_ast_nodes_or_ast_node, selections_result
|
|
219
219
|
)
|
|
220
220
|
finished_jobs += 1
|
|
221
|
-
if
|
|
222
|
-
|
|
221
|
+
if finished_jobs == enqueued_jobs
|
|
222
|
+
if target_result
|
|
223
|
+
selections_result.merge_into(target_result)
|
|
224
|
+
end
|
|
223
225
|
end
|
|
224
226
|
@dataloader.clear_cache
|
|
225
227
|
}
|
|
@@ -229,8 +231,10 @@ module GraphQL
|
|
|
229
231
|
result_name, field_ast_nodes_or_ast_node, selections_result
|
|
230
232
|
)
|
|
231
233
|
finished_jobs += 1
|
|
232
|
-
if
|
|
233
|
-
|
|
234
|
+
if finished_jobs == enqueued_jobs
|
|
235
|
+
if target_result
|
|
236
|
+
selections_result.merge_into(target_result)
|
|
237
|
+
end
|
|
234
238
|
end
|
|
235
239
|
}
|
|
236
240
|
end
|
|
@@ -332,7 +336,7 @@ module GraphQL
|
|
|
332
336
|
extra_args[extra] = field_defn.fetch_extra(extra, context)
|
|
333
337
|
end
|
|
334
338
|
end
|
|
335
|
-
if extra_args.
|
|
339
|
+
if !extra_args.empty?
|
|
336
340
|
resolved_arguments = resolved_arguments.merge_extras(extra_args)
|
|
337
341
|
end
|
|
338
342
|
resolved_arguments.keyword_arguments
|
|
@@ -361,7 +365,7 @@ module GraphQL
|
|
|
361
365
|
end
|
|
362
366
|
|
|
363
367
|
field_result = call_method_on_directives(:resolve, object, directives) do
|
|
364
|
-
if directives.
|
|
368
|
+
if !directives.empty?
|
|
365
369
|
# This might be executed in a different context; reset this info
|
|
366
370
|
runtime_state = get_current_runtime_state
|
|
367
371
|
runtime_state.current_field = field_defn
|
|
@@ -371,6 +375,7 @@ module GraphQL
|
|
|
371
375
|
end
|
|
372
376
|
# Actually call the field resolver and capture the result
|
|
373
377
|
app_result = begin
|
|
378
|
+
@current_trace.begin_execute_field(field_defn, object, kwarg_arguments, query)
|
|
374
379
|
@current_trace.execute_field(field: field_defn, ast_node: ast_node, query: query, object: object, arguments: kwarg_arguments) do
|
|
375
380
|
field_defn.resolve(object, kwarg_arguments, context)
|
|
376
381
|
end
|
|
@@ -383,6 +388,7 @@ module GraphQL
|
|
|
383
388
|
ex_err
|
|
384
389
|
end
|
|
385
390
|
end
|
|
391
|
+
@current_trace.end_execute_field(field_defn, object, kwarg_arguments, query, app_result)
|
|
386
392
|
after_lazy(app_result, field: field_defn, ast_node: ast_node, owner_object: object, arguments: resolved_arguments, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |inner_result, runtime_state|
|
|
387
393
|
owner_type = selection_result.graphql_result_type
|
|
388
394
|
return_type = field_defn.type
|
|
@@ -391,6 +397,8 @@ module GraphQL
|
|
|
391
397
|
was_scoped = runtime_state.was_authorized_by_scope_items
|
|
392
398
|
runtime_state.was_authorized_by_scope_items = nil
|
|
393
399
|
continue_field(continue_value, owner_type, field_defn, return_type, ast_node, next_selections, false, object, resolved_arguments, result_name, selection_result, was_scoped, runtime_state)
|
|
400
|
+
else
|
|
401
|
+
nil
|
|
394
402
|
end
|
|
395
403
|
end
|
|
396
404
|
end
|
|
@@ -465,7 +473,7 @@ module GraphQL
|
|
|
465
473
|
# When this comes from a list item, use the parent object:
|
|
466
474
|
parent_type = selection_result.is_a?(GraphQLResultArray) ? selection_result.graphql_parent.graphql_result_type : selection_result.graphql_result_type
|
|
467
475
|
# This block is called if `result_name` is not dead. (Maybe a previous invalid nil caused it be marked dead.)
|
|
468
|
-
err = parent_type::InvalidNullError.new(parent_type, field,
|
|
476
|
+
err = parent_type::InvalidNullError.new(parent_type, field, ast_node)
|
|
469
477
|
schema.type_error(err, context)
|
|
470
478
|
end
|
|
471
479
|
else
|
|
@@ -525,7 +533,7 @@ module GraphQL
|
|
|
525
533
|
end
|
|
526
534
|
when Array
|
|
527
535
|
# It's an array full of execution errors; add them all.
|
|
528
|
-
if value.
|
|
536
|
+
if !value.empty? && value.all?(GraphQL::ExecutionError)
|
|
529
537
|
list_type_at_all = (field && (field.type.list?))
|
|
530
538
|
if selection_result.nil? || !selection_result.graphql_dead
|
|
531
539
|
value.each_with_index do |error, index|
|
|
@@ -574,12 +582,22 @@ module GraphQL
|
|
|
574
582
|
r = begin
|
|
575
583
|
current_type.coerce_result(value, context)
|
|
576
584
|
rescue StandardError => err
|
|
577
|
-
|
|
585
|
+
query.handle_or_reraise(err)
|
|
578
586
|
end
|
|
579
587
|
set_result(selection_result, result_name, r, false, is_non_null)
|
|
580
588
|
r
|
|
581
589
|
when "UNION", "INTERFACE"
|
|
582
|
-
resolved_type_or_lazy =
|
|
590
|
+
resolved_type_or_lazy = begin
|
|
591
|
+
resolve_type(current_type, value)
|
|
592
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
|
593
|
+
return continue_value(ex_err, field, is_non_null, ast_node, result_name, selection_result)
|
|
594
|
+
rescue StandardError => err
|
|
595
|
+
begin
|
|
596
|
+
query.handle_or_reraise(err)
|
|
597
|
+
rescue GraphQL::ExecutionError => ex_err
|
|
598
|
+
return continue_value(ex_err, field, is_non_null, ast_node, result_name, selection_result)
|
|
599
|
+
end
|
|
600
|
+
end
|
|
583
601
|
after_lazy(resolved_type_or_lazy, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |resolved_type_result, runtime_state|
|
|
584
602
|
if resolved_type_result.is_a?(Array) && resolved_type_result.length == 2
|
|
585
603
|
resolved_type, resolved_value = resolved_type_result
|
|
@@ -609,11 +627,11 @@ module GraphQL
|
|
|
609
627
|
after_lazy(object_proxy, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |inner_object, runtime_state|
|
|
610
628
|
continue_value = continue_value(inner_object, field, is_non_null, ast_node, result_name, selection_result)
|
|
611
629
|
if HALT != continue_value
|
|
612
|
-
response_hash = GraphQLResultHash.new(result_name, current_type, continue_value, selection_result, is_non_null, next_selections, false)
|
|
630
|
+
response_hash = GraphQLResultHash.new(result_name, current_type, continue_value, selection_result, is_non_null, next_selections, false, ast_node, arguments, field)
|
|
613
631
|
set_result(selection_result, result_name, response_hash, true, is_non_null)
|
|
614
632
|
each_gathered_selections(response_hash) do |selections, is_selection_array|
|
|
615
633
|
if is_selection_array
|
|
616
|
-
this_result = GraphQLResultHash.new(result_name, current_type, continue_value, selection_result, is_non_null, selections, false)
|
|
634
|
+
this_result = GraphQLResultHash.new(result_name, current_type, continue_value, selection_result, is_non_null, selections, false, ast_node, arguments, field)
|
|
617
635
|
final_result = response_hash
|
|
618
636
|
else
|
|
619
637
|
this_result = response_hash
|
|
@@ -634,35 +652,43 @@ module GraphQL
|
|
|
634
652
|
# This is true for objects, unions, and interfaces
|
|
635
653
|
use_dataloader_job = !inner_type.unwrap.kind.input?
|
|
636
654
|
inner_type_non_null = inner_type.non_null?
|
|
637
|
-
response_list = GraphQLResultArray.new(result_name, current_type, owner_object, selection_result, is_non_null, next_selections, false)
|
|
655
|
+
response_list = GraphQLResultArray.new(result_name, current_type, owner_object, selection_result, is_non_null, next_selections, false, ast_node, arguments, field)
|
|
638
656
|
set_result(selection_result, result_name, response_list, true, is_non_null)
|
|
639
657
|
idx = nil
|
|
640
658
|
list_value = begin
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
659
|
+
begin
|
|
660
|
+
value.each do |inner_value|
|
|
661
|
+
idx ||= 0
|
|
662
|
+
this_idx = idx
|
|
663
|
+
idx += 1
|
|
664
|
+
if use_dataloader_job
|
|
665
|
+
@dataloader.append_job do
|
|
666
|
+
resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, owner_type, was_scoped, runtime_state)
|
|
667
|
+
end
|
|
668
|
+
else
|
|
647
669
|
resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, owner_type, was_scoped, runtime_state)
|
|
648
670
|
end
|
|
649
|
-
else
|
|
650
|
-
resolve_list_item(inner_value, inner_type, inner_type_non_null, ast_node, field, owner_object, arguments, this_idx, response_list, owner_type, was_scoped, runtime_state)
|
|
651
671
|
end
|
|
652
|
-
end
|
|
653
672
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
673
|
+
response_list
|
|
674
|
+
rescue NoMethodError => err
|
|
675
|
+
# Ruby 2.2 doesn't have NoMethodError#receiver, can't check that one in this case. (It's been EOL since 2017.)
|
|
676
|
+
if err.name == :each && (err.respond_to?(:receiver) ? err.receiver == value : true)
|
|
677
|
+
# This happens when the GraphQL schema doesn't match the implementation. Help the dev debug.
|
|
678
|
+
raise ListResultFailedError.new(value: value, field: field, path: current_path)
|
|
679
|
+
else
|
|
680
|
+
# This was some other NoMethodError -- let it bubble to reveal the real error.
|
|
681
|
+
raise
|
|
682
|
+
end
|
|
683
|
+
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
|
684
|
+
ex_err
|
|
685
|
+
rescue StandardError => err
|
|
686
|
+
begin
|
|
687
|
+
query.handle_or_reraise(err)
|
|
688
|
+
rescue GraphQL::ExecutionError => ex_err
|
|
689
|
+
ex_err
|
|
690
|
+
end
|
|
663
691
|
end
|
|
664
|
-
rescue GraphQL::ExecutionError, GraphQL::UnauthorizedError => ex_err
|
|
665
|
-
ex_err
|
|
666
692
|
rescue StandardError => err
|
|
667
693
|
begin
|
|
668
694
|
query.handle_or_reraise(err)
|
|
@@ -736,7 +762,7 @@ module GraphQL
|
|
|
736
762
|
end
|
|
737
763
|
|
|
738
764
|
def get_current_runtime_state
|
|
739
|
-
current_state =
|
|
765
|
+
current_state = Fiber[:__graphql_runtime_info] ||= {}.compare_by_identity
|
|
740
766
|
current_state[@query] ||= CurrentState.new
|
|
741
767
|
end
|
|
742
768
|
|
|
@@ -773,8 +799,10 @@ module GraphQL
|
|
|
773
799
|
runtime_state.was_authorized_by_scope_items = was_authorized_by_scope_items
|
|
774
800
|
# Wrap the execution of _this_ method with tracing,
|
|
775
801
|
# but don't wrap the continuation below
|
|
802
|
+
result = nil
|
|
776
803
|
inner_obj = begin
|
|
777
|
-
if trace
|
|
804
|
+
result = if trace
|
|
805
|
+
@current_trace.begin_execute_field(field, owner_object, arguments, query)
|
|
778
806
|
@current_trace.execute_field_lazy(field: field, query: query, object: owner_object, arguments: arguments, ast_node: ast_node) do
|
|
779
807
|
schema.sync_lazy(lazy_obj)
|
|
780
808
|
end
|
|
@@ -789,6 +817,10 @@ module GraphQL
|
|
|
789
817
|
rescue GraphQL::ExecutionError => ex_err
|
|
790
818
|
ex_err
|
|
791
819
|
end
|
|
820
|
+
ensure
|
|
821
|
+
if trace
|
|
822
|
+
@current_trace.end_execute_field(field, owner_object, arguments, query, result)
|
|
823
|
+
end
|
|
792
824
|
end
|
|
793
825
|
yield(inner_obj, runtime_state)
|
|
794
826
|
end
|
|
@@ -821,25 +853,30 @@ module GraphQL
|
|
|
821
853
|
end
|
|
822
854
|
|
|
823
855
|
def delete_all_interpreter_context
|
|
824
|
-
per_query_state =
|
|
856
|
+
per_query_state = Fiber[:__graphql_runtime_info]
|
|
825
857
|
if per_query_state
|
|
826
858
|
per_query_state.delete(@query)
|
|
827
859
|
if per_query_state.size == 0
|
|
828
|
-
|
|
860
|
+
Fiber[:__graphql_runtime_info] = nil
|
|
829
861
|
end
|
|
830
862
|
end
|
|
831
863
|
nil
|
|
832
864
|
end
|
|
833
865
|
|
|
834
866
|
def resolve_type(type, value)
|
|
867
|
+
@current_trace.begin_resolve_type(type, value, context)
|
|
835
868
|
resolved_type, resolved_value = @current_trace.resolve_type(query: query, type: type, object: value) do
|
|
836
869
|
query.resolve_type(type, value)
|
|
837
870
|
end
|
|
871
|
+
@current_trace.end_resolve_type(type, value, context, resolved_type)
|
|
838
872
|
|
|
839
873
|
if lazy?(resolved_type)
|
|
840
874
|
GraphQL::Execution::Lazy.new do
|
|
875
|
+
@current_trace.begin_resolve_type(type, value, context)
|
|
841
876
|
@current_trace.resolve_type_lazy(query: query, type: type, object: value) do
|
|
842
|
-
schema.sync_lazy(resolved_type)
|
|
877
|
+
rt = schema.sync_lazy(resolved_type)
|
|
878
|
+
@current_trace.end_resolve_type(type, value, context, rt)
|
|
879
|
+
rt
|
|
843
880
|
end
|
|
844
881
|
end
|
|
845
882
|
else
|
|
@@ -23,7 +23,7 @@ module GraphQL
|
|
|
23
23
|
# @return [Array<GraphQL::Query::Result>] One result per query
|
|
24
24
|
def run_all(schema, query_options, context: {}, max_complexity: schema.max_complexity)
|
|
25
25
|
queries = query_options.map do |opts|
|
|
26
|
-
case opts
|
|
26
|
+
query = case opts
|
|
27
27
|
when Hash
|
|
28
28
|
schema.query_class.new(schema, nil, **opts)
|
|
29
29
|
when GraphQL::Query
|
|
@@ -31,11 +31,15 @@ module GraphQL
|
|
|
31
31
|
else
|
|
32
32
|
raise "Expected Hash or GraphQL::Query, not #{opts.class} (#{opts.inspect})"
|
|
33
33
|
end
|
|
34
|
+
query
|
|
34
35
|
end
|
|
35
36
|
|
|
37
|
+
return GraphQL::EmptyObjects::EMPTY_ARRAY if queries.empty?
|
|
38
|
+
|
|
36
39
|
multiplex = Execution::Multiplex.new(schema: schema, queries: queries, context: context, max_complexity: max_complexity)
|
|
40
|
+
trace = multiplex.current_trace
|
|
37
41
|
Fiber[:__graphql_current_multiplex] = multiplex
|
|
38
|
-
|
|
42
|
+
trace.execute_multiplex(multiplex: multiplex) do
|
|
39
43
|
schema = multiplex.schema
|
|
40
44
|
queries = multiplex.queries
|
|
41
45
|
lazies_at_depth = Hash.new { |h, k| h[k] = [] }
|
|
@@ -44,7 +48,10 @@ module GraphQL
|
|
|
44
48
|
multiplex_analyzers += [GraphQL::Analysis::MaxQueryComplexity]
|
|
45
49
|
end
|
|
46
50
|
|
|
51
|
+
trace.begin_analyze_multiplex(multiplex, multiplex_analyzers)
|
|
47
52
|
schema.analysis_engine.analyze_multiplex(multiplex, multiplex_analyzers)
|
|
53
|
+
trace.end_analyze_multiplex(multiplex, multiplex_analyzers)
|
|
54
|
+
|
|
48
55
|
begin
|
|
49
56
|
# Since this is basically the batching context,
|
|
50
57
|
# share it for a whole multiplex
|
|
@@ -53,11 +60,13 @@ module GraphQL
|
|
|
53
60
|
results = []
|
|
54
61
|
queries.each_with_index do |query, idx|
|
|
55
62
|
if query.subscription? && !query.subscription_update?
|
|
56
|
-
query.context.namespace(:subscriptions)
|
|
63
|
+
subs_namespace = query.context.namespace(:subscriptions)
|
|
64
|
+
subs_namespace[:events] = []
|
|
65
|
+
subs_namespace[:subscriptions] = {}
|
|
57
66
|
end
|
|
58
67
|
multiplex.dataloader.append_job {
|
|
59
68
|
operation = query.selected_operation
|
|
60
|
-
result = if operation.nil? || !query.valid? || query.context.errors.
|
|
69
|
+
result = if operation.nil? || !query.valid? || !query.context.errors.empty?
|
|
61
70
|
NO_OPERATION
|
|
62
71
|
else
|
|
63
72
|
begin
|
|
@@ -100,12 +109,12 @@ module GraphQL
|
|
|
100
109
|
# Then, find all errors and assign the result to the query object
|
|
101
110
|
results.each_with_index do |data_result, idx|
|
|
102
111
|
query = queries[idx]
|
|
103
|
-
if (events = query.context.namespace(:subscriptions)[:events]) && events.
|
|
112
|
+
if (events = query.context.namespace(:subscriptions)[:events]) && !events.empty?
|
|
104
113
|
schema.subscriptions.write_subscription(query, events)
|
|
105
114
|
end
|
|
106
115
|
# Assign the result so that it can be accessed in instrumentation
|
|
107
116
|
query.result_values = if data_result.equal?(NO_OPERATION)
|
|
108
|
-
if !query.valid? || query.context.errors.
|
|
117
|
+
if !query.valid? || !query.context.errors.empty?
|
|
109
118
|
# A bit weird, but `Query#static_errors` _includes_ `query.context.errors`
|
|
110
119
|
{ "errors" => query.static_errors.map(&:to_h) }
|
|
111
120
|
else
|
|
@@ -114,7 +123,7 @@ module GraphQL
|
|
|
114
123
|
else
|
|
115
124
|
result = {}
|
|
116
125
|
|
|
117
|
-
if query.context.errors.
|
|
126
|
+
if !query.context.errors.empty?
|
|
118
127
|
error_result = query.context.errors.map(&:to_h)
|
|
119
128
|
result["errors"] = error_result
|
|
120
129
|
end
|
|
@@ -56,7 +56,14 @@ module GraphQL
|
|
|
56
56
|
else
|
|
57
57
|
@arguments = if @field
|
|
58
58
|
@query.after_lazy(@query.arguments_for(@ast_nodes.first, @field)) do |args|
|
|
59
|
-
|
|
59
|
+
case args
|
|
60
|
+
when Execution::Interpreter::Arguments
|
|
61
|
+
args.keyword_arguments
|
|
62
|
+
when GraphQL::ExecutionError
|
|
63
|
+
EmptyObjects::EMPTY_HASH
|
|
64
|
+
else
|
|
65
|
+
args
|
|
66
|
+
end
|
|
60
67
|
end
|
|
61
68
|
else
|
|
62
69
|
nil
|
|
@@ -32,14 +32,10 @@ module GraphQL
|
|
|
32
32
|
@queries = queries
|
|
33
33
|
@queries.each { |q| q.multiplex = self }
|
|
34
34
|
@context = context
|
|
35
|
-
@current_trace = @context[:trace] || schema.new_trace(multiplex: self)
|
|
36
35
|
@dataloader = @context[:dataloader] ||= @schema.dataloader_class.new
|
|
37
36
|
@tracers = schema.tracers + (context[:tracers] || [])
|
|
38
|
-
# Support `context: {backtrace: true}`
|
|
39
|
-
if context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
|
|
40
|
-
@tracers << GraphQL::Backtrace::Tracer
|
|
41
|
-
end
|
|
42
37
|
@max_complexity = max_complexity
|
|
38
|
+
@current_trace = context[:trace] ||= schema.new_trace(multiplex: self)
|
|
43
39
|
end
|
|
44
40
|
end
|
|
45
41
|
end
|
|
@@ -7,7 +7,7 @@ module GraphQL
|
|
|
7
7
|
"a __DirectiveLocation describes one such possible adjacencies."
|
|
8
8
|
|
|
9
9
|
GraphQL::Schema::Directive::LOCATIONS.each do |location|
|
|
10
|
-
value(location.to_s, GraphQL::Schema::Directive::LOCATION_DESCRIPTIONS[location], value: location)
|
|
10
|
+
value(location.to_s, GraphQL::Schema::Directive::LOCATION_DESCRIPTIONS[location], value: location, value_method: false)
|
|
11
11
|
end
|
|
12
12
|
introspection true
|
|
13
13
|
end
|