graphql 2.0.17 → 2.0.19
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.rb +2 -2
- data/lib/graphql/backtrace/tracer.rb +1 -1
- data/lib/graphql/execution/interpreter/resolve.rb +19 -0
- data/lib/graphql/execution/interpreter/runtime.rb +96 -88
- data/lib/graphql/execution/interpreter.rb +8 -13
- data/lib/graphql/execution/lazy.rb +2 -4
- data/lib/graphql/execution/multiplex.rb +2 -1
- data/lib/graphql/language/lexer.rb +216 -1505
- data/lib/graphql/language/lexer.ri +744 -0
- data/lib/graphql/language/nodes.rb +2 -2
- data/lib/graphql/language/parser.rb +39 -38
- data/lib/graphql/language/parser.y +38 -37
- data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
- data/lib/graphql/query/context.rb +57 -27
- data/lib/graphql/query.rb +15 -2
- data/lib/graphql/schema/field.rb +31 -19
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_fields.rb +6 -1
- data/lib/graphql/schema/object.rb +2 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +9 -9
- data/lib/graphql/schema/timeout.rb +24 -28
- data/lib/graphql/schema/warden.rb +8 -1
- data/lib/graphql/schema.rb +42 -0
- data/lib/graphql/static_validation/validator.rb +1 -1
- 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 +66 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +41 -0
- data/lib/graphql/tracing/platform_trace.rb +107 -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.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.rb +136 -39
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/relay/base_connection.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +10 -7
- metadata +31 -7
- data/lib/graphql/language/lexer.rl +0 -280
data/lib/graphql/query.rb
CHANGED
@@ -95,12 +95,20 @@ module GraphQL
|
|
95
95
|
@fragments = nil
|
96
96
|
@operations = nil
|
97
97
|
@validate = validate
|
98
|
-
|
98
|
+
context_tracers = (context ? context.fetch(:tracers, []) : [])
|
99
|
+
@tracers = schema.tracers + context_tracers
|
100
|
+
|
99
101
|
# Support `ctx[:backtrace] = true` for wrapping backtraces
|
100
102
|
if context && context[:backtrace] && !@tracers.include?(GraphQL::Backtrace::Tracer)
|
103
|
+
context_tracers += [GraphQL::Backtrace::Tracer]
|
101
104
|
@tracers << GraphQL::Backtrace::Tracer
|
102
105
|
end
|
103
106
|
|
107
|
+
if context_tracers.any? && !(schema.trace_class <= GraphQL::Tracing::LegacyTrace)
|
108
|
+
raise ArgumentError, "context[:tracers] and context[:backtrace] are not supported without `tracer_class(GraphQL::Tracing::LegacyTrace)` in the schema configuration, please add it."
|
109
|
+
end
|
110
|
+
|
111
|
+
|
104
112
|
@analysis_errors = []
|
105
113
|
if variables.is_a?(String)
|
106
114
|
raise ArgumentError, "Query variables should be a Hash, not a String. Try JSON.parse to prepare variables."
|
@@ -157,6 +165,11 @@ module GraphQL
|
|
157
165
|
|
158
166
|
attr_accessor :multiplex
|
159
167
|
|
168
|
+
# @return [GraphQL::Tracing::Trace]
|
169
|
+
def current_trace
|
170
|
+
@current_trace ||= multiplex ? multiplex.current_trace : schema.new_trace(multiplex: multiplex, query: self)
|
171
|
+
end
|
172
|
+
|
160
173
|
def subscription_update?
|
161
174
|
@subscription_topic && subscription?
|
162
175
|
end
|
@@ -362,7 +375,7 @@ module GraphQL
|
|
362
375
|
parse_error = nil
|
363
376
|
@document ||= begin
|
364
377
|
if query_string
|
365
|
-
GraphQL.parse(query_string,
|
378
|
+
GraphQL.parse(query_string, trace: self.current_trace)
|
366
379
|
end
|
367
380
|
rescue GraphQL::ParseError => err
|
368
381
|
parse_error = err
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -219,7 +219,7 @@ module GraphQL
|
|
219
219
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
220
220
|
# @param validates [Array<Hash>] Configurations for validating this field
|
221
221
|
# @fallback_value [Object] A fallback value if the method is not defined
|
222
|
-
def initialize(type: nil, name: nil, owner: nil, null: nil, description:
|
222
|
+
def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: :not_given, &definition_block)
|
223
223
|
if name.nil?
|
224
224
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
225
225
|
end
|
@@ -233,9 +233,10 @@ 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
|
-
|
237
|
-
|
238
|
-
|
236
|
+
|
237
|
+
@description = description
|
238
|
+
@type = @owner_type = @own_validators = @own_directives = @own_arguments = nil # these will be prepared later if necessary
|
239
|
+
|
239
240
|
self.deprecation_reason = deprecation_reason
|
240
241
|
|
241
242
|
if method && hash_key && dig
|
@@ -257,6 +258,9 @@ module GraphQL
|
|
257
258
|
if hash_key
|
258
259
|
@hash_key = hash_key
|
259
260
|
@hash_key_str = hash_key.to_s
|
261
|
+
else
|
262
|
+
@hash_key = NOT_CONFIGURED
|
263
|
+
@hash_key_str = NOT_CONFIGURED
|
260
264
|
end
|
261
265
|
|
262
266
|
@method_str = -method_name.to_s
|
@@ -272,15 +276,11 @@ module GraphQL
|
|
272
276
|
true
|
273
277
|
end
|
274
278
|
@connection = connection
|
275
|
-
@
|
276
|
-
@
|
277
|
-
@has_default_page_size = default_page_size != :not_given
|
278
|
-
@default_page_size = default_page_size == :not_given ? nil : default_page_size
|
279
|
+
@max_page_size = max_page_size
|
280
|
+
@default_page_size = default_page_size
|
279
281
|
@introspection = introspection
|
280
282
|
@extras = extras
|
281
|
-
|
282
|
-
@broadcastable = broadcastable
|
283
|
-
end
|
283
|
+
@broadcastable = broadcastable
|
284
284
|
@resolver_class = resolver_class
|
285
285
|
@scope = scope
|
286
286
|
@trace = trace
|
@@ -355,7 +355,7 @@ module GraphQL
|
|
355
355
|
# @return [Boolean, nil]
|
356
356
|
# @see GraphQL::Subscriptions::BroadcastAnalyzer
|
357
357
|
def broadcastable?
|
358
|
-
if
|
358
|
+
if !NOT_CONFIGURED.equal?(@broadcastable)
|
359
359
|
@broadcastable
|
360
360
|
elsif @resolver_class
|
361
361
|
@resolver_class.broadcastable?
|
@@ -369,10 +369,10 @@ module GraphQL
|
|
369
369
|
def description(text = nil)
|
370
370
|
if text
|
371
371
|
@description = text
|
372
|
-
elsif
|
372
|
+
elsif !NOT_CONFIGURED.equal?(@description)
|
373
373
|
@description
|
374
374
|
elsif @resolver_class
|
375
|
-
@
|
375
|
+
@resolver_class.description
|
376
376
|
else
|
377
377
|
nil
|
378
378
|
end
|
@@ -544,22 +544,34 @@ module GraphQL
|
|
544
544
|
|
545
545
|
# @return [Boolean] True if this field's {#max_page_size} should override the schema default.
|
546
546
|
def has_max_page_size?
|
547
|
-
@
|
547
|
+
!NOT_CONFIGURED.equal?(@max_page_size) || (@resolver_class && @resolver_class.has_max_page_size?)
|
548
548
|
end
|
549
549
|
|
550
550
|
# @return [Integer, nil] Applied to connections if {#has_max_page_size?}
|
551
551
|
def max_page_size
|
552
|
-
|
552
|
+
if !NOT_CONFIGURED.equal?(@max_page_size)
|
553
|
+
@max_page_size
|
554
|
+
elsif @resolver_class && @resolver_class.has_max_page_size?
|
555
|
+
@resolver_class.max_page_size
|
556
|
+
else
|
557
|
+
nil
|
558
|
+
end
|
553
559
|
end
|
554
560
|
|
555
561
|
# @return [Boolean] True if this field's {#default_page_size} should override the schema default.
|
556
562
|
def has_default_page_size?
|
557
|
-
@
|
563
|
+
!NOT_CONFIGURED.equal?(@default_page_size) || (@resolver_class && @resolver_class.has_default_page_size?)
|
558
564
|
end
|
559
565
|
|
560
566
|
# @return [Integer, nil] Applied to connections if {#has_default_page_size?}
|
561
567
|
def default_page_size
|
562
|
-
|
568
|
+
if !NOT_CONFIGURED.equal?(@default_page_size)
|
569
|
+
@default_page_size
|
570
|
+
elsif @resolver_class && @resolver_class.has_default_page_size?
|
571
|
+
@resolver_class.default_page_size
|
572
|
+
else
|
573
|
+
nil
|
574
|
+
end
|
563
575
|
end
|
564
576
|
|
565
577
|
class MissingReturnTypeError < GraphQL::Error; end
|
@@ -661,7 +673,7 @@ module GraphQL
|
|
661
673
|
|
662
674
|
inner_object = obj.object
|
663
675
|
|
664
|
-
if
|
676
|
+
if !NOT_CONFIGURED.equal?(@hash_key)
|
665
677
|
hash_value = if inner_object.is_a?(Hash)
|
666
678
|
inner_object.key?(@hash_key) ? inner_object[@hash_key] : inner_object[@hash_key_str]
|
667
679
|
elsif inner_object.respond_to?(:[])
|
@@ -5,17 +5,16 @@ module GraphQL
|
|
5
5
|
class Member
|
6
6
|
module HasDeprecationReason
|
7
7
|
# @return [String, nil] Explains why this member was deprecated (if present, this will be marked deprecated in introspection)
|
8
|
-
|
9
|
-
dir = self.directives.find { |d| d.is_a?(GraphQL::Schema::Directive::Deprecated) }
|
10
|
-
dir && dir.arguments[:reason] # rubocop:disable Development/ContextIsPassedCop -- definition-related
|
11
|
-
end
|
8
|
+
attr_reader :deprecation_reason
|
12
9
|
|
13
10
|
# Set the deprecation reason for this member, or remove it by assigning `nil`
|
14
11
|
# @param text [String, nil]
|
15
12
|
def deprecation_reason=(text)
|
13
|
+
@deprecation_reason = text
|
16
14
|
if text.nil?
|
17
15
|
remove_directive(GraphQL::Schema::Directive::Deprecated)
|
18
16
|
else
|
17
|
+
# This removes a previously-attached directive, if there is one:
|
19
18
|
directive(GraphQL::Schema::Directive::Deprecated, reason: text)
|
20
19
|
end
|
21
20
|
end
|
@@ -72,7 +72,12 @@ module GraphQL
|
|
72
72
|
def add_field(field_defn, method_conflict_warning: field_defn.method_conflict_warning?)
|
73
73
|
# Check that `field_defn.original_name` equals `resolver_method` and `method_sym` --
|
74
74
|
# that shows that no override value was given manually.
|
75
|
-
if method_conflict_warning &&
|
75
|
+
if method_conflict_warning &&
|
76
|
+
CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method) &&
|
77
|
+
field_defn.original_name == field_defn.resolver_method &&
|
78
|
+
field_defn.original_name == field_defn.method_sym &&
|
79
|
+
field_defn.hash_key == NOT_CONFIGURED &&
|
80
|
+
field_defn.dig_keys.nil?
|
76
81
|
warn(conflict_field_name_warning(field_defn))
|
77
82
|
end
|
78
83
|
prev_defn = own_fields[field_defn.name]
|
@@ -48,9 +48,7 @@ module GraphQL
|
|
48
48
|
# @return [GraphQL::Schema::Object, GraphQL::Execution::Lazy]
|
49
49
|
# @raise [GraphQL::UnauthorizedError] if the user-provided hook returns `false`
|
50
50
|
def authorized_new(object, context)
|
51
|
-
|
52
|
-
|
53
|
-
maybe_lazy_auth_val = context.query.trace("authorized", trace_payload) do
|
51
|
+
maybe_lazy_auth_val = context.query.current_trace.authorized(query: context.query, type: self, object: object) do
|
54
52
|
begin
|
55
53
|
authorized?(object, context)
|
56
54
|
rescue GraphQL::UnauthorizedError => err
|
@@ -62,7 +60,7 @@ module GraphQL
|
|
62
60
|
|
63
61
|
auth_val = if context.schema.lazy?(maybe_lazy_auth_val)
|
64
62
|
GraphQL::Execution::Lazy.new do
|
65
|
-
context.query.
|
63
|
+
context.query.current_trace.authorized_lazy(query: context.query, type: self, object: object) do
|
66
64
|
context.schema.sync_lazy(maybe_lazy_auth_val)
|
67
65
|
end
|
68
66
|
end
|
@@ -89,16 +89,16 @@ module GraphQL
|
|
89
89
|
def generate_payload_type
|
90
90
|
resolver_name = graphql_name
|
91
91
|
resolver_fields = all_field_definitions
|
92
|
-
Class.new(object_class)
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
end
|
92
|
+
pt = Class.new(object_class)
|
93
|
+
pt.graphql_name("#{resolver_name}Payload")
|
94
|
+
pt.description("Autogenerated return type of #{resolver_name}.")
|
95
|
+
resolver_fields.each do |f|
|
96
|
+
# Reattach the already-defined field here
|
97
|
+
# (The field's `.owner` will still point to the mutation, not the object type, I think)
|
98
|
+
# Don't re-warn about a method conflict. Since this type is generated, it should be fixed in the resolver instead.
|
99
|
+
pt.add_field(f, method_conflict_warning: false)
|
101
100
|
end
|
101
|
+
pt
|
102
102
|
end
|
103
103
|
end
|
104
104
|
end
|
@@ -33,60 +33,56 @@ module GraphQL
|
|
33
33
|
# end
|
34
34
|
#
|
35
35
|
class Timeout
|
36
|
-
def self.use(schema,
|
37
|
-
|
38
|
-
schema.
|
36
|
+
def self.use(schema, max_seconds: nil)
|
37
|
+
timeout = self.new(max_seconds: max_seconds)
|
38
|
+
schema.trace_with(self::Trace, timeout: timeout)
|
39
39
|
end
|
40
40
|
|
41
|
-
# @param max_seconds [Numeric] how many seconds the query should be allowed to resolve new fields
|
42
41
|
def initialize(max_seconds:)
|
43
42
|
@max_seconds = max_seconds
|
44
43
|
end
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
45
|
+
module Trace
|
46
|
+
# @param max_seconds [Numeric] how many seconds the query should be allowed to resolve new fields
|
47
|
+
def initialize(timeout:, **rest)
|
48
|
+
@timeout = timeout
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
def execute_multiplex(multiplex:)
|
53
|
+
multiplex.queries.each do |query|
|
54
|
+
timeout_duration_s = @timeout.max_seconds(query)
|
51
55
|
timeout_state = if timeout_duration_s == false
|
52
56
|
# if the method returns `false`, don't apply a timeout
|
53
57
|
false
|
54
58
|
else
|
55
59
|
now = Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond)
|
56
|
-
timeout_at = now + (
|
60
|
+
timeout_at = now + (timeout_duration_s * 1000)
|
57
61
|
{
|
58
62
|
timeout_at: timeout_at,
|
59
63
|
timed_out: false
|
60
64
|
}
|
61
65
|
end
|
62
|
-
query.context.namespace(
|
66
|
+
query.context.namespace(@timeout)[:state] = timeout_state
|
63
67
|
end
|
68
|
+
super
|
69
|
+
end
|
64
70
|
|
65
|
-
|
66
|
-
|
67
|
-
query_context = data[:context] || data[:query].context
|
68
|
-
timeout_state = query_context.namespace(self.class).fetch(:state)
|
71
|
+
def execute_field(query:, field:, **_rest)
|
72
|
+
timeout_state = query.context.namespace(@timeout).fetch(:state)
|
69
73
|
# If the `:state` is `false`, then `max_seconds(query)` opted out of timeout for this query.
|
70
74
|
if timeout_state != false && Process.clock_gettime(Process::CLOCK_MONOTONIC, :millisecond) > timeout_state.fetch(:timeout_at)
|
71
|
-
error =
|
72
|
-
GraphQL::Schema::Timeout::TimeoutError.new(query_context.parent_type, query_context.field)
|
73
|
-
else
|
74
|
-
field = data.fetch(:field)
|
75
|
-
GraphQL::Schema::Timeout::TimeoutError.new(field.owner, field)
|
76
|
-
end
|
77
|
-
|
75
|
+
error = GraphQL::Schema::Timeout::TimeoutError.new(field)
|
78
76
|
# Only invoke the timeout callback for the first timeout
|
79
77
|
if !timeout_state[:timed_out]
|
80
78
|
timeout_state[:timed_out] = true
|
81
|
-
handle_timeout(error,
|
79
|
+
@timeout.handle_timeout(error, query)
|
82
80
|
end
|
83
81
|
|
84
82
|
error
|
85
83
|
else
|
86
|
-
|
84
|
+
super
|
87
85
|
end
|
88
|
-
else
|
89
|
-
yield
|
90
86
|
end
|
91
87
|
end
|
92
88
|
|
@@ -114,8 +110,8 @@ module GraphQL
|
|
114
110
|
# to take this error and raise a new one which _doesn't_ descend from {GraphQL::ExecutionError},
|
115
111
|
# such as `RuntimeError`.
|
116
112
|
class TimeoutError < GraphQL::ExecutionError
|
117
|
-
def initialize(
|
118
|
-
super("Timeout on #{
|
113
|
+
def initialize(field)
|
114
|
+
super("Timeout on #{field.path}")
|
119
115
|
end
|
120
116
|
end
|
121
117
|
end
|
@@ -96,6 +96,13 @@ module GraphQL
|
|
96
96
|
@subscription = @schema.subscription
|
97
97
|
@context = context
|
98
98
|
@visibility_cache = read_through { |m| filter.call(m, context) }
|
99
|
+
# Initialize all ivars to improve object shape consistency:
|
100
|
+
@types = @visible_types = @reachable_types = @visible_parent_fields =
|
101
|
+
@visible_possible_types = @visible_fields = @visible_arguments = @visible_enum_arrays =
|
102
|
+
@visible_enum_values = @visible_interfaces = @type_visibility = @type_memberships =
|
103
|
+
@visible_and_reachable_type = @unions = @unfiltered_interfaces = @references_to =
|
104
|
+
@reachable_type_set =
|
105
|
+
nil
|
99
106
|
end
|
100
107
|
|
101
108
|
# @return [Hash<String, GraphQL::BaseType>] Visible types in the schema
|
@@ -347,7 +354,7 @@ module GraphQL
|
|
347
354
|
end
|
348
355
|
|
349
356
|
def reachable_type_set
|
350
|
-
return @reachable_type_set if
|
357
|
+
return @reachable_type_set if @reachable_type_set
|
351
358
|
|
352
359
|
@reachable_type_set = Set.new
|
353
360
|
rt_hash = {}
|
data/lib/graphql/schema.rb
CHANGED
@@ -143,6 +143,20 @@ module GraphQL
|
|
143
143
|
@subscriptions = new_implementation
|
144
144
|
end
|
145
145
|
|
146
|
+
def trace_class(new_class = nil)
|
147
|
+
if new_class
|
148
|
+
@trace_class = new_class
|
149
|
+
elsif !defined?(@trace_class)
|
150
|
+
parent_trace_class = if superclass.respond_to?(:trace_class)
|
151
|
+
superclass.trace_class
|
152
|
+
else
|
153
|
+
GraphQL::Tracing::Trace
|
154
|
+
end
|
155
|
+
@trace_class = Class.new(parent_trace_class)
|
156
|
+
end
|
157
|
+
@trace_class
|
158
|
+
end
|
159
|
+
|
146
160
|
# Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
|
147
161
|
# @see {#as_json}
|
148
162
|
# @return [String]
|
@@ -926,6 +940,12 @@ module GraphQL
|
|
926
940
|
end
|
927
941
|
|
928
942
|
def tracer(new_tracer)
|
943
|
+
if defined?(@trace_class) && !(@trace_class < GraphQL::Tracing::LegacyTrace)
|
944
|
+
raise ArgumentError, "Can't add tracer after configuring a `trace_class`, use GraphQL::Tracing::LegacyTrace to merge legacy tracers into a trace class instead."
|
945
|
+
elsif !defined?(@trace_class)
|
946
|
+
@trace_class = Class.new(GraphQL::Tracing::LegacyTrace)
|
947
|
+
end
|
948
|
+
|
929
949
|
own_tracers << new_tracer
|
930
950
|
end
|
931
951
|
|
@@ -933,6 +953,28 @@ module GraphQL
|
|
933
953
|
find_inherited_value(:tracers, EMPTY_ARRAY) + own_tracers
|
934
954
|
end
|
935
955
|
|
956
|
+
# Mix `trace_mod` into this schema's `Trace` class so that its methods
|
957
|
+
# will be called at runtime.
|
958
|
+
#
|
959
|
+
# @param trace_mod [Module] A module that implements tracing methods
|
960
|
+
# @param options [Hash] Keywords that will be passed to the tracing class during `#initialize`
|
961
|
+
# @return [void]
|
962
|
+
def trace_with(trace_mod, **options)
|
963
|
+
trace_options.merge!(options)
|
964
|
+
trace_class.include(trace_mod)
|
965
|
+
end
|
966
|
+
|
967
|
+
def trace_options
|
968
|
+
@trace_options ||= superclass.respond_to?(:trace_options) ? superclass.trace_options.dup : {}
|
969
|
+
end
|
970
|
+
|
971
|
+
def new_trace(**options)
|
972
|
+
if defined?(@trace_options)
|
973
|
+
options = trace_options.merge(options)
|
974
|
+
end
|
975
|
+
trace_class.new(**options)
|
976
|
+
end
|
977
|
+
|
936
978
|
def query_analyzer(new_analyzer)
|
937
979
|
own_query_analyzers << new_analyzer
|
938
980
|
end
|
@@ -27,7 +27,7 @@ module GraphQL
|
|
27
27
|
# @param max_errors [Integer] Maximum number of errors before aborting validation. Any positive number will limit the number of errors. Defaults to nil for no limit.
|
28
28
|
# @return [Array<Hash>]
|
29
29
|
def validate(query, validate: true, timeout: nil, max_errors: nil)
|
30
|
-
query.
|
30
|
+
query.current_trace.validate(validate: validate, query: query) do
|
31
31
|
errors = if validate == false
|
32
32
|
[]
|
33
33
|
else
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'graphql/tracing/notifications_trace'
|
4
|
+
|
5
|
+
module GraphQL
|
6
|
+
module Tracing
|
7
|
+
# This implementation forwards events to ActiveSupport::Notifications
|
8
|
+
# with a `graphql` suffix.
|
9
|
+
module ActiveSupportNotificationsTrace
|
10
|
+
include NotificationsTrace
|
11
|
+
def initialize(engine: ActiveSupport::Notifications, **rest)
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|