graphql 0.13.0 → 0.14.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/define/assign_argument.rb +3 -5
- data/lib/graphql/field.rb +1 -3
- data/lib/graphql/input_object_type.rb +4 -1
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/language/generation.rb +94 -0
- data/lib/graphql/language/lexer.rb +229 -201
- data/lib/graphql/language/lexer.rl +24 -7
- data/lib/graphql/language/nodes.rb +4 -0
- data/lib/graphql/language/parser.rb +195 -187
- data/lib/graphql/language/parser.y +11 -4
- data/lib/graphql/object_type.rb +21 -0
- data/lib/graphql/query.rb +8 -3
- data/lib/graphql/query/serial_execution/operation_resolution.rb +2 -2
- data/lib/graphql/query/serial_execution/value_resolution.rb +5 -0
- data/lib/graphql/schema.rb +11 -19
- data/lib/graphql/schema/invalid_type_error.rb +6 -0
- data/lib/graphql/schema/reduce_types.rb +68 -0
- data/lib/graphql/schema/type_expression.rb +6 -16
- data/lib/graphql/schema/type_map.rb +1 -5
- data/lib/graphql/schema/validation.rb +164 -0
- data/lib/graphql/version.rb +1 -1
- data/readme.md +3 -4
- data/spec/graphql/argument_spec.rb +20 -0
- data/spec/graphql/field_spec.rb +16 -0
- data/spec/graphql/introspection/schema_type_spec.rb +1 -0
- data/spec/graphql/language/generation_spec.rb +42 -0
- data/spec/graphql/language/parser_spec.rb +136 -26
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +23 -0
- data/spec/graphql/query_spec.rb +51 -0
- data/spec/graphql/schema/{type_reducer_spec.rb → reduce_types_spec.rb} +16 -14
- data/spec/graphql/schema/type_expression_spec.rb +4 -4
- data/spec/graphql/schema/validation_spec.rb +219 -0
- data/spec/support/dairy_app.rb +3 -0
- metadata +14 -13
- data/lib/graphql/schema/each_item_validator.rb +0 -21
- data/lib/graphql/schema/field_validator.rb +0 -17
- data/lib/graphql/schema/implementation_validator.rb +0 -31
- data/lib/graphql/schema/type_reducer.rb +0 -79
- data/lib/graphql/schema/type_validator.rb +0 -58
- data/spec/graphql/schema/field_validator_spec.rb +0 -21
- data/spec/graphql/schema/type_validator_spec.rb +0 -81
@@ -6,20 +6,20 @@ describe GraphQL::Schema::TypeExpression do
|
|
6
6
|
document = GraphQL.parse("query dostuff($var: #{type_name}) { id } ")
|
7
7
|
document.definitions.first.variables.first.type
|
8
8
|
}
|
9
|
-
let(:
|
9
|
+
let(:type_expression_result) { GraphQL::Schema::TypeExpression.build_type(schema, ast_node) }
|
10
10
|
|
11
11
|
describe "#type" do
|
12
12
|
describe "simple types" do
|
13
13
|
let(:type_name) { "DairyProductInput" }
|
14
14
|
it "it gets types from the schema" do
|
15
|
-
assert_equal(DairyProductInputType,
|
15
|
+
assert_equal(DairyProductInputType, type_expression_result)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
describe "non-null types" do
|
20
20
|
let(:type_name) { "String!"}
|
21
21
|
it "makes non-null types" do
|
22
|
-
assert_equal(GraphQL::STRING_TYPE.to_non_null_type,
|
22
|
+
assert_equal(GraphQL::STRING_TYPE.to_non_null_type,type_expression_result)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -31,7 +31,7 @@ describe GraphQL::Schema::TypeExpression do
|
|
31
31
|
.to_non_null_type
|
32
32
|
.to_list_type
|
33
33
|
.to_non_null_type
|
34
|
-
assert_equal(expected,
|
34
|
+
assert_equal(expected, type_expression_result)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -0,0 +1,219 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe GraphQL::Schema::Validation do
|
4
|
+
def assert_error_includes(object, error_substring)
|
5
|
+
validation_error = GraphQL::Schema::Validation.validate(object)
|
6
|
+
assert_includes validation_error, error_substring
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "validating Fields" do
|
10
|
+
let(:unnamed_field) {
|
11
|
+
GraphQL::Field.define do
|
12
|
+
type GraphQL::STRING_TYPE
|
13
|
+
end
|
14
|
+
}
|
15
|
+
|
16
|
+
let(:untyped_field) {
|
17
|
+
GraphQL::Field.define do
|
18
|
+
name "Untyped"
|
19
|
+
type :something_invalid
|
20
|
+
end
|
21
|
+
}
|
22
|
+
|
23
|
+
let(:bad_arguments_field) {
|
24
|
+
field = GraphQL::Field.define do
|
25
|
+
name "BadArgs"
|
26
|
+
type !GraphQL::BOOLEAN_TYPE
|
27
|
+
end
|
28
|
+
field.arguments[:bad_key] = :bad_value
|
29
|
+
field
|
30
|
+
}
|
31
|
+
|
32
|
+
let(:invalid_argument_member_field) {
|
33
|
+
GraphQL::Field.define do
|
34
|
+
name "InvalidArgument"
|
35
|
+
type !types[!GraphQL::INT_TYPE]
|
36
|
+
argument :invalid do
|
37
|
+
type GraphQL::STRING_TYPE
|
38
|
+
default_value [1,2,3]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
}
|
42
|
+
|
43
|
+
it "requires a String for name" do
|
44
|
+
assert_error_includes unnamed_field, "must return String, not NilClass"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "requires a BaseType for type" do
|
48
|
+
assert_error_includes untyped_field, "must return GraphQL::BaseType, not Symbol"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "requires String => Argument arguments" do
|
52
|
+
assert_error_includes bad_arguments_field, "must map String => GraphQL::Argument, not Symbol => Symbol"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "applies validation to its member Arguments" do
|
56
|
+
assert_error_includes invalid_argument_member_field, "default value [1, 2, 3] is not valid for type String"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "validating BaseType" do
|
61
|
+
let(:unnamed_type) {
|
62
|
+
GraphQL::BaseType.define do
|
63
|
+
name :invalid_name
|
64
|
+
end
|
65
|
+
}
|
66
|
+
|
67
|
+
let(:wrongly_described_type) {
|
68
|
+
GraphQL::BaseType.define do
|
69
|
+
name "WronglyDescribed"
|
70
|
+
description 12345
|
71
|
+
end
|
72
|
+
}
|
73
|
+
it "requires a String name" do
|
74
|
+
assert_error_includes unnamed_type, "must return String, not Symbol"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "requires String-or-nil description" do
|
78
|
+
assert_error_includes wrongly_described_type, "must return String or NilClass, not Fixnum"
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "validating ObjectTypes" do
|
83
|
+
let(:invalid_interfaces_object) {
|
84
|
+
GraphQL::ObjectType.define do
|
85
|
+
name "InvalidInterfaces"
|
86
|
+
interfaces({a: 1})
|
87
|
+
end
|
88
|
+
}
|
89
|
+
let(:invalid_interface_member_object) {
|
90
|
+
GraphQL::ObjectType.define do
|
91
|
+
name "InvalidInterfaceMember"
|
92
|
+
interfaces [:not_an_interface]
|
93
|
+
end
|
94
|
+
}
|
95
|
+
|
96
|
+
let(:invalid_field_object) {
|
97
|
+
GraphQL::ObjectType.define do
|
98
|
+
name "InvalidField"
|
99
|
+
field :invalid, :nonsense
|
100
|
+
end
|
101
|
+
}
|
102
|
+
|
103
|
+
it "requires an Array for interfaces" do
|
104
|
+
assert_error_includes invalid_interfaces_object, "must be an Array of GraphQL::InterfaceType, not a Hash"
|
105
|
+
assert_error_includes invalid_interface_member_object, "must contain GraphQL::InterfaceType, not Symbol"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "validates the fields" do
|
109
|
+
assert_error_includes invalid_field_object, "must return GraphQL::BaseType, not Symbol"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "validating UnionTypes" do
|
114
|
+
let(:non_array_union) {
|
115
|
+
GraphQL::UnionType.define do
|
116
|
+
name "NonArray"
|
117
|
+
possible_types 55
|
118
|
+
end
|
119
|
+
}
|
120
|
+
|
121
|
+
let(:non_object_type_union) {
|
122
|
+
GraphQL::UnionType.define do
|
123
|
+
name "NonObjectTypes"
|
124
|
+
possible_types [
|
125
|
+
GraphQL::InterfaceType.new
|
126
|
+
]
|
127
|
+
end
|
128
|
+
}
|
129
|
+
|
130
|
+
let(:no_possible_types_union) {
|
131
|
+
GraphQL::UnionType.define do
|
132
|
+
name "NoPossibleTypes"
|
133
|
+
possible_types []
|
134
|
+
end
|
135
|
+
}
|
136
|
+
|
137
|
+
it "requires an array of ObjectTypes for possible_types" do
|
138
|
+
assert_error_includes non_array_union, "must be an Array of GraphQL::ObjectType, not a Fixnum"
|
139
|
+
|
140
|
+
assert_error_includes non_object_type_union, "must contain GraphQL::ObjectType, not GraphQL::InterfaceType"
|
141
|
+
end
|
142
|
+
|
143
|
+
it "requires at least one possible_types" do
|
144
|
+
assert_error_includes no_possible_types_union, "must have at least one possible type"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "validating InputObjectTypes" do
|
149
|
+
let(:invalid_arguments_input) {
|
150
|
+
input = GraphQL::InputObjectType.define do
|
151
|
+
name "InvalidArgumentsHash"
|
152
|
+
end
|
153
|
+
input.arguments[123] = :nonsense
|
154
|
+
input
|
155
|
+
}
|
156
|
+
|
157
|
+
let(:invalid_argument_member_input) {
|
158
|
+
GraphQL::InputObjectType.define do
|
159
|
+
name "InvalidArgumentMember"
|
160
|
+
argument :nonsense do
|
161
|
+
type GraphQL::FLOAT_TYPE
|
162
|
+
default_value "xyz"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
}
|
166
|
+
|
167
|
+
it "requires {String => Argument} arguments" do
|
168
|
+
assert_error_includes invalid_arguments_input, "map String => GraphQL::Argument, not Fixnum => Symbol"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "applies validation to its member Arguments" do
|
172
|
+
assert_error_includes invalid_argument_member_input, "default value \"xyz\" is not valid for type Float"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "validating InterfaceTypes" do
|
177
|
+
let(:invalid_field_interface) {
|
178
|
+
GraphQL::InterfaceType.define do
|
179
|
+
name "InvalidField"
|
180
|
+
field :invalid do
|
181
|
+
type GraphQL::BOOLEAN_TYPE
|
182
|
+
argument :invalid do
|
183
|
+
type GraphQL::STRING_TYPE
|
184
|
+
default_value 4.56
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
188
|
+
}
|
189
|
+
|
190
|
+
it "validates fields" do
|
191
|
+
assert_error_includes invalid_field_interface, "default value 4.56 is not valid for type String"
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "validating Arguments" do
|
196
|
+
let(:untyped_argument) {
|
197
|
+
GraphQL::Argument.define do
|
198
|
+
name "Untyped"
|
199
|
+
type :Bogus
|
200
|
+
end
|
201
|
+
}
|
202
|
+
|
203
|
+
let(:invalid_default_argument) {
|
204
|
+
GraphQL::Argument.define do
|
205
|
+
name "InvalidDefault"
|
206
|
+
type GraphQL::INT_TYPE
|
207
|
+
default_value "abc"
|
208
|
+
end
|
209
|
+
}
|
210
|
+
|
211
|
+
it "requires the type is a Base type" do
|
212
|
+
assert_error_includes untyped_argument, "must be a valid input type (Scalar or InputObject), not Symbol"
|
213
|
+
end
|
214
|
+
|
215
|
+
it "requires the default value is compatible" do
|
216
|
+
assert_error_includes invalid_default_argument, 'default value "abc" is not valid for type Int'
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
data/spec/support/dairy_app.rb
CHANGED
@@ -200,6 +200,9 @@ FavoriteFieldDefn = Proc.new {
|
|
200
200
|
QueryType = GraphQL::ObjectType.define do
|
201
201
|
name "Query"
|
202
202
|
description "Query root of the system"
|
203
|
+
field :root, types.String do
|
204
|
+
resolve ->(root_value, args, c) { root_value }
|
205
|
+
end
|
203
206
|
field :cheese, field: FetchField.create(type: CheeseType, data: CHEESES)
|
204
207
|
field :milk, field: FetchField.create(type: MilkType, data: MILKS, id_type: !types.ID)
|
205
208
|
field :dairy, field: SingletonField.create(type: DairyType, data: DAIRY)
|
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: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: codeclimate-test-reporter
|
@@ -233,6 +233,7 @@ files:
|
|
233
233
|
- lib/graphql/introspection/typename_field.rb
|
234
234
|
- lib/graphql/invalid_null_error.rb
|
235
235
|
- lib/graphql/language.rb
|
236
|
+
- lib/graphql/language/generation.rb
|
236
237
|
- lib/graphql/language/lexer.rb
|
237
238
|
- lib/graphql/language/lexer.rl
|
238
239
|
- lib/graphql/language/nodes.rb
|
@@ -261,17 +262,15 @@ files:
|
|
261
262
|
- lib/graphql/query/variables.rb
|
262
263
|
- lib/graphql/scalar_type.rb
|
263
264
|
- lib/graphql/schema.rb
|
264
|
-
- lib/graphql/schema/
|
265
|
-
- lib/graphql/schema/field_validator.rb
|
266
|
-
- lib/graphql/schema/implementation_validator.rb
|
265
|
+
- lib/graphql/schema/invalid_type_error.rb
|
267
266
|
- lib/graphql/schema/middleware_chain.rb
|
268
267
|
- lib/graphql/schema/possible_types.rb
|
269
268
|
- lib/graphql/schema/printer.rb
|
269
|
+
- lib/graphql/schema/reduce_types.rb
|
270
270
|
- lib/graphql/schema/rescue_middleware.rb
|
271
271
|
- lib/graphql/schema/type_expression.rb
|
272
272
|
- lib/graphql/schema/type_map.rb
|
273
|
-
- lib/graphql/schema/
|
274
|
-
- lib/graphql/schema/type_validator.rb
|
273
|
+
- lib/graphql/schema/validation.rb
|
275
274
|
- lib/graphql/static_validation.rb
|
276
275
|
- lib/graphql/static_validation/all_rules.rb
|
277
276
|
- lib/graphql/static_validation/arguments_validator.rb
|
@@ -303,6 +302,7 @@ files:
|
|
303
302
|
- lib/graphql/union_type.rb
|
304
303
|
- lib/graphql/version.rb
|
305
304
|
- readme.md
|
305
|
+
- spec/graphql/argument_spec.rb
|
306
306
|
- spec/graphql/base_type_spec.rb
|
307
307
|
- spec/graphql/boolean_type_spec.rb
|
308
308
|
- spec/graphql/define/instance_definable_spec.rb
|
@@ -320,6 +320,7 @@ files:
|
|
320
320
|
- spec/graphql/introspection/introspection_query_spec.rb
|
321
321
|
- spec/graphql/introspection/schema_type_spec.rb
|
322
322
|
- spec/graphql/introspection/type_type_spec.rb
|
323
|
+
- spec/graphql/language/generation_spec.rb
|
323
324
|
- spec/graphql/language/parser_spec.rb
|
324
325
|
- spec/graphql/language/visitor_spec.rb
|
325
326
|
- spec/graphql/list_type_spec.rb
|
@@ -333,13 +334,12 @@ files:
|
|
333
334
|
- spec/graphql/query/variables_spec.rb
|
334
335
|
- spec/graphql/query_spec.rb
|
335
336
|
- spec/graphql/scalar_type_spec.rb
|
336
|
-
- spec/graphql/schema/field_validator_spec.rb
|
337
337
|
- spec/graphql/schema/middleware_chain_spec.rb
|
338
338
|
- spec/graphql/schema/printer_spec.rb
|
339
|
+
- spec/graphql/schema/reduce_types_spec.rb
|
339
340
|
- spec/graphql/schema/rescue_middleware_spec.rb
|
340
341
|
- spec/graphql/schema/type_expression_spec.rb
|
341
|
-
- spec/graphql/schema/
|
342
|
-
- spec/graphql/schema/type_validator_spec.rb
|
342
|
+
- spec/graphql/schema/validation_spec.rb
|
343
343
|
- spec/graphql/schema_spec.rb
|
344
344
|
- spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb
|
345
345
|
- spec/graphql/static_validation/rules/arguments_are_defined_spec.rb
|
@@ -394,6 +394,7 @@ signing_key:
|
|
394
394
|
specification_version: 4
|
395
395
|
summary: A GraphQL server implementation for Ruby
|
396
396
|
test_files:
|
397
|
+
- spec/graphql/argument_spec.rb
|
397
398
|
- spec/graphql/base_type_spec.rb
|
398
399
|
- spec/graphql/boolean_type_spec.rb
|
399
400
|
- spec/graphql/define/instance_definable_spec.rb
|
@@ -411,6 +412,7 @@ test_files:
|
|
411
412
|
- spec/graphql/introspection/introspection_query_spec.rb
|
412
413
|
- spec/graphql/introspection/schema_type_spec.rb
|
413
414
|
- spec/graphql/introspection/type_type_spec.rb
|
415
|
+
- spec/graphql/language/generation_spec.rb
|
414
416
|
- spec/graphql/language/parser_spec.rb
|
415
417
|
- spec/graphql/language/visitor_spec.rb
|
416
418
|
- spec/graphql/list_type_spec.rb
|
@@ -424,13 +426,12 @@ test_files:
|
|
424
426
|
- spec/graphql/query/variables_spec.rb
|
425
427
|
- spec/graphql/query_spec.rb
|
426
428
|
- spec/graphql/scalar_type_spec.rb
|
427
|
-
- spec/graphql/schema/field_validator_spec.rb
|
428
429
|
- spec/graphql/schema/middleware_chain_spec.rb
|
429
430
|
- spec/graphql/schema/printer_spec.rb
|
431
|
+
- spec/graphql/schema/reduce_types_spec.rb
|
430
432
|
- spec/graphql/schema/rescue_middleware_spec.rb
|
431
433
|
- spec/graphql/schema/type_expression_spec.rb
|
432
|
-
- spec/graphql/schema/
|
433
|
-
- spec/graphql/schema/type_validator_spec.rb
|
434
|
+
- spec/graphql/schema/validation_spec.rb
|
434
435
|
- spec/graphql/schema_spec.rb
|
435
436
|
- spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb
|
436
437
|
- spec/graphql/static_validation/rules/arguments_are_defined_spec.rb
|
@@ -1,21 +0,0 @@
|
|
1
|
-
module GraphQL
|
2
|
-
class Schema
|
3
|
-
class EachItemValidator
|
4
|
-
def initialize(errors)
|
5
|
-
@errors = errors
|
6
|
-
end
|
7
|
-
|
8
|
-
def validate(items, as:, must_be:)
|
9
|
-
if !items.is_a?(Array)
|
10
|
-
@errors << "#{as} must be an Array, not #{items.inspect}"
|
11
|
-
return
|
12
|
-
else
|
13
|
-
invalid_items = items.select {|k| !yield(k) }
|
14
|
-
if invalid_items.any?
|
15
|
-
@errors << "#{as} must be #{must_be}, but some aren't: #{invalid_items.map(&:to_s).join(", ")}"
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module GraphQL
|
2
|
-
class Schema
|
3
|
-
class FieldValidator
|
4
|
-
def validate(field, errors)
|
5
|
-
implementation = GraphQL::Schema::ImplementationValidator.new(field, as: "Field", errors: errors)
|
6
|
-
implementation.must_respond_to(:name)
|
7
|
-
implementation.must_respond_to(:type)
|
8
|
-
implementation.must_respond_to(:description)
|
9
|
-
implementation.must_respond_to(:arguments) do |arguments|
|
10
|
-
validator = GraphQL::Schema::EachItemValidator.new(errors)
|
11
|
-
validator.validate(arguments.keys, as: "#{field.name}.arguments keys", must_be: "Strings") { |k| k.is_a?(String) }
|
12
|
-
end
|
13
|
-
implementation.must_respond_to(:deprecation_reason)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module GraphQL
|
2
|
-
class Schema
|
3
|
-
# A helper to ensure `object` implements the concept `as`
|
4
|
-
class ImplementationValidator
|
5
|
-
attr_reader :object, :errors, :implementation_as
|
6
|
-
def initialize(object, as:, errors:)
|
7
|
-
@object = object
|
8
|
-
@implementation_as = as
|
9
|
-
@errors = errors
|
10
|
-
end
|
11
|
-
|
12
|
-
# Ensure the object responds to `method_name`.
|
13
|
-
# If `block_given?`, yield the return value of that method
|
14
|
-
# If provided, use `as` in the error message, overriding class-level `as`.
|
15
|
-
def must_respond_to(method_name, args: [], as: nil)
|
16
|
-
local_as = as || implementation_as
|
17
|
-
method_signature = "##{method_name}(#{args.join(", ")})"
|
18
|
-
if !object.respond_to?(method_name)
|
19
|
-
errors << "#{object.to_s} must respond to #{method_signature} to be a #{local_as}"
|
20
|
-
elsif block_given?
|
21
|
-
return_value = object.public_send(method_name)
|
22
|
-
if return_value.nil?
|
23
|
-
errors << "#{object.to_s} must return a value for #{method_signature} to be a #{local_as}"
|
24
|
-
else
|
25
|
-
yield(return_value)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
module GraphQL
|
2
|
-
class Schema
|
3
|
-
# Starting from a given type, discover other types in the system by
|
4
|
-
# traversing that type's fields, possible_types, etc
|
5
|
-
class TypeReducer
|
6
|
-
attr_reader :type, :existing_type_hash
|
7
|
-
|
8
|
-
def initialize(type, existing_type_hash)
|
9
|
-
validate_type(type)
|
10
|
-
if type.respond_to?(:name) && existing_type_hash.fetch(type.name, nil).equal?(type)
|
11
|
-
@result = existing_type_hash
|
12
|
-
else
|
13
|
-
@type = type
|
14
|
-
end
|
15
|
-
@existing_type_hash = existing_type_hash
|
16
|
-
end
|
17
|
-
|
18
|
-
def result
|
19
|
-
@result ||= find_types(type, existing_type_hash)
|
20
|
-
end
|
21
|
-
|
22
|
-
# Reduce all of `types` and return the combined result
|
23
|
-
def self.find_all(types)
|
24
|
-
type_map = GraphQL::Schema::TypeMap.new
|
25
|
-
types.reduce(type_map) do |memo, type|
|
26
|
-
self.new(type, memo).result
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def find_types(type, type_hash)
|
33
|
-
type_hash[type.name] = type
|
34
|
-
if type.kind.fields?
|
35
|
-
type.all_fields.each do |field|
|
36
|
-
reduce_type(field.type, type_hash, "Field #{type.name}.#{field.name}")
|
37
|
-
field.arguments.each do |name, argument|
|
38
|
-
reduce_type(argument.type, type_hash, "Argument #{name} on #{type.name}.#{field.name}")
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
if type.kind.object?
|
43
|
-
type.interfaces.each do |interface|
|
44
|
-
reduce_type(interface, type_hash, "Interface on #{type.name}")
|
45
|
-
end
|
46
|
-
end
|
47
|
-
if type.kind.union?
|
48
|
-
type.possible_types.each do |possible_type|
|
49
|
-
reduce_type(possible_type, type_hash, "Possible type for #{type.name}")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
if type.kind.input_object?
|
53
|
-
type.input_fields.each do |name, input_field|
|
54
|
-
reduce_type(input_field.type, type_hash, "Input field #{type.name}.#{name}")
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
type_hash
|
59
|
-
end
|
60
|
-
|
61
|
-
def reduce_type(type, type_hash, name = nil)
|
62
|
-
if type.is_a?(GraphQL::BaseType)
|
63
|
-
self.class.new(type.unwrap, type_hash).result
|
64
|
-
else
|
65
|
-
raise GraphQL::Schema::InvalidTypeError.new(type, name)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def validate_type(type)
|
70
|
-
errors = []
|
71
|
-
type_validator = GraphQL::Schema::TypeValidator.new
|
72
|
-
type_validator.validate(type, errors)
|
73
|
-
if errors.any?
|
74
|
-
raise GraphQL::Schema::InvalidTypeError.new(type, errors)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|