graphql 2.0.16 → 2.0.21
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/analysis/ast.rb +2 -2
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/tracer.rb +1 -1
- data/lib/graphql/backtrace.rb +6 -1
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
- data/lib/graphql/execution/interpreter/resolve.rb +19 -0
- data/lib/graphql/execution/interpreter/runtime.rb +264 -211
- data/lib/graphql/execution/interpreter.rb +15 -10
- data/lib/graphql/execution/lazy.rb +6 -12
- data/lib/graphql/execution/multiplex.rb +2 -1
- data/lib/graphql/filter.rb +7 -2
- 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/document_from_schema_definition.rb +25 -9
- data/lib/graphql/language/lexer.rb +216 -1505
- data/lib/graphql/language/nodes.rb +66 -40
- data/lib/graphql/language/parser.rb +509 -491
- data/lib/graphql/language/parser.y +43 -38
- data/lib/graphql/language/visitor.rb +191 -83
- data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
- data/lib/graphql/pagination/connection.rb +5 -5
- data/lib/graphql/query/context.rb +62 -31
- data/lib/graphql/query/null_context.rb +1 -1
- data/lib/graphql/query.rb +22 -5
- data/lib/graphql/schema/argument.rb +7 -13
- data/lib/graphql/schema/build_from_definition.rb +15 -3
- data/lib/graphql/schema/directive.rb +12 -2
- data/lib/graphql/schema/enum.rb +24 -17
- data/lib/graphql/schema/enum_value.rb +2 -3
- data/lib/graphql/schema/field.rb +68 -57
- data/lib/graphql/schema/field_extension.rb +1 -4
- data/lib/graphql/schema/find_inherited_value.rb +2 -7
- 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 +17 -14
- data/lib/graphql/schema/member/has_arguments.rb +105 -58
- data/lib/graphql/schema/member/has_ast_node.rb +12 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +15 -10
- data/lib/graphql/schema/member/has_fields.rb +95 -38
- data/lib/graphql/schema/member/has_interfaces.rb +49 -8
- data/lib/graphql/schema/member/has_validators.rb +32 -6
- data/lib/graphql/schema/member/relay_shortcuts.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +17 -0
- data/lib/graphql/schema/object.rb +2 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +9 -9
- data/lib/graphql/schema/resolver.rb +4 -4
- data/lib/graphql/schema/timeout.rb +24 -28
- data/lib/graphql/schema/validator.rb +1 -1
- data/lib/graphql/schema/warden.rb +29 -5
- data/lib/graphql/schema.rb +76 -25
- data/lib/graphql/static_validation/literal_validator.rb +15 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
- data/lib/graphql/static_validation/validator.rb +1 -1
- data/lib/graphql/subscriptions/event.rb +2 -7
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +42 -0
- data/lib/graphql/tracing/platform_trace.rb +109 -0
- data/lib/graphql/tracing/platform_tracing.rb +15 -3
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +16 -39
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/relay/base_connection.rb +1 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +24 -6
- data/lib/graphql/types/relay/edge_behaviors.rb +16 -6
- data/lib/graphql/types/relay/node_behaviors.rb +7 -1
- data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
- data/lib/graphql/types/relay.rb +0 -1
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +16 -9
- metadata +34 -9
- data/lib/graphql/language/lexer.rl +0 -280
- data/lib/graphql/types/relay/default_relay.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 43f1cc3ef36a54a31f8afa03ee3109b34f046e26c427acfb80599a2dd245cf14
|
4
|
+
data.tar.gz: 4e4a15c766650e36004175de15cfcb9f67c6b4e7d24e2f91712a6ad3f8681453
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 908f3790bcc773bb6c7fe3db1f5e2ccabf361ece7b462b80fc4e59911167eabb8baf544739f31ac425579bca61b56b46937ac60e7a54a03827228016457388de
|
7
|
+
data.tar.gz: 62fb9dc90ab55aff66d3d1621fc28b18c0c9599e2f8a7f8521d372a6f549c85ac0a2e50a0d43cb77bde728cb44f85b178bb37388c6bd3d2aed5f8e91723a79ef
|
@@ -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)
|
data/lib/graphql/analysis/ast.rb
CHANGED
@@ -21,7 +21,7 @@ module GraphQL
|
|
21
21
|
def analyze_multiplex(multiplex, analyzers)
|
22
22
|
multiplex_analyzers = analyzers.map { |analyzer| analyzer.new(multiplex) }
|
23
23
|
|
24
|
-
multiplex.
|
24
|
+
multiplex.current_trace.analyze_multiplex(multiplex: multiplex) do
|
25
25
|
query_results = multiplex.queries.map do |query|
|
26
26
|
if query.valid?
|
27
27
|
analyze_query(
|
@@ -48,7 +48,7 @@ module GraphQL
|
|
48
48
|
# @param analyzers [Array<GraphQL::Analysis::AST::Analyzer>]
|
49
49
|
# @return [Array<Any>] Results from those analyzers
|
50
50
|
def analyze_query(query, analyzers, multiplex_analyzers: [])
|
51
|
-
query.
|
51
|
+
query.current_trace.analyze_query(query: query) do
|
52
52
|
query_analyzers = analyzers
|
53
53
|
.map { |analyzer| analyzer.new(query) }
|
54
54
|
.select { |analyzer| analyzer.analyze? }
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
class Backtrace
|
4
|
+
module Trace
|
5
|
+
def validate(query:, validate:)
|
6
|
+
if query.multiplex
|
7
|
+
push_query_backtrace_context(query)
|
8
|
+
end
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def analyze_query(query:)
|
13
|
+
if query.multiplex # missing for stand-alone static validation
|
14
|
+
push_query_backtrace_context(query)
|
15
|
+
end
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute_query(query:)
|
20
|
+
push_query_backtrace_context(query)
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def execute_query_lazy(query:, multiplex:)
|
25
|
+
query ||= multiplex.queries.first
|
26
|
+
push_query_backtrace_context(query)
|
27
|
+
super
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute_field(field:, query:, ast_node:, arguments:, object:)
|
31
|
+
push_field_backtrace_context(field, query, ast_node, arguments, object)
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
def execute_field_lazy(field:, query:, ast_node:, arguments:, object:)
|
36
|
+
push_field_backtrace_context(field, query, ast_node, arguments, object)
|
37
|
+
super
|
38
|
+
end
|
39
|
+
|
40
|
+
def execute_multiplex(multiplex:)
|
41
|
+
super
|
42
|
+
rescue StandardError => err
|
43
|
+
# This is an unhandled error from execution,
|
44
|
+
# Re-raise it with a GraphQL trace.
|
45
|
+
multiplex_context = multiplex.context
|
46
|
+
potential_context = multiplex_context[:last_graphql_backtrace_context]
|
47
|
+
|
48
|
+
if potential_context.is_a?(GraphQL::Query::Context) ||
|
49
|
+
potential_context.is_a?(Backtrace::Frame)
|
50
|
+
raise TracedError.new(err, potential_context)
|
51
|
+
else
|
52
|
+
raise
|
53
|
+
end
|
54
|
+
ensure
|
55
|
+
multiplex_context = multiplex.context
|
56
|
+
multiplex_context.delete(:graphql_backtrace_contexts)
|
57
|
+
multiplex_context.delete(:last_graphql_backtrace_context)
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def push_query_backtrace_context(query)
|
63
|
+
push_data = query
|
64
|
+
multiplex = query.multiplex
|
65
|
+
push_key = []
|
66
|
+
push_storage = multiplex.context[:graphql_backtrace_contexts] ||= {}
|
67
|
+
push_storage[push_key] = push_data
|
68
|
+
multiplex.context[:last_graphql_backtrace_context] = push_data
|
69
|
+
end
|
70
|
+
|
71
|
+
def push_field_backtrace_context(field, query, ast_node, arguments, object)
|
72
|
+
multiplex = query.multiplex
|
73
|
+
push_key = query.context[:current_path]
|
74
|
+
push_storage = multiplex.context[:graphql_backtrace_contexts]
|
75
|
+
parent_frame = push_storage[push_key[0..-2]]
|
76
|
+
|
77
|
+
if parent_frame.is_a?(GraphQL::Query)
|
78
|
+
parent_frame = parent_frame.context
|
79
|
+
end
|
80
|
+
|
81
|
+
push_data = Frame.new(
|
82
|
+
query: query,
|
83
|
+
path: push_key,
|
84
|
+
ast_node: ast_node,
|
85
|
+
field: field,
|
86
|
+
object: object,
|
87
|
+
arguments: arguments,
|
88
|
+
parent_frame: parent_frame,
|
89
|
+
)
|
90
|
+
|
91
|
+
push_storage[push_key] = push_data
|
92
|
+
multiplex.context[:last_graphql_backtrace_context] = push_data
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -25,7 +25,7 @@ module GraphQL
|
|
25
25
|
when "execute_field", "execute_field_lazy"
|
26
26
|
query = metadata[:query]
|
27
27
|
multiplex = query.multiplex
|
28
|
-
push_key =
|
28
|
+
push_key = query.context[:current_path]
|
29
29
|
parent_frame = multiplex.context[:graphql_backtrace_contexts][push_key[0..-2]]
|
30
30
|
|
31
31
|
if parent_frame.is_a?(GraphQL::Query)
|
data/lib/graphql/backtrace.rb
CHANGED
@@ -3,6 +3,7 @@ require "graphql/backtrace/inspect_result"
|
|
3
3
|
require "graphql/backtrace/table"
|
4
4
|
require "graphql/backtrace/traced_error"
|
5
5
|
require "graphql/backtrace/tracer"
|
6
|
+
require "graphql/backtrace/trace"
|
6
7
|
module GraphQL
|
7
8
|
# Wrap unhandled errors with {TracedError}.
|
8
9
|
#
|
@@ -23,7 +24,7 @@ module GraphQL
|
|
23
24
|
def_delegators :to_a, :each, :[]
|
24
25
|
|
25
26
|
def self.use(schema_defn)
|
26
|
-
schema_defn.
|
27
|
+
schema_defn.trace_with(self::Trace)
|
27
28
|
end
|
28
29
|
|
29
30
|
def initialize(context, value: nil)
|
@@ -54,5 +55,9 @@ module GraphQL
|
|
54
55
|
@parent_frame = parent_frame
|
55
56
|
end
|
56
57
|
end
|
58
|
+
|
59
|
+
class DefaultBacktraceTrace < GraphQL::Tracing::Trace
|
60
|
+
include GraphQL::Backtrace::Trace
|
61
|
+
end
|
57
62
|
end
|
58
63
|
end
|
@@ -55,9 +55,8 @@ module GraphQL
|
|
55
55
|
|
56
56
|
private
|
57
57
|
|
58
|
-
NO_ARGUMENTS =
|
59
|
-
|
60
|
-
NO_VALUE_GIVEN = Object.new
|
58
|
+
NO_ARGUMENTS = GraphQL::EmptyObjects::EMPTY_HASH
|
59
|
+
NO_VALUE_GIVEN = NOT_CONFIGURED
|
61
60
|
|
62
61
|
def self.prepare_args_hash(query, ast_arg_or_hash_or_value)
|
63
62
|
case ast_arg_or_hash_or_value
|
@@ -11,6 +11,25 @@ module GraphQL
|
|
11
11
|
nil
|
12
12
|
end
|
13
13
|
|
14
|
+
def self.resolve_each_depth(lazies_at_depth, dataloader)
|
15
|
+
depths = lazies_at_depth.keys
|
16
|
+
depths.sort!
|
17
|
+
next_depth = depths.first
|
18
|
+
if next_depth
|
19
|
+
lazies = lazies_at_depth[next_depth]
|
20
|
+
lazies_at_depth.delete(next_depth)
|
21
|
+
if lazies.any?
|
22
|
+
dataloader.append_job {
|
23
|
+
lazies.each(&:value) # resolve these Lazy instances
|
24
|
+
}
|
25
|
+
# Run lazies _and_ dataloader, see if more are enqueued
|
26
|
+
dataloader.run
|
27
|
+
resolve_each_depth(lazies_at_depth, dataloader)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
14
33
|
# After getting `results` back from an interpreter evaluation,
|
15
34
|
# continue it until you get a response-ready Ruby value.
|
16
35
|
#
|