graphql 1.13.25 → 2.0.0
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/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/language/nodes.rb +0 -3
- data/lib/graphql/pagination/connections.rb +2 -28
- data/lib/graphql/pagination/relation_connection.rb +0 -2
- 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 +6 -28
- data/lib/graphql/schema/build_from_definition.rb +7 -9
- data/lib/graphql/schema/directive.rb +1 -22
- data/lib/graphql/schema/enum.rb +3 -19
- data/lib/graphql/schema/enum_value.rb +1 -23
- data/lib/graphql/schema/field.rb +22 -221
- data/lib/graphql/schema/input_object.rb +17 -65
- 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 -164
- 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
data/lib/graphql/directive.rb
DELETED
@@ -1,107 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
# Directives are server-defined hooks for modifying execution.
|
4
|
-
#
|
5
|
-
# Two directives are included out-of-the-box:
|
6
|
-
# - `@skip(if: ...)` Skips the tagged field if the value of `if` is true
|
7
|
-
# - `@include(if: ...)` Includes the tagged field _only_ if `if` is true
|
8
|
-
#
|
9
|
-
class Directive
|
10
|
-
include GraphQL::Define::InstanceDefinable
|
11
|
-
deprecated_accepts_definitions :locations, :name, :description, :arguments, :default_directive, argument: GraphQL::Define::AssignArgument
|
12
|
-
|
13
|
-
attr_accessor :locations, :arguments, :name, :description, :arguments_class
|
14
|
-
attr_accessor :ast_node
|
15
|
-
# @api private
|
16
|
-
attr_writer :default_directive
|
17
|
-
ensure_defined(:locations, :arguments, :graphql_name, :name, :description, :default_directive?)
|
18
|
-
|
19
|
-
# Future-compatible alias
|
20
|
-
# @see {GraphQL::SchemaMember}
|
21
|
-
alias :graphql_name :name
|
22
|
-
|
23
|
-
# Future-compatible alias
|
24
|
-
# @see {GraphQL::SchemaMember}
|
25
|
-
alias :graphql_definition :itself
|
26
|
-
|
27
|
-
LOCATIONS = [
|
28
|
-
QUERY = :QUERY,
|
29
|
-
MUTATION = :MUTATION,
|
30
|
-
SUBSCRIPTION = :SUBSCRIPTION,
|
31
|
-
FIELD = :FIELD,
|
32
|
-
FRAGMENT_DEFINITION = :FRAGMENT_DEFINITION,
|
33
|
-
FRAGMENT_SPREAD = :FRAGMENT_SPREAD,
|
34
|
-
INLINE_FRAGMENT = :INLINE_FRAGMENT,
|
35
|
-
SCHEMA = :SCHEMA,
|
36
|
-
SCALAR = :SCALAR,
|
37
|
-
OBJECT = :OBJECT,
|
38
|
-
FIELD_DEFINITION = :FIELD_DEFINITION,
|
39
|
-
ARGUMENT_DEFINITION = :ARGUMENT_DEFINITION,
|
40
|
-
INTERFACE = :INTERFACE,
|
41
|
-
UNION = :UNION,
|
42
|
-
ENUM = :ENUM,
|
43
|
-
ENUM_VALUE = :ENUM_VALUE,
|
44
|
-
INPUT_OBJECT = :INPUT_OBJECT,
|
45
|
-
INPUT_FIELD_DEFINITION = :INPUT_FIELD_DEFINITION,
|
46
|
-
]
|
47
|
-
|
48
|
-
LOCATION_DESCRIPTIONS = {
|
49
|
-
QUERY: 'Location adjacent to a query operation.',
|
50
|
-
MUTATION: 'Location adjacent to a mutation operation.',
|
51
|
-
SUBSCRIPTION: 'Location adjacent to a subscription operation.',
|
52
|
-
FIELD: 'Location adjacent to a field.',
|
53
|
-
FRAGMENT_DEFINITION: 'Location adjacent to a fragment definition.',
|
54
|
-
FRAGMENT_SPREAD: 'Location adjacent to a fragment spread.',
|
55
|
-
INLINE_FRAGMENT: 'Location adjacent to an inline fragment.',
|
56
|
-
SCHEMA: 'Location adjacent to a schema definition.',
|
57
|
-
SCALAR: 'Location adjacent to a scalar definition.',
|
58
|
-
OBJECT: 'Location adjacent to an object type definition.',
|
59
|
-
FIELD_DEFINITION: 'Location adjacent to a field definition.',
|
60
|
-
ARGUMENT_DEFINITION: 'Location adjacent to an argument definition.',
|
61
|
-
INTERFACE: 'Location adjacent to an interface definition.',
|
62
|
-
UNION: 'Location adjacent to a union definition.',
|
63
|
-
ENUM: 'Location adjacent to an enum definition.',
|
64
|
-
ENUM_VALUE: 'Location adjacent to an enum value definition.',
|
65
|
-
INPUT_OBJECT: 'Location adjacent to an input object type definition.',
|
66
|
-
INPUT_FIELD_DEFINITION: 'Location adjacent to an input object field definition.',
|
67
|
-
}
|
68
|
-
|
69
|
-
def initialize
|
70
|
-
@arguments = {}
|
71
|
-
@default_directive = false
|
72
|
-
end
|
73
|
-
|
74
|
-
def to_s
|
75
|
-
"<GraphQL::Directive #{name}>"
|
76
|
-
end
|
77
|
-
|
78
|
-
def on_field?
|
79
|
-
locations.include?(FIELD)
|
80
|
-
end
|
81
|
-
|
82
|
-
def on_fragment?
|
83
|
-
locations.include?(FRAGMENT_SPREAD) && locations.include?(INLINE_FRAGMENT)
|
84
|
-
end
|
85
|
-
|
86
|
-
def on_operation?
|
87
|
-
locations.include?(QUERY) && locations.include?(MUTATION) && locations.include?(SUBSCRIPTION)
|
88
|
-
end
|
89
|
-
|
90
|
-
# @return [Boolean] Is this directive supplied by default? (eg `@skip`)
|
91
|
-
def default_directive?
|
92
|
-
@default_directive
|
93
|
-
end
|
94
|
-
|
95
|
-
def inspect
|
96
|
-
"#<GraphQL::Directive #{name}>"
|
97
|
-
end
|
98
|
-
|
99
|
-
def type_class
|
100
|
-
metadata[:type_class]
|
101
|
-
end
|
102
|
-
|
103
|
-
def get_argument(argument_name)
|
104
|
-
arguments[argument_name]
|
105
|
-
end
|
106
|
-
end
|
107
|
-
end
|
data/lib/graphql/enum_type.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
# @api deprecated
|
4
|
-
class EnumType < GraphQL::BaseType
|
5
|
-
extend Define::InstanceDefinable::DeprecatedDefine
|
6
|
-
|
7
|
-
deprecated_accepts_definitions :values, value: GraphQL::Define::AssignEnumValue
|
8
|
-
ensure_defined(:values, :validate_non_null_input, :coerce_non_null_input, :coerce_result)
|
9
|
-
attr_accessor :ast_node
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
super
|
13
|
-
@values_by_name = {}
|
14
|
-
end
|
15
|
-
|
16
|
-
def initialize_copy(other)
|
17
|
-
super
|
18
|
-
self.values = other.values.values
|
19
|
-
end
|
20
|
-
|
21
|
-
# @param new_values [Array<EnumValue>] The set of values contained in this type
|
22
|
-
def values=(new_values)
|
23
|
-
@values_by_name = {}
|
24
|
-
new_values.each { |enum_value| add_value(enum_value) }
|
25
|
-
end
|
26
|
-
|
27
|
-
# @param enum_value [EnumValue] A value to add to this type's set of values
|
28
|
-
def add_value(enum_value)
|
29
|
-
if @values_by_name.key?(enum_value.name)
|
30
|
-
raise "Enum value names must be unique. Value `#{enum_value.name}` already exists on Enum `#{name}`."
|
31
|
-
end
|
32
|
-
|
33
|
-
@values_by_name[enum_value.name] = enum_value
|
34
|
-
end
|
35
|
-
|
36
|
-
# @return [Hash<String => EnumValue>] `{name => value}` pairs contained in this type
|
37
|
-
def values(_context = nil)
|
38
|
-
@values_by_name
|
39
|
-
end
|
40
|
-
|
41
|
-
def enum_values(_context = nil)
|
42
|
-
values.values
|
43
|
-
end
|
44
|
-
|
45
|
-
def kind
|
46
|
-
GraphQL::TypeKinds::ENUM
|
47
|
-
end
|
48
|
-
|
49
|
-
def coerce_result(value, ctx = nil)
|
50
|
-
if ctx.nil?
|
51
|
-
warn_deprecated_coerce("coerce_isolated_result")
|
52
|
-
ctx = GraphQL::Query::NullContext
|
53
|
-
end
|
54
|
-
|
55
|
-
warden = ctx.warden
|
56
|
-
all_values = warden ? warden.enum_values(self) : @values_by_name.each_value
|
57
|
-
enum_value = all_values.find { |val| val.value == value }
|
58
|
-
if enum_value
|
59
|
-
enum_value.name
|
60
|
-
else
|
61
|
-
raise(UnresolvedValueError, "Can't resolve enum #{name} for #{value.inspect}")
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def to_s
|
66
|
-
name
|
67
|
-
end
|
68
|
-
|
69
|
-
# A value within an {EnumType}
|
70
|
-
#
|
71
|
-
# Created with the `value` helper
|
72
|
-
class EnumValue
|
73
|
-
include GraphQL::Define::InstanceDefinable
|
74
|
-
ATTRIBUTES = [:name, :description, :deprecation_reason, :value]
|
75
|
-
deprecated_accepts_definitions(*ATTRIBUTES)
|
76
|
-
attr_accessor(*ATTRIBUTES)
|
77
|
-
attr_accessor :ast_node
|
78
|
-
ensure_defined(*ATTRIBUTES)
|
79
|
-
|
80
|
-
undef name=
|
81
|
-
def name=(new_name)
|
82
|
-
# Validate that the name is correct
|
83
|
-
GraphQL::NameValidator.validate!(new_name)
|
84
|
-
@name = new_name
|
85
|
-
end
|
86
|
-
|
87
|
-
def graphql_name
|
88
|
-
name
|
89
|
-
end
|
90
|
-
|
91
|
-
def type_class
|
92
|
-
metadata[:type_class]
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
class UnresolvedValueError < GraphQL::Error
|
97
|
-
end
|
98
|
-
|
99
|
-
private
|
100
|
-
|
101
|
-
# Get the underlying value for this enum value
|
102
|
-
#
|
103
|
-
# @example get episode value from Enum
|
104
|
-
# episode = EpisodeEnum.coerce("NEWHOPE")
|
105
|
-
# episode # => 6
|
106
|
-
#
|
107
|
-
# @param value_name [String] the string representation of this enum value
|
108
|
-
# @return [Object] the underlying value for this enum value
|
109
|
-
def coerce_non_null_input(value_name, ctx)
|
110
|
-
if @values_by_name.key?(value_name)
|
111
|
-
@values_by_name.fetch(value_name).value
|
112
|
-
elsif match_by_value = @values_by_name.find { |k, v| v.value == value_name }
|
113
|
-
# this is for matching default values, which are "inputs", but they're
|
114
|
-
# the Ruby value, not the GraphQL string.
|
115
|
-
match_by_value[1].value
|
116
|
-
else
|
117
|
-
nil
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
def validate_non_null_input(value_name, ctx)
|
122
|
-
result = GraphQL::Query::InputValidationResult.new
|
123
|
-
allowed_values = ctx.warden.enum_values(self)
|
124
|
-
matching_value = allowed_values.find { |v| v.name == value_name }
|
125
|
-
|
126
|
-
if matching_value.nil?
|
127
|
-
result.add_problem("Expected #{GraphQL::Language.serialize(value_name)} to be one of: #{allowed_values.map(&:name).join(', ')}")
|
128
|
-
end
|
129
|
-
|
130
|
-
result
|
131
|
-
end
|
132
|
-
end
|
133
|
-
end
|
@@ -1,333 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Execution
|
4
|
-
# A valid execution strategy
|
5
|
-
# @api private
|
6
|
-
class Execute
|
7
|
-
|
8
|
-
# @api private
|
9
|
-
class Skip < GraphQL::Error; end
|
10
|
-
|
11
|
-
# Just a singleton for implementing {Query::Context#skip}
|
12
|
-
# @api private
|
13
|
-
SKIP = Skip.new
|
14
|
-
|
15
|
-
# @api private
|
16
|
-
class PropagateNull
|
17
|
-
end
|
18
|
-
# @api private
|
19
|
-
PROPAGATE_NULL = PropagateNull.new
|
20
|
-
|
21
|
-
def self.use(schema_class)
|
22
|
-
schema_class.query_execution_strategy(self)
|
23
|
-
schema_class.mutation_execution_strategy(self)
|
24
|
-
schema_class.subscription_execution_strategy(self)
|
25
|
-
end
|
26
|
-
|
27
|
-
def execute(ast_operation, root_type, query)
|
28
|
-
GraphQL::Deprecation.warn "#{self.class} will be removed in GraphQL-Ruby 2.0, please upgrade to the Interpreter: https://graphql-ruby.org/queries/interpreter.html"
|
29
|
-
result = resolve_root_selection(query)
|
30
|
-
lazy_resolve_root_selection(result, **{query: query})
|
31
|
-
GraphQL::Execution::Flatten.call(query.context)
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.begin_multiplex(_multiplex)
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.begin_query(query, _multiplex)
|
38
|
-
ExecutionFunctions.resolve_root_selection(query)
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.finish_multiplex(results, multiplex)
|
42
|
-
ExecutionFunctions.lazy_resolve_root_selection(results, multiplex: multiplex)
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.finish_query(query, _multiplex)
|
46
|
-
{
|
47
|
-
"data" => Execution::Flatten.call(query.context)
|
48
|
-
}
|
49
|
-
end
|
50
|
-
|
51
|
-
# @api private
|
52
|
-
module ExecutionFunctions
|
53
|
-
module_function
|
54
|
-
|
55
|
-
def resolve_root_selection(query)
|
56
|
-
query.trace("execute_query", query: query) do
|
57
|
-
operation = query.selected_operation
|
58
|
-
op_type = operation.operation_type
|
59
|
-
root_type = query.root_type_for_operation(op_type)
|
60
|
-
if query.context[:__root_unauthorized]
|
61
|
-
# This was set by member/instrumentation.rb so that we wouldn't continue.
|
62
|
-
else
|
63
|
-
resolve_selection(
|
64
|
-
query.root_value,
|
65
|
-
root_type,
|
66
|
-
query.context,
|
67
|
-
mutation: query.mutation?
|
68
|
-
)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def lazy_resolve_root_selection(result, query: nil, multiplex: nil)
|
74
|
-
if query.nil? && multiplex.queries.length == 1
|
75
|
-
query = multiplex.queries[0]
|
76
|
-
end
|
77
|
-
|
78
|
-
tracer = (query || multiplex)
|
79
|
-
tracer.trace("execute_query_lazy", {multiplex: multiplex, query: query}) do
|
80
|
-
GraphQL::Execution::Lazy.resolve(result)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def resolve_selection(object, current_type, current_ctx, mutation: false )
|
85
|
-
# Assign this _before_ resolving the children
|
86
|
-
# so that when a child propagates null, the selection result is
|
87
|
-
# ready for it.
|
88
|
-
current_ctx.value = {}
|
89
|
-
|
90
|
-
selections_on_type = current_ctx.irep_node.typed_children[current_type]
|
91
|
-
|
92
|
-
selections_on_type.each do |name, child_irep_node|
|
93
|
-
field_ctx = current_ctx.spawn_child(
|
94
|
-
key: name,
|
95
|
-
object: object,
|
96
|
-
irep_node: child_irep_node,
|
97
|
-
)
|
98
|
-
|
99
|
-
field_result = resolve_field(
|
100
|
-
object,
|
101
|
-
field_ctx
|
102
|
-
)
|
103
|
-
|
104
|
-
if field_result.is_a?(Skip)
|
105
|
-
next
|
106
|
-
end
|
107
|
-
|
108
|
-
if mutation
|
109
|
-
GraphQL::Execution::Lazy.resolve(field_ctx)
|
110
|
-
end
|
111
|
-
|
112
|
-
|
113
|
-
# If the last subselection caused a null to propagate to _this_ selection,
|
114
|
-
# then we may as well quit executing fields because they
|
115
|
-
# won't be in the response
|
116
|
-
if current_ctx.invalid_null?
|
117
|
-
break
|
118
|
-
else
|
119
|
-
current_ctx.value[name] = field_ctx
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
current_ctx.value
|
124
|
-
end
|
125
|
-
|
126
|
-
def resolve_field(object, field_ctx)
|
127
|
-
query = field_ctx.query
|
128
|
-
irep_node = field_ctx.irep_node
|
129
|
-
parent_type = irep_node.owner_type
|
130
|
-
field = field_ctx.field
|
131
|
-
|
132
|
-
raw_value = begin
|
133
|
-
begin
|
134
|
-
arguments = query.arguments_for(irep_node, field)
|
135
|
-
field_ctx.trace("execute_field", { context: field_ctx }) do
|
136
|
-
field_ctx.schema.middleware.invoke([parent_type, object, field, arguments, field_ctx])
|
137
|
-
end
|
138
|
-
rescue GraphQL::UnauthorizedFieldError => err
|
139
|
-
err.field ||= field
|
140
|
-
field_ctx.schema.unauthorized_field(err)
|
141
|
-
rescue GraphQL::UnauthorizedError => err
|
142
|
-
field_ctx.schema.unauthorized_object(err)
|
143
|
-
end
|
144
|
-
rescue GraphQL::ExecutionError => err
|
145
|
-
err
|
146
|
-
end
|
147
|
-
|
148
|
-
if field_ctx.schema.lazy?(raw_value)
|
149
|
-
field_ctx.value = Execution::Lazy.new {
|
150
|
-
inner_value = field_ctx.trace("execute_field_lazy", {context: field_ctx}) {
|
151
|
-
begin
|
152
|
-
begin
|
153
|
-
field_ctx.field.lazy_resolve(raw_value, arguments, field_ctx)
|
154
|
-
rescue GraphQL::UnauthorizedError => err
|
155
|
-
field_ctx.schema.unauthorized_object(err)
|
156
|
-
end
|
157
|
-
rescue GraphQL::ExecutionError => err
|
158
|
-
err
|
159
|
-
end
|
160
|
-
}
|
161
|
-
continue_or_wait(inner_value, field_ctx.type, field_ctx)
|
162
|
-
}
|
163
|
-
else
|
164
|
-
continue_or_wait(raw_value, field_ctx.type, field_ctx)
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
# If the returned object is lazy (unfinished),
|
169
|
-
# assign the lazy object to `.value=` so we can resolve it later.
|
170
|
-
# When we resolve it later, reassign it to `.value=` so that
|
171
|
-
# the finished value replaces the unfinished one.
|
172
|
-
#
|
173
|
-
# If the returned object is finished, continue to coerce
|
174
|
-
# and resolve child fields
|
175
|
-
def continue_or_wait(raw_value, field_type, field_ctx)
|
176
|
-
if field_ctx.schema.lazy?(raw_value)
|
177
|
-
field_ctx.value = Execution::Lazy.new {
|
178
|
-
inner_value = begin
|
179
|
-
begin
|
180
|
-
field_ctx.schema.sync_lazy(raw_value)
|
181
|
-
rescue GraphQL::UnauthorizedError => err
|
182
|
-
field_ctx.schema.unauthorized_object(err)
|
183
|
-
end
|
184
|
-
rescue GraphQL::ExecutionError => err
|
185
|
-
err
|
186
|
-
end
|
187
|
-
|
188
|
-
field_ctx.value = continue_or_wait(inner_value, field_type, field_ctx)
|
189
|
-
}
|
190
|
-
else
|
191
|
-
field_ctx.value = continue_resolve_field(raw_value, field_type, field_ctx)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
def continue_resolve_field(raw_value, field_type, field_ctx)
|
196
|
-
if field_ctx.parent.invalid_null?
|
197
|
-
return nil
|
198
|
-
end
|
199
|
-
query = field_ctx.query
|
200
|
-
|
201
|
-
case raw_value
|
202
|
-
when GraphQL::ExecutionError
|
203
|
-
raw_value.ast_node ||= field_ctx.ast_node
|
204
|
-
raw_value.path = field_ctx.path
|
205
|
-
query.context.errors.push(raw_value)
|
206
|
-
when Array
|
207
|
-
if field_type.non_null?
|
208
|
-
# List type errors are handled above, this is for the case of fields returning an array of errors
|
209
|
-
list_errors = raw_value.each_with_index.select { |value, _| value.is_a?(GraphQL::ExecutionError) }
|
210
|
-
if list_errors.any?
|
211
|
-
list_errors.each do |error, index|
|
212
|
-
error.ast_node = field_ctx.ast_node
|
213
|
-
error.path = field_ctx.path + (field_ctx.type.list? ? [index] : [])
|
214
|
-
query.context.errors.push(error)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
resolve_value(
|
221
|
-
raw_value,
|
222
|
-
field_type,
|
223
|
-
field_ctx,
|
224
|
-
)
|
225
|
-
end
|
226
|
-
|
227
|
-
def resolve_value(value, field_type, field_ctx)
|
228
|
-
field_defn = field_ctx.field
|
229
|
-
|
230
|
-
if value.nil?
|
231
|
-
if field_type.kind.non_null?
|
232
|
-
parent_type = field_ctx.irep_node.owner_type
|
233
|
-
type_error = GraphQL::InvalidNullError.new(parent_type, field_defn, value)
|
234
|
-
field_ctx.schema.type_error(type_error, field_ctx)
|
235
|
-
PROPAGATE_NULL
|
236
|
-
else
|
237
|
-
nil
|
238
|
-
end
|
239
|
-
elsif value.is_a?(GraphQL::ExecutionError)
|
240
|
-
if field_type.kind.non_null?
|
241
|
-
PROPAGATE_NULL
|
242
|
-
else
|
243
|
-
nil
|
244
|
-
end
|
245
|
-
elsif value.is_a?(Array) && value.any? && value.all? {|v| v.is_a?(GraphQL::ExecutionError)}
|
246
|
-
if field_type.kind.non_null?
|
247
|
-
PROPAGATE_NULL
|
248
|
-
else
|
249
|
-
nil
|
250
|
-
end
|
251
|
-
elsif value.is_a?(Skip)
|
252
|
-
field_ctx.value = value
|
253
|
-
else
|
254
|
-
case field_type.kind
|
255
|
-
when GraphQL::TypeKinds::SCALAR, GraphQL::TypeKinds::ENUM
|
256
|
-
field_type.coerce_result(value, field_ctx)
|
257
|
-
when GraphQL::TypeKinds::LIST
|
258
|
-
inner_type = field_type.of_type
|
259
|
-
i = 0
|
260
|
-
result = []
|
261
|
-
field_ctx.value = result
|
262
|
-
|
263
|
-
value.each do |inner_value|
|
264
|
-
inner_ctx = field_ctx.spawn_child(
|
265
|
-
key: i,
|
266
|
-
object: inner_value,
|
267
|
-
irep_node: field_ctx.irep_node,
|
268
|
-
)
|
269
|
-
|
270
|
-
inner_result = continue_or_wait(
|
271
|
-
inner_value,
|
272
|
-
inner_type,
|
273
|
-
inner_ctx,
|
274
|
-
)
|
275
|
-
|
276
|
-
return PROPAGATE_NULL if inner_result == PROPAGATE_NULL
|
277
|
-
|
278
|
-
result << inner_ctx
|
279
|
-
i += 1
|
280
|
-
end
|
281
|
-
|
282
|
-
result
|
283
|
-
when GraphQL::TypeKinds::NON_NULL
|
284
|
-
inner_type = field_type.of_type
|
285
|
-
resolve_value(
|
286
|
-
value,
|
287
|
-
inner_type,
|
288
|
-
field_ctx,
|
289
|
-
)
|
290
|
-
when GraphQL::TypeKinds::OBJECT
|
291
|
-
resolve_selection(
|
292
|
-
value,
|
293
|
-
field_type,
|
294
|
-
field_ctx
|
295
|
-
)
|
296
|
-
when GraphQL::TypeKinds::UNION, GraphQL::TypeKinds::INTERFACE
|
297
|
-
query = field_ctx.query
|
298
|
-
resolved_type_or_lazy = field_type.resolve_type(value, field_ctx)
|
299
|
-
query.schema.after_lazy(resolved_type_or_lazy) do |resolved_type|
|
300
|
-
possible_types = query.possible_types(field_type)
|
301
|
-
|
302
|
-
if !possible_types.include?(resolved_type)
|
303
|
-
parent_type = field_ctx.irep_node.owner_type
|
304
|
-
type_error = GraphQL::UnresolvedTypeError.new(value, field_defn, parent_type, resolved_type, possible_types)
|
305
|
-
field_ctx.schema.type_error(type_error, field_ctx)
|
306
|
-
PROPAGATE_NULL
|
307
|
-
else
|
308
|
-
resolve_value(
|
309
|
-
value,
|
310
|
-
resolved_type,
|
311
|
-
field_ctx,
|
312
|
-
)
|
313
|
-
end
|
314
|
-
end
|
315
|
-
else
|
316
|
-
raise("Unknown type kind: #{field_type.kind}")
|
317
|
-
end
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
321
|
-
|
322
|
-
include ExecutionFunctions
|
323
|
-
|
324
|
-
# A `.call`-able suitable to be the last step in a middleware chain
|
325
|
-
module FieldResolveStep
|
326
|
-
# Execute the field's resolve method
|
327
|
-
def self.call(_parent_type, parent_object, field_definition, field_args, context, _next = nil)
|
328
|
-
field_definition.resolve(parent_object, field_args, context)
|
329
|
-
end
|
330
|
-
end
|
331
|
-
end
|
332
|
-
end
|
333
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Execution
|
4
|
-
# Starting from a root context,
|
5
|
-
# create a hash out of the context tree.
|
6
|
-
# @api private
|
7
|
-
module Flatten
|
8
|
-
def self.call(ctx)
|
9
|
-
flatten(ctx)
|
10
|
-
end
|
11
|
-
|
12
|
-
class << self
|
13
|
-
private
|
14
|
-
|
15
|
-
def flatten(obj)
|
16
|
-
case obj
|
17
|
-
when Hash
|
18
|
-
flattened = {}
|
19
|
-
obj.each do |key, val|
|
20
|
-
flattened[key] = flatten(val)
|
21
|
-
end
|
22
|
-
flattened
|
23
|
-
when Array
|
24
|
-
obj.map { |v| flatten(v) }
|
25
|
-
when Query::Context::SharedMethods
|
26
|
-
if obj.invalid_null?
|
27
|
-
nil
|
28
|
-
elsif obj.skipped? && obj.value.empty?
|
29
|
-
nil
|
30
|
-
else
|
31
|
-
flatten(obj.value)
|
32
|
-
end
|
33
|
-
else
|
34
|
-
obj
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Execution
|
4
|
-
# @api private
|
5
|
-
module Typecast
|
6
|
-
# @return [Boolean]
|
7
|
-
def self.subtype?(parent_type, child_type)
|
8
|
-
if parent_type == child_type
|
9
|
-
# Equivalent types are subtypes
|
10
|
-
true
|
11
|
-
elsif child_type.is_a?(GraphQL::NonNullType)
|
12
|
-
# A non-null type is a subtype of a nullable type
|
13
|
-
# if its inner type is a subtype of that type
|
14
|
-
if parent_type.is_a?(GraphQL::NonNullType)
|
15
|
-
subtype?(parent_type.of_type, child_type.of_type)
|
16
|
-
else
|
17
|
-
subtype?(parent_type, child_type.of_type)
|
18
|
-
end
|
19
|
-
else
|
20
|
-
case parent_type
|
21
|
-
when GraphQL::InterfaceType
|
22
|
-
# A type is a subtype of an interface
|
23
|
-
# if it implements that interface
|
24
|
-
case child_type
|
25
|
-
when GraphQL::ObjectType
|
26
|
-
child_type.interfaces.include?(parent_type)
|
27
|
-
else
|
28
|
-
false
|
29
|
-
end
|
30
|
-
when GraphQL::UnionType
|
31
|
-
# A type is a subtype of that union
|
32
|
-
# if the union includes that type
|
33
|
-
parent_type.possible_types.include?(child_type)
|
34
|
-
when GraphQL::ListType
|
35
|
-
# A list type is a subtype of another list type
|
36
|
-
# if its inner type is a subtype of the other inner type
|
37
|
-
case child_type
|
38
|
-
when GraphQL::ListType
|
39
|
-
subtype?(parent_type.of_type, child_type.of_type)
|
40
|
-
else
|
41
|
-
false
|
42
|
-
end
|
43
|
-
else
|
44
|
-
false
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|