graphql-client 0.15.0 → 0.16.0
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/client.rb +56 -11
- data/lib/graphql/client/definition.rb +7 -5
- data/lib/graphql/client/definition_variables.rb +6 -6
- data/lib/graphql/client/document_types.rb +5 -2
- data/lib/graphql/client/query_typename.rb +2 -2
- data/lib/graphql/client/schema.rb +18 -17
- data/lib/graphql/client/schema/enum_type.rb +2 -2
- data/lib/graphql/client/schema/interface_type.rb +2 -2
- data/lib/graphql/client/schema/object_type.rb +6 -5
- data/lib/graphql/client/schema/possible_types.rb +1 -1
- data/lib/graphql/client/schema/scalar_type.rb +2 -2
- data/lib/graphql/client/schema/union_type.rb +2 -2
- 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: 6810301cbdd84362dc4b8584e24deec3aec4248f4471734748cf1a33feaa5232
|
4
|
+
data.tar.gz: bb68c48d70c276c0443da6620506b37dbe152e20fb931a2ecf3a0cba45050f96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b7f114d4330ae5168669d7a663a0afdbd508ba056aa252a206efca9071f558c8749ecfd809ca0677ab9e3a5e95cc90eec3a6bcc2e4020875aab6621d9059dd8
|
7
|
+
data.tar.gz: b1a24192dc4ee004ae6d546d4d724d0c49da4a17a4fb86a1a7e81d1aefbe16618f32ed27a63a8c2297bd4074ec8dd91794ab057d3826d08ccfefe21d689e7e76
|
data/lib/graphql/client.rb
CHANGED
@@ -46,7 +46,7 @@ module GraphQL
|
|
46
46
|
|
47
47
|
def self.load_schema(schema)
|
48
48
|
case schema
|
49
|
-
when GraphQL::Schema
|
49
|
+
when GraphQL::Schema, Class
|
50
50
|
schema
|
51
51
|
when Hash
|
52
52
|
GraphQL::Schema::Loader.load(schema)
|
@@ -213,12 +213,17 @@ module GraphQL
|
|
213
213
|
definitions[node.name] = definition
|
214
214
|
end
|
215
215
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
216
|
+
if @document.respond_to?(:merge) # GraphQL 1.9+
|
217
|
+
visitor = RenameNodeVisitor.new(document_dependencies, definitions: definitions)
|
218
|
+
visitor.visit
|
219
|
+
else
|
220
|
+
name_hook = RenameNodeHook.new(definitions)
|
221
|
+
visitor = Language::Visitor.new(document_dependencies)
|
222
|
+
visitor[Language::Nodes::FragmentDefinition].leave << name_hook.method(:rename_node)
|
223
|
+
visitor[Language::Nodes::OperationDefinition].leave << name_hook.method(:rename_node)
|
224
|
+
visitor[Language::Nodes::FragmentSpread].leave << name_hook.method(:rename_node)
|
225
|
+
visitor.visit
|
226
|
+
end
|
222
227
|
|
223
228
|
if document_tracking_enabled
|
224
229
|
if @document.respond_to?(:merge) # GraphQL 1.9+
|
@@ -239,6 +244,38 @@ module GraphQL
|
|
239
244
|
end
|
240
245
|
end
|
241
246
|
|
247
|
+
class RenameNodeVisitor < GraphQL::Language::Visitor
|
248
|
+
def initialize(document, definitions:)
|
249
|
+
super(document)
|
250
|
+
@definitions = definitions
|
251
|
+
end
|
252
|
+
|
253
|
+
def on_fragment_definition(node, _parent)
|
254
|
+
rename_node(node)
|
255
|
+
super
|
256
|
+
end
|
257
|
+
|
258
|
+
def on_operation_definition(node, _parent)
|
259
|
+
rename_node(node)
|
260
|
+
super
|
261
|
+
end
|
262
|
+
|
263
|
+
def on_fragment_spread(node, _parent)
|
264
|
+
rename_node(node)
|
265
|
+
super
|
266
|
+
end
|
267
|
+
|
268
|
+
private
|
269
|
+
|
270
|
+
def rename_node(node)
|
271
|
+
definition = @definitions[node.name]
|
272
|
+
if definition
|
273
|
+
node.extend(LazyName)
|
274
|
+
node._definition = definition
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
242
279
|
class RenameNodeHook
|
243
280
|
def initialize(definitions)
|
244
281
|
@definitions = definitions
|
@@ -253,6 +290,14 @@ module GraphQL
|
|
253
290
|
end
|
254
291
|
end
|
255
292
|
|
293
|
+
# Public: A wrapper to use the more-efficient `.get_type` when it's available from GraphQL-Ruby (1.10+)
|
294
|
+
def get_type(type_name)
|
295
|
+
if @schema.respond_to?(:get_type)
|
296
|
+
@schema.get_type(type_name)
|
297
|
+
else
|
298
|
+
@schema.types[type_name]
|
299
|
+
end
|
300
|
+
end
|
256
301
|
|
257
302
|
# Public: Create operation definition from a fragment definition.
|
258
303
|
#
|
@@ -288,15 +333,15 @@ module GraphQL
|
|
288
333
|
variables = GraphQL::Client::DefinitionVariables.operation_variables(self.schema, fragment.document, fragment.definition_name)
|
289
334
|
type_name = fragment.definition_node.type.name
|
290
335
|
|
291
|
-
if schema.query && type_name == schema.query.
|
336
|
+
if schema.query && type_name == schema.query.graphql_name
|
292
337
|
operation_type = "query"
|
293
|
-
elsif schema.mutation && type_name == schema.mutation.
|
338
|
+
elsif schema.mutation && type_name == schema.mutation.graphql_name
|
294
339
|
operation_type = "mutation"
|
295
|
-
elsif schema.subscription && type_name == schema.subscription.
|
340
|
+
elsif schema.subscription && type_name == schema.subscription.graphql_name
|
296
341
|
operation_type = "subscription"
|
297
342
|
else
|
298
343
|
types = [schema.query, schema.mutation, schema.subscription].compact
|
299
|
-
raise Error, "Fragment must be defined on #{types.map(&:
|
344
|
+
raise Error, "Fragment must be defined on #{types.map(&:graphql_name).join(", ")}"
|
300
345
|
end
|
301
346
|
|
302
347
|
doc_ast = GraphQL::Language::Nodes::Document.new(definitions: [
|
@@ -45,7 +45,7 @@ module GraphQL
|
|
45
45
|
raise "Unexpected operation_type: #{ast_node.operation_type}"
|
46
46
|
end
|
47
47
|
when GraphQL::Language::Nodes::FragmentDefinition
|
48
|
-
@client.
|
48
|
+
@client.get_type(ast_node.type.name)
|
49
49
|
else
|
50
50
|
raise "Unexpected ast_node: #{ast_node}"
|
51
51
|
end
|
@@ -170,16 +170,18 @@ module GraphQL
|
|
170
170
|
end
|
171
171
|
|
172
172
|
def flatten_spreads(node)
|
173
|
-
|
173
|
+
spreads = []
|
174
|
+
node.selections.each do |selection|
|
174
175
|
case selection
|
175
176
|
when Language::Nodes::FragmentSpread
|
176
|
-
selection
|
177
|
+
spreads << selection
|
177
178
|
when Language::Nodes::InlineFragment
|
178
|
-
flatten_spreads(selection)
|
179
|
+
spreads.concat(flatten_spreads(selection))
|
179
180
|
else
|
180
|
-
|
181
|
+
# Do nothing, not a spread
|
181
182
|
end
|
182
183
|
end
|
184
|
+
spreads
|
183
185
|
end
|
184
186
|
|
185
187
|
def index_node_definitions(visitor)
|
@@ -14,7 +14,7 @@ module GraphQL
|
|
14
14
|
#
|
15
15
|
# Returns a Hash[Symbol] to GraphQL::Type objects.
|
16
16
|
def self.variables(schema, document, definition_name = nil)
|
17
|
-
unless schema.is_a?(GraphQL::Schema)
|
17
|
+
unless schema.is_a?(GraphQL::Schema) || (schema.is_a?(Class) && schema < GraphQL::Schema)
|
18
18
|
raise TypeError, "expected schema to be a GraphQL::Schema, but was #{schema.class}"
|
19
19
|
end
|
20
20
|
|
@@ -35,7 +35,7 @@ module GraphQL
|
|
35
35
|
|
36
36
|
if existing_type && existing_type.unwrap != definition.type.unwrap
|
37
37
|
raise GraphQL::Client::ValidationError, "$#{node.name} was already declared as #{existing_type.unwrap}, but was #{definition.type.unwrap}"
|
38
|
-
elsif !existing_type.
|
38
|
+
elsif !(existing_type && existing_type.kind.non_null?)
|
39
39
|
variables[node.name.to_sym] = definition.type
|
40
40
|
end
|
41
41
|
end
|
@@ -66,13 +66,13 @@ module GraphQL
|
|
66
66
|
#
|
67
67
|
# Returns GraphQL::Language::Nodes::Type.
|
68
68
|
def self.variable_node(type)
|
69
|
-
case type
|
70
|
-
when
|
69
|
+
case type.kind.name
|
70
|
+
when "NON_NULL"
|
71
71
|
GraphQL::Language::Nodes::NonNullType.new(of_type: variable_node(type.of_type))
|
72
|
-
when
|
72
|
+
when "LIST"
|
73
73
|
GraphQL::Language::Nodes::ListType.new(of_type: variable_node(type.of_type))
|
74
74
|
else
|
75
|
-
GraphQL::Language::Nodes::TypeName.new(name: type.
|
75
|
+
GraphQL::Language::Nodes::TypeName.new(name: type.graphql_name)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
end
|
@@ -12,7 +12,7 @@ module GraphQL
|
|
12
12
|
#
|
13
13
|
# Returns a Hash[Language::Nodes::Node] to GraphQL::Type objects.
|
14
14
|
def self.analyze_types(schema, document)
|
15
|
-
unless schema.is_a?(GraphQL::Schema)
|
15
|
+
unless schema.is_a?(GraphQL::Schema) || (schema.is_a?(Class) && schema < GraphQL::Schema)
|
16
16
|
raise TypeError, "expected schema to be a GraphQL::Schema, but was #{schema.class}"
|
17
17
|
end
|
18
18
|
|
@@ -40,7 +40,10 @@ module GraphQL
|
|
40
40
|
visitor.visit
|
41
41
|
|
42
42
|
fields
|
43
|
-
rescue StandardError
|
43
|
+
rescue StandardError => err
|
44
|
+
if err.is_a?(TypeError)
|
45
|
+
raise
|
46
|
+
end
|
44
47
|
# FIXME: TypeStack my crash on invalid documents
|
45
48
|
fields
|
46
49
|
end
|
@@ -28,8 +28,8 @@ module GraphQL
|
|
28
28
|
type = @types[node]
|
29
29
|
type = type && type.unwrap
|
30
30
|
|
31
|
-
if (node.selections.any? && (type.nil? || type.
|
32
|
-
(node.selections.none? && type.
|
31
|
+
if (node.selections.any? && (type.nil? || type.kind.interface? || type.kind.union?)) ||
|
32
|
+
(node.selections.none? && (type && type.kind.object?))
|
33
33
|
names = QueryTypename.node_flatten_selections(node.selections).map { |s| s.respond_to?(:name) ? s.name : nil }
|
34
34
|
names = Set.new(names.compact)
|
35
35
|
|
@@ -16,13 +16,13 @@ module GraphQL
|
|
16
16
|
module Schema
|
17
17
|
module ClassMethods
|
18
18
|
def define_class(definition, ast_nodes, type)
|
19
|
-
type_class = case type
|
20
|
-
when
|
19
|
+
type_class = case type.kind.name
|
20
|
+
when "NON_NULL"
|
21
21
|
define_class(definition, ast_nodes, type.of_type).to_non_null_type
|
22
|
-
when
|
22
|
+
when "LIST"
|
23
23
|
define_class(definition, ast_nodes, type.of_type).to_list_type
|
24
24
|
else
|
25
|
-
get_class(type.
|
25
|
+
get_class(type.graphql_name).define_class(definition, ast_nodes)
|
26
26
|
end
|
27
27
|
|
28
28
|
ast_nodes.each do |ast_node|
|
@@ -62,7 +62,7 @@ module GraphQL
|
|
62
62
|
private
|
63
63
|
|
64
64
|
def normalize_type_name(type_name)
|
65
|
-
|
65
|
+
/\A[A-Z]/.match?(type_name) ? type_name : type_name.camelize
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -85,18 +85,18 @@ module GraphQL
|
|
85
85
|
def self.class_for(schema, type, cache)
|
86
86
|
return cache[type] if cache[type]
|
87
87
|
|
88
|
-
case type
|
89
|
-
when
|
88
|
+
case type.kind.name
|
89
|
+
when "INPUT_OBJECT"
|
90
90
|
nil
|
91
|
-
when
|
91
|
+
when "SCALAR"
|
92
92
|
cache[type] = ScalarType.new(type)
|
93
|
-
when
|
93
|
+
when "ENUM"
|
94
94
|
cache[type] = EnumType.new(type)
|
95
|
-
when
|
95
|
+
when "LIST"
|
96
96
|
cache[type] = class_for(schema, type.of_type, cache).to_list_type
|
97
|
-
when
|
97
|
+
when "NON_NULL"
|
98
98
|
cache[type] = class_for(schema, type.of_type, cache).to_non_null_type
|
99
|
-
when
|
99
|
+
when "UNION"
|
100
100
|
klass = cache[type] = UnionType.new(type)
|
101
101
|
|
102
102
|
type.possible_types.each do |possible_type|
|
@@ -105,22 +105,23 @@ module GraphQL
|
|
105
105
|
end
|
106
106
|
|
107
107
|
klass
|
108
|
-
when
|
108
|
+
when "INTERFACE"
|
109
109
|
cache[type] = InterfaceType.new(type)
|
110
|
-
when
|
110
|
+
when "OBJECT"
|
111
111
|
klass = cache[type] = ObjectType.new(type)
|
112
112
|
|
113
113
|
type.interfaces.each do |interface|
|
114
114
|
klass.send :include, class_for(schema, interface, cache)
|
115
115
|
end
|
116
|
-
|
117
|
-
type.all_fields.
|
116
|
+
# Legacy objects have `.all_fields`
|
117
|
+
all_fields = type.respond_to?(:all_fields) ? type.all_fields : type.fields.values
|
118
|
+
all_fields.each do |field|
|
118
119
|
klass.fields[field.name.to_sym] = class_for(schema, field.type, cache)
|
119
120
|
end
|
120
121
|
|
121
122
|
klass
|
122
123
|
else
|
123
|
-
raise TypeError, "unexpected #{type.class}"
|
124
|
+
raise TypeError, "unexpected #{type.class} (#{type.inspect})"
|
124
125
|
end
|
125
126
|
end
|
126
127
|
end
|
@@ -41,8 +41,8 @@ module GraphQL
|
|
41
41
|
#
|
42
42
|
# type - GraphQL::EnumType instance
|
43
43
|
def initialize(type)
|
44
|
-
unless type.
|
45
|
-
raise "expected type to be
|
44
|
+
unless type.kind.enum?
|
45
|
+
raise "expected type to be an Enum, but was #{type.class}"
|
46
46
|
end
|
47
47
|
|
48
48
|
@type = type
|
@@ -9,8 +9,8 @@ module GraphQL
|
|
9
9
|
include BaseType
|
10
10
|
|
11
11
|
def initialize(type)
|
12
|
-
unless type.
|
13
|
-
raise "expected type to be
|
12
|
+
unless type.kind.interface?
|
13
|
+
raise "expected type to be an Interface, but was #{type.class}"
|
14
14
|
end
|
15
15
|
|
16
16
|
@type = type
|
@@ -41,7 +41,7 @@ module GraphQL
|
|
41
41
|
field_nodes.each do |result_name, field_ast_nodes|
|
42
42
|
# `result_name` might be an alias, so make sure to get the proper name
|
43
43
|
field_name = field_ast_nodes.first.name
|
44
|
-
field_definition = definition.client.schema.get_field(type.
|
44
|
+
field_definition = definition.client.schema.get_field(type.graphql_name, field_name)
|
45
45
|
field_return_type = field_definition.type
|
46
46
|
field_classes[result_name.to_sym] = schema_module.define_class(definition, field_ast_nodes, field_return_type)
|
47
47
|
end
|
@@ -135,7 +135,7 @@ module GraphQL
|
|
135
135
|
true
|
136
136
|
else
|
137
137
|
schema = definition.client.schema
|
138
|
-
type_condition =
|
138
|
+
type_condition = definition.client.get_type(selected_ast_node.type.name)
|
139
139
|
applicable_types = schema.possible_types(type_condition)
|
140
140
|
# continue if this object type is one of the types matching the fragment condition
|
141
141
|
applicable_types.include?(type)
|
@@ -152,7 +152,7 @@ module GraphQL
|
|
152
152
|
end
|
153
153
|
|
154
154
|
schema = definition.client.schema
|
155
|
-
type_condition =
|
155
|
+
type_condition = definition.client.get_type(fragment_definition.type.name)
|
156
156
|
applicable_types = schema.possible_types(type_condition)
|
157
157
|
# continue if this object type is one of the types matching the fragment condition
|
158
158
|
continue_selection = applicable_types.include?(type)
|
@@ -211,12 +211,13 @@ module GraphQL
|
|
211
211
|
raise e
|
212
212
|
end
|
213
213
|
|
214
|
-
|
214
|
+
all_fields = type.respond_to?(:all_fields) ? type.all_fields : type.fields.values
|
215
|
+
field = all_fields.find do |f|
|
215
216
|
f.name == e.name.to_s || ActiveSupport::Inflector.underscore(f.name) == e.name.to_s
|
216
217
|
end
|
217
218
|
|
218
219
|
unless field
|
219
|
-
raise UnimplementedFieldError, "undefined field `#{e.name}' on #{type} type. https://git.io/v1y3m"
|
220
|
+
raise UnimplementedFieldError, "undefined field `#{e.name}' on #{type.graphql_name} type. https://git.io/v1y3m"
|
220
221
|
end
|
221
222
|
|
222
223
|
if @data.key?(field.name)
|
@@ -12,8 +12,8 @@ module GraphQL
|
|
12
12
|
#
|
13
13
|
# type - GraphQL::BaseType instance
|
14
14
|
def initialize(type)
|
15
|
-
unless type.
|
16
|
-
raise "expected type to be a
|
15
|
+
unless type.kind.scalar?
|
16
|
+
raise "expected type to be a Scalar, but was #{type.class}"
|
17
17
|
end
|
18
18
|
|
19
19
|
@type = type
|
@@ -9,8 +9,8 @@ module GraphQL
|
|
9
9
|
include BaseType
|
10
10
|
|
11
11
|
def initialize(type)
|
12
|
-
unless type.
|
13
|
-
raise "expected type to be a
|
12
|
+
unless type.kind.union?
|
13
|
+
raise "expected type to be a Union, but was #{type.class}"
|
14
14
|
end
|
15
15
|
|
16
16
|
@type = type
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-10-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|