graphql 1.13.23 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +1 -1
- data/lib/graphql/analysis/ast.rb +0 -10
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/table.rb +0 -18
- data/lib/graphql/backtrace/tracer.rb +1 -2
- data/lib/graphql/backtrace.rb +2 -8
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +1 -9
- data/lib/graphql/execution/interpreter/runtime.rb +6 -13
- data/lib/graphql/execution/interpreter.rb +0 -22
- data/lib/graphql/execution/lazy.rb +1 -1
- data/lib/graphql/execution/lookahead.rb +6 -13
- data/lib/graphql/execution/multiplex.rb +50 -107
- data/lib/graphql/execution.rb +11 -3
- data/lib/graphql/introspection/directive_type.rb +2 -2
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +2 -15
- 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 +0 -17
- data/lib/graphql/pagination/connections.rb +2 -28
- data/lib/graphql/query/context.rb +1 -185
- data/lib/graphql/query/input_validation_result.rb +0 -9
- data/lib/graphql/query/literal_input.rb +8 -13
- data/lib/graphql/query/validation_pipeline.rb +6 -34
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +8 -31
- data/lib/graphql/query.rb +5 -34
- data/lib/graphql/railtie.rb +0 -104
- data/lib/graphql/relay/range_add.rb +0 -4
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/schema/addition.rb +1 -8
- data/lib/graphql/schema/argument.rb +1 -25
- data/lib/graphql/schema/build_from_definition.rb +0 -1
- data/lib/graphql/schema/directive.rb +1 -22
- data/lib/graphql/schema/enum.rb +3 -19
- data/lib/graphql/schema/enum_value.rb +0 -22
- data/lib/graphql/schema/field.rb +22 -220
- data/lib/graphql/schema/input_object.rb +11 -57
- data/lib/graphql/schema/interface.rb +1 -30
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +3 -24
- data/lib/graphql/schema/loader.rb +0 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +1 -6
- data/lib/graphql/schema/member/build_type.rb +4 -6
- data/lib/graphql/schema/member/has_arguments.rb +16 -20
- data/lib/graphql/schema/member/has_fields.rb +3 -3
- data/lib/graphql/schema/member/has_interfaces.rb +1 -13
- data/lib/graphql/schema/member/validates_input.rb +2 -2
- data/lib/graphql/schema/member.rb +0 -6
- data/lib/graphql/schema/mutation.rb +0 -9
- data/lib/graphql/schema/non_null.rb +3 -9
- data/lib/graphql/schema/object.rb +0 -40
- data/lib/graphql/schema/relay_classic_mutation.rb +17 -28
- data/lib/graphql/schema/scalar.rb +1 -16
- data/lib/graphql/schema/union.rb +0 -16
- data/lib/graphql/schema/warden.rb +3 -12
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +106 -945
- data/lib/graphql/static_validation/base_visitor.rb +4 -21
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
- data/lib/graphql/static_validation/validator.rb +2 -24
- data/lib/graphql/static_validation.rb +0 -2
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
- data/lib/graphql/subscriptions/event.rb +1 -1
- data/lib/graphql/subscriptions/instrumentation.rb +0 -51
- data/lib/graphql/subscriptions.rb +4 -13
- data/lib/graphql/tracing/data_dog_tracing.rb +16 -20
- data/lib/graphql/tracing/platform_tracing.rb +4 -32
- data/lib/graphql/tracing.rb +0 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +2 -6
- data/lib/graphql/types/relay/default_relay.rb +0 -10
- data/lib/graphql/types/relay/node_behaviors.rb +5 -1
- data/lib/graphql/types/relay.rb +0 -2
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -66
- metadata +28 -167
- data/lib/graphql/analysis/analyze_query.rb +0 -98
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
- data/lib/graphql/backwards_compatibility.rb +0 -61
- data/lib/graphql/base_type.rb +0 -232
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -436
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -255
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -55
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -133
- data/lib/graphql/execution/execute.rb +0 -333
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -226
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -128
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -138
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -72
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -130
- data/lib/graphql/query/arguments.rb +0 -189
- data/lib/graphql/query/arguments_cache.rb +0 -24
- data/lib/graphql/query/executor.rb +0 -52
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -40
- data/lib/graphql/relay/array_connection.rb +0 -83
- data/lib/graphql/relay/base_connection.rb +0 -189
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -54
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -39
- data/lib/graphql/relay/global_id_resolve.rb +0 -17
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -106
- data/lib/graphql/relay/node.rb +0 -39
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -188
- data/lib/graphql/relay/type_extensions.rb +0 -32
- data/lib/graphql/scalar_type.rb +0 -91
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -17
- data/lib/graphql/schema/member/accepts_definition.rb +0 -164
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
- data/lib/graphql/schema/member/instrumentation.rb +0 -131
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -44
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -88
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -313
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -76
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/node_field.rb +0 -24
- data/lib/graphql/types/relay/nodes_field.rb +0 -43
- data/lib/graphql/union_type.rb +0 -115
- data/lib/graphql/upgrader/member.rb +0 -937
- data/lib/graphql/upgrader/schema.rb +0 -38
@@ -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")]
|
17
|
+
field :fields, [GraphQL::Schema::LateBoundType.new("__Field")] 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")]
|
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
|
23
23
|
argument :include_deprecated, Boolean, required: false, default_value: false
|
24
24
|
end
|
25
|
-
field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")]
|
25
|
+
field :input_fields, [GraphQL::Schema::LateBoundType.new("__InputValue")] 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")
|
@@ -321,23 +321,6 @@ module GraphQL
|
|
321
321
|
end
|
322
322
|
end
|
323
323
|
|
324
|
-
# This is just for printing legacy `.define { ... }` schemas, where `deprecation_reason` isn't added to `.directives`.
|
325
|
-
if !member.respond_to?(:directives) && member.respond_to?(:deprecation_reason) && (reason = member.deprecation_reason)
|
326
|
-
arguments = []
|
327
|
-
|
328
|
-
if reason != GraphQL::Schema::Directive::DEFAULT_DEPRECATION_REASON
|
329
|
-
arguments << GraphQL::Language::Nodes::Argument.new(
|
330
|
-
name: "reason",
|
331
|
-
value: reason
|
332
|
-
)
|
333
|
-
end
|
334
|
-
|
335
|
-
dirs << GraphQL::Language::Nodes::Directive.new(
|
336
|
-
name: GraphQL::Directive::DeprecatedDirective.graphql_name,
|
337
|
-
arguments: arguments
|
338
|
-
)
|
339
|
-
end
|
340
|
-
|
341
324
|
dirs
|
342
325
|
end
|
343
326
|
|
@@ -21,13 +21,6 @@ module GraphQL
|
|
21
21
|
class ImplementationMissingError < GraphQL::Error
|
22
22
|
end
|
23
23
|
|
24
|
-
def self.use(schema_defn)
|
25
|
-
if schema_defn.plugins.any? { |(plugin, args)| plugin == self }
|
26
|
-
GraphQL::Deprecation.warn("#{self} is now the default, remove `use #{self}` from #{caller(2,1).first}")
|
27
|
-
end
|
28
|
-
schema_defn.connections = self.new(schema: schema_defn)
|
29
|
-
end
|
30
|
-
|
31
24
|
def initialize(schema:)
|
32
25
|
@schema = schema
|
33
26
|
@wrappers = {}
|
@@ -85,26 +78,7 @@ module GraphQL
|
|
85
78
|
edge_class: edge_class_for_field(field),
|
86
79
|
)
|
87
80
|
else
|
88
|
-
|
89
|
-
connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(items)
|
90
|
-
if parent.is_a?(GraphQL::Schema::Object)
|
91
|
-
parent = parent.object
|
92
|
-
end
|
93
|
-
connection_class.new(
|
94
|
-
items,
|
95
|
-
arguments,
|
96
|
-
field: field,
|
97
|
-
max_page_size: field.max_page_size,
|
98
|
-
parent: parent,
|
99
|
-
context: context,
|
100
|
-
)
|
101
|
-
rescue RuntimeError => err
|
102
|
-
if err.message.include?("No connection implementation to wrap")
|
103
|
-
raise ImplementationMissingError, "Couldn't find a connection wrapper for #{items.class} during #{field.path} (#{items.inspect})"
|
104
|
-
else
|
105
|
-
raise err
|
106
|
-
end
|
107
|
-
end
|
81
|
+
raise ImplementationMissingError, "Couldn't find a connection wrapper for #{items.class} during #{field.path} (#{items.inspect})"
|
108
82
|
end
|
109
83
|
end
|
110
84
|
|
@@ -113,7 +87,7 @@ module GraphQL
|
|
113
87
|
def edge_class_for_field(field)
|
114
88
|
conn_type = field.type.unwrap
|
115
89
|
conn_type_edge_type = conn_type.respond_to?(:edge_class) && conn_type.edge_class
|
116
|
-
if conn_type_edge_type && conn_type_edge_type !=
|
90
|
+
if conn_type_edge_type && conn_type_edge_type != Pagination::Connection::Edge
|
117
91
|
conn_type_edge_type
|
118
92
|
else
|
119
93
|
nil
|
@@ -5,49 +5,10 @@ module GraphQL
|
|
5
5
|
# It delegates `[]` to the hash that's passed to `GraphQL::Query#initialize`.
|
6
6
|
class Context
|
7
7
|
module SharedMethods
|
8
|
-
# @return [Object] The target for field resolution
|
9
|
-
attr_accessor :object
|
10
|
-
|
11
|
-
# @return [Hash, Array, String, Integer, Float, Boolean, nil] The resolved value for this field
|
12
|
-
attr_reader :value
|
13
|
-
|
14
|
-
# @return [Boolean] were any fields of this selection skipped?
|
15
|
-
attr_reader :skipped
|
16
|
-
alias :skipped? :skipped
|
17
|
-
|
18
|
-
# @api private
|
19
|
-
attr_writer :skipped
|
20
|
-
|
21
8
|
# Return this value to tell the runtime
|
22
9
|
# to exclude this field from the response altogether
|
23
10
|
def skip
|
24
|
-
GraphQL::Execution::
|
25
|
-
end
|
26
|
-
|
27
|
-
# @return [Boolean] True if this selection has been nullified by a null child
|
28
|
-
def invalid_null?
|
29
|
-
@invalid_null
|
30
|
-
end
|
31
|
-
|
32
|
-
# Remove this child from the result value
|
33
|
-
# (used for null propagation and skip)
|
34
|
-
# @api private
|
35
|
-
def delete_child(child_ctx)
|
36
|
-
@value.delete(child_ctx.key)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Create a child context to use for `key`
|
40
|
-
# @param key [String, Integer] The key in the response (name or index)
|
41
|
-
# @param irep_node [InternalRepresentation::Node] The node being evaluated
|
42
|
-
# @api private
|
43
|
-
def spawn_child(key:, irep_node:, object:)
|
44
|
-
FieldResolutionContext.new(
|
45
|
-
@context,
|
46
|
-
key,
|
47
|
-
irep_node,
|
48
|
-
self,
|
49
|
-
object
|
50
|
-
)
|
11
|
+
GraphQL::Execution::SKIP
|
51
12
|
end
|
52
13
|
|
53
14
|
# Add error at query-level.
|
@@ -72,12 +33,6 @@ module GraphQL
|
|
72
33
|
def execution_errors
|
73
34
|
@execution_errors ||= ExecutionErrors.new(self)
|
74
35
|
end
|
75
|
-
|
76
|
-
def lookahead
|
77
|
-
ast_nodes = irep_node.ast_nodes
|
78
|
-
field = irep_node.definition.metadata[:type_class] || raise("Lookahead is only compatible with class-based schemas")
|
79
|
-
Execution::Lookahead.new(query: query, ast_nodes: ast_nodes, field: field)
|
80
|
-
end
|
81
36
|
end
|
82
37
|
|
83
38
|
class ExecutionErrors
|
@@ -105,27 +60,6 @@ module GraphQL
|
|
105
60
|
include SharedMethods
|
106
61
|
extend Forwardable
|
107
62
|
|
108
|
-
attr_reader :execution_strategy
|
109
|
-
# `strategy` is required by GraphQL::Batch
|
110
|
-
alias_method :strategy, :execution_strategy
|
111
|
-
|
112
|
-
def execution_strategy=(new_strategy)
|
113
|
-
# GraphQL::Batch re-assigns this value but it was previously not used
|
114
|
-
# (ExecutionContext#strategy was used instead)
|
115
|
-
# now it _is_ used, but it breaks GraphQL::Batch tests
|
116
|
-
@execution_strategy ||= new_strategy
|
117
|
-
end
|
118
|
-
|
119
|
-
# @return [GraphQL::InternalRepresentation::Node] The internal representation for this query node
|
120
|
-
def irep_node
|
121
|
-
@irep_node ||= query.irep_selection
|
122
|
-
end
|
123
|
-
|
124
|
-
# @return [GraphQL::Language::Nodes::Field] The AST node for the currently-executing field
|
125
|
-
def ast_node
|
126
|
-
@irep_node.ast_node
|
127
|
-
end
|
128
|
-
|
129
63
|
# @return [Array<GraphQL::ExecutionError>] errors returned during execution
|
130
64
|
attr_reader :errors
|
131
65
|
|
@@ -250,12 +184,6 @@ module GraphQL
|
|
250
184
|
"#<Query::Context ...>"
|
251
185
|
end
|
252
186
|
|
253
|
-
# @api private
|
254
|
-
def received_null_child
|
255
|
-
@invalid_null = true
|
256
|
-
@value = nil
|
257
|
-
end
|
258
|
-
|
259
187
|
def scoped_merge!(hash)
|
260
188
|
@scoped_context = @scoped_context.merge(hash)
|
261
189
|
end
|
@@ -264,118 +192,6 @@ module GraphQL
|
|
264
192
|
scoped_merge!(key => value)
|
265
193
|
nil
|
266
194
|
end
|
267
|
-
|
268
|
-
class FieldResolutionContext
|
269
|
-
include SharedMethods
|
270
|
-
include Tracing::Traceable
|
271
|
-
extend Forwardable
|
272
|
-
|
273
|
-
attr_reader :irep_node, :field, :parent_type, :query, :schema, :parent, :key, :type
|
274
|
-
alias :selection :irep_node
|
275
|
-
|
276
|
-
def initialize(context, key, irep_node, parent, object)
|
277
|
-
@context = context
|
278
|
-
@key = key
|
279
|
-
@parent = parent
|
280
|
-
@object = object
|
281
|
-
@irep_node = irep_node
|
282
|
-
@field = irep_node.definition
|
283
|
-
@parent_type = irep_node.owner_type
|
284
|
-
@type = field.type
|
285
|
-
# This is needed constantly, so set it ahead of time:
|
286
|
-
@query = context.query
|
287
|
-
@schema = context.schema
|
288
|
-
@tracers = @query.tracers
|
289
|
-
# This hack flag is required by ConnectionResolve
|
290
|
-
@wrapped_connection = false
|
291
|
-
@wrapped_object = false
|
292
|
-
end
|
293
|
-
|
294
|
-
# @api private
|
295
|
-
attr_accessor :wrapped_connection, :wrapped_object
|
296
|
-
|
297
|
-
def path
|
298
|
-
@path ||= @parent.path.dup << @key
|
299
|
-
end
|
300
|
-
|
301
|
-
def_delegators :@context,
|
302
|
-
:[], :[]=, :key?, :fetch, :to_h, :namespace, :dig,
|
303
|
-
:spawn, :warden, :errors,
|
304
|
-
:execution_strategy, :strategy, :interpreter?
|
305
|
-
|
306
|
-
# @return [GraphQL::Language::Nodes::Field] The AST node for the currently-executing field
|
307
|
-
def ast_node
|
308
|
-
@irep_node.ast_node
|
309
|
-
end
|
310
|
-
|
311
|
-
# Add error to current field resolution.
|
312
|
-
# @param error [GraphQL::ExecutionError] an execution error
|
313
|
-
# @return [void]
|
314
|
-
def add_error(error)
|
315
|
-
super
|
316
|
-
error.ast_node ||= irep_node.ast_node
|
317
|
-
error.path ||= path
|
318
|
-
nil
|
319
|
-
end
|
320
|
-
|
321
|
-
def inspect
|
322
|
-
"#<GraphQL Context @ #{irep_node.owner_type.name}.#{field.name}>"
|
323
|
-
end
|
324
|
-
|
325
|
-
# Set a new value for this field in the response.
|
326
|
-
# It may be updated after resolving a {Lazy}.
|
327
|
-
# If it is {Execute::PROPAGATE_NULL}, tell the owner to propagate null.
|
328
|
-
# If it's {Execute::Execution::SKIP}, remove this field result from its parent
|
329
|
-
# @param new_value [Any] The GraphQL-ready value
|
330
|
-
# @api private
|
331
|
-
def value=(new_value)
|
332
|
-
case new_value
|
333
|
-
when GraphQL::Execution::Execute::PROPAGATE_NULL, nil
|
334
|
-
@invalid_null = true
|
335
|
-
@value = nil
|
336
|
-
if @type.kind.non_null?
|
337
|
-
@parent.received_null_child
|
338
|
-
end
|
339
|
-
when GraphQL::Execution::Execute::SKIP
|
340
|
-
@parent.skipped = true
|
341
|
-
@parent.delete_child(self)
|
342
|
-
else
|
343
|
-
@value = new_value
|
344
|
-
end
|
345
|
-
end
|
346
|
-
|
347
|
-
protected
|
348
|
-
|
349
|
-
def received_null_child
|
350
|
-
case @value
|
351
|
-
when Hash
|
352
|
-
self.value = GraphQL::Execution::Execute::PROPAGATE_NULL
|
353
|
-
when Array
|
354
|
-
if list_of_non_null_items?(@type)
|
355
|
-
self.value = GraphQL::Execution::Execute::PROPAGATE_NULL
|
356
|
-
end
|
357
|
-
when nil
|
358
|
-
# TODO This is a hack
|
359
|
-
# It was already nulled out but it's getting reassigned
|
360
|
-
else
|
361
|
-
raise "Unexpected value for received_null_child (#{self.value.class}): #{value}"
|
362
|
-
end
|
363
|
-
end
|
364
|
-
|
365
|
-
private
|
366
|
-
|
367
|
-
def list_of_non_null_items?(type)
|
368
|
-
case type
|
369
|
-
when GraphQL::NonNullType
|
370
|
-
# Unwrap [T]!
|
371
|
-
list_of_non_null_items?(type.of_type)
|
372
|
-
when GraphQL::ListType
|
373
|
-
type.of_type.is_a?(GraphQL::NonNullType)
|
374
|
-
else
|
375
|
-
raise "Unexpected list_of_non_null_items check: #{type}"
|
376
|
-
end
|
377
|
-
end
|
378
|
-
end
|
379
195
|
end
|
380
196
|
end
|
381
197
|
end
|
@@ -4,12 +4,6 @@ module GraphQL
|
|
4
4
|
class InputValidationResult
|
5
5
|
attr_accessor :problems
|
6
6
|
|
7
|
-
def self.from_problem(explanation, path = nil, extensions: nil, message: nil)
|
8
|
-
result = self.new
|
9
|
-
result.add_problem(explanation, path, extensions: extensions, message: message)
|
10
|
-
result
|
11
|
-
end
|
12
|
-
|
13
7
|
def initialize(valid: true, problems: nil)
|
14
8
|
@valid = valid
|
15
9
|
@problems = problems
|
@@ -44,9 +38,6 @@ module GraphQL
|
|
44
38
|
# It could have been explicitly set on inner_result (if it had no problems)
|
45
39
|
@valid = false
|
46
40
|
end
|
47
|
-
|
48
|
-
VALID = self.new
|
49
|
-
VALID.freeze
|
50
41
|
end
|
51
42
|
end
|
52
43
|
end
|
@@ -115,20 +115,15 @@ module GraphQL
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
argument_owner.new(ruby_kwargs: ruby_kwargs, context: context, defaults_used: defaults_used)
|
126
|
-
else
|
127
|
-
ruby_kwargs
|
128
|
-
end
|
118
|
+
# A Schema::InputObject, Schema::GraphQL::Field, Schema::Directive, logic from Interpreter::Arguments
|
119
|
+
ruby_kwargs = {}
|
120
|
+
values_hash.each do |key, value|
|
121
|
+
ruby_kwargs[Schema::Member::BuildType.underscore(key).to_sym] = value
|
122
|
+
end
|
123
|
+
if argument_owner.is_a?(Class) && argument_owner < GraphQL::Schema::InputObject
|
124
|
+
argument_owner.new(ruby_kwargs: ruby_kwargs, context: context, defaults_used: defaults_used)
|
129
125
|
else
|
130
|
-
|
131
|
-
result.prepare
|
126
|
+
ruby_kwargs
|
132
127
|
end
|
133
128
|
end
|
134
129
|
end
|
@@ -18,7 +18,6 @@ module GraphQL
|
|
18
18
|
|
19
19
|
def initialize(query:, parse_error:, operation_name_error:, max_depth:, max_complexity:)
|
20
20
|
@validation_errors = []
|
21
|
-
@internal_representation = nil
|
22
21
|
@parse_error = parse_error
|
23
22
|
@operation_name_error = operation_name_error
|
24
23
|
@query = query
|
@@ -41,12 +40,6 @@ module GraphQL
|
|
41
40
|
@validation_errors
|
42
41
|
end
|
43
42
|
|
44
|
-
# @return [Hash<String, nil => GraphQL::InternalRepresentation::Node] Operation name -> Irep node pairs
|
45
|
-
def internal_representation
|
46
|
-
ensure_has_validated
|
47
|
-
@internal_representation
|
48
|
-
end
|
49
|
-
|
50
43
|
def analyzers
|
51
44
|
ensure_has_validated
|
52
45
|
@query_analyzers
|
@@ -62,7 +55,7 @@ module GraphQL
|
|
62
55
|
|
63
56
|
if @parse_error
|
64
57
|
# This is kind of crazy: we push the parse error into `ctx`
|
65
|
-
# in
|
58
|
+
# in `def self.parse_error` by default so that users can _opt out_ by redefining that hook.
|
66
59
|
# That means we can't _re-add_ the error here (otherwise we'd either
|
67
60
|
# add it twice _or_ override the user's choice to not add it).
|
68
61
|
# So we just have to know that it was invalid and go from there.
|
@@ -73,7 +66,6 @@ module GraphQL
|
|
73
66
|
else
|
74
67
|
validation_result = @schema.static_validator.validate(@query, validate: @query.validate, timeout: @schema.validate_timeout, max_errors: @schema.validate_max_errors)
|
75
68
|
@validation_errors.concat(validation_result[:errors])
|
76
|
-
@internal_representation = validation_result[:irep]
|
77
69
|
|
78
70
|
if @validation_errors.empty?
|
79
71
|
@validation_errors.concat(@query.variables.errors)
|
@@ -99,35 +91,15 @@ module GraphQL
|
|
99
91
|
def build_analyzers(schema, max_depth, max_complexity)
|
100
92
|
qa = schema.query_analyzers.dup
|
101
93
|
|
102
|
-
# Filter out the built in authorization analyzer.
|
103
|
-
# It is deprecated and does not have an AST analyzer alternative.
|
104
|
-
qa = qa.select do |analyzer|
|
105
|
-
if analyzer == GraphQL::Authorization::Analyzer && schema.using_ast_analysis?
|
106
|
-
raise "The Authorization analyzer is not supported with AST Analyzers"
|
107
|
-
else
|
108
|
-
true
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
94
|
if max_depth || max_complexity
|
113
95
|
# Depending on the analysis engine, we must use different analyzers
|
114
96
|
# remove this once everything has switched over to AST analyzers
|
115
|
-
if
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
qa << GraphQL::Analysis::AST::MaxQueryComplexity
|
121
|
-
end
|
122
|
-
else
|
123
|
-
if max_depth
|
124
|
-
qa << GraphQL::Analysis::MaxQueryDepth.new(max_depth)
|
125
|
-
end
|
126
|
-
if max_complexity
|
127
|
-
qa << GraphQL::Analysis::MaxQueryComplexity.new(max_complexity)
|
128
|
-
end
|
97
|
+
if max_depth
|
98
|
+
qa << GraphQL::Analysis::AST::MaxQueryDepth
|
99
|
+
end
|
100
|
+
if max_complexity
|
101
|
+
qa << GraphQL::Analysis::AST::MaxQueryComplexity
|
129
102
|
end
|
130
|
-
|
131
103
|
qa
|
132
104
|
else
|
133
105
|
qa
|
@@ -4,11 +4,11 @@ module GraphQL
|
|
4
4
|
class VariableValidationError < GraphQL::ExecutionError
|
5
5
|
attr_accessor :value, :validation_result
|
6
6
|
|
7
|
-
def initialize(variable_ast, type, value, validation_result
|
7
|
+
def initialize(variable_ast, type, value, validation_result)
|
8
8
|
@value = value
|
9
9
|
@validation_result = validation_result
|
10
10
|
|
11
|
-
msg
|
11
|
+
msg = "Variable $#{variable_ast.name} of type #{type.to_type_signature} was provided invalid value"
|
12
12
|
|
13
13
|
if problem_fields.any?
|
14
14
|
msg += " for #{problem_fields.join(", ")}"
|
@@ -14,13 +14,9 @@ module GraphQL
|
|
14
14
|
schema = ctx.schema
|
15
15
|
@context = ctx
|
16
16
|
|
17
|
-
@provided_variables =
|
17
|
+
@provided_variables = deep_stringify(provided_variables)
|
18
18
|
@errors = []
|
19
19
|
@storage = ast_variables.each_with_object({}) do |ast_variable, memo|
|
20
|
-
if schema.validate_max_errors && schema.validate_max_errors <= @errors.count
|
21
|
-
add_max_errors_reached_message
|
22
|
-
break
|
23
|
-
end
|
24
20
|
# Find the right value for this variable:
|
25
21
|
# - First, use the value provided at runtime
|
26
22
|
# - Then, fall back to the default value from the query string
|
@@ -33,31 +29,17 @@ module GraphQL
|
|
33
29
|
default_value = ast_variable.default_value
|
34
30
|
provided_value = @provided_variables[variable_name]
|
35
31
|
value_was_provided = @provided_variables.key?(variable_name)
|
36
|
-
max_errors = schema.validate_max_errors - @errors.count if schema.validate_max_errors
|
37
32
|
begin
|
38
|
-
validation_result = variable_type.validate_input(provided_value, ctx
|
33
|
+
validation_result = variable_type.validate_input(provided_value, ctx)
|
39
34
|
if validation_result.valid?
|
40
35
|
if value_was_provided
|
41
36
|
# Add the variable if a value was provided
|
42
|
-
memo[variable_name] =
|
43
|
-
provided_value
|
44
|
-
elsif provided_value.nil?
|
45
|
-
nil
|
46
|
-
else
|
47
|
-
schema.error_handler.with_error_handling(context) do
|
48
|
-
variable_type.coerce_input(provided_value, ctx)
|
49
|
-
end
|
50
|
-
end
|
37
|
+
memo[variable_name] = provided_value
|
51
38
|
elsif default_value != nil
|
52
|
-
memo[variable_name] = if
|
53
|
-
|
54
|
-
nil
|
55
|
-
else
|
56
|
-
default_value
|
57
|
-
end
|
39
|
+
memo[variable_name] = if default_value.is_a?(Language::Nodes::NullValue)
|
40
|
+
nil
|
58
41
|
else
|
59
|
-
|
60
|
-
GraphQL::Query::LiteralInput.coerce(variable_type, default_value, self)
|
42
|
+
default_value
|
61
43
|
end
|
62
44
|
end
|
63
45
|
end
|
@@ -66,7 +48,8 @@ module GraphQL
|
|
66
48
|
# like InputValidationResults generated by validate_non_null_input but unfortunately we don't
|
67
49
|
# have this information available in the coerce_input call chain. Note this path is the path
|
68
50
|
# that appears under errors.extensions.problems.path and NOT the result path under errors.path.
|
69
|
-
validation_result = GraphQL::Query::InputValidationResult.
|
51
|
+
validation_result = GraphQL::Query::InputValidationResult.new
|
52
|
+
validation_result.add_problem(ex.message)
|
70
53
|
end
|
71
54
|
|
72
55
|
if !validation_result.valid?
|
@@ -94,12 +77,6 @@ module GraphQL
|
|
94
77
|
val
|
95
78
|
end
|
96
79
|
end
|
97
|
-
|
98
|
-
def add_max_errors_reached_message
|
99
|
-
message = "Too many errors processing variables, max validation error limit reached. Execution aborted"
|
100
|
-
validation_result = GraphQL::Query::InputValidationResult.from_problem(message)
|
101
|
-
errors << GraphQL::Query::VariableValidationError.new(nil, nil, nil, validation_result, msg: message)
|
102
|
-
end
|
103
80
|
end
|
104
81
|
end
|
105
82
|
end
|
data/lib/graphql/query.rb
CHANGED
@@ -1,13 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require "graphql/query/arguments"
|
3
|
-
require "graphql/query/arguments_cache"
|
4
2
|
require "graphql/query/context"
|
5
|
-
require "graphql/query/executor"
|
6
3
|
require "graphql/query/fingerprint"
|
7
4
|
require "graphql/query/literal_input"
|
8
5
|
require "graphql/query/null_context"
|
9
6
|
require "graphql/query/result"
|
10
|
-
require "graphql/query/serial_execution"
|
11
7
|
require "graphql/query/variables"
|
12
8
|
require "graphql/query/input_validation_result"
|
13
9
|
require "graphql/query/variable_validation_error"
|
@@ -82,13 +78,7 @@ module GraphQL
|
|
82
78
|
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, except: nil, only: nil, warden: nil)
|
83
79
|
# Even if `variables: nil` is passed, use an empty hash for simpler logic
|
84
80
|
variables ||= {}
|
85
|
-
|
86
|
-
# Use the `.graphql_definition` here which will return legacy types instead of classes
|
87
|
-
if schema.is_a?(Class) && !schema.interpreter?
|
88
|
-
schema = schema.graphql_definition
|
89
|
-
end
|
90
81
|
@schema = schema
|
91
|
-
@interpreter = @schema.interpreter?
|
92
82
|
@filter = schema.default_filter.merge(except: except, only: only)
|
93
83
|
@context = schema.context_class.new(query: self, object: root_value, values: context)
|
94
84
|
@warden = warden
|
@@ -154,7 +144,7 @@ module GraphQL
|
|
154
144
|
end
|
155
145
|
|
156
146
|
def interpreter?
|
157
|
-
|
147
|
+
true
|
158
148
|
end
|
159
149
|
|
160
150
|
attr_accessor :multiplex
|
@@ -169,7 +159,6 @@ module GraphQL
|
|
169
159
|
@lookahead ||= begin
|
170
160
|
ast_node = selected_operation
|
171
161
|
root_type = warden.root_type_for_operation(ast_node.operation_type || "query")
|
172
|
-
root_type = root_type.type_class || raise("Invariant: `lookahead` only works with class-based types")
|
173
162
|
GraphQL::Execution::Lookahead.new(query: self, root_type: root_type, ast_nodes: [ast_node])
|
174
163
|
end
|
175
164
|
end
|
@@ -199,7 +188,7 @@ module GraphQL
|
|
199
188
|
# @return [Hash] A GraphQL response, with `"data"` and/or `"errors"` keys
|
200
189
|
def result
|
201
190
|
if !@executed
|
202
|
-
Execution::Multiplex.
|
191
|
+
Execution::Multiplex.run_all(@schema, [self], context: @context)
|
203
192
|
end
|
204
193
|
@result ||= Query::Result.new(query: self, values: @result_values)
|
205
194
|
end
|
@@ -237,35 +226,17 @@ module GraphQL
|
|
237
226
|
end
|
238
227
|
end
|
239
228
|
|
240
|
-
def irep_selection
|
241
|
-
@selection ||= begin
|
242
|
-
if selected_operation && internal_representation
|
243
|
-
internal_representation.operation_definitions[selected_operation.name]
|
244
|
-
else
|
245
|
-
nil
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
229
|
# Node-level cache for calculating arguments. Used during execution and query analysis.
|
251
230
|
# @param ast_node [GraphQL::Language::Nodes::AbstractNode]
|
252
231
|
# @param definition [GraphQL::Schema::Field]
|
253
232
|
# @param parent_object [GraphQL::Schema::Object]
|
254
233
|
# @return Hash{Symbol => Object}
|
255
234
|
def arguments_for(ast_node, definition, parent_object: nil)
|
256
|
-
|
257
|
-
arguments_cache.fetch(ast_node, definition, parent_object)
|
258
|
-
else
|
259
|
-
arguments_cache[ast_node][definition]
|
260
|
-
end
|
235
|
+
arguments_cache.fetch(ast_node, definition, parent_object)
|
261
236
|
end
|
262
237
|
|
263
238
|
def arguments_cache
|
264
|
-
|
265
|
-
@arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
|
266
|
-
else
|
267
|
-
@arguments_cache ||= ArgumentsCache.build(self)
|
268
|
-
end
|
239
|
+
@arguments_cache ||= Execution::Interpreter::ArgumentsCache.new(self)
|
269
240
|
end
|
270
241
|
|
271
242
|
# A version of the given query string, with:
|
@@ -308,7 +279,7 @@ module GraphQL
|
|
308
279
|
with_prepared_ast { @validation_pipeline }
|
309
280
|
end
|
310
281
|
|
311
|
-
def_delegators :validation_pipeline, :validation_errors,
|
282
|
+
def_delegators :validation_pipeline, :validation_errors,
|
312
283
|
:analyzers, :ast_analyzers, :max_depth, :max_complexity
|
313
284
|
|
314
285
|
attr_accessor :analysis_errors
|