graphql 1.12.6 → 1.12.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/execution/errors.rb +108 -10
- data/lib/graphql/execution/interpreter/runtime.rb +5 -4
- data/lib/graphql/introspection.rb +1 -1
- data/lib/graphql/introspection/directive_type.rb +7 -3
- data/lib/graphql/pagination/active_record_relation_connection.rb +7 -0
- data/lib/graphql/pagination/relation_connection.rb +8 -1
- data/lib/graphql/query.rb +1 -3
- data/lib/graphql/query/validation_pipeline.rb +1 -1
- data/lib/graphql/schema.rb +5 -19
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +3 -1
- data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +6 -2
- data/lib/graphql/static_validation/rules/arguments_are_defined.rb +2 -1
- data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +4 -2
- data/lib/graphql/subscriptions/broadcast_analyzer.rb +0 -3
- data/lib/graphql/types/relay/base_connection.rb +4 -0
- data/lib/graphql/types/relay/connection_behaviors.rb +21 -10
- data/lib/graphql/types/relay/edge_behaviors.rb +12 -1
- data/lib/graphql/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0b3eaaf2e8d1d263d8de4e509bbca1413c41981ac69d8f722eba16883fc9023
|
4
|
+
data.tar.gz: e9d0a083c8553cb650a2aff619a4c04bd5a01fb345dc8ae560563db09fe4d0b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1580219b7da1f62566e65eff2b2c11f124415dad818243260b2ebefddb4de5dad2d2e1953bc671f2080d1523c98f31e7eee581edf5b6b830761a96b970796ca
|
7
|
+
data.tar.gz: 1a886d5d664bb4352b9f75f1c448acb5e2d0b8299c6f1cf6debd441df2f700869912b8a7083363aac6c41874ae18dd5bd87955a9979e44b7e5e21811c25539f3
|
@@ -18,21 +18,83 @@ module GraphQL
|
|
18
18
|
#
|
19
19
|
class Errors
|
20
20
|
def self.use(schema)
|
21
|
-
|
22
|
-
|
23
|
-
GraphQL::Deprecation.warn("GraphQL::Execution::Errors is now installed by default, remove `use GraphQL::Execution::Errors` from #{definition_line}")
|
24
|
-
end
|
25
|
-
schema.error_handler = self.new(schema)
|
21
|
+
definition_line = caller(2, 1).first
|
22
|
+
GraphQL::Deprecation.warn("GraphQL::Execution::Errors is now installed by default, remove `use GraphQL::Execution::Errors` from #{definition_line}")
|
26
23
|
end
|
27
24
|
|
25
|
+
NEW_HANDLER_HASH = ->(h, k) {
|
26
|
+
h[k] = {
|
27
|
+
class: k,
|
28
|
+
handler: nil,
|
29
|
+
subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
|
30
|
+
}
|
31
|
+
}
|
32
|
+
|
28
33
|
def initialize(schema)
|
29
34
|
@schema = schema
|
35
|
+
@handlers = {
|
36
|
+
class: nil,
|
37
|
+
handler: nil,
|
38
|
+
subclass_handlers: Hash.new(&NEW_HANDLER_HASH),
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
# @api private
|
43
|
+
def each_rescue
|
44
|
+
handlers = @handlers.values
|
45
|
+
while (handler = handlers.shift) do
|
46
|
+
yield(handler[:class], handler[:handler])
|
47
|
+
handlers.concat(handler[:subclass_handlers].values)
|
48
|
+
end
|
30
49
|
end
|
31
50
|
|
32
|
-
|
33
|
-
|
34
|
-
|
51
|
+
# Register this handler, updating the
|
52
|
+
# internal handler index to maintain least-to-most specific.
|
53
|
+
#
|
54
|
+
# @param error_class [Class<Exception>]
|
55
|
+
# @param error_handler [Proc]
|
56
|
+
# @return [void]
|
57
|
+
def rescue_from(error_class, error_handler)
|
58
|
+
subclasses_handlers = {}
|
59
|
+
this_level_subclasses = []
|
60
|
+
# During this traversal, do two things:
|
61
|
+
# - Identify any already-registered subclasses of this error class
|
62
|
+
# and gather them up to be inserted _under_ this class
|
63
|
+
# - Find the point in the index where this handler should be inserted
|
64
|
+
# (That is, _under_ any superclasses, or at top-level, if there are no superclasses registered)
|
65
|
+
handlers = @handlers[:subclass_handlers]
|
66
|
+
while (handlers) do
|
67
|
+
this_level_subclasses.clear
|
68
|
+
# First, identify already-loaded handlers that belong
|
69
|
+
# _under_ this one. (That is, they're handlers
|
70
|
+
# for subclasses of `error_class`.)
|
71
|
+
handlers.each do |err_class, handler|
|
72
|
+
if err_class < error_class
|
73
|
+
subclasses_handlers[err_class] = handler
|
74
|
+
this_level_subclasses << err_class
|
75
|
+
end
|
76
|
+
end
|
77
|
+
# Any handlers that we'll be moving, delete them from this point in the index
|
78
|
+
this_level_subclasses.each do |err_class|
|
79
|
+
handlers.delete(err_class)
|
80
|
+
end
|
81
|
+
|
82
|
+
# See if any keys in this hash are superclasses of this new class:
|
83
|
+
next_index_point = handlers.find { |err_class, handler| error_class < err_class }
|
84
|
+
if next_index_point
|
85
|
+
handlers = next_index_point[1][:subclass_handlers]
|
86
|
+
else
|
87
|
+
# this new handler doesn't belong to any sub-handlers,
|
88
|
+
# so insert it in the current set of `handlers`
|
89
|
+
break
|
90
|
+
end
|
35
91
|
end
|
92
|
+
# Having found the point at which to insert this handler,
|
93
|
+
# register it and merge any subclass handlers back in at this point.
|
94
|
+
this_class_handlers = handlers[error_class]
|
95
|
+
this_class_handlers[:handler] = error_handler
|
96
|
+
this_class_handlers[:subclass_handlers].merge!(subclasses_handlers)
|
97
|
+
nil
|
36
98
|
end
|
37
99
|
|
38
100
|
# Call the given block with the schema's configured error handlers.
|
@@ -44,8 +106,7 @@ module GraphQL
|
|
44
106
|
def with_error_handling(ctx)
|
45
107
|
yield
|
46
108
|
rescue StandardError => err
|
47
|
-
|
48
|
-
_err_class, handler = rescues.find { |err_class, handler| err.is_a?(err_class) }
|
109
|
+
handler = find_handler_for(err.class)
|
49
110
|
if handler
|
50
111
|
runtime_info = ctx.namespace(:interpreter) || {}
|
51
112
|
obj = runtime_info[:current_object]
|
@@ -59,6 +120,43 @@ module GraphQL
|
|
59
120
|
raise err
|
60
121
|
end
|
61
122
|
end
|
123
|
+
|
124
|
+
# @return [Proc, nil] The handler for `error_class`, if one was registered on this schema or inherited
|
125
|
+
def find_handler_for(error_class)
|
126
|
+
handlers = @handlers[:subclass_handlers]
|
127
|
+
handler = nil
|
128
|
+
while (handlers) do
|
129
|
+
_err_class, next_handler = handlers.find { |err_class, handler| error_class <= err_class }
|
130
|
+
if next_handler
|
131
|
+
handlers = next_handler[:subclass_handlers]
|
132
|
+
handler = next_handler
|
133
|
+
else
|
134
|
+
# Don't reassign `handler` --
|
135
|
+
# let the previous assignment carry over outside this block.
|
136
|
+
break
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# check for a handler from a parent class:
|
141
|
+
if @schema.superclass.respond_to?(:error_handler) && (parent_errors = @schema.superclass.error_handler)
|
142
|
+
parent_handler = parent_errors.find_handler_for(error_class)
|
143
|
+
end
|
144
|
+
|
145
|
+
# If the inherited handler is more specific than the one defined here,
|
146
|
+
# use it.
|
147
|
+
# If it's a tie (or there is no parent handler), use the one defined here.
|
148
|
+
# If there's an inherited one, but not one defined here, use the inherited one.
|
149
|
+
# Otherwise, there's no handler for this error, return `nil`.
|
150
|
+
if parent_handler && handler && parent_handler[:class] < handler[:class]
|
151
|
+
parent_handler[:handler]
|
152
|
+
elsif handler
|
153
|
+
handler[:handler]
|
154
|
+
elsif parent_handler
|
155
|
+
parent_handler[:handler]
|
156
|
+
else
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
end
|
62
160
|
end
|
63
161
|
end
|
64
162
|
end
|
@@ -277,10 +277,7 @@ module GraphQL
|
|
277
277
|
end
|
278
278
|
after_lazy(app_result, owner: owner_type, field: field_defn, path: next_path, ast_node: ast_node, scoped_context: context.scoped_context, owner_object: object, arguments: kwarg_arguments) do |inner_result|
|
279
279
|
continue_value = continue_value(next_path, inner_result, owner_type, field_defn, return_type.non_null?, ast_node)
|
280
|
-
if
|
281
|
-
# Write raw value directly to the response without resolving nested objects
|
282
|
-
write_in_response(next_path, continue_value.resolve)
|
283
|
-
elsif HALT != continue_value
|
280
|
+
if HALT != continue_value
|
284
281
|
continue_field(next_path, continue_value, owner_type, field_defn, return_type, ast_node, next_selections, false, object, kwarg_arguments)
|
285
282
|
end
|
286
283
|
end
|
@@ -332,6 +329,10 @@ module GraphQL
|
|
332
329
|
continue_value(path, next_value, parent_type, field, is_non_null, ast_node)
|
333
330
|
elsif GraphQL::Execution::Execute::SKIP == value
|
334
331
|
HALT
|
332
|
+
elsif value.is_a?(GraphQL::Execution::Interpreter::RawValue)
|
333
|
+
# Write raw value directly to the response without resolving nested objects
|
334
|
+
write_in_response(path, value.resolve)
|
335
|
+
HALT
|
335
336
|
else
|
336
337
|
value
|
337
338
|
end
|
@@ -12,13 +12,17 @@ module GraphQL
|
|
12
12
|
field :name, String, null: false, method: :graphql_name
|
13
13
|
field :description, String, null: true
|
14
14
|
field :locations, [GraphQL::Schema::LateBoundType.new("__DirectiveLocation")], null: false
|
15
|
-
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false
|
15
|
+
field :args, [GraphQL::Schema::LateBoundType.new("__InputValue")], null: false do
|
16
|
+
argument :include_deprecated, Boolean, required: false, default_value: false
|
17
|
+
end
|
16
18
|
field :on_operation, Boolean, null: false, deprecation_reason: "Use `locations`.", method: :on_operation?
|
17
19
|
field :on_fragment, Boolean, null: false, deprecation_reason: "Use `locations`.", method: :on_fragment?
|
18
20
|
field :on_field, Boolean, null: false, deprecation_reason: "Use `locations`.", method: :on_field?
|
19
21
|
|
20
|
-
def args
|
21
|
-
@context.warden.arguments(@object)
|
22
|
+
def args(include_deprecated:)
|
23
|
+
args = @context.warden.arguments(@object)
|
24
|
+
args = args.reject(&:deprecation_reason) unless include_deprecated
|
25
|
+
args
|
22
26
|
end
|
23
27
|
end
|
24
28
|
end
|
@@ -5,6 +5,13 @@ module GraphQL
|
|
5
5
|
module Pagination
|
6
6
|
# Customizes `RelationConnection` to work with `ActiveRecord::Relation`s.
|
7
7
|
class ActiveRecordRelationConnection < Pagination::RelationConnection
|
8
|
+
private
|
9
|
+
|
10
|
+
def relation_larger_than(relation, size)
|
11
|
+
initial_offset = relation.offset_value || 0
|
12
|
+
relation.offset(initial_offset + size).exists?
|
13
|
+
end
|
14
|
+
|
8
15
|
def relation_count(relation)
|
9
16
|
int_or_hash = if relation.respond_to?(:unscope)
|
10
17
|
relation.unscope(:order).count(:all)
|
@@ -35,7 +35,7 @@ module GraphQL
|
|
35
35
|
if @nodes && @nodes.count < first
|
36
36
|
false
|
37
37
|
else
|
38
|
-
|
38
|
+
relation_larger_than(sliced_nodes, first)
|
39
39
|
end
|
40
40
|
else
|
41
41
|
false
|
@@ -53,6 +53,13 @@ module GraphQL
|
|
53
53
|
|
54
54
|
private
|
55
55
|
|
56
|
+
# @param relation [Object] A database query object
|
57
|
+
# @param size [Integer] The value against which we check the relation size
|
58
|
+
# @return [Boolean] True if the number of items in this relation is larger than `size`
|
59
|
+
def relation_larger_than(relation, size)
|
60
|
+
relation_count(set_limit(relation, size + 1)) == size + 1
|
61
|
+
end
|
62
|
+
|
56
63
|
# @param relation [Object] A database query object
|
57
64
|
# @return [Integer, nil] The offset value, or nil if there isn't one
|
58
65
|
def relation_offset(relation)
|
data/lib/graphql/query.rb
CHANGED
@@ -195,9 +195,7 @@ module GraphQL
|
|
195
195
|
# @return [Hash] A GraphQL response, with `"data"` and/or `"errors"` keys
|
196
196
|
def result
|
197
197
|
if !@executed
|
198
|
-
|
199
|
-
Execution::Multiplex.run_queries(@schema, [self], context: @context)
|
200
|
-
}
|
198
|
+
Execution::Multiplex.run_queries(@schema, [self], context: @context)
|
201
199
|
end
|
202
200
|
@result ||= Query::Result.new(query: self, values: @result_values)
|
203
201
|
end
|
@@ -36,7 +36,7 @@ module GraphQL
|
|
36
36
|
@valid
|
37
37
|
end
|
38
38
|
|
39
|
-
# @return [Array<GraphQL::StaticValidation::Error >] Static validation errors for the query string
|
39
|
+
# @return [Array<GraphQL::StaticValidation::Error, GraphQL::Query::VariableValidationError>] Static validation errors for the query string
|
40
40
|
def validation_errors
|
41
41
|
ensure_has_validated
|
42
42
|
@validation_errors
|
data/lib/graphql/schema.rb
CHANGED
@@ -711,7 +711,7 @@ module GraphQL
|
|
711
711
|
alias :_schema_class :class
|
712
712
|
def_delegators :_schema_class, :unauthorized_object, :unauthorized_field, :inaccessible_fields
|
713
713
|
def_delegators :_schema_class, :directive
|
714
|
-
def_delegators :_schema_class, :error_handler
|
714
|
+
def_delegators :_schema_class, :error_handler
|
715
715
|
|
716
716
|
|
717
717
|
# Given this schema member, find the class-based definition object
|
@@ -989,7 +989,7 @@ module GraphQL
|
|
989
989
|
schema_defn.lazy_methods.set(lazy_class, value_method)
|
990
990
|
end
|
991
991
|
|
992
|
-
|
992
|
+
error_handler.each_rescue do |err_class, handler|
|
993
993
|
schema_defn.rescue_from(err_class, &handler)
|
994
994
|
end
|
995
995
|
|
@@ -1424,7 +1424,7 @@ module GraphQL
|
|
1424
1424
|
|
1425
1425
|
def rescue_from(*err_classes, &handler_block)
|
1426
1426
|
err_classes.each do |err_class|
|
1427
|
-
|
1427
|
+
error_handler.rescue_from(err_class, handler_block)
|
1428
1428
|
end
|
1429
1429
|
end
|
1430
1430
|
|
@@ -1468,10 +1468,6 @@ module GraphQL
|
|
1468
1468
|
super
|
1469
1469
|
end
|
1470
1470
|
|
1471
|
-
def rescues
|
1472
|
-
find_inherited_value(:rescues, EMPTY_HASH).merge(own_rescues)
|
1473
|
-
end
|
1474
|
-
|
1475
1471
|
def object_from_id(node_id, ctx)
|
1476
1472
|
raise GraphQL::RequiredImplementationMissingError, "#{self.name}.object_from_id(node_id, ctx) must be implemented to load by ID (tried to load from id `#{node_id}`)"
|
1477
1473
|
end
|
@@ -1548,15 +1544,10 @@ module GraphQL
|
|
1548
1544
|
def parse_error(parse_err, ctx)
|
1549
1545
|
ctx.errors.push(parse_err)
|
1550
1546
|
end
|
1551
|
-
attr_writer :error_handler
|
1552
1547
|
|
1553
|
-
# @return [GraphQL::Execution::Errors
|
1548
|
+
# @return [GraphQL::Execution::Errors]
|
1554
1549
|
def error_handler
|
1555
|
-
|
1556
|
-
@error_handler
|
1557
|
-
else
|
1558
|
-
find_inherited_value(:error_handler, GraphQL::Execution::Errors::NullErrorHandler)
|
1559
|
-
end
|
1550
|
+
@error_handler ||= GraphQL::Execution::Errors.new(self)
|
1560
1551
|
end
|
1561
1552
|
|
1562
1553
|
def lazy_resolve(lazy_class, value_method)
|
@@ -1744,10 +1735,6 @@ module GraphQL
|
|
1744
1735
|
@own_plugins ||= []
|
1745
1736
|
end
|
1746
1737
|
|
1747
|
-
def own_rescues
|
1748
|
-
@own_rescues ||= {}
|
1749
|
-
end
|
1750
|
-
|
1751
1738
|
def own_orphan_types
|
1752
1739
|
@own_orphan_types ||= []
|
1753
1740
|
end
|
@@ -1990,7 +1977,6 @@ module GraphQL
|
|
1990
1977
|
end
|
1991
1978
|
|
1992
1979
|
# Install these here so that subclasses will also install it.
|
1993
|
-
use(GraphQL::Execution::Errors)
|
1994
1980
|
use(GraphQL::Pagination::Connections)
|
1995
1981
|
|
1996
1982
|
protected
|
@@ -41,7 +41,9 @@ module GraphQL
|
|
41
41
|
error_options = {
|
42
42
|
nodes: parent,
|
43
43
|
type: kind_of_node,
|
44
|
-
|
44
|
+
argument_name: node.name,
|
45
|
+
argument: arg_defn,
|
46
|
+
value: node.value
|
45
47
|
}
|
46
48
|
if coerce_extensions
|
47
49
|
error_options[:coerce_extensions] = coerce_extensions
|
@@ -4,13 +4,17 @@ module GraphQL
|
|
4
4
|
class ArgumentLiteralsAreCompatibleError < StaticValidation::Error
|
5
5
|
attr_reader :type_name
|
6
6
|
attr_reader :argument_name
|
7
|
+
attr_reader :argument
|
8
|
+
attr_reader :value
|
7
9
|
|
8
|
-
def initialize(message, path: nil, nodes: [], type:,
|
10
|
+
def initialize(message, path: nil, nodes: [], type:, argument_name: nil, extensions: nil, coerce_extensions: nil, argument: nil, value: nil)
|
9
11
|
super(message, path: path, nodes: nodes)
|
10
12
|
@type_name = type
|
11
|
-
@argument_name =
|
13
|
+
@argument_name = argument_name
|
12
14
|
@extensions = extensions
|
13
15
|
@coerce_extensions = coerce_extensions
|
16
|
+
@argument = argument
|
17
|
+
@value = value
|
14
18
|
end
|
15
19
|
|
16
20
|
# A hash representation of this Message
|
@@ -5,12 +5,14 @@ module GraphQL
|
|
5
5
|
attr_reader :name
|
6
6
|
attr_reader :type_name
|
7
7
|
attr_reader :argument_name
|
8
|
+
attr_reader :parent
|
8
9
|
|
9
|
-
def initialize(message, path: nil, nodes: [], name:, type:,
|
10
|
+
def initialize(message, path: nil, nodes: [], name:, type:, argument_name:, parent:)
|
10
11
|
super(message, path: path, nodes: nodes)
|
11
12
|
@name = name
|
12
13
|
@type_name = type
|
13
|
-
@argument_name =
|
14
|
+
@argument_name = argument_name
|
15
|
+
@parent = parent
|
14
16
|
end
|
15
17
|
|
16
18
|
# A hash representation of this Message
|
@@ -35,9 +35,6 @@ module GraphQL
|
|
35
35
|
pt = @query.possible_types(current_type)
|
36
36
|
pt.each do |object_type|
|
37
37
|
ot_field = @query.get_field(object_type, current_field.graphql_name)
|
38
|
-
if !ot_field
|
39
|
-
binding.pry
|
40
|
-
end
|
41
38
|
# Inherited fields would be exactly the same object;
|
42
39
|
# only check fields that are overrides of the inherited one
|
43
40
|
if ot_field && ot_field != current_field
|
@@ -24,6 +24,10 @@ module GraphQL
|
|
24
24
|
# end
|
25
25
|
# class Types::PostConnection < Types::BaseConnection
|
26
26
|
# edge_type(Types::PostEdge)
|
27
|
+
# edges_nullable(true)
|
28
|
+
# edge_nullable(true)
|
29
|
+
# node_nullable(true)
|
30
|
+
# has_nodes_field(true)
|
27
31
|
# end
|
28
32
|
#
|
29
33
|
# @see Relay::BaseEdge for edge types
|
@@ -11,6 +11,7 @@ module GraphQL
|
|
11
11
|
child_class.extend(ClassMethods)
|
12
12
|
child_class.extend(Relay::DefaultRelay)
|
13
13
|
child_class.default_relay(true)
|
14
|
+
child_class.has_nodes_field(true)
|
14
15
|
child_class.node_nullable(true)
|
15
16
|
child_class.edges_nullable(true)
|
16
17
|
child_class.edge_nullable(true)
|
@@ -34,7 +35,7 @@ module GraphQL
|
|
34
35
|
# It's called when you subclass this base connection, trying to use the
|
35
36
|
# class name to set defaults. You can call it again in the class definition
|
36
37
|
# to override the default (or provide a value, if the default lookup failed).
|
37
|
-
def edge_type(edge_type_class, edge_class: GraphQL::Relay::Edge, node_type: edge_type_class.node_type, nodes_field:
|
38
|
+
def edge_type(edge_type_class, edge_class: GraphQL::Relay::Edge, node_type: edge_type_class.node_type, nodes_field: self.has_nodes_field, node_nullable: self.node_nullable, edges_nullable: self.edges_nullable, edge_nullable: self.edge_nullable)
|
38
39
|
# Set this connection's graphql name
|
39
40
|
node_type_name = node_type.graphql_name
|
40
41
|
|
@@ -79,9 +80,9 @@ module GraphQL
|
|
79
80
|
# Use `node_nullable(false)` in your base class to make non-null `node` and `nodes` fields.
|
80
81
|
def node_nullable(new_value = nil)
|
81
82
|
if new_value.nil?
|
82
|
-
@node_nullable
|
83
|
+
defined?(@node_nullable) ? @node_nullable : superclass.node_nullable
|
83
84
|
else
|
84
|
-
@node_nullable
|
85
|
+
@node_nullable = new_value
|
85
86
|
end
|
86
87
|
end
|
87
88
|
|
@@ -89,21 +90,31 @@ module GraphQL
|
|
89
90
|
# Use `edges_nullable(false)` in your base class to make non-null `edges` fields.
|
90
91
|
def edges_nullable(new_value = nil)
|
91
92
|
if new_value.nil?
|
92
|
-
@edges_nullable
|
93
|
+
defined?(@edges_nullable) ? @edges_nullable : superclass.edges_nullable
|
93
94
|
else
|
94
|
-
@edges_nullable
|
95
|
+
@edges_nullable = new_value
|
95
96
|
end
|
96
|
-
end
|
97
|
-
|
97
|
+
end
|
98
|
+
|
98
99
|
# Set the default `edge_nullable` for this class and its child classes. (Defaults to `true`.)
|
99
100
|
# Use `edge_nullable(false)` in your base class to make non-null `edge` fields.
|
100
101
|
def edge_nullable(new_value = nil)
|
101
102
|
if new_value.nil?
|
102
|
-
@edge_nullable
|
103
|
+
defined?(@edge_nullable) ? @edge_nullable : superclass.edge_nullable
|
104
|
+
else
|
105
|
+
@edge_nullable = new_value
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Set the default `nodes_field` for this class and its child classes. (Defaults to `true`.)
|
110
|
+
# Use `nodes_field(false)` in your base class to prevent adding of a nodes field.
|
111
|
+
def has_nodes_field(new_value = nil)
|
112
|
+
if new_value.nil?
|
113
|
+
defined?(@nodes_field) ? @nodes_field : superclass.has_nodes_field
|
103
114
|
else
|
104
|
-
@
|
115
|
+
@nodes_field = new_value
|
105
116
|
end
|
106
|
-
end
|
117
|
+
end
|
107
118
|
|
108
119
|
private
|
109
120
|
|
@@ -8,6 +8,7 @@ module GraphQL
|
|
8
8
|
child_class.description("An edge in a connection.")
|
9
9
|
child_class.field(:cursor, String, null: false, description: "A cursor for use in pagination.")
|
10
10
|
child_class.extend(ClassMethods)
|
11
|
+
child_class.node_nullable(true)
|
11
12
|
end
|
12
13
|
|
13
14
|
module ClassMethods
|
@@ -15,7 +16,7 @@ module GraphQL
|
|
15
16
|
#
|
16
17
|
# @param node_type [Class] A `Schema::Object` subclass
|
17
18
|
# @param null [Boolean]
|
18
|
-
def node_type(node_type = nil, null:
|
19
|
+
def node_type(node_type = nil, null: self.node_nullable)
|
19
20
|
if node_type
|
20
21
|
@node_type = node_type
|
21
22
|
# Add a default `node` field
|
@@ -35,6 +36,16 @@ module GraphQL
|
|
35
36
|
def visible?(ctx)
|
36
37
|
node_type.visible?(ctx)
|
37
38
|
end
|
39
|
+
|
40
|
+
# Set the default `node_nullable` for this class and its child classes. (Defaults to `true`.)
|
41
|
+
# Use `node_nullable(false)` in your base class to make non-null `node` field.
|
42
|
+
def node_nullable(new_value = nil)
|
43
|
+
if new_value.nil?
|
44
|
+
defined?(@node_nullable) ? @node_nullable : superclass.node_nullable
|
45
|
+
else
|
46
|
+
@node_nullable = new_value
|
47
|
+
end
|
48
|
+
end
|
38
49
|
end
|
39
50
|
end
|
40
51
|
end
|
data/lib/graphql/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.12.
|
4
|
+
version: 1.12.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|