graphql 2.3.2 → 2.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 573ce6f5423ca2d9eb0ca3dab40f01869501f834c3b48d5cac7f7c06fbf36da9
4
- data.tar.gz: c3b1f0393d2838a2478a36a43cec88560832c220a3896f2ee4c715d013d1758c
3
+ metadata.gz: d1511256e7812b5c2de2a01ffa44f8a77f2e8959837344eaf1c8780d0b1bf700
4
+ data.tar.gz: 87a0734b541d8f2cbbd3fb293a63663cbc57c61e6ab39242449596c6ca759442
5
5
  SHA512:
6
- metadata.gz: 14d6c96c20c8fdb56ecddf0279e24e83c862d4133c72b3cebc44dca9e40e1c684b4f4a4c45fca81451d48d1bb97a4e6c3ae13499a40e12a76926e679a12a13f2
7
- data.tar.gz: 44157aaa761da8c9f82afa9e31533ee3c87cdf4257256ec84f70f0e30dff8dc1830486c2ff02b4464a67e8815518466451ae598eabc12249cf2edaad6a9371f1
6
+ metadata.gz: fff5ef36d8e8dff310cac664178ebf0e902cd067a893fedd164902625751fe457a070f1daf2a2251d0dd2ec57fb16daccc81b54267048bbb71c027caf7905100
7
+ data.tar.gz: 5fc4e6c4a44398e9f77d99c5224d22128a9c80e64a17a156500337b4d658270da9aa7af71f8d06cc065939cc42b41de3e07d66cb7622704ad179424c312dd7a0
@@ -8,6 +8,7 @@ module GraphQL
8
8
  # - `complexities_on_type` holds complexity scores for each type
9
9
  def initialize(query)
10
10
  super
11
+ @skip_introspection_fields = !query.schema.max_complexity_count_introspection_fields
11
12
  @complexities_on_type_by_query = {}
12
13
  end
13
14
 
@@ -51,6 +52,7 @@ module GraphQL
51
52
  # we'll visit them when we hit the spreads instead
52
53
  return if visitor.visiting_fragment_definition?
53
54
  return if visitor.skipping?
55
+ return if @skip_introspection_fields && visitor.field_definition.introspection?
54
56
  parent_type = visitor.parent_type_definition
55
57
  field_key = node.alias || node.name
56
58
 
@@ -68,6 +70,7 @@ module GraphQL
68
70
  # we'll visit them when we hit the spreads instead
69
71
  return if visitor.visiting_fragment_definition?
70
72
  return if visitor.skipping?
73
+ return if @skip_introspection_fields && visitor.field_definition.introspection?
71
74
  scopes_stack = @complexities_on_type_by_query[visitor.query]
72
75
  scopes_stack.pop
73
76
  end
@@ -5,8 +5,10 @@ module GraphQL
5
5
  class Interpreter
6
6
  class Runtime
7
7
  module GraphQLResult
8
- def initialize(result_name, parent_result, is_non_null_in_parent)
8
+ def initialize(result_name, result_type, application_value, parent_result, is_non_null_in_parent)
9
9
  @graphql_parent = parent_result
10
+ @graphql_application_value = application_value
11
+ @graphql_result_type = result_type
10
12
  if parent_result && parent_result.graphql_dead
11
13
  @graphql_dead = true
12
14
  end
@@ -26,14 +28,14 @@ module GraphQL
26
28
  end
27
29
 
28
30
  attr_accessor :graphql_dead
29
- attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent
31
+ attr_reader :graphql_parent, :graphql_result_name, :graphql_is_non_null_in_parent, :graphql_application_value, :graphql_result_type
30
32
 
31
33
  # @return [Hash] Plain-Ruby result data (`@graphql_metadata` contains Result wrapper objects)
32
34
  attr_accessor :graphql_result_data
33
35
  end
34
36
 
35
37
  class GraphQLResultHash
36
- def initialize(_result_name, _parent_result, _is_non_null_in_parent)
38
+ def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent)
37
39
  super
38
40
  @graphql_result_data = {}
39
41
  end
@@ -121,7 +123,7 @@ module GraphQL
121
123
  class GraphQLResultArray
122
124
  include GraphQLResult
123
125
 
124
- def initialize(_result_name, _parent_result, _is_non_null_in_parent)
126
+ def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent)
125
127
  super
126
128
  @graphql_result_data = []
127
129
  end
@@ -11,7 +11,6 @@ module GraphQL
11
11
  class Runtime
12
12
  class CurrentState
13
13
  def initialize
14
- @current_object = nil
15
14
  @current_field = nil
16
15
  @current_arguments = nil
17
16
  @current_result_name = nil
@@ -19,8 +18,12 @@ module GraphQL
19
18
  @was_authorized_by_scope_items = nil
20
19
  end
21
20
 
21
+ def current_object
22
+ @current_result.graphql_application_value
23
+ end
24
+
22
25
  attr_accessor :current_result, :current_result_name,
23
- :current_arguments, :current_field, :current_object, :was_authorized_by_scope_items
26
+ :current_arguments, :current_field, :was_authorized_by_scope_items
24
27
  end
25
28
 
26
29
  # @return [GraphQL::Query]
@@ -39,7 +42,7 @@ module GraphQL
39
42
  @lazies_at_depth = lazies_at_depth
40
43
  @schema = query.schema
41
44
  @context = query.context
42
- @response = GraphQLResultHash.new(nil, nil, false)
45
+ @response = nil
43
46
  # Identify runtime directives by checking which of this schema's directives have overridden `def self.resolve`
44
47
  @runtime_directive_names = []
45
48
  noop_resolve_owner = GraphQL::Schema::Directive.singleton_class
@@ -79,12 +82,11 @@ module GraphQL
79
82
  root_operation = query.selected_operation
80
83
  root_op_type = root_operation.operation_type || "query"
81
84
  root_type = schema.root_type_for_operation(root_op_type)
82
-
83
- st = get_current_runtime_state
84
- st.current_object = query.root_value
85
- st.current_result = @response
86
85
  runtime_object = root_type.wrap(query.root_value, context)
87
86
  runtime_object = schema.sync_lazy(runtime_object)
87
+ @response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false)
88
+ st = get_current_runtime_state
89
+ st.current_result = @response
88
90
 
89
91
  if runtime_object.nil?
90
92
  # Root .authorized? returned false.
@@ -101,7 +103,7 @@ module GraphQL
101
103
  # directly evaluated and the results can be written right into the main response hash.
102
104
  tap_or_each(gathered_selections) do |selections, is_selection_array|
103
105
  if is_selection_array
104
- selection_response = GraphQLResultHash.new(nil, nil, false)
106
+ selection_response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false)
105
107
  final_response = @response
106
108
  else
107
109
  selection_response = @response
@@ -109,26 +111,14 @@ module GraphQL
109
111
  end
110
112
 
111
113
  @dataloader.append_job {
112
- st = get_current_runtime_state
113
- st.current_object = query.root_value
114
- st.current_result_name = nil
115
- st.current_result = selection_response
116
- # This is a less-frequent case; use a fast check since it's often not there.
117
- if (directives = selections[:graphql_directives])
118
- selections.delete(:graphql_directives)
119
- end
120
- call_method_on_directives(:resolve, runtime_object, directives) do
121
- evaluate_selections(
122
- runtime_object,
123
- root_type,
124
- root_op_type == "mutation",
125
- selections,
126
- selection_response,
127
- final_response,
128
- nil,
129
- st,
130
- )
131
- end
114
+ evaluate_selections(
115
+ root_op_type == "mutation",
116
+ selections,
117
+ selection_response,
118
+ final_response,
119
+ nil,
120
+ nil,
121
+ )
132
122
  }
133
123
  end
134
124
  end
@@ -205,36 +195,44 @@ module GraphQL
205
195
  NO_ARGS = GraphQL::EmptyObjects::EMPTY_HASH
206
196
 
207
197
  # @return [void]
208
- def evaluate_selections(owner_object, owner_type, is_eager_selection, gathered_selections, selections_result, target_result, parent_object, runtime_state) # rubocop:disable Metrics/ParameterLists
209
- finished_jobs = 0
210
- enqueued_jobs = gathered_selections.size
211
- gathered_selections.each do |result_name, field_ast_nodes_or_ast_node|
212
- @dataloader.append_job {
213
- runtime_state = get_current_runtime_state
214
- evaluate_selection(
215
- result_name, field_ast_nodes_or_ast_node, owner_object, owner_type, is_eager_selection, selections_result, parent_object, runtime_state
216
- )
217
- finished_jobs += 1
218
- if target_result && finished_jobs == enqueued_jobs
219
- selections_result.merge_into(target_result)
198
+ def evaluate_selections(is_eager_selection, gathered_selections, selections_result, target_result, parent_object, runtime_state) # rubocop:disable Metrics/ParameterLists
199
+ runtime_state ||= get_current_runtime_state
200
+ runtime_state.current_result_name = nil
201
+ runtime_state.current_result = selections_result
202
+ # This is a less-frequent case; use a fast check since it's often not there.
203
+ if (directives = gathered_selections[:graphql_directives])
204
+ gathered_selections.delete(:graphql_directives)
205
+ end
206
+
207
+ call_method_on_directives(:resolve, selections_result.graphql_application_value, directives) do
208
+ finished_jobs = 0
209
+ enqueued_jobs = gathered_selections.size
210
+ gathered_selections.each do |result_name, field_ast_nodes_or_ast_node|
211
+ @dataloader.append_job {
212
+ evaluate_selection(
213
+ result_name, field_ast_nodes_or_ast_node, is_eager_selection, selections_result, parent_object
214
+ )
215
+ finished_jobs += 1
216
+ if target_result && finished_jobs == enqueued_jobs
217
+ selections_result.merge_into(target_result)
218
+ end
219
+ }
220
+ # Field resolution may pause the fiber,
221
+ # so it wouldn't get to the `Resolve` call that happens below.
222
+ # So instead trigger a run from this outer context.
223
+ if is_eager_selection
224
+ @dataloader.clear_cache
225
+ @dataloader.run
226
+ @dataloader.clear_cache
220
227
  end
221
- }
222
- # Field resolution may pause the fiber,
223
- # so it wouldn't get to the `Resolve` call that happens below.
224
- # So instead trigger a run from this outer context.
225
- if is_eager_selection
226
- @dataloader.clear_cache
227
- @dataloader.run
228
- @dataloader.clear_cache
229
228
  end
229
+ selections_result
230
230
  end
231
-
232
- selections_result
233
231
  end
234
232
 
235
233
  # @return [void]
236
- def evaluate_selection(result_name, field_ast_nodes_or_ast_node, owner_object, owner_type, is_eager_field, selections_result, parent_object, runtime_state) # rubocop:disable Metrics/ParameterLists
237
- return if dead_result?(selections_result)
234
+ def evaluate_selection(result_name, field_ast_nodes_or_ast_node, is_eager_field, selections_result, parent_object) # rubocop:disable Metrics/ParameterLists
235
+ return if selections_result.graphql_dead
238
236
  # As a performance optimization, the hash key will be a `Node` if
239
237
  # there's only one selection of the field. But if there are multiple
240
238
  # selections of the field, it will be an Array of nodes
@@ -246,13 +244,16 @@ module GraphQL
246
244
  ast_node = field_ast_nodes_or_ast_node
247
245
  end
248
246
  field_name = ast_node.name
247
+ owner_type = selections_result.graphql_result_type
249
248
  field_defn = query.warden.get_field(owner_type, field_name)
250
249
 
251
250
  # Set this before calling `run_with_directives`, so that the directive can have the latest path
251
+ runtime_state = get_current_runtime_state
252
252
  runtime_state.current_field = field_defn
253
253
  runtime_state.current_result = selections_result
254
254
  runtime_state.current_result_name = result_name
255
255
 
256
+ owner_object = selections_result.graphql_application_value
256
257
  if field_defn.dynamic_introspection
257
258
  owner_object = field_defn.owner.wrap(owner_object, context)
258
259
  end
@@ -262,24 +263,24 @@ module GraphQL
262
263
  resolved_arguments = GraphQL::Execution::Interpreter::Arguments::EMPTY
263
264
  if field_defn.extras.size == 0
264
265
  evaluate_selection_with_resolved_keyword_args(
265
- NO_ARGS, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, return_type.non_null?, runtime_state
266
+ NO_ARGS, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, return_type.non_null?, runtime_state
266
267
  )
267
268
  else
268
- evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, runtime_state)
269
+ evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, runtime_state)
269
270
  end
270
271
  else
271
272
  @query.arguments_cache.dataload_for(ast_node, field_defn, owner_object) do |resolved_arguments|
272
273
  runtime_state = get_current_runtime_state # This might be in a different fiber
273
- evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, runtime_state)
274
+ evaluate_selection_with_args(resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_object, is_eager_field, result_name, selections_result, parent_object, return_type, runtime_state)
274
275
  end
275
276
  end
276
277
  end
277
278
 
278
- def evaluate_selection_with_args(arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type, runtime_state) # rubocop:disable Metrics/ParameterLists
279
+ def evaluate_selection_with_args(arguments, field_defn, ast_node, field_ast_nodes, object, is_eager_field, result_name, selection_result, parent_object, return_type, runtime_state) # rubocop:disable Metrics/ParameterLists
279
280
  after_lazy(arguments, field: field_defn, ast_node: ast_node, owner_object: object, arguments: arguments, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |resolved_arguments, runtime_state|
280
281
  return_type_non_null = return_type.non_null?
281
282
  if resolved_arguments.is_a?(GraphQL::ExecutionError) || resolved_arguments.is_a?(GraphQL::UnauthorizedError)
282
- continue_value(resolved_arguments, owner_type, field_defn, return_type_non_null, ast_node, result_name, selection_result)
283
+ continue_value(resolved_arguments, field_defn, return_type_non_null, ast_node, result_name, selection_result)
283
284
  next
284
285
  end
285
286
 
@@ -328,13 +329,12 @@ module GraphQL
328
329
  resolved_arguments.keyword_arguments
329
330
  end
330
331
 
331
- evaluate_selection_with_resolved_keyword_args(kwarg_arguments, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type, return_type_non_null, runtime_state)
332
+ evaluate_selection_with_resolved_keyword_args(kwarg_arguments, resolved_arguments, field_defn, ast_node, field_ast_nodes, object, is_eager_field, result_name, selection_result, parent_object, return_type, return_type_non_null, runtime_state)
332
333
  end
333
334
  end
334
335
 
335
- def evaluate_selection_with_resolved_keyword_args(kwarg_arguments, resolved_arguments, field_defn, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type, return_type_non_null, runtime_state) # rubocop:disable Metrics/ParameterLists
336
+ def evaluate_selection_with_resolved_keyword_args(kwarg_arguments, resolved_arguments, field_defn, ast_node, field_ast_nodes, object, is_eager_field, result_name, selection_result, parent_object, return_type, return_type_non_null, runtime_state) # rubocop:disable Metrics/ParameterLists
336
337
  runtime_state.current_field = field_defn
337
- runtime_state.current_object = object
338
338
  runtime_state.current_arguments = resolved_arguments
339
339
  runtime_state.current_result_name = result_name
340
340
  runtime_state.current_result = selection_result
@@ -356,7 +356,6 @@ module GraphQL
356
356
  # This might be executed in a different context; reset this info
357
357
  runtime_state = get_current_runtime_state
358
358
  runtime_state.current_field = field_defn
359
- runtime_state.current_object = object
360
359
  runtime_state.current_arguments = resolved_arguments
361
360
  runtime_state.current_result_name = result_name
362
361
  runtime_state.current_result = selection_result
@@ -376,7 +375,8 @@ module GraphQL
376
375
  end
377
376
  end
378
377
  after_lazy(app_result, field: field_defn, ast_node: ast_node, owner_object: object, arguments: resolved_arguments, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |inner_result, runtime_state|
379
- continue_value = continue_value(inner_result, owner_type, field_defn, return_type_non_null, ast_node, result_name, selection_result)
378
+ owner_type = selection_result.graphql_result_type
379
+ continue_value = continue_value(inner_result, field_defn, return_type_non_null, ast_node, result_name, selection_result)
380
380
  if HALT != continue_value
381
381
  was_scoped = runtime_state.was_authorized_by_scope_items
382
382
  runtime_state.was_authorized_by_scope_items = nil
@@ -384,25 +384,16 @@ module GraphQL
384
384
  end
385
385
  end
386
386
  end
387
-
388
387
  # If this field is a root mutation field, immediately resolve
389
388
  # all of its child fields before moving on to the next root mutation field.
390
389
  # (Subselections of this mutation will still be resolved level-by-level.)
391
390
  if is_eager_field
392
391
  Interpreter::Resolve.resolve_all([field_result], @dataloader)
393
- else
394
- # Return this from `after_lazy` because it might be another lazy that needs to be resolved
395
- field_result
396
392
  end
397
393
  end
398
394
 
399
-
400
- def dead_result?(selection_result)
401
- selection_result.graphql_dead # || ((parent = selection_result.graphql_parent) && parent.graphql_dead)
402
- end
403
-
404
395
  def set_result(selection_result, result_name, value, is_child_result, is_non_null)
405
- if !dead_result?(selection_result)
396
+ if !selection_result.graphql_dead
406
397
  if value.nil? && is_non_null
407
398
  # This is an invalid nil that should be propagated
408
399
  # One caller of this method passes a block,
@@ -456,11 +447,13 @@ module GraphQL
456
447
  end
457
448
 
458
449
  HALT = Object.new
459
- def continue_value(value, parent_type, field, is_non_null, ast_node, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
450
+ def continue_value(value, field, is_non_null, ast_node, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
460
451
  case value
461
452
  when nil
462
453
  if is_non_null
463
454
  set_result(selection_result, result_name, nil, false, is_non_null) do
455
+ # When this comes from a list item, use the parent object:
456
+ parent_type = selection_result.is_a?(GraphQLResultArray) ? selection_result.graphql_parent.graphql_result_type : selection_result.graphql_result_type
464
457
  # This block is called if `result_name` is not dead. (Maybe a previous invalid nil caused it be marked dead.)
465
458
  err = parent_type::InvalidNullError.new(parent_type, field, value)
466
459
  schema.type_error(err, context)
@@ -474,7 +467,7 @@ module GraphQL
474
467
  # to avoid the overhead of checking three different classes
475
468
  # every time.
476
469
  if value.is_a?(GraphQL::ExecutionError)
477
- if selection_result.nil? || !dead_result?(selection_result)
470
+ if selection_result.nil? || !selection_result.graphql_dead
478
471
  value.path ||= current_path
479
472
  value.ast_node ||= ast_node
480
473
  context.errors << value
@@ -492,7 +485,7 @@ module GraphQL
492
485
  rescue GraphQL::ExecutionError => err
493
486
  err
494
487
  end
495
- continue_value(next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
488
+ continue_value(next_value, field, is_non_null, ast_node, result_name, selection_result)
496
489
  elsif value.is_a?(GraphQL::UnauthorizedError)
497
490
  # this hook might raise & crash, or it might return
498
491
  # a replacement value
@@ -501,7 +494,7 @@ module GraphQL
501
494
  rescue GraphQL::ExecutionError => err
502
495
  err
503
496
  end
504
- continue_value(next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
497
+ continue_value(next_value, field, is_non_null, ast_node, result_name, selection_result)
505
498
  elsif GraphQL::Execution::SKIP == value
506
499
  # It's possible a lazy was already written here
507
500
  case selection_result
@@ -524,7 +517,7 @@ module GraphQL
524
517
  # It's an array full of execution errors; add them all.
525
518
  if value.any? && value.all?(GraphQL::ExecutionError)
526
519
  list_type_at_all = (field && (field.type.list?))
527
- if selection_result.nil? || !dead_result?(selection_result)
520
+ if selection_result.nil? || !selection_result.graphql_dead
528
521
  value.each_with_index do |error, index|
529
522
  error.ast_node ||= ast_node
530
523
  error.path ||= current_path + (list_type_at_all ? [index] : [])
@@ -604,9 +597,9 @@ module GraphQL
604
597
  err
605
598
  end
606
599
  after_lazy(object_proxy, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, trace: false, result_name: result_name, result: selection_result, runtime_state: runtime_state) do |inner_object, runtime_state|
607
- continue_value = continue_value(inner_object, owner_type, field, is_non_null, ast_node, result_name, selection_result)
600
+ continue_value = continue_value(inner_object, field, is_non_null, ast_node, result_name, selection_result)
608
601
  if HALT != continue_value
609
- response_hash = GraphQLResultHash.new(result_name, selection_result, is_non_null)
602
+ response_hash = GraphQLResultHash.new(result_name, current_type, continue_value, selection_result, is_non_null)
610
603
  set_result(selection_result, result_name, response_hash, true, is_non_null)
611
604
 
612
605
  gathered_selections = gather_selections(continue_value, current_type, next_selections)
@@ -620,34 +613,21 @@ module GraphQL
620
613
  # (Technically, it's possible that one of those entries _doesn't_ require isolation.)
621
614
  tap_or_each(gathered_selections) do |selections, is_selection_array|
622
615
  if is_selection_array
623
- this_result = GraphQLResultHash.new(result_name, selection_result, is_non_null)
616
+ this_result = GraphQLResultHash.new(result_name, current_type, continue_value, selection_result, is_non_null)
624
617
  final_result = response_hash
625
618
  else
626
619
  this_result = response_hash
627
620
  final_result = nil
628
621
  end
629
- # reset this mutable state
630
- # Unset `result_name` here because it's already included in the new response hash
631
- runtime_state.current_object = continue_value
632
- runtime_state.current_result_name = nil
633
- runtime_state.current_result = this_result
634
- # This is a less-frequent case; use a fast check since it's often not there.
635
- if (directives = selections[:graphql_directives])
636
- selections.delete(:graphql_directives)
637
- end
638
- call_method_on_directives(:resolve, continue_value, directives) do
639
- evaluate_selections(
640
- continue_value,
641
- current_type,
642
- false,
643
- selections,
644
- this_result,
645
- final_result,
646
- owner_object.object,
647
- runtime_state,
648
- )
649
- this_result
650
- end
622
+
623
+ evaluate_selections(
624
+ false,
625
+ selections,
626
+ this_result,
627
+ final_result,
628
+ owner_object.object,
629
+ runtime_state,
630
+ )
651
631
  end
652
632
  end
653
633
  end
@@ -656,7 +636,7 @@ module GraphQL
656
636
  # This is true for objects, unions, and interfaces
657
637
  use_dataloader_job = !inner_type.unwrap.kind.input?
658
638
  inner_type_non_null = inner_type.non_null?
659
- response_list = GraphQLResultArray.new(result_name, selection_result, is_non_null)
639
+ response_list = GraphQLResultArray.new(result_name, current_type, response_list, selection_result, is_non_null)
660
640
  set_result(selection_result, result_name, response_list, true, is_non_null)
661
641
  idx = nil
662
642
  list_value = begin
@@ -694,7 +674,7 @@ module GraphQL
694
674
  end
695
675
  # Detect whether this error came while calling `.each` (before `idx` is set) or while running list *items* (after `idx` is set)
696
676
  error_is_non_null = idx.nil? ? is_non_null : inner_type.non_null?
697
- continue_value(list_value, owner_type, field, error_is_non_null, ast_node, result_name, selection_result)
677
+ continue_value(list_value, field, error_is_non_null, ast_node, result_name, selection_result)
698
678
  else
699
679
  raise "Invariant: Unhandled type kind #{current_type.kind} (#{current_type})"
700
680
  end
@@ -706,7 +686,7 @@ module GraphQL
706
686
  call_method_on_directives(:resolve_each, owner_object, ast_node.directives) do
707
687
  # This will update `response_list` with the lazy
708
688
  after_lazy(inner_value, ast_node: ast_node, field: field, owner_object: owner_object, arguments: arguments, result_name: this_idx, result: response_list, runtime_state: runtime_state) do |inner_inner_value, runtime_state|
709
- continue_value = continue_value(inner_inner_value, owner_type, field, inner_type_non_null, ast_node, this_idx, response_list)
689
+ continue_value = continue_value(inner_inner_value, field, inner_type_non_null, ast_node, this_idx, response_list)
710
690
  if HALT != continue_value
711
691
  continue_field(continue_value, owner_type, field, inner_type, ast_node, next_selections, false, owner_object, arguments, this_idx, response_list, was_scoped, runtime_state)
712
692
  end
@@ -728,7 +708,6 @@ module GraphQL
728
708
  raw_dir_args = arguments(nil, dir_defn, dir_node)
729
709
  dir_args = continue_value(
730
710
  raw_dir_args, # value
731
- dir_defn, # parent_type
732
711
  nil, # field
733
712
  false, # is_non_null
734
713
  dir_node, # ast_node
@@ -794,7 +773,6 @@ module GraphQL
794
773
  # In that case, this will initialize a new state
795
774
  # to avoid conflicting with the parent fiber.
796
775
  runtime_state = get_current_runtime_state
797
- runtime_state.current_object = owner_object
798
776
  runtime_state.current_field = field
799
777
  runtime_state.current_arguments = arguments
800
778
  runtime_state.current_result_name = result_name
@@ -25,21 +25,15 @@ module GraphQL
25
25
  attr_reader :filename
26
26
 
27
27
  def line
28
- @line ||= (@source_string && @pos) ? @source_string[0..@pos].count("\n") + 1 : nil
28
+ @line ||= @source.line_at(@pos)
29
29
  end
30
30
 
31
31
  def col
32
- @col ||= if @source_string && @pos
33
- if @pos == 0
34
- 1
35
- else
36
- @source_string[0..@pos].split("\n").last.length
37
- end
38
- end
32
+ @col ||= @source.column_at(@pos)
39
33
  end
40
34
 
41
35
  def definition_line
42
- @definition_line ||= (@source_string && @definition_pos) ? @source_string[0..@definition_pos].count("\n") + 1 : nil
36
+ @definition_line ||= (@source && @definition_pos) ? @source.line_at(@definition_pos) : nil
43
37
  end
44
38
 
45
39
  # Value equality
@@ -267,7 +261,7 @@ module GraphQL
267
261
  "col: nil",
268
262
  "pos: nil",
269
263
  "filename: nil",
270
- "source_string: nil",
264
+ "source: nil",
271
265
  ]
272
266
 
273
267
  def generate_initialize
@@ -306,7 +300,7 @@ module GraphQL
306
300
  @col = col
307
301
  @pos = pos
308
302
  @filename = filename
309
- @source_string = source_string
303
+ @source = source
310
304
  #{assignments.join("\n")}
311
305
  end
312
306
 
@@ -385,7 +379,7 @@ module GraphQL
385
379
  # @!attribute selections
386
380
  # @return [Array<Nodes::Field>] Selections on this object (or empty array if this is a scalar field)
387
381
 
388
- def initialize(name: nil, arguments: NONE, directives: NONE, selections: NONE, field_alias: nil, line: nil, col: nil, pos: nil, filename: nil, source_string: nil)
382
+ def initialize(name: nil, arguments: NONE, directives: NONE, selections: NONE, field_alias: nil, line: nil, col: nil, pos: nil, filename: nil, source: nil)
389
383
  @name = name
390
384
  @arguments = arguments || NONE
391
385
  @directives = directives || NONE
@@ -396,7 +390,7 @@ module GraphQL
396
390
  @col = col
397
391
  @pos = pos
398
392
  @filename = filename
399
- @source_string = source_string
393
+ @source = source
400
394
  end
401
395
 
402
396
  def self.from_a(filename, line, col, field_alias, name, arguments, directives, selections) # rubocop:disable Metrics/ParameterLists
@@ -421,14 +415,14 @@ module GraphQL
421
415
 
422
416
  # @!attribute type
423
417
  # @return [String] the type condition for this fragment (name of type which it may apply to)
424
- def initialize(name: nil, type: nil, directives: NONE, selections: NONE, filename: nil, pos: nil, source_string: nil, line: nil, col: nil)
418
+ def initialize(name: nil, type: nil, directives: NONE, selections: NONE, filename: nil, pos: nil, source: nil, line: nil, col: nil)
425
419
  @name = name
426
420
  @type = type
427
421
  @directives = directives
428
422
  @selections = selections
429
423
  @filename = filename
430
424
  @pos = pos
431
- @source_string = source_string
425
+ @source = source
432
426
  @line = line
433
427
  @col = col
434
428
  end
@@ -36,6 +36,7 @@ module GraphQL
36
36
  @filename = filename
37
37
  @trace = trace
38
38
  @dedup_identifiers = false
39
+ @lines_at = nil
39
40
  end
40
41
 
41
42
  def parse
@@ -48,9 +49,43 @@ module GraphQL
48
49
  end
49
50
  end
50
51
 
52
+ def line_at(pos)
53
+ line = lines_at.bsearch_index { |l| l >= pos }
54
+ if line.nil?
55
+ @lines_at.size + 1
56
+ else
57
+ line + 1
58
+ end
59
+ end
60
+
61
+ def column_at(pos)
62
+ next_line_idx = lines_at.bsearch_index { |l| l >= pos } || 0
63
+ if next_line_idx > 0
64
+ line_pos = @lines_at[next_line_idx - 1]
65
+ pos - line_pos
66
+ else
67
+ pos + 1
68
+ end
69
+ end
51
70
 
52
71
  private
53
72
 
73
+ # @return [Array<Integer>] Positions of each line break in the original string
74
+ def lines_at
75
+ @lines_at ||= begin
76
+ la = []
77
+ idx = 0
78
+ while idx
79
+ idx = @graphql_str.index("\n", idx)
80
+ if idx
81
+ la << idx
82
+ idx += 1
83
+ end
84
+ end
85
+ la
86
+ end
87
+ end
88
+
54
89
  attr_reader :token_name
55
90
 
56
91
  def advance_token
@@ -73,7 +108,7 @@ module GraphQL
73
108
  while !@lexer.eos?
74
109
  defns << definition
75
110
  end
76
- Document.new(pos: 0, definitions: defns, filename: @filename, source_string: @graphql_str)
111
+ Document.new(pos: 0, definitions: defns, filename: @filename, source: self)
77
112
  end
78
113
 
79
114
  def definition
@@ -95,7 +130,7 @@ module GraphQL
95
130
  directives: directives,
96
131
  selections: selections,
97
132
  filename: @filename,
98
- source_string: @graphql_str
133
+ source: self
99
134
  )
100
135
  when :QUERY, :MUTATION, :SUBSCRIPTION, :LCURLY
101
136
  op_loc = pos
@@ -131,7 +166,7 @@ module GraphQL
131
166
  default_value: default_value,
132
167
  directives: directives,
133
168
  filename: @filename,
134
- source_string: @graphql_str
169
+ source: self
135
170
  )
136
171
  end
137
172
  expect_token(:RPAREN)
@@ -150,7 +185,7 @@ module GraphQL
150
185
  directives: directives,
151
186
  selections: selection_set,
152
187
  filename: @filename,
153
- source_string: @graphql_str
188
+ source: self
154
189
  )
155
190
  when :EXTEND
156
191
  loc = pos
@@ -160,7 +195,7 @@ module GraphQL
160
195
  advance_token
161
196
  name = parse_name
162
197
  directives = parse_directives
163
- ScalarTypeExtension.new(pos: loc, name: name, directives: directives, filename: @filename, source_string: @graphql_str)
198
+ ScalarTypeExtension.new(pos: loc, name: name, directives: directives, filename: @filename, source: self)
164
199
  when :TYPE
165
200
  advance_token
166
201
  name = parse_name
@@ -168,32 +203,32 @@ module GraphQL
168
203
  directives = parse_directives
169
204
  field_defns = at?(:LCURLY) ? parse_field_definitions : EMPTY_ARRAY
170
205
 
171
- ObjectTypeExtension.new(pos: loc, name: name, interfaces: implements_interfaces, directives: directives, fields: field_defns, filename: @filename, source_string: @graphql_str)
206
+ ObjectTypeExtension.new(pos: loc, name: name, interfaces: implements_interfaces, directives: directives, fields: field_defns, filename: @filename, source: self)
172
207
  when :INTERFACE
173
208
  advance_token
174
209
  name = parse_name
175
210
  directives = parse_directives
176
211
  interfaces = parse_implements
177
212
  fields_definition = at?(:LCURLY) ? parse_field_definitions : EMPTY_ARRAY
178
- InterfaceTypeExtension.new(pos: loc, name: name, directives: directives, fields: fields_definition, interfaces: interfaces, filename: @filename, source_string: @graphql_str)
213
+ InterfaceTypeExtension.new(pos: loc, name: name, directives: directives, fields: fields_definition, interfaces: interfaces, filename: @filename, source: self)
179
214
  when :UNION
180
215
  advance_token
181
216
  name = parse_name
182
217
  directives = parse_directives
183
218
  union_member_types = parse_union_members
184
- UnionTypeExtension.new(pos: loc, name: name, directives: directives, types: union_member_types, filename: @filename, source_string: @graphql_str)
219
+ UnionTypeExtension.new(pos: loc, name: name, directives: directives, types: union_member_types, filename: @filename, source: self)
185
220
  when :ENUM
186
221
  advance_token
187
222
  name = parse_name
188
223
  directives = parse_directives
189
224
  enum_values_definition = parse_enum_value_definitions
190
- Nodes::EnumTypeExtension.new(pos: loc, name: name, directives: directives, values: enum_values_definition, filename: @filename, source_string: @graphql_str)
225
+ Nodes::EnumTypeExtension.new(pos: loc, name: name, directives: directives, values: enum_values_definition, filename: @filename, source: self)
191
226
  when :INPUT
192
227
  advance_token
193
228
  name = parse_name
194
229
  directives = parse_directives
195
230
  input_fields_definition = parse_input_object_field_definitions
196
- InputObjectTypeExtension.new(pos: loc, name: name, directives: directives, fields: input_fields_definition, filename: @filename, source_string: @graphql_str)
231
+ InputObjectTypeExtension.new(pos: loc, name: name, directives: directives, fields: input_fields_definition, filename: @filename, source: self)
197
232
  when :SCHEMA
198
233
  advance_token
199
234
  directives = parse_directives
@@ -226,7 +261,7 @@ module GraphQL
226
261
  directives: directives,
227
262
  pos: loc,
228
263
  filename: @filename,
229
- source_string: @graphql_str,
264
+ source: self,
230
265
  )
231
266
  else
232
267
  expect_one_of([:SCHEMA, :SCALAR, :TYPE, :ENUM, :INPUT, :UNION, :INTERFACE])
@@ -259,7 +294,7 @@ module GraphQL
259
294
  end
260
295
  end
261
296
  expect_token :RCURLY
262
- SchemaDefinition.new(pos: loc, definition_pos: defn_loc, query: query, mutation: mutation, subscription: subscription, directives: directives, filename: @filename, source_string: @graphql_str)
297
+ SchemaDefinition.new(pos: loc, definition_pos: defn_loc, query: query, mutation: mutation, subscription: subscription, directives: directives, filename: @filename, source: self)
263
298
  when :DIRECTIVE
264
299
  advance_token
265
300
  expect_token :DIR_SIGN
@@ -272,12 +307,12 @@ module GraphQL
272
307
  false
273
308
  end
274
309
  expect_token :ON
275
- directive_locations = [DirectiveLocation.new(pos: pos, name: parse_name, filename: @filename, source_string: @graphql_str)]
310
+ directive_locations = [DirectiveLocation.new(pos: pos, name: parse_name, filename: @filename, source: self)]
276
311
  while at?(:PIPE)
277
312
  advance_token
278
- directive_locations << DirectiveLocation.new(pos: pos, name: parse_name, filename: @filename, source_string: @graphql_str)
313
+ directive_locations << DirectiveLocation.new(pos: pos, name: parse_name, filename: @filename, source: self)
279
314
  end
280
- DirectiveDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, arguments: arguments_definition, locations: directive_locations, repeatable: repeatable, filename: @filename, source_string: @graphql_str)
315
+ DirectiveDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, arguments: arguments_definition, locations: directive_locations, repeatable: repeatable, filename: @filename, source: self)
281
316
  when :TYPE
282
317
  advance_token
283
318
  name = parse_name
@@ -285,37 +320,37 @@ module GraphQL
285
320
  directives = parse_directives
286
321
  field_defns = at?(:LCURLY) ? parse_field_definitions : EMPTY_ARRAY
287
322
 
288
- ObjectTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, interfaces: implements_interfaces, directives: directives, fields: field_defns, filename: @filename, source_string: @graphql_str)
323
+ ObjectTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, interfaces: implements_interfaces, directives: directives, fields: field_defns, filename: @filename, source: self)
289
324
  when :INTERFACE
290
325
  advance_token
291
326
  name = parse_name
292
327
  interfaces = parse_implements
293
328
  directives = parse_directives
294
329
  fields_definition = parse_field_definitions
295
- InterfaceTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, fields: fields_definition, interfaces: interfaces, filename: @filename, source_string: @graphql_str)
330
+ InterfaceTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, fields: fields_definition, interfaces: interfaces, filename: @filename, source: self)
296
331
  when :UNION
297
332
  advance_token
298
333
  name = parse_name
299
334
  directives = parse_directives
300
335
  union_member_types = parse_union_members
301
- UnionTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, types: union_member_types, filename: @filename, source_string: @graphql_str)
336
+ UnionTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, types: union_member_types, filename: @filename, source: self)
302
337
  when :SCALAR
303
338
  advance_token
304
339
  name = parse_name
305
340
  directives = parse_directives
306
- ScalarTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, filename: @filename, source_string: @graphql_str)
341
+ ScalarTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, filename: @filename, source: self)
307
342
  when :ENUM
308
343
  advance_token
309
344
  name = parse_name
310
345
  directives = parse_directives
311
346
  enum_values_definition = parse_enum_value_definitions
312
- Nodes::EnumTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, values: enum_values_definition, filename: @filename, source_string: @graphql_str)
347
+ Nodes::EnumTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, values: enum_values_definition, filename: @filename, source: self)
313
348
  when :INPUT
314
349
  advance_token
315
350
  name = parse_name
316
351
  directives = parse_directives
317
352
  input_fields_definition = parse_input_object_field_definitions
318
- InputObjectTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, fields: input_fields_definition, filename: @filename, source_string: @graphql_str)
353
+ InputObjectTypeDefinition.new(pos: loc, definition_pos: defn_loc, description: desc, name: name, directives: directives, fields: input_fields_definition, filename: @filename, source: self)
319
354
  else
320
355
  expect_one_of([:SCHEMA, :SCALAR, :TYPE, :ENUM, :INPUT, :UNION, :INTERFACE])
321
356
  end
@@ -346,7 +381,7 @@ module GraphQL
346
381
  defn_loc = pos
347
382
  enum_value = parse_enum_name
348
383
  v_directives = parse_directives
349
- list << EnumValueDefinition.new(pos: v_loc, definition_pos: defn_loc, description: description, name: enum_value, directives: v_directives, filename: @filename, source_string: @graphql_str)
384
+ list << EnumValueDefinition.new(pos: v_loc, definition_pos: defn_loc, description: description, name: enum_value, directives: v_directives, filename: @filename, source: self)
350
385
  end
351
386
  expect_token :RCURLY
352
387
  list
@@ -397,7 +432,7 @@ module GraphQL
397
432
  type = self.type
398
433
  directives = parse_directives
399
434
 
400
- list << FieldDefinition.new(pos: loc, definition_pos: defn_loc, description: description, name: name, arguments: arguments_definition, type: type, directives: directives, filename: @filename, source_string: @graphql_str)
435
+ list << FieldDefinition.new(pos: loc, definition_pos: defn_loc, description: description, name: name, arguments: arguments_definition, type: type, directives: directives, filename: @filename, source: self)
401
436
  end
402
437
  expect_token :RCURLY
403
438
  list
@@ -431,7 +466,7 @@ module GraphQL
431
466
  nil
432
467
  end
433
468
  directives = parse_directives
434
- InputValueDefinition.new(pos: loc, definition_pos: defn_loc, description: description, name: name, type: type, default_value: default_value, directives: directives, filename: @filename, source_string: @graphql_str)
469
+ InputValueDefinition.new(pos: loc, definition_pos: defn_loc, description: description, name: name, type: type, default_value: default_value, directives: directives, filename: @filename, source: self)
435
470
  end
436
471
 
437
472
  def type
@@ -489,7 +524,7 @@ module GraphQL
489
524
 
490
525
  directives = parse_directives
491
526
 
492
- Nodes::InlineFragment.new(pos: loc, type: if_type, directives: directives, selections: selection_set, filename: @filename, source_string: @graphql_str)
527
+ Nodes::InlineFragment.new(pos: loc, type: if_type, directives: directives, selections: selection_set, filename: @filename, source: self)
493
528
  else
494
529
  name = parse_name_without_on
495
530
  directives = parse_directives
@@ -497,7 +532,7 @@ module GraphQL
497
532
  # Can this ever happen?
498
533
  # expect_token(:IDENTIFIER) if at?(:ON)
499
534
 
500
- FragmentSpread.new(pos: loc, name: name, directives: directives, filename: @filename, source_string: @graphql_str)
535
+ FragmentSpread.new(pos: loc, name: name, directives: directives, filename: @filename, source: self)
501
536
  end
502
537
  else
503
538
  loc = pos
@@ -515,7 +550,7 @@ module GraphQL
515
550
  directives = at?(:DIR_SIGN) ? parse_directives : nil
516
551
  selection_set = at?(:LCURLY) ? self.selection_set : nil
517
552
 
518
- Nodes::Field.new(pos: loc, field_alias: field_alias, name: name, arguments: arguments, directives: directives, selections: selection_set, filename: @filename, source_string: @graphql_str)
553
+ Nodes::Field.new(pos: loc, field_alias: field_alias, name: name, arguments: arguments, directives: directives, selections: selection_set, filename: @filename, source: self)
519
554
  end
520
555
  end
521
556
  expect_token(:RCURLY)
@@ -609,7 +644,7 @@ module GraphQL
609
644
  end
610
645
 
611
646
  def parse_type_name
612
- TypeName.new(pos: pos, name: parse_name, filename: @filename, source_string: @graphql_str)
647
+ TypeName.new(pos: pos, name: parse_name, filename: @filename, source: self)
613
648
  end
614
649
 
615
650
  def parse_directives
@@ -621,7 +656,7 @@ module GraphQL
621
656
  name = parse_name
622
657
  arguments = parse_arguments
623
658
 
624
- dirs << Nodes::Directive.new(pos: loc, name: name, arguments: arguments, filename: @filename, source_string: @graphql_str)
659
+ dirs << Nodes::Directive.new(pos: loc, name: name, arguments: arguments, filename: @filename, source: self)
625
660
  end
626
661
  dirs
627
662
  else
@@ -637,7 +672,7 @@ module GraphQL
637
672
  loc = pos
638
673
  name = parse_name
639
674
  expect_token(:COLON)
640
- args << Nodes::Argument.new(pos: loc, name: name, value: value, filename: @filename, source_string: @graphql_str)
675
+ args << Nodes::Argument.new(pos: loc, name: name, value: value, filename: @filename, source: self)
641
676
  end
642
677
  if args.empty?
643
678
  expect_token(:ARGUMENT_NAME) # At least one argument is required
@@ -671,9 +706,9 @@ module GraphQL
671
706
  false
672
707
  when :NULL
673
708
  advance_token
674
- NullValue.new(pos: pos, name: "null", filename: @filename, source_string: @graphql_str)
709
+ NullValue.new(pos: pos, name: "null", filename: @filename, source: self)
675
710
  when :IDENTIFIER
676
- Nodes::Enum.new(pos: pos, name: expect_token_value(:IDENTIFIER), filename: @filename, source_string: @graphql_str)
711
+ Nodes::Enum.new(pos: pos, name: expect_token_value(:IDENTIFIER), filename: @filename, source: self)
677
712
  when :LBRACKET
678
713
  advance_token
679
714
  list = []
@@ -690,14 +725,14 @@ module GraphQL
690
725
  loc = pos
691
726
  n = parse_name
692
727
  expect_token(:COLON)
693
- args << Argument.new(pos: loc, name: n, value: value, filename: @filename, source_string: @graphql_str)
728
+ args << Argument.new(pos: loc, name: n, value: value, filename: @filename, source: self)
694
729
  end
695
730
  expect_token(:RCURLY)
696
- InputObject.new(pos: start, arguments: args, filename: @filename, source_string: @graphql_str)
731
+ InputObject.new(pos: start, arguments: args, filename: @filename, source: self)
697
732
  when :VAR_SIGN
698
733
  loc = pos
699
734
  advance_token
700
- VariableIdentifier.new(pos: loc, name: parse_name, filename: @filename, source_string: @graphql_str)
735
+ VariableIdentifier.new(pos: loc, name: parse_name, filename: @filename, source: self)
701
736
  else
702
737
  expect_token(:VALUE)
703
738
  end
@@ -749,9 +749,10 @@ module GraphQL
749
749
 
750
750
  attr_writer :max_complexity
751
751
 
752
- def max_complexity(max_complexity = nil)
752
+ def max_complexity(max_complexity = nil, count_introspection_fields: true)
753
753
  if max_complexity
754
754
  @max_complexity = max_complexity
755
+ @max_complexity_count_introspection_fields = count_introspection_fields
755
756
  elsif defined?(@max_complexity)
756
757
  @max_complexity
757
758
  else
@@ -759,6 +760,14 @@ module GraphQL
759
760
  end
760
761
  end
761
762
 
763
+ def max_complexity_count_introspection_fields
764
+ if defined?(@max_complexity_count_introspection_fields)
765
+ @max_complexity_count_introspection_fields
766
+ else
767
+ find_inherited_value(:max_complexity_count_introspection_fields, true)
768
+ end
769
+ end
770
+
762
771
  attr_writer :analysis_engine
763
772
 
764
773
  def analysis_engine
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.3.2"
3
+ VERSION = "2.3.3"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.2
4
+ version: 2.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-26 00:00:00.000000000 Z
11
+ date: 2024-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64