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
@@ -1,164 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GraphQL
|
4
|
-
class Schema
|
5
|
-
class Member
|
6
|
-
# Support for legacy `accepts_definitions` functions.
|
7
|
-
#
|
8
|
-
# Keep the legacy handler hooked up. Class-based types and fields
|
9
|
-
# will call those legacy handlers during their `.to_graphql`
|
10
|
-
# methods.
|
11
|
-
#
|
12
|
-
# This can help out while transitioning from one to the other.
|
13
|
-
# Eventually, `GraphQL::{X}Type` objects will be removed entirely,
|
14
|
-
# But this can help during the transition.
|
15
|
-
#
|
16
|
-
# @example Applying a function to base object class
|
17
|
-
# # Here's the legacy-style config, which we're calling back to:
|
18
|
-
# GraphQL::ObjectType.accepts_definition({
|
19
|
-
# permission_level: ->(defn, value) { defn.metadata[:permission_level] = value }
|
20
|
-
# })
|
21
|
-
#
|
22
|
-
# class BaseObject < GraphQL::Schema::Object
|
23
|
-
# # Setup a named pass-through to the legacy config functions
|
24
|
-
# accepts_definition :permission_level
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
# class Account < BaseObject
|
28
|
-
# # This value will be passed to the legacy handler:
|
29
|
-
# permission_level 1
|
30
|
-
# end
|
31
|
-
#
|
32
|
-
# # The class gets a reader method which returns the args,
|
33
|
-
# # only marginally useful.
|
34
|
-
# Account.permission_level # => [1]
|
35
|
-
#
|
36
|
-
# # The legacy handler is called, as before:
|
37
|
-
# Account.graphql_definition.metadata[:permission_level] # => 1
|
38
|
-
module AcceptsDefinition
|
39
|
-
def self.included(child)
|
40
|
-
child.extend(AcceptsDefinitionDefinitionMethods)
|
41
|
-
child.prepend(ToGraphQLExtension)
|
42
|
-
child.prepend(InitializeExtension)
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.extended(child)
|
46
|
-
if defined?(child::DefinitionMethods)
|
47
|
-
child::DefinitionMethods.include(AcceptsDefinitionDefinitionMethods)
|
48
|
-
child::DefinitionMethods.prepend(ToGraphQLExtension)
|
49
|
-
else
|
50
|
-
child.extend(AcceptsDefinitionDefinitionMethods)
|
51
|
-
# I tried to use `super`, but super isn't quite right
|
52
|
-
# since the method is defined in the same class itself,
|
53
|
-
# not the superclass
|
54
|
-
child.class_eval do
|
55
|
-
class << self
|
56
|
-
prepend(ToGraphQLExtension)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
module AcceptsDefinitionDefinitionMethods
|
63
|
-
def accepts_definition(name)
|
64
|
-
own_accepts_definition_methods << name
|
65
|
-
|
66
|
-
ivar_name = "@#{name}_args"
|
67
|
-
if self.is_a?(Class)
|
68
|
-
define_singleton_method(name) do |*args|
|
69
|
-
if args.any?
|
70
|
-
instance_variable_set(ivar_name, args)
|
71
|
-
end
|
72
|
-
instance_variable_get(ivar_name) || (superclass.respond_to?(name) ? superclass.public_send(name) : nil)
|
73
|
-
end
|
74
|
-
|
75
|
-
define_method(name) do |*args|
|
76
|
-
if args.any?
|
77
|
-
instance_variable_set(ivar_name, args)
|
78
|
-
end
|
79
|
-
instance_variable_get(ivar_name)
|
80
|
-
end
|
81
|
-
else
|
82
|
-
# Special handling for interfaces, define it here
|
83
|
-
# so it's appropriately passed down
|
84
|
-
self::DefinitionMethods.module_eval do
|
85
|
-
define_method(name) do |*args|
|
86
|
-
if args.any?
|
87
|
-
instance_variable_set(ivar_name, args)
|
88
|
-
else
|
89
|
-
if (v = instance_variable_get(ivar_name))
|
90
|
-
v
|
91
|
-
elsif (ancestor = ancestors.find { |i| i.respond_to?(name) && i != self })
|
92
|
-
ancestor.public_send(name)
|
93
|
-
else
|
94
|
-
nil
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def accepts_definition_methods
|
103
|
-
inherited_methods = if self.is_a?(Class)
|
104
|
-
superclass.respond_to?(:accepts_definition_methods) ? superclass.accepts_definition_methods : []
|
105
|
-
elsif self.is_a?(Module)
|
106
|
-
m = []
|
107
|
-
ancestors.each do |a|
|
108
|
-
if a.respond_to?(:own_accepts_definition_methods)
|
109
|
-
m.concat(a.own_accepts_definition_methods)
|
110
|
-
end
|
111
|
-
end
|
112
|
-
m
|
113
|
-
else
|
114
|
-
self.class.accepts_definition_methods
|
115
|
-
end
|
116
|
-
|
117
|
-
own_accepts_definition_methods + inherited_methods
|
118
|
-
end
|
119
|
-
|
120
|
-
def own_accepts_definition_methods
|
121
|
-
@own_accepts_definition_methods ||= []
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
module ToGraphQLExtension
|
126
|
-
def to_graphql(*args, **kwargs)
|
127
|
-
|
128
|
-
defn = if args.empty? && kwargs.empty?
|
129
|
-
super()
|
130
|
-
else
|
131
|
-
super
|
132
|
-
end
|
133
|
-
accepts_definition_methods.each do |method_name|
|
134
|
-
value = public_send(method_name)
|
135
|
-
if !value.nil?
|
136
|
-
defn = defn.redefine { public_send(method_name, *value) }
|
137
|
-
end
|
138
|
-
end
|
139
|
-
defn
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
module InitializeExtension
|
144
|
-
def initialize(*args, **kwargs, &block)
|
145
|
-
self.class.accepts_definition_methods.each do |method_name|
|
146
|
-
if kwargs.key?(method_name)
|
147
|
-
value = kwargs.delete(method_name)
|
148
|
-
if !value.is_a?(Array)
|
149
|
-
value = [value]
|
150
|
-
end
|
151
|
-
instance_variable_set("@#{method_name}_args", value)
|
152
|
-
end
|
153
|
-
end
|
154
|
-
super(*args, **kwargs, &block)
|
155
|
-
end
|
156
|
-
|
157
|
-
def accepts_definition_methods
|
158
|
-
self.class.accepts_definition_methods
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GraphQL
|
4
|
-
class Schema
|
5
|
-
class Member
|
6
|
-
# Adds a layer of caching over user-supplied `.to_graphql` methods.
|
7
|
-
# Users override `.to_graphql`, but all runtime code should use `.graphql_definition`.
|
8
|
-
# @api private
|
9
|
-
# @see concrete classes that extend this, eg {Schema::Object}
|
10
|
-
module CachedGraphQLDefinition
|
11
|
-
# A cached result of {.to_graphql}.
|
12
|
-
# It's cached here so that user-overridden {.to_graphql} implementations
|
13
|
-
# are also cached
|
14
|
-
def graphql_definition(silence_deprecation_warning: false)
|
15
|
-
@graphql_definition ||= begin
|
16
|
-
unless silence_deprecation_warning
|
17
|
-
message = "Legacy `.graphql_definition` objects are deprecated and will be removed in GraphQL-Ruby 2.0. Remove `.graphql_definition` to use a class-based definition instead."
|
18
|
-
caller_message = "\n\nCalled on #{self.inspect} from:\n #{caller(1, 25).map { |l| " #{l}" }.join("\n")}"
|
19
|
-
GraphQL::Deprecation.warn(message + caller_message)
|
20
|
-
end
|
21
|
-
deprecated_to_graphql
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def deprecated_to_graphql
|
26
|
-
case method(:to_graphql).arity
|
27
|
-
when 0
|
28
|
-
to_graphql
|
29
|
-
else
|
30
|
-
to_graphql(silence_deprecation_warning: true)
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
# This is for a common interface with .define-based types
|
35
|
-
def type_class
|
36
|
-
self
|
37
|
-
end
|
38
|
-
|
39
|
-
# Wipe out the cached graphql_definition so that `.to_graphql` will be called again.
|
40
|
-
def initialize_copy(original)
|
41
|
-
super
|
42
|
-
@graphql_definition = nil
|
43
|
-
end
|
44
|
-
|
45
|
-
module DeprecatedToGraphQL
|
46
|
-
def to_graphql(silence_deprecation_warning: false)
|
47
|
-
unless silence_deprecation_warning
|
48
|
-
message = "Legacy `.to_graphql` objects are deprecated and will be removed in GraphQL-Ruby 2.0. Remove `.to_graphql` to use a class-based definition instead."
|
49
|
-
caller_message = "\n\nCalled on #{self.inspect} from:\n #{caller(1, 25).map { |l| " #{l}" }.join("\n")}"
|
50
|
-
GraphQL::Deprecation.warn(message + caller_message)
|
51
|
-
end
|
52
|
-
super()
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
@@ -1,131 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GraphQL
|
4
|
-
class Schema
|
5
|
-
class Member
|
6
|
-
module Instrumentation
|
7
|
-
module_function
|
8
|
-
def instrument(type, field)
|
9
|
-
return_type = field.type.unwrap
|
10
|
-
if (return_type.is_a?(GraphQL::ObjectType) && return_type.metadata[:type_class]) ||
|
11
|
-
return_type.is_a?(GraphQL::InterfaceType) ||
|
12
|
-
(return_type.is_a?(GraphQL::UnionType) && return_type.possible_types.any? { |t| t.metadata[:type_class] })
|
13
|
-
field = apply_proxy(field)
|
14
|
-
end
|
15
|
-
|
16
|
-
field
|
17
|
-
end
|
18
|
-
|
19
|
-
def before_query(query)
|
20
|
-
# Get the root type for this query
|
21
|
-
root_node = query.irep_selection
|
22
|
-
if root_node.nil?
|
23
|
-
# It's an invalid query, nothing to do here
|
24
|
-
else
|
25
|
-
root_type = query.irep_selection.return_type
|
26
|
-
# If it has a wrapper, apply it
|
27
|
-
wrapper_class = root_type.metadata[:type_class]
|
28
|
-
if wrapper_class
|
29
|
-
new_root_value = wrapper_class.authorized_new(query.root_value, query.context)
|
30
|
-
new_root_value = query.schema.sync_lazy(new_root_value)
|
31
|
-
if new_root_value.nil?
|
32
|
-
# This is definitely a hack,
|
33
|
-
# but we need some way to tell execute.rb not to run.
|
34
|
-
query.context[:__root_unauthorized] = true
|
35
|
-
end
|
36
|
-
query.root_value = new_root_value
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def after_query(_query)
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
module_function
|
47
|
-
|
48
|
-
def apply_proxy(field)
|
49
|
-
resolve_proc = field.resolve_proc
|
50
|
-
lazy_resolve_proc = field.lazy_resolve_proc
|
51
|
-
inner_return_type = field.type.unwrap
|
52
|
-
depth = list_depth(field.type)
|
53
|
-
|
54
|
-
field.redefine(
|
55
|
-
resolve: ProxiedResolve.new(inner_resolve: resolve_proc, list_depth: depth, inner_return_type: inner_return_type),
|
56
|
-
lazy_resolve: ProxiedResolve.new(inner_resolve: lazy_resolve_proc, list_depth: depth, inner_return_type: inner_return_type),
|
57
|
-
)
|
58
|
-
end
|
59
|
-
|
60
|
-
def list_depth(type, starting_at = 0)
|
61
|
-
case type
|
62
|
-
when GraphQL::ListType
|
63
|
-
list_depth(type.of_type, starting_at + 1)
|
64
|
-
when GraphQL::NonNullType
|
65
|
-
list_depth(type.of_type, starting_at)
|
66
|
-
else
|
67
|
-
starting_at
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
class ProxiedResolve
|
72
|
-
def initialize(inner_resolve:, list_depth:, inner_return_type:)
|
73
|
-
@inner_resolve = inner_resolve
|
74
|
-
@inner_return_type = inner_return_type
|
75
|
-
@list_depth = list_depth
|
76
|
-
end
|
77
|
-
|
78
|
-
def call(obj, args, ctx)
|
79
|
-
result = @inner_resolve.call(obj, args, ctx)
|
80
|
-
if ctx.skip == result || ctx.schema.lazy?(result) || result.nil? || execution_errors?(result) || ctx.wrapped_object
|
81
|
-
result
|
82
|
-
else
|
83
|
-
ctx.wrapped_object = true
|
84
|
-
proxy_to_depth(result, @list_depth, ctx)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
|
-
def execution_errors?(result)
|
91
|
-
result.is_a?(GraphQL::ExecutionError) ||
|
92
|
-
(result.is_a?(Array) && result.any? && result.all? { |v| v.is_a?(GraphQL::ExecutionError) })
|
93
|
-
end
|
94
|
-
|
95
|
-
def proxy_to_depth(inner_obj, depth, ctx)
|
96
|
-
if depth > 0
|
97
|
-
inner_obj.map { |i| proxy_to_depth(i, depth - 1, ctx) }
|
98
|
-
else
|
99
|
-
ctx.schema.after_lazy(inner_obj) do |inner_obj|
|
100
|
-
if inner_obj.nil?
|
101
|
-
# For lists with nil, we need another nil check here
|
102
|
-
nil
|
103
|
-
else
|
104
|
-
concrete_type_or_lazy = case @inner_return_type
|
105
|
-
when GraphQL::UnionType, GraphQL::InterfaceType
|
106
|
-
ctx.query.resolve_type(@inner_return_type, inner_obj)
|
107
|
-
when GraphQL::ObjectType
|
108
|
-
@inner_return_type
|
109
|
-
else
|
110
|
-
raise "unexpected proxying type #{@inner_return_type} for #{inner_obj} at #{ctx.owner_type}.#{ctx.field.name}"
|
111
|
-
end
|
112
|
-
|
113
|
-
# .resolve_type may have returned a lazy
|
114
|
-
ctx.schema.after_lazy(concrete_type_or_lazy) do |concrete_type|
|
115
|
-
if concrete_type && (object_class = concrete_type.metadata[:type_class])
|
116
|
-
# use the query-level context here, since it won't be field-specific anyways
|
117
|
-
query_ctx = ctx.query.context
|
118
|
-
object_class.authorized_new(inner_obj, query_ctx)
|
119
|
-
else
|
120
|
-
inner_obj
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# Given {steps} and {arguments}, call steps in order, passing `(*arguments, next_step)`.
|
5
|
-
#
|
6
|
-
# Steps should call `next_step.call` to continue the chain, or _not_ call it to stop the chain.
|
7
|
-
class MiddlewareChain
|
8
|
-
extend Forwardable
|
9
|
-
|
10
|
-
# @return [Array<#call(*args)>] Steps in this chain, will be called with arguments and `next_middleware`
|
11
|
-
attr_reader :steps, :final_step
|
12
|
-
|
13
|
-
def initialize(steps: [], final_step: nil)
|
14
|
-
@steps = steps
|
15
|
-
@final_step = final_step
|
16
|
-
end
|
17
|
-
|
18
|
-
def initialize_copy(other)
|
19
|
-
super
|
20
|
-
@steps = other.steps.dup
|
21
|
-
end
|
22
|
-
|
23
|
-
def_delegators :@steps, :[], :first, :insert, :delete
|
24
|
-
|
25
|
-
def <<(callable)
|
26
|
-
add_middleware(callable)
|
27
|
-
end
|
28
|
-
|
29
|
-
def push(callable)
|
30
|
-
add_middleware(callable)
|
31
|
-
end
|
32
|
-
|
33
|
-
def ==(other)
|
34
|
-
steps == other.steps && final_step == other.final_step
|
35
|
-
end
|
36
|
-
|
37
|
-
def invoke(arguments)
|
38
|
-
invoke_core(0, arguments)
|
39
|
-
end
|
40
|
-
|
41
|
-
def concat(callables)
|
42
|
-
callables.each { |c| add_middleware(c) }
|
43
|
-
end
|
44
|
-
|
45
|
-
private
|
46
|
-
|
47
|
-
def invoke_core(index, arguments)
|
48
|
-
if index >= steps.length
|
49
|
-
final_step.call(*arguments)
|
50
|
-
else
|
51
|
-
steps[index].call(*arguments) { |next_args = arguments| invoke_core(index + 1, next_args) }
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def add_middleware(callable)
|
56
|
-
# TODO: Stop wrapping callables once deprecated middleware becomes unsupported
|
57
|
-
steps << wrap(callable)
|
58
|
-
end
|
59
|
-
|
60
|
-
# TODO: Remove this code once deprecated middleware becomes unsupported
|
61
|
-
class MiddlewareWrapper
|
62
|
-
attr_reader :callable
|
63
|
-
def initialize(callable)
|
64
|
-
@callable = callable
|
65
|
-
end
|
66
|
-
|
67
|
-
def call(*args, &next_middleware)
|
68
|
-
callable.call(*args, next_middleware)
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def wrap(callable)
|
73
|
-
if BackwardsCompatibility.get_arity(callable) == 6
|
74
|
-
GraphQL::Deprecation.warn("Middleware that takes a next_middleware parameter is deprecated (#{callable.inspect}); instead, accept a block and use yield.")
|
75
|
-
MiddlewareWrapper.new(callable)
|
76
|
-
else
|
77
|
-
callable
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# Find the members of a union or interface within a given schema.
|
5
|
-
#
|
6
|
-
# (Although its members never change, unions are handled this way to simplify execution code.)
|
7
|
-
#
|
8
|
-
# Internally, the calculation is cached. It's assumed that schema members _don't_ change after creating the schema!
|
9
|
-
#
|
10
|
-
# @example Get an interface's possible types
|
11
|
-
# possible_types = GraphQL::Schema::PossibleTypes(MySchema)
|
12
|
-
# possible_types.possible_types(MyInterface)
|
13
|
-
# # => [MyObjectType, MyOtherObjectType]
|
14
|
-
class PossibleTypes
|
15
|
-
def initialize(schema)
|
16
|
-
@object_types = schema.types.values.select { |type| type.kind.object? }
|
17
|
-
@interface_implementers = Hash.new do |h1, ctx|
|
18
|
-
h1[ctx] = Hash.new do |h2, int_type|
|
19
|
-
h2[int_type] = @object_types.select { |type| type.interfaces(ctx).include?(int_type) }.sort_by(&:name)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def possible_types(type_defn, ctx)
|
25
|
-
case type_defn
|
26
|
-
when Module
|
27
|
-
possible_types(type_defn.graphql_definition, ctx)
|
28
|
-
when GraphQL::UnionType
|
29
|
-
type_defn.possible_types(ctx)
|
30
|
-
when GraphQL::InterfaceType
|
31
|
-
interface_implementers(ctx, type_defn)
|
32
|
-
when GraphQL::BaseType
|
33
|
-
[type_defn]
|
34
|
-
else
|
35
|
-
raise "Unexpected possible_types object: #{type_defn.inspect}"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def interface_implementers(ctx, type_defn)
|
40
|
-
@interface_implementers[ctx][type_defn]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# - Store a table of errors & handlers
|
5
|
-
# - Rescue errors in a middleware chain, then check for a handler
|
6
|
-
# - If a handler is found, use it & return a {GraphQL::ExecutionError}
|
7
|
-
# - If no handler is found, re-raise the error
|
8
|
-
class RescueMiddleware
|
9
|
-
# @return [Hash] `{class => proc}` pairs for handling errors
|
10
|
-
attr_reader :rescue_table
|
11
|
-
def initialize
|
12
|
-
@rescue_table = {}
|
13
|
-
end
|
14
|
-
|
15
|
-
# @example Rescue from not-found by telling the user
|
16
|
-
# MySchema.rescue_from(ActiveRecord::RecordNotFound) { "An item could not be found" }
|
17
|
-
#
|
18
|
-
# @param error_classes [Class] one or more classes of errors to rescue from
|
19
|
-
# @yield [err] A handler to return a message for these error instances
|
20
|
-
# @yieldparam [Exception] an error that was rescued
|
21
|
-
# @yieldreturn [String] message to put in GraphQL response
|
22
|
-
def rescue_from(*error_classes, &block)
|
23
|
-
error_classes.map{ |error_class| rescue_table[error_class] = block }
|
24
|
-
end
|
25
|
-
|
26
|
-
# Remove the handler for `error_classs`
|
27
|
-
# @param error_class [Class] the error class whose handler should be removed
|
28
|
-
def remove_handler(*error_classes)
|
29
|
-
error_classes.map{ |error_class| rescue_table.delete(error_class) }
|
30
|
-
end
|
31
|
-
|
32
|
-
# Implement the requirement for {GraphQL::Schema::MiddlewareChain}
|
33
|
-
def call(*args)
|
34
|
-
begin
|
35
|
-
yield
|
36
|
-
rescue StandardError => err
|
37
|
-
attempt_rescue(err)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def attempt_rescue(err)
|
44
|
-
rescue_table.each { |klass, handler|
|
45
|
-
if klass.is_a?(Class) && err.is_a?(klass) && handler
|
46
|
-
result = handler.call(err)
|
47
|
-
case result
|
48
|
-
when String
|
49
|
-
return GraphQL::ExecutionError.new(result)
|
50
|
-
when GraphQL::ExecutionError
|
51
|
-
return result
|
52
|
-
end
|
53
|
-
end
|
54
|
-
}
|
55
|
-
|
56
|
-
raise(err)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "delegate"
|
3
|
-
|
4
|
-
module GraphQL
|
5
|
-
class Schema
|
6
|
-
# This middleware will stop resolving new fields after `max_seconds` have elapsed.
|
7
|
-
# After the time has passed, any remaining fields will be `nil`, with errors added
|
8
|
-
# to the `errors` key. Any already-resolved fields will be in the `data` key, so
|
9
|
-
# you'll get a partial response.
|
10
|
-
#
|
11
|
-
# You can provide a block which will be called with any timeout errors that occur.
|
12
|
-
#
|
13
|
-
# Note that this will stop a query _in between_ field resolutions, but
|
14
|
-
# it doesn't interrupt long-running `resolve` functions. Be sure to use
|
15
|
-
# timeout options for external connections. For more info, see
|
16
|
-
# www.mikeperham.com/2015/05/08/timeout-rubys-most-dangerous-api/
|
17
|
-
#
|
18
|
-
# @example Stop resolving fields after 2 seconds
|
19
|
-
# MySchema.middleware << GraphQL::Schema::TimeoutMiddleware.new(max_seconds: 2)
|
20
|
-
#
|
21
|
-
# @example Notifying Bugsnag on a timeout
|
22
|
-
# MySchema.middleware << GraphQL::Schema::TimeoutMiddleware(max_seconds: 1.5) do |timeout_error, query|
|
23
|
-
# Bugsnag.notify(timeout_error, {query_string: query_ctx.query.query_string})
|
24
|
-
# end
|
25
|
-
#
|
26
|
-
# @api deprecated
|
27
|
-
# @see Schema::Timeout
|
28
|
-
class TimeoutMiddleware
|
29
|
-
# @param max_seconds [Numeric] how many seconds the query should be allowed to resolve new fields
|
30
|
-
def initialize(max_seconds:, context_key: nil, &block)
|
31
|
-
@max_seconds = max_seconds
|
32
|
-
if context_key
|
33
|
-
GraphQL::Deprecation.warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
|
34
|
-
end
|
35
|
-
@error_handler = block
|
36
|
-
end
|
37
|
-
|
38
|
-
def call(parent_type, parent_object, field_definition, field_args, query_context)
|
39
|
-
ns = query_context.namespace(self.class)
|
40
|
-
now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
41
|
-
timeout_at = ns[:timeout_at] ||= now + @max_seconds
|
42
|
-
|
43
|
-
if timeout_at < now
|
44
|
-
on_timeout(parent_type, parent_object, field_definition, field_args, query_context)
|
45
|
-
else
|
46
|
-
yield
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
# This is called when a field _would_ be resolved, except that we're over the time limit.
|
51
|
-
# @return [GraphQL::Schema::TimeoutMiddleware::TimeoutError] An error whose message will be added to the `errors` key
|
52
|
-
def on_timeout(parent_type, parent_object, field_definition, field_args, field_context)
|
53
|
-
err = GraphQL::Schema::TimeoutMiddleware::TimeoutError.new(parent_type, field_definition)
|
54
|
-
if @error_handler
|
55
|
-
query_proxy = TimeoutQueryProxy.new(field_context.query, field_context)
|
56
|
-
@error_handler.call(err, query_proxy)
|
57
|
-
end
|
58
|
-
err
|
59
|
-
end
|
60
|
-
|
61
|
-
# This behaves like {GraphQL::Query} but {#context} returns
|
62
|
-
# the _field-level_ context, not the query-level context.
|
63
|
-
# This means you can reliably get the `irep_node` and `path`
|
64
|
-
# from it after the fact.
|
65
|
-
class TimeoutQueryProxy < SimpleDelegator
|
66
|
-
def initialize(query, ctx)
|
67
|
-
@context = ctx
|
68
|
-
super(query)
|
69
|
-
end
|
70
|
-
|
71
|
-
attr_reader :context
|
72
|
-
end
|
73
|
-
|
74
|
-
# This error is raised when a query exceeds `max_seconds`.
|
75
|
-
# Since it's a child of {GraphQL::ExecutionError},
|
76
|
-
# its message will be added to the response's `errors` key.
|
77
|
-
#
|
78
|
-
# To raise an error that will stop query resolution, use a custom block
|
79
|
-
# to take this error and raise a new one which _doesn't_ descend from {GraphQL::ExecutionError},
|
80
|
-
# such as `RuntimeError`.
|
81
|
-
class TimeoutError < GraphQL::ExecutionError
|
82
|
-
def initialize(parent_type, field_defn)
|
83
|
-
super("Timeout on #{parent_type.name}.#{field_defn.name}")
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|