graphql 2.0.17.2 → 2.0.21
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/graphql/analysis/ast.rb +2 -2
- data/lib/graphql/backtrace/trace.rb +96 -0
- data/lib/graphql/backtrace/tracer.rb +1 -1
- data/lib/graphql/backtrace.rb +6 -1
- data/lib/graphql/execution/interpreter/arguments.rb +1 -1
- data/lib/graphql/execution/interpreter/arguments_cache.rb +2 -3
- data/lib/graphql/execution/interpreter/resolve.rb +19 -0
- data/lib/graphql/execution/interpreter/runtime.rb +254 -211
- data/lib/graphql/execution/interpreter.rb +9 -14
- data/lib/graphql/execution/lazy.rb +2 -4
- data/lib/graphql/execution/multiplex.rb +2 -1
- data/lib/graphql/filter.rb +7 -2
- data/lib/graphql/language/document_from_schema_definition.rb +25 -9
- data/lib/graphql/language/lexer.rb +216 -1505
- data/lib/graphql/language/nodes.rb +27 -9
- data/lib/graphql/language/parser.rb +509 -491
- data/lib/graphql/language/parser.y +43 -38
- data/lib/graphql/pagination/active_record_relation_connection.rb +0 -8
- data/lib/graphql/pagination/connection.rb +5 -5
- data/lib/graphql/query/context.rb +62 -31
- data/lib/graphql/query/null_context.rb +1 -1
- data/lib/graphql/query.rb +22 -5
- data/lib/graphql/schema/argument.rb +7 -9
- data/lib/graphql/schema/build_from_definition.rb +15 -3
- data/lib/graphql/schema/enum_value.rb +2 -5
- data/lib/graphql/schema/field.rb +44 -31
- data/lib/graphql/schema/field_extension.rb +1 -4
- data/lib/graphql/schema/find_inherited_value.rb +2 -7
- data/lib/graphql/schema/member/base_dsl_methods.rb +13 -11
- data/lib/graphql/schema/member/has_arguments.rb +1 -1
- data/lib/graphql/schema/member/has_ast_node.rb +12 -0
- data/lib/graphql/schema/member/has_deprecation_reason.rb +3 -4
- data/lib/graphql/schema/member/has_directives.rb +15 -10
- data/lib/graphql/schema/member/has_fields.rb +87 -37
- data/lib/graphql/schema/member/has_validators.rb +2 -2
- data/lib/graphql/schema/member/relay_shortcuts.rb +19 -0
- data/lib/graphql/schema/member/type_system_helpers.rb +1 -1
- data/lib/graphql/schema/object.rb +2 -4
- data/lib/graphql/schema/resolver/has_payload_type.rb +9 -9
- data/lib/graphql/schema/resolver.rb +4 -4
- data/lib/graphql/schema/timeout.rb +24 -28
- data/lib/graphql/schema/validator.rb +1 -1
- data/lib/graphql/schema/warden.rb +11 -2
- data/lib/graphql/schema.rb +72 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +12 -4
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -2
- data/lib/graphql/static_validation/validator.rb +1 -1
- data/lib/graphql/tracing/active_support_notifications_trace.rb +16 -0
- data/lib/graphql/tracing/appoptics_trace.rb +231 -0
- data/lib/graphql/tracing/appsignal_trace.rb +77 -0
- data/lib/graphql/tracing/data_dog_trace.rb +148 -0
- data/lib/graphql/tracing/legacy_trace.rb +65 -0
- data/lib/graphql/tracing/new_relic_trace.rb +75 -0
- data/lib/graphql/tracing/notifications_trace.rb +42 -0
- data/lib/graphql/tracing/platform_trace.rb +109 -0
- data/lib/graphql/tracing/platform_tracing.rb +15 -3
- data/lib/graphql/tracing/prometheus_trace.rb +89 -0
- data/lib/graphql/tracing/prometheus_tracing/graphql_collector.rb +1 -1
- data/lib/graphql/tracing/prometheus_tracing.rb +3 -3
- data/lib/graphql/tracing/scout_trace.rb +72 -0
- data/lib/graphql/tracing/statsd_trace.rb +56 -0
- data/lib/graphql/tracing/trace.rb +75 -0
- data/lib/graphql/tracing.rb +16 -39
- data/lib/graphql/type_kinds.rb +6 -3
- data/lib/graphql/types/relay/base_connection.rb +1 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +24 -2
- data/lib/graphql/types/relay/edge_behaviors.rb +16 -2
- data/lib/graphql/types/relay/node_behaviors.rb +7 -1
- data/lib/graphql/types/relay/page_info_behaviors.rb +7 -2
- data/lib/graphql/types/relay.rb +0 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +16 -9
- metadata +33 -8
- data/lib/graphql/language/lexer.rl +0 -280
- data/lib/graphql/types/relay/default_relay.rb +0 -27
data/lib/graphql/schema/field.rb
CHANGED
@@ -11,7 +11,7 @@ module GraphQL
|
|
11
11
|
include GraphQL::Schema::Member::HasPath
|
12
12
|
include GraphQL::Schema::Member::HasValidators
|
13
13
|
extend GraphQL::Schema::FindInheritedValue
|
14
|
-
include GraphQL::
|
14
|
+
include GraphQL::EmptyObjects
|
15
15
|
include GraphQL::Schema::Member::HasDirectives
|
16
16
|
include GraphQL::Schema::Member::HasDeprecationReason
|
17
17
|
|
@@ -219,7 +219,7 @@ module GraphQL
|
|
219
219
|
# @param method_conflict_warning [Boolean] If false, skip the warning if this field's method conflicts with a built-in method
|
220
220
|
# @param validates [Array<Hash>] Configurations for validating this field
|
221
221
|
# @fallback_value [Object] A fallback value if the method is not defined
|
222
|
-
def initialize(type: nil, name: nil, owner: nil, null: nil, description:
|
222
|
+
def initialize(type: nil, name: nil, owner: nil, null: nil, description: NOT_CONFIGURED, deprecation_reason: nil, method: nil, hash_key: nil, dig: nil, resolver_method: nil, connection: nil, max_page_size: NOT_CONFIGURED, default_page_size: NOT_CONFIGURED, scope: nil, introspection: false, camelize: true, trace: nil, complexity: nil, 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: NOT_CONFIGURED, arguments: EMPTY_HASH, directives: EMPTY_HASH, validates: EMPTY_ARRAY, fallback_value: NOT_CONFIGURED, &definition_block)
|
223
223
|
if name.nil?
|
224
224
|
raise ArgumentError, "missing first `name` argument or keyword `name:`"
|
225
225
|
end
|
@@ -233,9 +233,10 @@ module GraphQL
|
|
233
233
|
|
234
234
|
@underscored_name = -Member::BuildType.underscore(name_s)
|
235
235
|
@name = -(camelize ? Member::BuildType.camelize(name_s) : name_s)
|
236
|
-
|
237
|
-
|
238
|
-
|
236
|
+
|
237
|
+
@description = description
|
238
|
+
@type = @owner_type = @own_validators = @own_directives = @own_arguments = nil # these will be prepared later if necessary
|
239
|
+
|
239
240
|
self.deprecation_reason = deprecation_reason
|
240
241
|
|
241
242
|
if method && hash_key && dig
|
@@ -257,6 +258,9 @@ module GraphQL
|
|
257
258
|
if hash_key
|
258
259
|
@hash_key = hash_key
|
259
260
|
@hash_key_str = hash_key.to_s
|
261
|
+
else
|
262
|
+
@hash_key = NOT_CONFIGURED
|
263
|
+
@hash_key_str = NOT_CONFIGURED
|
260
264
|
end
|
261
265
|
|
262
266
|
@method_str = -method_name.to_s
|
@@ -272,15 +276,11 @@ module GraphQL
|
|
272
276
|
true
|
273
277
|
end
|
274
278
|
@connection = connection
|
275
|
-
@
|
276
|
-
@
|
277
|
-
@has_default_page_size = default_page_size != :not_given
|
278
|
-
@default_page_size = default_page_size == :not_given ? nil : default_page_size
|
279
|
+
@max_page_size = max_page_size
|
280
|
+
@default_page_size = default_page_size
|
279
281
|
@introspection = introspection
|
280
282
|
@extras = extras
|
281
|
-
|
282
|
-
@broadcastable = broadcastable
|
283
|
-
end
|
283
|
+
@broadcastable = broadcastable
|
284
284
|
@resolver_class = resolver_class
|
285
285
|
@scope = scope
|
286
286
|
@trace = trace
|
@@ -355,7 +355,7 @@ module GraphQL
|
|
355
355
|
# @return [Boolean, nil]
|
356
356
|
# @see GraphQL::Subscriptions::BroadcastAnalyzer
|
357
357
|
def broadcastable?
|
358
|
-
if
|
358
|
+
if !NOT_CONFIGURED.equal?(@broadcastable)
|
359
359
|
@broadcastable
|
360
360
|
elsif @resolver_class
|
361
361
|
@resolver_class.broadcastable?
|
@@ -369,10 +369,10 @@ module GraphQL
|
|
369
369
|
def description(text = nil)
|
370
370
|
if text
|
371
371
|
@description = text
|
372
|
-
elsif
|
372
|
+
elsif !NOT_CONFIGURED.equal?(@description)
|
373
373
|
@description
|
374
374
|
elsif @resolver_class
|
375
|
-
@
|
375
|
+
@resolver_class.description
|
376
376
|
else
|
377
377
|
nil
|
378
378
|
end
|
@@ -544,22 +544,34 @@ module GraphQL
|
|
544
544
|
|
545
545
|
# @return [Boolean] True if this field's {#max_page_size} should override the schema default.
|
546
546
|
def has_max_page_size?
|
547
|
-
@
|
547
|
+
!NOT_CONFIGURED.equal?(@max_page_size) || (@resolver_class && @resolver_class.has_max_page_size?)
|
548
548
|
end
|
549
549
|
|
550
550
|
# @return [Integer, nil] Applied to connections if {#has_max_page_size?}
|
551
551
|
def max_page_size
|
552
|
-
|
552
|
+
if !NOT_CONFIGURED.equal?(@max_page_size)
|
553
|
+
@max_page_size
|
554
|
+
elsif @resolver_class && @resolver_class.has_max_page_size?
|
555
|
+
@resolver_class.max_page_size
|
556
|
+
else
|
557
|
+
nil
|
558
|
+
end
|
553
559
|
end
|
554
560
|
|
555
561
|
# @return [Boolean] True if this field's {#default_page_size} should override the schema default.
|
556
562
|
def has_default_page_size?
|
557
|
-
@
|
563
|
+
!NOT_CONFIGURED.equal?(@default_page_size) || (@resolver_class && @resolver_class.has_default_page_size?)
|
558
564
|
end
|
559
565
|
|
560
566
|
# @return [Integer, nil] Applied to connections if {#has_default_page_size?}
|
561
567
|
def default_page_size
|
562
|
-
|
568
|
+
if !NOT_CONFIGURED.equal?(@default_page_size)
|
569
|
+
@default_page_size
|
570
|
+
elsif @resolver_class && @resolver_class.has_default_page_size?
|
571
|
+
@resolver_class.default_page_size
|
572
|
+
else
|
573
|
+
nil
|
574
|
+
end
|
563
575
|
end
|
564
576
|
|
565
577
|
class MissingReturnTypeError < GraphQL::Error; end
|
@@ -596,15 +608,16 @@ module GraphQL
|
|
596
608
|
# The resolver _instance_ will check itself during `resolve()`
|
597
609
|
@resolver_class.authorized?(object, context)
|
598
610
|
else
|
599
|
-
if (arg_values = context[:current_arguments])
|
600
|
-
# ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
|
601
|
-
using_arg_values = true
|
602
|
-
arg_values = arg_values.argument_values
|
603
|
-
else
|
604
|
-
arg_values = args
|
605
|
-
using_arg_values = false
|
606
|
-
end
|
607
611
|
if args.size > 0
|
612
|
+
if (arg_values = context[:current_arguments])
|
613
|
+
# ^^ that's provided by the interpreter at runtime, and includes info about whether the default value was used or not.
|
614
|
+
using_arg_values = true
|
615
|
+
arg_values = arg_values.argument_values
|
616
|
+
else
|
617
|
+
arg_values = args
|
618
|
+
using_arg_values = false
|
619
|
+
end
|
620
|
+
|
608
621
|
args = context.warden.arguments(self)
|
609
622
|
args.each do |arg|
|
610
623
|
arg_key = arg.keyword
|
@@ -661,7 +674,7 @@ module GraphQL
|
|
661
674
|
|
662
675
|
inner_object = obj.object
|
663
676
|
|
664
|
-
if
|
677
|
+
if !NOT_CONFIGURED.equal?(@hash_key)
|
665
678
|
hash_value = if inner_object.is_a?(Hash)
|
666
679
|
inner_object.key?(@hash_key) ? inner_object[@hash_key] : inner_object[@hash_key_str]
|
667
680
|
elsif inner_object.respond_to?(:[])
|
@@ -672,7 +685,7 @@ module GraphQL
|
|
672
685
|
if hash_value == false
|
673
686
|
hash_value
|
674
687
|
else
|
675
|
-
hash_value || (@fallback_value !=
|
688
|
+
hash_value || (@fallback_value != NOT_CONFIGURED ? @fallback_value : nil)
|
676
689
|
end
|
677
690
|
elsif obj.respond_to?(resolver_method)
|
678
691
|
method_to_call = resolver_method
|
@@ -690,7 +703,7 @@ module GraphQL
|
|
690
703
|
inner_object[@method_sym]
|
691
704
|
elsif inner_object.key?(@method_str)
|
692
705
|
inner_object[@method_str]
|
693
|
-
elsif @fallback_value !=
|
706
|
+
elsif @fallback_value != NOT_CONFIGURED
|
694
707
|
@fallback_value
|
695
708
|
else
|
696
709
|
nil
|
@@ -703,7 +716,7 @@ module GraphQL
|
|
703
716
|
else
|
704
717
|
inner_object.public_send(@method_sym)
|
705
718
|
end
|
706
|
-
elsif @fallback_value !=
|
719
|
+
elsif @fallback_value != NOT_CONFIGURED
|
707
720
|
@fallback_value
|
708
721
|
else
|
709
722
|
raise <<-ERR
|
@@ -71,14 +71,11 @@ module GraphQL
|
|
71
71
|
elsif inherited_extras
|
72
72
|
inherited_extras
|
73
73
|
else
|
74
|
-
|
74
|
+
GraphQL::EmptyObjects::EMPTY_ARRAY
|
75
75
|
end
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
NO_EXTRAS = [].freeze
|
80
|
-
private_constant :NO_EXTRAS
|
81
|
-
|
82
79
|
# Called when this extension is attached to a field.
|
83
80
|
# The field definition may be extended during this method.
|
84
81
|
# @return [void]
|
@@ -2,17 +2,12 @@
|
|
2
2
|
module GraphQL
|
3
3
|
class Schema
|
4
4
|
module FindInheritedValue
|
5
|
-
module EmptyObjects
|
6
|
-
EMPTY_HASH = {}.freeze
|
7
|
-
EMPTY_ARRAY = [].freeze
|
8
|
-
end
|
9
|
-
|
10
5
|
def self.extended(child_cls)
|
11
|
-
child_cls.singleton_class.include(EmptyObjects)
|
6
|
+
child_cls.singleton_class.include(GraphQL::EmptyObjects)
|
12
7
|
end
|
13
8
|
|
14
9
|
def self.included(child_cls)
|
15
|
-
child_cls.include(EmptyObjects)
|
10
|
+
child_cls.include(GraphQL::EmptyObjects)
|
16
11
|
end
|
17
12
|
|
18
13
|
private
|
@@ -46,7 +46,7 @@ module GraphQL
|
|
46
46
|
elsif defined?(@description)
|
47
47
|
@description
|
48
48
|
else
|
49
|
-
nil
|
49
|
+
@description = nil
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -56,8 +56,12 @@ module GraphQL
|
|
56
56
|
def inherited(child_class)
|
57
57
|
child_class.introspection(introspection)
|
58
58
|
child_class.description(description)
|
59
|
-
|
59
|
+
child_class.default_graphql_name = nil
|
60
|
+
|
61
|
+
if defined?(@graphql_name) && @graphql_name && (self.name.nil? || graphql_name != default_graphql_name)
|
60
62
|
child_class.graphql_name(graphql_name)
|
63
|
+
else
|
64
|
+
child_class.graphql_name = nil
|
61
65
|
end
|
62
66
|
super
|
63
67
|
end
|
@@ -98,7 +102,8 @@ module GraphQL
|
|
98
102
|
def default_graphql_name
|
99
103
|
@default_graphql_name ||= begin
|
100
104
|
raise GraphQL::RequiredImplementationMissingError, 'Anonymous class should declare a `graphql_name`' if name.nil?
|
101
|
-
-name.split("::").last.sub(/Type\Z/, "")
|
105
|
+
-name.split("::").last.sub(/Type\Z/, "")
|
106
|
+
end
|
102
107
|
end
|
103
108
|
|
104
109
|
def visible?(context)
|
@@ -109,16 +114,13 @@ module GraphQL
|
|
109
114
|
true
|
110
115
|
end
|
111
116
|
|
112
|
-
|
113
|
-
|
114
|
-
|
117
|
+
def default_relay
|
118
|
+
false
|
119
|
+
end
|
115
120
|
|
116
|
-
|
121
|
+
protected
|
117
122
|
|
118
|
-
|
119
|
-
super
|
120
|
-
subclass.default_graphql_name = nil
|
121
|
-
end
|
123
|
+
attr_writer :default_graphql_name, :graphql_name
|
122
124
|
end
|
123
125
|
end
|
124
126
|
end
|
@@ -3,6 +3,16 @@ module GraphQL
|
|
3
3
|
class Schema
|
4
4
|
class Member
|
5
5
|
module HasAstNode
|
6
|
+
def self.extended(child_cls)
|
7
|
+
super
|
8
|
+
child_cls.ast_node = nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def inherited(child_cls)
|
12
|
+
super
|
13
|
+
child_cls.ast_node = nil
|
14
|
+
end
|
15
|
+
|
6
16
|
# If this schema was parsed from a `.graphql` file (or other SDL),
|
7
17
|
# this is the AST node that defined this part of the schema.
|
8
18
|
def ast_node(new_ast_node = nil)
|
@@ -14,6 +24,8 @@ module GraphQL
|
|
14
24
|
nil
|
15
25
|
end
|
16
26
|
end
|
27
|
+
|
28
|
+
attr_writer :ast_node
|
17
29
|
end
|
18
30
|
end
|
19
31
|
end
|
@@ -5,17 +5,16 @@ module GraphQL
|
|
5
5
|
class Member
|
6
6
|
module HasDeprecationReason
|
7
7
|
# @return [String, nil] Explains why this member was deprecated (if present, this will be marked deprecated in introspection)
|
8
|
-
|
9
|
-
dir = self.directives.find { |d| d.is_a?(GraphQL::Schema::Directive::Deprecated) }
|
10
|
-
dir && dir.arguments[:reason] # rubocop:disable Development/ContextIsPassedCop -- definition-related
|
11
|
-
end
|
8
|
+
attr_reader :deprecation_reason
|
12
9
|
|
13
10
|
# Set the deprecation reason for this member, or remove it by assigning `nil`
|
14
11
|
# @param text [String, nil]
|
15
12
|
def deprecation_reason=(text)
|
13
|
+
@deprecation_reason = text
|
16
14
|
if text.nil?
|
17
15
|
remove_directive(GraphQL::Schema::Directive::Deprecated)
|
18
16
|
else
|
17
|
+
# This removes a previously-attached directive, if there is one:
|
19
18
|
directive(GraphQL::Schema::Directive::Deprecated, reason: text)
|
20
19
|
end
|
21
20
|
end
|
@@ -4,6 +4,16 @@ module GraphQL
|
|
4
4
|
class Schema
|
5
5
|
class Member
|
6
6
|
module HasDirectives
|
7
|
+
def self.extended(child_cls)
|
8
|
+
super
|
9
|
+
child_cls.module_eval { self.own_directives = nil }
|
10
|
+
end
|
11
|
+
|
12
|
+
def inherited(child_cls)
|
13
|
+
super
|
14
|
+
child_cls.own_directives = nil
|
15
|
+
end
|
16
|
+
|
7
17
|
# Create an instance of `dir_class` for `self`, using `options`.
|
8
18
|
#
|
9
19
|
# It removes a previously-attached instance of `dir_class`, if there is one.
|
@@ -23,8 +33,6 @@ module GraphQL
|
|
23
33
|
nil
|
24
34
|
end
|
25
35
|
|
26
|
-
NO_DIRECTIVES = [].freeze
|
27
|
-
|
28
36
|
def directives
|
29
37
|
HasDirectives.get_directives(self, @own_directives, :directives)
|
30
38
|
end
|
@@ -45,7 +53,7 @@ module GraphQL
|
|
45
53
|
inherited_directives = if schema_member.superclass.respond_to?(directives_method)
|
46
54
|
get_directives(schema_member.superclass, schema_member.superclass.public_send(directives_method), directives_method)
|
47
55
|
else
|
48
|
-
|
56
|
+
GraphQL::EmptyObjects::EMPTY_ARRAY
|
49
57
|
end
|
50
58
|
if inherited_directives.any? && directives
|
51
59
|
dirs = []
|
@@ -57,7 +65,7 @@ module GraphQL
|
|
57
65
|
elsif inherited_directives.any?
|
58
66
|
inherited_directives
|
59
67
|
else
|
60
|
-
|
68
|
+
GraphQL::EmptyObjects::EMPTY_ARRAY
|
61
69
|
end
|
62
70
|
when Module
|
63
71
|
dirs = nil
|
@@ -72,9 +80,9 @@ module GraphQL
|
|
72
80
|
dirs ||= []
|
73
81
|
merge_directives(dirs, directives)
|
74
82
|
end
|
75
|
-
dirs ||
|
83
|
+
dirs || GraphQL::EmptyObjects::EMPTY_ARRAY
|
76
84
|
when HasDirectives
|
77
|
-
directives ||
|
85
|
+
directives || GraphQL::EmptyObjects::EMPTY_ARRAY
|
78
86
|
else
|
79
87
|
raise "Invariant: how could #{schema_member} not be a Class, Module, or instance of HasDirectives?"
|
80
88
|
end
|
@@ -101,12 +109,9 @@ module GraphQL
|
|
101
109
|
end
|
102
110
|
end
|
103
111
|
|
104
|
-
|
105
112
|
protected
|
106
113
|
|
107
|
-
|
108
|
-
@own_directives
|
109
|
-
end
|
114
|
+
attr_accessor :own_directives
|
110
115
|
end
|
111
116
|
end
|
112
117
|
end
|
@@ -14,42 +14,6 @@ module GraphQL
|
|
14
14
|
field_defn
|
15
15
|
end
|
16
16
|
|
17
|
-
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
|
18
|
-
def fields(context = GraphQL::Query::NullContext)
|
19
|
-
warden = Warden.from_context(context)
|
20
|
-
is_object = self.respond_to?(:kind) && self.kind.object?
|
21
|
-
# Local overrides take precedence over inherited fields
|
22
|
-
visible_fields = {}
|
23
|
-
for ancestor in ancestors
|
24
|
-
if ancestor.respond_to?(:own_fields) &&
|
25
|
-
(is_object ? visible_interface_implementation?(ancestor, context, warden) : true)
|
26
|
-
|
27
|
-
ancestor.own_fields.each do |field_name, fields_entry|
|
28
|
-
# Choose the most local definition that passes `.visible?` --
|
29
|
-
# stop checking for fields by name once one has been found.
|
30
|
-
if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
|
31
|
-
visible_fields[field_name] = f
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
visible_fields
|
37
|
-
end
|
38
|
-
|
39
|
-
def get_field(field_name, context = GraphQL::Query::NullContext)
|
40
|
-
warden = Warden.from_context(context)
|
41
|
-
is_object = self.respond_to?(:kind) && self.kind.object?
|
42
|
-
for ancestor in ancestors
|
43
|
-
if ancestor.respond_to?(:own_fields) &&
|
44
|
-
(is_object ? visible_interface_implementation?(ancestor, context, warden) : true) &&
|
45
|
-
(f_entry = ancestor.own_fields[field_name]) &&
|
46
|
-
(f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
|
47
|
-
return f
|
48
|
-
end
|
49
|
-
end
|
50
|
-
nil
|
51
|
-
end
|
52
|
-
|
53
17
|
# A list of Ruby keywords.
|
54
18
|
#
|
55
19
|
# @api private
|
@@ -72,7 +36,12 @@ module GraphQL
|
|
72
36
|
def add_field(field_defn, method_conflict_warning: field_defn.method_conflict_warning?)
|
73
37
|
# Check that `field_defn.original_name` equals `resolver_method` and `method_sym` --
|
74
38
|
# that shows that no override value was given manually.
|
75
|
-
if method_conflict_warning &&
|
39
|
+
if method_conflict_warning &&
|
40
|
+
CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method) &&
|
41
|
+
field_defn.original_name == field_defn.resolver_method &&
|
42
|
+
field_defn.original_name == field_defn.method_sym &&
|
43
|
+
field_defn.hash_key == NOT_CONFIGURED &&
|
44
|
+
field_defn.dig_keys.nil?
|
76
45
|
warn(conflict_field_name_warning(field_defn))
|
77
46
|
end
|
78
47
|
prev_defn = own_fields[field_defn.name]
|
@@ -127,12 +96,93 @@ module GraphQL
|
|
127
96
|
all_fields
|
128
97
|
end
|
129
98
|
|
99
|
+
module InterfaceMethods
|
100
|
+
def get_field(field_name, context = GraphQL::Query::NullContext)
|
101
|
+
warden = Warden.from_context(context)
|
102
|
+
for ancestor in ancestors
|
103
|
+
if ancestor.respond_to?(:own_fields) &&
|
104
|
+
(f_entry = ancestor.own_fields[field_name]) &&
|
105
|
+
(f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
|
106
|
+
return f
|
107
|
+
end
|
108
|
+
end
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
|
112
|
+
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
|
113
|
+
def fields(context = GraphQL::Query::NullContext)
|
114
|
+
warden = Warden.from_context(context)
|
115
|
+
# Local overrides take precedence over inherited fields
|
116
|
+
visible_fields = {}
|
117
|
+
for ancestor in ancestors
|
118
|
+
if ancestor.respond_to?(:own_fields)
|
119
|
+
ancestor.own_fields.each do |field_name, fields_entry|
|
120
|
+
# Choose the most local definition that passes `.visible?` --
|
121
|
+
# stop checking for fields by name once one has been found.
|
122
|
+
if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
|
123
|
+
visible_fields[field_name] = f
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
visible_fields
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
module ObjectMethods
|
133
|
+
def get_field(field_name, context = GraphQL::Query::NullContext)
|
134
|
+
# Objects need to check that the interface implementation is visible, too
|
135
|
+
warden = Warden.from_context(context)
|
136
|
+
for ancestor in ancestors
|
137
|
+
if ancestor.respond_to?(:own_fields) &&
|
138
|
+
visible_interface_implementation?(ancestor, context, warden) &&
|
139
|
+
(f_entry = ancestor.own_fields[field_name]) &&
|
140
|
+
(f = Warden.visible_entry?(:visible_field?, f_entry, context, warden))
|
141
|
+
return f
|
142
|
+
end
|
143
|
+
end
|
144
|
+
nil
|
145
|
+
end
|
146
|
+
|
147
|
+
# @return [Hash<String => GraphQL::Schema::Field>] Fields on this object, keyed by name, including inherited fields
|
148
|
+
def fields(context = GraphQL::Query::NullContext)
|
149
|
+
# Objects need to check that the interface implementation is visible, too
|
150
|
+
warden = Warden.from_context(context)
|
151
|
+
# Local overrides take precedence over inherited fields
|
152
|
+
visible_fields = {}
|
153
|
+
for ancestor in ancestors
|
154
|
+
if ancestor.respond_to?(:own_fields) && visible_interface_implementation?(ancestor, context, warden)
|
155
|
+
ancestor.own_fields.each do |field_name, fields_entry|
|
156
|
+
# Choose the most local definition that passes `.visible?` --
|
157
|
+
# stop checking for fields by name once one has been found.
|
158
|
+
if !visible_fields.key?(field_name) && (f = Warden.visible_entry?(:visible_field?, fields_entry, context, warden))
|
159
|
+
visible_fields[field_name] = f
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
visible_fields
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.included(child_class)
|
169
|
+
# Included in an interface definition methods module
|
170
|
+
child_class.include(InterfaceMethods)
|
171
|
+
super
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.extended(child_class)
|
175
|
+
child_class.extend(ObjectMethods)
|
176
|
+
super
|
177
|
+
end
|
178
|
+
|
130
179
|
private
|
131
180
|
|
132
181
|
def inherited(subclass)
|
133
182
|
super
|
134
183
|
subclass.class_eval do
|
135
184
|
@own_fields ||= nil
|
185
|
+
@field_class ||= nil
|
136
186
|
end
|
137
187
|
end
|
138
188
|
|
@@ -3,7 +3,7 @@ module GraphQL
|
|
3
3
|
class Schema
|
4
4
|
class Member
|
5
5
|
module HasValidators
|
6
|
-
include
|
6
|
+
include GraphQL::EmptyObjects
|
7
7
|
|
8
8
|
# Build {GraphQL::Schema::Validator}s based on the given configuration
|
9
9
|
# and use them for this schema member
|
@@ -28,7 +28,7 @@ module GraphQL
|
|
28
28
|
end
|
29
29
|
|
30
30
|
module ClassValidators
|
31
|
-
include
|
31
|
+
include GraphQL::EmptyObjects
|
32
32
|
|
33
33
|
def validators
|
34
34
|
inherited_validators = superclass.validators
|
@@ -6,6 +6,7 @@ module GraphQL
|
|
6
6
|
module RelayShortcuts
|
7
7
|
def edge_type_class(new_edge_type_class = nil)
|
8
8
|
if new_edge_type_class
|
9
|
+
initialize_relay_metadata
|
9
10
|
@edge_type_class = new_edge_type_class
|
10
11
|
else
|
11
12
|
# Don't call `ancestor.edge_type_class`
|
@@ -22,6 +23,7 @@ module GraphQL
|
|
22
23
|
|
23
24
|
def connection_type_class(new_connection_type_class = nil)
|
24
25
|
if new_connection_type_class
|
26
|
+
initialize_relay_metadata
|
25
27
|
@connection_type_class = new_connection_type_class
|
26
28
|
else
|
27
29
|
# Don't call `ancestor.connection_type_class`
|
@@ -37,6 +39,7 @@ module GraphQL
|
|
37
39
|
end
|
38
40
|
|
39
41
|
def edge_type
|
42
|
+
initialize_relay_metadata
|
40
43
|
@edge_type ||= begin
|
41
44
|
edge_name = self.graphql_name + "Edge"
|
42
45
|
node_type_class = self
|
@@ -48,6 +51,7 @@ module GraphQL
|
|
48
51
|
end
|
49
52
|
|
50
53
|
def connection_type
|
54
|
+
initialize_relay_metadata
|
51
55
|
@connection_type ||= begin
|
52
56
|
conn_name = self.graphql_name + "Connection"
|
53
57
|
edge_type_class = self.edge_type
|
@@ -67,6 +71,21 @@ module GraphQL
|
|
67
71
|
def configured_edge_type_class
|
68
72
|
@edge_type_class
|
69
73
|
end
|
74
|
+
|
75
|
+
attr_writer :edge_type, :connection_type, :connection_type_class, :edge_type_class
|
76
|
+
|
77
|
+
private
|
78
|
+
|
79
|
+
# If one of thse values is accessed, initialize all the instance variables to retain
|
80
|
+
# a consistent object shape.
|
81
|
+
def initialize_relay_metadata
|
82
|
+
if !defined?(@connection_type)
|
83
|
+
@connection_type = nil
|
84
|
+
@edge_type = nil
|
85
|
+
@connection_type_class = nil
|
86
|
+
@edge_type_class = nil
|
87
|
+
end
|
88
|
+
end
|
70
89
|
end
|
71
90
|
end
|
72
91
|
end
|
@@ -48,9 +48,7 @@ module GraphQL
|
|
48
48
|
# @return [GraphQL::Schema::Object, GraphQL::Execution::Lazy]
|
49
49
|
# @raise [GraphQL::UnauthorizedError] if the user-provided hook returns `false`
|
50
50
|
def authorized_new(object, context)
|
51
|
-
|
52
|
-
|
53
|
-
maybe_lazy_auth_val = context.query.trace("authorized", trace_payload) do
|
51
|
+
maybe_lazy_auth_val = context.query.current_trace.authorized(query: context.query, type: self, object: object) do
|
54
52
|
begin
|
55
53
|
authorized?(object, context)
|
56
54
|
rescue GraphQL::UnauthorizedError => err
|
@@ -62,7 +60,7 @@ module GraphQL
|
|
62
60
|
|
63
61
|
auth_val = if context.schema.lazy?(maybe_lazy_auth_val)
|
64
62
|
GraphQL::Execution::Lazy.new do
|
65
|
-
context.query.
|
63
|
+
context.query.current_trace.authorized_lazy(query: context.query, type: self, object: object) do
|
66
64
|
context.schema.sync_lazy(maybe_lazy_auth_val)
|
67
65
|
end
|
68
66
|
end
|