graphql 2.5.1 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/graphql/execution/interpreter/runtime/graphql_result.rb +23 -0
- data/lib/graphql/execution/interpreter/runtime.rb +16 -10
- data/lib/graphql/schema/directive/flagged.rb +2 -0
- data/lib/graphql/schema/field.rb +15 -1
- data/lib/graphql/schema/input_object.rb +1 -1
- data/lib/graphql/schema/member/has_deprecation_reason.rb +15 -0
- data/lib/graphql/schema/resolver.rb +1 -0
- data/lib/graphql/schema/visibility/profile.rb +31 -11
- 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: cff992b51cd3efae382a362bc5708e8dce5060efb48cf1944560262a59276283
|
4
|
+
data.tar.gz: 206fd93c0504f9072f8af62a18557a9e0380664b1f8836acd38426ee44e9eaf7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 293369e23e4baee72a07481b6a6015be003e2557469ab3b30e1ee82d79bfaf6004218a5fe0a85033de8e92b3ae475508bf445e5906ec2a81c4df53c2b25add49
|
7
|
+
data.tar.gz: fafe652c92d2655ad39a16fb61252b33b27eee4e10476a5cc40ab7fd3c1e81a56f9e67b81f6a9ba1da67ba76c7112e756973a236287c634bae9cf66fb7ed3e3e
|
@@ -44,8 +44,11 @@ module GraphQL
|
|
44
44
|
def initialize(_result_name, _result_type, _application_value, _parent_result, _is_non_null_in_parent, _selections, _is_eager, _ast_node, _graphql_arguments, graphql_field) # rubocop:disable Metrics/ParameterLists
|
45
45
|
super
|
46
46
|
@graphql_result_data = {}
|
47
|
+
@ordered_result_keys = nil
|
47
48
|
end
|
48
49
|
|
50
|
+
attr_accessor :ordered_result_keys
|
51
|
+
|
49
52
|
include GraphQLResult
|
50
53
|
|
51
54
|
attr_accessor :graphql_merged_into
|
@@ -63,7 +66,13 @@ module GraphQL
|
|
63
66
|
t.set_leaf(key, value)
|
64
67
|
end
|
65
68
|
|
69
|
+
before_size = @graphql_result_data.size
|
66
70
|
@graphql_result_data[key] = value
|
71
|
+
after_size = @graphql_result_data.size
|
72
|
+
if after_size > before_size && @ordered_result_keys[before_size] != key
|
73
|
+
fix_result_order
|
74
|
+
end
|
75
|
+
|
67
76
|
# keep this up-to-date if it's been initialized
|
68
77
|
@graphql_metadata && @graphql_metadata[key] = value
|
69
78
|
|
@@ -74,7 +83,13 @@ module GraphQL
|
|
74
83
|
if (t = @graphql_merged_into)
|
75
84
|
t.set_child_result(key, value)
|
76
85
|
end
|
86
|
+
before_size = @graphql_result_data.size
|
77
87
|
@graphql_result_data[key] = value.graphql_result_data
|
88
|
+
after_size = @graphql_result_data.size
|
89
|
+
if after_size > before_size && @ordered_result_keys[before_size] != key
|
90
|
+
fix_result_order
|
91
|
+
end
|
92
|
+
|
78
93
|
# If we encounter some part of this response that requires metadata tracking,
|
79
94
|
# then create the metadata hash if necessary. It will be kept up-to-date after this.
|
80
95
|
(@graphql_metadata ||= @graphql_result_data.dup)[key] = value
|
@@ -124,6 +139,14 @@ module GraphQL
|
|
124
139
|
end
|
125
140
|
@graphql_merged_into = into_result
|
126
141
|
end
|
142
|
+
|
143
|
+
def fix_result_order
|
144
|
+
@ordered_result_keys.each do |k|
|
145
|
+
if @graphql_result_data.key?(k)
|
146
|
+
@graphql_result_data[k] = @graphql_result_data.delete(k)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
127
150
|
end
|
128
151
|
|
129
152
|
class GraphQLResultArray
|
@@ -83,9 +83,11 @@ module GraphQL
|
|
83
83
|
@response = nil
|
84
84
|
else
|
85
85
|
call_method_on_directives(:resolve, runtime_object, root_operation.directives) do # execute query level directives
|
86
|
-
each_gathered_selections(@response) do |selections, is_selection_array|
|
86
|
+
each_gathered_selections(@response) do |selections, is_selection_array, ordered_result_keys|
|
87
|
+
@response.ordered_result_keys ||= ordered_result_keys
|
87
88
|
if is_selection_array
|
88
89
|
selection_response = GraphQLResultHash.new(nil, root_type, runtime_object, nil, false, selections, is_eager, root_operation, nil, nil)
|
90
|
+
selection_response.ordered_result_keys = ordered_result_keys
|
89
91
|
final_response = @response
|
90
92
|
else
|
91
93
|
selection_response = @response
|
@@ -107,17 +109,19 @@ module GraphQL
|
|
107
109
|
end
|
108
110
|
|
109
111
|
def each_gathered_selections(response_hash)
|
110
|
-
|
112
|
+
ordered_result_keys = []
|
113
|
+
gathered_selections = gather_selections(response_hash.graphql_application_value, response_hash.graphql_result_type, response_hash.graphql_selections, nil, {}, ordered_result_keys)
|
114
|
+
ordered_result_keys.uniq!
|
111
115
|
if gathered_selections.is_a?(Array)
|
112
116
|
gathered_selections.each do |item|
|
113
|
-
yield(item, true)
|
117
|
+
yield(item, true, ordered_result_keys)
|
114
118
|
end
|
115
119
|
else
|
116
|
-
yield(gathered_selections, false)
|
120
|
+
yield(gathered_selections, false, ordered_result_keys)
|
117
121
|
end
|
118
122
|
end
|
119
123
|
|
120
|
-
def gather_selections(owner_object, owner_type, selections, selections_to_run
|
124
|
+
def gather_selections(owner_object, owner_type, selections, selections_to_run, selections_by_name, ordered_result_keys)
|
121
125
|
selections.each do |node|
|
122
126
|
# Skip gathering this if the directive says so
|
123
127
|
if !directives_include?(node, owner_object, owner_type)
|
@@ -126,6 +130,7 @@ module GraphQL
|
|
126
130
|
|
127
131
|
if node.is_a?(GraphQL::Language::Nodes::Field)
|
128
132
|
response_key = node.alias || node.name
|
133
|
+
ordered_result_keys << response_key
|
129
134
|
selections = selections_by_name[response_key]
|
130
135
|
# if there was already a selection of this field,
|
131
136
|
# use an array to hold all selections,
|
@@ -162,14 +167,14 @@ module GraphQL
|
|
162
167
|
type_defn = query.types.type(node.type.name)
|
163
168
|
|
164
169
|
if query.types.possible_types(type_defn).include?(owner_type)
|
165
|
-
result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
|
170
|
+
result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections, ordered_result_keys)
|
166
171
|
if !result.equal?(next_selections)
|
167
172
|
selections_to_run = result
|
168
173
|
end
|
169
174
|
end
|
170
175
|
else
|
171
176
|
# it's an untyped fragment, definitely continue
|
172
|
-
result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections)
|
177
|
+
result = gather_selections(owner_object, owner_type, node.selections, selections_to_run, next_selections, ordered_result_keys)
|
173
178
|
if !result.equal?(next_selections)
|
174
179
|
selections_to_run = result
|
175
180
|
end
|
@@ -178,7 +183,7 @@ module GraphQL
|
|
178
183
|
fragment_def = query.fragments[node.name]
|
179
184
|
type_defn = query.types.type(fragment_def.type.name)
|
180
185
|
if query.types.possible_types(type_defn).include?(owner_type)
|
181
|
-
result = gather_selections(owner_object, owner_type, fragment_def.selections, selections_to_run, next_selections)
|
186
|
+
result = gather_selections(owner_object, owner_type, fragment_def.selections, selections_to_run, next_selections, ordered_result_keys)
|
182
187
|
if !result.equal?(next_selections)
|
183
188
|
selections_to_run = result
|
184
189
|
end
|
@@ -207,7 +212,6 @@ module GraphQL
|
|
207
212
|
finished_jobs = 0
|
208
213
|
enqueued_jobs = gathered_selections.size
|
209
214
|
gathered_selections.each do |result_name, field_ast_nodes_or_ast_node|
|
210
|
-
|
211
215
|
# Field resolution may pause the fiber,
|
212
216
|
# so it wouldn't get to the `Resolve` call that happens below.
|
213
217
|
# So instead trigger a run from this outer context.
|
@@ -629,9 +633,11 @@ module GraphQL
|
|
629
633
|
if HALT != continue_value
|
630
634
|
response_hash = GraphQLResultHash.new(result_name, current_type, continue_value, selection_result, is_non_null, next_selections, false, ast_node, arguments, field)
|
631
635
|
set_result(selection_result, result_name, response_hash, true, is_non_null)
|
632
|
-
each_gathered_selections(response_hash) do |selections, is_selection_array|
|
636
|
+
each_gathered_selections(response_hash) do |selections, is_selection_array, ordered_result_keys|
|
637
|
+
response_hash.ordered_result_keys ||= ordered_result_keys
|
633
638
|
if is_selection_array
|
634
639
|
this_result = GraphQLResultHash.new(result_name, current_type, continue_value, selection_result, is_non_null, selections, false, ast_node, arguments, field)
|
640
|
+
this_result.ordered_result_keys = ordered_result_keys
|
635
641
|
final_result = response_hash
|
636
642
|
else
|
637
643
|
this_result = response_hash
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -41,10 +41,24 @@ module GraphQL
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
# @return [String, nil]
|
45
|
+
def deprecation_reason
|
46
|
+
super || @resolver_class&.deprecation_reason
|
47
|
+
end
|
48
|
+
|
44
49
|
def directives
|
45
50
|
if @resolver_class && !(r_dirs = @resolver_class.directives).empty?
|
46
51
|
if !(own_dirs = super).empty?
|
47
|
-
|
52
|
+
new_dirs = own_dirs.dup
|
53
|
+
r_dirs.each do |r_dir|
|
54
|
+
if r_dir.class.repeatable? ||
|
55
|
+
( (r_dir_name = r_dir.graphql_name) &&
|
56
|
+
(!new_dirs.any? { |d| d.graphql_name == r_dir_name })
|
57
|
+
)
|
58
|
+
new_dirs << r_dir
|
59
|
+
end
|
60
|
+
end
|
61
|
+
new_dirs
|
48
62
|
else
|
49
63
|
r_dirs
|
50
64
|
end
|
@@ -38,7 +38,7 @@ module GraphQL
|
|
38
38
|
# Weirdly, procs are applied during coercion, but not methods.
|
39
39
|
# Probably because these methods require a `self`.
|
40
40
|
if arg_defn.prepare.is_a?(Symbol) || context.nil?
|
41
|
-
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key])
|
41
|
+
prepared_value = arg_defn.prepare_value(self, @ruby_style_hash[ruby_kwargs_key], context: context)
|
42
42
|
overwrite_argument(ruby_kwargs_key, prepared_value)
|
43
43
|
end
|
44
44
|
end
|
@@ -18,6 +18,21 @@ module GraphQL
|
|
18
18
|
directive(GraphQL::Schema::Directive::Deprecated, reason: text)
|
19
19
|
end
|
20
20
|
end
|
21
|
+
|
22
|
+
def self.extended(child_class)
|
23
|
+
super
|
24
|
+
child_class.extend(ClassMethods)
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def deprecation_reason(new_reason = NOT_CONFIGURED)
|
29
|
+
if NOT_CONFIGURED.equal?(new_reason)
|
30
|
+
super()
|
31
|
+
else
|
32
|
+
self.deprecation_reason = new_reason
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
21
36
|
end
|
22
37
|
end
|
23
38
|
end
|
@@ -28,6 +28,7 @@ module GraphQL
|
|
28
28
|
extend Schema::Member::HasPath
|
29
29
|
extend Schema::Member::HasDirectives
|
30
30
|
include Schema::Member::HasDataloader
|
31
|
+
extend Schema::Member::HasDeprecationReason
|
31
32
|
|
32
33
|
# @param object [Object] The application object that this field is being resolved on
|
33
34
|
# @param context [GraphQL::Query::Context]
|
@@ -47,12 +47,21 @@ module GraphQL
|
|
47
47
|
end.compare_by_identity
|
48
48
|
}.compare_by_identity
|
49
49
|
|
50
|
-
@cached_visible_arguments = Hash.new do |h,
|
51
|
-
h[
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
50
|
+
@cached_visible_arguments = Hash.new do |h, owner|
|
51
|
+
h[owner] = Hash.new do |h2, arg|
|
52
|
+
h2[arg] = if @cached_visible[arg] && (arg_type = arg.type.unwrap) && @cached_visible[arg_type]
|
53
|
+
case owner
|
54
|
+
when GraphQL::Schema::Field
|
55
|
+
@cached_visible_fields[owner.owner][owner]
|
56
|
+
when Class
|
57
|
+
@cached_visible[owner]
|
58
|
+
else
|
59
|
+
raise "Unexpected argument owner for `#{arg.path}`: #{owner.inspect}"
|
60
|
+
end
|
61
|
+
else
|
62
|
+
false
|
63
|
+
end
|
64
|
+
end.compare_by_identity
|
56
65
|
end.compare_by_identity
|
57
66
|
|
58
67
|
@cached_parent_fields = Hash.new do |h, type|
|
@@ -82,7 +91,7 @@ module GraphQL
|
|
82
91
|
end.compare_by_identity
|
83
92
|
|
84
93
|
@cached_arguments = Hash.new do |h, owner|
|
85
|
-
h[owner] = non_duplicate_items(owner.all_argument_definitions, @cached_visible_arguments)
|
94
|
+
h[owner] = non_duplicate_items(owner.all_argument_definitions, @cached_visible_arguments[owner])
|
86
95
|
end.compare_by_identity
|
87
96
|
|
88
97
|
@loadable_possible_types = Hash.new { |h, union_type| h[union_type] = union_type.possible_types }.compare_by_identity
|
@@ -180,7 +189,7 @@ module GraphQL
|
|
180
189
|
if arg.is_a?(Array)
|
181
190
|
visible_arg = nil
|
182
191
|
arg.each do |arg_defn|
|
183
|
-
if @cached_visible_arguments[arg_defn]
|
192
|
+
if @cached_visible_arguments[owner][arg_defn]
|
184
193
|
if visible_arg.nil?
|
185
194
|
visible_arg = arg_defn
|
186
195
|
else
|
@@ -190,7 +199,7 @@ module GraphQL
|
|
190
199
|
end
|
191
200
|
visible_arg
|
192
201
|
else
|
193
|
-
if arg && @cached_visible_arguments[arg]
|
202
|
+
if arg && @cached_visible_arguments[owner][arg]
|
194
203
|
arg
|
195
204
|
else
|
196
205
|
nil
|
@@ -292,7 +301,7 @@ module GraphQL
|
|
292
301
|
@all_types_loaded = true
|
293
302
|
visit = Visibility::Visit.new(@schema) do |member|
|
294
303
|
if member.is_a?(Module) && member.respond_to?(:kind)
|
295
|
-
if @cached_visible[member]
|
304
|
+
if @cached_visible[member] && referenced?(member)
|
296
305
|
type_name = member.graphql_name
|
297
306
|
if (prev_t = @all_types[type_name]) && !prev_t.equal?(member)
|
298
307
|
raise_duplicate_definition(member, prev_t)
|
@@ -312,7 +321,18 @@ module GraphQL
|
|
312
321
|
end
|
313
322
|
|
314
323
|
def referenced?(type_defn)
|
315
|
-
@schema.visibility.all_references[type_defn].any?
|
324
|
+
@schema.visibility.all_references[type_defn].any? do |ref|
|
325
|
+
case ref
|
326
|
+
when GraphQL::Schema::Argument
|
327
|
+
@cached_visible_arguments[ref.owner][ref]
|
328
|
+
when GraphQL::Schema::Field
|
329
|
+
@cached_visible_fields[ref.owner][ref]
|
330
|
+
when Module
|
331
|
+
@cached_visible[ref]
|
332
|
+
when true
|
333
|
+
true
|
334
|
+
end
|
335
|
+
end
|
316
336
|
end
|
317
337
|
|
318
338
|
def possible_types_for(type)
|
data/lib/graphql/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.5.
|
4
|
+
version: 2.5.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
bindir: bin
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-04-
|
10
|
+
date: 2025-04-08 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: base64
|