graphql 1.12.17 → 1.12.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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/object_generator.rb +2 -1
  3. data/lib/generators/graphql/relay.rb +19 -11
  4. data/lib/generators/graphql/templates/schema.erb +14 -2
  5. data/lib/graphql/analysis/ast/field_usage.rb +1 -1
  6. data/lib/graphql/dataloader/source.rb +32 -2
  7. data/lib/graphql/dataloader.rb +13 -0
  8. data/lib/graphql/deprecated_dsl.rb +11 -3
  9. data/lib/graphql/deprecation.rb +1 -5
  10. data/lib/graphql/integer_encoding_error.rb +18 -2
  11. data/lib/graphql/pagination/connections.rb +35 -16
  12. data/lib/graphql/query/validation_pipeline.rb +1 -1
  13. data/lib/graphql/schema/argument.rb +55 -26
  14. data/lib/graphql/schema/field.rb +14 -4
  15. data/lib/graphql/schema/input_object.rb +1 -5
  16. data/lib/graphql/schema/member/has_arguments.rb +90 -44
  17. data/lib/graphql/schema/resolver.rb +20 -57
  18. data/lib/graphql/schema/subscription.rb +4 -4
  19. data/lib/graphql/schema/validator/allow_blank_validator.rb +29 -0
  20. data/lib/graphql/schema/validator/allow_null_validator.rb +26 -0
  21. data/lib/graphql/schema/validator/exclusion_validator.rb +3 -1
  22. data/lib/graphql/schema/validator/format_validator.rb +4 -1
  23. data/lib/graphql/schema/validator/inclusion_validator.rb +3 -1
  24. data/lib/graphql/schema/validator/length_validator.rb +5 -3
  25. data/lib/graphql/schema/validator/numericality_validator.rb +7 -1
  26. data/lib/graphql/schema/validator.rb +36 -25
  27. data/lib/graphql/schema.rb +18 -5
  28. data/lib/graphql/static_validation/base_visitor.rb +3 -0
  29. data/lib/graphql/static_validation/error.rb +3 -1
  30. data/lib/graphql/static_validation/rules/fields_will_merge.rb +40 -21
  31. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +25 -4
  32. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +2 -2
  33. data/lib/graphql/static_validation/validation_context.rb +8 -2
  34. data/lib/graphql/static_validation/validator.rb +15 -12
  35. data/lib/graphql/string_encoding_error.rb +13 -3
  36. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -1
  37. data/lib/graphql/subscriptions/event.rb +47 -2
  38. data/lib/graphql/subscriptions/serialize.rb +1 -1
  39. data/lib/graphql/tracing/appsignal_tracing.rb +15 -0
  40. data/lib/graphql/types/int.rb +1 -1
  41. data/lib/graphql/types/string.rb +1 -1
  42. data/lib/graphql/unauthorized_error.rb +1 -1
  43. data/lib/graphql/version.rb +1 -1
  44. metadata +5 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6c9089e4578454f473996553a4771e4086e51b2b2db17fc31a579ab28019bd39
4
- data.tar.gz: f45a70c81394f35c86d1610491f106e39899bc2c927a6a6d13e9e6533bc3bc85
3
+ metadata.gz: 6fa9800286687f6236697bf1f3eed4f3342b40fbbbebc64c472a7d791442bce4
4
+ data.tar.gz: a74ed6cf70cf2f626c2339a8377ada5dea5491eb3e53a1e1783b4a7a8dd8bebc
5
5
  SHA512:
6
- metadata.gz: b7231b5e00a336439d15d469a383cd7e211e305961d4a4b431e8a97f5e483819bbd87de3d7cfffc9b6677b8175f700e012cd9ee4a0c92fa47005455a14893d3c
7
- data.tar.gz: 98495c2b24d65ef90d7f5e1036956349ea79d03ea192de6ed06e517657f49b4e0e9c748c8a28d54aac24e96b42f52eea5d4cbfbca801a4389b1515804296831a
6
+ metadata.gz: 41c6592dbd0cd27e82f036f271c71098a14c2b10d7cc700fc680caa1133b0a148a730b9e15d5a4d04c98f72bfd4a418d8ae63b09f327193f80af2220fc399fc0
7
+ data.tar.gz: cb35e9d298bc92431ae561e8c663c00fcf899c1cc1c1daca9730717ba6636f9eb177af40b1314e55f73a411d2a78eeaadc2d2c6b34b583cd3fbe7525d18a8139
@@ -12,7 +12,8 @@ module Graphql
12
12
  #
13
13
  # Add the Node interface with `--node`.
14
14
  class ObjectGenerator < TypeGeneratorBase
15
- desc "Create a GraphQL::ObjectType with the given name and fields"
15
+ desc "Create a GraphQL::ObjectType with the given name and fields." \
16
+ "If the given type name matches an existing ActiveRecord model, the generated type will automatically include fields for the models database columns."
16
17
  source_root File.expand_path('../templates', __FILE__)
17
18
 
18
19
  argument :custom_fields,
@@ -32,20 +32,28 @@ module Graphql
32
32
 
33
33
  # Return a string UUID for `object`
34
34
  def self.id_from_object(object, type_definition, query_ctx)
35
- # Here's a simple implementation which:
36
- # - joins the type name & object.id
37
- # - encodes it with base64:
38
- # GraphQL::Schema::UniqueWithinType.encode(type_definition.name, object.id)
35
+ # For example, use Rails' GlobalID library (https://github.com/rails/globalid):
36
+ object_id = object.to_global_id.to_s
37
+ # Remove this redundant prefix to make IDs shorter:
38
+ object_id = object_id.sub("gid://\#{GlobalID.app}/", "")
39
+ encoded_id = Base64.urlsafe_encode64(object_id)
40
+ # Remove the "=" padding
41
+ encoded_id = encoded_id.sub(/=+/, "")
42
+ # Add a type hint
43
+ type_hint = type_definition.graphql_name.first
44
+ "\#{type_hint}_\#{encoded_id}"
39
45
  end
40
46
 
41
47
  # Given a string UUID, find the object
42
- def self.object_from_id(id, query_ctx)
43
- # For example, to decode the UUIDs generated above:
44
- # type_name, item_id = GraphQL::Schema::UniqueWithinType.decode(id)
45
- #
46
- # Then, based on `type_name` and `id`
47
- # find an object in your application
48
- # ...
48
+ def self.object_from_id(encoded_id_with_hint, query_ctx)
49
+ # For example, use Rails' GlobalID library (https://github.com/rails/globalid):
50
+ # Split off the type hint
51
+ _type_hint, encoded_id = encoded_id_with_hint.split("_", 2)
52
+ # Decode the ID
53
+ id = Base64.urlsafe_decode64(encoded_id)
54
+ # Rebuild it for Rails then find the object:
55
+ full_global_id = "gid://\#{GlobalID.app}/\#{id}"
56
+ GlobalID::Locator.locate(full_global_id)
49
57
  end
50
58
  RUBY
51
59
  inject_into_file schema_file_path, schema_code, before: /^end\n/m, force: false
@@ -4,11 +4,23 @@ class <%= schema_name %> < GraphQL::Schema
4
4
  <% if options[:batch] %>
5
5
  # GraphQL::Batch setup:
6
6
  use GraphQL::Batch
7
+ <% else %>
8
+ # For batch-loading (see https://graphql-ruby.org/dataloader/overview.html)
9
+ use GraphQL::Dataloader
7
10
  <% end %>
11
+ # GraphQL-Ruby calls this when something goes wrong while running a query:
12
+ def self.type_error(err, context)
13
+ # if err.is_a?(GraphQL::InvalidNullError)
14
+ # # report to your bug tracker here
15
+ # return nil
16
+ # end
17
+ super
18
+ end
19
+
8
20
  # Union and Interface Resolution
9
21
  def self.resolve_type(abstract_type, obj, ctx)
10
- # TODO: Implement this function
11
- # to return the correct object type for `obj`
22
+ # TODO: Implement this method
23
+ # to return the correct GraphQL object type for `obj`
12
24
  raise(GraphQL::RequiredImplementationMissingError)
13
25
  end
14
26
  end
@@ -37,7 +37,7 @@ module GraphQL
37
37
 
38
38
  if argument.definition.type.kind.input_object?
39
39
  extract_deprecated_arguments(argument.value.arguments.argument_values)
40
- elsif argument.definition.type.list?
40
+ elsif argument.definition.type.list? && !argument.value.nil?
41
41
  argument
42
42
  .value
43
43
  .select { |value| value.respond_to?(:arguments) }
@@ -6,7 +6,11 @@ module GraphQL
6
6
  # Called by {Dataloader} to prepare the {Source}'s internal state
7
7
  # @api private
8
8
  def setup(dataloader)
9
+ # These keys have been requested but haven't been fetched yet
9
10
  @pending_keys = []
11
+ # These keys have been passed to `fetch` but haven't been finished yet
12
+ @fetching_keys = []
13
+ # { key => result }
10
14
  @results = {}
11
15
  @dataloader = dataloader
12
16
  end
@@ -64,29 +68,46 @@ module GraphQL
64
68
  # Then run the batch and update the cache.
65
69
  # @return [void]
66
70
  def sync
71
+ pending_keys = @pending_keys.dup
67
72
  @dataloader.yield
73
+ iterations = 0
74
+ while pending_keys.any? { |k| !@results.key?(k) }
75
+ iterations += 1
76
+ if iterations > 1000
77
+ raise "#{self.class}#sync tried 1000 times to load pending keys (#{pending_keys}), but they still weren't loaded. There is likely a circular dependency."
78
+ end
79
+ @dataloader.yield
80
+ end
81
+ nil
68
82
  end
69
83
 
70
84
  # @return [Boolean] True if this source has any pending requests for data.
71
85
  def pending?
72
- @pending_keys.any?
86
+ !@pending_keys.empty?
73
87
  end
74
88
 
75
89
  # Called by {GraphQL::Dataloader} to resolve and pending requests to this source.
76
90
  # @api private
77
91
  # @return [void]
78
92
  def run_pending_keys
93
+ if !@fetching_keys.empty?
94
+ @pending_keys -= @fetching_keys
95
+ end
79
96
  return if @pending_keys.empty?
80
97
  fetch_keys = @pending_keys.uniq
98
+ @fetching_keys.concat(fetch_keys)
81
99
  @pending_keys = []
82
100
  results = fetch(fetch_keys)
83
101
  fetch_keys.each_with_index do |key, idx|
84
102
  @results[key] = results[idx]
85
103
  end
104
+ nil
86
105
  rescue StandardError => error
87
106
  fetch_keys.each { |key| @results[key] = error }
88
107
  ensure
89
- nil
108
+ if fetch_keys
109
+ @fetching_keys -= fetch_keys
110
+ end
90
111
  end
91
112
 
92
113
  # These arguments are given to `dataloader.with(source_class, ...)`. The object
@@ -107,6 +128,8 @@ module GraphQL
107
128
  [*batch_args, **batch_kwargs]
108
129
  end
109
130
 
131
+ attr_reader :pending_keys
132
+
110
133
  private
111
134
 
112
135
  # Reads and returns the result for the key from the internal cache, or raises an error if the result was an error
@@ -114,6 +137,13 @@ module GraphQL
114
137
  # @return [Object] The result from {#fetch} for `key`.
115
138
  # @api private
116
139
  def result_for(key)
140
+ if !@results.key?(key)
141
+ raise <<-ERR
142
+ Invariant: fetching result for a key on #{self.class} that hasn't been loaded yet (#{key.inspect}, loaded: #{@results.keys})
143
+
144
+ This key should have been loaded already. This is a bug in GraphQL::Dataloader, please report it on GitHub: https://github.com/rmosolgo/graphql-ruby/issues/new.
145
+ ERR
146
+ end
117
147
  result = @results[key]
118
148
 
119
149
  raise result if result.class <= StandardError
@@ -90,6 +90,16 @@ module GraphQL
90
90
  # Use a self-contained queue for the work in the block.
91
91
  def run_isolated
92
92
  prev_queue = @pending_jobs
93
+ prev_pending_keys = {}
94
+ @source_cache.each do |source_class, batched_sources|
95
+ batched_sources.each do |batch_args, batched_source_instance|
96
+ if batched_source_instance.pending?
97
+ prev_pending_keys[batched_source_instance] = batched_source_instance.pending_keys.dup
98
+ batched_source_instance.pending_keys.clear
99
+ end
100
+ end
101
+ end
102
+
93
103
  @pending_jobs = []
94
104
  res = nil
95
105
  # Make sure the block is inside a Fiber, so it can `Fiber.yield`
@@ -100,6 +110,9 @@ module GraphQL
100
110
  res
101
111
  ensure
102
112
  @pending_jobs = prev_queue
113
+ prev_pending_keys.each do |source_instance, pending_keys|
114
+ source_instance.pending_keys.concat(pending_keys)
115
+ end
103
116
  end
104
117
 
105
118
  # @api private Move along, move along
@@ -38,9 +38,17 @@ module GraphQL
38
38
  end
39
39
  end
40
40
 
41
- TYPE_CLASSES.each do |type_class|
42
- refine type_class.singleton_class do
43
- include Methods
41
+ if defined?(::Refinement) && Refinement.private_method_defined?(:import_methods)
42
+ TYPE_CLASSES.each do |type_class|
43
+ refine type_class.singleton_class do
44
+ import_methods Methods
45
+ end
46
+ end
47
+ else
48
+ TYPE_CLASSES.each do |type_class|
49
+ refine type_class.singleton_class do
50
+ include Methods
51
+ end
44
52
  end
45
53
  end
46
54
  end
@@ -3,11 +3,7 @@
3
3
  module GraphQL
4
4
  module Deprecation
5
5
  def self.warn(message)
6
- if defined?(ActiveSupport::Deprecation)
7
- ActiveSupport::Deprecation.warn(message)
8
- else
9
- Kernel.warn(message)
10
- end
6
+ Kernel.warn(message)
11
7
  end
12
8
  end
13
9
  end
@@ -12,9 +12,25 @@ module GraphQL
12
12
  # The value which couldn't be encoded
13
13
  attr_reader :integer_value
14
14
 
15
- def initialize(value)
15
+ # @return [GraphQL::Schema::Field] The field that returned a too-big integer
16
+ attr_reader :field
17
+
18
+ # @return [Array<String, Integer>] Where the field appeared in the GraphQL response
19
+ attr_reader :path
20
+
21
+ def initialize(value, context:)
16
22
  @integer_value = value
17
- super("Integer out of bounds: #{value}. \nConsider using ID or GraphQL::Types::BigInt instead.")
23
+ @field = context[:current_field]
24
+ @path = context[:current_path]
25
+ message = "Integer out of bounds: #{value}".dup
26
+ if @path
27
+ message << " @ #{@path.join(".")}"
28
+ end
29
+ if @field
30
+ message << " (#{@field.path})"
31
+ end
32
+ message << ". Consider using ID or GraphQL::Types::BigInt instead."
33
+ super(message)
18
34
  end
19
35
  end
20
36
  end
@@ -70,23 +70,42 @@ module GraphQL
70
70
  wrappers = context ? context.namespace(:connections)[:all_wrappers] : all_wrappers
71
71
  impl = wrapper_for(items, wrappers: wrappers)
72
72
 
73
- if impl.nil?
74
- raise ImplementationMissingError, "Couldn't find a connection wrapper for #{items.class} during #{field.path} (#{items.inspect})"
73
+ if impl
74
+ impl.new(
75
+ items,
76
+ context: context,
77
+ parent: parent,
78
+ field: field,
79
+ max_page_size: field.has_max_page_size? ? field.max_page_size : context.schema.default_max_page_size,
80
+ first: arguments[:first],
81
+ after: arguments[:after],
82
+ last: arguments[:last],
83
+ before: arguments[:before],
84
+ arguments: arguments,
85
+ edge_class: edge_class_for_field(field),
86
+ )
87
+ else
88
+ begin
89
+ connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(items)
90
+ if parent.is_a?(GraphQL::Schema::Object)
91
+ parent = parent.object
92
+ end
93
+ connection_class.new(
94
+ items,
95
+ arguments,
96
+ field: field,
97
+ max_page_size: field.max_page_size,
98
+ parent: parent,
99
+ context: context,
100
+ )
101
+ rescue RuntimeError => err
102
+ if err.message.include?("No connection implementation to wrap")
103
+ raise ImplementationMissingError, "Couldn't find a connection wrapper for #{items.class} during #{field.path} (#{items.inspect})"
104
+ else
105
+ raise err
106
+ end
107
+ end
75
108
  end
76
-
77
- impl.new(
78
- items,
79
- context: context,
80
- parent: parent,
81
- field: field,
82
- max_page_size: field.has_max_page_size? ? field.max_page_size : context.schema.default_max_page_size,
83
- first: arguments[:first],
84
- after: arguments[:after],
85
- last: arguments[:last],
86
- before: arguments[:before],
87
- arguments: arguments,
88
- edge_class: edge_class_for_field(field),
89
- )
90
109
  end
91
110
 
92
111
  # use an override if there is one
@@ -72,7 +72,7 @@ module GraphQL
72
72
  elsif @operation_name_error
73
73
  @validation_errors << @operation_name_error
74
74
  else
75
- validation_result = @schema.static_validator.validate(@query, validate: @validate, timeout: @schema.validate_timeout)
75
+ validation_result = @schema.static_validator.validate(@query, validate: @validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
76
76
  @validation_errors.concat(validation_result[:errors])
77
77
  @internal_representation = validation_result[:irep]
78
78
 
@@ -260,38 +260,67 @@ module GraphQL
260
260
  type.coerce_input(value, context)
261
261
  end
262
262
 
263
- # TODO this should probably be inside after_lazy
264
- if loads && !from_resolver?
265
- loaded_value = if type.list?
266
- loaded_values = coerced_value.map { |val| owner.load_application_object(self, loads, val, context) }
267
- context.schema.after_any_lazies(loaded_values) { |result| result }
268
- else
269
- context.query.with_error_handling do
270
- owner.load_application_object(self, loads, coerced_value, context)
263
+ # If this isn't lazy, then the block returns eagerly and assigns the result here
264
+ # If it _is_ lazy, then we write the lazy to the hash, then update it later
265
+ argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |resolved_coerced_value|
266
+ if loads && !from_resolver?
267
+ loaded_value = context.query.with_error_handling do
268
+ load_and_authorize_value(owner, coerced_value, context)
271
269
  end
272
270
  end
273
- end
274
271
 
275
- coerced_value = if loaded_value
276
- loaded_value
277
- else
278
- coerced_value
279
- end
272
+ maybe_loaded_value = loaded_value || resolved_coerced_value
273
+ context.schema.after_lazy(maybe_loaded_value) do |resolved_loaded_value|
274
+ owner.validate_directive_argument(self, resolved_loaded_value)
275
+ prepared_value = context.schema.error_handler.with_error_handling(context) do
276
+ prepare_value(parent_object, resolved_loaded_value, context: context)
277
+ end
280
278
 
281
- # If this isn't lazy, then the block returns eagerly and assigns the result here
282
- # If it _is_ lazy, then we write the lazy to the hash, then update it later
283
- argument_values[arg_key] = context.schema.after_lazy(coerced_value) do |coerced_value|
284
- owner.validate_directive_argument(self, coerced_value)
285
- prepared_value = context.schema.error_handler.with_error_handling(context) do
286
- prepare_value(parent_object, coerced_value, context: context)
279
+ # TODO code smell to access such a deeply-nested constant in a distant module
280
+ argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
281
+ value: prepared_value,
282
+ definition: self,
283
+ default_used: default_used,
284
+ )
287
285
  end
286
+ end
287
+ end
288
288
 
289
- # TODO code smell to access such a deeply-nested constant in a distant module
290
- argument_values[arg_key] = GraphQL::Execution::Interpreter::ArgumentValue.new(
291
- value: prepared_value,
292
- definition: self,
293
- default_used: default_used,
294
- )
289
+ def load_and_authorize_value(load_method_owner, coerced_value, context)
290
+ if coerced_value.nil?
291
+ return nil
292
+ end
293
+ arg_load_method = "load_#{keyword}"
294
+ if load_method_owner.respond_to?(arg_load_method)
295
+ custom_loaded_value = if load_method_owner.is_a?(Class)
296
+ load_method_owner.public_send(arg_load_method, coerced_value, context)
297
+ else
298
+ load_method_owner.public_send(arg_load_method, coerced_value)
299
+ end
300
+ context.schema.after_lazy(custom_loaded_value) do |custom_value|
301
+ if loads
302
+ if type.list?
303
+ loaded_values = custom_value.each_with_index.map { |custom_val, idx|
304
+ id = coerced_value[idx]
305
+ load_method_owner.authorize_application_object(self, id, context, custom_val)
306
+ }
307
+ context.schema.after_any_lazies(loaded_values, &:itself)
308
+ else
309
+ load_method_owner.authorize_application_object(self, coerced_value, context, custom_loaded_value)
310
+ end
311
+ else
312
+ custom_value
313
+ end
314
+ end
315
+ elsif loads
316
+ if type.list?
317
+ loaded_values = coerced_value.map { |val| load_method_owner.load_and_authorize_application_object(self, val, context) }
318
+ context.schema.after_any_lazies(loaded_values, &:itself)
319
+ else
320
+ load_method_owner.load_and_authorize_application_object(self, coerced_value, context)
321
+ end
322
+ else
323
+ coerced_value
295
324
  end
296
325
  end
297
326
 
@@ -122,6 +122,9 @@ module GraphQL
122
122
  else
123
123
  kwargs[:type] = type
124
124
  end
125
+ if type.is_a?(Class) && type < GraphQL::Schema::Mutation
126
+ raise ArgumentError, "Use `field #{name.inspect}, mutation: Mutation, ...` to provide a mutation to this field instead"
127
+ end
125
128
  end
126
129
  new(**kwargs, &block)
127
130
  end
@@ -510,6 +513,7 @@ module GraphQL
510
513
  field_defn
511
514
  end
512
515
 
516
+ class MissingReturnTypeError < GraphQL::Error; end
513
517
  attr_writer :type
514
518
 
515
519
  def type
@@ -517,14 +521,21 @@ module GraphQL
517
521
  Member::BuildType.parse_type(@function.type, null: false)
518
522
  elsif @field
519
523
  Member::BuildType.parse_type(@field.type, null: false)
524
+ elsif @return_type_expr.nil?
525
+ # Not enough info to determine type
526
+ message = "Can't determine the return type for #{self.path}"
527
+ if @resolver_class
528
+ message += " (it has `resolver: #{@resolver_class}`, consider configuration a `type ...` for that class)"
529
+ end
530
+ raise MissingReturnTypeError, message
520
531
  else
521
532
  Member::BuildType.parse_type(@return_type_expr, null: @return_type_null)
522
533
  end
523
- rescue GraphQL::Schema::InvalidDocumentError => err
534
+ rescue GraphQL::Schema::InvalidDocumentError, MissingReturnTypeError => err
524
535
  # Let this propagate up
525
536
  raise err
526
537
  rescue StandardError => err
527
- raise ArgumentError, "Failed to build return type for #{@owner.graphql_name}.#{name} from #{@return_type_expr.inspect}: (#{err.class}) #{err.message}", err.backtrace
538
+ raise MissingReturnTypeError, "Failed to build return type for #{@owner.graphql_name}.#{name} from #{@return_type_expr.inspect}: (#{err.class}) #{err.message}", err.backtrace
528
539
  end
529
540
 
530
541
  def visible?(context)
@@ -608,8 +619,7 @@ module GraphQL
608
619
  if is_authorized
609
620
  public_send_field(object, args, ctx)
610
621
  else
611
- err = GraphQL::UnauthorizedFieldError.new(object: application_object, type: object.class, context: ctx, field: self)
612
- ctx.schema.unauthorized_field(err)
622
+ raise GraphQL::UnauthorizedFieldError.new(object: application_object, type: object.class, context: ctx, field: self)
613
623
  end
614
624
  end
615
625
  rescue GraphQL::UnauthorizedFieldError => err
@@ -40,11 +40,7 @@ module GraphQL
40
40
  # With the interpreter, it's done during `coerce_arguments`
41
41
  if loads && !arg_defn.from_resolver? && !context.interpreter?
42
42
  value = @ruby_style_hash[ruby_kwargs_key]
43
- loaded_value = if arg_defn.type.list?
44
- value.map { |val| load_application_object(arg_defn, loads, val, context) }
45
- else
46
- load_application_object(arg_defn, loads, value, context)
47
- end
43
+ loaded_value = arg_defn.load_and_authorize_value(self, value, context)
48
44
  maybe_lazies << context.schema.after_lazy(loaded_value) do |loaded_value|
49
45
  overwrite_argument(ruby_kwargs_key, loaded_value)
50
46
  end