graphql 2.3.3 → 2.3.5
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.
- checksums.yaml +4 -4
- data/lib/generators/graphql/install/mutation_root_generator.rb +2 -2
- data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
- data/lib/graphql/dataloader/async_dataloader.rb +1 -0
- data/lib/graphql/dataloader/null_dataloader.rb +1 -1
- data/lib/graphql/dataloader.rb +6 -3
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +7 -4
- data/lib/graphql/execution/interpreter/runtime.rb +52 -63
- data/lib/graphql/execution/interpreter.rb +1 -1
- data/lib/graphql/language/nodes.rb +60 -26
- data/lib/graphql/language/parser.rb +56 -15
- data/lib/graphql/query.rb +2 -2
- data/lib/graphql/rubocop/graphql/base_cop.rb +1 -1
- data/lib/graphql/schema/addition.rb +21 -11
- data/lib/graphql/schema/has_single_input_argument.rb +1 -0
- data/lib/graphql/schema/input_object.rb +1 -0
- data/lib/graphql/schema/introspection_system.rb +2 -2
- data/lib/graphql/schema/late_bound_type.rb +4 -0
- data/lib/graphql/schema/list.rb +2 -2
- data/lib/graphql/schema/member/has_arguments.rb +2 -35
- data/lib/graphql/schema/member/has_directives.rb +1 -1
- data/lib/graphql/schema/member/relay_shortcuts.rb +1 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -2
- data/lib/graphql/schema/warden.rb +2 -3
- data/lib/graphql/schema.rb +20 -20
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +1 -1
- data/lib/graphql/tracing/prometheus_trace.rb +8 -8
- data/lib/graphql/tracing/sentry_trace.rb +10 -10
- data/lib/graphql/type_kinds.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +0 -8
- metadata +2 -2
@@ -379,7 +379,12 @@ module GraphQL
|
|
379
379
|
v_loc = pos
|
380
380
|
description = if at?(:STRING); string_value; end
|
381
381
|
defn_loc = pos
|
382
|
-
|
382
|
+
# Any identifier, but not true, false, or null
|
383
|
+
enum_value = if at?(:TRUE) || at?(:FALSE) || at?(:NULL)
|
384
|
+
expect_token(:IDENTIFIER)
|
385
|
+
else
|
386
|
+
parse_name
|
387
|
+
end
|
383
388
|
v_directives = parse_directives
|
384
389
|
list << EnumValueDefinition.new(pos: v_loc, definition_pos: defn_loc, description: description, name: enum_value, directives: v_directives, filename: @filename, source: self)
|
385
390
|
end
|
@@ -478,7 +483,7 @@ module GraphQL
|
|
478
483
|
end
|
479
484
|
|
480
485
|
if at?(:BANG)
|
481
|
-
type = Nodes::NonNullType.new(pos: pos, of_type: type)
|
486
|
+
type = Nodes::NonNullType.new(pos: pos, of_type: type, source: self)
|
482
487
|
expect_token(:BANG)
|
483
488
|
end
|
484
489
|
type
|
@@ -487,7 +492,7 @@ module GraphQL
|
|
487
492
|
def list_type
|
488
493
|
loc = pos
|
489
494
|
expect_token(:LBRACKET)
|
490
|
-
type = Nodes::ListType.new(pos: loc, of_type: self.type)
|
495
|
+
type = Nodes::ListType.new(pos: loc, of_type: self.type, source: self)
|
491
496
|
expect_token(:RBRACKET)
|
492
497
|
type
|
493
498
|
end
|
@@ -615,9 +620,6 @@ module GraphQL
|
|
615
620
|
when :ON
|
616
621
|
advance_token
|
617
622
|
"on"
|
618
|
-
when :DIRECTIVE
|
619
|
-
advance_token
|
620
|
-
"directive"
|
621
623
|
when :EXTEND
|
622
624
|
advance_token
|
623
625
|
"extend"
|
@@ -634,15 +636,6 @@ module GraphQL
|
|
634
636
|
end
|
635
637
|
end
|
636
638
|
|
637
|
-
# Any identifier, but not true, false, or null
|
638
|
-
def parse_enum_name
|
639
|
-
if at?(:TRUE) || at?(:FALSE) || at?(:NULL)
|
640
|
-
expect_token(:IDENTIFIER)
|
641
|
-
else
|
642
|
-
parse_name
|
643
|
-
end
|
644
|
-
end
|
645
|
-
|
646
639
|
def parse_type_name
|
647
640
|
TypeName.new(pos: pos, name: parse_name, filename: @filename, source: self)
|
648
641
|
end
|
@@ -733,6 +726,54 @@ module GraphQL
|
|
733
726
|
loc = pos
|
734
727
|
advance_token
|
735
728
|
VariableIdentifier.new(pos: loc, name: parse_name, filename: @filename, source: self)
|
729
|
+
when :SCHEMA
|
730
|
+
advance_token
|
731
|
+
Nodes::Enum.new(pos: pos, name: "schema", filename: @filename, source: self)
|
732
|
+
when :SCALAR
|
733
|
+
advance_token
|
734
|
+
Nodes::Enum.new(pos: pos, name: "scalar", filename: @filename, source: self)
|
735
|
+
when :IMPLEMENTS
|
736
|
+
advance_token
|
737
|
+
Nodes::Enum.new(pos: pos, name: "implements", filename: @filename, source: self)
|
738
|
+
when :INTERFACE
|
739
|
+
advance_token
|
740
|
+
Nodes::Enum.new(pos: pos, name: "interface", filename: @filename, source: self)
|
741
|
+
when :UNION
|
742
|
+
advance_token
|
743
|
+
Nodes::Enum.new(pos: pos, name: "union", filename: @filename, source: self)
|
744
|
+
when :ENUM
|
745
|
+
advance_token
|
746
|
+
Nodes::Enum.new(pos: pos, name: "enum", filename: @filename, source: self)
|
747
|
+
when :INPUT
|
748
|
+
advance_token
|
749
|
+
Nodes::Enum.new(pos: pos, name: "input", filename: @filename, source: self)
|
750
|
+
when :DIRECTIVE
|
751
|
+
advance_token
|
752
|
+
Nodes::Enum.new(pos: pos, name: "directive", filename: @filename, source: self)
|
753
|
+
when :TYPE
|
754
|
+
advance_token
|
755
|
+
Nodes::Enum.new(pos: pos, name: "type", filename: @filename, source: self)
|
756
|
+
when :QUERY
|
757
|
+
advance_token
|
758
|
+
Nodes::Enum.new(pos: pos, name: "query", filename: @filename, source: self)
|
759
|
+
when :MUTATION
|
760
|
+
advance_token
|
761
|
+
Nodes::Enum.new(pos: pos, name: "mutation", filename: @filename, source: self)
|
762
|
+
when :SUBSCRIPTION
|
763
|
+
advance_token
|
764
|
+
Nodes::Enum.new(pos: pos, name: "subscription", filename: @filename, source: self)
|
765
|
+
when :FRAGMENT
|
766
|
+
advance_token
|
767
|
+
Nodes::Enum.new(pos: pos, name: "fragment", filename: @filename, source: self)
|
768
|
+
when :REPEATABLE
|
769
|
+
advance_token
|
770
|
+
Nodes::Enum.new(pos: pos, name: "repeatable", filename: @filename, source: self)
|
771
|
+
when :ON
|
772
|
+
advance_token
|
773
|
+
Nodes::Enum.new(pos: pos, name: "on", filename: @filename, source: self)
|
774
|
+
when :EXTEND
|
775
|
+
advance_token
|
776
|
+
Nodes::Enum.new(pos: pos, name: "extend", filename: @filename, source: self)
|
736
777
|
else
|
737
778
|
expect_token(:VALUE)
|
738
779
|
end
|
data/lib/graphql/query.rb
CHANGED
@@ -222,7 +222,7 @@ module GraphQL
|
|
222
222
|
end
|
223
223
|
|
224
224
|
# Get the result for this query, executing it once
|
225
|
-
# @return [
|
225
|
+
# @return [GraphQL::Query::Result] A Hash-like GraphQL response, with `"data"` and/or `"errors"` keys
|
226
226
|
def result
|
227
227
|
if !@executed
|
228
228
|
Execution::Interpreter.run_all(@schema, [self], context: @context)
|
@@ -304,7 +304,7 @@ module GraphQL
|
|
304
304
|
|
305
305
|
# @return [String] An opaque hash for identifying this query's given query string and selected operation
|
306
306
|
def operation_fingerprint
|
307
|
-
@operation_fingerprint ||= "#{selected_operation_name || "anonymous"}/#{Fingerprint.generate(query_string)}"
|
307
|
+
@operation_fingerprint ||= "#{selected_operation_name || "anonymous"}/#{Fingerprint.generate(query_string || "")}"
|
308
308
|
end
|
309
309
|
|
310
310
|
# @return [String] An opaque hash for identifying this query's given a variable values (not including defaults)
|
@@ -9,7 +9,7 @@ module GraphQL
|
|
9
9
|
|
10
10
|
# Return the source of `send_node`, but without the keyword argument represented by `pair_node`
|
11
11
|
def source_without_keyword_argument(send_node, pair_node)
|
12
|
-
# work back to the
|
12
|
+
# work back to the preceding comma
|
13
13
|
first_pos = pair_node.location.expression.begin_pos
|
14
14
|
end_pos = pair_node.location.expression.end_pos
|
15
15
|
node_source = send_node.source_range.source
|
@@ -12,7 +12,7 @@ module GraphQL
|
|
12
12
|
@possible_types = {}
|
13
13
|
@types = {}
|
14
14
|
@union_memberships = {}
|
15
|
-
@references = Hash.new { |h, k| h[k] =
|
15
|
+
@references = Hash.new { |h, k| h[k] = Set.new }
|
16
16
|
@arguments_with_default_values = []
|
17
17
|
add_type_and_traverse(new_types)
|
18
18
|
end
|
@@ -20,7 +20,7 @@ module GraphQL
|
|
20
20
|
private
|
21
21
|
|
22
22
|
def references_to(thing, from:)
|
23
|
-
@references[thing]
|
23
|
+
@references[thing].add(from)
|
24
24
|
end
|
25
25
|
|
26
26
|
def get_type(name)
|
@@ -95,7 +95,7 @@ module GraphQL
|
|
95
95
|
# It's a union with possible_types
|
96
96
|
# Replace the item by class name
|
97
97
|
owner.assign_type_membership_object_type(type)
|
98
|
-
@possible_types[owner
|
98
|
+
@possible_types[owner] = owner.possible_types
|
99
99
|
elsif type.kind.interface? && (owner.kind.object? || owner.kind.interface?)
|
100
100
|
new_interfaces = []
|
101
101
|
owner.interfaces.each do |int_t|
|
@@ -110,7 +110,7 @@ module GraphQL
|
|
110
110
|
end
|
111
111
|
owner.implements(*new_interfaces)
|
112
112
|
new_interfaces.each do |int|
|
113
|
-
pt = @possible_types[int
|
113
|
+
pt = @possible_types[int] ||= []
|
114
114
|
if !pt.include?(owner) && owner.is_a?(Class)
|
115
115
|
pt << owner
|
116
116
|
end
|
@@ -126,6 +126,7 @@ module GraphQL
|
|
126
126
|
@types[type.graphql_name] = type
|
127
127
|
when GraphQL::Schema::Field, GraphQL::Schema::Argument
|
128
128
|
orig_type = owner.type
|
129
|
+
unwrapped_t = type
|
129
130
|
# Apply list/non-null wrapper as needed
|
130
131
|
if orig_type.respond_to?(:of_type)
|
131
132
|
transforms = []
|
@@ -142,6 +143,7 @@ module GraphQL
|
|
142
143
|
transforms.reverse_each { |t| type = type.public_send(t) }
|
143
144
|
end
|
144
145
|
owner.type = type
|
146
|
+
references_to(unwrapped_t, from: owner)
|
145
147
|
else
|
146
148
|
raise "Unexpected update: #{owner.inspect} #{type.inspect}"
|
147
149
|
end
|
@@ -164,7 +166,9 @@ module GraphQL
|
|
164
166
|
@directives << type
|
165
167
|
type.all_argument_definitions.each do |arg|
|
166
168
|
arg_type = arg.type.unwrap
|
167
|
-
|
169
|
+
if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
|
170
|
+
references_to(arg_type, from: arg)
|
171
|
+
end
|
168
172
|
path.push(arg.graphql_name)
|
169
173
|
add_type(arg_type, owner: arg, late_types: late_types, path: path)
|
170
174
|
path.pop
|
@@ -187,14 +191,18 @@ module GraphQL
|
|
187
191
|
type.all_field_definitions.each do |field|
|
188
192
|
name = field.graphql_name
|
189
193
|
field_type = field.type.unwrap
|
190
|
-
|
194
|
+
if !field_type.is_a?(GraphQL::Schema::LateBoundType)
|
195
|
+
references_to(field_type, from: field)
|
196
|
+
end
|
191
197
|
path.push(name)
|
192
198
|
add_type(field_type, owner: field, late_types: late_types, path: path)
|
193
199
|
add_directives_from(field)
|
194
200
|
field.all_argument_definitions.each do |arg|
|
195
201
|
add_directives_from(arg)
|
196
202
|
arg_type = arg.type.unwrap
|
197
|
-
|
203
|
+
if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
|
204
|
+
references_to(arg_type, from: arg)
|
205
|
+
end
|
198
206
|
path.push(arg.graphql_name)
|
199
207
|
add_type(arg_type, owner: arg, late_types: late_types, path: path)
|
200
208
|
path.pop
|
@@ -209,7 +217,9 @@ module GraphQL
|
|
209
217
|
type.all_argument_definitions.each do |arg|
|
210
218
|
add_directives_from(arg)
|
211
219
|
arg_type = arg.type.unwrap
|
212
|
-
|
220
|
+
if !arg_type.is_a?(GraphQL::Schema::LateBoundType)
|
221
|
+
references_to(arg_type, from: arg)
|
222
|
+
end
|
213
223
|
path.push(arg.graphql_name)
|
214
224
|
add_type(arg_type, owner: arg, late_types: late_types, path: path)
|
215
225
|
path.pop
|
@@ -219,7 +229,7 @@ module GraphQL
|
|
219
229
|
end
|
220
230
|
end
|
221
231
|
if type.kind.union?
|
222
|
-
@possible_types[type
|
232
|
+
@possible_types[type] = type.all_possible_types
|
223
233
|
path.push("possible_types")
|
224
234
|
type.all_possible_types.each do |t|
|
225
235
|
add_type(t, owner: type, late_types: late_types, path: path)
|
@@ -234,7 +244,7 @@ module GraphQL
|
|
234
244
|
path.pop
|
235
245
|
end
|
236
246
|
if type.kind.object?
|
237
|
-
possible_types_for_this_name = @possible_types[type
|
247
|
+
possible_types_for_this_name = @possible_types[type] ||= []
|
238
248
|
possible_types_for_this_name << type
|
239
249
|
end
|
240
250
|
|
@@ -246,7 +256,7 @@ module GraphQL
|
|
246
256
|
interface_type = interface_type_membership.abstract_type
|
247
257
|
# We can get these now; we'll have to get late-bound types later
|
248
258
|
if interface_type.is_a?(Module) && type.is_a?(Class)
|
249
|
-
implementers = @possible_types[interface_type
|
259
|
+
implementers = @possible_types[interface_type] ||= []
|
250
260
|
implementers << type
|
251
261
|
end
|
252
262
|
when String, Schema::LateBoundType
|
@@ -47,6 +47,7 @@ module GraphQL
|
|
47
47
|
def dummy
|
48
48
|
@dummy ||= begin
|
49
49
|
d = Class.new(GraphQL::Schema::Resolver)
|
50
|
+
d.graphql_name "#{self.graphql_name}DummyResolver"
|
50
51
|
d.argument_class(self.argument_class)
|
51
52
|
# TODO make this lazier?
|
52
53
|
d.argument(:input, input_type, description: "Parameters for #{self.graphql_name}")
|
@@ -25,10 +25,10 @@ module GraphQL
|
|
25
25
|
load_constant(:DirectiveLocationEnum)
|
26
26
|
]
|
27
27
|
@types = {}
|
28
|
-
@possible_types = {}
|
28
|
+
@possible_types = {}.tap(&:compare_by_identity)
|
29
29
|
type_defns.each do |t|
|
30
30
|
@types[t.graphql_name] = t
|
31
|
-
@possible_types[t
|
31
|
+
@possible_types[t] = [t]
|
32
32
|
end
|
33
33
|
@entry_point_fields =
|
34
34
|
if schema.disable_introspection_entry_points?
|
data/lib/graphql/schema/list.rb
CHANGED
@@ -52,7 +52,7 @@ module GraphQL
|
|
52
52
|
unless item_result.valid?
|
53
53
|
if max_errors
|
54
54
|
if max_errors == 0
|
55
|
-
|
55
|
+
add_max_errors_reached_message(result)
|
56
56
|
break
|
57
57
|
end
|
58
58
|
|
@@ -76,7 +76,7 @@ module GraphQL
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
79
|
+
def add_max_errors_reached_message(result)
|
80
80
|
message = "Too many errors processing list variable, max validation error limit reached. Execution aborted"
|
81
81
|
item_result = GraphQL::Query::InputValidationResult.from_problem(message)
|
82
82
|
result.merge_result!(nil, item_result)
|
@@ -38,39 +38,6 @@ module GraphQL
|
|
38
38
|
end
|
39
39
|
arg_defn = self.argument_class.new(*args, **kwargs, &block)
|
40
40
|
add_argument(arg_defn)
|
41
|
-
|
42
|
-
if self.is_a?(Class) && !method_defined?(:"load_#{arg_defn.keyword}")
|
43
|
-
method_owner = if self < GraphQL::Schema::InputObject || self < GraphQL::Schema::Directive
|
44
|
-
"self."
|
45
|
-
elsif self < GraphQL::Schema::Resolver
|
46
|
-
""
|
47
|
-
else
|
48
|
-
raise "Unexpected argument owner: #{self}"
|
49
|
-
end
|
50
|
-
if loads && arg_defn.type.list?
|
51
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
52
|
-
def #{method_owner}load_#{arg_defn.keyword}(values, context = nil)
|
53
|
-
argument = get_argument("#{arg_defn.graphql_name}", context || self.context)
|
54
|
-
(context || self.context).query.after_lazy(values) do |values2|
|
55
|
-
GraphQL::Execution::Lazy.all(values2.map { |value| load_application_object(argument, value, context || self.context) })
|
56
|
-
end
|
57
|
-
end
|
58
|
-
RUBY
|
59
|
-
elsif loads
|
60
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
61
|
-
def #{method_owner}load_#{arg_defn.keyword}(value, context = nil)
|
62
|
-
argument = get_argument("#{arg_defn.graphql_name}", context || self.context)
|
63
|
-
load_application_object(argument, value, context || self.context)
|
64
|
-
end
|
65
|
-
RUBY
|
66
|
-
else
|
67
|
-
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
68
|
-
def #{method_owner}load_#{arg_defn.keyword}(value, _context = nil)
|
69
|
-
value
|
70
|
-
end
|
71
|
-
RUBY
|
72
|
-
end
|
73
|
-
end
|
74
41
|
arg_defn
|
75
42
|
end
|
76
43
|
|
@@ -259,8 +226,8 @@ module GraphQL
|
|
259
226
|
#
|
260
227
|
# @param values [Hash<String, Object>]
|
261
228
|
# @param context [GraphQL::Query::Context]
|
262
|
-
# @yield [Interpreter::Arguments, Execution::Lazy<
|
263
|
-
# @return [Interpreter::Arguments, Execution::Lazy<
|
229
|
+
# @yield [Interpreter::Arguments, Execution::Lazy<Interpreter::Arguments>]
|
230
|
+
# @return [Interpreter::Arguments, Execution::Lazy<Interpreter::Arguments>]
|
264
231
|
def coerce_arguments(parent_object, values, context, &block)
|
265
232
|
# Cache this hash to avoid re-merging it
|
266
233
|
arg_defns = context.warden.arguments(self)
|
@@ -91,7 +91,7 @@ module GraphQL
|
|
91
91
|
private
|
92
92
|
|
93
93
|
# Modify `target` by adding items from `dirs` such that:
|
94
|
-
# - Any name conflict is
|
94
|
+
# - Any name conflict is overridden by the incoming member of `dirs`
|
95
95
|
# - Any other member of `dirs` is appended
|
96
96
|
# @param target [Array<GraphQL::Schema::Directive>]
|
97
97
|
# @param dirs [Array<GraphQL::Schema::Directive>]
|
@@ -76,7 +76,7 @@ module GraphQL
|
|
76
76
|
|
77
77
|
private
|
78
78
|
|
79
|
-
# If one of
|
79
|
+
# If one of these values is accessed, initialize all the instance variables to retain
|
80
80
|
# a consistent object shape.
|
81
81
|
def initialize_relay_metadata
|
82
82
|
if !defined?(@connection_type)
|
@@ -4,12 +4,11 @@ module GraphQL
|
|
4
4
|
class Schema
|
5
5
|
class Member
|
6
6
|
module TypeSystemHelpers
|
7
|
-
def initialize(
|
7
|
+
def initialize(...)
|
8
8
|
super
|
9
9
|
@to_non_null_type ||= nil
|
10
10
|
@to_list_type ||= nil
|
11
11
|
end
|
12
|
-
ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
|
13
12
|
|
14
13
|
# @return [Schema::NonNull] Make a non-null-type representation of this type
|
15
14
|
def to_non_null_type
|
@@ -295,7 +295,7 @@ module GraphQL
|
|
295
295
|
true
|
296
296
|
else
|
297
297
|
if @context.respond_to?(:logger) && (logger = @context.logger)
|
298
|
-
logger.debug { "Interface `#{type_defn.graphql_name}` hidden because it has no visible
|
298
|
+
logger.debug { "Interface `#{type_defn.graphql_name}` hidden because it has no visible implementers" }
|
299
299
|
end
|
300
300
|
false
|
301
301
|
end
|
@@ -363,8 +363,7 @@ module GraphQL
|
|
363
363
|
end
|
364
364
|
|
365
365
|
def referenced?(type_defn)
|
366
|
-
|
367
|
-
members = @schema.references_to(graphql_name)
|
366
|
+
members = @schema.references_to(type_defn)
|
368
367
|
members.any? { |m| visible?(m) }
|
369
368
|
end
|
370
369
|
|
data/lib/graphql/schema.rb
CHANGED
@@ -187,7 +187,7 @@ module GraphQL
|
|
187
187
|
# {default_trace_mode} is used when no `trace_mode: ...` is requested.
|
188
188
|
#
|
189
189
|
# When a `trace_class` is added this way, it will _not_ receive other modules added with `trace_with(...)`
|
190
|
-
# unless `trace_mode` is explicitly given. (This class will not
|
190
|
+
# unless `trace_mode` is explicitly given. (This class will not receive any default trace modules.)
|
191
191
|
#
|
192
192
|
# Subclasses of the schema will use `trace_class` as a base class for this mode and those
|
193
193
|
# subclass also will _not_ receive default tracing modules.
|
@@ -506,7 +506,7 @@ module GraphQL
|
|
506
506
|
if type.kind.union?
|
507
507
|
type.possible_types(context: context)
|
508
508
|
else
|
509
|
-
stored_possible_types = own_possible_types[type
|
509
|
+
stored_possible_types = own_possible_types[type]
|
510
510
|
visible_possible_types = if stored_possible_types && type.kind.interface?
|
511
511
|
stored_possible_types.select do |possible_type|
|
512
512
|
possible_type.interfaces(context).include?(type)
|
@@ -515,7 +515,7 @@ module GraphQL
|
|
515
515
|
stored_possible_types
|
516
516
|
end
|
517
517
|
visible_possible_types ||
|
518
|
-
introspection_system.possible_types[type
|
518
|
+
introspection_system.possible_types[type] ||
|
519
519
|
(
|
520
520
|
superclass.respond_to?(:possible_types) ?
|
521
521
|
superclass.possible_types(type, context) :
|
@@ -553,14 +553,9 @@ module GraphQL
|
|
553
553
|
attr_writer :dataloader_class
|
554
554
|
|
555
555
|
def references_to(to_type = nil, from: nil)
|
556
|
-
@own_references_to ||= {}
|
557
556
|
if to_type
|
558
|
-
if !to_type.is_a?(String)
|
559
|
-
to_type = to_type.graphql_name
|
560
|
-
end
|
561
|
-
|
562
557
|
if from
|
563
|
-
refs =
|
558
|
+
refs = own_references_to[to_type] ||= []
|
564
559
|
refs << from
|
565
560
|
else
|
566
561
|
get_references_to(to_type) || EMPTY_ARRAY
|
@@ -571,9 +566,9 @@ module GraphQL
|
|
571
566
|
# So optimize the most common case -- don't create a duplicate Hash.
|
572
567
|
inherited_value = find_inherited_value(:references_to, EMPTY_HASH)
|
573
568
|
if inherited_value.any?
|
574
|
-
inherited_value.merge(
|
569
|
+
inherited_value.merge(own_references_to)
|
575
570
|
else
|
576
|
-
|
571
|
+
own_references_to
|
577
572
|
end
|
578
573
|
end
|
579
574
|
end
|
@@ -1287,7 +1282,7 @@ module GraphQL
|
|
1287
1282
|
|
1288
1283
|
# Execute a query on itself.
|
1289
1284
|
# @see {Query#initialize} for arguments.
|
1290
|
-
# @return [
|
1285
|
+
# @return [GraphQL::Query::Result] query result, ready to be serialized as JSON
|
1291
1286
|
def execute(query_str = nil, **kwargs)
|
1292
1287
|
if query_str
|
1293
1288
|
kwargs[:query] = query_str
|
@@ -1327,7 +1322,7 @@ module GraphQL
|
|
1327
1322
|
# @see {Execution::Multiplex#run_all} for multiplex keyword arguments
|
1328
1323
|
# @param queries [Array<Hash>] Keyword arguments for each query
|
1329
1324
|
# @param context [Hash] Multiplex-level context
|
1330
|
-
# @return [Array<
|
1325
|
+
# @return [Array<GraphQL::Query::Result>] One result for each query in the input
|
1331
1326
|
def multiplex(queries, **kwargs)
|
1332
1327
|
GraphQL::Execution::Interpreter.run_all(self, queries, **kwargs)
|
1333
1328
|
end
|
@@ -1460,7 +1455,8 @@ module GraphQL
|
|
1460
1455
|
own_union_memberships.merge!(addition.union_memberships)
|
1461
1456
|
|
1462
1457
|
addition.references.each { |thing, pointers|
|
1463
|
-
|
1458
|
+
prev_refs = own_references_to[thing] || []
|
1459
|
+
own_references_to[thing] = prev_refs | pointers.to_a
|
1464
1460
|
}
|
1465
1461
|
|
1466
1462
|
addition.directives.each { |dir_class| own_directives[dir_class.graphql_name] = dir_class }
|
@@ -1488,6 +1484,10 @@ module GraphQL
|
|
1488
1484
|
@own_types ||= {}
|
1489
1485
|
end
|
1490
1486
|
|
1487
|
+
def own_references_to
|
1488
|
+
@own_references_to ||= {}.tap(&:compare_by_identity)
|
1489
|
+
end
|
1490
|
+
|
1491
1491
|
def non_introspection_types
|
1492
1492
|
find_inherited_value(:non_introspection_types, EMPTY_HASH).merge(own_types)
|
1493
1493
|
end
|
@@ -1501,7 +1501,7 @@ module GraphQL
|
|
1501
1501
|
end
|
1502
1502
|
|
1503
1503
|
def own_possible_types
|
1504
|
-
@own_possible_types ||= {}
|
1504
|
+
@own_possible_types ||= {}.tap(&:compare_by_identity)
|
1505
1505
|
end
|
1506
1506
|
|
1507
1507
|
def own_union_memberships
|
@@ -1529,15 +1529,15 @@ module GraphQL
|
|
1529
1529
|
end
|
1530
1530
|
|
1531
1531
|
# This is overridden in subclasses to check the inheritance chain
|
1532
|
-
def get_references_to(
|
1533
|
-
|
1532
|
+
def get_references_to(type_defn)
|
1533
|
+
own_references_to[type_defn]
|
1534
1534
|
end
|
1535
1535
|
end
|
1536
1536
|
|
1537
1537
|
module SubclassGetReferencesTo
|
1538
|
-
def get_references_to(
|
1539
|
-
own_refs =
|
1540
|
-
inherited_refs = superclass.references_to(
|
1538
|
+
def get_references_to(type_defn)
|
1539
|
+
own_refs = own_references_to[type_defn]
|
1540
|
+
inherited_refs = superclass.references_to(type_defn)
|
1541
1541
|
if inherited_refs&.any?
|
1542
1542
|
if own_refs&.any?
|
1543
1543
|
own_refs + inherited_refs
|
@@ -396,7 +396,7 @@ module GraphQL
|
|
396
396
|
end
|
397
397
|
|
398
398
|
# Given two list of parents, find out if they are mutually exclusive
|
399
|
-
# In this context, `parents`
|
399
|
+
# In this context, `parents` represents the "self scope" of the field,
|
400
400
|
# what types may be found at this point in the query.
|
401
401
|
def mutually_exclusive?(parents1, parents2)
|
402
402
|
if parents1.empty? || parents2.empty?
|
@@ -107,7 +107,7 @@ module GraphQL
|
|
107
107
|
when 2
|
108
108
|
true
|
109
109
|
else
|
110
|
-
raise ArgumentError, "#{@serializer} must
|
110
|
+
raise ArgumentError, "#{@serializer} must respond to `.load` accepting one or two arguments"
|
111
111
|
end
|
112
112
|
@transmit_ns = namespace
|
113
113
|
super
|
@@ -25,33 +25,33 @@ module GraphQL
|
|
25
25
|
}.each do |trace_method, platform_key|
|
26
26
|
module_eval <<-RUBY, __FILE__, __LINE__
|
27
27
|
def #{trace_method}(**data)
|
28
|
-
|
28
|
+
instrument_prometheus_execution("#{platform_key}", "#{trace_method}") { super }
|
29
29
|
end
|
30
30
|
RUBY
|
31
31
|
end
|
32
32
|
|
33
33
|
def platform_execute_field(platform_key, &block)
|
34
|
-
|
34
|
+
instrument_prometheus_execution(platform_key, "execute_field", &block)
|
35
35
|
end
|
36
36
|
|
37
37
|
def platform_execute_field_lazy(platform_key, &block)
|
38
|
-
|
38
|
+
instrument_prometheus_execution(platform_key, "execute_field_lazy", &block)
|
39
39
|
end
|
40
40
|
|
41
41
|
def platform_authorized(platform_key, &block)
|
42
|
-
|
42
|
+
instrument_prometheus_execution(platform_key, "authorized", &block)
|
43
43
|
end
|
44
44
|
|
45
45
|
def platform_authorized_lazy(platform_key, &block)
|
46
|
-
|
46
|
+
instrument_prometheus_execution(platform_key, "authorized_lazy", &block)
|
47
47
|
end
|
48
48
|
|
49
49
|
def platform_resolve_type(platform_key, &block)
|
50
|
-
|
50
|
+
instrument_prometheus_execution(platform_key, "resolve_type", &block)
|
51
51
|
end
|
52
52
|
|
53
53
|
def platform_resolve_type_lazy(platform_key, &block)
|
54
|
-
|
54
|
+
instrument_prometheus_execution(platform_key, "resolve_type_lazy", &block)
|
55
55
|
end
|
56
56
|
|
57
57
|
def platform_field_key(field)
|
@@ -68,7 +68,7 @@ module GraphQL
|
|
68
68
|
|
69
69
|
private
|
70
70
|
|
71
|
-
def
|
71
|
+
def instrument_prometheus_execution(platform_key, key, &block)
|
72
72
|
if @keys_whitelist.include?(key)
|
73
73
|
start = ::Process.clock_gettime ::Process::CLOCK_MONOTONIC
|
74
74
|
result = block.call
|