graphql 2.3.7 → 2.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install_generator.rb +46 -0
- data/lib/generators/graphql/orm_mutations_base.rb +1 -1
- data/lib/generators/graphql/templates/base_resolver.erb +2 -0
- data/lib/generators/graphql/type_generator.rb +1 -1
- data/lib/graphql/analysis/field_usage.rb +1 -1
- data/lib/graphql/analysis/query_complexity.rb +3 -3
- data/lib/graphql/analysis/visitor.rb +8 -7
- data/lib/graphql/analysis.rb +4 -4
- data/lib/graphql/autoload.rb +37 -0
- data/lib/graphql/current.rb +52 -0
- data/lib/graphql/dataloader/async_dataloader.rb +7 -6
- data/lib/graphql/dataloader/source.rb +7 -4
- data/lib/graphql/dataloader.rb +40 -19
- data/lib/graphql/execution/interpreter/arguments_cache.rb +5 -10
- data/lib/graphql/execution/interpreter/resolve.rb +13 -9
- data/lib/graphql/execution/interpreter/runtime.rb +35 -31
- data/lib/graphql/execution/interpreter.rb +6 -4
- data/lib/graphql/execution/lookahead.rb +18 -11
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +6 -11
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/cache.rb +13 -0
- data/lib/graphql/language/comment.rb +18 -0
- data/lib/graphql/language/document_from_schema_definition.rb +62 -34
- data/lib/graphql/language/lexer.rb +18 -15
- data/lib/graphql/language/nodes.rb +24 -16
- data/lib/graphql/language/parser.rb +14 -1
- data/lib/graphql/language/printer.rb +31 -15
- data/lib/graphql/language/sanitized_printer.rb +1 -1
- data/lib/graphql/language.rb +6 -6
- data/lib/graphql/pagination/connection.rb +1 -1
- data/lib/graphql/query/context/scoped_context.rb +1 -1
- data/lib/graphql/query/context.rb +13 -6
- data/lib/graphql/query/null_context.rb +3 -5
- data/lib/graphql/query/variable_validation_error.rb +1 -1
- data/lib/graphql/query.rb +72 -18
- data/lib/graphql/railtie.rb +7 -0
- data/lib/graphql/rubocop/graphql/field_type_in_block.rb +144 -0
- data/lib/graphql/rubocop/graphql/root_types_in_block.rb +38 -0
- data/lib/graphql/rubocop.rb +2 -0
- data/lib/graphql/schema/addition.rb +2 -1
- data/lib/graphql/schema/always_visible.rb +6 -2
- data/lib/graphql/schema/argument.rb +14 -1
- data/lib/graphql/schema/build_from_definition.rb +9 -1
- data/lib/graphql/schema/directive/flagged.rb +2 -2
- data/lib/graphql/schema/directive.rb +1 -1
- data/lib/graphql/schema/enum.rb +71 -23
- data/lib/graphql/schema/enum_value.rb +10 -2
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +102 -47
- data/lib/graphql/schema/field_extension.rb +1 -1
- data/lib/graphql/schema/has_single_input_argument.rb +5 -2
- data/lib/graphql/schema/input_object.rb +90 -39
- data/lib/graphql/schema/interface.rb +22 -5
- data/lib/graphql/schema/introspection_system.rb +5 -16
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -0
- data/lib/graphql/schema/member/has_arguments.rb +25 -20
- data/lib/graphql/schema/member/has_directives.rb +3 -3
- data/lib/graphql/schema/member/has_fields.rb +26 -6
- data/lib/graphql/schema/member/has_interfaces.rb +4 -4
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +5 -1
- data/lib/graphql/schema/member/has_validators.rb +1 -1
- data/lib/graphql/schema/object.rb +8 -0
- data/lib/graphql/schema/printer.rb +1 -0
- data/lib/graphql/schema/relay_classic_mutation.rb +0 -1
- data/lib/graphql/schema/resolver.rb +12 -14
- data/lib/graphql/schema/subscription.rb +2 -2
- data/lib/graphql/schema/type_expression.rb +2 -2
- data/lib/graphql/schema/union.rb +1 -1
- data/lib/graphql/schema/validator/all_validator.rb +62 -0
- data/lib/graphql/schema/validator/required_validator.rb +28 -4
- data/lib/graphql/schema/validator.rb +3 -1
- data/lib/graphql/schema/visibility/migration.rb +187 -0
- data/lib/graphql/schema/visibility/profile.rb +353 -0
- data/lib/graphql/schema/visibility/visit.rb +190 -0
- data/lib/graphql/schema/visibility.rb +294 -0
- data/lib/graphql/schema/warden.rb +166 -16
- data/lib/graphql/schema.rb +348 -94
- data/lib/graphql/static_validation/base_visitor.rb +6 -5
- data/lib/graphql/static_validation/literal_validator.rb +4 -4
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +3 -2
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +3 -3
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +2 -0
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +12 -2
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +2 -2
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +8 -7
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +12 -2
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +1 -1
- data/lib/graphql/static_validation/rules/query_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +4 -4
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +3 -3
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +18 -27
- data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +11 -2
- data/lib/graphql/static_validation/validation_context.rb +18 -2
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +3 -2
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +10 -4
- data/lib/graphql/subscriptions/event.rb +1 -1
- data/lib/graphql/subscriptions.rb +6 -4
- data/lib/graphql/testing/helpers.rb +10 -6
- data/lib/graphql/tracing/notifications_trace.rb +2 -2
- data/lib/graphql/types/relay/connection_behaviors.rb +12 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +11 -1
- data/lib/graphql/types/relay/page_info_behaviors.rb +4 -0
- data/lib/graphql/types.rb +18 -11
- data/lib/graphql/unauthorized_enum_value_error.rb +13 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +81 -45
- metadata +31 -8
- data/lib/graphql/language/token.rb +0 -34
- data/lib/graphql/schema/invalid_type_error.rb +0 -7
data/lib/graphql/schema.rb
CHANGED
@@ -5,7 +5,6 @@ require "graphql/schema/always_visible"
|
|
5
5
|
require "graphql/schema/base_64_encoder"
|
6
6
|
require "graphql/schema/find_inherited_value"
|
7
7
|
require "graphql/schema/finder"
|
8
|
-
require "graphql/schema/invalid_type_error"
|
9
8
|
require "graphql/schema/introspection_system"
|
10
9
|
require "graphql/schema/late_bound_type"
|
11
10
|
require "graphql/schema/null_mask"
|
@@ -46,6 +45,9 @@ require "graphql/schema/mutation"
|
|
46
45
|
require "graphql/schema/has_single_input_argument"
|
47
46
|
require "graphql/schema/relay_classic_mutation"
|
48
47
|
require "graphql/schema/subscription"
|
48
|
+
require "graphql/schema/visibility"
|
49
|
+
|
50
|
+
GraphQL.ensure_eager_load!
|
49
51
|
|
50
52
|
module GraphQL
|
51
53
|
# A GraphQL schema which may be queried with {GraphQL::Query}.
|
@@ -162,6 +164,7 @@ module GraphQL
|
|
162
164
|
# re-apply them here
|
163
165
|
mods = trace_modules_for(:default)
|
164
166
|
mods.each { |mod| new_class.include(mod) }
|
167
|
+
new_class.include(DefaultTraceClass)
|
165
168
|
trace_mode(:default, new_class)
|
166
169
|
backtrace_class = Class.new(new_class)
|
167
170
|
backtrace_class.include(GraphQL::Backtrace::Trace)
|
@@ -204,24 +207,19 @@ module GraphQL
|
|
204
207
|
@own_trace_modes ||= {}
|
205
208
|
end
|
206
209
|
|
207
|
-
module DefaultTraceClass
|
208
|
-
end
|
209
|
-
|
210
|
-
private_constant :DefaultTraceClass
|
211
|
-
|
212
210
|
def build_trace_mode(mode)
|
213
211
|
case mode
|
214
212
|
when :default
|
215
213
|
# Use the superclass's default mode if it has one, or else start an inheritance chain at the built-in base class.
|
216
|
-
base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode)) || GraphQL::Tracing::Trace
|
217
|
-
Class.new(base_class) do
|
214
|
+
base_class = (superclass.respond_to?(:trace_class_for) && superclass.trace_class_for(mode, build: true)) || GraphQL::Tracing::Trace
|
215
|
+
const_set(:DefaultTrace, Class.new(base_class) do
|
218
216
|
include DefaultTraceClass
|
219
|
-
end
|
217
|
+
end)
|
220
218
|
when :default_backtrace
|
221
219
|
schema_base_class = trace_class_for(:default, build: true)
|
222
|
-
Class.new(schema_base_class) do
|
220
|
+
const_set(:DefaultTraceBacktrace, Class.new(schema_base_class) do
|
223
221
|
include(GraphQL::Backtrace::Trace)
|
224
|
-
end
|
222
|
+
end)
|
225
223
|
else
|
226
224
|
# First, see if the superclass has a custom-defined class for this.
|
227
225
|
# Then, if it doesn't, use this class's default trace
|
@@ -237,7 +235,7 @@ module GraphQL
|
|
237
235
|
add_trace_options_for(mode, default_options)
|
238
236
|
|
239
237
|
Class.new(base_class) do
|
240
|
-
mods.
|
238
|
+
!mods.empty? && include(*mods)
|
241
239
|
end
|
242
240
|
end
|
243
241
|
end
|
@@ -321,8 +319,11 @@ module GraphQL
|
|
321
319
|
GraphQL::StaticValidation::Validator.new(schema: self)
|
322
320
|
end
|
323
321
|
|
322
|
+
# Add `plugin` to this schema
|
323
|
+
# @param plugin [#use] A Schema plugin
|
324
|
+
# @return void
|
324
325
|
def use(plugin, **kwargs)
|
325
|
-
if kwargs.
|
326
|
+
if !kwargs.empty?
|
326
327
|
plugin.use(self, **kwargs)
|
327
328
|
else
|
328
329
|
plugin.use(self)
|
@@ -338,6 +339,10 @@ module GraphQL
|
|
338
339
|
# @return [Hash<String => Class>] A dictionary of type classes by their GraphQL name
|
339
340
|
# @see get_type Which is more efficient for finding _one type_ by name, because it doesn't merge hashes.
|
340
341
|
def types(context = GraphQL::Query::NullContext.instance)
|
342
|
+
if use_visibility_profile?
|
343
|
+
types = Visibility::Profile.from_context(context, self)
|
344
|
+
return types.all_types_h
|
345
|
+
end
|
341
346
|
all_types = non_introspection_types.merge(introspection_system.types)
|
342
347
|
visible_types = {}
|
343
348
|
all_types.each do |k, v|
|
@@ -363,27 +368,36 @@ module GraphQL
|
|
363
368
|
end
|
364
369
|
|
365
370
|
# @param type_name [String]
|
371
|
+
# @param context [GraphQL::Query::Context] Used for filtering definitions at query-time
|
372
|
+
# @param use_visibility_profile Private, for migration to {Schema::Visibility}
|
366
373
|
# @return [Module, nil] A type, or nil if there's no type called `type_name`
|
367
|
-
def get_type(type_name, context = GraphQL::Query::NullContext.instance)
|
374
|
+
def get_type(type_name, context = GraphQL::Query::NullContext.instance, use_visibility_profile = use_visibility_profile?)
|
375
|
+
if use_visibility_profile
|
376
|
+
return Visibility::Profile.from_context(context, self).type(type_name)
|
377
|
+
end
|
368
378
|
local_entry = own_types[type_name]
|
369
379
|
type_defn = case local_entry
|
370
380
|
when nil
|
371
381
|
nil
|
372
382
|
when Array
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
+
if context.respond_to?(:types) && context.types.is_a?(GraphQL::Schema::Visibility::Profile)
|
384
|
+
local_entry
|
385
|
+
else
|
386
|
+
visible_t = nil
|
387
|
+
warden = Warden.from_context(context)
|
388
|
+
local_entry.each do |t|
|
389
|
+
if warden.visible_type?(t, context)
|
390
|
+
if visible_t.nil?
|
391
|
+
visible_t = t
|
392
|
+
else
|
393
|
+
raise DuplicateNamesError.new(
|
394
|
+
duplicated_name: type_name, duplicated_definition_1: visible_t.inspect, duplicated_definition_2: t.inspect
|
395
|
+
)
|
396
|
+
end
|
383
397
|
end
|
384
398
|
end
|
399
|
+
visible_t
|
385
400
|
end
|
386
|
-
visible_t
|
387
401
|
when Module
|
388
402
|
local_entry
|
389
403
|
else
|
@@ -392,7 +406,7 @@ module GraphQL
|
|
392
406
|
|
393
407
|
type_defn ||
|
394
408
|
introspection_system.types[type_name] || # todo context-specific introspection?
|
395
|
-
(superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context) : nil)
|
409
|
+
(superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context, use_visibility_profile) : nil)
|
396
410
|
end
|
397
411
|
|
398
412
|
# @return [Boolean] Does this schema have _any_ definition for a type named `type_name`, regardless of visibility?
|
@@ -419,55 +433,127 @@ module GraphQL
|
|
419
433
|
end
|
420
434
|
end
|
421
435
|
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
436
|
+
# Get or set the root `query { ... }` object for this schema.
|
437
|
+
#
|
438
|
+
# @example Using `Types::Query` as the entry-point
|
439
|
+
# query { Types::Query }
|
440
|
+
#
|
441
|
+
# @param new_query_object [Class<GraphQL::Schema::Object>] The root type to use for queries
|
442
|
+
# @param lazy_load_block If a block is given, then it will be called when GraphQL-Ruby needs the root query type.
|
443
|
+
# @return [Class<GraphQL::Schema::Object>, nil] The configured query root type, if there is one.
|
444
|
+
def query(new_query_object = nil, &lazy_load_block)
|
445
|
+
if new_query_object || block_given?
|
428
446
|
if @query_object
|
429
|
-
|
447
|
+
dup_defn = new_query_object || yield
|
448
|
+
raise GraphQL::Error, "Second definition of `query(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@query_object.inspect}"
|
449
|
+
elsif use_visibility_profile?
|
450
|
+
if block_given?
|
451
|
+
if visibility.preload?
|
452
|
+
@query_object = lazy_load_block.call
|
453
|
+
self.visibility.query_configured(@query_object)
|
454
|
+
else
|
455
|
+
@query_object = lazy_load_block
|
456
|
+
end
|
457
|
+
else
|
458
|
+
@query_object = new_query_object
|
459
|
+
self.visibility.query_configured(@query_object)
|
460
|
+
end
|
430
461
|
else
|
431
|
-
@query_object = new_query_object
|
432
|
-
add_type_and_traverse(
|
433
|
-
nil
|
462
|
+
@query_object = new_query_object || lazy_load_block.call
|
463
|
+
add_type_and_traverse(@query_object, root: true)
|
434
464
|
end
|
465
|
+
nil
|
466
|
+
elsif @query_object.is_a?(Proc)
|
467
|
+
@query_object = @query_object.call
|
468
|
+
self.visibility&.query_configured(@query_object)
|
469
|
+
@query_object
|
435
470
|
else
|
436
471
|
@query_object || find_inherited_value(:query)
|
437
472
|
end
|
438
473
|
end
|
439
474
|
|
440
|
-
|
441
|
-
|
475
|
+
# Get or set the root `mutation { ... }` object for this schema.
|
476
|
+
#
|
477
|
+
# @example Using `Types::Mutation` as the entry-point
|
478
|
+
# mutation { Types::Mutation }
|
479
|
+
#
|
480
|
+
# @param new_mutation_object [Class<GraphQL::Schema::Object>] The root type to use for mutations
|
481
|
+
# @param lazy_load_block If a block is given, then it will be called when GraphQL-Ruby needs the root mutation type.
|
482
|
+
# @return [Class<GraphQL::Schema::Object>, nil] The configured mutation root type, if there is one.
|
483
|
+
def mutation(new_mutation_object = nil, &lazy_load_block)
|
484
|
+
if new_mutation_object || block_given?
|
442
485
|
if @mutation_object
|
443
|
-
|
486
|
+
dup_defn = new_mutation_object || yield
|
487
|
+
raise GraphQL::Error, "Second definition of `mutation(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@mutation_object.inspect}"
|
488
|
+
elsif use_visibility_profile?
|
489
|
+
if block_given?
|
490
|
+
if visibility.preload?
|
491
|
+
@mutation_object = lazy_load_block.call
|
492
|
+
self.visibility.mutation_configured(@mutation_object)
|
493
|
+
else
|
494
|
+
@mutation_object = lazy_load_block
|
495
|
+
end
|
496
|
+
else
|
497
|
+
@mutation_object = new_mutation_object
|
498
|
+
self.visibility.mutation_configured(@mutation_object)
|
499
|
+
end
|
444
500
|
else
|
445
|
-
@mutation_object = new_mutation_object
|
446
|
-
add_type_and_traverse(
|
447
|
-
nil
|
501
|
+
@mutation_object = new_mutation_object || lazy_load_block.call
|
502
|
+
add_type_and_traverse(@mutation_object, root: true)
|
448
503
|
end
|
504
|
+
nil
|
505
|
+
elsif @mutation_object.is_a?(Proc)
|
506
|
+
@mutation_object = @mutation_object.call
|
507
|
+
self.visibility&.mutation_configured(@mutation_object)
|
508
|
+
@mutation_object
|
449
509
|
else
|
450
510
|
@mutation_object || find_inherited_value(:mutation)
|
451
511
|
end
|
452
512
|
end
|
453
513
|
|
454
|
-
|
455
|
-
|
514
|
+
# Get or set the root `subscription { ... }` object for this schema.
|
515
|
+
#
|
516
|
+
# @example Using `Types::Subscription` as the entry-point
|
517
|
+
# subscription { Types::Subscription }
|
518
|
+
#
|
519
|
+
# @param new_subscription_object [Class<GraphQL::Schema::Object>] The root type to use for subscriptions
|
520
|
+
# @param lazy_load_block If a block is given, then it will be called when GraphQL-Ruby needs the root subscription type.
|
521
|
+
# @return [Class<GraphQL::Schema::Object>, nil] The configured subscription root type, if there is one.
|
522
|
+
def subscription(new_subscription_object = nil, &lazy_load_block)
|
523
|
+
if new_subscription_object || block_given?
|
456
524
|
if @subscription_object
|
457
|
-
|
525
|
+
dup_defn = new_subscription_object || yield
|
526
|
+
raise GraphQL::Error, "Second definition of `subscription(...)` (#{dup_defn.inspect}) is invalid, already configured with #{@subscription_object.inspect}"
|
527
|
+
elsif use_visibility_profile?
|
528
|
+
if block_given?
|
529
|
+
if visibility.preload?
|
530
|
+
@subscription_object = lazy_load_block.call
|
531
|
+
visibility.subscription_configured(@subscription_object)
|
532
|
+
else
|
533
|
+
@subscription_object = lazy_load_block
|
534
|
+
end
|
535
|
+
else
|
536
|
+
@subscription_object = new_subscription_object
|
537
|
+
self.visibility.subscription_configured(@subscription_object)
|
538
|
+
end
|
539
|
+
add_subscription_extension_if_necessary
|
458
540
|
else
|
459
|
-
@subscription_object = new_subscription_object
|
541
|
+
@subscription_object = new_subscription_object || lazy_load_block.call
|
460
542
|
add_subscription_extension_if_necessary
|
461
|
-
add_type_and_traverse(
|
462
|
-
nil
|
543
|
+
add_type_and_traverse(@subscription_object, root: true)
|
463
544
|
end
|
545
|
+
nil
|
546
|
+
elsif @subscription_object.is_a?(Proc)
|
547
|
+
@subscription_object = @subscription_object.call
|
548
|
+
add_subscription_extension_if_necessary
|
549
|
+
self.visibility.subscription_configured(@subscription_object)
|
550
|
+
@subscription_object
|
464
551
|
else
|
465
552
|
@subscription_object || find_inherited_value(:subscription)
|
466
553
|
end
|
467
554
|
end
|
468
555
|
|
469
|
-
# @
|
470
|
-
# @return [GraphQL::ObjectType, nil]
|
556
|
+
# @api private
|
471
557
|
def root_type_for_operation(operation)
|
472
558
|
case operation
|
473
559
|
when "query"
|
@@ -481,10 +567,16 @@ module GraphQL
|
|
481
567
|
end
|
482
568
|
end
|
483
569
|
|
570
|
+
# @return [Array<Class>] The root types (query, mutation, subscription) defined for this schema
|
484
571
|
def root_types
|
485
|
-
|
572
|
+
if use_visibility_profile?
|
573
|
+
[query, mutation, subscription].compact
|
574
|
+
else
|
575
|
+
@root_types
|
576
|
+
end
|
486
577
|
end
|
487
578
|
|
579
|
+
# @api private
|
488
580
|
def warden_class
|
489
581
|
if defined?(@warden_class)
|
490
582
|
@warden_class
|
@@ -495,12 +587,48 @@ module GraphQL
|
|
495
587
|
end
|
496
588
|
end
|
497
589
|
|
590
|
+
# @api private
|
498
591
|
attr_writer :warden_class
|
499
592
|
|
593
|
+
# @api private
|
594
|
+
def visibility_profile_class
|
595
|
+
if defined?(@visibility_profile_class)
|
596
|
+
@visibility_profile_class
|
597
|
+
elsif superclass.respond_to?(:visibility_profile_class)
|
598
|
+
superclass.visibility_profile_class
|
599
|
+
else
|
600
|
+
GraphQL::Schema::Visibility::Profile
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
# @api private
|
605
|
+
attr_writer :visibility_profile_class, :use_visibility_profile
|
606
|
+
# @api private
|
607
|
+
attr_accessor :visibility
|
608
|
+
# @api private
|
609
|
+
def use_visibility_profile?
|
610
|
+
if defined?(@use_visibility_profile)
|
611
|
+
@use_visibility_profile
|
612
|
+
elsif superclass.respond_to?(:use_visibility_profile?)
|
613
|
+
superclass.use_visibility_profile?
|
614
|
+
else
|
615
|
+
false
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
500
619
|
# @param type [Module] The type definition whose possible types you want to see
|
620
|
+
# @param context [GraphQL::Query::Context] used for filtering visible possible types at runtime
|
621
|
+
# @param use_visibility_profile Private, for migration to {Schema::Visibility}
|
501
622
|
# @return [Hash<String, Module>] All possible types, if no `type` is given.
|
502
623
|
# @return [Array<Module>] Possible types for `type`, if it's given.
|
503
|
-
def possible_types(type = nil, context = GraphQL::Query::NullContext.instance)
|
624
|
+
def possible_types(type = nil, context = GraphQL::Query::NullContext.instance, use_visibility_profile = use_visibility_profile?)
|
625
|
+
if use_visibility_profile
|
626
|
+
if type
|
627
|
+
return Visibility::Profile.from_context(context, self).possible_types(type)
|
628
|
+
else
|
629
|
+
raise "Schema.possible_types is not implemented for `use_visibility_profile?`"
|
630
|
+
end
|
631
|
+
end
|
504
632
|
if type
|
505
633
|
# TODO duck-typing `.possible_types` would probably be nicer here
|
506
634
|
if type.kind.union?
|
@@ -518,7 +646,7 @@ module GraphQL
|
|
518
646
|
introspection_system.possible_types[type] ||
|
519
647
|
(
|
520
648
|
superclass.respond_to?(:possible_types) ?
|
521
|
-
superclass.possible_types(type, context) :
|
649
|
+
superclass.possible_types(type, context, use_visibility_profile) :
|
522
650
|
EMPTY_ARRAY
|
523
651
|
)
|
524
652
|
end
|
@@ -565,7 +693,7 @@ module GraphQL
|
|
565
693
|
# and generally speaking, we won't inherit any values.
|
566
694
|
# So optimize the most common case -- don't create a duplicate Hash.
|
567
695
|
inherited_value = find_inherited_value(:references_to, EMPTY_HASH)
|
568
|
-
if inherited_value.
|
696
|
+
if !inherited_value.empty?
|
569
697
|
inherited_value.merge(own_references_to)
|
570
698
|
else
|
571
699
|
own_references_to
|
@@ -573,9 +701,8 @@ module GraphQL
|
|
573
701
|
end
|
574
702
|
end
|
575
703
|
|
576
|
-
def type_from_ast(ast_node, context:
|
577
|
-
|
578
|
-
GraphQL::Schema::TypeExpression.build_type(type_owner, ast_node)
|
704
|
+
def type_from_ast(ast_node, context: self.query_class.new(self, "{ __typename }").context)
|
705
|
+
GraphQL::Schema::TypeExpression.build_type(context.query.types, ast_node)
|
579
706
|
end
|
580
707
|
|
581
708
|
def get_field(type_or_name, field_name, context = GraphQL::Query::NullContext.instance)
|
@@ -605,20 +732,27 @@ module GraphQL
|
|
605
732
|
type.fields(context)
|
606
733
|
end
|
607
734
|
|
735
|
+
# Pass a custom introspection module here to use it for this schema.
|
736
|
+
# @param new_introspection_namespace [Module] If given, use this module for custom introspection on the schema
|
737
|
+
# @return [Module, nil] The configured namespace, if there is one
|
608
738
|
def introspection(new_introspection_namespace = nil)
|
609
739
|
if new_introspection_namespace
|
610
740
|
@introspection = new_introspection_namespace
|
611
741
|
# reset this cached value:
|
612
742
|
@introspection_system = nil
|
743
|
+
introspection_system
|
744
|
+
@introspection
|
613
745
|
else
|
614
746
|
@introspection || find_inherited_value(:introspection)
|
615
747
|
end
|
616
748
|
end
|
617
749
|
|
750
|
+
# @return [Schema::IntrospectionSystem] Based on {introspection}
|
618
751
|
def introspection_system
|
619
752
|
if !@introspection_system
|
620
753
|
@introspection_system = Schema::IntrospectionSystem.new(self)
|
621
754
|
@introspection_system.resolve_late_bindings
|
755
|
+
self.visibility&.introspection_system_configured(@introspection_system)
|
622
756
|
end
|
623
757
|
@introspection_system
|
624
758
|
end
|
@@ -722,6 +856,7 @@ module GraphQL
|
|
722
856
|
res[:errors]
|
723
857
|
end
|
724
858
|
|
859
|
+
# @param new_query_class [Class<GraphQL::Query>] A subclass to use when executing queries
|
725
860
|
def query_class(new_query_class = NOT_CONFIGURED)
|
726
861
|
if NOT_CONFIGURED.equal?(new_query_class)
|
727
862
|
@query_class || (superclass.respond_to?(:query_class) ? superclass.query_class : GraphQL::Query)
|
@@ -732,13 +867,11 @@ module GraphQL
|
|
732
867
|
|
733
868
|
attr_writer :validate_max_errors
|
734
869
|
|
735
|
-
def validate_max_errors(new_validate_max_errors =
|
736
|
-
if new_validate_max_errors
|
737
|
-
@validate_max_errors
|
738
|
-
elsif defined?(@validate_max_errors)
|
739
|
-
@validate_max_errors
|
870
|
+
def validate_max_errors(new_validate_max_errors = NOT_CONFIGURED)
|
871
|
+
if NOT_CONFIGURED.equal?(new_validate_max_errors)
|
872
|
+
defined?(@validate_max_errors) ? @validate_max_errors : find_inherited_value(:validate_max_errors)
|
740
873
|
else
|
741
|
-
|
874
|
+
@validate_max_errors = new_validate_max_errors
|
742
875
|
end
|
743
876
|
end
|
744
877
|
|
@@ -769,16 +902,6 @@ module GraphQL
|
|
769
902
|
@analysis_engine || find_inherited_value(:analysis_engine, self.default_analysis_engine)
|
770
903
|
end
|
771
904
|
|
772
|
-
def using_ast_analysis?
|
773
|
-
true
|
774
|
-
end
|
775
|
-
|
776
|
-
def interpreter?
|
777
|
-
true
|
778
|
-
end
|
779
|
-
|
780
|
-
attr_writer :interpreter
|
781
|
-
|
782
905
|
def error_bubbling(new_error_bubbling = nil)
|
783
906
|
if !new_error_bubbling.nil?
|
784
907
|
warn("error_bubbling(#{new_error_bubbling.inspect}) is deprecated; the default value of `false` will be the only option in GraphQL-Ruby 3.0")
|
@@ -856,7 +979,7 @@ module GraphQL
|
|
856
979
|
# @param new_extra_types [Module] Type definitions to include in printing and introspection, even though they aren't referenced in the schema
|
857
980
|
# @return [Array<Module>] Type definitions added to this schema
|
858
981
|
def extra_types(*new_extra_types)
|
859
|
-
if new_extra_types.
|
982
|
+
if !new_extra_types.empty?
|
860
983
|
new_extra_types = new_extra_types.flatten
|
861
984
|
@own_extra_types ||= []
|
862
985
|
@own_extra_types.concat(new_extra_types)
|
@@ -873,11 +996,18 @@ module GraphQL
|
|
873
996
|
end
|
874
997
|
end
|
875
998
|
|
999
|
+
# Tell the schema about these types so that they can be registered as implementations of interfaces in the schema.
|
1000
|
+
#
|
1001
|
+
# This method must be used when an object type is connected to the schema as an interface implementor but
|
1002
|
+
# not as a return type of a field. In that case, if the object type isn't registered here, GraphQL-Ruby won't be able to find it.
|
1003
|
+
#
|
1004
|
+
# @param new_orphan_types [Array<Class<GraphQL::Schema::Object>>] Object types to register as implementations of interfaces in the schema.
|
1005
|
+
# @return [Array<Class<GraphQL::Schema::Object>>] All previously-registered orphan types for this schema
|
876
1006
|
def orphan_types(*new_orphan_types)
|
877
|
-
if new_orphan_types.
|
1007
|
+
if !new_orphan_types.empty?
|
878
1008
|
new_orphan_types = new_orphan_types.flatten
|
879
1009
|
non_object_types = new_orphan_types.reject { |ot| ot.is_a?(Class) && ot < GraphQL::Schema::Object }
|
880
|
-
if non_object_types.
|
1010
|
+
if !non_object_types.empty?
|
881
1011
|
raise ArgumentError, <<~ERR
|
882
1012
|
Only object type classes should be added as `orphan_types(...)`.
|
883
1013
|
|
@@ -887,13 +1017,14 @@ module GraphQL
|
|
887
1017
|
To add other types to your schema, you might want `extra_types`: https://graphql-ruby.org/schema/definition.html#extra-types
|
888
1018
|
ERR
|
889
1019
|
end
|
890
|
-
add_type_and_traverse(new_orphan_types, root: false)
|
1020
|
+
add_type_and_traverse(new_orphan_types, root: false) unless use_visibility_profile?
|
891
1021
|
own_orphan_types.concat(new_orphan_types.flatten)
|
1022
|
+
self.visibility&.orphan_types_configured(new_orphan_types)
|
892
1023
|
end
|
893
1024
|
|
894
1025
|
inherited_ot = find_inherited_value(:orphan_types, nil)
|
895
1026
|
if inherited_ot
|
896
|
-
if own_orphan_types.
|
1027
|
+
if !own_orphan_types.empty?
|
897
1028
|
inherited_ot + own_orphan_types
|
898
1029
|
else
|
899
1030
|
inherited_ot
|
@@ -919,6 +1050,8 @@ module GraphQL
|
|
919
1050
|
end
|
920
1051
|
end
|
921
1052
|
|
1053
|
+
|
1054
|
+
# @param new_default_logger [#log] Something to use for logging messages
|
922
1055
|
def default_logger(new_default_logger = NOT_CONFIGURED)
|
923
1056
|
if NOT_CONFIGURED.equal?(new_default_logger)
|
924
1057
|
if defined?(@default_logger)
|
@@ -939,6 +1072,7 @@ module GraphQL
|
|
939
1072
|
end
|
940
1073
|
end
|
941
1074
|
|
1075
|
+
# @param new_context_class [Class<GraphQL::Query::Context>] A subclass to use when executing queries
|
942
1076
|
def context_class(new_context_class = nil)
|
943
1077
|
if new_context_class
|
944
1078
|
@context_class = new_context_class
|
@@ -947,6 +1081,20 @@ module GraphQL
|
|
947
1081
|
end
|
948
1082
|
end
|
949
1083
|
|
1084
|
+
# Register a handler for errors raised during execution. The handlers can return a new value or raise a new error.
|
1085
|
+
#
|
1086
|
+
# @example Handling "not found" with a client-facing error
|
1087
|
+
# rescue_from(ActiveRecord::NotFound) { raise GraphQL::ExecutionError, "An object could not be found" }
|
1088
|
+
#
|
1089
|
+
# @param err_classes [Array<StandardError>] Classes which should be rescued by `handler_block`
|
1090
|
+
# @param handler_block The code to run when one of those errors is raised during execution
|
1091
|
+
# @yieldparam error [StandardError] An instance of one of the configured `err_classes`
|
1092
|
+
# @yieldparam object [Object] The current application object in the query when the error was raised
|
1093
|
+
# @yieldparam arguments [GraphQL::Query::Arguments] The current field arguments when the error was raised
|
1094
|
+
# @yieldparam context [GraphQL::Query::Context] The context for the currently-running operation
|
1095
|
+
# @yieldreturn [Object] Some object to use in the place where this error was raised
|
1096
|
+
# @raise [GraphQL::ExecutionError] In the handler, raise to add a client-facing error to the response
|
1097
|
+
# @raise [StandardError] In the handler, raise to crash the query with a developer-facing error
|
950
1098
|
def rescue_from(*err_classes, &handler_block)
|
951
1099
|
err_classes.each do |err_class|
|
952
1100
|
Execution::Errors.register_rescue_from(err_class, error_handlers[:subclass_handlers], handler_block)
|
@@ -1013,8 +1161,24 @@ module GraphQL
|
|
1013
1161
|
end
|
1014
1162
|
end
|
1015
1163
|
|
1016
|
-
|
1017
|
-
|
1164
|
+
# GraphQL-Ruby calls this method during execution when it needs the application to determine the type to use for an object.
|
1165
|
+
#
|
1166
|
+
# Usually, this object was returned from a field whose return type is an {GraphQL::Schema::Interface} or a {GraphQL::Schema::Union}.
|
1167
|
+
# But this method is called in other cases, too -- for example, when {GraphQL::Schema::Argument.loads} cases an object to be directly loaded from the database.
|
1168
|
+
#
|
1169
|
+
# @example Returning a GraphQL type based on the object's class name
|
1170
|
+
# class MySchema < GraphQL::Schema
|
1171
|
+
# def resolve_type(_abs_type, object, _context)
|
1172
|
+
# graphql_type_name = "Types::#{object.class.name}Type"
|
1173
|
+
# graphql_type_name.constantize # If this raises a NameError, then come implement special cases in this method
|
1174
|
+
# end
|
1175
|
+
# end
|
1176
|
+
# @param abstract_type [Class, Module, nil] The Interface or Union type which is being resolved, if there is one
|
1177
|
+
# @param application_object [Object] The object returned from a field whose type must be determined
|
1178
|
+
# @param context [GraphQL::Query::Context] The query context for the currently-executing query
|
1179
|
+
# @return [Class<GraphQL::Schema::Object] The Object type definition to use for `obj`
|
1180
|
+
def resolve_type(abstract_type, application_object, context)
|
1181
|
+
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(abstract_type, application_object, context) must be implemented to use Union types, Interface types, or `loads:` (tried to resolve: #{abstract_type.name})"
|
1018
1182
|
end
|
1019
1183
|
# rubocop:enable Lint/DuplicateMethods
|
1020
1184
|
|
@@ -1029,15 +1193,45 @@ module GraphQL
|
|
1029
1193
|
child_class.own_trace_modes[name] = child_class.build_trace_mode(name)
|
1030
1194
|
end
|
1031
1195
|
child_class.singleton_class.prepend(ResolveTypeWithType)
|
1032
|
-
super
|
1033
|
-
end
|
1034
1196
|
|
1035
|
-
|
1036
|
-
|
1197
|
+
if use_visibility_profile?
|
1198
|
+
vis = self.visibility
|
1199
|
+
child_class.visibility = vis.dup_for(child_class)
|
1200
|
+
end
|
1201
|
+
super
|
1037
1202
|
end
|
1038
1203
|
|
1039
|
-
|
1040
|
-
|
1204
|
+
# Fetch an object based on an incoming ID and the current context. This method should return an object
|
1205
|
+
# from your application, or return `nil` if there is no object or the object shouldn't be available to this operation.
|
1206
|
+
#
|
1207
|
+
# @example Fetching an object with Rails's GlobalID
|
1208
|
+
# def self.object_from_id(object_id, _context)
|
1209
|
+
# GlobalID.find(global_id)
|
1210
|
+
# # TODO: use `context[:current_user]` to determine if this object is authorized.
|
1211
|
+
# end
|
1212
|
+
# @param object_id [String] The ID to fetch an object for. This may be client-provided (as in `node(id: ...)` or `loads:`) or previously stored by the schema (eg, by the `ObjectCache`)
|
1213
|
+
# @param context [GraphQL::Query::Context] The context for the currently-executing operation
|
1214
|
+
# @return [Object, nil] The application which `object_id` references, or `nil` if there is no object or the current operation shouldn't have access to the object
|
1215
|
+
# @see id_from_object which produces these IDs
|
1216
|
+
def object_from_id(object_id, context)
|
1217
|
+
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.object_from_id(object_id, context) must be implemented to load by ID (tried to load from id `#{object_id}`)"
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
# Return a stable ID string for `object` so that it can be refetched later, using {.object_from_id}.
|
1221
|
+
#
|
1222
|
+
# {GlobalID}(https://github.com/rails/globalid) and {SQIDs}(https://sqids.org/ruby) can both be used to create IDs.
|
1223
|
+
#
|
1224
|
+
# @example Using Rails's GlobalID to generate IDs
|
1225
|
+
# def self.id_from_object(application_object, graphql_type, context)
|
1226
|
+
# application_object.to_gid_param
|
1227
|
+
# end
|
1228
|
+
#
|
1229
|
+
# @param application_object [Object] Some object encountered by GraphQL-Ruby while running a query
|
1230
|
+
# @param graphql_type [Class, Module] The type that GraphQL-Ruby is using for `application_object` during this query
|
1231
|
+
# @param context [GraphQL::Query::Context] The context for the operation that is currently running
|
1232
|
+
# @return [String] A stable identifier which can be passed to {.object_from_id} later to re-fetch `application_object`
|
1233
|
+
def id_from_object(application_object, graphql_type, context)
|
1234
|
+
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.id_from_object(application_object, graphql_type, context) must be implemented to create global ids (tried to create an id for `#{application_object.inspect}`)"
|
1041
1235
|
end
|
1042
1236
|
|
1043
1237
|
def visible?(member, ctx)
|
@@ -1053,6 +1247,10 @@ module GraphQL
|
|
1053
1247
|
Member::HasDirectives.get_directives(self, @own_schema_directives, :schema_directives)
|
1054
1248
|
end
|
1055
1249
|
|
1250
|
+
# Called when a type is needed by name at runtime
|
1251
|
+
def load_type(type_name, ctx)
|
1252
|
+
get_type(type_name, ctx)
|
1253
|
+
end
|
1056
1254
|
# This hook is called when an object fails an `authorized?` check.
|
1057
1255
|
# You might report to your bug tracker here, so you can correct
|
1058
1256
|
# the field resolvers not to return unauthorized objects.
|
@@ -1088,6 +1286,16 @@ module GraphQL
|
|
1088
1286
|
unauthorized_object(unauthorized_error)
|
1089
1287
|
end
|
1090
1288
|
|
1289
|
+
# Called at runtime when GraphQL-Ruby encounters a mismatch between the application behavior
|
1290
|
+
# and the GraphQL type system.
|
1291
|
+
#
|
1292
|
+
# The default implementation of this method is to follow the GraphQL specification,
|
1293
|
+
# but you can override this to report errors to your bug tracker or customize error handling.
|
1294
|
+
# @param type_error [GraphQL::Error] several specific error classes are passed here, see the default implementation for details
|
1295
|
+
# @param context [GraphQL::Query::Context] the context for the currently-running operation
|
1296
|
+
# @return [void]
|
1297
|
+
# @raise [GraphQL::ExecutionError] to return this error to the client
|
1298
|
+
# @raise [GraphQL::Error] to crash the query and raise a developer-facing error
|
1091
1299
|
def type_error(type_error, ctx)
|
1092
1300
|
case type_error
|
1093
1301
|
when GraphQL::InvalidNullError
|
@@ -1126,12 +1334,12 @@ module GraphQL
|
|
1126
1334
|
# Add several directives at once
|
1127
1335
|
# @param new_directives [Class]
|
1128
1336
|
def directives(*new_directives)
|
1129
|
-
if new_directives.
|
1337
|
+
if !new_directives.empty?
|
1130
1338
|
new_directives.flatten.each { |d| directive(d) }
|
1131
1339
|
end
|
1132
1340
|
|
1133
1341
|
inherited_dirs = find_inherited_value(:directives, default_directives)
|
1134
|
-
if own_directives.
|
1342
|
+
if !own_directives.empty?
|
1135
1343
|
inherited_dirs.merge(own_directives)
|
1136
1344
|
else
|
1137
1345
|
inherited_dirs
|
@@ -1142,7 +1350,11 @@ module GraphQL
|
|
1142
1350
|
# @param new_directive [Class]
|
1143
1351
|
# @return void
|
1144
1352
|
def directive(new_directive)
|
1145
|
-
|
1353
|
+
if use_visibility_profile?
|
1354
|
+
own_directives[new_directive.graphql_name] = new_directive
|
1355
|
+
else
|
1356
|
+
add_type_and_traverse(new_directive, root: false)
|
1357
|
+
end
|
1146
1358
|
end
|
1147
1359
|
|
1148
1360
|
def default_directives
|
@@ -1179,6 +1391,7 @@ module GraphQL
|
|
1179
1391
|
# @param mode [Symbol] Trace module will only be used for this trade mode
|
1180
1392
|
# @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
|
1181
1393
|
# @return [void]
|
1394
|
+
# @see GraphQL::Tracing::Trace for available tracing methods
|
1182
1395
|
def trace_with(trace_mod, mode: :default, **options)
|
1183
1396
|
if mode.is_a?(Array)
|
1184
1397
|
mode.each { |m| trace_with(trace_mod, mode: m, **options) }
|
@@ -1256,6 +1469,8 @@ module GraphQL
|
|
1256
1469
|
trace_class_for_mode.new(**trace_options)
|
1257
1470
|
end
|
1258
1471
|
|
1472
|
+
# @param new_analyzer [Class<GraphQL::Analysis::Analyzer>] An analyzer to run on queries to this schema
|
1473
|
+
# @see GraphQL::Analysis the analysis system
|
1259
1474
|
def query_analyzer(new_analyzer)
|
1260
1475
|
own_query_analyzers << new_analyzer
|
1261
1476
|
end
|
@@ -1264,6 +1479,8 @@ module GraphQL
|
|
1264
1479
|
find_inherited_value(:query_analyzers, EMPTY_ARRAY) + own_query_analyzers
|
1265
1480
|
end
|
1266
1481
|
|
1482
|
+
# @param new_analyzer [Class<GraphQL::Analysis::Analyzer>] An analyzer to run on multiplexes to this schema
|
1483
|
+
# @see GraphQL::Analysis the analysis system
|
1267
1484
|
def multiplex_analyzer(new_analyzer)
|
1268
1485
|
own_multiplex_analyzers << new_analyzer
|
1269
1486
|
end
|
@@ -1336,7 +1553,8 @@ module GraphQL
|
|
1336
1553
|
|
1337
1554
|
# @api private
|
1338
1555
|
def add_subscription_extension_if_necessary
|
1339
|
-
|
1556
|
+
# TODO: when there's a proper API for extending root types, migrat this to use it.
|
1557
|
+
if !defined?(@subscription_extension_added) && @subscription_object.is_a?(Class) && self.subscriptions
|
1340
1558
|
@subscription_extension_added = true
|
1341
1559
|
subscription.all_field_definitions.each do |field|
|
1342
1560
|
if !field.extensions.any? { |ext| ext.is_a?(Subscriptions::DefaultSubscriptionResolveExtension) }
|
@@ -1346,6 +1564,11 @@ module GraphQL
|
|
1346
1564
|
end
|
1347
1565
|
end
|
1348
1566
|
|
1567
|
+
# Called when execution encounters a `SystemStackError`. By default, it adds a client-facing error to the response.
|
1568
|
+
# You could modify this method to report this error to your bug tracker.
|
1569
|
+
# @param query [GraphQL::Query]
|
1570
|
+
# @param err [SystemStackError]
|
1571
|
+
# @return [void]
|
1349
1572
|
def query_stack_error(query, err)
|
1350
1573
|
query.context.errors.push(GraphQL::ExecutionError.new("This query is too large to execute."))
|
1351
1574
|
end
|
@@ -1404,11 +1627,34 @@ module GraphQL
|
|
1404
1627
|
end
|
1405
1628
|
end
|
1406
1629
|
|
1630
|
+
# Returns `DidYouMean` if it's defined.
|
1631
|
+
# Override this to return `nil` if you don't want to use `DidYouMean`
|
1632
|
+
def did_you_mean(new_dym = NOT_CONFIGURED)
|
1633
|
+
if NOT_CONFIGURED.equal?(new_dym)
|
1634
|
+
if defined?(@did_you_mean)
|
1635
|
+
@did_you_mean
|
1636
|
+
else
|
1637
|
+
find_inherited_value(:did_you_mean, defined?(DidYouMean) ? DidYouMean : nil)
|
1638
|
+
end
|
1639
|
+
else
|
1640
|
+
@did_you_mean = new_dym
|
1641
|
+
end
|
1642
|
+
end
|
1643
|
+
|
1407
1644
|
private
|
1408
1645
|
|
1409
1646
|
def add_trace_options_for(mode, new_options)
|
1410
|
-
|
1411
|
-
|
1647
|
+
if mode == :default
|
1648
|
+
own_trace_modes.each do |mode_name, t_class|
|
1649
|
+
if t_class <= DefaultTraceClass
|
1650
|
+
t_opts = trace_options_for(mode_name)
|
1651
|
+
t_opts.merge!(new_options)
|
1652
|
+
end
|
1653
|
+
end
|
1654
|
+
else
|
1655
|
+
t_opts = trace_options_for(mode)
|
1656
|
+
t_opts.merge!(new_options)
|
1657
|
+
end
|
1412
1658
|
nil
|
1413
1659
|
end
|
1414
1660
|
|
@@ -1485,7 +1731,7 @@ module GraphQL
|
|
1485
1731
|
end
|
1486
1732
|
|
1487
1733
|
def own_references_to
|
1488
|
-
@own_references_to ||= {}.
|
1734
|
+
@own_references_to ||= {}.compare_by_identity
|
1489
1735
|
end
|
1490
1736
|
|
1491
1737
|
def non_introspection_types
|
@@ -1501,7 +1747,7 @@ module GraphQL
|
|
1501
1747
|
end
|
1502
1748
|
|
1503
1749
|
def own_possible_types
|
1504
|
-
@own_possible_types ||= {}.
|
1750
|
+
@own_possible_types ||= {}.compare_by_identity
|
1505
1751
|
end
|
1506
1752
|
|
1507
1753
|
def own_union_memberships
|
@@ -1552,5 +1798,13 @@ module GraphQL
|
|
1552
1798
|
|
1553
1799
|
# Install these here so that subclasses will also install it.
|
1554
1800
|
self.connections = GraphQL::Pagination::Connections.new(schema: self)
|
1801
|
+
|
1802
|
+
# @api private
|
1803
|
+
module DefaultTraceClass
|
1804
|
+
end
|
1555
1805
|
end
|
1556
1806
|
end
|
1807
|
+
|
1808
|
+
require "graphql/schema/built_in_types"
|
1809
|
+
require "graphql/schema/loader"
|
1810
|
+
require "graphql/schema/printer"
|