graphql 1.13.18 → 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 +2 -9
- 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/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +2 -15
- 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 +0 -21
- data/lib/graphql/schema/enum.rb +3 -19
- data/lib/graphql/schema/enum_value.rb +0 -22
- data/lib/graphql/schema/field.rb +4 -199
- data/lib/graphql/schema/input_object.rb +11 -57
- data/lib/graphql/schema/interface.rb +0 -25
- 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 +0 -5
- data/lib/graphql/schema/member/build_type.rb +4 -6
- data/lib/graphql/schema/member/has_arguments.rb +14 -18
- data/lib/graphql/schema/member/has_fields.rb +2 -2
- data/lib/graphql/schema/member/has_interfaces.rb +0 -2
- 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 +1 -1
- 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 +2 -19
- data/lib/graphql/tracing/platform_tracing.rb +4 -31
- 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/version.rb +1 -1
- data/lib/graphql.rb +1 -65
- metadata +6 -131
- 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/relay.rb
CHANGED
@@ -1,18 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'graphql/relay/page_info'
|
4
|
-
require 'graphql/relay/edge'
|
5
|
-
require 'graphql/relay/edge_type'
|
6
|
-
require 'graphql/relay/edges_instrumentation'
|
7
|
-
require 'graphql/relay/base_connection'
|
8
|
-
require 'graphql/relay/array_connection'
|
9
3
|
require 'graphql/relay/range_add'
|
10
|
-
require 'graphql/relay/relation_connection'
|
11
|
-
require 'graphql/relay/mongo_relation_connection'
|
12
|
-
require 'graphql/relay/global_id_resolve'
|
13
|
-
require 'graphql/relay/mutation'
|
14
|
-
require 'graphql/relay/node'
|
15
|
-
require 'graphql/relay/connection_instrumentation'
|
16
|
-
require 'graphql/relay/connection_resolve'
|
17
|
-
require 'graphql/relay/connection_type'
|
18
|
-
require 'graphql/relay/type_extensions'
|
@@ -136,14 +136,7 @@ module GraphQL
|
|
136
136
|
end
|
137
137
|
|
138
138
|
def add_type(type, owner:, late_types:, path:)
|
139
|
-
if type.
|
140
|
-
type_class = type.metadata[:type_class]
|
141
|
-
if type_class.nil?
|
142
|
-
raise ArgumentError, "Can't add legacy type: #{type} (#{type.class})"
|
143
|
-
else
|
144
|
-
type = type_class
|
145
|
-
end
|
146
|
-
elsif type.is_a?(String) || type.is_a?(GraphQL::Schema::LateBoundType)
|
139
|
+
if type.is_a?(String) || type.is_a?(GraphQL::Schema::LateBoundType)
|
147
140
|
late_types << [owner, type]
|
148
141
|
return
|
149
142
|
end
|
@@ -2,8 +2,6 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
4
|
class Argument
|
5
|
-
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
6
|
-
include GraphQL::Schema::Member::AcceptsDefinition
|
7
5
|
include GraphQL::Schema::Member::HasPath
|
8
6
|
include GraphQL::Schema::Member::HasAstNode
|
9
7
|
include GraphQL::Schema::Member::HasDirectives
|
@@ -44,12 +42,11 @@ module GraphQL
|
|
44
42
|
# @param prepare [Symbol] A method to call to transform this argument's valuebefore sending it to field resolution
|
45
43
|
# @param camelize [Boolean] if true, the name will be camelized when building the schema
|
46
44
|
# @param from_resolver [Boolean] if true, a Resolver class defined this argument
|
47
|
-
# @param method_access [Boolean] If false, don't build method access on legacy {Query::Arguments} instances.
|
48
45
|
# @param directives [Hash{Class => Hash}]
|
49
46
|
# @param deprecation_reason [String]
|
50
47
|
# @param validates [Hash, nil] Options for building validators, if any should be applied
|
51
48
|
# @param replace_null_with_default [Boolean] if `true`, incoming values of `null` will be replaced with the configured `default_value`
|
52
|
-
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil,
|
49
|
+
def initialize(arg_name = nil, type_expr = nil, desc = nil, required: true, type: nil, name: nil, loads: nil, description: nil, ast_node: nil, default_value: NO_DEFAULT, as: nil, from_resolver: false, camelize: true, prepare: nil, owner:, validates: nil, directives: nil, deprecation_reason: nil, replace_null_with_default: false, &definition_block)
|
53
50
|
arg_name ||= name
|
54
51
|
@name = -(camelize ? Member::BuildType.camelize(arg_name.to_s) : arg_name.to_s)
|
55
52
|
@type_expr = type_expr || type
|
@@ -70,7 +67,6 @@ module GraphQL
|
|
70
67
|
@prepare = prepare
|
71
68
|
@ast_node = ast_node
|
72
69
|
@from_resolver = from_resolver
|
73
|
-
@method_access = method_access
|
74
70
|
self.deprecation_reason = deprecation_reason
|
75
71
|
|
76
72
|
if directives
|
@@ -169,26 +165,6 @@ module GraphQL
|
|
169
165
|
true
|
170
166
|
end
|
171
167
|
|
172
|
-
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
173
|
-
|
174
|
-
def to_graphql
|
175
|
-
argument = GraphQL::Argument.new
|
176
|
-
argument.name = @name
|
177
|
-
argument.type = -> { type }
|
178
|
-
argument.description = @description
|
179
|
-
argument.metadata[:type_class] = self
|
180
|
-
argument.as = @as
|
181
|
-
argument.ast_node = ast_node
|
182
|
-
argument.method_access = @method_access
|
183
|
-
if NO_DEFAULT != @default_value
|
184
|
-
argument.default_value = @default_value
|
185
|
-
end
|
186
|
-
if self.deprecation_reason
|
187
|
-
argument.deprecation_reason = self.deprecation_reason
|
188
|
-
end
|
189
|
-
argument
|
190
|
-
end
|
191
|
-
|
192
168
|
def type=(new_type)
|
193
169
|
validate_input_type(new_type)
|
194
170
|
# This isn't true for LateBoundTypes, but we can assume those will
|
@@ -365,7 +365,6 @@ module GraphQL
|
|
365
365
|
deprecation_reason: builder.build_deprecation_reason(argument_defn.directives),
|
366
366
|
ast_node: argument_defn,
|
367
367
|
camelize: false,
|
368
|
-
method_access: false,
|
369
368
|
directives: prepare_directives(argument_defn, type_resolver),
|
370
369
|
**default_value_kwargs
|
371
370
|
)
|
@@ -8,7 +8,6 @@ module GraphQL
|
|
8
8
|
# - {.resolve}: Wraps field resolution (so it should call `yield` to continue)
|
9
9
|
class Directive < GraphQL::Schema::Member
|
10
10
|
extend GraphQL::Schema::Member::HasArguments
|
11
|
-
extend GraphQL::Schema::Member::AcceptsDefinition
|
12
11
|
|
13
12
|
class << self
|
14
13
|
# Directives aren't types, they don't have kinds.
|
@@ -55,26 +54,6 @@ module GraphQL
|
|
55
54
|
default_directive
|
56
55
|
end
|
57
56
|
|
58
|
-
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
59
|
-
|
60
|
-
def to_graphql
|
61
|
-
defn = GraphQL::Directive.new
|
62
|
-
defn.name = self.graphql_name
|
63
|
-
defn.description = self.description
|
64
|
-
defn.locations = self.locations
|
65
|
-
defn.default_directive = self.default_directive
|
66
|
-
defn.ast_node = ast_node
|
67
|
-
defn.metadata[:type_class] = self
|
68
|
-
all_argument_definitions.each do |arg_defn|
|
69
|
-
arg_graphql = arg_defn.to_graphql(silence_deprecation_warning: true)
|
70
|
-
defn.arguments[arg_graphql.name] = arg_graphql # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
71
|
-
end
|
72
|
-
# Make a reference to a classic-style Arguments class
|
73
|
-
defn.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(defn)
|
74
|
-
|
75
|
-
defn
|
76
|
-
end
|
77
|
-
|
78
57
|
# If false, this part of the query won't be evaluated
|
79
58
|
def include?(_object, arguments, context)
|
80
59
|
static_include?(arguments, context)
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -20,10 +20,9 @@ module GraphQL
|
|
20
20
|
# end
|
21
21
|
class Schema
|
22
22
|
class Enum < GraphQL::Schema::Member
|
23
|
-
extend GraphQL::Schema::Member::AcceptsDefinition
|
24
23
|
extend GraphQL::Schema::Member::ValidatesInput
|
25
24
|
|
26
|
-
class UnresolvedValueError < GraphQL::
|
25
|
+
class UnresolvedValueError < GraphQL::Error
|
27
26
|
def initialize(value:, enum:, context:)
|
28
27
|
fix_message = ", but this isn't a valid value for `#{enum.graphql_name}`. Update the field or resolver to return one of `#{enum.graphql_name}`'s values instead."
|
29
28
|
message = if (cp = context[:current_path]) && (cf = context[:current_field])
|
@@ -108,22 +107,6 @@ module GraphQL
|
|
108
107
|
enum_values(context).each_with_object({}) { |val, obj| obj[val.graphql_name] = val }
|
109
108
|
end
|
110
109
|
|
111
|
-
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
112
|
-
|
113
|
-
# @return [GraphQL::EnumType]
|
114
|
-
def to_graphql
|
115
|
-
enum_type = GraphQL::EnumType.new
|
116
|
-
enum_type.name = graphql_name
|
117
|
-
enum_type.description = description
|
118
|
-
enum_type.introspection = introspection
|
119
|
-
enum_type.ast_node = ast_node
|
120
|
-
values.each do |name, val|
|
121
|
-
enum_type.add_value(val.deprecated_to_graphql)
|
122
|
-
end
|
123
|
-
enum_type.metadata[:type_class] = self
|
124
|
-
enum_type
|
125
|
-
end
|
126
|
-
|
127
110
|
# @return [Class] for handling `value(...)` inputs and building `GraphQL::Enum::EnumValue`s out of them
|
128
111
|
def enum_value_class(new_enum_value_class = nil)
|
129
112
|
if new_enum_value_class
|
@@ -139,8 +122,9 @@ module GraphQL
|
|
139
122
|
GraphQL::TypeKinds::ENUM
|
140
123
|
end
|
141
124
|
|
142
|
-
def validate_non_null_input(value_name, ctx
|
125
|
+
def validate_non_null_input(value_name, ctx)
|
143
126
|
result = GraphQL::Query::InputValidationResult.new
|
127
|
+
|
144
128
|
allowed_values = ctx.warden.enum_values(self)
|
145
129
|
matching_value = allowed_values.find { |v| v.graphql_name == value_name }
|
146
130
|
|
@@ -13,12 +13,6 @@ module GraphQL
|
|
13
13
|
# # arguments to `value(...)` in Enum classes are passed here
|
14
14
|
# super
|
15
15
|
# end
|
16
|
-
#
|
17
|
-
# def to_graphql
|
18
|
-
# enum_value = super
|
19
|
-
# # customize the derived GraphQL::EnumValue here
|
20
|
-
# enum_value
|
21
|
-
# end
|
22
16
|
# end
|
23
17
|
#
|
24
18
|
# class BaseEnum < GraphQL::Schema::Enum
|
@@ -26,8 +20,6 @@ module GraphQL
|
|
26
20
|
# enum_value_class CustomEnumValue
|
27
21
|
# end
|
28
22
|
class EnumValue < GraphQL::Schema::Member
|
29
|
-
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
30
|
-
include GraphQL::Schema::Member::AcceptsDefinition
|
31
23
|
include GraphQL::Schema::Member::HasPath
|
32
24
|
include GraphQL::Schema::Member::HasAstNode
|
33
25
|
include GraphQL::Schema::Member::HasDirectives
|
@@ -73,20 +65,6 @@ module GraphQL
|
|
73
65
|
@value
|
74
66
|
end
|
75
67
|
|
76
|
-
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
77
|
-
|
78
|
-
# @return [GraphQL::EnumType::EnumValue] A runtime-ready object derived from this object
|
79
|
-
def to_graphql
|
80
|
-
enum_value = GraphQL::EnumType::EnumValue.new
|
81
|
-
enum_value.name = @graphql_name
|
82
|
-
enum_value.description = @description
|
83
|
-
enum_value.value = @value
|
84
|
-
enum_value.deprecation_reason = self.deprecation_reason
|
85
|
-
enum_value.metadata[:type_class] = self
|
86
|
-
enum_value.ast_node = ast_node
|
87
|
-
enum_value
|
88
|
-
end
|
89
|
-
|
90
68
|
def inspect
|
91
69
|
"#<#{self.class} #{path} @value=#{@value.inspect}#{description ? " @description=#{description.inspect}" : ""}>"
|
92
70
|
end
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -5,8 +5,6 @@ require "graphql/schema/field/scope_extension"
|
|
5
5
|
module GraphQL
|
6
6
|
class Schema
|
7
7
|
class Field
|
8
|
-
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
9
|
-
include GraphQL::Schema::Member::AcceptsDefinition
|
10
8
|
include GraphQL::Schema::Member::HasArguments
|
11
9
|
include GraphQL::Schema::Member::HasAstNode
|
12
10
|
include GraphQL::Schema::Member::HasPath
|
@@ -84,16 +82,6 @@ module GraphQL
|
|
84
82
|
# @return [GraphQL::Schema:Field] an instance of `self
|
85
83
|
# @see {.initialize} for other options
|
86
84
|
def self.from_options(name = nil, type = nil, desc = nil, resolver: nil, mutation: nil, subscription: nil,**kwargs, &block)
|
87
|
-
if kwargs[:field]
|
88
|
-
if kwargs[:field].is_a?(GraphQL::Field) && kwargs[:field] == GraphQL::Types::Relay::NodeField.graphql_definition
|
89
|
-
GraphQL::Deprecation.warn("Legacy-style `GraphQL::Relay::Node.field` is being added to a class-based type. See `GraphQL::Types::Relay::NodeField` for a replacement.")
|
90
|
-
return GraphQL::Types::Relay::NodeField
|
91
|
-
elsif kwargs[:field].is_a?(GraphQL::Field) && kwargs[:field] == GraphQL::Types::Relay::NodesField.graphql_definition
|
92
|
-
GraphQL::Deprecation.warn("Legacy-style `GraphQL::Relay::Node.plural_field` is being added to a class-based type. See `GraphQL::Types::Relay::NodesField` for a replacement.")
|
93
|
-
return GraphQL::Types::Relay::NodesField
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
85
|
if (parent_config = resolver || mutation || subscription)
|
98
86
|
# Get the parent config, merge in local overrides
|
99
87
|
kwargs = parent_config.field_options.merge(kwargs)
|
@@ -106,9 +94,6 @@ module GraphQL
|
|
106
94
|
end
|
107
95
|
|
108
96
|
if !type.nil?
|
109
|
-
if type.is_a?(GraphQL::Field)
|
110
|
-
raise ArgumentError, "A GraphQL::Field was passed as the second argument, use the `field:` keyword for this instead."
|
111
|
-
end
|
112
97
|
if desc
|
113
98
|
if kwargs[:description]
|
114
99
|
raise ArgumentError, "Provide description as a positional argument or `description:` keyword, but not both (#{desc.inspect}, #{kwargs[:description].inspect})"
|
@@ -176,8 +161,6 @@ module GraphQL
|
|
176
161
|
|
177
162
|
# @return Boolean
|
178
163
|
attr_reader :relay_node_field
|
179
|
-
# @return Boolean
|
180
|
-
attr_reader :relay_nodes_field
|
181
164
|
|
182
165
|
# @return [Boolean] Should we warn if this field's name conflicts with a built-in method?
|
183
166
|
def method_conflict_warning?
|
@@ -214,8 +197,7 @@ module GraphQL
|
|
214
197
|
# @param ast_node [Language::Nodes::FieldDefinition, nil] If this schema was parsed from definition, this AST node defined the field
|
215
198
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
216
199
|
# @param validates [Array<Hash>] Configurations for validating this field
|
217
|
-
|
218
|
-
def initialize(type: nil, name: nil, owner: nil, null: true, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, resolve: nil, connection: nil, max_page_size: :not_given, scope: nil, introspection: false, camelize: true, trace: nil, complexity: 1, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: nil, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, legacy_edge_class: nil, &definition_block)
|
200
|
+
def initialize(type: nil, name: nil, owner: nil, null: true, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, resolve: nil, connection: nil, max_page_size: :not_given, scope: nil, introspection: false, camelize: true, trace: nil, complexity: 1, ast_node: nil, extras: EMPTY_ARRAY, extensions: EMPTY_ARRAY, connection_extension: self.class.connection_extension, resolver_class: nil, subscription_scope: nil, relay_node_field: false, relay_nodes_field: false, method_conflict_warning: true, broadcastable: nil, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, &definition_block)
|
219
201
|
if name.nil?
|
220
202
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
221
203
|
end
|
@@ -258,10 +240,6 @@ module GraphQL
|
|
258
240
|
# TODO: I think non-string/symbol hash keys are wrongly normalized (eg `1` will not work)
|
259
241
|
method_name = method || hash_key || name_s
|
260
242
|
@dig_keys = dig
|
261
|
-
if hash_key
|
262
|
-
@hash_key = hash_key
|
263
|
-
end
|
264
|
-
|
265
243
|
resolver_method ||= name_s.to_sym
|
266
244
|
|
267
245
|
@method_str = -method_name.to_s
|
@@ -283,7 +261,6 @@ module GraphQL
|
|
283
261
|
@relay_nodes_field = relay_nodes_field
|
284
262
|
@ast_node = ast_node
|
285
263
|
@method_conflict_warning = method_conflict_warning
|
286
|
-
@legacy_edge_class = legacy_edge_class
|
287
264
|
|
288
265
|
arguments.each do |name, arg|
|
289
266
|
case arg
|
@@ -477,13 +454,7 @@ module GraphQL
|
|
477
454
|
case defined_complexity
|
478
455
|
when Proc
|
479
456
|
arguments = query.arguments_for(nodes.first, self)
|
480
|
-
|
481
|
-
return child_complexity
|
482
|
-
elsif arguments.respond_to?(:keyword_arguments)
|
483
|
-
arguments = arguments.keyword_arguments
|
484
|
-
end
|
485
|
-
|
486
|
-
defined_complexity.call(query.context, arguments, child_complexity)
|
457
|
+
defined_complexity.call(query.context, arguments.keyword_arguments, child_complexity)
|
487
458
|
when Numeric
|
488
459
|
defined_complexity + child_complexity
|
489
460
|
else
|
@@ -520,82 +491,6 @@ module GraphQL
|
|
520
491
|
# @return [Integer, nil] Applied to connections if {#has_max_page_size?}
|
521
492
|
attr_reader :max_page_size
|
522
493
|
|
523
|
-
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
524
|
-
|
525
|
-
# @return [GraphQL::Field]
|
526
|
-
def to_graphql
|
527
|
-
field_defn = if @field
|
528
|
-
@field.dup
|
529
|
-
elsif @function
|
530
|
-
GraphQL::Function.build_field(@function)
|
531
|
-
else
|
532
|
-
GraphQL::Field.new
|
533
|
-
end
|
534
|
-
|
535
|
-
field_defn.name = @name
|
536
|
-
if @return_type_expr
|
537
|
-
field_defn.type = -> { type }
|
538
|
-
end
|
539
|
-
|
540
|
-
if @description
|
541
|
-
field_defn.description = @description
|
542
|
-
end
|
543
|
-
|
544
|
-
if self.deprecation_reason
|
545
|
-
field_defn.deprecation_reason = self.deprecation_reason
|
546
|
-
end
|
547
|
-
|
548
|
-
if @resolver_class
|
549
|
-
if @resolver_class < GraphQL::Schema::Mutation
|
550
|
-
field_defn.mutation = @resolver_class
|
551
|
-
end
|
552
|
-
field_defn.metadata[:resolver] = @resolver_class
|
553
|
-
end
|
554
|
-
|
555
|
-
if !@trace.nil?
|
556
|
-
field_defn.trace = @trace
|
557
|
-
end
|
558
|
-
|
559
|
-
if @relay_node_field
|
560
|
-
field_defn.relay_node_field = @relay_node_field
|
561
|
-
end
|
562
|
-
|
563
|
-
if @relay_nodes_field
|
564
|
-
field_defn.relay_nodes_field = @relay_nodes_field
|
565
|
-
end
|
566
|
-
|
567
|
-
if @legacy_edge_class
|
568
|
-
field_defn.edge_class = @legacy_edge_class
|
569
|
-
end
|
570
|
-
|
571
|
-
field_defn.resolve = self.method(:resolve_field)
|
572
|
-
field_defn.connection = connection?
|
573
|
-
field_defn.connection_max_page_size = max_page_size
|
574
|
-
field_defn.introspection = @introspection
|
575
|
-
field_defn.complexity = @complexity
|
576
|
-
field_defn.subscription_scope = @subscription_scope
|
577
|
-
field_defn.ast_node = ast_node
|
578
|
-
|
579
|
-
all_argument_definitions.each do |defn|
|
580
|
-
arg_graphql = defn.deprecated_to_graphql
|
581
|
-
field_defn.arguments[arg_graphql.name] = arg_graphql # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
582
|
-
end
|
583
|
-
|
584
|
-
# Support a passed-in proc, one way or another
|
585
|
-
@resolve_proc = if @resolve
|
586
|
-
@resolve
|
587
|
-
elsif @function
|
588
|
-
@function
|
589
|
-
elsif @field
|
590
|
-
@field.resolve_proc
|
591
|
-
end
|
592
|
-
|
593
|
-
# Ok, `self` isn't a class, but this is for consistency with the classes
|
594
|
-
field_defn.metadata[:type_class] = self
|
595
|
-
field_defn.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(field_defn)
|
596
|
-
field_defn
|
597
|
-
end
|
598
|
-
|
599
494
|
class MissingReturnTypeError < GraphQL::Error; end
|
600
495
|
attr_writer :type
|
601
496
|
|
@@ -678,37 +573,6 @@ module GraphQL
|
|
678
573
|
end
|
679
574
|
end
|
680
575
|
|
681
|
-
# Implement {GraphQL::Field}'s resolve API.
|
682
|
-
#
|
683
|
-
# Eventually, we might hook up field instances to execution in another way. TBD.
|
684
|
-
# @see #resolve for how the interpreter hooks up to it
|
685
|
-
def resolve_field(obj, args, ctx)
|
686
|
-
ctx.schema.after_lazy(obj) do |after_obj|
|
687
|
-
# First, apply auth ...
|
688
|
-
query_ctx = ctx.query.context
|
689
|
-
# Some legacy fields can have `nil` here, not exactly sure why.
|
690
|
-
# @see https://github.com/rmosolgo/graphql-ruby/issues/1990 before removing
|
691
|
-
inner_obj = after_obj && after_obj.object
|
692
|
-
ctx.schema.after_lazy(to_ruby_args(after_obj, args, ctx)) do |ruby_args|
|
693
|
-
if authorized?(inner_obj, ruby_args, query_ctx)
|
694
|
-
# Then if it passed, resolve the field
|
695
|
-
if @resolve_proc
|
696
|
-
# Might be nil, still want to call the func in that case
|
697
|
-
with_extensions(inner_obj, ruby_args, query_ctx) do |extended_obj, extended_args|
|
698
|
-
# Pass the GraphQL args here for compatibility:
|
699
|
-
@resolve_proc.call(extended_obj, args, ctx)
|
700
|
-
end
|
701
|
-
else
|
702
|
-
public_send_field(after_obj, ruby_args, query_ctx)
|
703
|
-
end
|
704
|
-
else
|
705
|
-
err = GraphQL::UnauthorizedFieldError.new(object: inner_obj, type: obj.class, context: ctx, field: self)
|
706
|
-
query_ctx.schema.unauthorized_field(err)
|
707
|
-
end
|
708
|
-
end
|
709
|
-
end
|
710
|
-
end
|
711
|
-
|
712
576
|
# This method is called by the interpreter for each field.
|
713
577
|
# You can extend it in your base field classes.
|
714
578
|
# @param object [GraphQL::Schema::Object] An instance of some type class, wrapping an application object
|
@@ -741,7 +605,7 @@ module GraphQL
|
|
741
605
|
err
|
742
606
|
end
|
743
607
|
|
744
|
-
# @param ctx [GraphQL::Query::Context
|
608
|
+
# @param ctx [GraphQL::Query::Context]
|
745
609
|
def fetch_extra(extra_name, ctx)
|
746
610
|
if extra_name != :path && extra_name != :ast_node && respond_to?(extra_name)
|
747
611
|
self.public_send(extra_name)
|
@@ -754,63 +618,6 @@ module GraphQL
|
|
754
618
|
|
755
619
|
private
|
756
620
|
|
757
|
-
NO_ARGS = {}.freeze
|
758
|
-
|
759
|
-
# Convert a GraphQL arguments instance into a Ruby-style hash.
|
760
|
-
#
|
761
|
-
# @param obj [GraphQL::Schema::Object] The object where this field is being resolved
|
762
|
-
# @param graphql_args [GraphQL::Query::Arguments]
|
763
|
-
# @param field_ctx [GraphQL::Query::Context::FieldResolutionContext]
|
764
|
-
# @return [Hash<Symbol => Any>]
|
765
|
-
def to_ruby_args(obj, graphql_args, field_ctx)
|
766
|
-
if graphql_args.any? || @extras.any?
|
767
|
-
# Splat the GraphQL::Arguments to Ruby keyword arguments
|
768
|
-
ruby_kwargs = graphql_args.to_kwargs
|
769
|
-
maybe_lazies = []
|
770
|
-
# Apply any `prepare` methods. Not great code organization, can this go somewhere better?
|
771
|
-
arguments(field_ctx).each do |name, arg_defn|
|
772
|
-
ruby_kwargs_key = arg_defn.keyword
|
773
|
-
|
774
|
-
if ruby_kwargs.key?(ruby_kwargs_key)
|
775
|
-
loads = arg_defn.loads
|
776
|
-
value = ruby_kwargs[ruby_kwargs_key]
|
777
|
-
loaded_value = if loads && !arg_defn.from_resolver?
|
778
|
-
if arg_defn.type.list?
|
779
|
-
loaded_values = value.map { |val| load_application_object(arg_defn, loads, val, field_ctx.query.context) }
|
780
|
-
field_ctx.schema.after_any_lazies(loaded_values) { |result| result }
|
781
|
-
else
|
782
|
-
load_application_object(arg_defn, loads, value, field_ctx.query.context)
|
783
|
-
end
|
784
|
-
elsif arg_defn.type.list? && value.is_a?(Array)
|
785
|
-
field_ctx.schema.after_any_lazies(value, &:itself)
|
786
|
-
else
|
787
|
-
value
|
788
|
-
end
|
789
|
-
|
790
|
-
maybe_lazies << field_ctx.schema.after_lazy(loaded_value) do |loaded_value|
|
791
|
-
prepared_value = if arg_defn.prepare
|
792
|
-
arg_defn.prepare_value(obj, loaded_value)
|
793
|
-
else
|
794
|
-
loaded_value
|
795
|
-
end
|
796
|
-
|
797
|
-
ruby_kwargs[ruby_kwargs_key] = prepared_value
|
798
|
-
end
|
799
|
-
end
|
800
|
-
end
|
801
|
-
|
802
|
-
@extras.each do |extra_arg|
|
803
|
-
ruby_kwargs[extra_arg] = fetch_extra(extra_arg, field_ctx)
|
804
|
-
end
|
805
|
-
|
806
|
-
field_ctx.schema.after_any_lazies(maybe_lazies) do
|
807
|
-
ruby_kwargs
|
808
|
-
end
|
809
|
-
else
|
810
|
-
NO_ARGS
|
811
|
-
end
|
812
|
-
end
|
813
|
-
|
814
621
|
def public_send_field(unextended_obj, unextended_ruby_kwargs, query_ctx)
|
815
622
|
with_extensions(unextended_obj, unextended_ruby_kwargs, query_ctx) do |obj, ruby_kwargs|
|
816
623
|
begin
|
@@ -826,7 +633,7 @@ module GraphQL
|
|
826
633
|
# Find a way to resolve this field, checking:
|
827
634
|
#
|
828
635
|
# - A method on the type instance;
|
829
|
-
# - Hash keys, if the wrapped object is a hash
|
636
|
+
# - Hash keys, if the wrapped object is a hash;
|
830
637
|
# - A method on the wrapped object;
|
831
638
|
# - Or, raise not implemented.
|
832
639
|
#
|
@@ -848,8 +655,6 @@ module GraphQL
|
|
848
655
|
else
|
849
656
|
inner_object[@method_str]
|
850
657
|
end
|
851
|
-
elsif defined?(@hash_key) && obj.object.respond_to?(:[])
|
852
|
-
obj.object[@hash_key]
|
853
658
|
elsif obj.object.respond_to?(@method_sym)
|
854
659
|
method_to_call = @method_sym
|
855
660
|
method_receiver = obj.object
|
@@ -2,7 +2,6 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
4
|
class InputObject < GraphQL::Schema::Member
|
5
|
-
extend GraphQL::Schema::Member::AcceptsDefinition
|
6
5
|
extend Forwardable
|
7
6
|
extend GraphQL::Schema::Member::HasArguments
|
8
7
|
extend GraphQL::Schema::Member::HasArguments::ArgumentObjectLoader
|
@@ -13,49 +12,28 @@ module GraphQL
|
|
13
12
|
|
14
13
|
# @return [GraphQL::Query::Context] The context for this query
|
15
14
|
attr_reader :context
|
16
|
-
# @return [GraphQL::
|
15
|
+
# @return [GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
|
17
16
|
attr_reader :arguments
|
18
17
|
|
19
18
|
# Ruby-like hash behaviors, read-only
|
20
19
|
def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
|
21
20
|
|
22
|
-
def initialize(arguments
|
21
|
+
def initialize(arguments, ruby_kwargs:, context:, defaults_used:)
|
23
22
|
@context = context
|
24
|
-
|
25
|
-
|
26
|
-
@arguments = arguments
|
27
|
-
else
|
28
|
-
@arguments = self.class.arguments_class.new(arguments, context: context, defaults_used: defaults_used)
|
29
|
-
# Symbolized, underscored hash:
|
30
|
-
@ruby_style_hash = @arguments.to_kwargs
|
31
|
-
end
|
23
|
+
@ruby_style_hash = ruby_kwargs
|
24
|
+
@arguments = arguments
|
32
25
|
# Apply prepares, not great to have it duplicated here.
|
33
|
-
maybe_lazies = []
|
34
26
|
self.class.arguments(context).each_value do |arg_defn|
|
35
27
|
ruby_kwargs_key = arg_defn.keyword
|
36
|
-
|
37
28
|
if @ruby_style_hash.key?(ruby_kwargs_key)
|
38
|
-
loads = arg_defn.loads
|
39
|
-
# Resolvers do this loading themselves;
|
40
|
-
# With the interpreter, it's done during `coerce_arguments`
|
41
|
-
if loads && !arg_defn.from_resolver? && !context.interpreter?
|
42
|
-
value = @ruby_style_hash[ruby_kwargs_key]
|
43
|
-
loaded_value = arg_defn.load_and_authorize_value(self, value, context)
|
44
|
-
maybe_lazies << context.schema.after_lazy(loaded_value) do |loaded_value|
|
45
|
-
overwrite_argument(ruby_kwargs_key, loaded_value)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
29
|
# Weirdly, procs are applied during coercion, but not methods.
|
50
30
|
# Probably because these methods require a `self`.
|
51
|
-
if arg_defn.prepare.is_a?(Symbol) || context.nil?
|
31
|
+
if arg_defn.prepare.is_a?(Symbol) || context.nil?
|
52
32
|
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
|
53
33
|
overwrite_argument(ruby_kwargs_key, prepared_value)
|
54
34
|
end
|
55
35
|
end
|
56
36
|
end
|
57
|
-
|
58
|
-
@maybe_lazies = maybe_lazies
|
59
37
|
end
|
60
38
|
|
61
39
|
def to_h
|
@@ -68,12 +46,10 @@ module GraphQL
|
|
68
46
|
|
69
47
|
def prepare
|
70
48
|
if @context
|
71
|
-
@context
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
self
|
76
|
-
end
|
49
|
+
object = @context[:current_object]
|
50
|
+
# Pass this object's class with `as` so that messages are rendered correctly from inherited validators
|
51
|
+
Schema::Validator.validate!(self.class.validators, object, @context, @ruby_style_hash, as: self.class)
|
52
|
+
self
|
77
53
|
else
|
78
54
|
self
|
79
55
|
end
|
@@ -83,7 +59,6 @@ module GraphQL
|
|
83
59
|
# Authorize each argument (but this doesn't apply if `prepare` is implemented):
|
84
60
|
if value.respond_to?(:key?)
|
85
61
|
arguments(ctx).each do |_name, input_obj_arg|
|
86
|
-
input_obj_arg = input_obj_arg.type_class
|
87
62
|
if value.key?(input_obj_arg.keyword) &&
|
88
63
|
!input_obj_arg.authorized?(obj, value[input_obj_arg.keyword], ctx)
|
89
64
|
return false
|
@@ -132,9 +107,6 @@ module GraphQL
|
|
132
107
|
end
|
133
108
|
|
134
109
|
class << self
|
135
|
-
# @return [Class<GraphQL::Arguments>]
|
136
|
-
attr_accessor :arguments_class
|
137
|
-
|
138
110
|
def argument(*args, **kwargs, &block)
|
139
111
|
argument_defn = super(*args, **kwargs, &block)
|
140
112
|
# Add a method access
|
@@ -147,25 +119,6 @@ module GraphQL
|
|
147
119
|
argument_defn
|
148
120
|
end
|
149
121
|
|
150
|
-
prepend Schema::Member::CachedGraphQLDefinition::DeprecatedToGraphQL
|
151
|
-
|
152
|
-
def to_graphql
|
153
|
-
type_defn = GraphQL::InputObjectType.new
|
154
|
-
type_defn.name = graphql_name
|
155
|
-
type_defn.description = description
|
156
|
-
type_defn.metadata[:type_class] = self
|
157
|
-
type_defn.mutation = mutation
|
158
|
-
type_defn.ast_node = ast_node
|
159
|
-
all_argument_definitions.each do |arg|
|
160
|
-
type_defn.arguments[arg.graphql_definition(silence_deprecation_warning: true).name] = arg.graphql_definition(silence_deprecation_warning: true) # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
161
|
-
end
|
162
|
-
# Make a reference to a classic-style Arguments class
|
163
|
-
self.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(type_defn)
|
164
|
-
# But use this InputObject class at runtime
|
165
|
-
type_defn.arguments_class = self
|
166
|
-
type_defn
|
167
|
-
end
|
168
|
-
|
169
122
|
def kind
|
170
123
|
GraphQL::TypeKinds::INPUT_OBJECT
|
171
124
|
end
|
@@ -173,8 +126,9 @@ module GraphQL
|
|
173
126
|
# @api private
|
174
127
|
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object responding to `to_h` or `to_unsafe_h`."
|
175
128
|
|
176
|
-
def validate_non_null_input(input, ctx
|
129
|
+
def validate_non_null_input(input, ctx)
|
177
130
|
result = GraphQL::Query::InputValidationResult.new
|
131
|
+
|
178
132
|
warden = ctx.warden
|
179
133
|
|
180
134
|
if input.is_a?(Array)
|