graphql 2.0.7 → 2.0.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -321,13 +321,13 @@ rule
321
321
 
322
322
  object_type_extension:
323
323
  /* TODO - This first one shouldn't be necessary but parser is getting confused */
324
- EXTEND TYPE name implements LCURLY field_definition_list RCURLY { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: [], fields: val[5], position_source: val[0]) }
325
- | EXTEND TYPE name implements_opt directives_list_opt LCURLY field_definition_list RCURLY { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: val[6], position_source: val[0]) }
324
+ EXTEND TYPE name implements field_definition_list_opt { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: [], fields: val[4], position_source: val[0]) }
325
+ | EXTEND TYPE name implements_opt directives_list_opt field_definition_list_opt { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: val[5], position_source: val[0]) }
326
326
  | EXTEND TYPE name implements_opt directives_list { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: [], position_source: val[0]) }
327
327
  | EXTEND TYPE name implements { result = make_node(:ObjectTypeExtension, name: val[2], interfaces: val[3], directives: [], fields: [], position_source: val[0]) }
328
328
 
329
329
  interface_type_extension:
330
- EXTEND INTERFACE name implements_opt directives_list_opt LCURLY field_definition_list RCURLY { result = make_node(:InterfaceTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: val[6], position_source: val[0]) }
330
+ EXTEND INTERFACE name implements_opt directives_list_opt field_definition_list_opt { result = make_node(:InterfaceTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: val[5], position_source: val[0]) }
331
331
  | EXTEND INTERFACE name implements_opt directives_list { result = make_node(:InterfaceTypeExtension, name: val[2], interfaces: val[3], directives: val[4], fields: [], position_source: val[0]) }
332
332
  | EXTEND INTERFACE name implements { result = make_node(:InterfaceTypeExtension, name: val[2], interfaces: val[3], directives: [], fields: [], position_source: val[0]) }
333
333
 
@@ -355,8 +355,8 @@ rule
355
355
  }
356
356
 
357
357
  object_type_definition:
358
- description_opt TYPE name implements_opt directives_list_opt LCURLY field_definition_list RCURLY {
359
- result = make_node(:ObjectTypeDefinition, name: val[2], interfaces: val[3], directives: val[4], fields: val[6], description: val[0] || get_description(val[1]), definition_line: val[1].line, position_source: val[0] || val[1])
358
+ description_opt TYPE name implements_opt directives_list_opt field_definition_list_opt {
359
+ result = make_node(:ObjectTypeDefinition, name: val[2], interfaces: val[3], directives: val[4], fields: val[5], description: val[0] || get_description(val[1]), definition_line: val[1].line, position_source: val[0] || val[1])
360
360
  }
361
361
 
362
362
  implements_opt:
@@ -394,14 +394,18 @@ rule
394
394
  result = make_node(:FieldDefinition, name: val[1], arguments: val[2], type: val[4], directives: val[5], description: val[0] || get_description(val[1]), definition_line: val[1].line, position_source: val[0] || val[1])
395
395
  }
396
396
 
397
- field_definition_list:
397
+ field_definition_list_opt:
398
398
  /* none */ { result = EMPTY_ARRAY }
399
+ | LCURLY field_definition_list RCURLY { result = val[1] }
400
+
401
+ field_definition_list:
402
+ /* none - this is not actually valid but graphql-ruby used to print this */ { result = EMPTY_ARRAY }
399
403
  | field_definition { result = [val[0]] }
400
404
  | field_definition_list field_definition { val[0] << val[1] }
401
405
 
402
406
  interface_type_definition:
403
- description_opt INTERFACE name implements_opt directives_list_opt LCURLY field_definition_list RCURLY {
404
- result = make_node(:InterfaceTypeDefinition, name: val[2], interfaces: val[3], directives: val[4], fields: val[6], description: val[0] || get_description(val[1]), definition_line: val[1].line, position_source: val[0] || val[1])
407
+ description_opt INTERFACE name implements_opt directives_list_opt field_definition_list_opt {
408
+ result = make_node(:InterfaceTypeDefinition, name: val[2], interfaces: val[3], directives: val[4], fields: val[5], description: val[0] || get_description(val[1]), definition_line: val[1].line, position_source: val[0] || val[1])
405
409
  }
406
410
 
407
411
  union_members:
@@ -56,8 +56,9 @@ module GraphQL
56
56
  # @param last [Integer, nil] Limit parameter from the client, if provided
57
57
  # @param before [String, nil] A cursor for pagination, if the client provided one.
58
58
  # @param arguments [Hash] The arguments to the field that returned the collection wrapped by this connection
59
- # @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given.
60
- def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: :not_given, last: nil, before: nil, edge_class: nil, arguments: nil)
59
+ # @param max_page_size [Integer, nil] A configured value to cap the result size. Applied as `first` if neither first or last are given and no `default_page_size` is set.
60
+ # @param default_page_size [Integer, nil] A configured value to determine the result size when neither first or last are given.
61
+ def initialize(items, parent: nil, field: nil, context: nil, first: nil, after: nil, max_page_size: :not_given, default_page_size: :not_given, last: nil, before: nil, edge_class: nil, arguments: nil)
61
62
  @items = items
62
63
  @parent = parent
63
64
  @context = context
@@ -76,6 +77,12 @@ module GraphQL
76
77
  else
77
78
  max_page_size
78
79
  end
80
+ @has_default_page_size_override = default_page_size != :not_given
81
+ @default_page_size = if default_page_size == :not_given
82
+ nil
83
+ else
84
+ default_page_size
85
+ end
79
86
  end
80
87
 
81
88
  def max_page_size=(new_value)
@@ -95,16 +102,36 @@ module GraphQL
95
102
  @has_max_page_size_override
96
103
  end
97
104
 
105
+ def default_page_size=(new_value)
106
+ @has_default_page_size_override = true
107
+ @default_page_size = new_value
108
+ end
109
+
110
+ def default_page_size
111
+ if @has_default_page_size_override
112
+ @default_page_size
113
+ else
114
+ context.schema.default_page_size
115
+ end
116
+ end
117
+
118
+ def has_default_page_size_override?
119
+ @has_default_page_size_override
120
+ end
121
+
98
122
  attr_writer :first
99
123
  # @return [Integer, nil]
100
124
  # A clamped `first` value.
101
125
  # (The underlying instance variable doesn't have limits on it.)
102
- # If neither `first` nor `last` is given, but `max_page_size` is present, max_page_size is used for first.
126
+ # If neither `first` nor `last` is given, but `default_page_size` is
127
+ # present, default_page_size is used for first. If `default_page_size`
128
+ # is greater than `max_page_size``, it'll be clamped down to
129
+ # `max_page_size`. If `default_page_size` is nil, use `max_page_size`.
103
130
  def first
104
131
  @first ||= begin
105
132
  capped = limit_pagination_argument(@first_value, max_page_size)
106
133
  if capped.nil? && last.nil?
107
- capped = max_page_size
134
+ capped = limit_pagination_argument(default_page_size, max_page_size) || max_page_size
108
135
  end
109
136
  capped
110
137
  end
@@ -70,6 +70,7 @@ module GraphQL
70
70
  parent: parent,
71
71
  field: field,
72
72
  max_page_size: field.has_max_page_size? ? field.max_page_size : context.schema.default_max_page_size,
73
+ default_page_size: field.has_default_page_size? ? field.default_page_size : context.schema.default_page_size,
73
74
  first: arguments[:first],
74
75
  after: arguments[:after],
75
76
  last: arguments[:last],
@@ -117,6 +117,8 @@ module GraphQL
117
117
  return
118
118
  else
119
119
  next_offset = relation_offset(items) || 0
120
+ relation_limit = relation_limit(items)
121
+
120
122
  if after_offset
121
123
  next_offset += after_offset
122
124
  end
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  require "fileutils"
3
+ require "rake"
3
4
  require "graphql/rake_task/validate"
4
5
 
5
6
  module GraphQL
@@ -151,7 +151,7 @@ module GraphQL
151
151
  um << owner
152
152
  end
153
153
 
154
- if (prev_type = get_local_type(type.graphql_name)) && prev_type == type
154
+ if (prev_type = get_local_type(type.graphql_name)) && (prev_type == type || (prev_type.is_a?(Array) && prev_type.include?(type)))
155
155
  # No need to re-visit
156
156
  elsif type.is_a?(Class) && type < GraphQL::Schema::Directive
157
157
  @directives << type
@@ -47,6 +47,9 @@ module GraphQL
47
47
  if field.has_max_page_size? && !value.has_max_page_size_override?
48
48
  value.max_page_size = field.max_page_size
49
49
  end
50
+ if field.has_default_page_size? && !value.has_default_page_size_override?
51
+ value.default_page_size = field.default_page_size
52
+ end
50
53
  if context.schema.new_connections? && (custom_t = context.schema.connections.edge_class_for_field(@field))
51
54
  value.edge_class = custom_t
52
55
  end
@@ -64,6 +67,7 @@ module GraphQL
64
67
  original_arguments,
65
68
  field: field,
66
69
  max_page_size: field.max_page_size,
70
+ default_page_size: field.default_page_size,
67
71
  parent: object,
68
72
  context: context,
69
73
  )
@@ -181,6 +181,8 @@ module GraphQL
181
181
 
182
182
  # @return Boolean
183
183
  attr_reader :relay_node_field
184
+ # @return Boolean
185
+ attr_reader :relay_nodes_field
184
186
 
185
187
  # @return [Boolean] Should we warn if this field's name conflicts with a built-in method?
186
188
  def method_conflict_warning?
@@ -200,6 +202,7 @@ module GraphQL
200
202
  # @param connection [Boolean] `true` if this field should get automagic connection behavior; default is to infer by `*Connection` in the return type name
201
203
  # @param connection_extension [Class] The extension to add, to implement connections. If `nil`, no extension is added.
202
204
  # @param max_page_size [Integer, nil] For connections, the maximum number of items to return from this field, or `nil` to allow unlimited results.
205
+ # @param default_page_size [Integer, nil] For connections, the default number of items to return from this field, or `nil` to return unlimited results.
203
206
  # @param introspection [Boolean] If true, this field will be marked as `#introspection?` and the name may begin with `__`
204
207
  # @param resolver_class [Class] (Private) A {Schema::Resolver} which this field was derived from. Use `resolver:` to create a field with a resolver.
205
208
  # @param arguments [{String=>GraphQL::Schema::Argument, Hash}] Arguments for this field (may be added in the block, also)
@@ -214,7 +217,8 @@ module GraphQL
214
217
  # @param ast_node [Language::Nodes::FieldDefinition, nil] If this schema was parsed from definition, this AST node defined the field
215
218
  # @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
216
219
  # @param validates [Array<Hash>] Configurations for validating this field
217
- def initialize(type: nil, name: nil, owner: nil, null: nil, description: :not_given, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: :not_given, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: nil, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, &definition_block)
220
+ # @fallback_value [Object] A fallback value if the method is not defined
221
+ def initialize(type: nil, name: nil, owner: nil, null: nil, description: :not_given, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: :not_given, default_page_size: :not_given, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: nil, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: :not_given, &definition_block)
218
222
  if name.nil?
219
223
  raise ArgumentError, "missing first `name` argument or keyword `name:`"
220
224
  end
@@ -246,7 +250,7 @@ module GraphQL
246
250
  end
247
251
  end
248
252
 
249
- method_name = method || name_s
253
+ method_name = method || hash_key || name_s
250
254
  @dig_keys = dig
251
255
  if hash_key
252
256
  @hash_key = hash_key
@@ -268,6 +272,8 @@ module GraphQL
268
272
  @connection = connection
269
273
  @has_max_page_size = max_page_size != :not_given
270
274
  @max_page_size = max_page_size == :not_given ? nil : max_page_size
275
+ @has_default_page_size = default_page_size != :not_given
276
+ @default_page_size = default_page_size == :not_given ? nil : default_page_size
271
277
  @introspection = introspection
272
278
  @extras = extras
273
279
  if !broadcastable.nil?
@@ -280,6 +286,7 @@ module GraphQL
280
286
  @relay_nodes_field = relay_nodes_field
281
287
  @ast_node = ast_node
282
288
  @method_conflict_warning = method_conflict_warning
289
+ @fallback_value = fallback_value
283
290
 
284
291
  arguments.each do |name, arg|
285
292
  case arg
@@ -462,11 +469,11 @@ module GraphQL
462
469
  end
463
470
 
464
471
  if max_possible_page_size.nil?
465
- max_possible_page_size = max_page_size || query.schema.default_max_page_size
472
+ max_possible_page_size = default_page_size || query.schema.default_page_size || max_page_size || query.schema.default_max_page_size
466
473
  end
467
474
 
468
475
  if max_possible_page_size.nil?
469
- raise GraphQL::Error, "Can't calculate complexity for #{path}, no `first:`, `last:`, `max_page_size` or `default_max_page_size`"
476
+ raise GraphQL::Error, "Can't calculate complexity for #{path}, no `first:`, `last:`, `default_page_size`, `max_page_size` or `default_max_page_size`"
470
477
  else
471
478
  metadata_complexity = 0
472
479
  lookahead = GraphQL::Execution::Lookahead.new(query: query, field: self, ast_nodes: nodes, owner_type: owner)
@@ -494,7 +501,13 @@ module GraphQL
494
501
  case defined_complexity
495
502
  when Proc
496
503
  arguments = query.arguments_for(nodes.first, self)
497
- defined_complexity.call(query.context, arguments.keyword_arguments, child_complexity)
504
+ if arguments.is_a?(GraphQL::ExecutionError)
505
+ return child_complexity
506
+ elsif arguments.respond_to?(:keyword_arguments)
507
+ arguments = arguments.keyword_arguments
508
+ end
509
+
510
+ defined_complexity.call(query.context, arguments, child_complexity)
498
511
  when Numeric
499
512
  defined_complexity + child_complexity
500
513
  else
@@ -537,6 +550,16 @@ module GraphQL
537
550
  @max_page_size || (@resolver_class && @resolver_class.max_page_size)
538
551
  end
539
552
 
553
+ # @return [Boolean] True if this field's {#default_page_size} should override the schema default.
554
+ def has_default_page_size?
555
+ @has_default_page_size || (@resolver_class && @resolver_class.has_default_page_size?)
556
+ end
557
+
558
+ # @return [Integer, nil] Applied to connections if {#has_default_page_size?}
559
+ def default_page_size
560
+ @default_page_size || (@resolver_class && @resolver_class.default_page_size)
561
+ end
562
+
540
563
  class MissingReturnTypeError < GraphQL::Error; end
541
564
  attr_writer :type
542
565
 
@@ -643,11 +666,7 @@ module GraphQL
643
666
  inner_object = obj.object
644
667
 
645
668
  if defined?(@hash_key)
646
- inner_object.fetch(@hash_key) {
647
- inner_object[@hash_key_str]
648
- }
649
- elsif @dig_keys
650
- inner_object.dig(*@dig_keys)
669
+ inner_object[@hash_key] || inner_object[@hash_key_str] || (@fallback_value != :not_given ? @fallback_value : nil)
651
670
  elsif obj.respond_to?(resolver_method)
652
671
  method_to_call = resolver_method
653
672
  method_receiver = obj
@@ -658,10 +677,26 @@ module GraphQL
658
677
  obj.public_send(resolver_method)
659
678
  end
660
679
  elsif inner_object.is_a?(Hash)
661
- if inner_object.key?(@method_sym)
680
+ if @dig_keys
681
+ inner_object.dig(*@dig_keys)
682
+ elsif defined?(@hash_key)
683
+ if inner_object.key?(@hash_key)
684
+ inner_object[@hash_key]
685
+ elsif inner_object.key?(@hash_key_str)
686
+ inner_object[@hash_key_str]
687
+ elsif @fallback_value != :not_given
688
+ @fallback_value
689
+ else
690
+ nil
691
+ end
692
+ elsif inner_object.key?(@method_sym)
662
693
  inner_object[@method_sym]
663
- else
694
+ elsif inner_object.key?(@method_str)
664
695
  inner_object[@method_str]
696
+ elsif @fallback_value != :not_given
697
+ @fallback_value
698
+ else
699
+ nil
665
700
  end
666
701
  elsif inner_object.respond_to?(@method_sym)
667
702
  method_to_call = @method_sym
@@ -671,6 +706,8 @@ module GraphQL
671
706
  else
672
707
  inner_object.public_send(@method_sym)
673
708
  end
709
+ elsif @fallback_value != :not_given
710
+ @fallback_value
674
711
  else
675
712
  raise <<-ERR
676
713
  Failed to implement #{@owner.graphql_name}.#{@name}, tried:
@@ -679,7 +716,7 @@ module GraphQL
679
716
  - `#{inner_object.class}##{@method_sym}`, which did not exist
680
717
  - Looking up hash key `#{@method_sym.inspect}` or `#{@method_str.inspect}` on `#{inner_object}`, but it wasn't a Hash
681
718
 
682
- To implement this field, define one of the methods above (and check for typos)
719
+ To implement this field, define one of the methods above (and check for typos), or supply a `fallback_value`.
683
720
  ERR
684
721
  end
685
722
  end
@@ -751,7 +788,7 @@ module GraphQL
751
788
 
752
789
  if unsatisfied_ruby_kwargs.any? || unsatisfied_method_params.any?
753
790
  raise FieldImplementationFailed.new, <<-ERR
754
- Failed to call #{method_name} on #{receiver.inspect} because the Ruby method params were incompatible with the GraphQL arguments:
791
+ Failed to call `#{method_name.inspect}` on #{receiver.inspect} because the Ruby method params were incompatible with the GraphQL arguments:
755
792
 
756
793
  #{ unsatisfied_ruby_kwargs
757
794
  .map { |key, value| "- `#{key}: #{value}` was given by GraphQL but not defined in the Ruby method. Add `#{key}:` to the method parameters." }
@@ -328,6 +328,27 @@ module GraphQL
328
328
  (!!defined?(@max_page_size)) || (superclass.respond_to?(:has_max_page_size?) && superclass.has_max_page_size?)
329
329
  end
330
330
 
331
+ # Get or set the `default_page_size:` which will be configured for fields using this resolver
332
+ # (`nil` means "unlimited default page size".)
333
+ # @param default_page_size [Integer, nil] Set a new value
334
+ # @return [Integer, nil] The `default_page_size` assigned to fields that use this resolver
335
+ def default_page_size(new_default_page_size = :not_given)
336
+ if new_default_page_size != :not_given
337
+ @default_page_size = new_default_page_size
338
+ elsif defined?(@default_page_size)
339
+ @default_page_size
340
+ elsif superclass.respond_to?(:default_page_size)
341
+ superclass.default_page_size
342
+ else
343
+ nil
344
+ end
345
+ end
346
+
347
+ # @return [Boolean] `true` if this resolver or a superclass has an assigned `default_page_size`
348
+ def has_default_page_size?
349
+ (!!defined?(@default_page_size)) || (superclass.respond_to?(:has_default_page_size?) && superclass.has_default_page_size?)
350
+ end
351
+
331
352
  # A non-normalized type configuration, without `null` applied
332
353
  def type_expr
333
354
  @type_expr || (superclass.respond_to?(:type_expr) ? superclass.type_expr : nil)
@@ -132,7 +132,13 @@ module GraphQL
132
132
  end
133
133
 
134
134
  # @return [GraphQL::Subscriptions]
135
- attr_accessor :subscriptions
135
+ def subscriptions(inherited: true)
136
+ defined?(@subscriptions) ? @subscriptions : (inherited ? find_inherited_value(:subscriptions, nil) : nil)
137
+ end
138
+
139
+ def subscriptions=(new_implementation)
140
+ @subscriptions = new_implementation
141
+ end
136
142
 
137
143
  # Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
138
144
  # @see {#as_json}
@@ -506,6 +512,14 @@ module GraphQL
506
512
  end
507
513
  end
508
514
 
515
+ def default_page_size(new_default_page_size = nil)
516
+ if new_default_page_size
517
+ @default_page_size = new_default_page_size
518
+ else
519
+ @default_page_size || find_inherited_value(:default_page_size)
520
+ end
521
+ end
522
+
509
523
  def query_execution_strategy(new_query_execution_strategy = nil)
510
524
  if new_query_execution_strategy
511
525
  @query_execution_strategy = new_query_execution_strategy
@@ -26,7 +26,7 @@ module GraphQL
26
26
  def self.use(defn, options = {})
27
27
  schema = defn.is_a?(Class) ? defn : defn.target
28
28
 
29
- if schema.subscriptions
29
+ if schema.subscriptions(inherited: false)
30
30
  raise ArgumentError, "Can't reinstall subscriptions. #{schema} is using #{schema.subscriptions}, can't also add #{self}"
31
31
  end
32
32
 
@@ -45,6 +45,8 @@ module GraphQL
45
45
  span.set_tag(:query_string, data[:query].query_string)
46
46
  end
47
47
 
48
+ prepare_span(key, data, span)
49
+
48
50
  yield
49
51
  end
50
52
  end
@@ -53,6 +55,13 @@ module GraphQL
53
55
  options.fetch(:service, 'ruby-graphql')
54
56
  end
55
57
 
58
+ # Implement this method in a subclass to apply custom tags to datadog spans
59
+ # @param key [String] The event being traced
60
+ # @param data [Hash] The runtime data for this event (@see GraphQL::Tracing for keys for each event)
61
+ # @param span [Datadog::Tracing::SpanOperation] The datadog span for this event
62
+ def prepare_span(key, data, span)
63
+ end
64
+
56
65
  def tracer
57
66
  default_tracer = defined?(Datadog::Tracing) ? Datadog::Tracing : Datadog.tracer
58
67
 
@@ -10,6 +10,10 @@ module GraphQL
10
10
  class PlatformTracing
11
11
  class << self
12
12
  attr_accessor :platform_keys
13
+
14
+ def inherited(child_class)
15
+ child_class.platform_keys = self.platform_keys
16
+ end
13
17
  end
14
18
 
15
19
  def initialize(options = {})
@@ -26,25 +30,19 @@ module GraphQL
26
30
  yield
27
31
  end
28
32
  when "execute_field", "execute_field_lazy"
29
- if data[:context]
30
- field = data[:context].field
31
- platform_key = field.metadata[:platform_key]
32
- trace_field = true # implemented with instrumenter
33
+ field = data[:field]
34
+ return_type = field.type.unwrap
35
+ trace_field = if return_type.kind.scalar? || return_type.kind.enum?
36
+ (field.trace.nil? && @trace_scalars) || field.trace
33
37
  else
34
- field = data[:field]
35
- return_type = field.type.unwrap
36
- trace_field = if return_type.kind.scalar? || return_type.kind.enum?
37
- (field.trace.nil? && @trace_scalars) || field.trace
38
- else
39
- true
40
- end
38
+ true
39
+ end
41
40
 
42
- platform_key = if trace_field
43
- context = data.fetch(:query).context
44
- cached_platform_key(context, field) { platform_field_key(data[:owner], field) }
45
- else
46
- nil
47
- end
41
+ platform_key = if trace_field
42
+ context = data.fetch(:query).context
43
+ cached_platform_key(context, field, :field) { platform_field_key(data[:owner], field) }
44
+ else
45
+ nil
48
46
  end
49
47
 
50
48
  if platform_key && trace_field
@@ -57,14 +55,14 @@ module GraphQL
57
55
  when "authorized", "authorized_lazy"
58
56
  type = data.fetch(:type)
59
57
  context = data.fetch(:context)
60
- platform_key = cached_platform_key(context, type) { platform_authorized_key(type) }
58
+ platform_key = cached_platform_key(context, type, :authorized) { platform_authorized_key(type) }
61
59
  platform_trace(platform_key, key, data) do
62
60
  yield
63
61
  end
64
62
  when "resolve_type", "resolve_type_lazy"
65
63
  type = data.fetch(:type)
66
64
  context = data.fetch(:context)
67
- platform_key = cached_platform_key(context, type) { platform_resolve_type_key(type) }
65
+ platform_key = cached_platform_key(context, type, :resolve_type) { platform_resolve_type_key(type) }
68
66
  platform_trace(platform_key, key, data) do
69
67
  yield
70
68
  end
@@ -111,8 +109,11 @@ module GraphQL
111
109
  #
112
110
  # If the key isn't present, the given block is called and the result is cached for `key`.
113
111
  #
112
+ # @param ctx [GraphQL::Query::Context]
113
+ # @param key [Class, GraphQL::Field] A part of the schema
114
+ # @param trace_phase [Symbol] The stage of execution being traced (used by OpenTelementry tracing)
114
115
  # @return [String]
115
- def cached_platform_key(ctx, key)
116
+ def cached_platform_key(ctx, key, trace_phase)
116
117
  cache = ctx.namespace(self.class)[:platform_key_cache] ||= {}
117
118
  cache.fetch(key) { cache[key] = yield }
118
119
  end
@@ -60,6 +60,9 @@ module GraphQL
60
60
  # But without this, it would zero out given any time part of `str_value` (hours and/or minutes)
61
61
  if dt.iso8601.start_with?(str_value)
62
62
  dt
63
+ elsif str_value.length == 8 && str_value.match?(/\A\d{8}\Z/)
64
+ # Allow dates that are missing the "-". eg. "20220404"
65
+ dt
63
66
  else
64
67
  nil
65
68
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.0.7"
3
+ VERSION = "2.0.11"
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.0.7
4
+ version: 2.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-04-25 00:00:00.000000000 Z
11
+ date: 2022-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -595,7 +595,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
595
595
  - !ruby/object:Gem::Version
596
596
  version: '0'
597
597
  requirements: []
598
- rubygems_version: 3.2.32
598
+ rubygems_version: 3.2.22
599
599
  signing_key:
600
600
  specification_version: 4
601
601
  summary: A GraphQL language and runtime for Ruby