graphql 2.0.16 → 2.0.21

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.

Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/ast/visitor.rb +42 -35
  3. data/lib/graphql/analysis/ast.rb +2 -2
  4. data/lib/graphql/backtrace/trace.rb +96 -0
  5. data/lib/graphql/backtrace/tracer.rb +1 -1
  6. data/lib/graphql/backtrace.rb +6 -1
  7. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  8. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
  9. data/lib/graphql/execution/interpreter/resolve.rb +19 -0
  10. data/lib/graphql/execution/interpreter/runtime.rb +264 -211
  11. data/lib/graphql/execution/interpreter.rb +15 -10
  12. data/lib/graphql/execution/lazy.rb +6 -12
  13. data/lib/graphql/execution/multiplex.rb +2 -1
  14. data/lib/graphql/filter.rb +7 -2
  15. data/lib/graphql/introspection/directive_type.rb +2 -2
  16. data/lib/graphql/introspection/field_type.rb +1 -1
  17. data/lib/graphql/introspection/schema_type.rb +2 -2
  18. data/lib/graphql/introspection/type_type.rb +5 -5
  19. data/lib/graphql/language/document_from_schema_definition.rb +25 -9
  20. data/lib/graphql/language/lexer.rb +216 -1505
  21. data/lib/graphql/language/nodes.rb +66 -40
  22. data/lib/graphql/language/parser.rb +509 -491
  23. data/lib/graphql/language/parser.y +43 -38
  24. data/lib/graphql/language/visitor.rb +191 -83
  25. data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
  26. data/lib/graphql/pagination/connection.rb +5 -5
  27. data/lib/graphql/query/context.rb +62 -31
  28. data/lib/graphql/query/null_context.rb +1 -1
  29. data/lib/graphql/query.rb +22 -5
  30. data/lib/graphql/schema/argument.rb +7 -13
  31. data/lib/graphql/schema/build_from_definition.rb +15 -3
  32. data/lib/graphql/schema/directive.rb +12 -2
  33. data/lib/graphql/schema/enum.rb +24 -17
  34. data/lib/graphql/schema/enum_value.rb +2 -3
  35. data/lib/graphql/schema/field.rb +68 -57
  36. data/lib/graphql/schema/field_extension.rb +1 -4
  37. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  38. data/lib/graphql/schema/interface.rb +0 -10
  39. data/lib/graphql/schema/late_bound_type.rb +2 -0
  40. data/lib/graphql/schema/member/base_dsl_methods.rb +17 -14
  41. data/lib/graphql/schema/member/has_arguments.rb +105 -58
  42. data/lib/graphql/schema/member/has_ast_node.rb +12 -0
  43. data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
  44. data/lib/graphql/schema/member/has_directives.rb +15 -10
  45. data/lib/graphql/schema/member/has_fields.rb +95 -38
  46. data/lib/graphql/schema/member/has_interfaces.rb +49 -8
  47. data/lib/graphql/schema/member/has_validators.rb +32 -6
  48. data/lib/graphql/schema/member/relay_shortcuts.rb +19 -0
  49. data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
  50. data/lib/graphql/schema/object.rb +2 -4
  51. data/lib/graphql/schema/resolver/has_payload_type.rb +9 -9
  52. data/lib/graphql/schema/resolver.rb +4 -4
  53. data/lib/graphql/schema/timeout.rb +24 -28
  54. data/lib/graphql/schema/validator.rb +1 -1
  55. data/lib/graphql/schema/warden.rb +29 -5
  56. data/lib/graphql/schema.rb +76 -25
  57. data/lib/graphql/static_validation/literal_validator.rb +15 -1
  58. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  59. data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
  60. data/lib/graphql/static_validation/validator.rb +1 -1
  61. data/lib/graphql/subscriptions/event.rb +2 -7
  62. data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
  63. data/lib/graphql/tracing/appoptics_trace.rb +231 -0
  64. data/lib/graphql/tracing/appsignal_trace.rb +77 -0
  65. data/lib/graphql/tracing/data_dog_trace.rb +148 -0
  66. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  67. data/lib/graphql/tracing/new_relic_trace.rb +75 -0
  68. data/lib/graphql/tracing/notifications_trace.rb +42 -0
  69. data/lib/graphql/tracing/platform_trace.rb +109 -0
  70. data/lib/graphql/tracing/platform_tracing.rb +15 -3
  71. data/lib/graphql/tracing/prometheus_trace.rb +89 -0
  72. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
  73. data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
  74. data/lib/graphql/tracing/scout_trace.rb +72 -0
  75. data/lib/graphql/tracing/statsd_trace.rb +56 -0
  76. data/lib/graphql/tracing/trace.rb +75 -0
  77. data/lib/graphql/tracing.rb +16 -39
  78. data/lib/graphql/type_kinds.rb +6 -3
  79. data/lib/graphql/types/relay/base_connection.rb +1 -1
  80. data/lib/graphql/types/relay/connection_behaviors.rb +24 -6
  81. data/lib/graphql/types/relay/edge_behaviors.rb +16 -6
  82. data/lib/graphql/types/relay/node_behaviors.rb +7 -1
  83. data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
  84. data/lib/graphql/types/relay.rb +0 -1
  85. data/lib/graphql/types/string.rb +1 -1
  86. data/lib/graphql/version.rb +1 -1
  87. data/lib/graphql.rb +16 -9
  88. metadata +34 -9
  89. data/lib/graphql/language/lexer.rl +0 -280
  90. data/lib/graphql/types/relay/default_relay.rb +0 -27
@@ -6,11 +6,12 @@ module GraphQL
6
6
  class Schema
7
7
  class Field
8
8
  include GraphQL::Schema::Member::HasArguments
9
+ include GraphQL::Schema::Member::HasArguments::FieldConfigured
9
10
  include GraphQL::Schema::Member::HasAstNode
10
11
  include GraphQL::Schema::Member::HasPath
11
12
  include GraphQL::Schema::Member::HasValidators
12
13
  extend GraphQL::Schema::FindInheritedValue
13
- include GraphQL::Schema::FindInheritedValue::EmptyObjects
14
+ include GraphQL::EmptyObjects
14
15
  include GraphQL::Schema::Member::HasDirectives
15
16
  include GraphQL::Schema::Member::HasDeprecationReason
16
17
 
@@ -218,7 +219,7 @@ module GraphQL
218
219
  # @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
219
220
  # @param validates [Array<Hash>] Configurations for validating this field
220
221
  # @fallback_value [Object] A fallback value if the method is not defined
221
- def initialize(type: nil, name: nil, owner: nil, null: nil, description: :not_given, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: :not_given, default_page_size: :not_given, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: nil, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: :not_given, &definition_block)
222
+ def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: NOT_CONFIGURED, &definition_block)
222
223
  if name.nil?
223
224
  raise ArgumentError, "missing first `name` argument or keyword `name:`"
224
225
  end
@@ -229,11 +230,13 @@ module GraphQL
229
230
  end
230
231
  @original_name = name
231
232
  name_s = -name.to_s
233
+
232
234
  @underscored_name = -Member::BuildType.underscore(name_s)
233
235
  @name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
234
- if description != :not_given
235
- @description = description
236
- end
236
+
237
+ @description = description
238
+ @type = @owner_type = @own_validators = @own_directives = @own_arguments = nil # these will be prepared later if necessary
239
+
237
240
  self.deprecation_reason = deprecation_reason
238
241
 
239
242
  if method && hash_key && dig
@@ -255,6 +258,9 @@ module GraphQL
255
258
  if hash_key
256
259
  @hash_key = hash_key
257
260
  @hash_key_str = hash_key.to_s
261
+ else
262
+ @hash_key = NOT_CONFIGURED
263
+ @hash_key_str = NOT_CONFIGURED
258
264
  end
259
265
 
260
266
  @method_str = -method_name.to_s
@@ -270,15 +276,11 @@ module GraphQL
270
276
  true
271
277
  end
272
278
  @connection = connection
273
- @has_max_page_size = max_page_size != :not_given
274
- @max_page_size = max_page_size == :not_given ? nil : max_page_size
275
- @has_default_page_size = default_page_size != :not_given
276
- @default_page_size = default_page_size == :not_given ? nil : default_page_size
279
+ @max_page_size = max_page_size
280
+ @default_page_size = default_page_size
277
281
  @introspection = introspection
278
282
  @extras = extras
279
- if !broadcastable.nil?
280
- @broadcastable = broadcastable
281
- end
283
+ @broadcastable = broadcastable
282
284
  @resolver_class = resolver_class
283
285
  @scope = scope
284
286
  @trace = trace
@@ -353,7 +355,7 @@ module GraphQL
353
355
  # @return [Boolean, nil]
354
356
  # @see GraphQL::Subscriptions::BroadcastAnalyzer
355
357
  def broadcastable?
356
- if defined?(@broadcastable)
358
+ if !NOT_CONFIGURED.equal?(@broadcastable)
357
359
  @broadcastable
358
360
  elsif @resolver_class
359
361
  @resolver_class.broadcastable?
@@ -367,10 +369,10 @@ module GraphQL
367
369
  def description(text = nil)
368
370
  if text
369
371
  @description = text
370
- elsif defined?(@description)
372
+ elsif !NOT_CONFIGURED.equal?(@description)
371
373
  @description
372
374
  elsif @resolver_class
373
- @description || @resolver_class.description
375
+ @resolver_class.description
374
376
  else
375
377
  nil
376
378
  end
@@ -542,22 +544,34 @@ module GraphQL
542
544
 
543
545
  # @return [Boolean] True if this field's {#max_page_size} should override the schema default.
544
546
  def has_max_page_size?
545
- @has_max_page_size || (@resolver_class && @resolver_class.has_max_page_size?)
547
+ !NOT_CONFIGURED.equal?(@max_page_size) || (@resolver_class && @resolver_class.has_max_page_size?)
546
548
  end
547
549
 
548
550
  # @return [Integer, nil] Applied to connections if {#has_max_page_size?}
549
551
  def max_page_size
550
- @max_page_size || (@resolver_class && @resolver_class.max_page_size)
552
+ if !NOT_CONFIGURED.equal?(@max_page_size)
553
+ @max_page_size
554
+ elsif @resolver_class && @resolver_class.has_max_page_size?
555
+ @resolver_class.max_page_size
556
+ else
557
+ nil
558
+ end
551
559
  end
552
560
 
553
561
  # @return [Boolean] True if this field's {#default_page_size} should override the schema default.
554
562
  def has_default_page_size?
555
- @has_default_page_size || (@resolver_class && @resolver_class.has_default_page_size?)
563
+ !NOT_CONFIGURED.equal?(@default_page_size) || (@resolver_class && @resolver_class.has_default_page_size?)
556
564
  end
557
565
 
558
566
  # @return [Integer, nil] Applied to connections if {#has_default_page_size?}
559
567
  def default_page_size
560
- @default_page_size || (@resolver_class && @resolver_class.default_page_size)
568
+ if !NOT_CONFIGURED.equal?(@default_page_size)
569
+ @default_page_size
570
+ elsif @resolver_class && @resolver_class.has_default_page_size?
571
+ @resolver_class.default_page_size
572
+ else
573
+ nil
574
+ end
561
575
  end
562
576
 
563
577
  class MissingReturnTypeError < GraphQL::Error; end
@@ -589,48 +603,43 @@ module GraphQL
589
603
  end
590
604
  end
591
605
 
592
- def accessible?(context)
593
- if @resolver_class
594
- @resolver_class.accessible?(context)
595
- else
596
- true
597
- end
598
- end
599
-
600
606
  def authorized?(object, args, context)
601
607
  if @resolver_class
602
608
  # The resolver _instance_ will check itself during `resolve()`
603
609
  @resolver_class.authorized?(object, context)
604
610
  else
605
- if (arg_values = context[:current_arguments])
606
- # ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
607
- using_arg_values = true
608
- arg_values = arg_values.argument_values
609
- else
610
- arg_values = args
611
- using_arg_values = false
612
- end
613
- # Faster than `.any?`
614
- arguments(context).each_value do |arg|
615
- arg_key = arg.keyword
616
- if arg_values.key?(arg_key)
617
- arg_value = arg_values[arg_key]
618
- if using_arg_values
619
- if arg_value.default_used?
620
- # pass -- no auth required for default used
621
- next
622
- else
623
- application_arg_value = arg_value.value
624
- if application_arg_value.is_a?(GraphQL::Execution::Interpreter::Arguments)
625
- application_arg_value.keyword_arguments
611
+ if args.size > 0
612
+ if (arg_values = context[:current_arguments])
613
+ # ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
614
+ using_arg_values = true
615
+ arg_values = arg_values.argument_values
616
+ else
617
+ arg_values = args
618
+ using_arg_values = false
619
+ end
620
+
621
+ args = context.warden.arguments(self)
622
+ args.each do |arg|
623
+ arg_key = arg.keyword
624
+ if arg_values.key?(arg_key)
625
+ arg_value = arg_values[arg_key]
626
+ if using_arg_values
627
+ if arg_value.default_used?
628
+ # pass -- no auth required for default used
629
+ next
630
+ else
631
+ application_arg_value = arg_value.value
632
+ if application_arg_value.is_a?(GraphQL::Execution::Interpreter::Arguments)
633
+ application_arg_value.keyword_arguments
634
+ end
626
635
  end
636
+ else
637
+ application_arg_value = arg_value
627
638
  end
628
- else
629
- application_arg_value = arg_value
630
- end
631
639
 
632
- if !arg.authorized?(object, application_arg_value, context)
633
- return false
640
+ if !arg.authorized?(object, application_arg_value, context)
641
+ return false
642
+ end
634
643
  end
635
644
  end
636
645
  end
@@ -665,7 +674,7 @@ module GraphQL
665
674
 
666
675
  inner_object = obj.object
667
676
 
668
- if defined?(@hash_key)
677
+ if !NOT_CONFIGURED.equal?(@hash_key)
669
678
  hash_value = if inner_object.is_a?(Hash)
670
679
  inner_object.key?(@hash_key) ? inner_object[@hash_key] : inner_object[@hash_key_str]
671
680
  elsif inner_object.respond_to?(:[])
@@ -676,7 +685,7 @@ module GraphQL
676
685
  if hash_value == false
677
686
  hash_value
678
687
  else
679
- hash_value || (@fallback_value != :not_given ? @fallback_value : nil)
688
+ hash_value || (@fallback_value != NOT_CONFIGURED ? @fallback_value : nil)
680
689
  end
681
690
  elsif obj.respond_to?(resolver_method)
682
691
  method_to_call = resolver_method
@@ -694,7 +703,7 @@ module GraphQL
694
703
  inner_object[@method_sym]
695
704
  elsif inner_object.key?(@method_str)
696
705
  inner_object[@method_str]
697
- elsif @fallback_value != :not_given
706
+ elsif @fallback_value != NOT_CONFIGURED
698
707
  @fallback_value
699
708
  else
700
709
  nil
@@ -707,7 +716,7 @@ module GraphQL
707
716
  else
708
717
  inner_object.public_send(@method_sym)
709
718
  end
710
- elsif @fallback_value != :not_given
719
+ elsif @fallback_value != NOT_CONFIGURED
711
720
  @fallback_value
712
721
  else
713
722
  raise <<-ERR
@@ -744,6 +753,8 @@ module GraphQL
744
753
  end
745
754
  # if the line above doesn't raise, re-raise
746
755
  raise
756
+ rescue GraphQL::ExecutionError => err
757
+ err
747
758
  end
748
759
 
749
760
  # @param ctx [GraphQL::Query::Context]
@@ -71,14 +71,11 @@ module GraphQL
71
71
  elsif inherited_extras
72
72
  inherited_extras
73
73
  else
74
- NO_EXTRAS
74
+ GraphQL::EmptyObjects::EMPTY_ARRAY
75
75
  end
76
76
  end
77
77
  end
78
78
 
79
- NO_EXTRAS = [].freeze
80
- private_constant :NO_EXTRAS
81
-
82
79
  # Called when this extension is attached to a field.
83
80
  # The field definition may be extended during this method.
84
81
  # @return [void]
@@ -2,17 +2,12 @@
2
2
  module GraphQL
3
3
  class Schema
4
4
  module FindInheritedValue
5
- module EmptyObjects
6
- EMPTY_HASH = {}.freeze
7
- EMPTY_ARRAY = [].freeze
8
- end
9
-
10
5
  def self.extended(child_cls)
11
- child_cls.singleton_class.include(EmptyObjects)
6
+ child_cls.singleton_class.include(GraphQL::EmptyObjects)
12
7
  end
13
8
 
14
9
  def self.included(child_cls)
15
- child_cls.include(EmptyObjects)
10
+ child_cls.include(GraphQL::EmptyObjects)
16
11
  end
17
12
 
18
13
  private
@@ -28,16 +28,6 @@ module GraphQL
28
28
  true
29
29
  end
30
30
 
31
- # The interface is accessible if any of its possible types are accessible
32
- def accessible?(context)
33
- context.schema.possible_types(self, context).each do |type|
34
- if context.schema.accessible?(type, context)
35
- return true
36
- end
37
- end
38
- false
39
- end
40
-
41
31
  def type_membership_class(membership_class = nil)
42
32
  if membership_class
43
33
  @type_membership_class = membership_class
@@ -9,6 +9,8 @@ module GraphQL
9
9
  alias :graphql_name :name
10
10
  def initialize(local_name)
11
11
  @name = local_name
12
+ @to_non_null_type = nil
13
+ @to_list_type = nil
12
14
  end
13
15
 
14
16
  def unwrap
@@ -22,14 +22,10 @@ module GraphQL
22
22
  GraphQL::NameValidator.validate!(new_name)
23
23
  @graphql_name = new_name
24
24
  else
25
- overridden_graphql_name || default_graphql_name
25
+ @graphql_name ||= default_graphql_name
26
26
  end
27
27
  end
28
28
 
29
- def overridden_graphql_name
30
- defined?(@graphql_name) ? @graphql_name : nil
31
- end
32
-
33
29
  # Just a convenience method to point out that people should use graphql_name instead
34
30
  def name(new_name = nil)
35
31
  return super() if new_name.nil?
@@ -50,7 +46,7 @@ module GraphQL
50
46
  elsif defined?(@description)
51
47
  @description
52
48
  else
53
- nil
49
+ @description = nil
54
50
  end
55
51
  end
56
52
 
@@ -60,8 +56,12 @@ module GraphQL
60
56
  def inherited(child_class)
61
57
  child_class.introspection(introspection)
62
58
  child_class.description(description)
63
- if overridden_graphql_name
64
- child_class.graphql_name(overridden_graphql_name)
59
+ child_class.default_graphql_name = nil
60
+
61
+ if defined?(@graphql_name) && @graphql_name && (self.name.nil? || graphql_name != default_graphql_name)
62
+ child_class.graphql_name(graphql_name)
63
+ else
64
+ child_class.graphql_name = nil
65
65
  end
66
66
  super
67
67
  end
@@ -79,7 +79,7 @@ module GraphQL
79
79
  end
80
80
 
81
81
  def introspection?
82
- introspection
82
+ !!@introspection
83
83
  end
84
84
 
85
85
  # The mutation this type was derived from, if it was derived from a mutation
@@ -102,8 +102,7 @@ module GraphQL
102
102
  def default_graphql_name
103
103
  @default_graphql_name ||= begin
104
104
  raise GraphQL::RequiredImplementationMissingError, 'Anonymous class should declare a `graphql_name`' if name.nil?
105
-
106
- name.split("::").last.sub(/Type\Z/, "")
105
+ -name.split("::").last.sub(/Type\Z/, "")
107
106
  end
108
107
  end
109
108
 
@@ -111,13 +110,17 @@ module GraphQL
111
110
  true
112
111
  end
113
112
 
114
- def accessible?(context)
113
+ def authorized?(object, context)
115
114
  true
116
115
  end
117
116
 
118
- def authorized?(object, context)
119
- true
117
+ def default_relay
118
+ false
120
119
  end
120
+
121
+ protected
122
+
123
+ attr_writer :default_graphql_name, :graphql_name
121
124
  end
122
125
  end
123
126
  end
@@ -11,6 +11,7 @@ module GraphQL
11
11
  def self.extended(cls)
12
12
  cls.extend(ArgumentClassAccessor)
13
13
  cls.include(ArgumentObjectLoader)
14
+ cls.extend(ClassConfigured)
14
15
  end
15
16
 
16
17
  # @see {GraphQL::Schema::Argument#initialize} for parameters
@@ -109,14 +110,6 @@ module GraphQL
109
110
 
110
111
  # @return [Hash<String => GraphQL::Schema::Argument] Arguments defined on this thing, keyed by name. Includes inherited definitions
111
112
  def arguments(context = GraphQL::Query::NullContext)
112
- inherited_arguments = if self.is_a?(Class) && superclass.respond_to?(:arguments)
113
- superclass.arguments(context)
114
- elsif defined?(@resolver_class) && @resolver_class
115
- @resolver_class.field_arguments(context)
116
- else
117
- nil
118
- end
119
- # Local definitions override inherited ones
120
113
  if own_arguments.any?
121
114
  own_arguments_that_apply = {}
122
115
  own_arguments.each do |name, args_entry|
@@ -125,47 +118,107 @@ module GraphQL
125
118
  end
126
119
  end
127
120
  end
121
+ # might be nil if there are actually no arguments
122
+ own_arguments_that_apply || own_arguments
123
+ end
128
124
 
129
- if inherited_arguments
130
- if own_arguments_that_apply
131
- inherited_arguments.merge(own_arguments_that_apply)
132
- else
133
- inherited_arguments
125
+ module ClassConfigured
126
+ def inherited(child_class)
127
+ super
128
+ child_class.extend(InheritedArguments)
129
+ end
130
+
131
+ module InheritedArguments
132
+ def arguments(context = GraphQL::Query::NullContext)
133
+ own_arguments = super
134
+ inherited_arguments = superclass.arguments(context)
135
+
136
+ if own_arguments.any?
137
+ if inherited_arguments.any?
138
+ # Local definitions override inherited ones
139
+ inherited_arguments.merge(own_arguments)
140
+ else
141
+ own_arguments
142
+ end
143
+ else
144
+ inherited_arguments
145
+ end
146
+ end
147
+
148
+ def all_argument_definitions
149
+ all_defns = {}
150
+ ancestors.reverse_each do |ancestor|
151
+ if ancestor.respond_to?(:own_arguments)
152
+ all_defns.merge!(ancestor.own_arguments)
153
+ end
154
+ end
155
+ all_defns = all_defns.values
156
+ all_defns.flatten!
157
+ all_defns
158
+ end
159
+
160
+
161
+ def get_argument(argument_name, context = GraphQL::Query::NullContext)
162
+ warden = Warden.from_context(context)
163
+ for ancestor in ancestors
164
+ if ancestor.respond_to?(:own_arguments) &&
165
+ (a = ancestor.own_arguments[argument_name]) &&
166
+ (a = Warden.visible_entry?(:visible_argument?, a, context, warden))
167
+ return a
168
+ end
169
+ end
170
+ nil
134
171
  end
135
- else
136
- # might be nil if there are actually no arguments
137
- own_arguments_that_apply || own_arguments
138
172
  end
139
173
  end
140
174
 
141
- def all_argument_definitions
142
- if self.is_a?(Class)
143
- all_defns = {}
144
- ancestors.reverse_each do |ancestor|
145
- if ancestor.respond_to?(:own_arguments)
146
- all_defns.merge!(ancestor.own_arguments)
175
+ module FieldConfigured
176
+ def arguments(context = GraphQL::Query::NullContext)
177
+ own_arguments = super
178
+ if defined?(@resolver_class) && @resolver_class
179
+ inherited_arguments = @resolver_class.field_arguments(context)
180
+ if own_arguments.any?
181
+ if inherited_arguments.any?
182
+ inherited_arguments.merge(own_arguments)
183
+ else
184
+ own_arguments
185
+ end
186
+ else
187
+ inherited_arguments
147
188
  end
189
+ else
190
+ own_arguments
148
191
  end
149
- elsif defined?(@resolver_class) && @resolver_class
150
- all_defns = {}
151
- @resolver_class.all_field_argument_definitions.each do |arg_defn|
152
- key = arg_defn.graphql_name
153
- case (current_value = all_defns[key])
154
- when nil
155
- all_defns[key] = arg_defn
156
- when Array
157
- current_value << arg_defn
158
- when GraphQL::Schema::Argument
159
- all_defns[key] = [current_value, arg_defn]
160
- else
161
- raise "Invariant: Unexpected argument definition, #{current_value.class}: #{current_value.inspect}"
192
+ end
193
+
194
+ def all_argument_definitions
195
+ if defined?(@resolver_class) && @resolver_class
196
+ all_defns = {}
197
+ @resolver_class.all_field_argument_definitions.each do |arg_defn|
198
+ key = arg_defn.graphql_name
199
+ case (current_value = all_defns[key])
200
+ when nil
201
+ all_defns[key] = arg_defn
202
+ when Array
203
+ current_value << arg_defn
204
+ when GraphQL::Schema::Argument
205
+ all_defns[key] = [current_value, arg_defn]
206
+ else
207
+ raise "Invariant: Unexpected argument definition, #{current_value.class}: #{current_value.inspect}"
208
+ end
162
209
  end
210
+ all_defns.merge!(own_arguments)
211
+ all_defns = all_defns.values
212
+ all_defns.flatten!
213
+ all_defns
214
+ else
215
+ super
163
216
  end
164
- all_defns.merge!(own_arguments)
165
- else
166
- all_defns = own_arguments
167
217
  end
168
- all_defns = all_defns.values
218
+ end
219
+
220
+ def all_argument_definitions
221
+ all_defns = own_arguments.values
169
222
  all_defns.flatten!
170
223
  all_defns
171
224
  end
@@ -173,22 +226,11 @@ module GraphQL
173
226
  # @return [GraphQL::Schema::Argument, nil] Argument defined on this thing, fetched by name.
174
227
  def get_argument(argument_name, context = GraphQL::Query::NullContext)
175
228
  warden = Warden.from_context(context)
176
- if !self.is_a?(Class)
177
- if (arg_config = own_arguments[argument_name]) && (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden))
178
- visible_arg
179
- elsif defined?(@resolver_class) && @resolver_class
180
- @resolver_class.get_field_argument(argument_name, context)
181
- else
182
- nil
183
- end
229
+ if (arg_config = own_arguments[argument_name]) && (visible_arg = Warden.visible_entry?(:visible_argument?, arg_config, context, warden))
230
+ visible_arg
231
+ elsif defined?(@resolver_class) && @resolver_class
232
+ @resolver_class.get_field_argument(argument_name, context)
184
233
  else
185
- for ancestor in ancestors
186
- if ancestor.respond_to?(:own_arguments) &&
187
- (a = ancestor.own_arguments[argument_name]) &&
188
- (a = Warden.visible_entry?(:visible_argument?, a, context, warden))
189
- return a
190
- end
191
- end
192
234
  nil
193
235
  end
194
236
  end
@@ -209,7 +251,7 @@ module GraphQL
209
251
  # @return [Interpreter::Arguments, Execution::Lazy<Interpeter::Arguments>]
210
252
  def coerce_arguments(parent_object, values, context, &block)
211
253
  # Cache this hash to avoid re-merging it
212
- arg_defns = self.arguments(context)
254
+ arg_defns = context.warden.arguments(self)
213
255
  total_args_count = arg_defns.size
214
256
 
215
257
  finished_args = nil
@@ -223,7 +265,7 @@ module GraphQL
223
265
  argument_values = {}
224
266
  resolved_args_count = 0
225
267
  raised_error = false
226
- arg_defns.each do |arg_name, arg_defn|
268
+ arg_defns.each do |arg_defn|
227
269
  context.dataloader.append_job do
228
270
  begin
229
271
  arg_defn.coerce_into_values(parent_object, values, context, argument_values)
@@ -265,7 +307,12 @@ module GraphQL
265
307
  # but not for directives.
266
308
  # TODO apply static validations on schema definitions?
267
309
  def validate_directive_argument(arg_defn, value)
268
- if arg_defn.owner.is_a?(Class) && arg_defn.owner < GraphQL::Schema::Directive
310
+ # this is only implemented on directives.
311
+ nil
312
+ end
313
+
314
+ module HasDirectiveArguments
315
+ def validate_directive_argument(arg_defn, value)
269
316
  if value.nil? && arg_defn.type.non_null?
270
317
  raise ArgumentError, "#{arg_defn.path} is required, but no value was given"
271
318
  end
@@ -366,7 +413,7 @@ module GraphQL
366
413
  end
367
414
  end
368
415
 
369
- NO_ARGUMENTS = {}.freeze
416
+ NO_ARGUMENTS = GraphQL::EmptyObjects::EMPTY_HASH
370
417
  def own_arguments
371
418
  @own_arguments || NO_ARGUMENTS
372
419
  end
@@ -3,6 +3,16 @@ module GraphQL
3
3
  class Schema
4
4
  class Member
5
5
  module HasAstNode
6
+ def self.extended(child_cls)
7
+ super
8
+ child_cls.ast_node = nil
9
+ end
10
+
11
+ def inherited(child_cls)
12
+ super
13
+ child_cls.ast_node = nil
14
+ end
15
+
6
16
  # If this schema was parsed from a `.graphql` file (or other SDL),
7
17
  # this is the AST node that defined this part of the schema.
8
18
  def ast_node(new_ast_node = nil)
@@ -14,6 +24,8 @@ module GraphQL
14
24
  nil
15
25
  end
16
26
  end
27
+
28
+ attr_writer :ast_node
17
29
  end
18
30
  end
19
31
  end
@@ -5,17 +5,16 @@ module GraphQL
5
5
  class Member
6
6
  module HasDeprecationReason
7
7
  # @return [String, nil] Explains why this member was deprecated (if present, this will be marked deprecated in introspection)
8
- def deprecation_reason
9
- dir = self.directives.find { |d| d.is_a?(GraphQL::Schema::Directive::Deprecated) }
10
- dir && dir.arguments[:reason] # rubocop:disable Development/ContextIsPassedCop -- definition-related
11
- end
8
+ attr_reader :deprecation_reason
12
9
 
13
10
  # Set the deprecation reason for this member, or remove it by assigning `nil`
14
11
  # @param text [String, nil]
15
12
  def deprecation_reason=(text)
13
+ @deprecation_reason = text
16
14
  if text.nil?
17
15
  remove_directive(GraphQL::Schema::Directive::Deprecated)
18
16
  else
17
+ # This removes a previously-attached directive, if there is one:
19
18
  directive(GraphQL::Schema::Directive::Deprecated, reason: text)
20
19
  end
21
20
  end