graphql 1.12.25 → 1.13.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/generators/graphql/mutation_generator.rb +1 -1
- data/lib/generators/graphql/type_generator.rb +0 -1
- data/lib/graphql/analysis/ast/field_usage.rb +4 -8
- data/lib/graphql/analysis/ast/query_complexity.rb +10 -14
- data/lib/graphql/analysis/ast/visitor.rb +4 -4
- data/lib/graphql/backtrace/table.rb +1 -1
- data/lib/graphql/dataloader.rb +55 -22
- data/lib/graphql/directive.rb +0 -4
- data/lib/graphql/enum_type.rb +5 -1
- data/lib/graphql/execution/errors.rb +1 -0
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -2
- data/lib/graphql/execution/interpreter/runtime.rb +20 -12
- data/lib/graphql/execution/lookahead.rb +2 -2
- data/lib/graphql/execution/multiplex.rb +1 -1
- data/lib/graphql/introspection/directive_type.rb +1 -1
- data/lib/graphql/introspection/entry_points.rb +2 -2
- data/lib/graphql/introspection/enum_value_type.rb +2 -2
- data/lib/graphql/introspection/field_type.rb +2 -2
- data/lib/graphql/introspection/input_value_type.rb +4 -4
- data/lib/graphql/introspection/schema_type.rb +2 -2
- data/lib/graphql/introspection/type_type.rb +10 -10
- data/lib/graphql/language/block_string.rb +0 -4
- data/lib/graphql/language/document_from_schema_definition.rb +4 -2
- data/lib/graphql/language/lexer.rb +0 -3
- data/lib/graphql/language/lexer.rl +0 -4
- data/lib/graphql/language/nodes.rb +3 -14
- data/lib/graphql/language/parser.rb +442 -434
- data/lib/graphql/language/parser.y +5 -4
- data/lib/graphql/language/printer.rb +6 -1
- data/lib/graphql/language/sanitized_printer.rb +5 -5
- data/lib/graphql/language/token.rb +0 -4
- data/lib/graphql/name_validator.rb +0 -4
- data/lib/graphql/query/arguments.rb +1 -1
- data/lib/graphql/query/arguments_cache.rb +1 -1
- data/lib/graphql/query/context.rb +5 -2
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/query/null_context.rb +12 -7
- data/lib/graphql/query/serial_execution/field_resolution.rb +1 -1
- data/lib/graphql/query/variables.rb +5 -1
- data/lib/graphql/relay/edges_instrumentation.rb +0 -1
- data/lib/graphql/rubocop/graphql/base_cop.rb +36 -0
- data/lib/graphql/rubocop/graphql/default_null_true.rb +43 -0
- data/lib/graphql/rubocop/graphql/default_required_true.rb +43 -0
- data/lib/graphql/rubocop.rb +4 -0
- data/lib/graphql/schema/addition.rb +37 -28
- data/lib/graphql/schema/argument.rb +11 -9
- data/lib/graphql/schema/build_from_definition.rb +12 -13
- data/lib/graphql/schema/directive/feature.rb +1 -1
- data/lib/graphql/schema/directive/flagged.rb +2 -2
- data/lib/graphql/schema/directive/include.rb +1 -1
- data/lib/graphql/schema/directive/skip.rb +1 -1
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/directive.rb +2 -6
- data/lib/graphql/schema/enum.rb +57 -9
- data/lib/graphql/schema/enum_value.rb +5 -1
- data/lib/graphql/schema/field/connection_extension.rb +1 -1
- data/lib/graphql/schema/field.rb +92 -18
- data/lib/graphql/schema/find_inherited_value.rb +1 -0
- data/lib/graphql/schema/finder.rb +5 -5
- data/lib/graphql/schema/input_object.rb +11 -13
- data/lib/graphql/schema/interface.rb +8 -19
- data/lib/graphql/schema/member/accepts_definition.rb +8 -1
- data/lib/graphql/schema/member/build_type.rb +0 -4
- data/lib/graphql/schema/member/has_arguments.rb +55 -13
- data/lib/graphql/schema/member/has_deprecation_reason.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +76 -18
- data/lib/graphql/schema/member/has_interfaces.rb +90 -0
- data/lib/graphql/schema/member.rb +1 -0
- data/lib/graphql/schema/object.rb +7 -74
- data/lib/graphql/schema/printer.rb +1 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +29 -3
- data/lib/graphql/schema/resolver/has_payload_type.rb +27 -2
- data/lib/graphql/schema/resolver.rb +19 -5
- data/lib/graphql/schema/subscription.rb +11 -1
- data/lib/graphql/schema/type_expression.rb +1 -1
- data/lib/graphql/schema/type_membership.rb +18 -4
- data/lib/graphql/schema/union.rb +6 -1
- data/lib/graphql/schema/validator/format_validator.rb +0 -4
- data/lib/graphql/schema/validator/numericality_validator.rb +1 -0
- data/lib/graphql/schema/warden.rb +116 -52
- data/lib/graphql/schema.rb +87 -15
- data/lib/graphql/static_validation/base_visitor.rb +5 -5
- data/lib/graphql/static_validation/definition_dependencies.rb +0 -1
- data/lib/graphql/static_validation/literal_validator.rb +1 -1
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +8 -15
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -3
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +4 -4
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +7 -7
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +6 -4
- data/lib/graphql/subscriptions/event.rb +20 -12
- data/lib/graphql/subscriptions.rb +17 -19
- data/lib/graphql/types/relay/has_node_field.rb +1 -1
- data/lib/graphql/types/relay/has_nodes_field.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +9 -31
- metadata +14 -6
@@ -35,7 +35,7 @@ module GraphQL
|
|
35
35
|
GraphQL::Schema::Directive::INPUT_FIELD_DEFINITION,
|
36
36
|
)
|
37
37
|
|
38
|
-
argument :by, [String], "Flags to check for this schema member"
|
38
|
+
argument :by, [String], "Flags to check for this schema member"
|
39
39
|
|
40
40
|
module VisibleByFlag
|
41
41
|
def self.included(schema_class)
|
@@ -44,7 +44,7 @@ module GraphQL
|
|
44
44
|
|
45
45
|
def visible?(context)
|
46
46
|
if dir = self.directives.find { |d| d.is_a?(Flagged) }
|
47
|
-
relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f
|
47
|
+
relevant_flags = (f = context[:flags]) && dir.arguments[:by] & f # rubocop:disable Development/ContextIsPassedCop -- definition-related
|
48
48
|
relevant_flags && relevant_flags.any? && super
|
49
49
|
else
|
50
50
|
super
|
@@ -61,9 +61,9 @@ module GraphQL
|
|
61
61
|
defn.default_directive = self.default_directive
|
62
62
|
defn.ast_node = ast_node
|
63
63
|
defn.metadata[:type_class] = self
|
64
|
-
|
64
|
+
all_argument_definitions.each do |arg_defn|
|
65
65
|
arg_graphql = arg_defn.to_graphql
|
66
|
-
defn.arguments[arg_graphql.name] = arg_graphql
|
66
|
+
defn.arguments[arg_graphql.name] = arg_graphql # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
67
67
|
end
|
68
68
|
# Make a reference to a classic-style Arguments class
|
69
69
|
defn.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(defn)
|
@@ -116,10 +116,6 @@ module GraphQL
|
|
116
116
|
@arguments = self.class.coerce_arguments(nil, arguments, Query::NullContext)
|
117
117
|
end
|
118
118
|
|
119
|
-
def graphql_name
|
120
|
-
self.class.graphql_name
|
121
|
-
end
|
122
|
-
|
123
119
|
LOCATIONS = [
|
124
120
|
QUERY = :QUERY,
|
125
121
|
MUTATION = :MUTATION,
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -46,18 +46,66 @@ module GraphQL
|
|
46
46
|
def value(*args, **kwargs, &block)
|
47
47
|
kwargs[:owner] = self
|
48
48
|
value = enum_value_class.new(*args, **kwargs, &block)
|
49
|
-
|
50
|
-
|
49
|
+
key = value.graphql_name
|
50
|
+
prev_value = own_values[key]
|
51
|
+
case prev_value
|
52
|
+
when nil
|
53
|
+
own_values[key] = value
|
54
|
+
when GraphQL::Schema::EnumValue
|
55
|
+
own_values[key] = [prev_value, value]
|
56
|
+
when Array
|
57
|
+
prev_value << value
|
58
|
+
else
|
59
|
+
raise "Invariant: Unexpected enum value for #{key.inspect}: #{prev_value.inspect}"
|
60
|
+
end
|
61
|
+
value
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [Array<GraphQL::Schema::EnumValue>] Possible values of this enum
|
65
|
+
def enum_values(context = GraphQL::Query::NullContext)
|
66
|
+
inherited_values = superclass.respond_to?(:enum_values) ? superclass.enum_values(context) : nil
|
67
|
+
visible_values = []
|
68
|
+
warden = Warden.from_context(context)
|
69
|
+
own_values.each do |key, values_entry|
|
70
|
+
if (v = Warden.visible_entry?(:visible_enum_value?, values_entry, context, warden))
|
71
|
+
visible_values << v
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
if inherited_values
|
76
|
+
# Local values take precedence over inherited ones
|
77
|
+
inherited_values.each do |i_val|
|
78
|
+
if !visible_values.any? { |v| v.graphql_name == i_val.graphql_name }
|
79
|
+
visible_values << i_val
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
visible_values
|
85
|
+
end
|
86
|
+
|
87
|
+
# @return [Array<Schema::EnumValue>] An unfiltered list of all definitions
|
88
|
+
def all_enum_value_definitions
|
89
|
+
all_defns = if superclass.respond_to?(:all_enum_value_definitions)
|
90
|
+
superclass.all_enum_value_definitions
|
91
|
+
else
|
92
|
+
[]
|
51
93
|
end
|
52
|
-
|
53
|
-
|
94
|
+
|
95
|
+
@own_values && @own_values.each do |_key, value|
|
96
|
+
if value.is_a?(Array)
|
97
|
+
all_defns.concat(value)
|
98
|
+
else
|
99
|
+
all_defns << value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
all_defns
|
54
104
|
end
|
55
105
|
|
56
|
-
# @return [Hash<String => GraphQL::Schema::
|
57
|
-
def values
|
58
|
-
|
59
|
-
# Local values take precedence over inherited ones
|
60
|
-
inherited_values.merge(own_values)
|
106
|
+
# @return [Hash<String => GraphQL::Schema::EnumValue>] Possible values of this enum, keyed by name.
|
107
|
+
def values(context = GraphQL::Query::NullContext)
|
108
|
+
enum_values(context).each_with_object({}) { |val, obj| obj[val.graphql_name] = val }
|
61
109
|
end
|
62
110
|
|
63
111
|
# @return [GraphQL::EnumType]
|
@@ -55,7 +55,7 @@ module GraphQL
|
|
55
55
|
end
|
56
56
|
|
57
57
|
if block_given?
|
58
|
-
|
58
|
+
instance_eval(&block)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
@@ -85,6 +85,10 @@ module GraphQL
|
|
85
85
|
enum_value
|
86
86
|
end
|
87
87
|
|
88
|
+
def inspect
|
89
|
+
"#<#{self.class} #{path} @value=#{@value.inspect}#{description ? " @description=#{description.inspect}" : ""}>"
|
90
|
+
end
|
91
|
+
|
88
92
|
def visible?(_ctx); true; end
|
89
93
|
def accessible?(_ctx); true; end
|
90
94
|
def authorized?(_ctx); true; end
|
@@ -42,7 +42,7 @@ module GraphQL
|
|
42
42
|
value.after_value ||= original_arguments[:after]
|
43
43
|
value.last_value ||= original_arguments[:last]
|
44
44
|
value.before_value ||= original_arguments[:before]
|
45
|
-
value.arguments ||= original_arguments
|
45
|
+
value.arguments ||= original_arguments # rubocop:disable Development/ContextIsPassedCop -- unrelated .arguments method
|
46
46
|
value.field ||= field
|
47
47
|
if field.has_max_page_size? && !value.has_max_page_size_override?
|
48
48
|
value.max_page_size = field.max_page_size
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -5,10 +5,6 @@ require "graphql/schema/field/scope_extension"
|
|
5
5
|
module GraphQL
|
6
6
|
class Schema
|
7
7
|
class Field
|
8
|
-
if !String.method_defined?(:-@)
|
9
|
-
using GraphQL::StringDedupBackport
|
10
|
-
end
|
11
|
-
|
12
8
|
include GraphQL::Schema::Member::CachedGraphQLDefinition
|
13
9
|
include GraphQL::Schema::Member::AcceptsDefinition
|
14
10
|
include GraphQL::Schema::Member::HasArguments
|
@@ -61,7 +57,7 @@ module GraphQL
|
|
61
57
|
end
|
62
58
|
|
63
59
|
def inspect
|
64
|
-
"#<#{self.class} #{path}#{
|
60
|
+
"#<#{self.class} #{path}#{all_argument_definitions.any? ? "(...)" : ""}: #{type.to_type_signature}>"
|
65
61
|
end
|
66
62
|
|
67
63
|
alias :mutation :resolver
|
@@ -212,7 +208,7 @@ module GraphQL
|
|
212
208
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
213
209
|
# @param validates [Array<Hash>] Configurations for validating this field
|
214
210
|
# @param legacy_edge_class [Class, nil] (DEPRECATED) If present, pass this along to the legacy field definition
|
215
|
-
def initialize(type: nil, name: nil, owner: nil, null:
|
211
|
+
def initialize(type: nil, name: nil, owner: nil, null: true, field: nil, function: nil, description: nil, deprecation_reason: nil, method: nil, hash_key: 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)
|
216
212
|
if name.nil?
|
217
213
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
218
214
|
end
|
@@ -220,9 +216,6 @@ module GraphQL
|
|
220
216
|
if type.nil?
|
221
217
|
raise ArgumentError, "missing second `type` argument or keyword `type:`"
|
222
218
|
end
|
223
|
-
if null.nil?
|
224
|
-
raise ArgumentError, "missing keyword argument null:"
|
225
|
-
end
|
226
219
|
end
|
227
220
|
if (field || function || resolve) && extras.any?
|
228
221
|
raise ArgumentError, "keyword `extras:` may only be used with method-based resolve and class-based field such as mutation class, please remove `field:`, `function:` or `resolve:`"
|
@@ -231,7 +224,6 @@ module GraphQL
|
|
231
224
|
name_s = -name.to_s
|
232
225
|
@underscored_name = -Member::BuildType.underscore(name_s)
|
233
226
|
@name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
|
234
|
-
NameValidator.validate!(@name)
|
235
227
|
@description = description
|
236
228
|
if field.is_a?(GraphQL::Schema::Field)
|
237
229
|
raise ArgumentError, "Instead of passing a field as `field:`, use `add_field(field)` to add an already-defined field."
|
@@ -282,10 +274,15 @@ module GraphQL
|
|
282
274
|
@legacy_edge_class = legacy_edge_class
|
283
275
|
|
284
276
|
arguments.each do |name, arg|
|
285
|
-
|
277
|
+
case arg
|
278
|
+
when Hash
|
286
279
|
argument(name: name, **arg)
|
287
|
-
|
280
|
+
when GraphQL::Schema::Argument
|
288
281
|
add_argument(arg)
|
282
|
+
when Array
|
283
|
+
arg.each { |a| add_argument(a) }
|
284
|
+
else
|
285
|
+
raise ArgumentError, "Unexpected argument config (#{arg.class}): #{arg.inspect}"
|
289
286
|
end
|
290
287
|
end
|
291
288
|
|
@@ -412,6 +409,57 @@ module GraphQL
|
|
412
409
|
end
|
413
410
|
end
|
414
411
|
|
412
|
+
def calculate_complexity(query:, nodes:, child_complexity:)
|
413
|
+
if respond_to?(:complexity_for)
|
414
|
+
lookahead = GraphQL::Execution::Lookahead.new(query: query, field: self, ast_nodes: nodes, owner_type: owner)
|
415
|
+
complexity_for(child_complexity: child_complexity, query: query, lookahead: lookahead)
|
416
|
+
elsif connection?
|
417
|
+
arguments = query.arguments_for(nodes.first, self)
|
418
|
+
max_possible_page_size = nil
|
419
|
+
if arguments[:first]
|
420
|
+
max_possible_page_size = arguments[:first]
|
421
|
+
end
|
422
|
+
if arguments[:last] && (max_possible_page_size.nil? || arguments[:last] > max_possible_page_size)
|
423
|
+
max_possible_page_size = arguments[:last]
|
424
|
+
end
|
425
|
+
|
426
|
+
if max_possible_page_size.nil?
|
427
|
+
max_possible_page_size = max_page_size || query.schema.default_max_page_size
|
428
|
+
end
|
429
|
+
|
430
|
+
if max_possible_page_size.nil?
|
431
|
+
raise GraphQL::Error, "Can't calculate complexity for #{path}, no `first:`, `last:`, `max_page_size` or `default_max_page_size`"
|
432
|
+
else
|
433
|
+
metadata_complexity = 0
|
434
|
+
lookahead = GraphQL::Execution::Lookahead.new(query: query, field: self, ast_nodes: nodes, owner_type: owner)
|
435
|
+
|
436
|
+
if (page_info_lookahead = lookahead.selection(:page_info)).selected?
|
437
|
+
metadata_complexity += 1 # pageInfo
|
438
|
+
metadata_complexity += page_info_lookahead.selections.size # subfields
|
439
|
+
end
|
440
|
+
|
441
|
+
if lookahead.selects?(:total) || lookahead.selects?(:total_count) || lookahead.selects?(:count)
|
442
|
+
metadata_complexity += 1
|
443
|
+
end
|
444
|
+
# Possible bug: selections on `edges` and `nodes` are _both_ multiplied here. Should they be?
|
445
|
+
items_complexity = child_complexity - metadata_complexity
|
446
|
+
# Add 1 for _this_ field
|
447
|
+
1 + (max_possible_page_size * items_complexity) + metadata_complexity
|
448
|
+
end
|
449
|
+
else
|
450
|
+
defined_complexity = complexity
|
451
|
+
case defined_complexity
|
452
|
+
when Proc
|
453
|
+
arguments = query.arguments_for(nodes.first, self)
|
454
|
+
defined_complexity.call(query.context, arguments.keyword_arguments, child_complexity)
|
455
|
+
when Numeric
|
456
|
+
defined_complexity + child_complexity
|
457
|
+
else
|
458
|
+
raise("Invalid complexity: #{defined_complexity.inspect} on #{path} (#{inspect})")
|
459
|
+
end
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
415
463
|
def complexity(new_complexity = nil)
|
416
464
|
case new_complexity
|
417
465
|
when Proc
|
@@ -494,9 +542,9 @@ module GraphQL
|
|
494
542
|
field_defn.subscription_scope = @subscription_scope
|
495
543
|
field_defn.ast_node = ast_node
|
496
544
|
|
497
|
-
|
545
|
+
all_argument_definitions.each do |defn|
|
498
546
|
arg_graphql = defn.to_graphql
|
499
|
-
field_defn.arguments[arg_graphql.name] = arg_graphql
|
547
|
+
field_defn.arguments[arg_graphql.name] = arg_graphql # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
500
548
|
end
|
501
549
|
|
502
550
|
# Support a passed-in proc, one way or another
|
@@ -560,10 +608,36 @@ module GraphQL
|
|
560
608
|
# The resolver will check itself during `resolve()`
|
561
609
|
@resolver_class.authorized?(object, context)
|
562
610
|
else
|
611
|
+
if (arg_values = context[:current_arguments])
|
612
|
+
# ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
|
613
|
+
using_arg_values = true
|
614
|
+
arg_values = arg_values.argument_values
|
615
|
+
else
|
616
|
+
arg_values = args
|
617
|
+
using_arg_values = false
|
618
|
+
end
|
563
619
|
# Faster than `.any?`
|
564
|
-
arguments.each_value do |arg|
|
565
|
-
|
566
|
-
|
620
|
+
arguments(context).each_value do |arg|
|
621
|
+
arg_key = arg.keyword
|
622
|
+
if arg_values.key?(arg_key)
|
623
|
+
arg_value = arg_values[arg_key]
|
624
|
+
if using_arg_values
|
625
|
+
if arg_value.default_used?
|
626
|
+
# pass -- no auth required for default used
|
627
|
+
next
|
628
|
+
else
|
629
|
+
application_arg_value = arg_value.value
|
630
|
+
if application_arg_value.is_a?(GraphQL::Execution::Interpreter::Arguments)
|
631
|
+
application_arg_value.keyword_arguments
|
632
|
+
end
|
633
|
+
end
|
634
|
+
else
|
635
|
+
application_arg_value = arg_value
|
636
|
+
end
|
637
|
+
|
638
|
+
if !arg.authorized?(object, application_arg_value, context)
|
639
|
+
return false
|
640
|
+
end
|
567
641
|
end
|
568
642
|
end
|
569
643
|
true
|
@@ -660,7 +734,7 @@ module GraphQL
|
|
660
734
|
ruby_kwargs = graphql_args.to_kwargs
|
661
735
|
maybe_lazies = []
|
662
736
|
# Apply any `prepare` methods. Not great code organization, can this go somewhere better?
|
663
|
-
arguments.each do |name, arg_defn|
|
737
|
+
arguments(field_ctx).each do |name, arg_defn|
|
664
738
|
ruby_kwargs_key = arg_defn.keyword
|
665
739
|
|
666
740
|
if ruby_kwargs.key?(ruby_kwargs_key)
|
@@ -38,7 +38,7 @@ module GraphQL
|
|
38
38
|
|
39
39
|
find_in_directive(directive, path: path)
|
40
40
|
else
|
41
|
-
type = schema.get_type(type_or_directive)
|
41
|
+
type = schema.get_type(type_or_directive) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
42
42
|
|
43
43
|
if type.nil?
|
44
44
|
raise MemberNotFoundError, "Could not find type `#{type_or_directive}` in schema."
|
@@ -56,7 +56,7 @@ module GraphQL
|
|
56
56
|
|
57
57
|
def find_in_directive(directive, path:)
|
58
58
|
argument_name = path.shift
|
59
|
-
argument = directive.
|
59
|
+
argument = directive.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
60
60
|
|
61
61
|
if argument.nil?
|
62
62
|
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on directive #{directive}."
|
@@ -102,7 +102,7 @@ module GraphQL
|
|
102
102
|
|
103
103
|
def find_in_field(field, path:)
|
104
104
|
argument_name = path.shift
|
105
|
-
argument = field.
|
105
|
+
argument = field.get_argument(argument_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
106
106
|
|
107
107
|
if argument.nil?
|
108
108
|
raise MemberNotFoundError, "Could not find argument `#{argument_name}` on field `#{field.name}`."
|
@@ -119,7 +119,7 @@ module GraphQL
|
|
119
119
|
|
120
120
|
def find_in_input_object(input_object, path:)
|
121
121
|
field_name = path.shift
|
122
|
-
input_field = input_object.
|
122
|
+
input_field = input_object.get_argument(field_name) # rubocop:disable Development/ContextIsPassedCop -- build-time
|
123
123
|
|
124
124
|
if input_field.nil?
|
125
125
|
raise MemberNotFoundError, "Could not find input field `#{field_name}` on input object type `#{input_object.graphql_name}`."
|
@@ -136,7 +136,7 @@ module GraphQL
|
|
136
136
|
|
137
137
|
def find_in_enum_type(enum_type, path:)
|
138
138
|
value_name = path.shift
|
139
|
-
enum_value = enum_type.
|
139
|
+
enum_value = enum_type.enum_values.find { |v| v.graphql_name == value_name } # rubocop:disable Development/ContextIsPassedCop -- build-time, not runtime
|
140
140
|
|
141
141
|
if enum_value.nil?
|
142
142
|
raise MemberNotFoundError, "Could not find enum value `#{value_name}` on enum type `#{enum_type.graphql_name}`."
|
@@ -31,7 +31,7 @@ module GraphQL
|
|
31
31
|
end
|
32
32
|
# Apply prepares, not great to have it duplicated here.
|
33
33
|
maybe_lazies = []
|
34
|
-
self.class.arguments.each_value do |arg_defn|
|
34
|
+
self.class.arguments(context).each_value do |arg_defn|
|
35
35
|
ruby_kwargs_key = arg_defn.keyword
|
36
36
|
|
37
37
|
if @ruby_style_hash.key?(ruby_kwargs_key)
|
@@ -123,7 +123,12 @@ module GraphQL
|
|
123
123
|
def argument(*args, **kwargs, &block)
|
124
124
|
argument_defn = super(*args, **kwargs, &block)
|
125
125
|
# Add a method access
|
126
|
-
|
126
|
+
method_name = argument_defn.keyword
|
127
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
128
|
+
def #{method_name}
|
129
|
+
self[#{method_name.inspect}]
|
130
|
+
end
|
131
|
+
RUBY
|
127
132
|
argument_defn
|
128
133
|
end
|
129
134
|
|
@@ -134,8 +139,8 @@ module GraphQL
|
|
134
139
|
type_defn.metadata[:type_class] = self
|
135
140
|
type_defn.mutation = mutation
|
136
141
|
type_defn.ast_node = ast_node
|
137
|
-
|
138
|
-
type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition
|
142
|
+
all_argument_definitions.each do |arg|
|
143
|
+
type_defn.arguments[arg.graphql_definition.name] = arg.graphql_definition # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
139
144
|
end
|
140
145
|
# Make a reference to a classic-style Arguments class
|
141
146
|
self.arguments_class = GraphQL::Query::Arguments.construct_arguments_class(type_defn)
|
@@ -168,7 +173,7 @@ module GraphQL
|
|
168
173
|
end
|
169
174
|
|
170
175
|
# Inject missing required arguments
|
171
|
-
missing_required_inputs = self.arguments.reduce({}) do |m, (argument_name, argument)|
|
176
|
+
missing_required_inputs = self.arguments(ctx).reduce({}) do |m, (argument_name, argument)|
|
172
177
|
if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
|
173
178
|
m[argument_name] = nil
|
174
179
|
end
|
@@ -219,7 +224,7 @@ module GraphQL
|
|
219
224
|
|
220
225
|
result = {}
|
221
226
|
|
222
|
-
arguments.each do |input_key, input_field_defn|
|
227
|
+
arguments(ctx).each do |input_key, input_field_defn|
|
223
228
|
input_value = value[input_key]
|
224
229
|
if value.key?(input_key)
|
225
230
|
result[input_key] = if input_value.nil?
|
@@ -232,13 +237,6 @@ module GraphQL
|
|
232
237
|
|
233
238
|
result
|
234
239
|
end
|
235
|
-
|
236
|
-
private
|
237
|
-
|
238
|
-
def define_accessor_method(method_name)
|
239
|
-
define_method(method_name) { self[method_name] }
|
240
|
-
alias_method(method_name, method_name)
|
241
|
-
end
|
242
240
|
end
|
243
241
|
|
244
242
|
private
|
@@ -16,6 +16,7 @@ module GraphQL
|
|
16
16
|
include GraphQL::Schema::Member::HasAstNode
|
17
17
|
include GraphQL::Schema::Member::HasUnresolvedTypeError
|
18
18
|
include GraphQL::Schema::Member::HasDirectives
|
19
|
+
include GraphQL::Schema::Member::HasInterfaces
|
19
20
|
|
20
21
|
# Methods defined in this block will be:
|
21
22
|
# - Added as class methods to this interface
|
@@ -57,9 +58,10 @@ module GraphQL
|
|
57
58
|
child_class.extend(Schema::Interface::DefinitionMethods)
|
58
59
|
|
59
60
|
child_class.type_membership_class(self.type_membership_class)
|
60
|
-
child_class.
|
61
|
-
|
62
|
-
|
61
|
+
child_class.ancestors.reverse_each do |ancestor|
|
62
|
+
if ancestor.const_defined?(:DefinitionMethods)
|
63
|
+
child_class.extend(ancestor::DefinitionMethods)
|
64
|
+
end
|
63
65
|
end
|
64
66
|
|
65
67
|
# Use an instance variable to tell whether it's been included previously or not;
|
@@ -73,16 +75,13 @@ module GraphQL
|
|
73
75
|
end
|
74
76
|
child_class.introspection(introspection)
|
75
77
|
child_class.description(description)
|
76
|
-
if overridden_graphql_name
|
77
|
-
child_class.graphql_name(overridden_graphql_name)
|
78
|
-
end
|
79
78
|
# If interfaces are mixed into each other, only define this class once
|
80
79
|
if !child_class.const_defined?(:UnresolvedTypeError, false)
|
81
80
|
add_unresolved_type_error(child_class)
|
82
81
|
end
|
83
82
|
elsif child_class < GraphQL::Schema::Object
|
84
83
|
# This is being included into an object type, make sure it's using `implements(...)`
|
85
|
-
backtrace_line = caller(0, 10).find { |line| line.include?("schema/
|
84
|
+
backtrace_line = caller(0, 10).find { |line| line.include?("schema/member/has_interfaces.rb") && line.include?("in `implements'")}
|
86
85
|
if !backtrace_line
|
87
86
|
raise "Attach interfaces using `implements(#{self})`, not `include(#{self})`"
|
88
87
|
end
|
@@ -108,9 +107,9 @@ module GraphQL
|
|
108
107
|
type_defn.orphan_types = orphan_types
|
109
108
|
type_defn.type_membership_class = self.type_membership_class
|
110
109
|
type_defn.ast_node = ast_node
|
111
|
-
fields.each do |field_name, field_inst|
|
110
|
+
fields.each do |field_name, field_inst| # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
112
111
|
field_defn = field_inst.graphql_definition
|
113
|
-
type_defn.fields[field_defn.name] = field_defn
|
112
|
+
type_defn.fields[field_defn.name] = field_defn # rubocop:disable Development/ContextIsPassedCop -- legacy-related
|
114
113
|
end
|
115
114
|
type_defn.metadata[:type_class] = self
|
116
115
|
if respond_to?(:resolve_type)
|
@@ -122,16 +121,6 @@ module GraphQL
|
|
122
121
|
def kind
|
123
122
|
GraphQL::TypeKinds::INTERFACE
|
124
123
|
end
|
125
|
-
|
126
|
-
protected
|
127
|
-
|
128
|
-
def own_interfaces
|
129
|
-
@own_interfaces ||= []
|
130
|
-
end
|
131
|
-
|
132
|
-
def interfaces
|
133
|
-
own_interfaces + (own_interfaces.map { |i| i.own_interfaces }).flatten
|
134
|
-
end
|
135
124
|
end
|
136
125
|
|
137
126
|
# Extend this _after_ `DefinitionMethods` is defined, so it will be used
|
@@ -85,8 +85,15 @@ module GraphQL
|
|
85
85
|
define_method(name) do |*args|
|
86
86
|
if args.any?
|
87
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
|
88
96
|
end
|
89
|
-
instance_variable_get(ivar_name) || ((int = interfaces.first { |i| i.respond_to?()}) && int.public_send(name))
|
90
97
|
end
|
91
98
|
end
|
92
99
|
end
|
@@ -4,10 +4,6 @@ module GraphQL
|
|
4
4
|
class Member
|
5
5
|
# @api private
|
6
6
|
module BuildType
|
7
|
-
if !String.method_defined?(:match?)
|
8
|
-
using GraphQL::StringMatchBackport
|
9
|
-
end
|
10
|
-
|
11
7
|
LIST_TYPE_ERROR = "Use an array of [T] or [T, null: true] for list types; other arrays are not supported"
|
12
8
|
|
13
9
|
module_function
|