graphql 1.6.4 → 1.6.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +47 -0
- data/lib/generators/graphql/install_generator.rb +15 -20
- data/lib/generators/graphql/mutation_generator.rb +31 -1
- data/lib/generators/graphql/templates/mutation.erb +2 -2
- data/lib/generators/graphql/templates/mutation_type.erb +5 -0
- data/lib/generators/graphql/templates/schema.erb +0 -1
- data/lib/graphql/argument.rb +6 -5
- data/lib/graphql/backwards_compatibility.rb +18 -4
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -1
- data/lib/graphql/compatibility/lazy_execution_specification.rb +9 -2
- data/lib/graphql/define.rb +1 -0
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/no_definition_error.rb +7 -0
- data/lib/graphql/enum_type.rb +4 -0
- data/lib/graphql/execution/execute.rb +3 -3
- data/lib/graphql/execution/field_result.rb +1 -1
- data/lib/graphql/execution/lazy/resolve.rb +10 -9
- data/lib/graphql/execution/multiplex.rb +6 -5
- data/lib/graphql/input_object_type.rb +5 -1
- data/lib/graphql/interface_type.rb +12 -3
- data/lib/graphql/query.rb +21 -5
- data/lib/graphql/query/context.rb +11 -0
- data/lib/graphql/schema.rb +48 -27
- data/lib/graphql/schema/build_from_definition.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +2 -2
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/traversal.rb +91 -0
- data/lib/graphql/schema/validation.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +41 -7
- data/lib/graphql/union_type.rb +13 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -3
- data/spec/generators/graphql/install_generator_spec.rb +3 -1
- data/spec/generators/graphql/mutation_generator_spec.rb +14 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +12 -1
- data/spec/graphql/analysis/query_complexity_spec.rb +1 -1
- data/spec/graphql/argument_spec.rb +29 -0
- data/spec/graphql/define/assign_argument_spec.rb +4 -4
- data/spec/graphql/define/instance_definable_spec.rb +1 -1
- data/spec/graphql/enum_type_spec.rb +8 -0
- data/spec/graphql/execution/lazy_spec.rb +30 -3
- data/spec/graphql/interface_type_spec.rb +44 -0
- data/spec/graphql/introspection/schema_type_spec.rb +3 -0
- data/spec/graphql/introspection/type_type_spec.rb +1 -0
- data/spec/graphql/object_type_spec.rb +8 -3
- data/spec/graphql/query/context_spec.rb +18 -0
- data/spec/graphql/query/executor_spec.rb +1 -1
- data/spec/graphql/query/literal_input_spec.rb +31 -15
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -1
- data/spec/graphql/query/variables_spec.rb +25 -1
- data/spec/graphql/query_spec.rb +24 -9
- data/spec/graphql/relay/mutation_spec.rb +1 -1
- data/spec/graphql/schema/build_from_definition_spec.rb +1 -1
- data/spec/graphql/schema/loader_spec.rb +1 -1
- data/spec/graphql/schema/printer_spec.rb +1 -1
- data/spec/graphql/schema/{reduce_types_spec.rb → traversal_spec.rb} +21 -4
- data/spec/graphql/schema/warden_spec.rb +1 -1
- data/spec/graphql/schema_spec.rb +23 -2
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +133 -0
- data/spec/graphql/union_type_spec.rb +53 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/dummy/data.rb +14 -5
- data/spec/support/dummy/schema.rb +46 -5
- data/spec/support/star_wars/data.rb +10 -6
- data/spec/support/star_wars/schema.rb +5 -2
- metadata +8 -7
- data/lib/graphql/schema/instrumented_field_map.rb +0 -40
- data/lib/graphql/schema/reduce_types.rb +0 -69
- data/lib/graphql/schema/type_map.rb +0 -31
@@ -26,6 +26,59 @@ describe GraphQL::UnionType do
|
|
26
26
|
assert_equal(false, union.include?(type_3))
|
27
27
|
end
|
28
28
|
|
29
|
+
it '#resolve_type raises error if resolved type is not in possible_types' do
|
30
|
+
test_str = 'Hello world'
|
31
|
+
union.resolve_type = ->(value, ctx) {
|
32
|
+
"This is not the types you are looking for"
|
33
|
+
}
|
34
|
+
fake_ctx = OpenStruct.new(query: GraphQL::Query.new(Dummy::Schema, ""))
|
35
|
+
|
36
|
+
assert_raises(RuntimeError) {
|
37
|
+
union.resolve_type(test_str, fake_ctx)
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#resolve_type" do
|
42
|
+
let(:result) { Dummy::Schema.execute(query_string) }
|
43
|
+
let(:query_string) {%|
|
44
|
+
{
|
45
|
+
allAnimal {
|
46
|
+
type: __typename
|
47
|
+
... on Cow {
|
48
|
+
cowName: name
|
49
|
+
}
|
50
|
+
... on Goat {
|
51
|
+
goatName: name
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
allAnimalAsCow {
|
56
|
+
type: __typename
|
57
|
+
... on Cow {
|
58
|
+
name
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
|}
|
63
|
+
|
64
|
+
it 'returns correct types for general schema and specific union' do
|
65
|
+
expected_result = {
|
66
|
+
# When using Query#resolve_type
|
67
|
+
"allAnimal" => [
|
68
|
+
{ "type" => "Cow", "cowName" => "Billy" },
|
69
|
+
{ "type" => "Goat", "goatName" => "Gilly" }
|
70
|
+
],
|
71
|
+
|
72
|
+
# When using UnionType#resolve_type
|
73
|
+
"allAnimalAsCow" => [
|
74
|
+
{ "type" => "Cow", "name" => "Billy" },
|
75
|
+
{ "type" => "Cow", "name" => "Gilly" }
|
76
|
+
]
|
77
|
+
}
|
78
|
+
assert_equal expected_result, result["data"]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
29
82
|
describe "typecasting from union to union" do
|
30
83
|
let(:result) { Dummy::Schema.execute(query_string) }
|
31
84
|
let(:query_string) {%|
|
data/spec/spec_helper.rb
CHANGED
@@ -6,10 +6,12 @@ require "rails/all"
|
|
6
6
|
require "rails/generators"
|
7
7
|
require "jdbc/sqlite3" if RUBY_ENGINE == 'jruby'
|
8
8
|
require "sqlite3" if RUBY_ENGINE == 'ruby'
|
9
|
+
require "pg" if RUBY_ENGINE == 'ruby'
|
9
10
|
require "sequel"
|
10
11
|
require "graphql"
|
11
12
|
require "graphql/rake_task"
|
12
13
|
require "benchmark"
|
14
|
+
require "pry"
|
13
15
|
require "minitest/autorun"
|
14
16
|
require "minitest/focus"
|
15
17
|
require "minitest/reporters"
|
@@ -24,9 +26,11 @@ Minitest.backtrace_filter = Minitest::BacktraceFilter.new
|
|
24
26
|
|
25
27
|
# This is for convenient access to metadata in test definitions
|
26
28
|
assign_metadata_key = ->(target, key, value) { target.metadata[key] = value }
|
29
|
+
assign_metadata_flag = ->(target, flag) { target.metadata[flag] = true }
|
27
30
|
GraphQL::BaseType.accepts_definitions(metadata: assign_metadata_key)
|
28
31
|
GraphQL::Field.accepts_definitions(metadata: assign_metadata_key)
|
29
32
|
GraphQL::Argument.accepts_definitions(metadata: assign_metadata_key)
|
33
|
+
GraphQL::Argument.accepts_definitions(metadata_flag: assign_metadata_flag)
|
30
34
|
GraphQL::EnumType::EnumValue.accepts_definitions(metadata: assign_metadata_key)
|
31
35
|
|
32
36
|
# Can be used as a GraphQL::Schema::Warden for some purposes, but allows nothing
|
@@ -36,6 +40,11 @@ module NothingWarden
|
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
43
|
+
# Use this when a schema requires a `resolve_type` hook
|
44
|
+
# but you know it won't be called
|
45
|
+
NO_OP_RESOLVE_TYPE = ->(type, obj, ctx) {
|
46
|
+
raise "this should never be called"
|
47
|
+
}
|
39
48
|
# Load support files
|
40
49
|
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
41
50
|
|
data/spec/support/dummy/data.rb
CHANGED
@@ -6,6 +6,11 @@ module Dummy
|
|
6
6
|
# This is buggy on purpose -- it shouldn't be called during execution.
|
7
7
|
other.id == id
|
8
8
|
end
|
9
|
+
|
10
|
+
# Alias for when this is treated as milk in EdibleAsMilkInterface
|
11
|
+
def fatContent # rubocop:disable Style/MethodName
|
12
|
+
fat_content
|
13
|
+
end
|
9
14
|
end
|
10
15
|
|
11
16
|
CHEESES = {
|
@@ -25,9 +30,13 @@ module Dummy
|
|
25
30
|
milks: [MILKS[1]]
|
26
31
|
)
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
+
Cow = Struct.new(:id, :name, :last_produced_dairy)
|
34
|
+
COWS = {
|
35
|
+
1 => Cow.new(1, "Billy", MILKS[1])
|
36
|
+
}
|
37
|
+
|
38
|
+
Goat = Struct.new(:id, :name, :last_produced_dairy)
|
39
|
+
GOATS = {
|
40
|
+
1 => Goat.new(1, "Gilly", MILKS[1]),
|
41
|
+
}
|
33
42
|
end
|
@@ -21,6 +21,12 @@ module Dummy
|
|
21
21
|
field :selfAsEdible, EdibleInterface, resolve: ->(o, a, c) { o }
|
22
22
|
end
|
23
23
|
|
24
|
+
EdibleAsMilkInterface = EdibleInterface.redefine do
|
25
|
+
name "EdibleAsMilk"
|
26
|
+
description "Milk :+1:"
|
27
|
+
resolve_type ->(obj, ctx) { MilkType }
|
28
|
+
end
|
29
|
+
|
24
30
|
AnimalProductInterface = GraphQL::InterfaceType.define do
|
25
31
|
name "AnimalProduct"
|
26
32
|
description "Comes from an animal, no joke"
|
@@ -48,7 +54,7 @@ module Dummy
|
|
48
54
|
name "Cheese"
|
49
55
|
class_names ["Cheese"]
|
50
56
|
description "Cultured dairy product"
|
51
|
-
interfaces [EdibleInterface, AnimalProductInterface, LocalProductInterface]
|
57
|
+
interfaces [EdibleInterface, EdibleAsMilkInterface, AnimalProductInterface, LocalProductInterface]
|
52
58
|
|
53
59
|
# Can have (name, type, desc)
|
54
60
|
field :id, !types.Int, "Unique identifier"
|
@@ -96,7 +102,7 @@ module Dummy
|
|
96
102
|
MilkType = GraphQL::ObjectType.define do
|
97
103
|
name "Milk"
|
98
104
|
description "Dairy beverage"
|
99
|
-
interfaces [EdibleInterface, AnimalProductInterface, LocalProductInterface]
|
105
|
+
interfaces [EdibleInterface, EdibleAsMilkInterface, AnimalProductInterface, LocalProductInterface]
|
100
106
|
field :id, !types.ID
|
101
107
|
field :source, !DairyAnimalEnum, "Animal which produced this milk", hash_key: :source
|
102
108
|
field :origin, !types.String, "Place the milk comes from"
|
@@ -152,7 +158,7 @@ module Dummy
|
|
152
158
|
|
153
159
|
CowType = GraphQL::ObjectType.define do
|
154
160
|
name "Cow"
|
155
|
-
description "A
|
161
|
+
description "A bovine animal that produces milk"
|
156
162
|
field :id, !types.ID
|
157
163
|
field :name, types.String
|
158
164
|
field :last_produced_dairy, DairyProductUnion
|
@@ -168,6 +174,29 @@ module Dummy
|
|
168
174
|
end
|
169
175
|
end
|
170
176
|
|
177
|
+
GoatType = GraphQL::ObjectType.define do
|
178
|
+
name "Goat"
|
179
|
+
description "An caprinae animal that produces milk"
|
180
|
+
field :id, !types.ID
|
181
|
+
field :name, types.String
|
182
|
+
field :last_produced_dairy, DairyProductUnion
|
183
|
+
end
|
184
|
+
|
185
|
+
AnimalUnion = GraphQL::UnionType.define do
|
186
|
+
name "Animal"
|
187
|
+
description "Species of living things"
|
188
|
+
possible_types [CowType, GoatType]
|
189
|
+
end
|
190
|
+
|
191
|
+
AnimalAsCowUnion = GraphQL::UnionType.define do
|
192
|
+
name "AnimalAsCow"
|
193
|
+
description "All animals go mooooo!"
|
194
|
+
possible_types [CowType]
|
195
|
+
resolve_type ->(obj, ctx) {
|
196
|
+
CowType
|
197
|
+
}
|
198
|
+
end
|
199
|
+
|
171
200
|
ResourceOrderType = GraphQL::InputObjectType.define {
|
172
201
|
name "ResourceOrderType"
|
173
202
|
description "Properties used to determine ordering"
|
@@ -271,7 +300,7 @@ module Dummy
|
|
271
300
|
field :dairy, function: GetSingleton.new(type: DairyType, data: DAIRY)
|
272
301
|
field :fromSource, &SourceFieldDefn
|
273
302
|
field :favoriteEdible, FavoriteFieldDefn
|
274
|
-
field :cow, function: GetSingleton.new(type: CowType, data:
|
303
|
+
field :cow, function: GetSingleton.new(type: CowType, data: COWS[1])
|
275
304
|
field :searchDairy do
|
276
305
|
description "Find dairy products matching a description"
|
277
306
|
type !DairyProductUnion
|
@@ -287,6 +316,14 @@ module Dummy
|
|
287
316
|
}
|
288
317
|
end
|
289
318
|
|
319
|
+
field :allAnimal, !types[AnimalUnion] do
|
320
|
+
resolve ->(obj, args, ctx) { COWS.values + GOATS.values }
|
321
|
+
end
|
322
|
+
|
323
|
+
field :allAnimalAsCow, !types[AnimalAsCowUnion] do
|
324
|
+
resolve ->(obj, args, ctx) { COWS.values + GOATS.values }
|
325
|
+
end
|
326
|
+
|
290
327
|
field :allDairy, types[DairyProductUnion] do
|
291
328
|
argument :executionErrorAtIndex, types.Int
|
292
329
|
resolve ->(obj, args, ctx) {
|
@@ -300,6 +337,10 @@ module Dummy
|
|
300
337
|
resolve ->(obj, args, ctx) { CHEESES.values + MILKS.values }
|
301
338
|
end
|
302
339
|
|
340
|
+
field :allEdibleAsMilk, types[EdibleAsMilkInterface] do
|
341
|
+
resolve ->(obj, args, ctx) { CHEESES.values + MILKS.values }
|
342
|
+
end
|
343
|
+
|
303
344
|
field :error do
|
304
345
|
description "Raise an error"
|
305
346
|
type GraphQL::STRING_TYPE
|
@@ -375,7 +416,7 @@ module Dummy
|
|
375
416
|
|
376
417
|
rescue_from(NoSuchDairyError) { |err| err.message }
|
377
418
|
|
378
|
-
resolve_type ->(obj, ctx) {
|
419
|
+
resolve_type ->(type, obj, ctx) {
|
379
420
|
Schema.types[obj.class.name.split("::").last]
|
380
421
|
}
|
381
422
|
end
|
@@ -21,10 +21,20 @@ module StarWars
|
|
21
21
|
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
22
22
|
`rm -f ./_test_.db`
|
23
23
|
# Set up "Bases" in ActiveRecord
|
24
|
+
|
24
25
|
if jruby?
|
25
26
|
ActiveRecord::Base.establish_connection(adapter: "jdbcsqlite3", database: "./_test_.db")
|
27
|
+
Sequel.connect('jdbc:sqlite:./_test_.db')
|
28
|
+
elsif ENV['DATABASE'] == 'POSTGRESQL'
|
29
|
+
ActiveRecord::Base.establish_connection(
|
30
|
+
adapter: "postgresql",
|
31
|
+
username: "postgres",
|
32
|
+
database: "graphql_ruby_test"
|
33
|
+
)
|
34
|
+
DB = Sequel.connect('postgres://postgres:@localhost:5432/graphql_ruby_test')
|
26
35
|
else
|
27
36
|
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: "./_test_.db")
|
37
|
+
DB = Sequel.sqlite("./_test_.db")
|
28
38
|
end
|
29
39
|
|
30
40
|
ActiveRecord::Schema.define do
|
@@ -46,12 +56,6 @@ module StarWars
|
|
46
56
|
Base.create!(name: "Shield Generator", planet: "Endor", faction_id: 2)
|
47
57
|
Base.create!(name: "Headquarters", planet: "Coruscant", faction_id: 2)
|
48
58
|
|
49
|
-
# Also, set up Bases with Sequel
|
50
|
-
DB = if jruby?
|
51
|
-
Sequel.connect('jdbc:sqlite:./_test_.db')
|
52
|
-
else
|
53
|
-
Sequel.sqlite("./_test_.db")
|
54
|
-
end
|
55
59
|
class SequelBase < Sequel::Model(:bases)
|
56
60
|
end
|
57
61
|
|
@@ -304,7 +304,10 @@ module StarWars
|
|
304
304
|
|
305
305
|
connection :newestBasesGroupedByFaction, BaseType.connection_type do
|
306
306
|
resolve ->(obj, args, ctx) {
|
307
|
-
Base
|
307
|
+
Base
|
308
|
+
.having('id in (select max(id) from bases group by faction_id)')
|
309
|
+
.group(:id)
|
310
|
+
.order('faction_id desc')
|
308
311
|
}
|
309
312
|
end
|
310
313
|
|
@@ -359,7 +362,7 @@ module StarWars
|
|
359
362
|
mutation(MutationType)
|
360
363
|
default_max_page_size 3
|
361
364
|
|
362
|
-
resolve_type ->(object, ctx) {
|
365
|
+
resolve_type ->(type, object, ctx) {
|
363
366
|
if object == :test_error
|
364
367
|
:not_a_type
|
365
368
|
elsif object.is_a?(Base)
|
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.6.
|
4
|
+
version: 1.6.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-07-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|
@@ -299,6 +299,7 @@ extra_rdoc_files: []
|
|
299
299
|
files:
|
300
300
|
- ".yardopts"
|
301
301
|
- MIT-LICENSE
|
302
|
+
- lib/generators/graphql/core.rb
|
302
303
|
- lib/generators/graphql/enum_generator.rb
|
303
304
|
- lib/generators/graphql/function_generator.rb
|
304
305
|
- lib/generators/graphql/install_generator.rb
|
@@ -312,6 +313,7 @@ files:
|
|
312
313
|
- lib/generators/graphql/templates/interface.erb
|
313
314
|
- lib/generators/graphql/templates/loader.erb
|
314
315
|
- lib/generators/graphql/templates/mutation.erb
|
316
|
+
- lib/generators/graphql/templates/mutation_type.erb
|
315
317
|
- lib/generators/graphql/templates/object.erb
|
316
318
|
- lib/generators/graphql/templates/query_type.erb
|
317
319
|
- lib/generators/graphql/templates/schema.erb
|
@@ -351,6 +353,7 @@ files:
|
|
351
353
|
- lib/graphql/define/assign_object_field.rb
|
352
354
|
- lib/graphql/define/defined_object_proxy.rb
|
353
355
|
- lib/graphql/define/instance_definable.rb
|
356
|
+
- lib/graphql/define/no_definition_error.rb
|
354
357
|
- lib/graphql/define/non_null_with_bang.rb
|
355
358
|
- lib/graphql/define/type_definer.rb
|
356
359
|
- lib/graphql/directive.rb
|
@@ -465,18 +468,16 @@ files:
|
|
465
468
|
- lib/graphql/schema/catchall_middleware.rb
|
466
469
|
- lib/graphql/schema/default_parse_error.rb
|
467
470
|
- lib/graphql/schema/default_type_error.rb
|
468
|
-
- lib/graphql/schema/instrumented_field_map.rb
|
469
471
|
- lib/graphql/schema/invalid_type_error.rb
|
470
472
|
- lib/graphql/schema/loader.rb
|
471
473
|
- lib/graphql/schema/middleware_chain.rb
|
472
474
|
- lib/graphql/schema/null_mask.rb
|
473
475
|
- lib/graphql/schema/possible_types.rb
|
474
476
|
- lib/graphql/schema/printer.rb
|
475
|
-
- lib/graphql/schema/reduce_types.rb
|
476
477
|
- lib/graphql/schema/rescue_middleware.rb
|
477
478
|
- lib/graphql/schema/timeout_middleware.rb
|
479
|
+
- lib/graphql/schema/traversal.rb
|
478
480
|
- lib/graphql/schema/type_expression.rb
|
479
|
-
- lib/graphql/schema/type_map.rb
|
480
481
|
- lib/graphql/schema/unique_within_type.rb
|
481
482
|
- lib/graphql/schema/validation.rb
|
482
483
|
- lib/graphql/schema/warden.rb
|
@@ -600,9 +601,9 @@ files:
|
|
600
601
|
- spec/graphql/schema/loader_spec.rb
|
601
602
|
- spec/graphql/schema/middleware_chain_spec.rb
|
602
603
|
- spec/graphql/schema/printer_spec.rb
|
603
|
-
- spec/graphql/schema/reduce_types_spec.rb
|
604
604
|
- spec/graphql/schema/rescue_middleware_spec.rb
|
605
605
|
- spec/graphql/schema/timeout_middleware_spec.rb
|
606
|
+
- spec/graphql/schema/traversal_spec.rb
|
606
607
|
- spec/graphql/schema/type_expression_spec.rb
|
607
608
|
- spec/graphql/schema/unique_within_type_spec.rb
|
608
609
|
- spec/graphql/schema/validation_spec.rb
|
@@ -750,9 +751,9 @@ test_files:
|
|
750
751
|
- spec/graphql/schema/loader_spec.rb
|
751
752
|
- spec/graphql/schema/middleware_chain_spec.rb
|
752
753
|
- spec/graphql/schema/printer_spec.rb
|
753
|
-
- spec/graphql/schema/reduce_types_spec.rb
|
754
754
|
- spec/graphql/schema/rescue_middleware_spec.rb
|
755
755
|
- spec/graphql/schema/timeout_middleware_spec.rb
|
756
|
+
- spec/graphql/schema/traversal_spec.rb
|
756
757
|
- spec/graphql/schema/type_expression_spec.rb
|
757
758
|
- spec/graphql/schema/unique_within_type_spec.rb
|
758
759
|
- spec/graphql/schema/validation_spec.rb
|
@@ -1,40 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
# A two-level map with fields as the last values.
|
5
|
-
# The first level is type names, which point to a second map.
|
6
|
-
# The second level is field names, which point to fields.
|
7
|
-
#
|
8
|
-
# The catch is, the fields in this map _may_ have been modified by being instrumented.
|
9
|
-
class InstrumentedFieldMap
|
10
|
-
# Build a map using types from `schema` and instrumenters in `field_instrumenters`
|
11
|
-
# @param schema [GraphQL::Schema]
|
12
|
-
# @param field_instrumenters [Array<#instrument(type, field)>]
|
13
|
-
def initialize(schema, field_instrumenters)
|
14
|
-
@storage = Hash.new { |h, k| h[k] = {} }
|
15
|
-
schema.types.each do |type_name, type|
|
16
|
-
if type.kind.fields?
|
17
|
-
type.all_fields.each do |field_defn|
|
18
|
-
instrumented_field_defn = field_instrumenters.reduce(field_defn) do |defn, inst|
|
19
|
-
inst.instrument(type, defn)
|
20
|
-
end
|
21
|
-
self.set(type.name, field_defn.name, instrumented_field_defn)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def set(type_name, field_name, field)
|
28
|
-
@storage[type_name][field_name] = field
|
29
|
-
end
|
30
|
-
|
31
|
-
def get(type_name, field_name)
|
32
|
-
@storage[type_name][field_name]
|
33
|
-
end
|
34
|
-
|
35
|
-
def get_all(type_name)
|
36
|
-
@storage[type_name]
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
class Schema
|
4
|
-
module ReduceTypes
|
5
|
-
# @param types [Array<GraphQL::BaseType>] members of a schema to crawl for all member types
|
6
|
-
# @return [GraphQL::Schema::TypeMap] `{name => Type}` pairs derived from `types`
|
7
|
-
def self.reduce(types)
|
8
|
-
type_map = GraphQL::Schema::TypeMap.new
|
9
|
-
types.each do |type|
|
10
|
-
reduce_type(type, type_map, type.name)
|
11
|
-
end
|
12
|
-
type_map
|
13
|
-
end
|
14
|
-
|
15
|
-
private
|
16
|
-
|
17
|
-
# Based on `type`, add members to `type_hash`.
|
18
|
-
# If `type` has already been visited, just return the `type_hash` as-is
|
19
|
-
def self.reduce_type(type, type_hash, context_description)
|
20
|
-
if !type.is_a?(GraphQL::BaseType)
|
21
|
-
message = "#{context_description} has an invalid type: must be an instance of GraphQL::BaseType, not #{type.class.inspect} (#{type.inspect})"
|
22
|
-
raise GraphQL::Schema::InvalidTypeError.new(message)
|
23
|
-
end
|
24
|
-
|
25
|
-
type = type.unwrap
|
26
|
-
|
27
|
-
# Don't re-visit a type
|
28
|
-
if !type_hash.fetch(type.name, nil).equal?(type)
|
29
|
-
validate_type(type, context_description)
|
30
|
-
type_hash[type.name] = type
|
31
|
-
crawl_type(type, type_hash, context_description)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.crawl_type(type, type_hash, context_description)
|
36
|
-
if type.kind.fields?
|
37
|
-
type.all_fields.each do |field|
|
38
|
-
reduce_type(field.type, type_hash, "Field #{type.name}.#{field.name}")
|
39
|
-
field.arguments.each do |name, argument|
|
40
|
-
reduce_type(argument.type, type_hash, "Argument #{name} on #{type.name}.#{field.name}")
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
if type.kind.object?
|
45
|
-
type.interfaces.each do |interface|
|
46
|
-
reduce_type(interface, type_hash, "Interface on #{type.name}")
|
47
|
-
end
|
48
|
-
end
|
49
|
-
if type.kind.union?
|
50
|
-
type.possible_types.each do |possible_type|
|
51
|
-
reduce_type(possible_type, type_hash, "Possible type for #{type.name}")
|
52
|
-
end
|
53
|
-
end
|
54
|
-
if type.kind.input_object?
|
55
|
-
type.arguments.each do |argument_name, argument|
|
56
|
-
reduce_type(argument.type, type_hash, "Input field #{type.name}.#{argument_name}")
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.validate_type(type, context_description)
|
62
|
-
error_message = GraphQL::Schema::Validation.validate(type)
|
63
|
-
if error_message
|
64
|
-
raise GraphQL::Schema::InvalidTypeError.new("#{context_description} is invalid: #{error_message}")
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|