graphql 2.3.7 → 2.4.5
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.
Potentially problematic release.
This version of graphql might be problematic. Click here for more details.
- 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"
|