graphql 2.1.15 → 2.2.0
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/graphql/dataloader/async_dataloader.rb +88 -0
- data/lib/graphql/dataloader/source.rb +5 -8
- data/lib/graphql/dataloader.rb +35 -21
- data/lib/graphql/language/lexer.rb +271 -177
- data/lib/graphql/language/nodes.rb +72 -57
- data/lib/graphql/language/parser.rb +686 -1986
- data/lib/graphql/language/printer.rb +16 -12
- data/lib/graphql/language/static_visitor.rb +33 -37
- data/lib/graphql/language/visitor.rb +55 -59
- data/lib/graphql/schema/argument.rb +5 -3
- data/lib/graphql/schema/build_from_definition.rb +7 -8
- data/lib/graphql/schema/directive.rb +1 -1
- data/lib/graphql/schema/enum_value.rb +1 -1
- data/lib/graphql/schema/field.rb +1 -1
- data/lib/graphql/schema/input_object.rb +6 -8
- data/lib/graphql/schema/interface.rb +2 -6
- data/lib/graphql/schema/member/has_directives.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +1 -1
- data/lib/graphql/schema/member/has_interfaces.rb +1 -1
- data/lib/graphql/schema/member/scoped.rb +1 -1
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
- data/lib/graphql/schema.rb +6 -5
- data/lib/graphql/testing/helpers.rb +125 -0
- data/lib/graphql/testing.rb +2 -0
- data/lib/graphql/tracing/appoptics_trace.rb +0 -4
- data/lib/graphql/tracing/appsignal_trace.rb +0 -4
- data/lib/graphql/tracing/data_dog_trace.rb +34 -25
- data/lib/graphql/tracing/data_dog_tracing.rb +21 -7
- data/lib/graphql/tracing/notifications_trace.rb +0 -4
- data/lib/graphql/tracing/platform_trace.rb +0 -5
- data/lib/graphql/tracing/prometheus_trace.rb +0 -4
- data/lib/graphql/tracing/scout_trace.rb +0 -3
- data/lib/graphql/tracing/statsd_trace.rb +0 -4
- data/lib/graphql/tracing/trace.rb +1 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +1 -1
- data/lib/graphql/types/relay/edge_behaviors.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -0
- metadata +21 -19
- data/lib/graphql/language/parser.y +0 -560
@@ -337,14 +337,16 @@ module GraphQL
|
|
337
337
|
print_string("union ")
|
338
338
|
print_string(union_type.name)
|
339
339
|
print_directives(union_type.directives)
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
340
|
+
if union_type.types.any?
|
341
|
+
print_string(" = ")
|
342
|
+
i = 0
|
343
|
+
union_type.types.each do |t|
|
344
|
+
if i > 0
|
345
|
+
print_string(" | ")
|
346
|
+
end
|
347
|
+
print_string(t.name)
|
348
|
+
i += 1
|
345
349
|
end
|
346
|
-
print_string(t.name)
|
347
|
-
i += 1
|
348
350
|
end
|
349
351
|
end
|
350
352
|
|
@@ -353,12 +355,14 @@ module GraphQL
|
|
353
355
|
print_string("enum ")
|
354
356
|
print_string(enum_type.name)
|
355
357
|
print_directives(enum_type.directives)
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
358
|
+
if enum_type.values.any?
|
359
|
+
print_string(" {\n")
|
360
|
+
enum_type.values.each.with_index do |value, i|
|
361
|
+
print_description(value, indent: " ", first_in_block: i == 0)
|
362
|
+
print_enum_value_definition(value)
|
363
|
+
end
|
364
|
+
print_string("}")
|
360
365
|
end
|
361
|
-
print_string("}")
|
362
366
|
end
|
363
367
|
|
364
368
|
def print_enum_value_definition(enum_value)
|
@@ -22,6 +22,39 @@ module GraphQL
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
# We don't use `alias` here because it breaks `super`
|
26
|
+
def self.make_visit_methods(ast_node_class)
|
27
|
+
node_method = ast_node_class.visit_method
|
28
|
+
children_of_type = ast_node_class.children_of_type
|
29
|
+
child_visit_method = :"#{node_method}_children"
|
30
|
+
|
31
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
32
|
+
# The default implementation for visiting an AST node.
|
33
|
+
# It doesn't _do_ anything, but it continues to visiting the node's children.
|
34
|
+
# To customize this hook, override one of its make_visit_methods (or the base method?)
|
35
|
+
# in your subclasses.
|
36
|
+
#
|
37
|
+
# @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
|
38
|
+
# @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
|
39
|
+
# @return [void]
|
40
|
+
def #{node_method}(node, parent)
|
41
|
+
#{
|
42
|
+
if method_defined?(child_visit_method)
|
43
|
+
"#{child_visit_method}(node)"
|
44
|
+
elsif children_of_type
|
45
|
+
children_of_type.map do |child_accessor, child_class|
|
46
|
+
"node.#{child_accessor}.each do |child_node|
|
47
|
+
#{child_class.visit_method}(child_node, node)
|
48
|
+
end"
|
49
|
+
end.join("\n")
|
50
|
+
else
|
51
|
+
""
|
52
|
+
end
|
53
|
+
}
|
54
|
+
end
|
55
|
+
RUBY
|
56
|
+
end
|
57
|
+
|
25
58
|
def on_document_children(document_node)
|
26
59
|
document_node.children.each do |child_node|
|
27
60
|
visit_method = child_node.visit_method
|
@@ -90,41 +123,6 @@ module GraphQL
|
|
90
123
|
end
|
91
124
|
end
|
92
125
|
|
93
|
-
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
94
|
-
|
95
|
-
# We don't use `alias` here because it breaks `super`
|
96
|
-
def self.make_visit_methods(ast_node_class)
|
97
|
-
node_method = ast_node_class.visit_method
|
98
|
-
children_of_type = ast_node_class.children_of_type
|
99
|
-
child_visit_method = :"#{node_method}_children"
|
100
|
-
|
101
|
-
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
102
|
-
# The default implementation for visiting an AST node.
|
103
|
-
# It doesn't _do_ anything, but it continues to visiting the node's children.
|
104
|
-
# To customize this hook, override one of its make_visit_methods (or the base method?)
|
105
|
-
# in your subclasses.
|
106
|
-
#
|
107
|
-
# @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
|
108
|
-
# @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
|
109
|
-
# @return [void]
|
110
|
-
def #{node_method}(node, parent)
|
111
|
-
#{
|
112
|
-
if method_defined?(child_visit_method)
|
113
|
-
"#{child_visit_method}(node)"
|
114
|
-
elsif children_of_type
|
115
|
-
children_of_type.map do |child_accessor, child_class|
|
116
|
-
"node.#{child_accessor}.each do |child_node|
|
117
|
-
#{child_class.visit_method}(child_node, node)
|
118
|
-
end"
|
119
|
-
end.join("\n")
|
120
|
-
else
|
121
|
-
""
|
122
|
-
end
|
123
|
-
}
|
124
|
-
end
|
125
|
-
RUBY
|
126
|
-
end
|
127
|
-
|
128
126
|
[
|
129
127
|
Language::Nodes::Argument,
|
130
128
|
Language::Nodes::Directive,
|
@@ -164,8 +162,6 @@ module GraphQL
|
|
164
162
|
].each do |ast_node_class|
|
165
163
|
make_visit_methods(ast_node_class)
|
166
164
|
end
|
167
|
-
|
168
|
-
# rubocop:disable Development/NoEvalCop
|
169
165
|
end
|
170
166
|
end
|
171
167
|
end
|
@@ -61,6 +61,61 @@ module GraphQL
|
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
|
+
# We don't use `alias` here because it breaks `super`
|
65
|
+
def self.make_visit_methods(ast_node_class)
|
66
|
+
node_method = ast_node_class.visit_method
|
67
|
+
children_of_type = ast_node_class.children_of_type
|
68
|
+
child_visit_method = :"#{node_method}_children"
|
69
|
+
|
70
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
71
|
+
# The default implementation for visiting an AST node.
|
72
|
+
# It doesn't _do_ anything, but it continues to visiting the node's children.
|
73
|
+
# To customize this hook, override one of its make_visit_methods (or the base method?)
|
74
|
+
# in your subclasses.
|
75
|
+
#
|
76
|
+
# @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
|
77
|
+
# @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
|
78
|
+
# @return [Array, nil] If there were modifications, it returns an array of new nodes, otherwise, it returns `nil`.
|
79
|
+
def #{node_method}(node, parent)
|
80
|
+
if node.equal?(DELETE_NODE)
|
81
|
+
# This might be passed to `super(DELETE_NODE, ...)`
|
82
|
+
# by a user hook, don't want to keep visiting in that case.
|
83
|
+
[node, parent]
|
84
|
+
else
|
85
|
+
new_node = node
|
86
|
+
#{
|
87
|
+
if method_defined?(child_visit_method)
|
88
|
+
"new_node = #{child_visit_method}(new_node)"
|
89
|
+
elsif children_of_type
|
90
|
+
children_of_type.map do |child_accessor, child_class|
|
91
|
+
"node.#{child_accessor}.each do |child_node|
|
92
|
+
new_child_and_node = #{child_class.visit_method}_with_modifications(child_node, new_node)
|
93
|
+
# Reassign `node` in case the child hook makes a modification
|
94
|
+
if new_child_and_node.is_a?(Array)
|
95
|
+
new_node = new_child_and_node[1]
|
96
|
+
end
|
97
|
+
end"
|
98
|
+
end.join("\n")
|
99
|
+
else
|
100
|
+
""
|
101
|
+
end
|
102
|
+
}
|
103
|
+
|
104
|
+
if new_node.equal?(node)
|
105
|
+
[node, parent]
|
106
|
+
else
|
107
|
+
[new_node, parent]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def #{node_method}_with_modifications(node, parent)
|
113
|
+
new_node_and_new_parent = #{node_method}(node, parent)
|
114
|
+
apply_modifications(node, parent, new_node_and_new_parent)
|
115
|
+
end
|
116
|
+
RUBY
|
117
|
+
end
|
118
|
+
|
64
119
|
def on_document_children(document_node)
|
65
120
|
new_node = document_node
|
66
121
|
document_node.children.each do |child_node|
|
@@ -161,63 +216,6 @@ module GraphQL
|
|
161
216
|
new_node
|
162
217
|
end
|
163
218
|
|
164
|
-
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
165
|
-
|
166
|
-
# We don't use `alias` here because it breaks `super`
|
167
|
-
def self.make_visit_methods(ast_node_class)
|
168
|
-
node_method = ast_node_class.visit_method
|
169
|
-
children_of_type = ast_node_class.children_of_type
|
170
|
-
child_visit_method = :"#{node_method}_children"
|
171
|
-
|
172
|
-
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
173
|
-
# The default implementation for visiting an AST node.
|
174
|
-
# It doesn't _do_ anything, but it continues to visiting the node's children.
|
175
|
-
# To customize this hook, override one of its make_visit_methods (or the base method?)
|
176
|
-
# in your subclasses.
|
177
|
-
#
|
178
|
-
# @param node [GraphQL::Language::Nodes::AbstractNode] the node being visited
|
179
|
-
# @param parent [GraphQL::Language::Nodes::AbstractNode, nil] the previously-visited node, or `nil` if this is the root node.
|
180
|
-
# @return [Array, nil] If there were modifications, it returns an array of new nodes, otherwise, it returns `nil`.
|
181
|
-
def #{node_method}(node, parent)
|
182
|
-
if node.equal?(DELETE_NODE)
|
183
|
-
# This might be passed to `super(DELETE_NODE, ...)`
|
184
|
-
# by a user hook, don't want to keep visiting in that case.
|
185
|
-
[node, parent]
|
186
|
-
else
|
187
|
-
new_node = node
|
188
|
-
#{
|
189
|
-
if method_defined?(child_visit_method)
|
190
|
-
"new_node = #{child_visit_method}(new_node)"
|
191
|
-
elsif children_of_type
|
192
|
-
children_of_type.map do |child_accessor, child_class|
|
193
|
-
"node.#{child_accessor}.each do |child_node|
|
194
|
-
new_child_and_node = #{child_class.visit_method}_with_modifications(child_node, new_node)
|
195
|
-
# Reassign `node` in case the child hook makes a modification
|
196
|
-
if new_child_and_node.is_a?(Array)
|
197
|
-
new_node = new_child_and_node[1]
|
198
|
-
end
|
199
|
-
end"
|
200
|
-
end.join("\n")
|
201
|
-
else
|
202
|
-
""
|
203
|
-
end
|
204
|
-
}
|
205
|
-
|
206
|
-
if new_node.equal?(node)
|
207
|
-
[node, parent]
|
208
|
-
else
|
209
|
-
[new_node, parent]
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
def #{node_method}_with_modifications(node, parent)
|
215
|
-
new_node_and_new_parent = #{node_method}(node, parent)
|
216
|
-
apply_modifications(node, parent, new_node_and_new_parent)
|
217
|
-
end
|
218
|
-
RUBY
|
219
|
-
end
|
220
|
-
|
221
219
|
[
|
222
220
|
Language::Nodes::Argument,
|
223
221
|
Language::Nodes::Directive,
|
@@ -258,8 +256,6 @@ module GraphQL
|
|
258
256
|
make_visit_methods(ast_node_class)
|
259
257
|
end
|
260
258
|
|
261
|
-
# rubocop:enable Development/NoEvalCop
|
262
|
-
|
263
259
|
private
|
264
260
|
|
265
261
|
def apply_modifications(node, parent, new_node_and_new_parent)
|
@@ -53,7 +53,6 @@ module GraphQL
|
|
53
53
|
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NOT_CONFIGURED, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
|
54
54
|
arg_name ||= name
|
55
55
|
@name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
|
56
|
-
NameValidator.validate!(@name)
|
57
56
|
@type_expr = type_expr || type
|
58
57
|
@description = desc || description
|
59
58
|
@null = required != true
|
@@ -89,8 +88,11 @@ module GraphQL
|
|
89
88
|
end
|
90
89
|
|
91
90
|
if definition_block
|
92
|
-
|
93
|
-
|
91
|
+
if definition_block.arity == 1
|
92
|
+
instance_exec(self, &definition_block)
|
93
|
+
else
|
94
|
+
instance_eval(&definition_block)
|
95
|
+
end
|
94
96
|
end
|
95
97
|
end
|
96
98
|
|
@@ -451,18 +451,17 @@ module GraphQL
|
|
451
451
|
|
452
452
|
# Don't do this for interfaces
|
453
453
|
if default_resolve
|
454
|
-
|
454
|
+
owner.class_eval <<-RUBY, __FILE__, __LINE__
|
455
|
+
# frozen_string_literal: true
|
456
|
+
def #{resolve_method_name}(**args)
|
457
|
+
field_instance = self.class.get_field("#{field_definition.name}")
|
458
|
+
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
459
|
+
end
|
460
|
+
RUBY
|
455
461
|
end
|
456
462
|
end
|
457
463
|
end
|
458
464
|
|
459
|
-
def define_field_resolve_method(owner, method_name, field_name)
|
460
|
-
owner.define_method(method_name) { |**args|
|
461
|
-
field_instance = self.class.get_field(field_name)
|
462
|
-
context.schema.definition_default_resolve.call(self.class, field_instance, object, args, context)
|
463
|
-
}
|
464
|
-
end
|
465
|
-
|
466
465
|
def build_resolve_type(lookup_hash, directives, missing_type_handler)
|
467
466
|
resolve_type_proc = nil
|
468
467
|
resolve_type_proc = ->(ast_node) {
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -233,7 +233,7 @@ module GraphQL
|
|
233
233
|
|
234
234
|
@underscored_name = -Member::BuildType.underscore(name_s)
|
235
235
|
@name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
|
236
|
-
|
236
|
+
|
237
237
|
@description = description
|
238
238
|
@type = @owner_type = @own_validators = @own_directives = @own_arguments = @arguments_statically_coercible = nil # these will be prepared later if necessary
|
239
239
|
|
@@ -131,7 +131,12 @@ module GraphQL
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
# Add a method access
|
134
|
-
|
134
|
+
method_name = argument_defn.keyword
|
135
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
136
|
+
def #{method_name}
|
137
|
+
self[#{method_name.inspect}]
|
138
|
+
end
|
139
|
+
RUBY
|
135
140
|
argument_defn
|
136
141
|
end
|
137
142
|
|
@@ -237,13 +242,6 @@ module GraphQL
|
|
237
242
|
|
238
243
|
result
|
239
244
|
end
|
240
|
-
|
241
|
-
private
|
242
|
-
|
243
|
-
def define_accessor_method(method_name)
|
244
|
-
define_method(method_name) { self[method_name] }
|
245
|
-
alias_method(method_name, method_name)
|
246
|
-
end
|
247
245
|
end
|
248
246
|
|
249
247
|
private
|
@@ -29,7 +29,7 @@ module GraphQL
|
|
29
29
|
const_set(:DefinitionMethods, defn_methods_module)
|
30
30
|
extend(self::DefinitionMethods)
|
31
31
|
end
|
32
|
-
self::DefinitionMethods.
|
32
|
+
self::DefinitionMethods.module_eval(&block)
|
33
33
|
end
|
34
34
|
|
35
35
|
# @see {Schema::Warden} hides interfaces without visible implementations
|
@@ -69,11 +69,7 @@ module GraphQL
|
|
69
69
|
end
|
70
70
|
elsif child_class < GraphQL::Schema::Object
|
71
71
|
# This is being included into an object type, make sure it's using `implements(...)`
|
72
|
-
backtrace_line =
|
73
|
-
location.base_label == "implements" &&
|
74
|
-
location.path.end_with?("schema/member/has_interfaces.rb")
|
75
|
-
end
|
76
|
-
|
72
|
+
backtrace_line = caller(0, 10).find { |line| line.include?("schema/member/has_interfaces.rb") && line.include?("in `implements'")}
|
77
73
|
if !backtrace_line
|
78
74
|
raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
|
79
75
|
end
|
data/lib/graphql/schema.rb
CHANGED
@@ -384,6 +384,11 @@ module GraphQL
|
|
384
384
|
(superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context) : nil)
|
385
385
|
end
|
386
386
|
|
387
|
+
# @return [Boolean] Does this schema have _any_ definition for a type named `type_name`, regardless of visibility?
|
388
|
+
def has_defined_type?(type_name)
|
389
|
+
own_types.key?(type_name) || introspection_system.types.key?(type_name) || (superclass.respond_to?(:has_defined_type?) ? superclass.has_defined_type?(type_name) : false)
|
390
|
+
end
|
391
|
+
|
387
392
|
# @api private
|
388
393
|
attr_writer :connections
|
389
394
|
|
@@ -939,11 +944,7 @@ module GraphQL
|
|
939
944
|
end
|
940
945
|
|
941
946
|
def resolve_type(type, obj, ctx)
|
942
|
-
|
943
|
-
type
|
944
|
-
else
|
945
|
-
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types or Interface types (tried to resolve: #{type.name})"
|
946
|
-
end
|
947
|
+
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types, Interface types, or `loads:` (tried to resolve: #{type.name})"
|
947
948
|
end
|
948
949
|
# rubocop:enable Lint/DuplicateMethods
|
949
950
|
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Testing
|
4
|
+
module Helpers
|
5
|
+
# @param schema_class [Class<GraphQL::Schema>]
|
6
|
+
# @return [Module] A helpers module which always uses the given schema
|
7
|
+
def self.for(schema_class)
|
8
|
+
Module.new do
|
9
|
+
include SchemaHelpers
|
10
|
+
@@schema_class_for_helpers = schema_class
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Error < GraphQL::Error
|
15
|
+
end
|
16
|
+
|
17
|
+
class TypeNotVisibleError < Error
|
18
|
+
def initialize(type_name:)
|
19
|
+
message = "`#{type_name}` should be `visible?` this field resolution and `context`, but it was not"
|
20
|
+
super(message)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class FieldNotVisibleError < Error
|
25
|
+
def initialize(type_name:, field_name:)
|
26
|
+
message = "`#{type_name}.#{field_name}` should be `visible?` for this resolution, but it was not"
|
27
|
+
super(message)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
class TypeNotDefinedError < Error
|
32
|
+
def initialize(type_name:)
|
33
|
+
message = "No type named `#{type_name}` is defined; choose another type name or define this type."
|
34
|
+
super(message)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class FieldNotDefinedError < Error
|
39
|
+
def initialize(type_name:, field_name:)
|
40
|
+
message = "`#{type_name}` has no field named `#{field_name}`; pick another name or define this field."
|
41
|
+
super(message)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def run_graphql_field(schema, field_path, object, arguments: {}, context: {})
|
46
|
+
type_name, *field_names = field_path.split(".")
|
47
|
+
dummy_query = GraphQL::Query.new(schema, context: context)
|
48
|
+
query_context = dummy_query.context
|
49
|
+
object_type = dummy_query.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
|
50
|
+
if object_type
|
51
|
+
graphql_result = object
|
52
|
+
field_names.each do |field_name|
|
53
|
+
inner_object = graphql_result
|
54
|
+
graphql_result = object_type.wrap(inner_object, query_context)
|
55
|
+
if graphql_result.nil?
|
56
|
+
return nil
|
57
|
+
end
|
58
|
+
visible_field = dummy_query.get_field(object_type, field_name)
|
59
|
+
if visible_field
|
60
|
+
dummy_query.context.dataloader.run_isolated {
|
61
|
+
field_args = visible_field.coerce_arguments(graphql_result, arguments, query_context)
|
62
|
+
field_args = schema.sync_lazy(field_args)
|
63
|
+
graphql_result = visible_field.resolve(graphql_result, field_args.keyword_arguments, query_context)
|
64
|
+
graphql_result = schema.sync_lazy(graphql_result)
|
65
|
+
}
|
66
|
+
object_type = visible_field.type.unwrap
|
67
|
+
elsif object_type.all_field_definitions.any? { |f| f.graphql_name == field_name }
|
68
|
+
raise FieldNotVisibleError.new(field_name: field_name, type_name: type_name)
|
69
|
+
else
|
70
|
+
raise FieldNotDefinedError.new(type_name: type_name, field_name: field_name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
graphql_result
|
74
|
+
elsif schema.has_defined_type?(type_name)
|
75
|
+
raise TypeNotVisibleError.new(type_name: type_name)
|
76
|
+
else
|
77
|
+
raise TypeNotDefinedError.new(type_name: type_name)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def with_resolution_context(schema, type:, object:, context:{})
|
82
|
+
resolution_context = ResolutionAssertionContext.new(
|
83
|
+
self,
|
84
|
+
schema: schema,
|
85
|
+
type_name: type,
|
86
|
+
object: object,
|
87
|
+
context: context
|
88
|
+
)
|
89
|
+
yield(resolution_context)
|
90
|
+
end
|
91
|
+
|
92
|
+
class ResolutionAssertionContext
|
93
|
+
def initialize(test, type_name:, object:, schema:, context:)
|
94
|
+
@test = test
|
95
|
+
@type_name = type_name
|
96
|
+
@object = object
|
97
|
+
@schema = schema
|
98
|
+
@context = context
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
def run_graphql_field(field_name, arguments: {})
|
103
|
+
if @schema
|
104
|
+
@test.run_graphql_field(@schema, "#{@type_name}.#{field_name}", @object, arguments: arguments, context: @context)
|
105
|
+
else
|
106
|
+
@test.run_graphql_field("#{@type_name}.#{field_name}", @object, arguments: arguments, context: @context)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
module SchemaHelpers
|
112
|
+
include Helpers
|
113
|
+
|
114
|
+
def run_graphql_field(field_path, object, arguments: {}, context: {})
|
115
|
+
super(@@schema_class_for_helpers, field_path, object, arguments: arguments, context: context)
|
116
|
+
end
|
117
|
+
|
118
|
+
def with_resolution_context(*args, **kwargs, &block)
|
119
|
+
# schema will be added later
|
120
|
+
super(nil, *args, **kwargs, &block)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -28,8 +28,6 @@ module GraphQL
|
|
28
28
|
Gem::Version.new('1.0.0')
|
29
29
|
end
|
30
30
|
|
31
|
-
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
32
|
-
|
33
31
|
[
|
34
32
|
'lex',
|
35
33
|
'parse',
|
@@ -57,8 +55,6 @@ module GraphQL
|
|
57
55
|
RUBY
|
58
56
|
end
|
59
57
|
|
60
|
-
# rubocop:enable Development/NoEvalCop
|
61
|
-
|
62
58
|
def execute_field(query:, field:, ast_node:, arguments:, object:)
|
63
59
|
return_type = field.type.unwrap
|
64
60
|
trace_field = if return_type.kind.scalar? || return_type.kind.enum?
|
@@ -13,8 +13,6 @@ module GraphQL
|
|
13
13
|
super
|
14
14
|
end
|
15
15
|
|
16
|
-
# rubocop:disable Development/NoEvalCop This eval takes static inputs at load-time
|
17
|
-
|
18
16
|
{
|
19
17
|
"lex" => "lex.graphql",
|
20
18
|
"parse" => "parse.graphql",
|
@@ -45,8 +43,6 @@ module GraphQL
|
|
45
43
|
RUBY
|
46
44
|
end
|
47
45
|
|
48
|
-
# rubocop:enable Development/NoEvalCop
|
49
|
-
|
50
46
|
def platform_execute_field(platform_key)
|
51
47
|
Appsignal.instrument(platform_key) do
|
52
48
|
yield
|