graphql 1.10.12 → 1.11.2
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.
- 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
|
|