graphql 1.10.12 → 1.11.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/templates/graphql_controller.erb +11 -9
- data/lib/graphql.rb +3 -3
- data/lib/graphql/directive.rb +4 -0
- data/lib/graphql/execution/interpreter.rb +1 -1
- data/lib/graphql/execution/interpreter/runtime.rb +6 -4
- data/lib/graphql/execution/multiplex.rb +1 -2
- data/lib/graphql/field.rb +4 -0
- data/lib/graphql/input_object_type.rb +4 -0
- data/lib/graphql/introspection/schema_type.rb +3 -3
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/language/nodes.rb +1 -0
- data/lib/graphql/language/visitor.rb +2 -2
- data/lib/graphql/pagination/connection.rb +18 -13
- data/lib/graphql/pagination/connections.rb +17 -4
- data/lib/graphql/query.rb +1 -2
- data/lib/graphql/schema.rb +22 -16
- data/lib/graphql/schema/argument.rb +5 -0
- data/lib/graphql/schema/build_from_definition.rb +7 -12
- data/lib/graphql/schema/enum_value.rb +1 -0
- data/lib/graphql/schema/field.rb +63 -77
- data/lib/graphql/schema/field/connection_extension.rb +5 -1
- data/lib/graphql/schema/input_object.rb +16 -15
- data/lib/graphql/schema/loader.rb +19 -1
- data/lib/graphql/schema/member/has_arguments.rb +16 -0
- data/lib/graphql/schema/object.rb +1 -1
- data/lib/graphql/schema/resolver.rb +14 -0
- data/lib/graphql/schema/subscription.rb +1 -1
- data/lib/graphql/schema/union.rb +29 -0
- data/lib/graphql/schema/warden.rb +6 -1
- data/lib/graphql/static_validation/literal_validator.rb +7 -7
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +2 -2
- data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +1 -2
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +4 -2
- data/lib/graphql/subscriptions.rb +41 -8
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +66 -11
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +84 -0
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +21 -0
- data/lib/graphql/subscriptions/event.rb +16 -1
- data/lib/graphql/subscriptions/serialize.rb +22 -4
- data/lib/graphql/subscriptions/subscription_root.rb +3 -1
- data/lib/graphql/tracing.rb +1 -27
- data/lib/graphql/tracing/platform_tracing.rb +25 -15
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/version.rb +1 -1
- metadata +5 -2
@@ -43,9 +43,7 @@ module GraphQL
|
|
43
43
|
when GraphQL::Language::Nodes::EnumTypeDefinition
|
44
44
|
types[definition.name] = build_enum_type(definition, type_resolver)
|
45
45
|
when GraphQL::Language::Nodes::ObjectTypeDefinition
|
46
|
-
|
47
|
-
should_extend_subscription_root = is_subscription_root && interpreter
|
48
|
-
types[definition.name] = build_object_type(definition, type_resolver, default_resolve: default_resolve, extend_subscription_root: should_extend_subscription_root)
|
46
|
+
types[definition.name] = build_object_type(definition, type_resolver, default_resolve: default_resolve)
|
49
47
|
when GraphQL::Language::Nodes::InterfaceTypeDefinition
|
50
48
|
types[definition.name] = build_interface_type(definition, type_resolver)
|
51
49
|
when GraphQL::Language::Nodes::UnionTypeDefinition
|
@@ -204,7 +202,7 @@ module GraphQL
|
|
204
202
|
end
|
205
203
|
end
|
206
204
|
|
207
|
-
def build_object_type(object_type_definition, type_resolver, default_resolve
|
205
|
+
def build_object_type(object_type_definition, type_resolver, default_resolve:)
|
208
206
|
builder = self
|
209
207
|
type_def = nil
|
210
208
|
typed_resolve_fn = ->(field, obj, args, ctx) { default_resolve.call(type_def, field, obj, args, ctx) }
|
@@ -214,10 +212,6 @@ module GraphQL
|
|
214
212
|
graphql_name(object_type_definition.name)
|
215
213
|
description(object_type_definition.description)
|
216
214
|
ast_node(object_type_definition)
|
217
|
-
if extend_subscription_root
|
218
|
-
# This has to come before `field ...` configurations since it modifies them
|
219
|
-
extend Subscriptions::SubscriptionRoot
|
220
|
-
end
|
221
215
|
|
222
216
|
object_type_definition.interfaces.each do |interface_name|
|
223
217
|
interface_defn = type_resolver.call(interface_name)
|
@@ -303,7 +297,7 @@ module GraphQL
|
|
303
297
|
|
304
298
|
field_definitions.map do |field_definition|
|
305
299
|
type_name = resolve_type_name(field_definition.type)
|
306
|
-
|
300
|
+
resolve_method_name = "resolve_field_#{field_definition.name}"
|
307
301
|
owner.field(
|
308
302
|
field_definition.name,
|
309
303
|
description: field_definition.description,
|
@@ -315,14 +309,15 @@ module GraphQL
|
|
315
309
|
ast_node: field_definition,
|
316
310
|
method_conflict_warning: false,
|
317
311
|
camelize: false,
|
312
|
+
resolver_method: resolve_method_name,
|
318
313
|
) do
|
319
314
|
builder.build_arguments(self, field_definition.arguments, type_resolver)
|
320
315
|
|
321
316
|
# Don't do this for interfaces
|
322
317
|
if default_resolve
|
323
|
-
|
324
|
-
|
325
|
-
default_resolve.call(
|
318
|
+
owner.send(:define_method, resolve_method_name) do |**args|
|
319
|
+
field_instance = self.class.get_field(field_definition.name)
|
320
|
+
default_resolve.call(field_instance, object, args, context)
|
326
321
|
end
|
327
322
|
end
|
328
323
|
end
|
@@ -41,6 +41,7 @@ module GraphQL
|
|
41
41
|
|
42
42
|
def initialize(graphql_name, desc = nil, owner:, ast_node: nil, description: nil, value: nil, deprecation_reason: nil, &block)
|
43
43
|
@graphql_name = graphql_name.to_s
|
44
|
+
GraphQL::NameValidator.validate!(@graphql_name)
|
44
45
|
@description = desc || description
|
45
46
|
@value = value.nil? ? @graphql_name : value
|
46
47
|
@deprecation_reason = deprecation_reason
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -36,9 +36,18 @@ module GraphQL
|
|
36
36
|
# @return [Symbol] The method on the type to look up
|
37
37
|
attr_reader :resolver_method
|
38
38
|
|
39
|
-
# @return [Class] The
|
39
|
+
# @return [Class] The thing this field was defined on (type, mutation, resolver)
|
40
40
|
attr_accessor :owner
|
41
41
|
|
42
|
+
# @return [Class] The GraphQL type this field belongs to. (For fields defined on mutations, it's the payload type)
|
43
|
+
def owner_type
|
44
|
+
@owner_type ||= if owner < GraphQL::Schema::Mutation
|
45
|
+
owner.payload_type
|
46
|
+
else
|
47
|
+
owner
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
42
51
|
# @return [Symbol] the original name of the field, passed in by the user
|
43
52
|
attr_reader :original_name
|
44
53
|
|
@@ -191,9 +200,10 @@ module GraphQL
|
|
191
200
|
# @param subscription_scope [Symbol, String] A key in `context` which will be used to scope subscription payloads
|
192
201
|
# @param extensions [Array<Class, Hash<Class => Object>>] Named extensions to apply to this field (see also {#extension})
|
193
202
|
# @param trace [Boolean] If true, a {GraphQL::Tracing} tracer will measure this scalar field
|
203
|
+
# @param broadcastable [Boolean] Whether or not this field can be distributed in subscription broadcasts
|
194
204
|
# @param ast_node [Language::Nodes::FieldDefinition, nil] If this schema was parsed from definition, this AST node defined the field
|
195
205
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
196
|
-
def initialize(type: nil, name: nil, owner: nil, null: nil, 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: [], 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, arguments: EMPTY_HASH, &definition_block)
|
206
|
+
def initialize(type: nil, name: nil, owner: nil, null: nil, 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: [], 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, &definition_block)
|
197
207
|
if name.nil?
|
198
208
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
199
209
|
end
|
@@ -237,8 +247,8 @@ module GraphQL
|
|
237
247
|
end
|
238
248
|
|
239
249
|
# TODO: I think non-string/symbol hash keys are wrongly normalized (eg `1` will not work)
|
240
|
-
method_name = method || hash_key ||
|
241
|
-
resolver_method ||=
|
250
|
+
method_name = method || hash_key || name_s
|
251
|
+
resolver_method ||= name_s.to_sym
|
242
252
|
|
243
253
|
@method_str = method_name.to_s
|
244
254
|
@method_sym = method_name.to_sym
|
@@ -251,6 +261,7 @@ module GraphQL
|
|
251
261
|
@max_page_size = max_page_size == :not_given ? nil : max_page_size
|
252
262
|
@introspection = introspection
|
253
263
|
@extras = extras
|
264
|
+
@broadcastable = broadcastable
|
254
265
|
@resolver_class = resolver_class
|
255
266
|
@scope = scope
|
256
267
|
@trace = trace
|
@@ -295,6 +306,13 @@ module GraphQL
|
|
295
306
|
end
|
296
307
|
end
|
297
308
|
|
309
|
+
# If true, subscription updates with this field can be shared between viewers
|
310
|
+
# @return [Boolean, nil]
|
311
|
+
# @see GraphQL::Subscriptions::BroadcastAnalyzer
|
312
|
+
def broadcastable?
|
313
|
+
@broadcastable
|
314
|
+
end
|
315
|
+
|
298
316
|
# @param text [String]
|
299
317
|
# @return [String]
|
300
318
|
def description(text = nil)
|
@@ -534,7 +552,7 @@ module GraphQL
|
|
534
552
|
@resolve_proc.call(extended_obj, args, ctx)
|
535
553
|
end
|
536
554
|
else
|
537
|
-
public_send_field(after_obj, ruby_args,
|
555
|
+
public_send_field(after_obj, ruby_args, query_ctx)
|
538
556
|
end
|
539
557
|
else
|
540
558
|
err = GraphQL::UnauthorizedFieldError.new(object: inner_obj, type: obj.class, context: ctx, field: self)
|
@@ -558,30 +576,7 @@ module GraphQL
|
|
558
576
|
application_object = object.object
|
559
577
|
ctx.schema.after_lazy(self.authorized?(application_object, args, ctx)) do |is_authorized|
|
560
578
|
if is_authorized
|
561
|
-
|
562
|
-
with_extensions(object, args, ctx) do |extended_obj, extended_args|
|
563
|
-
field_receiver = if @resolver_class
|
564
|
-
resolver_obj = if extended_obj.is_a?(GraphQL::Schema::Object)
|
565
|
-
extended_obj.object
|
566
|
-
else
|
567
|
-
extended_obj
|
568
|
-
end
|
569
|
-
@resolver_class.new(object: resolver_obj, context: ctx, field: self)
|
570
|
-
else
|
571
|
-
extended_obj
|
572
|
-
end
|
573
|
-
|
574
|
-
if field_receiver.respond_to?(@resolver_method)
|
575
|
-
# Call the method with kwargs, if there are any
|
576
|
-
if extended_args.any?
|
577
|
-
field_receiver.public_send(@resolver_method, **extended_args)
|
578
|
-
else
|
579
|
-
field_receiver.public_send(@resolver_method)
|
580
|
-
end
|
581
|
-
else
|
582
|
-
resolve_field_method(field_receiver, extended_args, ctx)
|
583
|
-
end
|
584
|
-
end
|
579
|
+
public_send_field(object, args, ctx)
|
585
580
|
else
|
586
581
|
err = GraphQL::UnauthorizedFieldError.new(object: application_object, type: object.class, context: ctx, field: self)
|
587
582
|
ctx.schema.unauthorized_field(err)
|
@@ -597,43 +592,6 @@ module GraphQL
|
|
597
592
|
err
|
598
593
|
end
|
599
594
|
|
600
|
-
# Find a way to resolve this field, checking:
|
601
|
-
#
|
602
|
-
# - Hash keys, if the wrapped object is a hash;
|
603
|
-
# - A method on the wrapped object;
|
604
|
-
# - Or, raise not implemented.
|
605
|
-
#
|
606
|
-
# This can be overridden by defining a method on the object type.
|
607
|
-
# @param obj [GraphQL::Schema::Object]
|
608
|
-
# @param ruby_kwargs [Hash<Symbol => Object>]
|
609
|
-
# @param ctx [GraphQL::Query::Context]
|
610
|
-
def resolve_field_method(obj, ruby_kwargs, ctx)
|
611
|
-
if obj.object.is_a?(Hash)
|
612
|
-
inner_object = obj.object
|
613
|
-
if inner_object.key?(@method_sym)
|
614
|
-
inner_object[@method_sym]
|
615
|
-
else
|
616
|
-
inner_object[@method_str]
|
617
|
-
end
|
618
|
-
elsif obj.object.respond_to?(@method_sym)
|
619
|
-
if ruby_kwargs.any?
|
620
|
-
obj.object.public_send(@method_sym, **ruby_kwargs)
|
621
|
-
else
|
622
|
-
obj.object.public_send(@method_sym)
|
623
|
-
end
|
624
|
-
else
|
625
|
-
raise <<-ERR
|
626
|
-
Failed to implement #{@owner.graphql_name}.#{@name}, tried:
|
627
|
-
|
628
|
-
- `#{obj.class}##{@resolver_method}`, which did not exist
|
629
|
-
- `#{obj.object.class}##{@method_sym}`, which did not exist
|
630
|
-
- Looking up hash key `#{@method_sym.inspect}` or `#{@method_str.inspect}` on `#{obj.object}`, but it wasn't a Hash
|
631
|
-
|
632
|
-
To implement this field, define one of the methods above (and check for typos)
|
633
|
-
ERR
|
634
|
-
end
|
635
|
-
end
|
636
|
-
|
637
595
|
# @param ctx [GraphQL::Query::Context::FieldResolutionContext]
|
638
596
|
def fetch_extra(extra_name, ctx)
|
639
597
|
if extra_name != :path && extra_name != :ast_node && respond_to?(extra_name)
|
@@ -704,24 +662,52 @@ module GraphQL
|
|
704
662
|
end
|
705
663
|
end
|
706
664
|
|
707
|
-
def public_send_field(
|
708
|
-
query_ctx
|
709
|
-
with_extensions(obj, ruby_kwargs, query_ctx) do |extended_obj, extended_args|
|
665
|
+
def public_send_field(unextended_obj, unextended_ruby_kwargs, query_ctx)
|
666
|
+
with_extensions(unextended_obj, unextended_ruby_kwargs, query_ctx) do |obj, ruby_kwargs|
|
710
667
|
if @resolver_class
|
711
|
-
if
|
712
|
-
|
668
|
+
if obj.is_a?(GraphQL::Schema::Object)
|
669
|
+
obj = obj.object
|
713
670
|
end
|
714
|
-
|
671
|
+
obj = @resolver_class.new(object: obj, context: query_ctx, field: self)
|
715
672
|
end
|
716
673
|
|
717
|
-
|
718
|
-
|
719
|
-
|
674
|
+
# Find a way to resolve this field, checking:
|
675
|
+
#
|
676
|
+
# - A method on the type instance;
|
677
|
+
# - Hash keys, if the wrapped object is a hash;
|
678
|
+
# - A method on the wrapped object;
|
679
|
+
# - Or, raise not implemented.
|
680
|
+
#
|
681
|
+
if obj.respond_to?(@resolver_method)
|
682
|
+
# Call the method with kwargs, if there are any
|
683
|
+
if ruby_kwargs.any?
|
684
|
+
obj.public_send(@resolver_method, **ruby_kwargs)
|
685
|
+
else
|
686
|
+
obj.public_send(@resolver_method)
|
687
|
+
end
|
688
|
+
elsif obj.object.is_a?(Hash)
|
689
|
+
inner_object = obj.object
|
690
|
+
if inner_object.key?(@method_sym)
|
691
|
+
inner_object[@method_sym]
|
720
692
|
else
|
721
|
-
|
693
|
+
inner_object[@method_str]
|
694
|
+
end
|
695
|
+
elsif obj.object.respond_to?(@method_sym)
|
696
|
+
if ruby_kwargs.any?
|
697
|
+
obj.object.public_send(@method_sym, **ruby_kwargs)
|
698
|
+
else
|
699
|
+
obj.object.public_send(@method_sym)
|
722
700
|
end
|
723
701
|
else
|
724
|
-
|
702
|
+
raise <<-ERR
|
703
|
+
Failed to implement #{@owner.graphql_name}.#{@name}, tried:
|
704
|
+
|
705
|
+
- `#{obj.class}##{@resolver_method}`, which did not exist
|
706
|
+
- `#{obj.object.class}##{@method_sym}`, which did not exist
|
707
|
+
- Looking up hash key `#{@method_sym.inspect}` or `#{@method_str.inspect}` on `#{obj.object}`, but it wasn't a Hash
|
708
|
+
|
709
|
+
To implement this field, define one of the methods above (and check for typos)
|
710
|
+
ERR
|
725
711
|
end
|
726
712
|
end
|
727
713
|
end
|
@@ -31,6 +31,7 @@ module GraphQL
|
|
31
31
|
elsif value.is_a?(GraphQL::Pagination::Connection)
|
32
32
|
# update the connection with some things that may not have been provided
|
33
33
|
value.context ||= context
|
34
|
+
value.parent ||= object.object
|
34
35
|
value.first_value ||= arguments[:first]
|
35
36
|
value.after_value ||= arguments[:after]
|
36
37
|
value.last_value ||= arguments[:last]
|
@@ -38,10 +39,13 @@ module GraphQL
|
|
38
39
|
if field.has_max_page_size? && !value.has_max_page_size_override?
|
39
40
|
value.max_page_size = field.max_page_size
|
40
41
|
end
|
42
|
+
if (custom_t = context.schema.connections.edge_class_for_field(@field))
|
43
|
+
value.edge_class = custom_t
|
44
|
+
end
|
41
45
|
value
|
42
46
|
elsif context.schema.new_connections?
|
43
47
|
wrappers = context.namespace(:connections)[:all_wrappers] ||= context.schema.connections.all_wrappers
|
44
|
-
context.schema.connections.wrap(field, value, arguments, context, wrappers: wrappers)
|
48
|
+
context.schema.connections.wrap(field, object.object, value, arguments, context, wrappers: wrappers)
|
45
49
|
else
|
46
50
|
if object.is_a?(GraphQL::Schema::Object)
|
47
51
|
object = object.object
|
@@ -166,10 +166,7 @@ module GraphQL
|
|
166
166
|
return result
|
167
167
|
end
|
168
168
|
|
169
|
-
|
170
|
-
# using these methods to make sure that the object will
|
171
|
-
# behave like a hash below, when we call `each` on it.
|
172
|
-
begin
|
169
|
+
input = begin
|
173
170
|
input.to_h
|
174
171
|
rescue
|
175
172
|
begin
|
@@ -182,21 +179,25 @@ module GraphQL
|
|
182
179
|
end
|
183
180
|
end
|
184
181
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
if visible_arguments_map[name].nil?
|
190
|
-
result.add_problem("Field is not defined on #{self.graphql_name}", [name])
|
182
|
+
# Inject missing required arguments
|
183
|
+
missing_required_inputs = self.arguments.reduce({}) do |m, (argument_name, argument)|
|
184
|
+
if !input.key?(argument_name) && argument.type.non_null? && warden.get_argument(self, argument_name)
|
185
|
+
m[argument_name] = nil
|
191
186
|
end
|
187
|
+
|
188
|
+
m
|
192
189
|
end
|
193
190
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
result.
|
191
|
+
input.merge(missing_required_inputs).each do |argument_name, value|
|
192
|
+
argument = warden.get_argument(self, argument_name)
|
193
|
+
# Items in the input that are unexpected
|
194
|
+
unless argument
|
195
|
+
result.add_problem("Field is not defined on #{self.graphql_name}", [argument_name])
|
196
|
+
next
|
199
197
|
end
|
198
|
+
# Items in the input that are expected, but have invalid values
|
199
|
+
argument_result = argument.type.validate_input(value, ctx)
|
200
|
+
result.merge_result!(argument_name, argument_result) unless argument_result.valid?
|
200
201
|
end
|
201
202
|
|
202
203
|
result
|
@@ -25,8 +25,15 @@ module GraphQL
|
|
25
25
|
types[type["name"]] = type_object
|
26
26
|
end
|
27
27
|
|
28
|
+
directives = []
|
29
|
+
schema.fetch("directives", []).each do |directive|
|
30
|
+
next if GraphQL::Schema.default_directives.include?(directive.fetch("name"))
|
31
|
+
directives << define_directive(directive, type_resolver)
|
32
|
+
end
|
33
|
+
|
28
34
|
Class.new(GraphQL::Schema) do
|
29
35
|
orphan_types(types.values)
|
36
|
+
directives(directives)
|
30
37
|
|
31
38
|
def self.resolve_type(*)
|
32
39
|
raise(GraphQL::RequiredImplementationMissingError, "This schema was loaded from string, so it can't resolve types for objects")
|
@@ -98,7 +105,7 @@ module GraphQL
|
|
98
105
|
value(
|
99
106
|
enum_value["name"],
|
100
107
|
description: enum_value["description"],
|
101
|
-
deprecation_reason: enum_value["
|
108
|
+
deprecation_reason: enum_value["deprecationReason"],
|
102
109
|
)
|
103
110
|
end
|
104
111
|
end
|
@@ -147,6 +154,16 @@ module GraphQL
|
|
147
154
|
end
|
148
155
|
end
|
149
156
|
|
157
|
+
def define_directive(directive, type_resolver)
|
158
|
+
loader = self
|
159
|
+
Class.new(GraphQL::Schema::Directive) do
|
160
|
+
graphql_name(directive["name"])
|
161
|
+
description(directive["description"])
|
162
|
+
locations(*directive["locations"].map(&:to_sym))
|
163
|
+
loader.build_arguments(self, directive["args"], type_resolver)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
150
167
|
public
|
151
168
|
|
152
169
|
def build_fields(type_defn, fields, type_resolver)
|
@@ -156,6 +173,7 @@ module GraphQL
|
|
156
173
|
field_hash["name"],
|
157
174
|
type: type_resolver.call(field_hash["type"]),
|
158
175
|
description: field_hash["description"],
|
176
|
+
deprecation_reason: field_hash["deprecationReason"],
|
159
177
|
null: true,
|
160
178
|
camelize: false,
|
161
179
|
) do
|
@@ -58,6 +58,22 @@ module GraphQL
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
+
# @return [GraphQL::Schema::Argument, nil] Argument defined on this thing, fetched by name.
|
62
|
+
def get_argument(argument_name)
|
63
|
+
a = own_arguments[argument_name]
|
64
|
+
|
65
|
+
if a || !self.is_a?(Class)
|
66
|
+
a
|
67
|
+
else
|
68
|
+
for ancestor in ancestors
|
69
|
+
if ancestor.respond_to?(:own_arguments) && a = ancestor.own_arguments[argument_name]
|
70
|
+
return a
|
71
|
+
end
|
72
|
+
end
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
61
77
|
# @param new_arg_class [Class] A class to use for building argument definitions
|
62
78
|
def argument_class(new_arg_class = nil)
|
63
79
|
self.class.argument_class(new_arg_class)
|
@@ -74,7 +74,7 @@ module GraphQL
|
|
74
74
|
# Set up a type-specific invalid null error to use when this object's non-null fields wrongly return `nil`.
|
75
75
|
# It should help with debugging and bug tracker integrations.
|
76
76
|
def inherited(child_class)
|
77
|
-
child_class.const_set(:InvalidNullError,
|
77
|
+
child_class.const_set(:InvalidNullError, GraphQL::InvalidNullError.subclass_for(child_class))
|
78
78
|
super
|
79
79
|
end
|
80
80
|
|
@@ -250,6 +250,19 @@ module GraphQL
|
|
250
250
|
@complexity || (superclass.respond_to?(:complexity) ? superclass.complexity : 1)
|
251
251
|
end
|
252
252
|
|
253
|
+
def broadcastable(new_broadcastable)
|
254
|
+
@broadcastable = new_broadcastable
|
255
|
+
end
|
256
|
+
|
257
|
+
# @return [Boolean, nil]
|
258
|
+
def broadcastable?
|
259
|
+
if defined?(@broadcastable)
|
260
|
+
@broadcastable
|
261
|
+
else
|
262
|
+
(superclass.respond_to?(:broadcastable?) ? superclass.broadcastable? : nil)
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
253
266
|
def field_options
|
254
267
|
{
|
255
268
|
type: type_expr,
|
@@ -261,6 +274,7 @@ module GraphQL
|
|
261
274
|
null: null,
|
262
275
|
complexity: complexity,
|
263
276
|
extensions: extensions,
|
277
|
+
broadcastable: broadcastable?,
|
264
278
|
}
|
265
279
|
end
|
266
280
|
|