graphql 2.0.16 → 2.0.17
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/analysis/ast/visitor.rb +42 -35
- data/lib/graphql/execution/interpreter/runtime.rb +14 -4
- data/lib/graphql/execution/interpreter.rb +10 -0
- data/lib/graphql/execution/lazy.rb +4 -8
- data/lib/graphql/introspection/directive_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +2 -2
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/language/nodes.rb +39 -31
- data/lib/graphql/language/visitor.rb +191 -83
- data/lib/graphql/schema/argument.rb +0 -4
- data/lib/graphql/schema/directive.rb +12 -2
- data/lib/graphql/schema/enum.rb +24 -17
- data/lib/graphql/schema/enum_value.rb +5 -3
- data/lib/graphql/schema/field.rb +22 -26
- data/lib/graphql/schema/interface.rb +0 -10
- data/lib/graphql/schema/late_bound_type.rb +2 -0
- data/lib/graphql/schema/member/base_dsl_methods.rb +15 -14
- data/lib/graphql/schema/member/has_arguments.rb +104 -57
- data/lib/graphql/schema/member/has_fields.rb +8 -1
- data/lib/graphql/schema/member/has_interfaces.rb +49 -8
- data/lib/graphql/schema/member/has_validators.rb +31 -5
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
- data/lib/graphql/schema/warden.rb +18 -3
- data/lib/graphql/schema.rb +3 -19
- data/lib/graphql/static_validation/literal_validator.rb +15 -1
- data/lib/graphql/subscriptions/event.rb +2 -7
- data/lib/graphql/types/relay/connection_behaviors.rb +0 -4
- data/lib/graphql/types/relay/edge_behaviors.rb +0 -4
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f95232ddde41ec605d304a572989213869296dc3818f15844d86a13f5cfa8c4
|
4
|
+
data.tar.gz: b4850a0d39ccca8d81f0d487e0311b51fba6f2bfe1151461ce39c732743799b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a15e0e17fd99b2c24c0a66f40f54c9909fc56c70d97fba2833bcb4934af65c06c5834b847386caa92100c4bb329c8fb27b799f5628f29cf89e6ff04946c013c
|
7
|
+
data.tar.gz: 92eac476af42ec7222b371ebd87b81b78873a3240fe83ac994b0c603b990f84a082b05dead69d59dff48a58c5762d1d26028e13f57ec55481f86e4b67c92f70b
|
@@ -65,14 +65,41 @@ module GraphQL
|
|
65
65
|
end
|
66
66
|
|
67
67
|
# Visitor Hooks
|
68
|
+
[
|
69
|
+
:operation_definition, :fragment_definition,
|
70
|
+
:inline_fragment, :field, :directive, :argument, :fragment_spread
|
71
|
+
].each do |node_type|
|
72
|
+
module_eval <<-RUBY, __FILE__, __LINE__
|
73
|
+
def call_on_enter_#{node_type}(node, parent)
|
74
|
+
@analyzers.each do |a|
|
75
|
+
begin
|
76
|
+
a.on_enter_#{node_type}(node, parent, self)
|
77
|
+
rescue AnalysisError => err
|
78
|
+
@rescued_errors << err
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def call_on_leave_#{node_type}(node, parent)
|
84
|
+
@analyzers.each do |a|
|
85
|
+
begin
|
86
|
+
a.on_leave_#{node_type}(node, parent, self)
|
87
|
+
rescue AnalysisError => err
|
88
|
+
@rescued_errors << err
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
RUBY
|
94
|
+
end
|
68
95
|
|
69
96
|
def on_operation_definition(node, parent)
|
70
97
|
object_type = @schema.root_type_for_operation(node.operation_type)
|
71
98
|
@object_types.push(object_type)
|
72
99
|
@path.push("#{node.operation_type}#{node.name ? " #{node.name}" : ""}")
|
73
|
-
|
100
|
+
call_on_enter_operation_definition(node, parent)
|
74
101
|
super
|
75
|
-
|
102
|
+
call_on_leave_operation_definition(node, parent)
|
76
103
|
@object_types.pop
|
77
104
|
@path.pop
|
78
105
|
end
|
@@ -81,19 +108,19 @@ module GraphQL
|
|
81
108
|
on_fragment_with_type(node) do
|
82
109
|
@path.push("fragment #{node.name}")
|
83
110
|
@in_fragment_def = false
|
84
|
-
|
111
|
+
call_on_enter_fragment_definition(node, parent)
|
85
112
|
super
|
86
113
|
@in_fragment_def = false
|
87
|
-
|
114
|
+
call_on_leave_fragment_definition(node, parent)
|
88
115
|
end
|
89
116
|
end
|
90
117
|
|
91
118
|
def on_inline_fragment(node, parent)
|
92
119
|
on_fragment_with_type(node) do
|
93
120
|
@path.push("...#{node.type ? " on #{node.type.name}" : ""}")
|
94
|
-
|
121
|
+
call_on_enter_inline_fragment(node, parent)
|
95
122
|
super
|
96
|
-
|
123
|
+
call_on_leave_inline_fragment(node, parent)
|
97
124
|
end
|
98
125
|
end
|
99
126
|
|
@@ -114,12 +141,10 @@ module GraphQL
|
|
114
141
|
@skipping = @skip_stack.last || skip?(node)
|
115
142
|
@skip_stack << @skipping
|
116
143
|
|
117
|
-
|
144
|
+
call_on_enter_field(node, parent)
|
118
145
|
super
|
119
|
-
|
120
146
|
@skipping = @skip_stack.pop
|
121
|
-
|
122
|
-
call_analyzers(:on_leave_field, node, parent)
|
147
|
+
call_on_leave_field(node, parent)
|
123
148
|
@response_path.pop
|
124
149
|
@field_definitions.pop
|
125
150
|
@object_types.pop
|
@@ -129,9 +154,9 @@ module GraphQL
|
|
129
154
|
def on_directive(node, parent)
|
130
155
|
directive_defn = @schema.directives[node.name]
|
131
156
|
@directive_definitions.push(directive_defn)
|
132
|
-
|
157
|
+
call_on_enter_directive(node, parent)
|
133
158
|
super
|
134
|
-
|
159
|
+
call_on_leave_directive(node, parent)
|
135
160
|
@directive_definitions.pop
|
136
161
|
end
|
137
162
|
|
@@ -153,29 +178,23 @@ module GraphQL
|
|
153
178
|
|
154
179
|
@argument_definitions.push(argument_defn)
|
155
180
|
@path.push(node.name)
|
156
|
-
|
181
|
+
call_on_enter_argument(node, parent)
|
157
182
|
super
|
158
|
-
|
183
|
+
call_on_leave_argument(node, parent)
|
159
184
|
@argument_definitions.pop
|
160
185
|
@path.pop
|
161
186
|
end
|
162
187
|
|
163
188
|
def on_fragment_spread(node, parent)
|
164
189
|
@path.push("... #{node.name}")
|
165
|
-
|
190
|
+
call_on_enter_fragment_spread(node, parent)
|
166
191
|
enter_fragment_spread_inline(node)
|
167
192
|
super
|
168
193
|
leave_fragment_spread_inline(node)
|
169
|
-
|
194
|
+
call_on_leave_fragment_spread(node, parent)
|
170
195
|
@path.pop
|
171
196
|
end
|
172
197
|
|
173
|
-
def on_abstract_node(node, parent)
|
174
|
-
call_analyzers(:on_enter_abstract_node, node, parent)
|
175
|
-
super
|
176
|
-
call_analyzers(:on_leave_abstract_node, node, parent)
|
177
|
-
end
|
178
|
-
|
179
198
|
# @return [GraphQL::BaseType] The current object type
|
180
199
|
def type_definition
|
181
200
|
@object_types.last
|
@@ -226,9 +245,7 @@ module GraphQL
|
|
226
245
|
|
227
246
|
object_types << object_type
|
228
247
|
|
229
|
-
fragment_def
|
230
|
-
visit_node(selection, fragment_def)
|
231
|
-
end
|
248
|
+
on_fragment_definition_children(fragment_def)
|
232
249
|
end
|
233
250
|
|
234
251
|
# Visit a fragment spread inline instead of visiting the definition
|
@@ -242,16 +259,6 @@ module GraphQL
|
|
242
259
|
dir.any? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
|
243
260
|
end
|
244
261
|
|
245
|
-
def call_analyzers(method, node, parent)
|
246
|
-
@analyzers.each do |analyzer|
|
247
|
-
begin
|
248
|
-
analyzer.public_send(method, node, parent, self)
|
249
|
-
rescue AnalysisError => err
|
250
|
-
@rescued_errors << err
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
262
|
def on_fragment_with_type(node)
|
256
263
|
object_type = if node.type
|
257
264
|
@query.warden.get_type(node.type.name)
|
@@ -409,6 +409,7 @@ module GraphQL
|
|
409
409
|
raise "Invariant: no field for #{owner_type}.#{field_name}"
|
410
410
|
end
|
411
411
|
end
|
412
|
+
|
412
413
|
return_type = field_defn.type
|
413
414
|
|
414
415
|
next_path = path + [result_name]
|
@@ -431,17 +432,16 @@ module GraphQL
|
|
431
432
|
total_args_count = field_defn.arguments(context).size
|
432
433
|
if total_args_count == 0
|
433
434
|
resolved_arguments = GraphQL::Execution::Interpreter::Arguments::EMPTY
|
434
|
-
evaluate_selection_with_args(resolved_arguments, field_defn, next_path, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selections_result, parent_object)
|
435
|
+
evaluate_selection_with_args(resolved_arguments, field_defn, next_path, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selections_result, parent_object, return_type)
|
435
436
|
else
|
436
437
|
# TODO remove all arguments(...) usages?
|
437
438
|
@query.arguments_cache.dataload_for(ast_node, field_defn, object) do |resolved_arguments|
|
438
|
-
evaluate_selection_with_args(resolved_arguments, field_defn, next_path, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selections_result, parent_object)
|
439
|
+
evaluate_selection_with_args(resolved_arguments, field_defn, next_path, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selections_result, parent_object, return_type)
|
439
440
|
end
|
440
441
|
end
|
441
442
|
end
|
442
443
|
|
443
|
-
def evaluate_selection_with_args(arguments, field_defn, next_path, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object) # rubocop:disable Metrics/ParameterLists
|
444
|
-
return_type = field_defn.type
|
444
|
+
def evaluate_selection_with_args(arguments, field_defn, next_path, ast_node, field_ast_nodes, owner_type, object, is_eager_field, result_name, selection_result, parent_object, return_type) # rubocop:disable Metrics/ParameterLists
|
445
445
|
after_lazy(arguments, owner: owner_type, field: field_defn, path: next_path, ast_node: ast_node, owner_object: object, arguments: arguments, result_name: result_name, result: selection_result) do |resolved_arguments|
|
446
446
|
if resolved_arguments.is_a?(GraphQL::ExecutionError) || resolved_arguments.is_a?(GraphQL::UnauthorizedError)
|
447
447
|
continue_value(next_path, resolved_arguments, owner_type, field_defn, return_type.non_null?, ast_node, result_name, selection_result)
|
@@ -615,6 +615,16 @@ module GraphQL
|
|
615
615
|
end
|
616
616
|
end
|
617
617
|
HALT
|
618
|
+
elsif value.is_a?(GraphQL::UnauthorizedFieldError)
|
619
|
+
value.field ||= field
|
620
|
+
# this hook might raise & crash, or it might return
|
621
|
+
# a replacement value
|
622
|
+
next_value = begin
|
623
|
+
schema.unauthorized_field(value)
|
624
|
+
rescue GraphQL::ExecutionError => err
|
625
|
+
err
|
626
|
+
end
|
627
|
+
continue_value(path, next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
|
618
628
|
elsif value.is_a?(GraphQL::UnauthorizedError)
|
619
629
|
# this hook might raise & crash, or it might return
|
620
630
|
# a replacement value
|
@@ -146,6 +146,16 @@ module GraphQL
|
|
146
146
|
# Assign values here so that the query's `@executed` becomes true
|
147
147
|
queries.map { |q| q.result_values ||= {} }
|
148
148
|
raise
|
149
|
+
ensure
|
150
|
+
queries.map { |query|
|
151
|
+
runtime = query.context.namespace(:interpreter_runtime)[:runtime]
|
152
|
+
if runtime
|
153
|
+
runtime.delete_interpreter_context(:current_path)
|
154
|
+
runtime.delete_interpreter_context(:current_field)
|
155
|
+
runtime.delete_interpreter_context(:current_object)
|
156
|
+
runtime.delete_interpreter_context(:current_arguments)
|
157
|
+
end
|
158
|
+
}
|
149
159
|
end
|
150
160
|
end
|
151
161
|
end
|
@@ -29,15 +29,11 @@ module GraphQL
|
|
29
29
|
def value
|
30
30
|
if !@resolved
|
31
31
|
@resolved = true
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
v = v.value
|
36
|
-
end
|
37
|
-
v
|
38
|
-
rescue GraphQL::ExecutionError => err
|
39
|
-
err
|
32
|
+
v = @get_value_func.call
|
33
|
+
if v.is_a?(Lazy)
|
34
|
+
v = v.value
|
40
35
|
end
|
36
|
+
@value = v
|
41
37
|
end
|
42
38
|
|
43
39
|
# `SKIP` was made into a subclass of `GraphQL::Error` to improve runtime performance
|
@@ -11,8 +11,8 @@ module GraphQL
|
|
11
11
|
"to the executor."
|
12
12
|
field :name, String, null: false, method: :graphql_name
|
13
13
|
field :description, String
|
14
|
-
field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false
|
15
|
-
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
|
14
|
+
field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false, scope: false
|
15
|
+
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false, scope: false do
|
16
16
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
17
17
|
end
|
18
18
|
field :on_operation, Boolean, null: false, deprecation_reason: "Use `locations`.", method: :on_operation?
|
@@ -7,7 +7,7 @@ module GraphQL
|
|
7
7
|
"a name, potentially a list of arguments, and a return type."
|
8
8
|
field :name, String, null: false
|
9
9
|
field :description, String
|
10
|
-
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
|
10
|
+
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false, scope: false do
|
11
11
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
12
12
|
end
|
13
13
|
field :type, GraphQL::Schema::LateBoundType.new("__Type"), null: false
|
@@ -8,11 +8,11 @@ module GraphQL
|
|
8
8
|
"available types and directives on the server, as well as the entry points for "\
|
9
9
|
"query, mutation, and subscription operations."
|
10
10
|
|
11
|
-
field :types, [GraphQL::Schema::LateBoundType.new("__Type")], "A list of all types supported by this server.", null: false
|
11
|
+
field :types, [GraphQL::Schema::LateBoundType.new("__Type")], "A list of all types supported by this server.", null: false, scope: false
|
12
12
|
field :query_type, GraphQL::Schema::LateBoundType.new("__Type"), "The type that query operations will be rooted at.", null: false
|
13
13
|
field :mutation_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server supports mutation, the type that mutation operations will be rooted at."
|
14
14
|
field :subscription_type, GraphQL::Schema::LateBoundType.new("__Type"), "If this server support subscription, the type that subscription operations will be rooted at."
|
15
|
-
field :directives, [GraphQL::Schema::LateBoundType.new("__Directive")], "A list of all directives supported by this server.", null: false
|
15
|
+
field :directives, [GraphQL::Schema::LateBoundType.new("__Directive")], "A list of all directives supported by this server.", null: false, scope: false
|
16
16
|
field :description, String, resolver_method: :schema_description
|
17
17
|
|
18
18
|
def schema_description
|
@@ -14,15 +14,15 @@ module GraphQL
|
|
14
14
|
field :kind, GraphQL::Schema::LateBoundType.new("__TypeKind"), null: false
|
15
15
|
field :name, String, method: :graphql_name
|
16
16
|
field :description, String
|
17
|
-
field :fields, [GraphQL::Schema::LateBoundType.new("__Field")] do
|
17
|
+
field :fields, [GraphQL::Schema::LateBoundType.new("__Field")], scope: false do
|
18
18
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
19
19
|
end
|
20
|
-
field :interfaces, [GraphQL::Schema::LateBoundType.new("__Type")]
|
21
|
-
field :possible_types, [GraphQL::Schema::LateBoundType.new("__Type")]
|
22
|
-
field :enum_values, [GraphQL::Schema::LateBoundType.new("__EnumValue")] do
|
20
|
+
field :interfaces, [GraphQL::Schema::LateBoundType.new("__Type")], scope: false
|
21
|
+
field :possible_types, [GraphQL::Schema::LateBoundType.new("__Type")], scope: false
|
22
|
+
field :enum_values, [GraphQL::Schema::LateBoundType.new("__EnumValue")], scope: false do
|
23
23
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
24
24
|
end
|
25
|
-
field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")] do
|
25
|
+
field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")], scope: false do
|
26
26
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
27
27
|
end
|
28
28
|
field :of_type, GraphQL::Schema::LateBoundType.new("__Type")
|
@@ -141,18 +141,26 @@ module GraphQL
|
|
141
141
|
.gsub(/([a-z])([A-Z])/,'\1_\2') # insert underscores
|
142
142
|
.downcase # remove caps
|
143
143
|
|
144
|
-
child_class.module_eval <<-RUBY
|
144
|
+
child_class.module_eval <<-RUBY, __FILE__, __LINE__
|
145
145
|
def visit_method
|
146
146
|
:on_#{name_underscored}
|
147
147
|
end
|
148
148
|
|
149
149
|
class << self
|
150
150
|
attr_accessor :children_method_name
|
151
|
+
|
152
|
+
def visit_method
|
153
|
+
:on_#{name_underscored}
|
154
|
+
end
|
151
155
|
end
|
152
156
|
self.children_method_name = :#{name_underscored}s
|
153
157
|
RUBY
|
154
158
|
end
|
155
159
|
|
160
|
+
def children_of_type
|
161
|
+
@children_methods
|
162
|
+
end
|
163
|
+
|
156
164
|
private
|
157
165
|
|
158
166
|
# Name accessors which return lists of nodes,
|
@@ -300,7 +308,7 @@ module GraphQL
|
|
300
308
|
# @return [String] the key for this argument
|
301
309
|
|
302
310
|
# @!attribute value
|
303
|
-
# @return [String, Float, Integer, Boolean, Array, InputObject] The value passed for this key
|
311
|
+
# @return [String, Float, Integer, Boolean, Array, InputObject, VariableIdentifier] The value passed for this key
|
304
312
|
|
305
313
|
def children
|
306
314
|
@children ||= Array(value).flatten.select { |v| v.is_a?(AbstractNode) }
|
@@ -325,35 +333,6 @@ module GraphQL
|
|
325
333
|
)
|
326
334
|
end
|
327
335
|
|
328
|
-
# This is the AST root for normal queries
|
329
|
-
#
|
330
|
-
# @example Deriving a document by parsing a string
|
331
|
-
# document = GraphQL.parse(query_string)
|
332
|
-
#
|
333
|
-
# @example Creating a string from a document
|
334
|
-
# document.to_query_string
|
335
|
-
# # { ... }
|
336
|
-
#
|
337
|
-
# @example Creating a custom string from a document
|
338
|
-
# class VariableScrubber < GraphQL::Language::Printer
|
339
|
-
# def print_argument(arg)
|
340
|
-
# "#{arg.name}: <HIDDEN>"
|
341
|
-
# end
|
342
|
-
# end
|
343
|
-
#
|
344
|
-
# document.to_query_string(printer: VariableScrubber.new)
|
345
|
-
#
|
346
|
-
class Document < AbstractNode
|
347
|
-
scalar_methods false
|
348
|
-
children_methods(definitions: nil)
|
349
|
-
# @!attribute definitions
|
350
|
-
# @return [Array<OperationDefinition, FragmentDefinition>] top-level GraphQL units: operations or fragments
|
351
|
-
|
352
|
-
def slice_definition(name)
|
353
|
-
GraphQL::Language::DefinitionSlice.slice(self, name)
|
354
|
-
end
|
355
|
-
end
|
356
|
-
|
357
336
|
# An enum value. The string is available as {#name}.
|
358
337
|
class Enum < NameOnlyNode
|
359
338
|
end
|
@@ -526,6 +505,35 @@ module GraphQL
|
|
526
505
|
self.children_method_name = :definitions
|
527
506
|
end
|
528
507
|
|
508
|
+
# This is the AST root for normal queries
|
509
|
+
#
|
510
|
+
# @example Deriving a document by parsing a string
|
511
|
+
# document = GraphQL.parse(query_string)
|
512
|
+
#
|
513
|
+
# @example Creating a string from a document
|
514
|
+
# document.to_query_string
|
515
|
+
# # { ... }
|
516
|
+
#
|
517
|
+
# @example Creating a custom string from a document
|
518
|
+
# class VariableScrubber < GraphQL::Language::Printer
|
519
|
+
# def print_argument(arg)
|
520
|
+
# "#{arg.name}: <HIDDEN>"
|
521
|
+
# end
|
522
|
+
# end
|
523
|
+
#
|
524
|
+
# document.to_query_string(printer: VariableScrubber.new)
|
525
|
+
#
|
526
|
+
class Document < AbstractNode
|
527
|
+
scalar_methods false
|
528
|
+
children_methods(definitions: nil)
|
529
|
+
# @!attribute definitions
|
530
|
+
# @return [Array<OperationDefinition, FragmentDefinition>] top-level GraphQL units: operations or fragments
|
531
|
+
|
532
|
+
def slice_definition(name)
|
533
|
+
GraphQL::Language::DefinitionSlice.slice(self, name)
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
529
537
|
# A type name, used for variable definitions
|
530
538
|
class TypeName < NameOnlyNode
|
531
539
|
end
|