graphql 2.0.20 → 2.0.22

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 (50) 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 +33 -33
  6. data/lib/graphql/execution/interpreter/runtime.rb +274 -209
  7. data/lib/graphql/execution/interpreter.rb +2 -3
  8. data/lib/graphql/execution/lookahead.rb +1 -1
  9. data/lib/graphql/filter.rb +8 -2
  10. data/lib/graphql/language/document_from_schema_definition.rb +37 -17
  11. data/lib/graphql/language/lexer.rb +5 -3
  12. data/lib/graphql/language/nodes.rb +2 -2
  13. data/lib/graphql/language/parser.rb +475 -458
  14. data/lib/graphql/language/parser.y +5 -1
  15. data/lib/graphql/pagination/connection.rb +5 -5
  16. data/lib/graphql/query/context.rb +22 -12
  17. data/lib/graphql/query/null_context.rb +4 -1
  18. data/lib/graphql/query.rb +25 -11
  19. data/lib/graphql/schema/argument.rb +12 -14
  20. data/lib/graphql/schema/build_from_definition.rb +15 -3
  21. data/lib/graphql/schema/enum_value.rb +2 -5
  22. data/lib/graphql/schema/field/connection_extension.rb +1 -1
  23. data/lib/graphql/schema/field.rb +17 -16
  24. data/lib/graphql/schema/field_extension.rb +1 -4
  25. data/lib/graphql/schema/find_inherited_value.rb +2 -7
  26. data/lib/graphql/schema/input_object.rb +1 -1
  27. data/lib/graphql/schema/member/has_arguments.rb +10 -8
  28. data/lib/graphql/schema/member/has_directives.rb +4 -6
  29. data/lib/graphql/schema/member/has_fields.rb +80 -36
  30. data/lib/graphql/schema/member/has_validators.rb +2 -2
  31. data/lib/graphql/schema/object.rb +1 -1
  32. data/lib/graphql/schema/printer.rb +3 -1
  33. data/lib/graphql/schema/relay_classic_mutation.rb +1 -1
  34. data/lib/graphql/schema/resolver.rb +8 -8
  35. data/lib/graphql/schema/validator.rb +1 -1
  36. data/lib/graphql/schema/warden.rb +11 -3
  37. data/lib/graphql/schema.rb +41 -12
  38. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
  39. data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
  40. data/lib/graphql/tracing/appsignal_trace.rb +6 -0
  41. data/lib/graphql/tracing/legacy_trace.rb +65 -0
  42. data/lib/graphql/tracing/notifications_trace.rb +5 -1
  43. data/lib/graphql/tracing/platform_trace.rb +21 -19
  44. data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
  45. data/lib/graphql/tracing/trace.rb +75 -0
  46. data/lib/graphql/tracing.rb +4 -123
  47. data/lib/graphql/version.rb +1 -1
  48. data/lib/graphql.rb +4 -0
  49. data/readme.md +1 -1
  50. metadata +6 -3
@@ -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,9 @@ 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
+ (query_runtime_state = current_runtime_state[@query]) &&
231
+ (query_runtime_state.public_send(key))
231
232
  end
232
233
  else
233
234
  # not found
@@ -236,11 +237,13 @@ module GraphQL
236
237
  end
237
238
 
238
239
  def current_path
239
- thread_info = Thread.current[:__graphql_runtime_info]
240
- path = thread_info &&
241
- (result = thread_info[:current_result]) &&
240
+ current_runtime_state = Thread.current[:__graphql_runtime_info]
241
+ query_runtime_state = current_runtime_state && current_runtime_state[@query]
242
+
243
+ path = query_runtime_state &&
244
+ (result = query_runtime_state.current_result) &&
242
245
  (result.path)
243
- if path && (rn = thread_info[:current_result_name])
246
+ if path && (rn = query_runtime_state.current_result_name)
244
247
  path = path.dup
245
248
  path.push(rn)
246
249
  end
@@ -259,8 +262,9 @@ module GraphQL
259
262
 
260
263
  def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
261
264
  if RUNTIME_METADATA_KEYS.include?(key)
262
- (thread_info = Thread.current[:__graphql_runtime_info]) &&
263
- thread_info[key]
265
+ (runtime = Thread.current[:__graphql_runtime_info]) &&
266
+ (query_runtime_state = runtime[@query]) &&
267
+ (query_runtime_state.public_send(key))
264
268
  elsif @scoped_context.key?(key)
265
269
  scoped_context[key]
266
270
  elsif @provided_values.key?(key)
@@ -276,8 +280,14 @@ module GraphQL
276
280
 
277
281
  def dig(key, *other_keys)
278
282
  if RUNTIME_METADATA_KEYS.include?(key)
279
- (thread_info = Thread.current[:__graphql_runtime_info]).key?(key) &&
280
- thread_info.dig(key, *other_keys)
283
+ (current_runtime_state = Thread.current[:__graphql_runtime_info]) &&
284
+ (query_runtime_state = current_runtime_state[@query]) &&
285
+ (obj = query_runtime_state.public_send(key)) &&
286
+ if other_keys.empty?
287
+ obj
288
+ else
289
+ obj.dig(*other_keys)
290
+ end
281
291
  elsif @scoped_context.key?(key)
282
292
  @scoped_context.dig(key, *other_keys)
283
293
  else
@@ -12,6 +12,9 @@ module GraphQL
12
12
  end
13
13
 
14
14
  class NullQuery
15
+ def after_lazy(value)
16
+ yield(value)
17
+ end
15
18
  end
16
19
 
17
20
  class NullSchema < GraphQL::Schema
@@ -24,7 +27,7 @@ module GraphQL
24
27
  @dataloader = GraphQL::Dataloader::NullDataloader.new
25
28
  @schema = NullSchema
26
29
  @warden = NullWarden.new(
27
- GraphQL::Filter.new,
30
+ GraphQL::Filter.new(silence_deprecation_warning: true),
28
31
  context: self,
29
32
  schema: @schema,
30
33
  )
data/lib/graphql/query.rb CHANGED
@@ -87,7 +87,9 @@ module GraphQL
87
87
  # Even if `variables: nil` is passed, use an empty hash for simpler logic
88
88
  variables ||= {}
89
89
  @schema = schema
90
- @filter = schema.default_filter.merge(except: except, only: only)
90
+ if only || except
91
+ merge_filters(except: except, only: only)
92
+ end
91
93
  @context = schema.context_class.new(query: self, object: root_value, values: context)
92
94
  @warden = warden
93
95
  @subscription_topic = subscription_topic
@@ -100,12 +102,16 @@ module GraphQL
100
102
 
101
103
  # Support `ctx[:backtrace] = true` for wrapping backtraces
102
104
  if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
103
- context_tracers += [GraphQL::Backtrace::Tracer]
104
- @tracers << GraphQL::Backtrace::Tracer
105
+ if schema.trace_class <= GraphQL::Tracing::LegacyTrace
106
+ context_tracers += [GraphQL::Backtrace::Tracer]
107
+ @tracers << GraphQL::Backtrace::Tracer
108
+ elsif !(current_trace.class <= GraphQL::Backtrace::Trace)
109
+ 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."
110
+ end
105
111
  end
106
112
 
107
113
  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."
114
+ raise ArgumentError, "context[:tracers] are not supported without `trace_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
109
115
  end
110
116
 
111
117
 
@@ -147,11 +153,6 @@ module GraphQL
147
153
 
148
154
  @result_values = nil
149
155
  @executed = false
150
-
151
- # TODO add a general way to define schema-level filters
152
- if @schema.respond_to?(:visible?)
153
- merge_filters(only: @schema.method(:visible?))
154
- end
155
156
  end
156
157
 
157
158
  # If a document was provided to `GraphQL::Schema#execute` instead of the raw query string, we will need to get it from the document
@@ -318,8 +319,8 @@ module GraphQL
318
319
  # @param value [Object] Any runtime value
319
320
  # @return [GraphQL::ObjectType, nil] The runtime type of `value` from {Schema#resolve_type}
320
321
  # @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__
322
+ def resolve_type(abstract_type, value = NOT_CONFIGURED)
323
+ if value.is_a?(Symbol) && value == NOT_CONFIGURED
323
324
  # Old method signature
324
325
  value = abstract_type
325
326
  abstract_type = nil
@@ -343,6 +344,7 @@ module GraphQL
343
344
  if @prepared_ast
344
345
  raise "Can't add filters after preparing the query"
345
346
  else
347
+ @filter ||= @schema.default_filter
346
348
  @filter = @filter.merge(only: only, except: except)
347
349
  end
348
350
  nil
@@ -357,6 +359,18 @@ module GraphQL
357
359
  schema.handle_or_reraise(context, err)
358
360
  end
359
361
 
362
+ def after_lazy(value, &block)
363
+ if !defined?(@runtime_instance)
364
+ @runtime_instance = context.namespace(:interpreter_runtime)[:runtime]
365
+ end
366
+
367
+ if @runtime_instance
368
+ @runtime_instance.minimal_after_lazy(value, &block)
369
+ else
370
+ @schema.after_lazy(value, &block)
371
+ end
372
+ end
373
+
360
374
  private
361
375
 
362
376
  def find_operation(operations, operation_name)
@@ -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?
@@ -200,8 +198,8 @@ module GraphQL
200
198
 
201
199
  def statically_coercible?
202
200
  return @statically_coercible if defined?(@statically_coercible)
203
-
204
- @statically_coercible = !@prepare.is_a?(String) && !@prepare.is_a?(Symbol)
201
+ requires_parent_object = @prepare.is_a?(String) || @prepare.is_a?(Symbol) || @own_validators
202
+ @statically_coercible = !requires_parent_object
205
203
  end
206
204
 
207
205
  # Apply the {prepare} configuration to `value`, using methods from `obj`.
@@ -266,7 +264,7 @@ module GraphQL
266
264
 
267
265
  # If this isn't lazy, then the block returns eagerly and assigns the result here
268
266
  # If it _is_ lazy, then we write the lazy to the hash, then update it later
269
- argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |resolved_coerced_value|
267
+ argument_values[arg_key] = context.query.after_lazy(coerced_value) do |resolved_coerced_value|
270
268
  owner.validate_directive_argument(self, resolved_coerced_value)
271
269
  prepared_value = begin
272
270
  prepare_value(parent_object, resolved_coerced_value, context: context)
@@ -283,7 +281,7 @@ module GraphQL
283
281
  end
284
282
 
285
283
  maybe_loaded_value = loaded_value || prepared_value
286
- context.schema.after_lazy(maybe_loaded_value) do |resolved_loaded_value|
284
+ context.query.after_lazy(maybe_loaded_value) do |resolved_loaded_value|
287
285
  # TODO code smell to access such a deeply-nested constant in a distant module
288
286
  argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
289
287
  value: resolved_loaded_value,
@@ -305,7 +303,7 @@ module GraphQL
305
303
  else
306
304
  load_method_owner.public_send(arg_load_method, coerced_value)
307
305
  end
308
- context.schema.after_lazy(custom_loaded_value) do |custom_value|
306
+ context.query.after_lazy(custom_loaded_value) do |custom_value|
309
307
  if loads
310
308
  if type.list?
311
309
  loaded_values = custom_value.each_with_index.map { |custom_val, idx|
@@ -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
@@ -26,7 +26,7 @@ module GraphQL
26
26
  # rename some inputs to avoid conflicts inside the block
27
27
  maybe_lazy = value
28
28
  value = nil
29
- context.schema.after_lazy(maybe_lazy) do |resolved_value|
29
+ context.query.after_lazy(maybe_lazy) do |resolved_value|
30
30
  value = resolved_value
31
31
  if value.is_a? GraphQL::ExecutionError
32
32
  # This isn't even going to work because context doesn't have ast_node anymore
@@ -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
@@ -235,7 +235,7 @@ module GraphQL
235
235
  @name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
236
236
 
237
237
  @description = description
238
- @type = @owner_type = @own_validators = @own_directives = @own_arguments = nil # these will be prepared later if necessary
238
+ @type = @owner_type = @own_validators = @own_directives = @own_arguments = @arguments_statically_coercible = nil # these will be prepared later if necessary
239
239
 
240
240
  self.deprecation_reason = deprecation_reason
241
241
 
@@ -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
@@ -660,7 +661,7 @@ module GraphQL
660
661
 
661
662
  Schema::Validator.validate!(validators, application_object, query_ctx, args)
662
663
 
663
- query_ctx.schema.after_lazy(self.authorized?(application_object, args, query_ctx)) do |is_authorized|
664
+ query_ctx.query.after_lazy(self.authorized?(application_object, args, query_ctx)) do |is_authorized|
664
665
  if is_authorized
665
666
  with_extensions(object, args, query_ctx) do |obj, ruby_kwargs|
666
667
  method_args = ruby_kwargs
@@ -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
@@ -832,7 +833,7 @@ ERR
832
833
  extended_args = extended[:args]
833
834
  memos = extended[:memos] || EMPTY_HASH
834
835
 
835
- ctx.schema.after_lazy(value) do |resolved_value|
836
+ ctx.query.after_lazy(value) do |resolved_value|
836
837
  idx = 0
837
838
  @extensions.each do |ext|
838
839
  memo = memos[idx]
@@ -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
@@ -211,7 +211,7 @@ module GraphQL
211
211
 
212
212
  arguments = coerce_arguments(nil, value, ctx)
213
213
 
214
- ctx.schema.after_lazy(arguments) do |resolved_arguments|
214
+ ctx.query.after_lazy(arguments) do |resolved_arguments|
215
215
  if resolved_arguments.is_a?(GraphQL::Error)
216
216
  raise resolved_arguments
217
217
  else
@@ -51,7 +51,7 @@ module GraphQL
51
51
  class_eval <<-RUBY, __FILE__, __LINE__ + 1
52
52
  def #{method_owner}load_#{arg_defn.keyword}(values, context = nil)
53
53
  argument = get_argument("#{arg_defn.graphql_name}")
54
- (context || self.context).schema.after_lazy(values) do |values2|
54
+ (context || self.context).query.after_lazy(values) do |values2|
55
55
  GraphQL::Execution::Lazy.all(values2.map { |value| load_application_object(argument, value, context || self.context) })
56
56
  end
57
57
  end
@@ -320,9 +320,11 @@ module GraphQL
320
320
  end
321
321
 
322
322
  def arguments_statically_coercible?
323
- return @arguments_statically_coercible if defined?(@arguments_statically_coercible)
324
-
325
- @arguments_statically_coercible = all_argument_definitions.all?(&:statically_coercible?)
323
+ if defined?(@arguments_statically_coercible) && !@arguments_statically_coercible.nil?
324
+ @arguments_statically_coercible
325
+ else
326
+ @arguments_statically_coercible = all_argument_definitions.all?(&:statically_coercible?)
327
+ end
326
328
  end
327
329
 
328
330
  module ArgumentClassAccessor
@@ -363,7 +365,7 @@ module GraphQL
363
365
  end
364
366
 
365
367
  def authorize_application_object(argument, id, context, loaded_application_object)
366
- context.schema.after_lazy(loaded_application_object) do |application_object|
368
+ context.query.after_lazy(loaded_application_object) do |application_object|
367
369
  if application_object.nil?
368
370
  err = GraphQL::LoadApplicationObjectFailedError.new(argument: argument, id: id, object: application_object)
369
371
  load_application_object_failed(err)
@@ -371,7 +373,7 @@ module GraphQL
371
373
  # Double-check that the located object is actually of this type
372
374
  # (Don't want to allow arbitrary access to objects this way)
373
375
  maybe_lazy_resolve_type = context.schema.resolve_type(argument.loads, application_object, context)
374
- context.schema.after_lazy(maybe_lazy_resolve_type) do |resolve_type_result|
376
+ context.query.after_lazy(maybe_lazy_resolve_type) do |resolve_type_result|
375
377
  if resolve_type_result.is_a?(Array) && resolve_type_result.size == 2
376
378
  application_object_type, application_object = resolve_type_result
377
379
  else
@@ -386,7 +388,7 @@ module GraphQL
386
388
  # This object was loaded successfully
387
389
  # and resolved to the right type,
388
390
  # now apply the `.authorized?` class method if there is one
389
- context.schema.after_lazy(application_object_type.authorized?(application_object, context)) do |authed|
391
+ context.query.after_lazy(application_object_type.authorized?(application_object, context)) do |authed|
390
392
  if authed
391
393
  application_object
392
394
  else
@@ -413,7 +415,7 @@ module GraphQL
413
415
  end
414
416
  end
415
417
 
416
- NO_ARGUMENTS = {}.freeze
418
+ NO_ARGUMENTS = GraphQL::EmptyObjects::EMPTY_HASH
417
419
  def own_arguments
418
420
  @own_arguments || NO_ARGUMENTS
419
421
  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