graphql 1.10.10 → 1.11.1
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/object_generator.rb +50 -8
- data/lib/graphql.rb +3 -3
- data/lib/graphql/execution/interpreter.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments.rb +1 -5
- data/lib/graphql/execution/interpreter/runtime.rb +20 -24
- data/lib/graphql/execution/multiplex.rb +1 -2
- data/lib/graphql/introspection/schema_type.rb +3 -3
- data/lib/graphql/invalid_null_error.rb +18 -0
- data/lib/graphql/pagination/connection.rb +13 -6
- data/lib/graphql/pagination/connections.rb +5 -4
- data/lib/graphql/query.rb +1 -2
- data/lib/graphql/schema.rb +26 -3
- data/lib/graphql/schema/argument.rb +6 -0
- data/lib/graphql/schema/build_from_definition.rb +7 -12
- data/lib/graphql/schema/enum.rb +9 -1
- data/lib/graphql/schema/field.rb +68 -80
- data/lib/graphql/schema/field/connection_extension.rb +2 -1
- data/lib/graphql/schema/input_object.rb +1 -3
- data/lib/graphql/schema/interface.rb +5 -0
- data/lib/graphql/schema/member.rb +1 -0
- data/lib/graphql/schema/member/has_arguments.rb +6 -0
- data/lib/graphql/schema/member/has_fields.rb +1 -1
- data/lib/graphql/schema/member/has_unresolved_type_error.rb +15 -0
- data/lib/graphql/schema/object.rb +7 -0
- data/lib/graphql/schema/resolver.rb +14 -0
- data/lib/graphql/schema/subscription.rb +1 -1
- data/lib/graphql/schema/union.rb +6 -0
- data/lib/graphql/schema/warden.rb +0 -1
- data/lib/graphql/subscriptions.rb +41 -8
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +49 -5
- 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/subscription_root.rb +13 -3
- data/lib/graphql/tracing.rb +1 -27
- data/lib/graphql/tracing/new_relic_tracing.rb +1 -12
- data/lib/graphql/tracing/platform_tracing.rb +39 -15
- data/lib/graphql/tracing/scout_tracing.rb +11 -0
- data/lib/graphql/tracing/statsd_tracing.rb +42 -0
- data/lib/graphql/types/iso_8601_date.rb +1 -1
- data/lib/graphql/types/iso_8601_date_time.rb +17 -13
- data/lib/graphql/version.rb +1 -1
- metadata +6 -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
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -23,6 +23,9 @@ module GraphQL
|
|
23
23
|
extend GraphQL::Schema::Member::AcceptsDefinition
|
24
24
|
extend GraphQL::Schema::Member::ValidatesInput
|
25
25
|
|
26
|
+
class UnresolvedValueError < GraphQL::EnumType::UnresolvedValueError
|
27
|
+
end
|
28
|
+
|
26
29
|
class << self
|
27
30
|
# Define a value for this enum
|
28
31
|
# @param graphql_name [String, Symbol] the GraphQL value for this, usually `SCREAMING_CASE`
|
@@ -94,7 +97,7 @@ module GraphQL
|
|
94
97
|
if enum_value
|
95
98
|
enum_value.graphql_name
|
96
99
|
else
|
97
|
-
raise(
|
100
|
+
raise(self::UnresolvedValueError, "Can't resolve enum #{graphql_name} for #{value.inspect}")
|
98
101
|
end
|
99
102
|
end
|
100
103
|
|
@@ -112,6 +115,11 @@ module GraphQL
|
|
112
115
|
end
|
113
116
|
end
|
114
117
|
|
118
|
+
def inherited(child_class)
|
119
|
+
child_class.const_set(:UnresolvedValueError, Class.new(Schema::Enum::UnresolvedValueError))
|
120
|
+
super
|
121
|
+
end
|
122
|
+
|
115
123
|
private
|
116
124
|
|
117
125
|
def own_values
|
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)
|
@@ -556,34 +574,13 @@ module GraphQL
|
|
556
574
|
begin
|
557
575
|
# Unwrap the GraphQL object to get the application object.
|
558
576
|
application_object = object.object
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
else
|
566
|
-
extended_obj
|
567
|
-
end
|
568
|
-
@resolver_class.new(object: resolver_obj, context: ctx, field: self)
|
569
|
-
else
|
570
|
-
extended_obj
|
571
|
-
end
|
572
|
-
|
573
|
-
if field_receiver.respond_to?(@resolver_method)
|
574
|
-
# Call the method with kwargs, if there are any
|
575
|
-
if extended_args.any?
|
576
|
-
field_receiver.public_send(@resolver_method, **extended_args)
|
577
|
-
else
|
578
|
-
field_receiver.public_send(@resolver_method)
|
579
|
-
end
|
580
|
-
else
|
581
|
-
resolve_field_method(field_receiver, extended_args, ctx)
|
582
|
-
end
|
577
|
+
ctx.schema.after_lazy(self.authorized?(application_object, args, ctx)) do |is_authorized|
|
578
|
+
if is_authorized
|
579
|
+
public_send_field(object, args, ctx)
|
580
|
+
else
|
581
|
+
err = GraphQL::UnauthorizedFieldError.new(object: application_object, type: object.class, context: ctx, field: self)
|
582
|
+
ctx.schema.unauthorized_field(err)
|
583
583
|
end
|
584
|
-
else
|
585
|
-
err = GraphQL::UnauthorizedFieldError.new(object: application_object, type: object.class, context: ctx, field: self)
|
586
|
-
ctx.schema.unauthorized_field(err)
|
587
584
|
end
|
588
585
|
rescue GraphQL::UnauthorizedFieldError => err
|
589
586
|
err.field ||= self
|
@@ -595,43 +592,6 @@ module GraphQL
|
|
595
592
|
err
|
596
593
|
end
|
597
594
|
|
598
|
-
# Find a way to resolve this field, checking:
|
599
|
-
#
|
600
|
-
# - Hash keys, if the wrapped object is a hash;
|
601
|
-
# - A method on the wrapped object;
|
602
|
-
# - Or, raise not implemented.
|
603
|
-
#
|
604
|
-
# This can be overridden by defining a method on the object type.
|
605
|
-
# @param obj [GraphQL::Schema::Object]
|
606
|
-
# @param ruby_kwargs [Hash<Symbol => Object>]
|
607
|
-
# @param ctx [GraphQL::Query::Context]
|
608
|
-
def resolve_field_method(obj, ruby_kwargs, ctx)
|
609
|
-
if obj.object.is_a?(Hash)
|
610
|
-
inner_object = obj.object
|
611
|
-
if inner_object.key?(@method_sym)
|
612
|
-
inner_object[@method_sym]
|
613
|
-
else
|
614
|
-
inner_object[@method_str]
|
615
|
-
end
|
616
|
-
elsif obj.object.respond_to?(@method_sym)
|
617
|
-
if ruby_kwargs.any?
|
618
|
-
obj.object.public_send(@method_sym, **ruby_kwargs)
|
619
|
-
else
|
620
|
-
obj.object.public_send(@method_sym)
|
621
|
-
end
|
622
|
-
else
|
623
|
-
raise <<-ERR
|
624
|
-
Failed to implement #{@owner.graphql_name}.#{@name}, tried:
|
625
|
-
|
626
|
-
- `#{obj.class}##{@resolver_method}`, which did not exist
|
627
|
-
- `#{obj.object.class}##{@method_sym}`, which did not exist
|
628
|
-
- Looking up hash key `#{@method_sym.inspect}` or `#{@method_str.inspect}` on `#{obj.object}`, but it wasn't a Hash
|
629
|
-
|
630
|
-
To implement this field, define one of the methods above (and check for typos)
|
631
|
-
ERR
|
632
|
-
end
|
633
|
-
end
|
634
|
-
|
635
595
|
# @param ctx [GraphQL::Query::Context::FieldResolutionContext]
|
636
596
|
def fetch_extra(extra_name, ctx)
|
637
597
|
if extra_name != :path && extra_name != :ast_node && respond_to?(extra_name)
|
@@ -702,24 +662,52 @@ module GraphQL
|
|
702
662
|
end
|
703
663
|
end
|
704
664
|
|
705
|
-
def public_send_field(
|
706
|
-
query_ctx
|
707
|
-
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|
|
708
667
|
if @resolver_class
|
709
|
-
if
|
710
|
-
|
668
|
+
if obj.is_a?(GraphQL::Schema::Object)
|
669
|
+
obj = obj.object
|
711
670
|
end
|
712
|
-
|
671
|
+
obj = @resolver_class.new(object: obj, context: query_ctx, field: self)
|
713
672
|
end
|
714
673
|
|
715
|
-
|
716
|
-
|
717
|
-
|
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]
|
718
692
|
else
|
719
|
-
|
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)
|
720
700
|
end
|
721
701
|
else
|
722
|
-
|
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
|
723
711
|
end
|
724
712
|
end
|
725
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]
|
@@ -41,7 +42,7 @@ module GraphQL
|
|
41
42
|
value
|
42
43
|
elsif context.schema.new_connections?
|
43
44
|
wrappers = context.namespace(:connections)[:all_wrappers] ||= context.schema.connections.all_wrappers
|
44
|
-
context.schema.connections.wrap(field, value, arguments, context, wrappers: wrappers)
|
45
|
+
context.schema.connections.wrap(field, object.object, value, arguments, context, wrappers: wrappers)
|
45
46
|
else
|
46
47
|
if object.is_a?(GraphQL::Schema::Object)
|
47
48
|
object = object.object
|
@@ -21,10 +21,8 @@ module GraphQL
|
|
21
21
|
@ruby_style_hash = @arguments.to_kwargs
|
22
22
|
end
|
23
23
|
# Apply prepares, not great to have it duplicated here.
|
24
|
-
@arguments_by_keyword = {}
|
25
24
|
maybe_lazies = []
|
26
|
-
self.class.arguments.
|
27
|
-
@arguments_by_keyword[arg_defn.keyword] = arg_defn
|
25
|
+
self.class.arguments.each_value do |arg_defn|
|
28
26
|
ruby_kwargs_key = arg_defn.keyword
|
29
27
|
|
30
28
|
if @ruby_style_hash.key?(ruby_kwargs_key)
|
@@ -14,6 +14,7 @@ module GraphQL
|
|
14
14
|
include GraphQL::Schema::Member::RelayShortcuts
|
15
15
|
include GraphQL::Schema::Member::Scoped
|
16
16
|
include GraphQL::Schema::Member::HasAstNode
|
17
|
+
include GraphQL::Schema::Member::HasUnresolvedTypeError
|
17
18
|
|
18
19
|
# Methods defined in this block will be:
|
19
20
|
# - Added as class methods to this interface
|
@@ -74,6 +75,10 @@ module GraphQL
|
|
74
75
|
if overridden_graphql_name
|
75
76
|
child_class.graphql_name(overridden_graphql_name)
|
76
77
|
end
|
78
|
+
# If interfaces are mixed into each other, only define this class once
|
79
|
+
if !child_class.const_defined?(:UnresolvedTypeError, false)
|
80
|
+
add_unresolved_type_error(child_class)
|
81
|
+
end
|
77
82
|
elsif child_class < GraphQL::Schema::Object
|
78
83
|
# This is being included into an object type, make sure it's using `implements(...)`
|
79
84
|
backtrace_line = caller(0, 10).find { |line| line.include?("schema/object.rb") && line.include?("in `implements'")}
|
@@ -5,6 +5,7 @@ require 'graphql/schema/member/cached_graphql_definition'
|
|
5
5
|
require 'graphql/schema/member/graphql_type_names'
|
6
6
|
require 'graphql/schema/member/has_ast_node'
|
7
7
|
require 'graphql/schema/member/has_path'
|
8
|
+
require 'graphql/schema/member/has_unresolved_type_error'
|
8
9
|
require 'graphql/schema/member/relay_shortcuts'
|
9
10
|
require 'graphql/schema/member/scoped'
|
10
11
|
require 'graphql/schema/member/type_system_helpers'
|
@@ -135,6 +135,12 @@ module GraphQL
|
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
+
def arguments_statically_coercible?
|
139
|
+
return @arguments_statically_coercible if defined?(@arguments_statically_coercible)
|
140
|
+
|
141
|
+
@arguments_statically_coercible = arguments.each_value.all?(&:statically_coercible?)
|
142
|
+
end
|
143
|
+
|
138
144
|
module ArgumentClassAccessor
|
139
145
|
def argument_class(new_arg_class = nil)
|
140
146
|
if new_arg_class
|
@@ -47,7 +47,7 @@ module GraphQL
|
|
47
47
|
# A list of GraphQL-Ruby keywords.
|
48
48
|
#
|
49
49
|
# @api private
|
50
|
-
GRAPHQL_RUBY_KEYWORDS = [:context, :object, :method]
|
50
|
+
GRAPHQL_RUBY_KEYWORDS = [:context, :object, :method, :raw_value]
|
51
51
|
|
52
52
|
# A list of field names that we should advise users to pick a different
|
53
53
|
# resolve method name.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
class Member
|
6
|
+
# Set up a type-specific error to make debugging & bug tracker integration better
|
7
|
+
module HasUnresolvedTypeError
|
8
|
+
private
|
9
|
+
def add_unresolved_type_error(child_class)
|
10
|
+
child_class.const_set(:UnresolvedTypeError, Class.new(GraphQL::UnresolvedTypeError))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -71,6 +71,13 @@ module GraphQL
|
|
71
71
|
end
|
72
72
|
|
73
73
|
class << self
|
74
|
+
# Set up a type-specific invalid null error to use when this object's non-null fields wrongly return `nil`.
|
75
|
+
# It should help with debugging and bug tracker integrations.
|
76
|
+
def inherited(child_class)
|
77
|
+
child_class.const_set(:InvalidNullError, GraphQL::InvalidNullError.subclass_for(child_class))
|
78
|
+
super
|
79
|
+
end
|
80
|
+
|
74
81
|
def implements(*new_interfaces, **options)
|
75
82
|
new_memberships = []
|
76
83
|
new_interfaces.each do |int|
|
@@ -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
|
|
@@ -93,11 +93,11 @@ module GraphQL
|
|
93
93
|
raise UnsubscribedError
|
94
94
|
end
|
95
95
|
|
96
|
+
READING_SCOPE = ::Object.new
|
96
97
|
# Call this method to provide a new subscription_scope; OR
|
97
98
|
# call it without an argument to get the subscription_scope
|
98
99
|
# @param new_scope [Symbol]
|
99
100
|
# @return [Symbol]
|
100
|
-
READING_SCOPE = ::Object.new
|
101
101
|
def self.subscription_scope(new_scope = READING_SCOPE)
|
102
102
|
if new_scope != READING_SCOPE
|
103
103
|
@subscription_scope = new_scope
|