graphql 1.12.12 → 1.12.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/backtrace/table.rb +1 -1
- data/lib/graphql/backtrace/tracer.rb +1 -1
- data/lib/graphql/execution/interpreter.rb +3 -3
- data/lib/graphql/execution/interpreter/resolve.rb +6 -2
- data/lib/graphql/execution/interpreter/runtime.rb +144 -29
- data/lib/graphql/execution/lazy.rb +5 -1
- data/lib/graphql/schema/directive/transform.rb +1 -1
- data/lib/graphql/schema/enum.rb +10 -1
- data/lib/graphql/schema/input_object.rb +11 -15
- data/lib/graphql/schema/printer.rb +11 -16
- data/lib/graphql/schema/resolver.rb +6 -1
- data/lib/graphql/types/relay/has_node_field.rb +1 -1
- data/lib/graphql/types/relay/has_nodes_field.rb +1 -1
- data/lib/graphql/types/relay/node_field.rb +2 -2
- data/lib/graphql/types/relay/nodes_field.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +0 -3
- metadata +6 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2cad71b0084305ae219dd00e6c6ed48871f126d90c38cf47b9708db1eaf1feb6
|
4
|
+
data.tar.gz: afe00c0b1f14134068015098392817c0c0f0841f8016863789d319590dc5a9ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fc7bee0a1a2bdc836358338d41d56c394f495dcc78d17403c60efd47ae8f807ad447fcb96a9c270137fa247fde43b5936961436efb6d1276768f945bd5be077
|
7
|
+
data.tar.gz: a0da8f32b54df7b1254dac3749ffe1e9a9b2d93ec273313280d755b5c2bf3910880f2a13f4861d7efb0b2e39a5aefc63491918a89bcdfa223893769a0a9a1ddf
|
@@ -22,7 +22,7 @@ module GraphQL
|
|
22
22
|
when "execute_field", "execute_field_lazy"
|
23
23
|
query = metadata[:query] || raise(ArgumentError, "Add `legacy: true` to use GraphQL::Backtrace without the interpreter runtime.")
|
24
24
|
multiplex = query.multiplex
|
25
|
-
push_key = metadata[:path]
|
25
|
+
push_key = metadata[:path]
|
26
26
|
parent_frame = multiplex.context[:graphql_backtrace_contexts][push_key[0..-2]]
|
27
27
|
|
28
28
|
if parent_frame.is_a?(GraphQL::Query)
|
@@ -18,7 +18,7 @@ module GraphQL
|
|
18
18
|
def execute(_operation, _root_type, query)
|
19
19
|
runtime = evaluate(query)
|
20
20
|
sync_lazies(query: query)
|
21
|
-
runtime.
|
21
|
+
runtime.final_result
|
22
22
|
end
|
23
23
|
|
24
24
|
def self.use(schema_class)
|
@@ -56,7 +56,7 @@ module GraphQL
|
|
56
56
|
|
57
57
|
def self.finish_query(query, _multiplex)
|
58
58
|
{
|
59
|
-
"data" => query.context.namespace(:interpreter)[:runtime].
|
59
|
+
"data" => query.context.namespace(:interpreter)[:runtime].final_result
|
60
60
|
}
|
61
61
|
end
|
62
62
|
|
@@ -87,7 +87,7 @@ module GraphQL
|
|
87
87
|
final_values = queries.map do |query|
|
88
88
|
runtime = query.context.namespace(:interpreter)[:runtime]
|
89
89
|
# it might not be present if the query has an error
|
90
|
-
runtime ? runtime.
|
90
|
+
runtime ? runtime.final_result : nil
|
91
91
|
end
|
92
92
|
final_values.compact!
|
93
93
|
tracer.trace("execute_query_lazy", {multiplex: multiplex, query: query}) do
|
@@ -34,7 +34,10 @@ module GraphQL
|
|
34
34
|
next_results = []
|
35
35
|
while results.any?
|
36
36
|
result_value = results.shift
|
37
|
-
if result_value.is_a?(Hash)
|
37
|
+
if result_value.is_a?(Runtime::GraphQLResultHash) || result_value.is_a?(Hash)
|
38
|
+
results.concat(result_value.values)
|
39
|
+
next
|
40
|
+
elsif result_value.is_a?(Runtime::GraphQLResultArray)
|
38
41
|
results.concat(result_value.values)
|
39
42
|
next
|
40
43
|
elsif result_value.is_a?(Array)
|
@@ -46,7 +49,8 @@ module GraphQL
|
|
46
49
|
# Since this field returned another lazy,
|
47
50
|
# add it to the same queue
|
48
51
|
results << loaded_value
|
49
|
-
elsif loaded_value.is_a?(
|
52
|
+
elsif loaded_value.is_a?(Runtime::GraphQLResultHash) || loaded_value.is_a?(Runtime::GraphQLResultArray) ||
|
53
|
+
loaded_value.is_a?(Hash) || loaded_value.is_a?(Array)
|
50
54
|
# Add these values in wholesale --
|
51
55
|
# they might be modified by later work in the dataloader.
|
52
56
|
next_results << loaded_value
|
@@ -10,8 +10,6 @@ module GraphQL
|
|
10
10
|
class Runtime
|
11
11
|
|
12
12
|
module GraphQLResult
|
13
|
-
# These methods are private concerns of GraphQL-Ruby,
|
14
|
-
# they aren't guaranteed to continue working in the future.
|
15
13
|
attr_accessor :graphql_dead, :graphql_parent, :graphql_result_name
|
16
14
|
# Although these are used by only one of the Result classes,
|
17
15
|
# it's handy to have the methods implemented on both (even though they just return `nil`)
|
@@ -20,9 +18,18 @@ module GraphQL
|
|
20
18
|
attr_accessor :graphql_non_null_field_names
|
21
19
|
# @return [nil, true]
|
22
20
|
attr_accessor :graphql_non_null_list_items
|
21
|
+
|
22
|
+
# @return [Hash] Plain-Ruby result data (`@graphql_metadata` contains Result wrapper objects)
|
23
|
+
attr_accessor :graphql_result_data
|
23
24
|
end
|
24
25
|
|
25
|
-
class GraphQLResultHash
|
26
|
+
class GraphQLResultHash
|
27
|
+
def initialize
|
28
|
+
# Jump through some hoops to avoid creating this duplicate hash if at all possible.
|
29
|
+
@graphql_metadata = nil
|
30
|
+
@graphql_result_data = {}
|
31
|
+
end
|
32
|
+
|
26
33
|
include GraphQLResult
|
27
34
|
|
28
35
|
attr_accessor :graphql_merged_into
|
@@ -39,12 +46,84 @@ module GraphQL
|
|
39
46
|
if (t = @graphql_merged_into)
|
40
47
|
t[key] = value
|
41
48
|
end
|
42
|
-
|
49
|
+
|
50
|
+
if value.respond_to?(:graphql_result_data)
|
51
|
+
@graphql_result_data[key] = value.graphql_result_data
|
52
|
+
# If we encounter some part of this response that requires metadata tracking,
|
53
|
+
# then create the metadata hash if necessary. It will be kept up-to-date after this.
|
54
|
+
(@graphql_metadata ||= @graphql_result_data.dup)[key] = value
|
55
|
+
else
|
56
|
+
@graphql_result_data[key] = value
|
57
|
+
# keep this up-to-date if it's been initialized
|
58
|
+
@graphql_metadata && @graphql_metadata[key] = value
|
59
|
+
end
|
60
|
+
|
61
|
+
value
|
62
|
+
end
|
63
|
+
|
64
|
+
def delete(key)
|
65
|
+
@graphql_metadata && @graphql_metadata.delete(key)
|
66
|
+
@graphql_result_data.delete(key)
|
67
|
+
end
|
68
|
+
|
69
|
+
def each
|
70
|
+
(@graphql_metadata || @graphql_result_data).each { |k, v| yield(k, v) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def values
|
74
|
+
(@graphql_metadata || @graphql_result_data).values
|
75
|
+
end
|
76
|
+
|
77
|
+
def key?(k)
|
78
|
+
@graphql_result_data.key?(k)
|
79
|
+
end
|
80
|
+
|
81
|
+
def [](k)
|
82
|
+
(@graphql_metadata || @graphql_result_data)[k]
|
43
83
|
end
|
44
84
|
end
|
45
85
|
|
46
|
-
class GraphQLResultArray
|
86
|
+
class GraphQLResultArray
|
47
87
|
include GraphQLResult
|
88
|
+
|
89
|
+
def initialize
|
90
|
+
# Avoid this duplicate allocation if possible -
|
91
|
+
# but it will require some work to keep it up-to-date if it's created.
|
92
|
+
@graphql_metadata = nil
|
93
|
+
@graphql_result_data = []
|
94
|
+
end
|
95
|
+
|
96
|
+
def graphql_skip_at(index)
|
97
|
+
# Mark this index as dead. It's tricky because some indices may already be storing
|
98
|
+
# `Lazy`s. So the runtime is still holding indexes _before_ skipping,
|
99
|
+
# this object has to coordinate incoming writes to account for any already-skipped indices.
|
100
|
+
@skip_indices ||= []
|
101
|
+
@skip_indices << index
|
102
|
+
offset_by = @skip_indices.count { |skipped_idx| skipped_idx < index}
|
103
|
+
delete_at_index = index - offset_by
|
104
|
+
@graphql_metadata && @graphql_metadata.delete_at(delete_at_index)
|
105
|
+
@graphql_result_data.delete_at(delete_at_index)
|
106
|
+
end
|
107
|
+
|
108
|
+
def []=(idx, value)
|
109
|
+
if @skip_indices
|
110
|
+
offset_by = @skip_indices.count { |skipped_idx| skipped_idx < idx }
|
111
|
+
idx -= offset_by
|
112
|
+
end
|
113
|
+
if value.respond_to?(:graphql_result_data)
|
114
|
+
@graphql_result_data[idx] = value.graphql_result_data
|
115
|
+
(@graphql_metadata ||= @graphql_result_data.dup)[idx] = value
|
116
|
+
else
|
117
|
+
@graphql_result_data[idx] = value
|
118
|
+
@graphql_metadata && @graphql_metadata[idx] = value
|
119
|
+
end
|
120
|
+
|
121
|
+
value
|
122
|
+
end
|
123
|
+
|
124
|
+
def values
|
125
|
+
(@graphql_metadata || @graphql_result_data)
|
126
|
+
end
|
48
127
|
end
|
49
128
|
|
50
129
|
class GraphQLSelectionSet < Hash
|
@@ -60,9 +139,6 @@ module GraphQL
|
|
60
139
|
# @return [GraphQL::Query::Context]
|
61
140
|
attr_reader :context
|
62
141
|
|
63
|
-
# @return [Hash]
|
64
|
-
attr_reader :response
|
65
|
-
|
66
142
|
def initialize(query:)
|
67
143
|
@query = query
|
68
144
|
@dataloader = query.multiplex.dataloader
|
@@ -87,6 +163,10 @@ module GraphQL
|
|
87
163
|
@lazy_cache = {}
|
88
164
|
end
|
89
165
|
|
166
|
+
def final_result
|
167
|
+
@response && @response.graphql_result_data
|
168
|
+
end
|
169
|
+
|
90
170
|
def inspect
|
91
171
|
"#<#{self.class.name} response=#{@response.inspect}>"
|
92
172
|
end
|
@@ -167,7 +247,7 @@ module GraphQL
|
|
167
247
|
into_result[key] = value
|
168
248
|
else
|
169
249
|
case value
|
170
|
-
when
|
250
|
+
when GraphQLResultHash
|
171
251
|
deep_merge_selection_result(value, into_result[key])
|
172
252
|
else
|
173
253
|
# We have to assume that, since this passed the `fields_will_merge` selection,
|
@@ -439,15 +519,7 @@ module GraphQL
|
|
439
519
|
end
|
440
520
|
|
441
521
|
def dead_result?(selection_result)
|
442
|
-
|
443
|
-
while r
|
444
|
-
if r.graphql_dead
|
445
|
-
return true
|
446
|
-
else
|
447
|
-
r = r.graphql_parent
|
448
|
-
end
|
449
|
-
end
|
450
|
-
false
|
522
|
+
selection_result.graphql_dead || ((parent = selection_result.graphql_parent) && parent.graphql_dead)
|
451
523
|
end
|
452
524
|
|
453
525
|
def set_result(selection_result, result_name, value)
|
@@ -471,9 +543,7 @@ module GraphQL
|
|
471
543
|
@response = nil
|
472
544
|
else
|
473
545
|
set_result(parent, name_in_parent, nil)
|
474
|
-
|
475
|
-
# a `nil`, it's marked dead. TODO: check the spec, is there a reason for this?
|
476
|
-
parent.graphql_dead = true
|
546
|
+
set_graphql_dead(selection_result)
|
477
547
|
end
|
478
548
|
else
|
479
549
|
selection_result[result_name] = value
|
@@ -481,6 +551,21 @@ module GraphQL
|
|
481
551
|
end
|
482
552
|
end
|
483
553
|
|
554
|
+
# Mark this node and any already-registered children as dead,
|
555
|
+
# so that it accepts no more writes.
|
556
|
+
def set_graphql_dead(selection_result)
|
557
|
+
case selection_result
|
558
|
+
when GraphQLResultArray
|
559
|
+
selection_result.graphql_dead = true
|
560
|
+
selection_result.values.each { |v| set_graphql_dead(v) }
|
561
|
+
when GraphQLResultHash
|
562
|
+
selection_result.graphql_dead = true
|
563
|
+
selection_result.each { |k, v| set_graphql_dead(v) }
|
564
|
+
else
|
565
|
+
# It's a scalar, no way to mark it dead.
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
484
569
|
HALT = Object.new
|
485
570
|
def continue_value(path, value, parent_type, field, is_non_null, ast_node, result_name, selection_result) # rubocop:disable Metrics/ParameterLists
|
486
571
|
case value
|
@@ -500,11 +585,13 @@ module GraphQL
|
|
500
585
|
# to avoid the overhead of checking three different classes
|
501
586
|
# every time.
|
502
587
|
if value.is_a?(GraphQL::ExecutionError)
|
503
|
-
if !dead_result?(selection_result)
|
588
|
+
if selection_result.nil? || !dead_result?(selection_result)
|
504
589
|
value.path ||= path
|
505
590
|
value.ast_node ||= ast_node
|
506
591
|
context.errors << value
|
507
|
-
|
592
|
+
if selection_result
|
593
|
+
set_result(selection_result, result_name, nil)
|
594
|
+
end
|
508
595
|
end
|
509
596
|
HALT
|
510
597
|
elsif value.is_a?(GraphQL::UnauthorizedError)
|
@@ -517,6 +604,17 @@ module GraphQL
|
|
517
604
|
end
|
518
605
|
continue_value(path, next_value, parent_type, field, is_non_null, ast_node, result_name, selection_result)
|
519
606
|
elsif GraphQL::Execution::Execute::SKIP == value
|
607
|
+
# It's possible a lazy was already written here
|
608
|
+
case selection_result
|
609
|
+
when GraphQLResultHash
|
610
|
+
selection_result.delete(result_name)
|
611
|
+
when GraphQLResultArray
|
612
|
+
selection_result.graphql_skip_at(result_name)
|
613
|
+
when nil
|
614
|
+
# this can happen with directives
|
615
|
+
else
|
616
|
+
raise "Invariant: unexpected result class #{selection_result.class} (#{selection_result.inspect})"
|
617
|
+
end
|
520
618
|
HALT
|
521
619
|
else
|
522
620
|
# What could this actually _be_? Anyhow,
|
@@ -526,13 +624,15 @@ module GraphQL
|
|
526
624
|
when Array
|
527
625
|
# It's an array full of execution errors; add them all.
|
528
626
|
if value.any? && value.all? { |v| v.is_a?(GraphQL::ExecutionError) }
|
529
|
-
if !dead_result?(selection_result)
|
627
|
+
if selection_result.nil? || !dead_result?(selection_result)
|
530
628
|
value.each_with_index do |error, index|
|
531
629
|
error.ast_node ||= ast_node
|
532
|
-
error.path ||= path + (field.type.list? ? [index] : [])
|
630
|
+
error.path ||= path + ((field && field.type.list?) ? [index] : [])
|
533
631
|
context.errors << error
|
534
632
|
end
|
535
|
-
|
633
|
+
if selection_result
|
634
|
+
set_result(selection_result, result_name, nil)
|
635
|
+
end
|
536
636
|
end
|
537
637
|
HALT
|
538
638
|
else
|
@@ -689,9 +789,24 @@ module GraphQL
|
|
689
789
|
if !dir_defn.is_a?(Class)
|
690
790
|
dir_defn = dir_defn.type_class || raise("Only class-based directives are supported (not `@#{dir_node.name}`)")
|
691
791
|
end
|
692
|
-
|
693
|
-
|
694
|
-
|
792
|
+
raw_dir_args = arguments(nil, dir_defn, dir_node)
|
793
|
+
dir_args = continue_value(
|
794
|
+
@context[:current_path], # path
|
795
|
+
raw_dir_args, # value
|
796
|
+
dir_defn, # parent_type
|
797
|
+
nil, # field
|
798
|
+
false, # is_non_null
|
799
|
+
dir_node, # ast_node
|
800
|
+
nil, # result_name
|
801
|
+
nil, # selection_result
|
802
|
+
)
|
803
|
+
|
804
|
+
if dir_args == HALT
|
805
|
+
nil
|
806
|
+
else
|
807
|
+
dir_defn.resolve(object, dir_args, context) do
|
808
|
+
run_directive(object, directives, idx + 1, &block)
|
809
|
+
end
|
695
810
|
end
|
696
811
|
end
|
697
812
|
end
|
@@ -48,7 +48,11 @@ module GraphQL
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
|
51
|
+
# `SKIP` was made into a subclass of `GraphQL::Error` to improve runtime performance
|
52
|
+
# (fewer clauses in a hot `case` block), but now it requires special handling here.
|
53
|
+
# I think it's still worth it for the performance win, but if the number of special
|
54
|
+
# cases grows, then maybe it's worth rethinking somehow.
|
55
|
+
if @value.is_a?(StandardError) && @value != GraphQL::Execution::Execute::SKIP
|
52
56
|
raise @value
|
53
57
|
else
|
54
58
|
@value
|
@@ -39,7 +39,7 @@ module GraphQL
|
|
39
39
|
transform_name = arguments[:by]
|
40
40
|
if TRANSFORMS.include?(transform_name) && return_value.respond_to?(transform_name)
|
41
41
|
return_value = return_value.public_send(transform_name)
|
42
|
-
response = context.namespace(:interpreter)[:runtime].
|
42
|
+
response = context.namespace(:interpreter)[:runtime].final_result
|
43
43
|
*keys, last = path
|
44
44
|
keys.each do |key|
|
45
45
|
if response && (response = response[key])
|
data/lib/graphql/schema/enum.rb
CHANGED
@@ -24,6 +24,15 @@ module GraphQL
|
|
24
24
|
extend GraphQL::Schema::Member::ValidatesInput
|
25
25
|
|
26
26
|
class UnresolvedValueError < GraphQL::EnumType::UnresolvedValueError
|
27
|
+
def initialize(value:, enum:, context:)
|
28
|
+
fix_message = ", but this isn't a valid value for `#{enum.graphql_name}`. Update the field or resolver to return one of `#{enum.graphql_name}`'s values instead."
|
29
|
+
message = if (cp = context[:current_path]) && (cf = context[:current_field])
|
30
|
+
"`#{cf.path}` returned `#{value.inspect}` at `#{cp.join(".")}`#{fix_message}"
|
31
|
+
else
|
32
|
+
"`#{value.inspect}` was returned for `#{enum.graphql_name}`#{fix_message}"
|
33
|
+
end
|
34
|
+
super(message)
|
35
|
+
end
|
27
36
|
end
|
28
37
|
|
29
38
|
class << self
|
@@ -100,7 +109,7 @@ module GraphQL
|
|
100
109
|
if enum_value
|
101
110
|
enum_value.graphql_name
|
102
111
|
else
|
103
|
-
raise
|
112
|
+
raise self::UnresolvedValueError.new(enum: self, value: value, context: ctx)
|
104
113
|
end
|
105
114
|
end
|
106
115
|
|
@@ -11,6 +11,14 @@ module GraphQL
|
|
11
11
|
|
12
12
|
include GraphQL::Dig
|
13
13
|
|
14
|
+
# @return [GraphQL::Query::Context] The context for this query
|
15
|
+
attr_reader :context
|
16
|
+
# @return [GraphQL::Query::Arguments, GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
|
17
|
+
attr_reader :arguments
|
18
|
+
|
19
|
+
# Ruby-like hash behaviors, read-only
|
20
|
+
def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
|
21
|
+
|
14
22
|
def initialize(arguments = nil, ruby_kwargs: nil, context:, defaults_used:)
|
15
23
|
@context = context
|
16
24
|
if ruby_kwargs
|
@@ -54,19 +62,8 @@ module GraphQL
|
|
54
62
|
@maybe_lazies = maybe_lazies
|
55
63
|
end
|
56
64
|
|
57
|
-
# @return [GraphQL::Query::Context] The context for this query
|
58
|
-
attr_reader :context
|
59
|
-
|
60
|
-
# @return [GraphQL::Query::Arguments, GraphQL::Execution::Interpereter::Arguments] The underlying arguments instance
|
61
|
-
attr_reader :arguments
|
62
|
-
|
63
|
-
# Ruby-like hash behaviors, read-only
|
64
|
-
def_delegators :@ruby_style_hash, :keys, :values, :each, :map, :any?, :empty?
|
65
|
-
|
66
65
|
def to_h
|
67
|
-
@ruby_style_hash
|
68
|
-
h.merge(key => unwrap_value(value))
|
69
|
-
end
|
66
|
+
unwrap_value(@ruby_style_hash)
|
70
67
|
end
|
71
68
|
|
72
69
|
def to_hash
|
@@ -91,8 +88,8 @@ module GraphQL
|
|
91
88
|
when Array
|
92
89
|
value.map { |item| unwrap_value(item) }
|
93
90
|
when Hash
|
94
|
-
value.
|
95
|
-
h.merge(key => unwrap_value(value))
|
91
|
+
value.reduce({}) do |h, (key, value)|
|
92
|
+
h.merge!(key => unwrap_value(value))
|
96
93
|
end
|
97
94
|
when InputObject
|
98
95
|
value.to_h
|
@@ -162,7 +159,6 @@ module GraphQL
|
|
162
159
|
# @api private
|
163
160
|
INVALID_OBJECT_MESSAGE = "Expected %{object} to be a key-value object responding to `to_h` or `to_unsafe_h`."
|
164
161
|
|
165
|
-
|
166
162
|
def validate_non_null_input(input, ctx)
|
167
163
|
result = GraphQL::Query::InputValidationResult.new
|
168
164
|
|
@@ -4,37 +4,32 @@ module GraphQL
|
|
4
4
|
# Used to convert your {GraphQL::Schema} to a GraphQL schema string
|
5
5
|
#
|
6
6
|
# @example print your schema to standard output (via helper)
|
7
|
-
# MySchema = GraphQL::Schema.define(query: QueryType)
|
8
7
|
# puts GraphQL::Schema::Printer.print_schema(MySchema)
|
9
8
|
#
|
10
9
|
# @example print your schema to standard output
|
11
|
-
# MySchema = GraphQL::Schema.define(query: QueryType)
|
12
10
|
# puts GraphQL::Schema::Printer.new(MySchema).print_schema
|
13
11
|
#
|
14
12
|
# @example print a single type to standard output
|
15
|
-
#
|
16
|
-
# name "Query"
|
13
|
+
# class Types::Query < GraphQL::Schema::Object
|
17
14
|
# description "The query root of this schema"
|
18
15
|
#
|
19
|
-
# field :post
|
20
|
-
# type post_type
|
21
|
-
# resolve ->(obj, args, ctx) { Post.find(args["id"]) }
|
22
|
-
# end
|
16
|
+
# field :post, Types::Post, null: true
|
23
17
|
# end
|
24
18
|
#
|
25
|
-
#
|
26
|
-
# name "Post"
|
19
|
+
# class Types::Post < GraphQL::Schema::Object
|
27
20
|
# description "A blog post"
|
28
21
|
#
|
29
|
-
# field :id,
|
30
|
-
# field :title,
|
31
|
-
# field :body,
|
22
|
+
# field :id, ID, null: false
|
23
|
+
# field :title, String, null: false
|
24
|
+
# field :body, String, null: false
|
32
25
|
# end
|
33
26
|
#
|
34
|
-
# MySchema
|
27
|
+
# class MySchema < GraphQL::Schema
|
28
|
+
# query(Types::Query)
|
29
|
+
# end
|
35
30
|
#
|
36
31
|
# printer = GraphQL::Schema::Printer.new(MySchema)
|
37
|
-
# puts printer.print_type(
|
32
|
+
# puts printer.print_type(Types::Post)
|
38
33
|
#
|
39
34
|
class Printer < GraphQL::Language::Printer
|
40
35
|
attr_reader :schema, :warden
|
@@ -87,7 +82,7 @@ module GraphQL
|
|
87
82
|
|
88
83
|
# Return a GraphQL schema string for the defined types in the schema
|
89
84
|
def print_schema
|
90
|
-
print(@document)
|
85
|
+
print(@document) + "\n"
|
91
86
|
end
|
92
87
|
|
93
88
|
def print_type(type)
|
@@ -307,10 +307,15 @@ module GraphQL
|
|
307
307
|
arguments: arguments,
|
308
308
|
null: null,
|
309
309
|
complexity: complexity,
|
310
|
-
extensions: extensions,
|
311
310
|
broadcastable: broadcastable?,
|
312
311
|
}
|
313
312
|
|
313
|
+
# If there aren't any, then the returned array is `[].freeze`,
|
314
|
+
# but passing that along breaks some user code.
|
315
|
+
if (exts = extensions).any?
|
316
|
+
field_opts[:extensions] = exts
|
317
|
+
end
|
318
|
+
|
314
319
|
if has_max_page_size?
|
315
320
|
field_opts[:max_page_size] = max_page_size
|
316
321
|
end
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module GraphQL
|
4
4
|
module Types
|
5
5
|
module Relay
|
6
|
+
# Include this module to your root Query type to get a Relay-compliant `node(id: ID!): Node` field that uses the schema's `object_from_id` hook.
|
6
7
|
module HasNodeField
|
7
8
|
def self.included(child_class)
|
8
9
|
child_class.field(**field_options, &field_block)
|
@@ -12,7 +13,6 @@ module GraphQL
|
|
12
13
|
def field_options
|
13
14
|
{
|
14
15
|
name: "node",
|
15
|
-
owner: nil,
|
16
16
|
type: GraphQL::Types::Relay::Node,
|
17
17
|
null: true,
|
18
18
|
description: "Fetches an object given its ID.",
|
@@ -3,6 +3,7 @@
|
|
3
3
|
module GraphQL
|
4
4
|
module Types
|
5
5
|
module Relay
|
6
|
+
# Include this module to your root Query type to get a Relay-style `nodes(id: ID!): [Node]` field that uses the schema's `object_from_id` hook.
|
6
7
|
module HasNodesField
|
7
8
|
def self.included(child_class)
|
8
9
|
child_class.field(**field_options, &field_block)
|
@@ -12,7 +13,6 @@ module GraphQL
|
|
12
13
|
def field_options
|
13
14
|
{
|
14
15
|
name: "nodes",
|
15
|
-
owner: nil,
|
16
16
|
type: [GraphQL::Types::Relay::Node, null: true],
|
17
17
|
null: false,
|
18
18
|
description: "Fetches a list of objects given a list of IDs.",
|
@@ -6,7 +6,7 @@ module GraphQL
|
|
6
6
|
# or use it for inspiration for your own field definition.
|
7
7
|
#
|
8
8
|
# @example Adding this field directly
|
9
|
-
#
|
9
|
+
# include GraphQL::Types::Relay::HasNodeField
|
10
10
|
#
|
11
11
|
# @example Implementing a similar field in your own Query root
|
12
12
|
#
|
@@ -19,7 +19,7 @@ module GraphQL
|
|
19
19
|
# context.schema.object_from_id(id, context)
|
20
20
|
# end
|
21
21
|
#
|
22
|
-
NodeField = GraphQL::Schema::Field.new(**HasNodeField.field_options, &HasNodeField.field_block)
|
22
|
+
NodeField = GraphQL::Schema::Field.new(owner: nil, **HasNodeField.field_options, &HasNodeField.field_block)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -6,7 +6,7 @@ module GraphQL
|
|
6
6
|
# or use it for inspiration for your own field definition.
|
7
7
|
#
|
8
8
|
# @example Adding this field directly
|
9
|
-
#
|
9
|
+
# include GraphQL::Types::Relay::HasNodesField
|
10
10
|
#
|
11
11
|
# @example Implementing a similar field in your own Query root
|
12
12
|
#
|
@@ -21,7 +21,7 @@ module GraphQL
|
|
21
21
|
# end
|
22
22
|
# end
|
23
23
|
#
|
24
|
-
NodesField = GraphQL::Schema::Field.new(**HasNodesField.field_options, &HasNodesField.field_block)
|
24
|
+
NodesField = GraphQL::Schema::Field.new(owner: nil, **HasNodesField.field_options, &HasNodesField.field_block)
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
data/lib/graphql/version.rb
CHANGED
data/readme.md
CHANGED
@@ -2,9 +2,6 @@
|
|
2
2
|
|
3
3
|
[![CI Suite](https://github.com/rmosolgo/graphql-ruby/actions/workflows/ci.yaml/badge.svg)](https://github.com/rmosolgo/graphql-ruby/actions/workflows/ci.yaml)
|
4
4
|
[![Gem Version](https://badge.fury.io/rb/graphql.svg)](https://rubygems.org/gems/graphql)
|
5
|
-
[![Code Climate](https://codeclimate.com/github/rmosolgo/graphql-ruby/badges/gpa.svg)](https://codeclimate.com/github/rmosolgo/graphql-ruby)
|
6
|
-
[![Test Coverage](https://codeclimate.com/github/rmosolgo/graphql-ruby/badges/coverage.svg)](https://codeclimate.com/github/rmosolgo/graphql-ruby)
|
7
|
-
[![built with love](https://cloud.githubusercontent.com/assets/2231765/6766607/d07992c6-cfc9-11e4-813f-d9240714dd50.png)](https://rmosolgo.github.io/react-badges/)
|
8
5
|
|
9
6
|
A Ruby implementation of [GraphQL](https://graphql.org/).
|
10
7
|
|
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.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: codeclimate-test-reporter
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0.4'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0.4'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: concurrent-ruby
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,20 +136,6 @@ dependencies:
|
|
150
136
|
- - '='
|
151
137
|
- !ruby/object:Gem::Version
|
152
138
|
version: '0.68'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: stackprof
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - ">="
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '0'
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - ">="
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: '0'
|
167
139
|
- !ruby/object:Gem::Dependency
|
168
140
|
name: parser
|
169
141
|
requirement: !ruby/object:Gem::Requirement
|
@@ -713,7 +685,7 @@ metadata:
|
|
713
685
|
source_code_uri: https://github.com/rmosolgo/graphql-ruby
|
714
686
|
bug_tracker_uri: https://github.com/rmosolgo/graphql-ruby/issues
|
715
687
|
mailing_list_uri: https://tinyletter.com/graphql-ruby
|
716
|
-
post_install_message:
|
688
|
+
post_install_message:
|
717
689
|
rdoc_options: []
|
718
690
|
require_paths:
|
719
691
|
- lib
|
@@ -728,8 +700,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
728
700
|
- !ruby/object:Gem::Version
|
729
701
|
version: '0'
|
730
702
|
requirements: []
|
731
|
-
rubygems_version: 3.
|
732
|
-
signing_key:
|
703
|
+
rubygems_version: 3.2.15
|
704
|
+
signing_key:
|
733
705
|
specification_version: 4
|
734
706
|
summary: A GraphQL language and runtime for Ruby
|
735
707
|
test_files: []
|