graphql 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/analysis/analyze_query.rb +4 -2
- data/lib/graphql/analysis/field_usage.rb +4 -4
- data/lib/graphql/analysis/query_complexity.rb +16 -21
- data/lib/graphql/argument.rb +13 -6
- data/lib/graphql/base_type.rb +2 -1
- data/lib/graphql/compatibility/execution_specification.rb +76 -0
- data/lib/graphql/compatibility/query_parser_specification.rb +16 -2
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -5
- data/lib/graphql/compatibility/schema_parser_specification.rb +6 -0
- data/lib/graphql/define/assign_argument.rb +8 -2
- data/lib/graphql/define/instance_definable.rb +12 -15
- data/lib/graphql/directive.rb +2 -1
- data/lib/graphql/enum_type.rb +5 -7
- data/lib/graphql/field.rb +6 -11
- data/lib/graphql/field/resolve.rb +1 -0
- data/lib/graphql/input_object_type.rb +9 -9
- data/lib/graphql/interface_type.rb +2 -1
- data/lib/graphql/internal_representation.rb +1 -0
- data/lib/graphql/internal_representation/node.rb +31 -9
- data/lib/graphql/internal_representation/rewrite.rb +26 -26
- data/lib/graphql/internal_representation/selections.rb +41 -0
- data/lib/graphql/introspection/input_value_type.rb +6 -2
- data/lib/graphql/language/generation.rb +2 -0
- data/lib/graphql/language/lexer.rl +4 -0
- data/lib/graphql/language/nodes.rb +3 -0
- data/lib/graphql/language/parser.rb +525 -509
- data/lib/graphql/language/parser.y +2 -0
- data/lib/graphql/object_type.rb +2 -2
- data/lib/graphql/query.rb +21 -0
- data/lib/graphql/query/context.rb +52 -4
- data/lib/graphql/query/serial_execution.rb +3 -4
- data/lib/graphql/query/serial_execution/field_resolution.rb +35 -36
- data/lib/graphql/query/serial_execution/operation_resolution.rb +9 -15
- data/lib/graphql/query/serial_execution/selection_resolution.rb +14 -11
- data/lib/graphql/query/serial_execution/value_resolution.rb +18 -17
- data/lib/graphql/query/variables.rb +1 -1
- data/lib/graphql/relay/mutation.rb +5 -8
- data/lib/graphql/scalar_type.rb +1 -2
- data/lib/graphql/schema.rb +2 -13
- data/lib/graphql/schema/build_from_definition.rb +28 -13
- data/lib/graphql/schema/loader.rb +4 -1
- data/lib/graphql/schema/printer.rb +10 -3
- data/lib/graphql/schema/timeout_middleware.rb +18 -2
- data/lib/graphql/schema/unique_within_type.rb +6 -3
- data/lib/graphql/static_validation/literal_validator.rb +3 -1
- data/lib/graphql/union_type.rb +1 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -0
- data/spec/graphql/analysis/analyze_query_spec.rb +6 -8
- data/spec/graphql/argument_spec.rb +18 -0
- data/spec/graphql/define/assign_argument_spec.rb +48 -0
- data/spec/graphql/define/instance_definable_spec.rb +4 -2
- data/spec/graphql/execution_error_spec.rb +66 -0
- data/spec/graphql/input_object_type_spec.rb +81 -0
- data/spec/graphql/internal_representation/rewrite_spec.rb +104 -21
- data/spec/graphql/introspection/input_value_type_spec.rb +43 -6
- data/spec/graphql/introspection/schema_type_spec.rb +1 -0
- data/spec/graphql/introspection/type_type_spec.rb +2 -0
- data/spec/graphql/language/generation_spec.rb +3 -2
- data/spec/graphql/query/arguments_spec.rb +17 -4
- data/spec/graphql/query/context_spec.rb +23 -0
- data/spec/graphql/query/variables_spec.rb +15 -1
- data/spec/graphql/relay/mutation_spec.rb +42 -2
- data/spec/graphql/schema/build_from_definition_spec.rb +4 -2
- data/spec/graphql/schema/loader_spec.rb +59 -1
- data/spec/graphql/schema/printer_spec.rb +2 -0
- data/spec/graphql/schema/reduce_types_spec.rb +1 -1
- data/spec/graphql/schema/timeout_middleware_spec.rb +2 -2
- data/spec/graphql/schema/unique_within_type_spec.rb +9 -0
- data/spec/graphql/schema/validation_spec.rb +15 -3
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +122 -0
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +78 -0
- data/spec/support/dairy_app.rb +9 -0
- data/spec/support/minimum_input_object.rb +4 -0
- data/spec/support/star_wars_schema.rb +1 -1
- metadata +5 -5
- data/lib/graphql/query/serial_execution/execution_context.rb +0 -37
- data/spec/graphql/query/serial_execution/execution_context_spec.rb +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8e06bd99f6bb6350c2d7111d5014ef9c71154f8a
|
4
|
+
data.tar.gz: 1b90cfb31081700c64abab2f8f26a665bd2fe6fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8c0847198e4c6403cffac42b6cf8ab3cf1446d04ebcb91d2cb916244e170f0072d6ef9ee1ac355c4585ab62d0eac73048d34cb89e990b0cf62bde639d8fd166
|
7
|
+
data.tar.gz: ce1ea3d57512c38593c50ba2531994b5ce5ed83b0cb91ee13e4e78402d3ed4494c8d8ec88db2c037460e0379820b47821c0fcdb03a18cc804de17157fc252acd
|
@@ -32,8 +32,10 @@ module GraphQL
|
|
32
32
|
def reduce_node(irep_node, reducer_states)
|
33
33
|
visit_analyzers(:enter, irep_node, reducer_states)
|
34
34
|
|
35
|
-
irep_node.
|
36
|
-
|
35
|
+
irep_node.typed_children.each do |type_defn, children|
|
36
|
+
children.each do |name, child_irep_node|
|
37
|
+
reduce_node(child_irep_node, reducer_states)
|
38
|
+
end
|
37
39
|
end
|
38
40
|
|
39
41
|
visit_analyzers(:leave, irep_node, reducer_states)
|
@@ -26,10 +26,10 @@ module GraphQL
|
|
26
26
|
|
27
27
|
def call(memo, visit_type, irep_node)
|
28
28
|
if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field) && visit_type == :leave
|
29
|
-
irep_node.
|
30
|
-
|
31
|
-
|
32
|
-
memo[:used_deprecated_fields] << field
|
29
|
+
field = "#{irep_node.owner_type.name}.#{irep_node.definition.name}"
|
30
|
+
memo[:used_fields] << field
|
31
|
+
if irep_node.definition.deprecation_reason
|
32
|
+
memo[:used_deprecated_fields] << field
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -46,7 +46,7 @@ module GraphQL
|
|
46
46
|
type_complexities = memo[:complexities_on_type].pop
|
47
47
|
child_complexity = type_complexities.max_possible_complexity
|
48
48
|
own_complexity = get_complexity(irep_node, memo[:query], child_complexity)
|
49
|
-
memo[:complexities_on_type].last.merge(irep_node.
|
49
|
+
memo[:complexities_on_type].last.merge(irep_node.owner_type, own_complexity)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -65,24 +65,18 @@ module GraphQL
|
|
65
65
|
# Get a complexity value for a field,
|
66
66
|
# by getting the number or calling its proc
|
67
67
|
def get_complexity(irep_node, query, child_complexity)
|
68
|
-
|
69
|
-
irep_node.
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
end
|
80
|
-
|
81
|
-
if type_cpx > max_possible_complexity
|
82
|
-
max_possible_complexity = type_cpx
|
83
|
-
end
|
68
|
+
type_defn = irep_node.owner_type
|
69
|
+
field_defn = irep_node.definition
|
70
|
+
defined_complexity = field_defn.complexity
|
71
|
+
case defined_complexity
|
72
|
+
when Proc
|
73
|
+
args = query.arguments_for(irep_node, field_defn)
|
74
|
+
defined_complexity.call(query.context, args, child_complexity)
|
75
|
+
when Numeric
|
76
|
+
defined_complexity + (child_complexity || 0)
|
77
|
+
else
|
78
|
+
raise("Invalid complexity: #{defined_complexity.inspect} on #{field_defn.name}")
|
84
79
|
end
|
85
|
-
max_possible_complexity
|
86
80
|
end
|
87
81
|
|
88
82
|
# Selections on an object may apply differently depending on what is _actually_ returned by the resolve function.
|
@@ -112,9 +106,10 @@ module GraphQL
|
|
112
106
|
max_complexity
|
113
107
|
end
|
114
108
|
|
115
|
-
# Store the complexity
|
116
|
-
|
117
|
-
|
109
|
+
# Store the complexity for the branch on `type_defn`.
|
110
|
+
# Later we will see if this is the max complexity among branches.
|
111
|
+
def merge(type_defn, complexity)
|
112
|
+
@types[type_defn] += complexity
|
118
113
|
end
|
119
114
|
|
120
115
|
private
|
data/lib/graphql/argument.rb
CHANGED
@@ -17,24 +17,31 @@ module GraphQL
|
|
17
17
|
class Argument
|
18
18
|
include GraphQL::Define::InstanceDefinable
|
19
19
|
accepts_definitions :name, :type, :description, :default_value
|
20
|
-
|
20
|
+
attr_accessor :type, :description, :default_value, :name
|
21
|
+
|
22
|
+
ensure_defined(:name, :description, :default_value, :type=, :type)
|
23
|
+
|
24
|
+
def default_value?
|
25
|
+
!!@has_default_value
|
26
|
+
end
|
27
|
+
|
28
|
+
def default_value=(new_default_value)
|
29
|
+
@has_default_value = true
|
30
|
+
@default_value = new_default_value
|
31
|
+
end
|
21
32
|
|
22
33
|
# @!attribute name
|
23
34
|
# @return [String] The name of this argument on its {GraphQL::Field} or {GraphQL::InputObjectType}
|
24
35
|
|
25
36
|
# @param new_input_type [GraphQL::BaseType, Proc] Assign a new input type for this argument (if it's a proc, it will be called after schema initialization)
|
26
37
|
def type=(new_input_type)
|
27
|
-
ensure_defined
|
28
38
|
@clean_type = nil
|
29
39
|
@dirty_type = new_input_type
|
30
40
|
end
|
31
41
|
|
32
42
|
# @return [GraphQL::BaseType] the input type for this argument
|
33
43
|
def type
|
34
|
-
@clean_type ||=
|
35
|
-
ensure_defined
|
36
|
-
GraphQL::BaseType.resolve_related_type(@dirty_type)
|
37
|
-
end
|
44
|
+
@clean_type ||= GraphQL::BaseType.resolve_related_type(@dirty_type)
|
38
45
|
end
|
39
46
|
end
|
40
47
|
end
|
data/lib/graphql/base_type.rb
CHANGED
@@ -8,7 +8,8 @@ module GraphQL
|
|
8
8
|
global_id_field: GraphQL::Define::AssignGlobalIdField,
|
9
9
|
}
|
10
10
|
|
11
|
-
|
11
|
+
attr_accessor :name, :description
|
12
|
+
ensure_defined(:name, :description)
|
12
13
|
|
13
14
|
# @!attribute name
|
14
15
|
# @return [String] the name of this type, must be unique within a Schema
|
@@ -407,6 +407,82 @@ module GraphQL
|
|
407
407
|
error_messages = res["errors"].map { |e| e["message"] }
|
408
408
|
assert_equal ["Error on Nullable"], error_messages
|
409
409
|
end
|
410
|
+
|
411
|
+
def test_it_only_resolves_fields_once_on_typed_fragments
|
412
|
+
count = 0
|
413
|
+
counter_type = nil
|
414
|
+
|
415
|
+
has_count_interface = GraphQL::InterfaceType.define do
|
416
|
+
name "HasCount"
|
417
|
+
field :count, types.Int
|
418
|
+
field :counter, ->{ counter_type }
|
419
|
+
end
|
420
|
+
|
421
|
+
counter_type = GraphQL::ObjectType.define do
|
422
|
+
name "Counter"
|
423
|
+
interfaces [has_count_interface]
|
424
|
+
field :count, types.Int, resolve: ->(o,a,c) { count += 1 }
|
425
|
+
field :counter, has_count_interface, resolve: ->(o,a,c) { :counter }
|
426
|
+
end
|
427
|
+
|
428
|
+
alt_counter_type = GraphQL::ObjectType.define do
|
429
|
+
name "AltCounter"
|
430
|
+
interfaces [has_count_interface]
|
431
|
+
field :count, types.Int, resolve: ->(o,a,c) { count += 1 }
|
432
|
+
field :counter, has_count_interface, resolve: ->(o,a,c) { :counter }
|
433
|
+
end
|
434
|
+
|
435
|
+
has_counter_interface = GraphQL::InterfaceType.define do
|
436
|
+
name "HasCounter"
|
437
|
+
field :counter, counter_type
|
438
|
+
end
|
439
|
+
|
440
|
+
query_type = GraphQL::ObjectType.define do
|
441
|
+
name "Query"
|
442
|
+
interfaces [has_counter_interface]
|
443
|
+
field :counter, has_count_interface, resolve: ->(o,a,c) { :counter }
|
444
|
+
end
|
445
|
+
|
446
|
+
schema = GraphQL::Schema.define(
|
447
|
+
query: query_type,
|
448
|
+
resolve_type: ->(o, c) { o == :counter ? counter_type : nil },
|
449
|
+
orphan_types: [alt_counter_type],
|
450
|
+
)
|
451
|
+
|
452
|
+
res = schema.execute("
|
453
|
+
{
|
454
|
+
counter { count }
|
455
|
+
... on HasCounter {
|
456
|
+
counter { count }
|
457
|
+
}
|
458
|
+
}
|
459
|
+
")
|
460
|
+
|
461
|
+
expected_data = {
|
462
|
+
"counter" => { "count" => 1 }
|
463
|
+
}
|
464
|
+
assert_equal expected_data, res["data"]
|
465
|
+
assert_equal 1, count
|
466
|
+
|
467
|
+
# Deep typed children are correctly distinguished:
|
468
|
+
res = schema.execute("
|
469
|
+
{
|
470
|
+
counter {
|
471
|
+
... on Counter {
|
472
|
+
counter { count }
|
473
|
+
}
|
474
|
+
... on AltCounter {
|
475
|
+
counter { count, t: __typename }
|
476
|
+
}
|
477
|
+
}
|
478
|
+
}
|
479
|
+
")
|
480
|
+
|
481
|
+
expected_data = {
|
482
|
+
"counter" => { "counter" => { "count" => 2 } }
|
483
|
+
}
|
484
|
+
assert_equal expected_data, res["data"]
|
485
|
+
end
|
410
486
|
end
|
411
487
|
end
|
412
488
|
end
|
@@ -57,12 +57,15 @@ module GraphQL
|
|
57
57
|
int: 3,
|
58
58
|
float: 4.7e-24,
|
59
59
|
bool: false,
|
60
|
-
string: "
|
60
|
+
string: "☀︎🏆 \\b \\f \\n \\r \\t \\" \u00b6 \\u00b6 / \\/",
|
61
61
|
enum: ENUM_NAME,
|
62
62
|
array: [7, 8, 9]
|
63
63
|
object: {a: [1,2,3], b: {c: "4"}}
|
64
64
|
unicode_bom: "\xef\xbb\xbfquery"
|
65
65
|
keywordEnum: on
|
66
|
+
nullValue: null
|
67
|
+
nullValueInObject: {a: null, b: "b"}
|
68
|
+
nullValueInArray: ["a", null, "b"]
|
66
69
|
)
|
67
70
|
}
|
68
71
|
|
|
@@ -71,7 +74,7 @@ module GraphQL
|
|
71
74
|
assert_equal 3, inputs[0].value, "Integers"
|
72
75
|
assert_equal 0.47e-23, inputs[1].value, "Floats"
|
73
76
|
assert_equal false, inputs[2].value, "Booleans"
|
74
|
-
assert_equal
|
77
|
+
assert_equal %|☀︎🏆 \b \f \n \r \t " ¶ ¶ / /|, inputs[3].value, "Strings"
|
75
78
|
assert_instance_of GraphQL::Language::Nodes::Enum, inputs[4].value
|
76
79
|
assert_equal "ENUM_NAME", inputs[4].value.name, "Enums"
|
77
80
|
assert_equal [7,8,9], inputs[5].value, "Lists"
|
@@ -85,6 +88,17 @@ module GraphQL
|
|
85
88
|
|
86
89
|
assert_equal %|\xef\xbb\xbfquery|, inputs[7].value, "Unicode BOM"
|
87
90
|
assert_equal "on", inputs[8].value.name, "Enum value 'on'"
|
91
|
+
|
92
|
+
assert_instance_of GraphQL::Language::Nodes::NullValue, inputs[9].value
|
93
|
+
|
94
|
+
args = inputs[10].value.arguments
|
95
|
+
assert_instance_of GraphQL::Language::Nodes::NullValue, args.find{ |arg| arg.name == 'a' }.value
|
96
|
+
assert_equal 'b', args.find{ |arg| arg.name == 'b' }.value
|
97
|
+
|
98
|
+
values = inputs[11].value
|
99
|
+
assert_equal 'a', values[0]
|
100
|
+
assert_instance_of GraphQL::Language::Nodes::NullValue, values[1]
|
101
|
+
assert_equal 'b', values[2]
|
88
102
|
end
|
89
103
|
end
|
90
104
|
end
|
@@ -70,11 +70,6 @@ module GraphQL
|
|
70
70
|
assert_raises_parse_error("{ ...on }")
|
71
71
|
assert_raises_parse_error("fragment on on Type { field }")
|
72
72
|
end
|
73
|
-
|
74
|
-
def test_it_rejects_null
|
75
|
-
err = assert_raises_parse_error("{ field(input: null) }")
|
76
|
-
assert_includes(err.message, "null")
|
77
|
-
end
|
78
73
|
end
|
79
74
|
end
|
80
75
|
end
|
@@ -184,6 +184,11 @@ module GraphQL
|
|
184
184
|
assert_equal GraphQL::Language::Nodes::InterfaceTypeDefinition, interface_type_definition.class
|
185
185
|
assert_equal 'Comment for interface definitions', interface_type_definition.description
|
186
186
|
assert_equal 'Amount of wheels', interface_type_definition.fields[0].description
|
187
|
+
|
188
|
+
brand_field = interface_type_definition.fields[1]
|
189
|
+
assert_equal 1, brand_field.arguments.length
|
190
|
+
assert_equal 'argument', brand_field.arguments[0].name
|
191
|
+
assert_instance_of GraphQL::Language::Nodes::NullValue, brand_field.arguments[0].default_value
|
187
192
|
end
|
188
193
|
end
|
189
194
|
end
|
@@ -230,6 +235,7 @@ module GraphQL
|
|
230
235
|
interface Vehicle {
|
231
236
|
# Amount of wheels
|
232
237
|
wheels: Int!
|
238
|
+
brand(argument: String = null): String!
|
233
239
|
}
|
234
240
|
|
235
241
|
# Comment at the end of schema
|
@@ -2,16 +2,22 @@ module GraphQL
|
|
2
2
|
module Define
|
3
3
|
# Turn argument configs into a {GraphQL::Argument}.
|
4
4
|
module AssignArgument
|
5
|
-
def self.call(target, name, type = nil, description = nil,
|
5
|
+
def self.call(target, name, type = nil, description = nil, **rest, &block)
|
6
6
|
argument = if block_given?
|
7
7
|
GraphQL::Argument.define(&block)
|
8
8
|
else
|
9
9
|
GraphQL::Argument.new
|
10
10
|
end
|
11
|
+
|
12
|
+
unsupported_keys = rest.keys - [:default_value]
|
13
|
+
if unsupported_keys.any?
|
14
|
+
raise ArgumentError.new("unknown keyword#{unsupported_keys.length > 1 ? 's' : ''}: #{unsupported_keys.join(', ')}")
|
15
|
+
end
|
16
|
+
|
11
17
|
argument.name = name.to_s
|
12
18
|
type && argument.type = type
|
13
19
|
description && argument.description = description
|
14
|
-
|
20
|
+
rest.key?(:default_value) && argument.default_value = rest[:default_value]
|
15
21
|
|
16
22
|
target.arguments[name.to_s] = argument
|
17
23
|
end
|
@@ -71,13 +71,13 @@ module GraphQL
|
|
71
71
|
module InstanceDefinable
|
72
72
|
def self.included(base)
|
73
73
|
base.extend(ClassMethods)
|
74
|
+
base.ensure_defined(:metadata)
|
74
75
|
end
|
75
76
|
|
76
77
|
# `metadata` can store arbitrary key-values with an object.
|
77
78
|
#
|
78
79
|
# @return [Hash<Object, Object>] Hash for user-defined storage
|
79
80
|
def metadata
|
80
|
-
ensure_defined
|
81
81
|
@metadata ||= {}
|
82
82
|
end
|
83
83
|
|
@@ -174,21 +174,18 @@ module GraphQL
|
|
174
174
|
@own_dictionary = own_dictionary.merge(new_assignments)
|
175
175
|
end
|
176
176
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
end
|
186
|
-
|
187
|
-
define_method("#{attr_name}=") do |new_value|
|
188
|
-
ensure_defined
|
189
|
-
instance_variable_set(ivar_name, new_value)
|
177
|
+
def ensure_defined(*method_names)
|
178
|
+
ensure_defined_module = Module.new
|
179
|
+
ensure_defined_module.module_eval {
|
180
|
+
method_names.each do |method_name|
|
181
|
+
define_method(method_name) { |*args, &block|
|
182
|
+
ensure_defined
|
183
|
+
super(*args, &block)
|
184
|
+
}
|
190
185
|
end
|
191
|
-
|
186
|
+
}
|
187
|
+
self.prepend(ensure_defined_module)
|
188
|
+
nil
|
192
189
|
end
|
193
190
|
|
194
191
|
# @return [Hash] combined definitions for self and ancestors
|
data/lib/graphql/directive.rb
CHANGED
@@ -9,7 +9,8 @@ module GraphQL
|
|
9
9
|
include GraphQL::Define::InstanceDefinable
|
10
10
|
accepts_definitions :locations, :name, :description, :arguments, argument: GraphQL::Define::AssignArgument
|
11
11
|
|
12
|
-
|
12
|
+
attr_accessor :locations, :arguments, :name, :description
|
13
|
+
ensure_defined(:locations, :arguments, :name, :description)
|
13
14
|
|
14
15
|
LOCATIONS = [
|
15
16
|
QUERY = :QUERY,
|
data/lib/graphql/enum_type.rb
CHANGED
@@ -72,6 +72,7 @@ module GraphQL
|
|
72
72
|
|
73
73
|
class EnumType < GraphQL::BaseType
|
74
74
|
accepts_definitions :values, value: GraphQL::Define::AssignEnumValue
|
75
|
+
ensure_defined(:values, :validate_non_null_input, :coerce_non_null_input, :coerce_result)
|
75
76
|
|
76
77
|
def initialize
|
77
78
|
@values_by_name = {}
|
@@ -90,7 +91,6 @@ module GraphQL
|
|
90
91
|
|
91
92
|
# @return [Hash<String => EnumValue>] `{name => value}` pairs contained in this type
|
92
93
|
def values
|
93
|
-
ensure_defined
|
94
94
|
@values_by_name
|
95
95
|
end
|
96
96
|
|
@@ -99,7 +99,6 @@ module GraphQL
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def validate_non_null_input(value_name, warden)
|
102
|
-
ensure_defined
|
103
102
|
result = GraphQL::Query::InputValidationResult.new
|
104
103
|
allowed_values = warden.enum_values(self)
|
105
104
|
matching_value = allowed_values.find { |v| v.name == value_name }
|
@@ -120,7 +119,6 @@ module GraphQL
|
|
120
119
|
# @param value_name [String] the string representation of this enum value
|
121
120
|
# @return [Object] the underlying value for this enum value
|
122
121
|
def coerce_non_null_input(value_name)
|
123
|
-
ensure_defined
|
124
122
|
if @values_by_name.key?(value_name)
|
125
123
|
@values_by_name.fetch(value_name).value
|
126
124
|
else
|
@@ -129,7 +127,6 @@ module GraphQL
|
|
129
127
|
end
|
130
128
|
|
131
129
|
def coerce_result(value, warden = nil)
|
132
|
-
ensure_defined
|
133
130
|
all_values = warden ? warden.enum_values(self) : @values_by_name.each_value
|
134
131
|
enum_value = all_values.find { |val| val.value == value }
|
135
132
|
if enum_value
|
@@ -148,9 +145,10 @@ module GraphQL
|
|
148
145
|
# Created with the `value` helper
|
149
146
|
class EnumValue
|
150
147
|
include GraphQL::Define::InstanceDefinable
|
151
|
-
|
152
|
-
|
153
|
-
|
148
|
+
ATTRIBUTES = [:name, :description, :deprecation_reason, :value]
|
149
|
+
accepts_definitions(*ATTRIBUTES)
|
150
|
+
attr_accessor(*ATTRIBUTES)
|
151
|
+
ensure_defined(*ATTRIBUTES)
|
154
152
|
end
|
155
153
|
|
156
154
|
class UnresolvedValueError < GraphQL::Error
|
data/lib/graphql/field.rb
CHANGED
@@ -126,7 +126,11 @@ module GraphQL
|
|
126
126
|
argument: GraphQL::Define::AssignArgument
|
127
127
|
|
128
128
|
|
129
|
-
|
129
|
+
attr_accessor :name, :deprecation_reason, :description, :property, :hash_key, :mutation, :arguments, :complexity
|
130
|
+
ensure_defined(
|
131
|
+
:name, :deprecation_reason, :description, :property, :hash_key, :mutation, :arguments, :complexity,
|
132
|
+
:resolve, :resolve=, :type, :type=, :name=, :property=, :hash_key=
|
133
|
+
)
|
130
134
|
|
131
135
|
# @!attribute [r] resolve_proc
|
132
136
|
# @return [<#call(obj, args,ctx)>] A proc-like object which can be called to return the field's value
|
@@ -158,7 +162,6 @@ module GraphQL
|
|
158
162
|
# @param arguments [Hash] Arguments declared in the query
|
159
163
|
# @param context [GraphQL::Query::Context]
|
160
164
|
def resolve(object, arguments, context)
|
161
|
-
ensure_defined
|
162
165
|
resolve_proc.call(object, arguments, context)
|
163
166
|
end
|
164
167
|
|
@@ -166,22 +169,17 @@ module GraphQL
|
|
166
169
|
# a new resolve proc will be build based on its {#name}, {#property} or {#hash_key}.
|
167
170
|
# @param new_resolve_proc [<#call(obj, args, ctx)>, nil]
|
168
171
|
def resolve=(new_resolve_proc)
|
169
|
-
ensure_defined
|
170
172
|
@resolve_proc = new_resolve_proc || build_default_resolver
|
171
173
|
end
|
172
174
|
|
173
175
|
def type=(new_return_type)
|
174
|
-
ensure_defined
|
175
176
|
@clean_type = nil
|
176
177
|
@dirty_type = new_return_type
|
177
178
|
end
|
178
179
|
|
179
180
|
# Get the return type for this field.
|
180
181
|
def type
|
181
|
-
@clean_type ||=
|
182
|
-
ensure_defined
|
183
|
-
GraphQL::BaseType.resolve_related_type(@dirty_type)
|
184
|
-
end
|
182
|
+
@clean_type ||= GraphQL::BaseType.resolve_related_type(@dirty_type)
|
185
183
|
end
|
186
184
|
|
187
185
|
# You can only set a field's name _once_ -- this to prevent
|
@@ -189,7 +187,6 @@ module GraphQL
|
|
189
187
|
#
|
190
188
|
# This is important because {#name} may be used by {#resolve}.
|
191
189
|
def name=(new_name)
|
192
|
-
ensure_defined
|
193
190
|
if @name.nil?
|
194
191
|
@name = new_name
|
195
192
|
elsif @name != new_name
|
@@ -199,14 +196,12 @@ module GraphQL
|
|
199
196
|
|
200
197
|
# @param new_property [Symbol] A method to call to resolve this field. Overrides the existing resolve proc.
|
201
198
|
def property=(new_property)
|
202
|
-
ensure_defined
|
203
199
|
@property = new_property
|
204
200
|
self.resolve = nil # reset resolve proc
|
205
201
|
end
|
206
202
|
|
207
203
|
# @param new_hash_key [Symbol] A key to access with `#[key]` to resolve this field. Overrides the existing resolve proc.
|
208
204
|
def hash_key=(new_hash_key)
|
209
|
-
ensure_defined
|
210
205
|
@hash_key = new_hash_key
|
211
206
|
self.resolve = nil # reset resolve proc
|
212
207
|
end
|