graphql 2.4.10 → 2.4.12
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/visitor.rb +35 -40
- data/lib/graphql/analysis.rb +12 -9
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.css +6 -0
- data/lib/graphql/dashboard/statics/bootstrap-5.3.3.min.js +7 -0
- data/lib/graphql/dashboard/statics/dashboard.css +3 -0
- data/lib/graphql/dashboard/statics/dashboard.js +78 -0
- data/lib/graphql/dashboard/statics/header-icon.png +0 -0
- data/lib/graphql/dashboard/statics/icon.png +0 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/landings/show.html.erb +18 -0
- data/lib/graphql/dashboard/views/graphql/dashboard/traces/index.html.erb +63 -0
- data/lib/graphql/dashboard/views/layouts/graphql/dashboard/application.html.erb +60 -0
- data/lib/graphql/dashboard.rb +142 -0
- data/lib/graphql/execution/interpreter/runtime.rb +1 -1
- data/lib/graphql/invalid_name_error.rb +1 -1
- data/lib/graphql/invalid_null_error.rb +5 -15
- data/lib/graphql/language/lexer.rb +7 -3
- data/lib/graphql/language/parser.rb +1 -1
- data/lib/graphql/schema/build_from_definition.rb +0 -1
- data/lib/graphql/schema/enum.rb +16 -1
- data/lib/graphql/schema/input_object.rb +1 -1
- data/lib/graphql/schema/loader.rb +0 -1
- data/lib/graphql/schema/member/has_dataloader.rb +4 -0
- data/lib/graphql/schema/resolver.rb +5 -1
- data/lib/graphql/schema.rb +51 -9
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +1 -1
- data/lib/graphql/tracing/active_support_notifications_trace.rb +6 -2
- data/lib/graphql/tracing/appoptics_trace.rb +2 -0
- data/lib/graphql/tracing/appsignal_trace.rb +6 -0
- data/lib/graphql/tracing/data_dog_trace.rb +5 -0
- data/lib/graphql/tracing/detailed_trace/memory_backend.rb +60 -0
- data/lib/graphql/tracing/detailed_trace/redis_backend.rb +72 -0
- data/lib/graphql/tracing/detailed_trace.rb +93 -0
- data/lib/graphql/tracing/new_relic_trace.rb +47 -23
- data/lib/graphql/tracing/perfetto_trace.rb +13 -2
- data/lib/graphql/tracing/prometheus_trace.rb +22 -0
- data/lib/graphql/tracing/scout_trace.rb +6 -0
- data/lib/graphql/tracing/sentry_trace.rb +5 -0
- data/lib/graphql/tracing/statsd_trace.rb +9 -0
- data/lib/graphql/tracing.rb +1 -0
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +3 -0
- metadata +15 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b105157510cb5779715118d5f28f49822a9b3b86b0faec0fdc86a2331904f667
|
4
|
+
data.tar.gz: 9230b70e18665505190c673579fa66b2906d04009f9e46d844990bafdba374da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e64decd9e23e3dcc23ced201998963ca0894e38161659a153d9c1ae918dce90c8ae365a3eb1debd753a78f65a1ffe3bf281ee0bb285cd1a0f6cd572cbb31455a
|
7
|
+
data.tar.gz: 4f0b3ac80a45a5db47e96abacc7fb935ed20c5a0ebe65ba2ca04e20c0bac58f1ec73e2e4af42c05307c76fd358c36bcfbd5529479201cf104540a50448298b80
|
@@ -10,7 +10,7 @@ module GraphQL
|
|
10
10
|
#
|
11
11
|
# @see {GraphQL::Analysis::Analyzer} AST Analyzers for queries
|
12
12
|
class Visitor < GraphQL::Language::StaticVisitor
|
13
|
-
def initialize(query:, analyzers:)
|
13
|
+
def initialize(query:, analyzers:, timeout:)
|
14
14
|
@analyzers = analyzers
|
15
15
|
@path = []
|
16
16
|
@object_types = []
|
@@ -24,6 +24,11 @@ module GraphQL
|
|
24
24
|
@types = query.types
|
25
25
|
@response_path = []
|
26
26
|
@skip_stack = [false]
|
27
|
+
@timeout_time = if timeout
|
28
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second) + timeout
|
29
|
+
else
|
30
|
+
Float::INFINITY
|
31
|
+
end
|
27
32
|
super(query.selected_operation)
|
28
33
|
end
|
29
34
|
|
@@ -72,21 +77,17 @@ module GraphQL
|
|
72
77
|
module_eval <<-RUBY, __FILE__, __LINE__
|
73
78
|
def call_on_enter_#{node_type}(node, parent)
|
74
79
|
@analyzers.each do |a|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
@rescued_errors << err
|
79
|
-
end
|
80
|
+
a.on_enter_#{node_type}(node, parent, self)
|
81
|
+
rescue AnalysisError => err
|
82
|
+
@rescued_errors << err
|
80
83
|
end
|
81
84
|
end
|
82
85
|
|
83
86
|
def call_on_leave_#{node_type}(node, parent)
|
84
87
|
@analyzers.each do |a|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
@rescued_errors << err
|
89
|
-
end
|
88
|
+
a.on_leave_#{node_type}(node, parent, self)
|
89
|
+
rescue AnalysisError => err
|
90
|
+
@rescued_errors << err
|
90
91
|
end
|
91
92
|
end
|
92
93
|
|
@@ -94,6 +95,7 @@ module GraphQL
|
|
94
95
|
end
|
95
96
|
|
96
97
|
def on_operation_definition(node, parent)
|
98
|
+
check_timeout
|
97
99
|
object_type = @schema.root_type_for_operation(node.operation_type)
|
98
100
|
@object_types.push(object_type)
|
99
101
|
@path.push("#{node.operation_type}#{node.name ? " #{node.name}" : ""}")
|
@@ -104,31 +106,27 @@ module GraphQL
|
|
104
106
|
@path.pop
|
105
107
|
end
|
106
108
|
|
107
|
-
def on_fragment_definition(node, parent)
|
108
|
-
on_fragment_with_type(node) do
|
109
|
-
@path.push("fragment #{node.name}")
|
110
|
-
@in_fragment_def = false
|
111
|
-
call_on_enter_fragment_definition(node, parent)
|
112
|
-
super
|
113
|
-
@in_fragment_def = false
|
114
|
-
call_on_leave_fragment_definition(node, parent)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
109
|
def on_inline_fragment(node, parent)
|
119
|
-
|
120
|
-
|
121
|
-
@
|
122
|
-
|
123
|
-
|
124
|
-
call_on_enter_inline_fragment(node, parent)
|
125
|
-
super
|
126
|
-
@skipping = @skip_stack.pop
|
127
|
-
call_on_leave_inline_fragment(node, parent)
|
110
|
+
check_timeout
|
111
|
+
object_type = if node.type
|
112
|
+
@types.type(node.type.name)
|
113
|
+
else
|
114
|
+
@object_types.last
|
128
115
|
end
|
116
|
+
@object_types.push(object_type)
|
117
|
+
@path.push("...#{node.type ? " on #{node.type.name}" : ""}")
|
118
|
+
@skipping = @skip_stack.last || skip?(node)
|
119
|
+
@skip_stack << @skipping
|
120
|
+
call_on_enter_inline_fragment(node, parent)
|
121
|
+
super
|
122
|
+
@skipping = @skip_stack.pop
|
123
|
+
call_on_leave_inline_fragment(node, parent)
|
124
|
+
@object_types.pop
|
125
|
+
@path.pop
|
129
126
|
end
|
130
127
|
|
131
128
|
def on_field(node, parent)
|
129
|
+
check_timeout
|
132
130
|
@response_path.push(node.alias || node.name)
|
133
131
|
parent_type = @object_types.last
|
134
132
|
# This could be nil if the previous field wasn't found:
|
@@ -156,6 +154,7 @@ module GraphQL
|
|
156
154
|
end
|
157
155
|
|
158
156
|
def on_directive(node, parent)
|
157
|
+
check_timeout
|
159
158
|
directive_defn = @schema.directives[node.name]
|
160
159
|
@directive_definitions.push(directive_defn)
|
161
160
|
call_on_enter_directive(node, parent)
|
@@ -165,6 +164,7 @@ module GraphQL
|
|
165
164
|
end
|
166
165
|
|
167
166
|
def on_argument(node, parent)
|
167
|
+
check_timeout
|
168
168
|
argument_defn = if (arg = @argument_definitions.last)
|
169
169
|
arg_type = arg.type.unwrap
|
170
170
|
if arg_type.kind.input_object?
|
@@ -190,6 +190,7 @@ module GraphQL
|
|
190
190
|
end
|
191
191
|
|
192
192
|
def on_fragment_spread(node, parent)
|
193
|
+
check_timeout
|
193
194
|
@path.push("... #{node.name}")
|
194
195
|
@skipping = @skip_stack.last || skip?(node)
|
195
196
|
@skip_stack << @skipping
|
@@ -267,16 +268,10 @@ module GraphQL
|
|
267
268
|
!dir.empty? && !GraphQL::Execution::DirectiveChecks.include?(dir, query)
|
268
269
|
end
|
269
270
|
|
270
|
-
def
|
271
|
-
|
272
|
-
|
273
|
-
else
|
274
|
-
@object_types.last
|
271
|
+
def check_timeout
|
272
|
+
if Process.clock_gettime(Process::CLOCK_MONOTONIC, :float_second) > @timeout_time
|
273
|
+
raise GraphQL::Analysis::TimeoutError
|
275
274
|
end
|
276
|
-
@object_types.push(object_type)
|
277
|
-
yield(node)
|
278
|
-
@object_types.pop
|
279
|
-
@path.pop
|
280
275
|
end
|
281
276
|
end
|
282
277
|
end
|
data/lib/graphql/analysis.rb
CHANGED
@@ -6,11 +6,16 @@ require "graphql/analysis/query_complexity"
|
|
6
6
|
require "graphql/analysis/max_query_complexity"
|
7
7
|
require "graphql/analysis/query_depth"
|
8
8
|
require "graphql/analysis/max_query_depth"
|
9
|
-
require "timeout"
|
10
|
-
|
11
9
|
module GraphQL
|
12
10
|
module Analysis
|
13
11
|
AST = self
|
12
|
+
|
13
|
+
class TimeoutError < AnalysisError
|
14
|
+
def initialize(...)
|
15
|
+
super("Timeout on validation of query")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
14
19
|
module_function
|
15
20
|
# Analyze a multiplex, and all queries within.
|
16
21
|
# Multiplex analyzers are ran for all queries, keeping state.
|
@@ -61,13 +66,11 @@ module GraphQL
|
|
61
66
|
if !analyzers_to_run.empty?
|
62
67
|
visitor = GraphQL::Analysis::Visitor.new(
|
63
68
|
query: query,
|
64
|
-
analyzers: analyzers_to_run
|
69
|
+
analyzers: analyzers_to_run,
|
70
|
+
timeout: query.validate_timeout_remaining,
|
65
71
|
)
|
66
72
|
|
67
|
-
|
68
|
-
Timeout::timeout(query.validate_timeout_remaining) do
|
69
|
-
visitor.visit
|
70
|
-
end
|
73
|
+
visitor.visit
|
71
74
|
|
72
75
|
if !visitor.rescued_errors.empty?
|
73
76
|
return visitor.rescued_errors
|
@@ -79,8 +82,8 @@ module GraphQL
|
|
79
82
|
[]
|
80
83
|
end
|
81
84
|
end
|
82
|
-
rescue
|
83
|
-
[
|
85
|
+
rescue TimeoutError => err
|
86
|
+
[err]
|
84
87
|
rescue GraphQL::UnauthorizedError, GraphQL::ExecutionError
|
85
88
|
# This error was raised during analysis and will be returned the client before execution
|
86
89
|
[]
|