graphql 1.11.4 → 1.11.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/object_generator.rb +2 -0
- data/lib/generators/graphql/templates/union.erb +1 -1
- data/lib/graphql.rb +17 -0
- data/lib/graphql/argument.rb +3 -3
- data/lib/graphql/backtrace/tracer.rb +2 -1
- data/lib/graphql/define/assign_global_id_field.rb +2 -2
- data/lib/graphql/execution/interpreter.rb +10 -0
- data/lib/graphql/execution/interpreter/arguments.rb +21 -6
- data/lib/graphql/execution/interpreter/arguments_cache.rb +8 -0
- data/lib/graphql/execution/interpreter/runtime.rb +70 -42
- data/lib/graphql/integer_decoding_error.rb +17 -0
- data/lib/graphql/introspection.rb +96 -0
- data/lib/graphql/introspection/field_type.rb +7 -3
- data/lib/graphql/introspection/input_value_type.rb +6 -0
- data/lib/graphql/introspection/introspection_query.rb +6 -92
- data/lib/graphql/introspection/type_type.rb +7 -3
- data/lib/graphql/invalid_null_error.rb +1 -1
- data/lib/graphql/language/block_string.rb +24 -5
- data/lib/graphql/language/lexer.rb +7 -3
- data/lib/graphql/language/lexer.rl +7 -3
- data/lib/graphql/language/nodes.rb +1 -1
- data/lib/graphql/language/parser.rb +107 -103
- data/lib/graphql/language/parser.y +4 -0
- data/lib/graphql/language/sanitized_printer.rb +59 -26
- data/lib/graphql/name_validator.rb +6 -7
- data/lib/graphql/pagination/connections.rb +11 -3
- data/lib/graphql/query.rb +6 -3
- data/lib/graphql/query/context.rb +14 -3
- data/lib/graphql/query/validation_pipeline.rb +1 -1
- data/lib/graphql/relay/array_connection.rb +2 -2
- data/lib/graphql/relay/range_add.rb +14 -5
- data/lib/graphql/schema.rb +47 -19
- data/lib/graphql/schema/argument.rb +56 -5
- data/lib/graphql/schema/build_from_definition.rb +67 -38
- data/lib/graphql/schema/default_type_error.rb +2 -0
- data/lib/graphql/schema/directive/deprecated.rb +1 -1
- data/lib/graphql/schema/field.rb +32 -16
- data/lib/graphql/schema/field/connection_extension.rb +8 -7
- data/lib/graphql/schema/field/scope_extension.rb +1 -1
- data/lib/graphql/schema/input_object.rb +5 -3
- data/lib/graphql/schema/interface.rb +1 -1
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/loader.rb +1 -0
- data/lib/graphql/schema/member/build_type.rb +14 -4
- data/lib/graphql/schema/member/has_arguments.rb +54 -53
- data/lib/graphql/schema/member/has_fields.rb +2 -2
- data/lib/graphql/schema/member/type_system_helpers.rb +2 -2
- data/lib/graphql/schema/relay_classic_mutation.rb +4 -2
- data/lib/graphql/schema/timeout.rb +29 -15
- data/lib/graphql/schema/unique_within_type.rb +1 -2
- data/lib/graphql/schema/validation.rb +8 -0
- data/lib/graphql/static_validation.rb +1 -0
- data/lib/graphql/static_validation/all_rules.rb +1 -0
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +25 -17
- data/lib/graphql/static_validation/rules/input_object_names_are_unique.rb +30 -0
- data/lib/graphql/static_validation/rules/input_object_names_are_unique_error.rb +30 -0
- data/lib/graphql/static_validation/validation_timeout_error.rb +25 -0
- data/lib/graphql/static_validation/validator.rb +29 -7
- data/lib/graphql/subscriptions.rb +1 -3
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +21 -7
- data/lib/graphql/tracing/platform_tracing.rb +1 -1
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +4 -1
- data/lib/graphql/types/int.rb +9 -2
- data/lib/graphql/types/relay/base_connection.rb +2 -1
- data/lib/graphql/types/relay/base_edge.rb +2 -1
- data/lib/graphql/types/string.rb +7 -1
- data/lib/graphql/unauthorized_error.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- metadata +7 -3
@@ -466,6 +466,10 @@ def self.parse(query_string, filename: nil, tracer: GraphQL::Tracing::NullTracer
|
|
466
466
|
self.new(query_string, filename: filename, tracer: tracer).parse_document
|
467
467
|
end
|
468
468
|
|
469
|
+
def self.parse_file(filename, tracer: GraphQL::Tracing::NullTracer)
|
470
|
+
self.parse(File.read(filename), filename: filename, tracer: tracer)
|
471
|
+
end
|
472
|
+
|
469
473
|
private
|
470
474
|
|
471
475
|
def next_token
|
@@ -19,11 +19,12 @@ module GraphQL
|
|
19
19
|
|
20
20
|
REDACTED = "\"<REDACTED>\""
|
21
21
|
|
22
|
-
def initialize(query)
|
22
|
+
def initialize(query, inline_variables: true)
|
23
23
|
@query = query
|
24
24
|
@current_type = nil
|
25
25
|
@current_field = nil
|
26
26
|
@current_input_type = nil
|
27
|
+
@inline_variables = inline_variables
|
27
28
|
end
|
28
29
|
|
29
30
|
# @return [String, nil] A scrubbed query string, if the query was valid.
|
@@ -36,15 +37,14 @@ module GraphQL
|
|
36
37
|
end
|
37
38
|
|
38
39
|
def print_node(node, indent: "")
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
super
|
40
|
+
case node
|
41
|
+
when FalseClass, Float, Integer, String, TrueClass
|
42
|
+
if @current_argument && redact_argument_value?(@current_argument, node)
|
43
|
+
redacted_argument_value(@current_argument)
|
44
44
|
else
|
45
|
-
|
45
|
+
super
|
46
46
|
end
|
47
|
-
|
47
|
+
when Array
|
48
48
|
old_input_type = @current_input_type
|
49
49
|
if @current_input_type && @current_input_type.list?
|
50
50
|
@current_input_type = @current_input_type.of_type
|
@@ -59,28 +59,57 @@ module GraphQL
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
+
# Indicates whether or not to redact non-null values for the given argument. Defaults to redacting all strings
|
63
|
+
# arguments but this can be customized by subclasses.
|
64
|
+
def redact_argument_value?(argument, value)
|
65
|
+
# Default to redacting any strings or custom scalars encoded as strings
|
66
|
+
type = argument.type.unwrap
|
67
|
+
value.is_a?(String) && type.kind.scalar? && (type.graphql_name == "String" || !type.default_scalar?)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Returns the value to use for redacted versions of the given argument. Defaults to the
|
71
|
+
# string "<REDACTED>".
|
72
|
+
def redacted_argument_value(argument)
|
73
|
+
REDACTED
|
74
|
+
end
|
75
|
+
|
62
76
|
def print_argument(argument)
|
77
|
+
# We won't have type information if we're recursing into a custom scalar
|
78
|
+
return super if @current_input_type && @current_input_type.kind.scalar?
|
79
|
+
|
63
80
|
arg_owner = @current_input_type || @current_directive || @current_field
|
64
|
-
|
81
|
+
old_current_argument = @current_argument
|
82
|
+
@current_argument = arg_owner.arguments[argument.name]
|
65
83
|
|
66
84
|
old_input_type = @current_input_type
|
67
|
-
@current_input_type =
|
68
|
-
|
85
|
+
@current_input_type = @current_argument.type.non_null? ? @current_argument.type.of_type : @current_argument.type
|
86
|
+
|
87
|
+
argument_value = if coerce_argument_value_to_list?(@current_input_type, argument.value)
|
88
|
+
[argument.value]
|
89
|
+
else
|
90
|
+
argument.value
|
91
|
+
end
|
92
|
+
res = "#{argument.name}: #{print_node(argument_value)}".dup
|
93
|
+
|
69
94
|
@current_input_type = old_input_type
|
95
|
+
@current_argument = old_current_argument
|
70
96
|
res
|
71
97
|
end
|
72
98
|
|
73
|
-
def
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
res
|
99
|
+
def coerce_argument_value_to_list?(type, value)
|
100
|
+
type.list? &&
|
101
|
+
!value.is_a?(Array) &&
|
102
|
+
!value.nil? &&
|
103
|
+
!value.is_a?(GraphQL::Language::Nodes::VariableIdentifier)
|
79
104
|
end
|
80
105
|
|
81
106
|
def print_variable_identifier(variable_id)
|
82
|
-
|
83
|
-
|
107
|
+
if @inline_variables
|
108
|
+
variable_value = query.variables[variable_id.name]
|
109
|
+
print_node(value_to_ast(variable_value, @current_input_type))
|
110
|
+
else
|
111
|
+
super
|
112
|
+
end
|
84
113
|
end
|
85
114
|
|
86
115
|
def print_field(field, indent: "")
|
@@ -132,10 +161,14 @@ module GraphQL
|
|
132
161
|
old_type = @current_type
|
133
162
|
@current_type = query.schema.public_send(operation_definition.operation_type)
|
134
163
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
164
|
+
if @inline_variables
|
165
|
+
out = "#{indent}#{operation_definition.operation_type}".dup
|
166
|
+
out << " #{operation_definition.name}" if operation_definition.name
|
167
|
+
out << print_directives(operation_definition.directives)
|
168
|
+
out << print_selections(operation_definition.selections, indent: indent)
|
169
|
+
else
|
170
|
+
out = super
|
171
|
+
end
|
139
172
|
|
140
173
|
@current_type = old_type
|
141
174
|
out
|
@@ -171,10 +204,10 @@ module GraphQL
|
|
171
204
|
arguments: arguments
|
172
205
|
)
|
173
206
|
when "LIST"
|
174
|
-
if value.
|
175
|
-
value.
|
207
|
+
if value.is_a?(Array)
|
208
|
+
value.map { |v| value_to_ast(v, type.of_type) }
|
176
209
|
else
|
177
|
-
[value].
|
210
|
+
[value].map { |v| value_to_ast(v, type.of_type) }
|
178
211
|
end
|
179
212
|
when "ENUM"
|
180
213
|
GraphQL::Language::Nodes::Enum.new(name: value)
|
@@ -1,16 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module GraphQL
|
3
3
|
class NameValidator
|
4
|
-
|
5
|
-
|
6
|
-
def self.validate!(name)
|
7
|
-
raise GraphQL::InvalidNameError.new(name, VALID_NAME_REGEX) unless valid?(name)
|
4
|
+
if !String.method_defined?(:match?)
|
5
|
+
using GraphQL::StringMatchBackport
|
8
6
|
end
|
9
7
|
|
10
|
-
|
8
|
+
VALID_NAME_REGEX = /^[_a-zA-Z][_a-zA-Z0-9]*$/
|
11
9
|
|
12
|
-
def self.
|
13
|
-
name
|
10
|
+
def self.validate!(name)
|
11
|
+
name = name.is_a?(String) ? name : name.to_s
|
12
|
+
raise GraphQL::InvalidNameError.new(name, VALID_NAME_REGEX) unless name.match?(VALID_NAME_REGEX)
|
14
13
|
end
|
15
14
|
end
|
16
15
|
end
|
@@ -63,9 +63,7 @@ module GraphQL
|
|
63
63
|
all_wrappers
|
64
64
|
end
|
65
65
|
|
66
|
-
|
67
|
-
# @api Private
|
68
|
-
def wrap(field, parent, items, arguments, context, wrappers: all_wrappers)
|
66
|
+
def wrapper_for(items, wrappers: all_wrappers)
|
69
67
|
impl = nil
|
70
68
|
|
71
69
|
items.class.ancestors.each { |cls|
|
@@ -73,6 +71,16 @@ module GraphQL
|
|
73
71
|
break if impl
|
74
72
|
}
|
75
73
|
|
74
|
+
impl
|
75
|
+
end
|
76
|
+
|
77
|
+
# Used by the runtime to wrap values in connection wrappers.
|
78
|
+
# @api Private
|
79
|
+
def wrap(field, parent, items, arguments, context, wrappers: all_wrappers)
|
80
|
+
return items if GraphQL::Execution::Interpreter::RawValue === items
|
81
|
+
|
82
|
+
impl = wrapper_for(items, wrappers: wrappers)
|
83
|
+
|
76
84
|
if impl.nil?
|
77
85
|
raise ImplementationMissingError, "Couldn't find a connection wrapper for #{items.class} during #{field.path} (#{items.inspect})"
|
78
86
|
end
|
data/lib/graphql/query.rb
CHANGED
@@ -88,6 +88,7 @@ module GraphQL
|
|
88
88
|
schema = schema.graphql_definition
|
89
89
|
end
|
90
90
|
@schema = schema
|
91
|
+
@interpreter = @schema.interpreter?
|
91
92
|
@filter = schema.default_filter.merge(except: except, only: only)
|
92
93
|
@context = schema.context_class.new(query: self, object: root_value, values: context)
|
93
94
|
@warden = warden
|
@@ -148,7 +149,9 @@ module GraphQL
|
|
148
149
|
@query_string ||= (document ? document.to_query_string : nil)
|
149
150
|
end
|
150
151
|
|
151
|
-
|
152
|
+
def interpreter?
|
153
|
+
@interpreter
|
154
|
+
end
|
152
155
|
|
153
156
|
def subscription_update?
|
154
157
|
@subscription_topic && subscription?
|
@@ -259,9 +262,9 @@ module GraphQL
|
|
259
262
|
# - Variables inlined to the query
|
260
263
|
# - Strings replaced with `<REDACTED>`
|
261
264
|
# @return [String, nil] Returns nil if the query is invalid.
|
262
|
-
def sanitized_query_string
|
265
|
+
def sanitized_query_string(inline_variables: true)
|
263
266
|
with_prepared_ast {
|
264
|
-
GraphQL::Language::SanitizedPrinter.new(self).sanitized_query_string
|
267
|
+
GraphQL::Language::SanitizedPrinter.new(self, inline_variables: inline_variables).sanitized_query_string
|
265
268
|
}
|
266
269
|
end
|
267
270
|
|
@@ -34,7 +34,7 @@ module GraphQL
|
|
34
34
|
# Remove this child from the result value
|
35
35
|
# (used for null propagation and skip)
|
36
36
|
# @api private
|
37
|
-
def
|
37
|
+
def delete_child(child_ctx)
|
38
38
|
@value.delete(child_ctx.key)
|
39
39
|
end
|
40
40
|
|
@@ -167,7 +167,10 @@ module GraphQL
|
|
167
167
|
# @api private
|
168
168
|
attr_accessor :scoped_context
|
169
169
|
|
170
|
-
|
170
|
+
def []=(key, value)
|
171
|
+
@provided_values[key] = value
|
172
|
+
end
|
173
|
+
|
171
174
|
def_delegators :@query, :trace, :interpreter?
|
172
175
|
|
173
176
|
# @!method []=(key, value)
|
@@ -179,6 +182,14 @@ module GraphQL
|
|
179
182
|
@provided_values[key]
|
180
183
|
end
|
181
184
|
|
185
|
+
def delete(key)
|
186
|
+
if @scoped_context.key?(key)
|
187
|
+
@scoped_context.delete(key)
|
188
|
+
else
|
189
|
+
@provided_values.delete(key)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
182
193
|
UNSPECIFIED_FETCH_DEFAULT = Object.new
|
183
194
|
|
184
195
|
def fetch(key, default = UNSPECIFIED_FETCH_DEFAULT)
|
@@ -312,7 +323,7 @@ module GraphQL
|
|
312
323
|
end
|
313
324
|
when GraphQL::Execution::Execute::SKIP
|
314
325
|
@parent.skipped = true
|
315
|
-
@parent.
|
326
|
+
@parent.delete_child(self)
|
316
327
|
else
|
317
328
|
@value = new_value
|
318
329
|
end
|
@@ -72,7 +72,7 @@ module GraphQL
|
|
72
72
|
elsif @operation_name_error
|
73
73
|
@validation_errors << @operation_name_error
|
74
74
|
else
|
75
|
-
validation_result = @schema.static_validator.validate(@query, validate: @validate)
|
75
|
+
validation_result = @schema.static_validator.validate(@query, validate: @validate, timeout: @schema.validate_timeout)
|
76
76
|
@validation_errors.concat(validation_result[:errors])
|
77
77
|
@internal_representation = validation_result[:irep]
|
78
78
|
|
@@ -31,8 +31,6 @@ module GraphQL
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
private
|
35
|
-
|
36
34
|
def first
|
37
35
|
@first ||= begin
|
38
36
|
capped = limit_pagination_argument(arguments[:first], max_page_size)
|
@@ -47,6 +45,8 @@ module GraphQL
|
|
47
45
|
@last ||= limit_pagination_argument(arguments[:last], max_page_size)
|
48
46
|
end
|
49
47
|
|
48
|
+
private
|
49
|
+
|
50
50
|
# apply first / last limit results
|
51
51
|
def paged_nodes
|
52
52
|
@paged_nodes ||= begin
|
@@ -33,12 +33,21 @@ module GraphQL
|
|
33
33
|
# @param item [Object] The newly-added item (will be wrapped in `edge_class`)
|
34
34
|
# @param parent [Object] The owner of `collection`, will be passed to the connection if provided
|
35
35
|
# @param context [GraphQL::Query::Context] The surrounding `ctx`, will be passed to the connection if provided (this is required for cursor encoders)
|
36
|
-
# @param edge_class [Class] The class to wrap `item` with
|
37
|
-
def initialize(collection:, item:, parent: nil, context: nil, edge_class:
|
38
|
-
|
36
|
+
# @param edge_class [Class] The class to wrap `item` with (defaults to the connection's edge class)
|
37
|
+
def initialize(collection:, item:, parent: nil, context: nil, edge_class: nil)
|
38
|
+
if context && context.schema.new_connections?
|
39
|
+
conn_class = context.schema.connections.wrapper_for(collection)
|
40
|
+
# The rest will be added by ConnectionExtension
|
41
|
+
@connection = conn_class.new(collection, parent: parent, context: context, edge_class: edge_class)
|
42
|
+
@edge = @connection.edge_class.new(item, @connection)
|
43
|
+
else
|
44
|
+
connection_class = BaseConnection.connection_for_nodes(collection)
|
45
|
+
@connection = connection_class.new(collection, {}, parent: parent, context: context)
|
46
|
+
edge_class ||= Relay::Edge
|
47
|
+
@edge = edge_class.new(item, @connection)
|
48
|
+
end
|
49
|
+
|
39
50
|
@parent = parent
|
40
|
-
@connection = connection_class.new(collection, {}, parent: parent, context: context)
|
41
|
-
@edge = edge_class.new(item, @connection)
|
42
51
|
end
|
43
52
|
end
|
44
53
|
end
|
data/lib/graphql/schema.rb
CHANGED
@@ -157,7 +157,7 @@ module GraphQL
|
|
157
157
|
|
158
158
|
accepts_definitions \
|
159
159
|
:query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
|
160
|
-
:max_depth, :max_complexity, :default_max_page_size,
|
160
|
+
:validate_timeout, :max_depth, :max_complexity, :default_max_page_size,
|
161
161
|
:orphan_types, :resolve_type, :type_error, :parse_error,
|
162
162
|
:error_bubbling,
|
163
163
|
:raise_definition_error,
|
@@ -196,7 +196,7 @@ module GraphQL
|
|
196
196
|
attr_accessor \
|
197
197
|
:query, :mutation, :subscription,
|
198
198
|
:query_execution_strategy, :mutation_execution_strategy, :subscription_execution_strategy,
|
199
|
-
:max_depth, :max_complexity, :default_max_page_size,
|
199
|
+
:validate_timeout, :max_depth, :max_complexity, :default_max_page_size,
|
200
200
|
:orphan_types, :directives,
|
201
201
|
:query_analyzers, :multiplex_analyzers, :instrumenters, :lazy_methods,
|
202
202
|
:cursor_encoder,
|
@@ -366,7 +366,7 @@ module GraphQL
|
|
366
366
|
validator_opts = { schema: self }
|
367
367
|
rules && (validator_opts[:rules] = rules)
|
368
368
|
validator = GraphQL::StaticValidation::Validator.new(**validator_opts)
|
369
|
-
res = validator.validate(query)
|
369
|
+
res = validator.validate(query, timeout: validate_timeout)
|
370
370
|
res[:errors]
|
371
371
|
end
|
372
372
|
|
@@ -789,20 +789,25 @@ module GraphQL
|
|
789
789
|
# @param using [Hash] Plugins to attach to the created schema with `use(key, value)`
|
790
790
|
# @param interpreter [Boolean] If false, the legacy {Execution::Execute} runtime will be used
|
791
791
|
# @return [Class] the schema described by `document`
|
792
|
-
def self.from_definition(definition_or_path, default_resolve: nil, interpreter: true, parser:
|
792
|
+
def self.from_definition(definition_or_path, default_resolve: nil, interpreter: true, parser: GraphQL.default_parser, using: {})
|
793
793
|
# If the file ends in `.graphql`, treat it like a filepath
|
794
|
-
|
795
|
-
|
794
|
+
if definition_or_path.end_with?(".graphql")
|
795
|
+
GraphQL::Schema::BuildFromDefinition.from_definition_path(
|
796
|
+
definition_or_path,
|
797
|
+
default_resolve: default_resolve,
|
798
|
+
parser: parser,
|
799
|
+
using: using,
|
800
|
+
interpreter: interpreter,
|
801
|
+
)
|
796
802
|
else
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
)
|
803
|
+
GraphQL::Schema::BuildFromDefinition.from_definition(
|
804
|
+
definition_or_path,
|
805
|
+
default_resolve: default_resolve,
|
806
|
+
parser: parser,
|
807
|
+
using: using,
|
808
|
+
interpreter: interpreter,
|
809
|
+
)
|
810
|
+
end
|
806
811
|
end
|
807
812
|
|
808
813
|
# Error that is raised when [#Schema#from_definition] is passed an invalid schema definition string.
|
@@ -832,7 +837,7 @@ module GraphQL
|
|
832
837
|
# @param except [<#call(member, ctx)>]
|
833
838
|
# @return [Hash] GraphQL result
|
834
839
|
def as_json(only: nil, except: nil, context: {})
|
835
|
-
execute(Introspection
|
840
|
+
execute(Introspection.query(include_deprecated_args: true), only: only, except: except, context: context).to_h
|
836
841
|
end
|
837
842
|
|
838
843
|
# Returns the JSON response of {Introspection::INTROSPECTION_QUERY}.
|
@@ -880,7 +885,7 @@ module GraphQL
|
|
880
885
|
# @param except [<#call(member, ctx)>]
|
881
886
|
# @return [Hash] GraphQL result
|
882
887
|
def as_json(only: nil, except: nil, context: {})
|
883
|
-
execute(Introspection
|
888
|
+
execute(Introspection.query(include_deprecated_args: true), only: only, except: except, context: context).to_h
|
884
889
|
end
|
885
890
|
|
886
891
|
# Return the GraphQL IDL for the schema
|
@@ -945,6 +950,7 @@ module GraphQL
|
|
945
950
|
schema_defn.query = query && query.graphql_definition
|
946
951
|
schema_defn.mutation = mutation && mutation.graphql_definition
|
947
952
|
schema_defn.subscription = subscription && subscription.graphql_definition
|
953
|
+
schema_defn.validate_timeout = validate_timeout
|
948
954
|
schema_defn.max_complexity = max_complexity
|
949
955
|
schema_defn.error_bubbling = error_bubbling
|
950
956
|
schema_defn.max_depth = max_depth
|
@@ -1112,7 +1118,17 @@ module GraphQL
|
|
1112
1118
|
if type.kind.union?
|
1113
1119
|
type.possible_types(context: context)
|
1114
1120
|
else
|
1115
|
-
own_possible_types[type.graphql_name]
|
1121
|
+
stored_possible_types = own_possible_types[type.graphql_name]
|
1122
|
+
visible_possible_types = if stored_possible_types && type.kind.interface?
|
1123
|
+
stored_possible_types.select do |possible_type|
|
1124
|
+
# Use `.graphql_name` comparison to match legacy vs class-based types.
|
1125
|
+
# When we don't need to support legacy `.define` types, use `.include?(type)` instead.
|
1126
|
+
possible_type.interfaces(context).any? { |interface| interface.graphql_name == type.graphql_name }
|
1127
|
+
end
|
1128
|
+
else
|
1129
|
+
stored_possible_types
|
1130
|
+
end
|
1131
|
+
visible_possible_types ||
|
1116
1132
|
introspection_system.possible_types[type.graphql_name] ||
|
1117
1133
|
(
|
1118
1134
|
superclass.respond_to?(:possible_types) ?
|
@@ -1258,6 +1274,18 @@ module GraphQL
|
|
1258
1274
|
end
|
1259
1275
|
end
|
1260
1276
|
|
1277
|
+
attr_writer :validate_timeout
|
1278
|
+
|
1279
|
+
def validate_timeout(new_validate_timeout = nil)
|
1280
|
+
if new_validate_timeout
|
1281
|
+
@validate_timeout = new_validate_timeout
|
1282
|
+
elsif defined?(@validate_timeout)
|
1283
|
+
@validate_timeout
|
1284
|
+
else
|
1285
|
+
find_inherited_value(:validate_timeout)
|
1286
|
+
end
|
1287
|
+
end
|
1288
|
+
|
1261
1289
|
attr_writer :max_complexity
|
1262
1290
|
|
1263
1291
|
def max_complexity(max_complexity = nil)
|
@@ -1664,7 +1692,7 @@ module GraphQL
|
|
1664
1692
|
end
|
1665
1693
|
|
1666
1694
|
def query_stack_error(query, err)
|
1667
|
-
query.
|
1695
|
+
query.context.errors.push(GraphQL::ExecutionError.new("This query is too large to execute."))
|
1668
1696
|
end
|
1669
1697
|
|
1670
1698
|
private
|