graphql 2.4.11 → 2.4.15

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/analyzer.rb +2 -1
  3. data/lib/graphql/analysis/visitor.rb +37 -40
  4. data/lib/graphql/analysis.rb +12 -9
  5. data/lib/graphql/backtrace/table.rb +37 -14
  6. data/lib/graphql/execution/interpreter/runtime.rb +12 -2
  7. data/lib/graphql/execution/interpreter.rb +1 -0
  8. data/lib/graphql/invalid_null_error.rb +1 -5
  9. data/lib/graphql/language/lexer.rb +7 -3
  10. data/lib/graphql/language/nodes.rb +3 -0
  11. data/lib/graphql/language/parser.rb +1 -1
  12. data/lib/graphql/language/static_visitor.rb +37 -33
  13. data/lib/graphql/language/visitor.rb +59 -55
  14. data/lib/graphql/schema/argument.rb +7 -8
  15. data/lib/graphql/schema/build_from_definition.rb +99 -53
  16. data/lib/graphql/schema/directive.rb +1 -1
  17. data/lib/graphql/schema/enum.rb +2 -2
  18. data/lib/graphql/schema/enum_value.rb +1 -1
  19. data/lib/graphql/schema/field.rb +2 -2
  20. data/lib/graphql/schema/input_object.rb +16 -16
  21. data/lib/graphql/schema/interface.rb +1 -1
  22. data/lib/graphql/schema/member/has_directives.rb +1 -1
  23. data/lib/graphql/schema/member/has_fields.rb +1 -1
  24. data/lib/graphql/schema/member/has_interfaces.rb +1 -1
  25. data/lib/graphql/schema/member/scoped.rb +1 -1
  26. data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
  27. data/lib/graphql/schema/resolver.rb +5 -1
  28. data/lib/graphql/schema.rb +6 -4
  29. data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
  30. data/lib/graphql/testing/helpers.rb +5 -2
  31. data/lib/graphql/tracing/appoptics_trace.rb +4 -0
  32. data/lib/graphql/tracing/appsignal_trace.rb +4 -0
  33. data/lib/graphql/tracing/data_dog_trace.rb +4 -0
  34. data/lib/graphql/tracing/new_relic_trace.rb +41 -24
  35. data/lib/graphql/tracing/notifications_trace.rb +4 -0
  36. data/lib/graphql/tracing/platform_trace.rb +5 -0
  37. data/lib/graphql/tracing/prometheus_trace.rb +4 -0
  38. data/lib/graphql/tracing/scout_trace.rb +3 -0
  39. data/lib/graphql/tracing/sentry_trace.rb +4 -0
  40. data/lib/graphql/tracing/statsd_trace.rb +4 -0
  41. data/lib/graphql/types/relay/connection_behaviors.rb +1 -1
  42. data/lib/graphql/types/relay/edge_behaviors.rb +1 -1
  43. data/lib/graphql/version.rb +1 -1
  44. metadata +3 -31
@@ -53,6 +53,7 @@ module GraphQL
53
53
  def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, comment: 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)
54
54
  arg_name ||= name
55
55
  @name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
56
+ NameValidator.validate!(@name)
56
57
  @type_expr = type_expr || type
57
58
  @description = desc || description
58
59
  @comment = comment
@@ -89,11 +90,8 @@ module GraphQL
89
90
  end
90
91
 
91
92
  if definition_block
92
- if definition_block.arity == 1
93
- instance_exec(self, &definition_block)
94
- else
95
- instance_eval(&definition_block)
96
- end
93
+ # `self` will still be self, it will also be the first argument to the block:
94
+ instance_exec(self, &definition_block)
97
95
  end
98
96
  end
99
97
 
@@ -219,7 +217,7 @@ module GraphQL
219
217
  # @api private
220
218
  def prepare_value(obj, value, context: nil)
221
219
  if type.unwrap.kind.input_object?
222
- value = recursively_prepare_input_object(value, type)
220
+ value = recursively_prepare_input_object(value, type, context)
223
221
  end
224
222
 
225
223
  Schema::Validator.validate!(validators, obj, context, value)
@@ -400,15 +398,16 @@ module GraphQL
400
398
 
401
399
  private
402
400
 
403
- def recursively_prepare_input_object(value, type)
401
+ def recursively_prepare_input_object(value, type, context)
404
402
  if type.non_null?
405
403
  type = type.of_type
406
404
  end
407
405
 
408
406
  if type.list? && !value.nil?
409
407
  inner_type = type.of_type
410
- value.map { |v| recursively_prepare_input_object(v, inner_type) }
408
+ value.map { |v| recursively_prepare_input_object(v, inner_type, context) }
411
409
  elsif value.is_a?(GraphQL::Schema::InputObject)
410
+ value.validate_for(context)
412
411
  value.prepare
413
412
  else
414
413
  value
@@ -20,8 +20,8 @@ module GraphQL
20
20
  from_document(schema_superclass, parser.parse_file(definition_path), **kwargs)
21
21
  end
22
22
 
23
- def from_document(schema_superclass, document, default_resolve:, using: {}, relay: false)
24
- Builder.build(schema_superclass, document, default_resolve: default_resolve || {}, relay: relay, using: using)
23
+ def from_document(schema_superclass, document, default_resolve:, using: {}, base_types: {}, relay: false)
24
+ Builder.build(schema_superclass, document, default_resolve: default_resolve || {}, relay: relay, using: using, base_types: base_types)
25
25
  end
26
26
  end
27
27
 
@@ -30,9 +30,18 @@ module GraphQL
30
30
  include GraphQL::EmptyObjects
31
31
  extend self
32
32
 
33
- def build(schema_superclass, document, default_resolve:, using: {}, relay:)
33
+ def build(schema_superclass, document, default_resolve:, using: {}, base_types: {}, relay:)
34
34
  raise InvalidDocumentError.new('Must provide a document ast.') if !document || !document.is_a?(GraphQL::Language::Nodes::Document)
35
35
 
36
+ base_types = {
37
+ object: GraphQL::Schema::Object,
38
+ interface: GraphQL::Schema::Interface,
39
+ union: GraphQL::Schema::Union,
40
+ scalar: GraphQL::Schema::Scalar,
41
+ enum: GraphQL::Schema::Enum,
42
+ input_object: GraphQL::Schema::InputObject,
43
+ }.merge!(base_types)
44
+
36
45
  if default_resolve.is_a?(Hash)
37
46
  default_resolve = ResolveMap.new(default_resolve)
38
47
  end
@@ -53,7 +62,7 @@ module GraphQL
53
62
  types[type_name] ||= begin
54
63
  defn = document.definitions.find { |d| d.respond_to?(:name) && d.name == type_name }
55
64
  if defn
56
- build_definition_from_node(defn, directive_type_resolver, default_resolve)
65
+ build_definition_from_node(defn, directive_type_resolver, default_resolve, base_types)
57
66
  elsif (built_in_defn = GraphQL::Schema::BUILT_IN_TYPES[type_name])
58
67
  built_in_defn
59
68
  else
@@ -77,14 +86,20 @@ module GraphQL
77
86
  case definition
78
87
  when GraphQL::Language::Nodes::SchemaDefinition, GraphQL::Language::Nodes::DirectiveDefinition
79
88
  nil # already handled
80
- when GraphQL::Language::Nodes::SchemaExtension
89
+ when GraphQL::Language::Nodes::SchemaExtension,
90
+ GraphQL::Language::Nodes::ScalarTypeExtension,
91
+ GraphQL::Language::Nodes::ObjectTypeExtension,
92
+ GraphQL::Language::Nodes::InterfaceTypeExtension,
93
+ GraphQL::Language::Nodes::UnionTypeExtension,
94
+ GraphQL::Language::Nodes::EnumTypeExtension,
95
+ GraphQL::Language::Nodes::InputObjectTypeExtension
81
96
  schema_extensions ||= []
82
97
  schema_extensions << definition
83
98
  else
84
99
  # It's possible that this was already loaded by the directives
85
100
  prev_type = types[definition.name]
86
101
  if prev_type.nil? || prev_type.is_a?(Schema::LateBoundType)
87
- types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve)
102
+ types[definition.name] = build_definition_from_node(definition, type_resolver, default_resolve, base_types)
88
103
  end
89
104
  end
90
105
  end
@@ -124,6 +139,34 @@ module GraphQL
124
139
 
125
140
  raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
126
141
 
142
+ schema_extensions&.each do |ext|
143
+ next if ext.is_a?(GraphQL::Language::Nodes::SchemaExtension)
144
+
145
+ built_type = types[ext.name]
146
+
147
+ case ext
148
+ when GraphQL::Language::Nodes::ScalarTypeExtension
149
+ build_directives(built_type, ext, type_resolver)
150
+ when GraphQL::Language::Nodes::ObjectTypeExtension
151
+ build_directives(built_type, ext, type_resolver)
152
+ build_fields(built_type, ext.fields, type_resolver, default_resolve: true)
153
+ build_interfaces(built_type, ext.interfaces, type_resolver)
154
+ when GraphQL::Language::Nodes::InterfaceTypeExtension
155
+ build_directives(built_type, ext, type_resolver)
156
+ build_fields(built_type, ext.fields, type_resolver, default_resolve: nil)
157
+ build_interfaces(built_type, ext.interfaces, type_resolver)
158
+ when GraphQL::Language::Nodes::UnionTypeExtension
159
+ build_directives(built_type, ext, type_resolver)
160
+ built_type.possible_types(*ext.types.map { |type_name| type_resolver.call(type_name) })
161
+ when GraphQL::Language::Nodes::EnumTypeExtension
162
+ build_directives(built_type, ext, type_resolver)
163
+ build_values(built_type, ext.values, type_resolver)
164
+ when GraphQL::Language::Nodes::InputObjectTypeExtension
165
+ build_directives(built_type, ext, type_resolver)
166
+ build_arguments(built_type, ext.fields, type_resolver)
167
+ end
168
+ end
169
+
127
170
  builder = self
128
171
 
129
172
  found_types = types.values
@@ -192,8 +235,8 @@ module GraphQL
192
235
  end
193
236
  end
194
237
 
195
- if schema_extensions
196
- schema_extensions.each do |ext|
238
+ schema_extensions&.each do |ext|
239
+ if ext.is_a?(GraphQL::Language::Nodes::SchemaExtension)
197
240
  build_directives(schema_class, ext, type_resolver)
198
241
  end
199
242
  end
@@ -205,20 +248,20 @@ module GraphQL
205
248
  raise(GraphQL::RequiredImplementationMissingError, "Generated Schema cannot use Interface or Union types for execution. Implement resolve_type on your resolver.")
206
249
  }
207
250
 
208
- def build_definition_from_node(definition, type_resolver, default_resolve)
251
+ def build_definition_from_node(definition, type_resolver, default_resolve, base_types)
209
252
  case definition
210
253
  when GraphQL::Language::Nodes::EnumTypeDefinition
211
- build_enum_type(definition, type_resolver)
254
+ build_enum_type(definition, type_resolver, base_types[:enum])
212
255
  when GraphQL::Language::Nodes::ObjectTypeDefinition
213
- build_object_type(definition, type_resolver)
256
+ build_object_type(definition, type_resolver, base_types[:object])
214
257
  when GraphQL::Language::Nodes::InterfaceTypeDefinition
215
- build_interface_type(definition, type_resolver)
258
+ build_interface_type(definition, type_resolver, base_types[:interface])
216
259
  when GraphQL::Language::Nodes::UnionTypeDefinition
217
- build_union_type(definition, type_resolver)
260
+ build_union_type(definition, type_resolver, base_types[:union])
218
261
  when GraphQL::Language::Nodes::ScalarTypeDefinition
219
- build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
262
+ build_scalar_type(definition, type_resolver, base_types[:scalar], default_resolve: default_resolve)
220
263
  when GraphQL::Language::Nodes::InputObjectTypeDefinition
221
- build_input_object_type(definition, type_resolver)
264
+ build_input_object_type(definition, type_resolver, base_types[:input_object])
222
265
  end
223
266
  end
224
267
 
@@ -284,22 +327,26 @@ module GraphQL
284
327
  end
285
328
  end
286
329
 
287
- def build_enum_type(enum_type_definition, type_resolver)
330
+ def build_enum_type(enum_type_definition, type_resolver, base_type)
288
331
  builder = self
289
- Class.new(GraphQL::Schema::Enum) do
332
+ Class.new(base_type) do
290
333
  graphql_name(enum_type_definition.name)
291
334
  builder.build_directives(self, enum_type_definition, type_resolver)
292
335
  description(enum_type_definition.description)
293
336
  ast_node(enum_type_definition)
294
- enum_type_definition.values.each do |enum_value_definition|
295
- value(enum_value_definition.name,
296
- value: enum_value_definition.name,
297
- deprecation_reason: builder.build_deprecation_reason(enum_value_definition.directives),
298
- description: enum_value_definition.description,
299
- directives: builder.prepare_directives(enum_value_definition, type_resolver),
300
- ast_node: enum_value_definition,
301
- )
302
- end
337
+ builder.build_values(self, enum_type_definition.values, type_resolver)
338
+ end
339
+ end
340
+
341
+ def build_values(type_class, enum_value_definitions, type_resolver)
342
+ enum_value_definitions.each do |enum_value_definition|
343
+ type_class.value(enum_value_definition.name,
344
+ value: enum_value_definition.name,
345
+ deprecation_reason: build_deprecation_reason(enum_value_definition.directives),
346
+ description: enum_value_definition.description,
347
+ directives: prepare_directives(enum_value_definition, type_resolver),
348
+ ast_node: enum_value_definition,
349
+ )
303
350
  end
304
351
  end
305
352
 
@@ -313,9 +360,9 @@ module GraphQL
313
360
  reason.value
314
361
  end
315
362
 
316
- def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
363
+ def build_scalar_type(scalar_type_definition, type_resolver, base_type, default_resolve:)
317
364
  builder = self
318
- Class.new(GraphQL::Schema::Scalar) do
365
+ Class.new(base_type) do
319
366
  graphql_name(scalar_type_definition.name)
320
367
  description(scalar_type_definition.description)
321
368
  ast_node(scalar_type_definition)
@@ -336,9 +383,9 @@ module GraphQL
336
383
  end
337
384
  end
338
385
 
339
- def build_union_type(union_type_definition, type_resolver)
386
+ def build_union_type(union_type_definition, type_resolver, base_type)
340
387
  builder = self
341
- Class.new(GraphQL::Schema::Union) do
388
+ Class.new(base_type) do
342
389
  graphql_name(union_type_definition.name)
343
390
  description(union_type_definition.description)
344
391
  possible_types(*union_type_definition.types.map { |type_name| type_resolver.call(type_name) })
@@ -347,27 +394,28 @@ module GraphQL
347
394
  end
348
395
  end
349
396
 
350
- def build_object_type(object_type_definition, type_resolver)
397
+ def build_object_type(object_type_definition, type_resolver, base_type)
351
398
  builder = self
352
399
 
353
- Class.new(GraphQL::Schema::Object) do
400
+ Class.new(base_type) do
354
401
  graphql_name(object_type_definition.name)
355
402
  description(object_type_definition.description)
356
403
  ast_node(object_type_definition)
357
404
  builder.build_directives(self, object_type_definition, type_resolver)
358
-
359
- object_type_definition.interfaces.each do |interface_name|
360
- interface_defn = type_resolver.call(interface_name)
361
- implements(interface_defn)
362
- end
363
-
405
+ builder.build_interfaces(self, object_type_definition.interfaces, type_resolver)
364
406
  builder.build_fields(self, object_type_definition.fields, type_resolver, default_resolve: true)
365
407
  end
366
408
  end
367
409
 
368
- def build_input_object_type(input_object_type_definition, type_resolver)
410
+ def build_interfaces(type_class, interface_names, type_resolver)
411
+ interface_names.each do |interface_name|
412
+ type_class.implements(type_resolver.call(interface_name))
413
+ end
414
+ end
415
+
416
+ def build_input_object_type(input_object_type_definition, type_resolver, base_type)
369
417
  builder = self
370
- Class.new(GraphQL::Schema::InputObject) do
418
+ Class.new(base_type) do
371
419
  graphql_name(input_object_type_definition.name)
372
420
  description(input_object_type_definition.description)
373
421
  ast_node(input_object_type_definition)
@@ -427,16 +475,13 @@ module GraphQL
427
475
  end
428
476
  end
429
477
 
430
- def build_interface_type(interface_type_definition, type_resolver)
478
+ def build_interface_type(interface_type_definition, type_resolver, base_type)
431
479
  builder = self
432
480
  Module.new do
433
- include GraphQL::Schema::Interface
481
+ include base_type
434
482
  graphql_name(interface_type_definition.name)
435
483
  description(interface_type_definition.description)
436
- interface_type_definition.interfaces.each do |interface_name|
437
- interface_defn = type_resolver.call(interface_name)
438
- implements(interface_defn)
439
- end
484
+ builder.build_interfaces(self, interface_type_definition.interfaces, type_resolver)
440
485
  ast_node(interface_type_definition)
441
486
  builder.build_directives(self, interface_type_definition, type_resolver)
442
487
 
@@ -467,17 +512,18 @@ module GraphQL
467
512
 
468
513
  # Don't do this for interfaces
469
514
  if default_resolve
470
- owner.class_eval <<-RUBY, __FILE__, __LINE__
471
- # frozen_string_literal: true
472
- def #{resolve_method_name}(**args)
473
- field_instance = self.class.get_field("#{field_definition.name}")
474
- context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
475
- end
476
- RUBY
515
+ define_field_resolve_method(owner, resolve_method_name, field_definition.name)
477
516
  end
478
517
  end
479
518
  end
480
519
 
520
+ def define_field_resolve_method(owner, method_name, field_name)
521
+ owner.define_method(method_name) { |**args|
522
+ field_instance = self.class.get_field(field_name)
523
+ context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
524
+ }
525
+ end
526
+
481
527
  def build_resolve_type(lookup_hash, directives, missing_type_handler)
482
528
  resolve_type_proc = nil
483
529
  resolve_type_proc = ->(ast_node) {
@@ -99,7 +99,7 @@ module GraphQL
99
99
 
100
100
  def inherited(subclass)
101
101
  super
102
- subclass.class_eval do
102
+ subclass.class_exec do
103
103
  @default_graphql_name ||= nil
104
104
  end
105
105
  end
@@ -234,7 +234,7 @@ module GraphQL
234
234
  # because they would end up with names like `#<Class0x1234>::UnresolvedValueError` which messes up bug trackers
235
235
  child_class.const_set(:UnresolvedValueError, Class.new(Schema::Enum::UnresolvedValueError))
236
236
  end
237
- child_class.class_eval { @value_methods = nil }
237
+ child_class.class_exec { @value_methods = nil }
238
238
  super
239
239
  end
240
240
 
@@ -256,7 +256,7 @@ module GraphQL
256
256
  return
257
257
  end
258
258
 
259
- instance_eval("def #{value_method_name}; #{value.graphql_name.inspect}; end;", __FILE__, __LINE__)
259
+ define_singleton_method(value_method_name) { value.graphql_name }
260
260
  end
261
261
  end
262
262
 
@@ -48,7 +48,7 @@ module GraphQL
48
48
  end
49
49
 
50
50
  if block_given?
51
- instance_eval(&block)
51
+ instance_exec(self, &block)
52
52
  end
53
53
  end
54
54
 
@@ -255,7 +255,7 @@ module GraphQL
255
255
 
256
256
  @underscored_name = -Member::BuildType.underscore(name_s)
257
257
  @name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
258
-
258
+ NameValidator.validate!(@name)
259
259
  @description = description
260
260
  @comment = comment
261
261
  @type = @owner_type = @own_validators = @own_directives = @own_arguments = @arguments_statically_coercible = nil # these will be prepared later if necessary
@@ -369,7 +369,7 @@ module GraphQL
369
369
  if @definition_block.arity == 1
370
370
  @definition_block.call(self)
371
371
  else
372
- instance_eval(&@definition_block)
372
+ instance_exec(self, &@definition_block)
373
373
  end
374
374
  self.extensions.each(&:after_define_apply)
375
375
  @call_after_define = true
@@ -59,19 +59,12 @@ module GraphQL
59
59
  else
60
60
  new_h = {}
61
61
  keys.each { |k| @ruby_style_hash.key?(k) && new_h[k] = @ruby_style_hash[k] }
62
- new_h
62
+ new_h
63
63
  end
64
64
  end
65
65
 
66
66
  def prepare
67
- if @context
68
- object = @context[:current_object]
69
- # Pass this object's class with `as` so that messages are rendered correctly from inherited validators
70
- Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
71
- self
72
- else
73
- self
74
- end
67
+ self
75
68
  end
76
69
 
77
70
  def unwrap_value(value)
@@ -111,6 +104,14 @@ module GraphQL
111
104
  @ruby_style_hash.dup
112
105
  end
113
106
 
107
+ # @api private
108
+ def validate_for(context)
109
+ object = context[:current_object]
110
+ # Pass this object's class with `as` so that messages are rendered correctly from inherited validators
111
+ Schema::Validator.validate!(self.class.validators, object, context, @ruby_style_hash, as: self.class)
112
+ nil
113
+ end
114
+
114
115
  class << self
115
116
  def authorized?(obj, value, ctx)
116
117
  # Authorize each argument (but this doesn't apply if `prepare` is implemented):
@@ -150,14 +151,8 @@ module GraphQL
150
151
  end
151
152
  end
152
153
  # Add a method access
153
- method_name = argument_defn.keyword
154
154
  suppress_redefinition_warning do
155
- class_eval <<-RUBY, __FILE__, __LINE__
156
- def #{method_name}
157
- self[#{method_name.inspect}]
158
- end
159
- alias_method #{method_name.inspect}, #{method_name.inspect}
160
- RUBY
155
+ define_accessor_method(argument_defn.keyword)
161
156
  end
162
157
  argument_defn
163
158
  end
@@ -293,6 +288,11 @@ module GraphQL
293
288
  ensure
294
289
  $VERBOSE = verbose
295
290
  end
291
+
292
+ def define_accessor_method(method_name)
293
+ define_method(method_name) { self[method_name] }
294
+ alias_method(method_name, method_name)
295
+ end
296
296
  end
297
297
 
298
298
  private
@@ -30,7 +30,7 @@ module GraphQL
30
30
  const_set(:DefinitionMethods, defn_methods_module)
31
31
  extend(self::DefinitionMethods)
32
32
  end
33
- self::DefinitionMethods.module_eval(&block)
33
+ self::DefinitionMethods.module_exec(&block)
34
34
  end
35
35
 
36
36
  # @see {Schema::Warden} hides interfaces without visible implementations
@@ -6,7 +6,7 @@ module GraphQL
6
6
  module HasDirectives
7
7
  def self.extended(child_cls)
8
8
  super
9
- child_cls.module_eval { self.own_directives = nil }
9
+ child_cls.module_exec { self.own_directives = nil }
10
10
  end
11
11
 
12
12
  def inherited(child_cls)
@@ -202,7 +202,7 @@ module GraphQL
202
202
 
203
203
  def inherited(subclass)
204
204
  super
205
- subclass.class_eval do
205
+ subclass.class_exec do
206
206
  @own_fields ||= nil
207
207
  @field_class ||= nil
208
208
  @has_no_fields ||= false
@@ -133,7 +133,7 @@ module GraphQL
133
133
 
134
134
  def inherited(subclass)
135
135
  super
136
- subclass.class_eval do
136
+ subclass.class_exec do
137
137
  @own_interface_type_memberships ||= nil
138
138
  end
139
139
  end
@@ -30,7 +30,7 @@ module GraphQL
30
30
 
31
31
  def inherited(subclass)
32
32
  super
33
- subclass.class_eval do
33
+ subclass.class_exec do
34
34
  @reauthorize_scoped_objects = nil
35
35
  end
36
36
  end
@@ -42,7 +42,7 @@ module GraphQL
42
42
  private
43
43
 
44
44
  def inherited(subclass)
45
- subclass.class_eval do
45
+ subclass.class_exec do
46
46
  @to_non_null_type ||= nil
47
47
  @to_list_type ||= nil
48
48
  end
@@ -22,7 +22,6 @@ module GraphQL
22
22
  include Schema::Member::GraphQLTypeNames
23
23
  # Really we only need description & comment from here, but:
24
24
  extend Schema::Member::BaseDSLMethods
25
- extend Member::BaseDSLMethods::ConfigurationExtension
26
25
  extend GraphQL::Schema::Member::HasArguments
27
26
  extend GraphQL::Schema::Member::HasValidators
28
27
  include Schema::Member::HasPath
@@ -404,6 +403,11 @@ module GraphQL
404
403
  end
405
404
  end
406
405
 
406
+ def inherited(child_class)
407
+ child_class.description(description)
408
+ super
409
+ end
410
+
407
411
  private
408
412
 
409
413
  attr_reader :own_extensions
@@ -111,7 +111,7 @@ module GraphQL
111
111
  # @param parser [Object] An object for handling definition string parsing (must respond to `parse`)
112
112
  # @param using [Hash] Plugins to attach to the created schema with `use(key, value)`
113
113
  # @return [Class] the schema described by `document`
114
- def from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {})
114
+ def from_definition(definition_or_path, default_resolve: nil, parser: GraphQL.default_parser, using: {}, base_types: {})
115
115
  # If the file ends in `.graphql` or `.graphqls`, treat it like a filepath
116
116
  if definition_or_path.end_with?(".graphql") || definition_or_path.end_with?(".graphqls")
117
117
  GraphQL::Schema::BuildFromDefinition.from_definition_path(
@@ -120,6 +120,7 @@ module GraphQL
120
120
  default_resolve: default_resolve,
121
121
  parser: parser,
122
122
  using: using,
123
+ base_types: base_types,
123
124
  )
124
125
  else
125
126
  GraphQL::Schema::BuildFromDefinition.from_definition(
@@ -128,6 +129,7 @@ module GraphQL
128
129
  default_resolve: default_resolve,
129
130
  parser: parser,
130
131
  using: using,
132
+ base_types: base_types,
131
133
  )
132
134
  end
133
135
  end
@@ -821,13 +823,13 @@ module GraphQL
821
823
 
822
824
  attr_writer :validate_timeout
823
825
 
824
- def validate_timeout(new_validate_timeout = nil)
825
- if new_validate_timeout
826
+ def validate_timeout(new_validate_timeout = NOT_CONFIGURED)
827
+ if !NOT_CONFIGURED.equal?(new_validate_timeout)
826
828
  @validate_timeout = new_validate_timeout
827
829
  elsif defined?(@validate_timeout)
828
830
  @validate_timeout
829
831
  else
830
- find_inherited_value(:validate_timeout)
832
+ find_inherited_value(:validate_timeout) || 3
831
833
  end
832
834
  end
833
835
 
@@ -345,7 +345,7 @@ module GraphQL
345
345
  fields << Field.new(node, definition, owner_type, parents)
346
346
  when GraphQL::Language::Nodes::InlineFragment
347
347
  fragment_type = node.type ? @types.type(node.type.name) : owner_type
348
- find_fields_and_fragments(node.selections, parents: [*parents, fragment_type], owner_type: owner_type, fields: fields, fragment_spreads: fragment_spreads) if fragment_type
348
+ find_fields_and_fragments(node.selections, parents: [*parents, fragment_type], owner_type: fragment_type, fields: fields, fragment_spreads: fragment_spreads) if fragment_type
349
349
  when GraphQL::Language::Nodes::FragmentSpread
350
350
  fragment_spreads << FragmentSpread.new(node.name, parents)
351
351
  end
@@ -43,18 +43,21 @@ module GraphQL
43
43
  type_name, *field_names = field_path.split(".")
44
44
  dummy_query = GraphQL::Query.new(schema, "{ __typename }", context: context)
45
45
  query_context = dummy_query.context
46
+ dataloader = query_context.dataloader
46
47
  object_type = dummy_query.types.type(type_name) # rubocop:disable Development/ContextIsPassedCop
47
48
  if object_type
48
49
  graphql_result = object
49
50
  field_names.each do |field_name|
50
51
  inner_object = graphql_result
51
- graphql_result = object_type.wrap(inner_object, query_context)
52
+ dataloader.run_isolated {
53
+ graphql_result = object_type.wrap(inner_object, query_context)
54
+ }
52
55
  if graphql_result.nil?
53
56
  return nil
54
57
  end
55
58
  visible_field = dummy_query.types.field(object_type, field_name) # rubocop:disable Development/ContextIsPassedCop
56
59
  if visible_field
57
- dummy_query.context.dataloader.run_isolated {
60
+ dataloader.run_isolated {
58
61
  query_context[:current_field] = visible_field
59
62
  field_args = visible_field.coerce_arguments(graphql_result, arguments, query_context)
60
63
  field_args = schema.sync_lazy(field_args)
@@ -32,6 +32,8 @@ module GraphQL
32
32
  Gem::Version.new('1.0.0')
33
33
  end
34
34
 
35
+ # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
36
+
35
37
  [
36
38
  'lex',
37
39
  'parse',
@@ -59,6 +61,8 @@ module GraphQL
59
61
  RUBY
60
62
  end
61
63
 
64
+ # rubocop:enable Development/NoEvalCop
65
+
62
66
  def execute_field(query:, field:, ast_node:, arguments:, object:)
63
67
  return_type = field.type.unwrap
64
68
  trace_field = if return_type.kind.scalar? || return_type.kind.enum?
@@ -21,6 +21,8 @@ module GraphQL
21
21
  super
22
22
  end
23
23
 
24
+ # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
25
+
24
26
  {
25
27
  "lex" => "lex.graphql",
26
28
  "parse" => "parse.graphql",
@@ -51,6 +53,8 @@ module GraphQL
51
53
  RUBY
52
54
  end
53
55
 
56
+ # rubocop:enable Development/NoEvalCop
57
+
54
58
  def platform_execute_field(platform_key)
55
59
  Appsignal.instrument(platform_key) do
56
60
  yield
@@ -27,6 +27,8 @@ module GraphQL
27
27
  super
28
28
  end
29
29
 
30
+ # rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
31
+
30
32
  {
31
33
  'lex' => 'lex.graphql',
32
34
  'parse' => 'parse.graphql',
@@ -76,6 +78,8 @@ module GraphQL
76
78
  RUBY
77
79
  end
78
80
 
81
+ # rubocop:enable Development/NoEvalCop
82
+
79
83
  def execute_field_span(span_key, query, field, ast_node, arguments, object)
80
84
  return_type = field.type.unwrap
81
85
  trace_field = if return_type.kind.scalar? || return_type.kind.enum?