graphql 2.0.20 → 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 (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/backtrace/trace.rb +96 -0
  3. data/lib/graphql/backtrace.rb +6 -1
  4. data/lib/graphql/execution/interpreter/arguments.rb +1 -1
  5. data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
  6. data/lib/graphql/execution/interpreter/runtime.rb +200 -161
  7. data/lib/graphql/execution/interpreter.rb +1 -1
  8. data/lib/graphql/filter.rb +7 -2
  9. data/lib/graphql/language/document_from_schema_definition.rb +25 -9
  10. data/lib/graphql/language/nodes.rb +2 -2
  11. data/lib/graphql/language/parser.rb +475 -458
  12. data/lib/graphql/language/parser.y +5 -1
  13. data/lib/graphql/pagination/connection.rb +5 -5
  14. data/lib/graphql/query/context.rb +13 -12
  15. data/lib/graphql/query/null_context.rb +1 -1
  16. data/lib/graphql/query.rb +9 -5
  17. data/lib/graphql/schema/argument.rb +7 -9
  18. data/lib/graphql/schema/build_from_definition.rb +15 -3
  19. data/lib/graphql/schema/enum_value.rb +2 -5
  20. data/lib/graphql/schema/field.rb +14 -13
  21. data/lib/graphql/schema/field_extension.rb +1 -4
  22. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  23. data/lib/graphql/schema/member/has_arguments.rb +1 -1
  24. data/lib/graphql/schema/member/has_directives.rb +4 -6
  25. data/lib/graphql/schema/member/has_fields.rb +80 -36
  26. data/lib/graphql/schema/member/has_validators.rb +2 -2
  27. data/lib/graphql/schema/resolver.rb +4 -4
  28. data/lib/graphql/schema/validator.rb +1 -1
  29. data/lib/graphql/schema/warden.rb +3 -1
  30. data/lib/graphql/schema.rb +40 -11
  31. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  32. data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
  33. data/lib/graphql/tracing/appsignal_trace.rb +6 -0
  34. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  35. data/lib/graphql/tracing/notifications_trace.rb +2 -1
  36. data/lib/graphql/tracing/platform_trace.rb +21 -19
  37. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
  38. data/lib/graphql/tracing/trace.rb +75 -0
  39. data/lib/graphql/tracing.rb +3 -123
  40. data/lib/graphql/version.rb +1 -1
  41. data/lib/graphql.rb +4 -0
  42. metadata +5 -2
@@ -284,7 +284,11 @@ rule
284
284
  | directive_definition
285
285
 
286
286
  schema_definition:
287
- SCHEMA directives_list_opt LCURLY operation_type_definition_list RCURLY { result = make_node(:SchemaDefinition, position_source: val[0], definition_line: val[0][1], directives: val[1], **val[3]) }
287
+ SCHEMA directives_list_opt operation_type_definition_list_opt { result = make_node(:SchemaDefinition, position_source: val[0], definition_line: val[0][1], directives: val[1], **val[2]) }
288
+
289
+ operation_type_definition_list_opt:
290
+ /* none */ { result = {} }
291
+ | LCURLY operation_type_definition_list RCURLY { result = val[1] }
288
292
 
289
293
  operation_type_definition_list:
290
294
  operation_type_definition
@@ -58,7 +58,7 @@ module GraphQL
58
58
  # @param arguments [Hash] The arguments to the field that returned the collection wrapped by this connection
59
59
  # @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given and no `default_page_size` is set.
60
60
  # @param default_page_size [Integer, nil] A configured value to determine the result size when neither first or last are given.
61
- def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: :not_given, default_page_size: :not_given, last: nil, before: nil, edge_class: nil, arguments: nil)
61
+ def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, last: nil, before: nil, edge_class: nil, arguments: nil)
62
62
  @items = items
63
63
  @parent = parent
64
64
  @context = context
@@ -71,14 +71,14 @@ module GraphQL
71
71
  @edge_class = edge_class || self.class::Edge
72
72
  # This is only true if the object was _initialized_ with an override
73
73
  # or if one is assigned later.
74
- @has_max_page_size_override = max_page_size != :not_given
75
- @max_page_size = if max_page_size == :not_given
74
+ @has_max_page_size_override = max_page_size != NOT_CONFIGURED
75
+ @max_page_size = if max_page_size == NOT_CONFIGURED
76
76
  nil
77
77
  else
78
78
  max_page_size
79
79
  end
80
- @has_default_page_size_override = default_page_size != :not_given
81
- @default_page_size = if default_page_size == :not_given
80
+ @has_default_page_size_override = default_page_size != NOT_CONFIGURED
81
+ @default_page_size = if default_page_size == NOT_CONFIGURED
82
82
  nil
83
83
  else
84
84
  default_page_size
@@ -91,8 +91,8 @@ module GraphQL
91
91
  end
92
92
 
93
93
  class ScopedContext
94
- NO_PATH = [].freeze
95
- NO_CONTEXT = {}.freeze
94
+ NO_PATH = GraphQL::EmptyObjects::EMPTY_ARRAY
95
+ NO_CONTEXT = GraphQL::EmptyObjects::EMPTY_HASH
96
96
 
97
97
  def initialize(query_context)
98
98
  @query_context = query_context
@@ -226,8 +226,8 @@ module GraphQL
226
226
  if key == :current_path
227
227
  current_path
228
228
  else
229
- thread_info = Thread.current[:__graphql_runtime_info]
230
- thread_info && thread_info[key]
229
+ (current_runtime_state = Thread.current[:__graphql_runtime_info]) &&
230
+ (current_runtime_state.public_send(key))
231
231
  end
232
232
  else
233
233
  # not found
@@ -236,11 +236,11 @@ module GraphQL
236
236
  end
237
237
 
238
238
  def current_path
239
- thread_info = Thread.current[:__graphql_runtime_info]
240
- path = thread_info &&
241
- (result = thread_info[:current_result]) &&
239
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
240
+ path = current_runtime_state &&
241
+ (result = current_runtime_state.current_result) &&
242
242
  (result.path)
243
- if path && (rn = thread_info[:current_result_name])
243
+ if path && (rn = current_runtime_state.current_result_name)
244
244
  path = path.dup
245
245
  path.push(rn)
246
246
  end
@@ -259,8 +259,8 @@ module GraphQL
259
259
 
260
260
  def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
261
261
  if RUNTIME_METADATA_KEYS.include?(key)
262
- (thread_info = Thread.current[:__graphql_runtime_info]) &&
263
- thread_info[key]
262
+ (runtime = Thread.current[:__graphql_runtime_info]) &&
263
+ (runtime.public_send(key))
264
264
  elsif @scoped_context.key?(key)
265
265
  scoped_context[key]
266
266
  elsif @provided_values.key?(key)
@@ -276,8 +276,9 @@ module GraphQL
276
276
 
277
277
  def dig(key, *other_keys)
278
278
  if RUNTIME_METADATA_KEYS.include?(key)
279
- (thread_info = Thread.current[:__graphql_runtime_info]).key?(key) &&
280
- thread_info.dig(key, *other_keys)
279
+ (current_runtime_state = Thread.current[:__graphql_runtime_info]) &&
280
+ (obj = current_runtime_state.public_send(key)) &&
281
+ obj.dig(*other_keys)
281
282
  elsif @scoped_context.key?(key)
282
283
  @scoped_context.dig(key, *other_keys)
283
284
  else
@@ -24,7 +24,7 @@ module GraphQL
24
24
  @dataloader = GraphQL::Dataloader::NullDataloader.new
25
25
  @schema = NullSchema
26
26
  @warden = NullWarden.new(
27
- GraphQL::Filter.new,
27
+ GraphQL::Filter.new(silence_deprecation_warning: true),
28
28
  context: self,
29
29
  schema: @schema,
30
30
  )
data/lib/graphql/query.rb CHANGED
@@ -100,12 +100,16 @@ module GraphQL
100
100
 
101
101
  # Support `ctx[:backtrace] = true` for wrapping backtraces
102
102
  if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
103
- context_tracers += [GraphQL::Backtrace::Tracer]
104
- @tracers << GraphQL::Backtrace::Tracer
103
+ if schema.trace_class <= GraphQL::Tracing::LegacyTrace
104
+ context_tracers += [GraphQL::Backtrace::Tracer]
105
+ @tracers << GraphQL::Backtrace::Tracer
106
+ elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
107
+ raise "Invariant: `backtrace: true` should have provided a trace class with Backtrace mixed in, but it didnt. (Found: #{current_trace.class.ancestors}). This is a bug in GraphQL-Ruby, please report it on GitHub."
108
+ end
105
109
  end
106
110
 
107
111
  if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::LegacyTrace)
108
- raise ArgumentError, "context[:tracers] and context[:backtrace] are not supported without `tracer_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
112
+ raise ArgumentError, "context[:tracers] are not supported without `trace_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
109
113
  end
110
114
 
111
115
 
@@ -318,8 +322,8 @@ module GraphQL
318
322
  # @param value [Object] Any runtime value
319
323
  # @return [GraphQL::ObjectType, nil] The runtime type of `value` from {Schema#resolve_type}
320
324
  # @see {#possible_types} to apply filtering from `only` / `except`
321
- def resolve_type(abstract_type, value = :__undefined__)
322
- if value.is_a?(Symbol) && value == :__undefined__
325
+ def resolve_type(abstract_type, value = NOT_CONFIGURED)
326
+ if value.is_a?(Symbol) && value == NOT_CONFIGURED
323
327
  # Old method signature
324
328
  value = abstract_type
325
329
  abstract_type = nil
@@ -7,9 +7,7 @@ module GraphQL
7
7
  include GraphQL::Schema::Member::HasDirectives
8
8
  include GraphQL::Schema::Member::HasDeprecationReason
9
9
  include GraphQL::Schema::Member::HasValidators
10
- include GraphQL::Schema::FindInheritedValue::EmptyObjects
11
-
12
- NO_DEFAULT = :__no_default__
10
+ include GraphQL::EmptyObjects
13
11
 
14
12
  # @return [String] the GraphQL name for this argument, camelized unless `camelize: false` is provided
15
13
  attr_reader :name
@@ -20,8 +18,8 @@ module GraphQL
20
18
 
21
19
  # @param new_prepare [Method, Proc]
22
20
  # @return [Symbol] A method or proc to call to transform this value before sending it to field resolution method
23
- def prepare(new_prepare = NO_DEFAULT)
24
- if new_prepare != NO_DEFAULT
21
+ def prepare(new_prepare = NOT_CONFIGURED)
22
+ if new_prepare != NOT_CONFIGURED
25
23
  @prepare = new_prepare
26
24
  end
27
25
  @prepare
@@ -52,7 +50,7 @@ module GraphQL
52
50
  # @param deprecation_reason [String]
53
51
  # @param validates [Hash, nil] Options for building validators, if any should be applied
54
52
  # @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
55
- def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
53
+ def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
56
54
  arg_name ||= name
57
55
  @name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
58
56
  @type_expr = type_expr || type
@@ -104,8 +102,8 @@ module GraphQL
104
102
 
105
103
  # @param default_value [Object] The value to use when the client doesn't provide one
106
104
  # @return [Object] the value used when the client doesn't provide a value for this argument
107
- def default_value(new_default_value = NO_DEFAULT)
108
- if new_default_value != NO_DEFAULT
105
+ def default_value(new_default_value = NOT_CONFIGURED)
106
+ if new_default_value != NOT_CONFIGURED
109
107
  @default_value = new_default_value
110
108
  end
111
109
  @default_value
@@ -113,7 +111,7 @@ module GraphQL
113
111
 
114
112
  # @return [Boolean] True if this argument has a default value
115
113
  def default_value?
116
- @default_value != NO_DEFAULT
114
+ @default_value != NOT_CONFIGURED
117
115
  end
118
116
 
119
117
  def replace_null_with_default?
@@ -21,6 +21,7 @@ module GraphQL
21
21
 
22
22
  # @api private
23
23
  module Builder
24
+ include GraphQL::EmptyObjects
24
25
  extend self
25
26
 
26
27
  def build(schema_superclass, document, default_resolve:, using: {}, relay:)
@@ -99,6 +100,16 @@ module GraphQL
99
100
  raise InvalidDocumentError.new("Specified subscription type \"#{schema_definition.subscription}\" not found in document.") unless types[schema_definition.subscription]
100
101
  subscription_root_type = types[schema_definition.subscription]
101
102
  end
103
+
104
+ if schema_definition.query.nil? &&
105
+ schema_definition.mutation.nil? &&
106
+ schema_definition.subscription.nil?
107
+ # This schema may have been given with directives only,
108
+ # check for defaults:
109
+ query_root_type = types['Query']
110
+ mutation_root_type = types['Mutation']
111
+ subscription_root_type = types['Subscription']
112
+ end
102
113
  else
103
114
  query_root_type = types['Query']
104
115
  mutation_root_type = types['Mutation']
@@ -107,6 +118,8 @@ module GraphQL
107
118
 
108
119
  raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
109
120
 
121
+ builder = self
122
+
110
123
  schema_class = Class.new(schema_superclass) do
111
124
  begin
112
125
  # Add these first so that there's some chance of resolving late-bound types
@@ -134,6 +147,7 @@ module GraphQL
134
147
 
135
148
  if schema_definition
136
149
  ast_node(schema_definition)
150
+ builder.build_directives(self, schema_definition, type_resolver)
137
151
  end
138
152
 
139
153
  using.each do |plugin, options|
@@ -361,8 +375,6 @@ module GraphQL
361
375
  end
362
376
  end
363
377
 
364
- NO_DEFAULT_VALUE = {}.freeze
365
-
366
378
  def build_arguments(type_class, arguments, type_resolver)
367
379
  builder = self
368
380
 
@@ -370,7 +382,7 @@ module GraphQL
370
382
  default_value_kwargs = if !argument_defn.default_value.nil?
371
383
  { default_value: builder.build_default_value(argument_defn.default_value) }
372
384
  else
373
- NO_DEFAULT_VALUE
385
+ EMPTY_HASH
374
386
  end
375
387
 
376
388
  type_class.argument(
@@ -25,19 +25,16 @@ module GraphQL
25
25
  include GraphQL::Schema::Member::HasDirectives
26
26
  include GraphQL::Schema::Member::HasDeprecationReason
27
27
 
28
- UNDEFINED_VALUE = Object.new.freeze
29
- private_constant :UNDEFINED_VALUE
30
-
31
28
  attr_reader :graphql_name
32
29
 
33
30
  # @return [Class] The enum type that owns this value
34
31
  attr_reader :owner
35
32
 
36
- def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: UNDEFINED_VALUE, deprecation_reason: nil, &block)
33
+ def initialize(graphql_name, desc = nil, owner:, ast_node: nil, directives: nil, description: nil, value: NOT_CONFIGURED, deprecation_reason: nil, &block)
37
34
  @graphql_name = graphql_name.to_s
38
35
  GraphQL::NameValidator.validate!(@graphql_name)
39
36
  @description = desc || description
40
- @value = value === UNDEFINED_VALUE ? @graphql_name : value
37
+ @value = value === NOT_CONFIGURED ? @graphql_name : value
41
38
  if deprecation_reason
42
39
  self.deprecation_reason = deprecation_reason
43
40
  end
@@ -11,7 +11,7 @@ module GraphQL
11
11
  include GraphQL::Schema::Member::HasPath
12
12
  include GraphQL::Schema::Member::HasValidators
13
13
  extend GraphQL::Schema::FindInheritedValue
14
- include GraphQL::Schema::FindInheritedValue::EmptyObjects
14
+ include GraphQL::EmptyObjects
15
15
  include GraphQL::Schema::Member::HasDirectives
16
16
  include GraphQL::Schema::Member::HasDeprecationReason
17
17
 
@@ -219,7 +219,7 @@ module GraphQL
219
219
  # @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
220
220
  # @param validates [Array<Hash>] Configurations for validating this field
221
221
  # @fallback_value [Object] A fallback value if the method is not defined
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_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)
223
223
  if name.nil?
224
224
  raise ArgumentError, "missing first `name` argument or keyword `name:`"
225
225
  end
@@ -608,15 +608,16 @@ module GraphQL
608
608
  # The resolver _instance_ will check itself during `resolve()`
609
609
  @resolver_class.authorized?(object, context)
610
610
  else
611
- if (arg_values = context[:current_arguments])
612
- # ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
613
- using_arg_values = true
614
- arg_values = arg_values.argument_values
615
- else
616
- arg_values = args
617
- using_arg_values = false
618
- end
619
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
+
620
621
  args = context.warden.arguments(self)
621
622
  args.each do |arg|
622
623
  arg_key = arg.keyword
@@ -684,7 +685,7 @@ module GraphQL
684
685
  if hash_value == false
685
686
  hash_value
686
687
  else
687
- hash_value || (@fallback_value != :not_given ? @fallback_value : nil)
688
+ hash_value || (@fallback_value != NOT_CONFIGURED ? @fallback_value : nil)
688
689
  end
689
690
  elsif obj.respond_to?(resolver_method)
690
691
  method_to_call = resolver_method
@@ -702,7 +703,7 @@ module GraphQL
702
703
  inner_object[@method_sym]
703
704
  elsif inner_object.key?(@method_str)
704
705
  inner_object[@method_str]
705
- elsif @fallback_value != :not_given
706
+ elsif @fallback_value != NOT_CONFIGURED
706
707
  @fallback_value
707
708
  else
708
709
  nil
@@ -715,7 +716,7 @@ module GraphQL
715
716
  else
716
717
  inner_object.public_send(@method_sym)
717
718
  end
718
- elsif @fallback_value != :not_given
719
+ elsif @fallback_value != NOT_CONFIGURED
719
720
  @fallback_value
720
721
  else
721
722
  raise <<-ERR
@@ -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
@@ -413,7 +413,7 @@ module GraphQL
413
413
  end
414
414
  end
415
415
 
416
- NO_ARGUMENTS = {}.freeze
416
+ NO_ARGUMENTS = GraphQL::EmptyObjects::EMPTY_HASH
417
417
  def own_arguments
418
418
  @own_arguments || NO_ARGUMENTS
419
419
  end
@@ -33,8 +33,6 @@ module GraphQL
33
33
  nil
34
34
  end
35
35
 
36
- NO_DIRECTIVES = [].freeze
37
-
38
36
  def directives
39
37
  HasDirectives.get_directives(self, @own_directives, :directives)
40
38
  end
@@ -55,7 +53,7 @@ module GraphQL
55
53
  inherited_directives = if schema_member.superclass.respond_to?(directives_method)
56
54
  get_directives(schema_member.superclass, schema_member.superclass.public_send(directives_method), directives_method)
57
55
  else
58
- NO_DIRECTIVES
56
+ GraphQL::EmptyObjects::EMPTY_ARRAY
59
57
  end
60
58
  if inherited_directives.any? && directives
61
59
  dirs = []
@@ -67,7 +65,7 @@ module GraphQL
67
65
  elsif inherited_directives.any?
68
66
  inherited_directives
69
67
  else
70
- NO_DIRECTIVES
68
+ GraphQL::EmptyObjects::EMPTY_ARRAY
71
69
  end
72
70
  when Module
73
71
  dirs = nil
@@ -82,9 +80,9 @@ module GraphQL
82
80
  dirs ||= []
83
81
  merge_directives(dirs, directives)
84
82
  end
85
- dirs || NO_DIRECTIVES
83
+ dirs || GraphQL::EmptyObjects::EMPTY_ARRAY
86
84
  when HasDirectives
87
- directives || NO_DIRECTIVES
85
+ directives || GraphQL::EmptyObjects::EMPTY_ARRAY
88
86
  else
89
87
  raise "Invariant: how could #{schema_member} not be a Class, Module, or instance of HasDirectives?"
90
88
  end
@@ -14,42 +14,6 @@ module GraphQL
14
14
  field_defn
15
15
  end
16
16
 
17
- # @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
18
- def fields(context = GraphQL::Query::NullContext)
19
- warden = Warden.from_context(context)
20
- is_object = self.respond_to?(:kind) && self.kind.object?
21
- # Local overrides take precedence over inherited fields
22
- visible_fields = {}
23
- for ancestor in ancestors
24
- if ancestor.respond_to?(:own_fields) &&
25
- (is_object ? visible_interface_implementation?(ancestor, context, warden) : true)
26
-
27
- ancestor.own_fields.each do |field_name, fields_entry|
28
- # Choose the most local definition that passes `.visible?` --
29
- # stop checking for fields by name once one has been found.
30
- if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
31
- visible_fields[field_name] = f
32
- end
33
- end
34
- end
35
- end
36
- visible_fields
37
- end
38
-
39
- def get_field(field_name, context = GraphQL::Query::NullContext)
40
- warden = Warden.from_context(context)
41
- is_object = self.respond_to?(:kind) && self.kind.object?
42
- for ancestor in ancestors
43
- if ancestor.respond_to?(:own_fields) &&
44
- (is_object ? visible_interface_implementation?(ancestor, context, warden) : true) &&
45
- (f_entry = ancestor.own_fields[field_name]) &&
46
- (f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
47
- return f
48
- end
49
- end
50
- nil
51
- end
52
-
53
17
  # A list of Ruby keywords.
54
18
  #
55
19
  # @api private
@@ -132,6 +96,86 @@ module GraphQL
132
96
  all_fields
133
97
  end
134
98
 
99
+ module InterfaceMethods
100
+ def get_field(field_name, context = GraphQL::Query::NullContext)
101
+ warden = Warden.from_context(context)
102
+ for ancestor in ancestors
103
+ if ancestor.respond_to?(:own_fields) &&
104
+ (f_entry = ancestor.own_fields[field_name]) &&
105
+ (f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
106
+ return f
107
+ end
108
+ end
109
+ nil
110
+ end
111
+
112
+ # @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
113
+ def fields(context = GraphQL::Query::NullContext)
114
+ warden = Warden.from_context(context)
115
+ # Local overrides take precedence over inherited fields
116
+ visible_fields = {}
117
+ for ancestor in ancestors
118
+ if ancestor.respond_to?(:own_fields)
119
+ ancestor.own_fields.each do |field_name, fields_entry|
120
+ # Choose the most local definition that passes `.visible?` --
121
+ # stop checking for fields by name once one has been found.
122
+ if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
123
+ visible_fields[field_name] = f
124
+ end
125
+ end
126
+ end
127
+ end
128
+ visible_fields
129
+ end
130
+ end
131
+
132
+ module ObjectMethods
133
+ def get_field(field_name, context = GraphQL::Query::NullContext)
134
+ # Objects need to check that the interface implementation is visible, too
135
+ warden = Warden.from_context(context)
136
+ for ancestor in ancestors
137
+ if ancestor.respond_to?(:own_fields) &&
138
+ visible_interface_implementation?(ancestor, context, warden) &&
139
+ (f_entry = ancestor.own_fields[field_name]) &&
140
+ (f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
141
+ return f
142
+ end
143
+ end
144
+ nil
145
+ end
146
+
147
+ # @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
148
+ def fields(context = GraphQL::Query::NullContext)
149
+ # Objects need to check that the interface implementation is visible, too
150
+ warden = Warden.from_context(context)
151
+ # Local overrides take precedence over inherited fields
152
+ visible_fields = {}
153
+ for ancestor in ancestors
154
+ if ancestor.respond_to?(:own_fields) && visible_interface_implementation?(ancestor, context, warden)
155
+ ancestor.own_fields.each do |field_name, fields_entry|
156
+ # Choose the most local definition that passes `.visible?` --
157
+ # stop checking for fields by name once one has been found.
158
+ if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
159
+ visible_fields[field_name] = f
160
+ end
161
+ end
162
+ end
163
+ end
164
+ visible_fields
165
+ end
166
+ end
167
+
168
+ def self.included(child_class)
169
+ # Included in an interface definition methods module
170
+ child_class.include(InterfaceMethods)
171
+ super
172
+ end
173
+
174
+ def self.extended(child_class)
175
+ child_class.extend(ObjectMethods)
176
+ super
177
+ end
178
+
135
179
  private
136
180
 
137
181
  def inherited(subclass)
@@ -3,7 +3,7 @@ module GraphQL
3
3
  class Schema
4
4
  class Member
5
5
  module HasValidators
6
- include Schema::FindInheritedValue::EmptyObjects
6
+ include GraphQL::EmptyObjects
7
7
 
8
8
  # Build {GraphQL::Schema::Validator}s based on the given configuration
9
9
  # and use them for this schema member
@@ -28,7 +28,7 @@ module GraphQL
28
28
  end
29
29
 
30
30
  module ClassValidators
31
- include Schema::FindInheritedValue::EmptyObjects
31
+ include GraphQL::EmptyObjects
32
32
 
33
33
  def validators
34
34
  inherited_validators = superclass.validators
@@ -311,8 +311,8 @@ module GraphQL
311
311
  # (`nil` means "unlimited max page size".)
312
312
  # @param max_page_size [Integer, nil] Set a new value
313
313
  # @return [Integer, nil] The `max_page_size` assigned to fields that use this resolver
314
- def max_page_size(new_max_page_size = :not_given)
315
- if new_max_page_size != :not_given
314
+ def max_page_size(new_max_page_size = NOT_CONFIGURED)
315
+ if new_max_page_size != NOT_CONFIGURED
316
316
  @max_page_size = new_max_page_size
317
317
  elsif defined?(@max_page_size)
318
318
  @max_page_size
@@ -332,8 +332,8 @@ module GraphQL
332
332
  # (`nil` means "unlimited default page size".)
333
333
  # @param default_page_size [Integer, nil] Set a new value
334
334
  # @return [Integer, nil] The `default_page_size` assigned to fields that use this resolver
335
- def default_page_size(new_default_page_size = :not_given)
336
- if new_default_page_size != :not_given
335
+ def default_page_size(new_default_page_size = NOT_CONFIGURED)
336
+ if new_default_page_size != NOT_CONFIGURED
337
337
  @default_page_size = new_default_page_size
338
338
  elsif defined?(@default_page_size)
339
339
  @default_page_size
@@ -102,7 +102,7 @@ module GraphQL
102
102
 
103
103
  self.all_validators = {}
104
104
 
105
- include Schema::FindInheritedValue::EmptyObjects
105
+ include GraphQL::EmptyObjects
106
106
 
107
107
  class ValidationFailedError < GraphQL::ExecutionError
108
108
  attr_reader :errors
@@ -38,7 +38,9 @@ module GraphQL
38
38
  # @api private
39
39
  class Warden
40
40
  def self.from_context(context)
41
- (context.respond_to?(:warden) && context.warden) || PassThruWarden
41
+ context.warden # this might be a hash which won't respond to this
42
+ rescue
43
+ PassThruWarden
42
44
  end
43
45
 
44
46
  # @param visibility_method [Symbol] a Warden method to call for this entry