graphql 0.10.6 → 0.10.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/language/transform.rb +31 -37
- data/lib/graphql/list_type.rb +9 -3
- data/lib/graphql/static_validation/literal_validator.rb +8 -4
- data/lib/graphql/version.rb +1 -1
- data/spec/graphql/interface_type_spec.rb +1 -1
- data/spec/graphql/query/variables_spec.rb +28 -0
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +2 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f94bf39aba9a98caa4bf69c263eacb820d41b08
|
4
|
+
data.tar.gz: 4a11eb3ee5d554345942bab98098a623d33f0aad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33a339144c49cc616818d398248f8b6f75c507efde44975f8e03e758c7f3783887bddeadb8c094551bad3444f9c1eaa8ecf8966ef19c58fae8f6a23e95a226e0
|
7
|
+
data.tar.gz: b1d227ca3c1981e22a2b8be23e30c7d7eee78f3e8a13f8b6702ea29a842d4198eb929a38b01ae19e44c39e2cef81e2b322565035d7ecf7832c80ddecc4e5aac2
|
@@ -1,31 +1,25 @@
|
|
1
1
|
module GraphQL
|
2
2
|
module Language
|
3
|
-
# Extend `Parslet::Context` with a convenience method
|
4
|
-
# for building AST nodes
|
5
|
-
module ParsletContextCreateNode
|
6
|
-
refine Parslet::Context do
|
7
|
-
# @param [Symbol] name of a node constant
|
8
|
-
# @param [Hash] attributes to initialize the {Node} with
|
9
|
-
# @return [GraphQL::Language::Node] a node of type `name` with attributes `attributes`
|
10
|
-
def create_node(name, attributes)
|
11
|
-
node_class = GraphQL::Language::Nodes.const_get(name)
|
12
|
-
node_class.new(attributes)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
using ParsletContextCreateNode
|
18
3
|
|
19
4
|
# {Transform} is a [parslet](http://kschiess.github.io/parslet/) transform for for turning the AST into objects in {GraphQL::Language::Nodes} objects.
|
20
5
|
class Transform < Parslet::Transform
|
6
|
+
|
7
|
+
# @param [Symbol] name of a node constant
|
8
|
+
# @param [Hash] attributes to initialize the {Node} with
|
9
|
+
# @return [GraphQL::Language::Node] a node of type `name` with attributes `attributes`
|
10
|
+
CREATE_NODE = Proc.new do |name, attributes|
|
11
|
+
node_class = GraphQL::Language::Nodes.const_get(name)
|
12
|
+
node_class.new(attributes)
|
13
|
+
end
|
14
|
+
|
21
15
|
def self.optional_sequence(name)
|
22
16
|
rule(name => simple(:val)) { [] }
|
23
17
|
rule(name => sequence(:val)) { val }
|
24
18
|
end
|
25
19
|
|
26
20
|
# Document
|
27
|
-
rule(document_parts: sequence(:p)) {
|
28
|
-
rule(document_parts: simple(:p)) {
|
21
|
+
rule(document_parts: sequence(:p)) { CREATE_NODE[:Document, parts: p, line: (p.first ? p.first.line : 1), col: (p.first ? p.first.col : 1)]}
|
22
|
+
rule(document_parts: simple(:p)) { CREATE_NODE[:Document, parts: [], line: 1, col: 1]}
|
29
23
|
|
30
24
|
# Fragment Definition
|
31
25
|
rule(
|
@@ -34,20 +28,20 @@ module GraphQL
|
|
34
28
|
type_condition: simple(:type),
|
35
29
|
directives: sequence(:directives),
|
36
30
|
selections: sequence(:selections)
|
37
|
-
) {
|
31
|
+
) { CREATE_NODE[:FragmentDefinition, name: name.to_s, type: type.to_s, directives: directives, selections: selections, position_source: kw]}
|
38
32
|
|
39
33
|
rule(
|
40
34
|
fragment_spread_keyword: simple(:kw),
|
41
35
|
fragment_spread_name: simple(:n),
|
42
36
|
directives: sequence(:d)
|
43
|
-
) {
|
37
|
+
) { CREATE_NODE[:FragmentSpread, name: n.to_s, directives: d, position_source: kw]}
|
44
38
|
|
45
39
|
rule(
|
46
40
|
fragment_spread_keyword: simple(:kw),
|
47
41
|
inline_fragment_type: simple(:n),
|
48
42
|
directives: sequence(:d),
|
49
43
|
selections: sequence(:s),
|
50
|
-
) {
|
44
|
+
) { CREATE_NODE[:InlineFragment, type: n.to_s, directives: d, selections: s, position_source: kw]}
|
51
45
|
|
52
46
|
# Operation Definition
|
53
47
|
rule(
|
@@ -56,14 +50,14 @@ module GraphQL
|
|
56
50
|
variables: sequence(:v),
|
57
51
|
directives: sequence(:d),
|
58
52
|
selections: sequence(:s),
|
59
|
-
) {
|
53
|
+
) { CREATE_NODE[:OperationDefinition, operation_type: ot.to_s, name: n.to_s, variables: v, directives: d, selections: s, position_source: ot] }
|
60
54
|
optional_sequence(:optional_variables)
|
61
|
-
rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: simple(:v)) {
|
62
|
-
rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: sequence(:v)) {
|
55
|
+
rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: simple(:v)) { CREATE_NODE.(:Variable, name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
|
56
|
+
rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: sequence(:v)) { CREATE_NODE.(:Variable, name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
|
63
57
|
rule(variable_default_value: simple(:v) ) { v }
|
64
58
|
rule(variable_default_value: sequence(:v) ) { v }
|
65
59
|
# Query short-hand
|
66
|
-
rule(unnamed_selections: sequence(:s)) {
|
60
|
+
rule(unnamed_selections: sequence(:s)) { CREATE_NODE[:OperationDefinition, selections: s, operation_type: "query", name: nil, variables: [], directives: [], line: s.first.line, col: s.first.col]}
|
67
61
|
|
68
62
|
# Field
|
69
63
|
rule(
|
@@ -72,32 +66,32 @@ module GraphQL
|
|
72
66
|
field_arguments: sequence(:args),
|
73
67
|
directives: sequence(:dir),
|
74
68
|
selections: sequence(:sel)
|
75
|
-
) {
|
69
|
+
) { CREATE_NODE[:Field, alias: a && a.to_s, name: name.to_s, arguments: args, directives: dir, selections: sel, position_source: [a, name].find { |part| !part.nil? }] }
|
76
70
|
|
77
71
|
rule(alias_name: simple(:a)) { a }
|
78
72
|
optional_sequence(:optional_field_arguments)
|
79
|
-
rule(field_argument_name: simple(:n), field_argument_value: simple(:v)) {
|
80
|
-
rule(field_argument_name: simple(:n), field_argument_value: sequence(:v)) {
|
73
|
+
rule(field_argument_name: simple(:n), field_argument_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
|
74
|
+
rule(field_argument_name: simple(:n), field_argument_value: sequence(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
|
81
75
|
optional_sequence(:optional_selections)
|
82
76
|
optional_sequence(:optional_directives)
|
83
77
|
|
84
78
|
# Directive
|
85
|
-
rule(directive_name: simple(:name), directive_arguments: sequence(:args)) {
|
86
|
-
rule(directive_argument_name: simple(:n), directive_argument_value: simple(:v)) {
|
79
|
+
rule(directive_name: simple(:name), directive_arguments: sequence(:args)) { CREATE_NODE[:Directive, name: name.to_s, arguments: args, position_source: name ] }
|
80
|
+
rule(directive_argument_name: simple(:n), directive_argument_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
|
87
81
|
optional_sequence(:optional_directive_arguments)
|
88
82
|
|
89
83
|
# Type Defs
|
90
|
-
rule(type_name: simple(:n)) {
|
91
|
-
rule(list_type: simple(:t)) {
|
92
|
-
rule(non_null_type: simple(:t)) {
|
84
|
+
rule(type_name: simple(:n)) { CREATE_NODE[:TypeName, name: n.to_s, position_source: n] }
|
85
|
+
rule(list_type: simple(:t)) { CREATE_NODE[:ListType, of_type: t, line: t.line, col: t.col] }
|
86
|
+
rule(non_null_type: simple(:t)) { CREATE_NODE[:NonNullType, of_type: t, line: t.line, col: t.col] }
|
93
87
|
|
94
88
|
# Values
|
95
89
|
rule(array: sequence(:v)) { v }
|
96
90
|
rule(array: simple(:v)) { [] } # just `nil`
|
97
91
|
rule(boolean: simple(:v)) { v == "true" ? true : false }
|
98
|
-
rule(input_object: sequence(:v)) {
|
99
|
-
rule(input_object_name: simple(:n), input_object_value: simple(:v)) {
|
100
|
-
rule(input_object_name: simple(:n), input_object_value: sequence(:v)) {
|
92
|
+
rule(input_object: sequence(:v)) { CREATE_NODE[:InputObject, pairs: v, line: (v.first ? v.first.line : 1), col: (v.first ? v.first.col : 1)] }
|
93
|
+
rule(input_object_name: simple(:n), input_object_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
|
94
|
+
rule(input_object_name: simple(:n), input_object_value: sequence(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
|
101
95
|
rule(int: simple(:v)) { v.to_i }
|
102
96
|
rule(float: simple(:v)) { v.to_f }
|
103
97
|
|
@@ -112,8 +106,8 @@ module GraphQL
|
|
112
106
|
string
|
113
107
|
}
|
114
108
|
rule(optional_string_content: simple(:v)) { v.to_s }
|
115
|
-
rule(variable: simple(:v)) {
|
116
|
-
rule(enum: simple(:v)) {
|
109
|
+
rule(variable: simple(:v)) { CREATE_NODE[:VariableIdentifier, name: v.to_s, position_source: v] }
|
110
|
+
rule(enum: simple(:v)) { CREATE_NODE[:Enum, name: v.to_s, position_source: v] }
|
117
111
|
end
|
118
112
|
end
|
119
113
|
end
|
data/lib/graphql/list_type.rb
CHANGED
@@ -18,11 +18,17 @@ class GraphQL::ListType < GraphQL::BaseType
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def valid_non_null_input?(value)
|
21
|
-
|
22
|
-
value.all?{ |item| of_type.valid_input?(item) }
|
21
|
+
ensure_array(value).all?{ |item| of_type.valid_input?(item) }
|
23
22
|
end
|
24
23
|
|
25
24
|
def coerce_non_null_input(value)
|
26
|
-
value.map{ |item| of_type.coerce_input(item) }
|
25
|
+
ensure_array(value).map{ |item| of_type.coerce_input(item) }
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def ensure_array(value)
|
32
|
+
value.is_a?(Array) ? value : [value]
|
27
33
|
end
|
28
34
|
end
|
@@ -3,9 +3,9 @@ class GraphQL::StaticValidation::LiteralValidator
|
|
3
3
|
def validate(ast_value, type)
|
4
4
|
if type.kind.non_null?
|
5
5
|
(!ast_value.nil?) && validate(ast_value, type.of_type)
|
6
|
-
elsif type.kind.list?
|
6
|
+
elsif type.kind.list?
|
7
7
|
item_type = type.of_type
|
8
|
-
ast_value.all? { |val| validate(val, item_type) }
|
8
|
+
ensure_array(ast_value).all? { |val| validate(val, item_type) }
|
9
9
|
elsif type.kind.scalar? && !ast_value.is_a?(GraphQL::Language::Nodes::AbstractNode) && !ast_value.is_a?(Array)
|
10
10
|
type.valid_input?(ast_value)
|
11
11
|
elsif type.kind.enum? && ast_value.is_a?(GraphQL::Language::Nodes::Enum)
|
@@ -39,6 +39,10 @@ class GraphQL::StaticValidation::LiteralValidator
|
|
39
39
|
ast_node.pairs.all? do |value|
|
40
40
|
field_type = fields[value.name].type
|
41
41
|
validate(value.value, field_type)
|
42
|
-
|
43
|
-
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def ensure_array(value)
|
46
|
+
value.is_a?(Array) ? value : [value]
|
47
|
+
end
|
44
48
|
end
|
data/lib/graphql/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe GraphQL::Query::Variables do
|
4
|
+
let(:query_string) {%|
|
5
|
+
query getCheese($animals: [DairyAnimal]) {
|
6
|
+
cheese(id: 1) {
|
7
|
+
similarCheese(source: $animals)
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|}
|
11
|
+
let(:ast_variables) { GraphQL.parse(query_string).parts.first.variables }
|
12
|
+
let(:variables) { GraphQL::Query::Variables.new(
|
13
|
+
DummySchema,
|
14
|
+
ast_variables,
|
15
|
+
provided_variables)
|
16
|
+
}
|
17
|
+
|
18
|
+
describe "#initialize" do
|
19
|
+
describe "coercing inputs" do
|
20
|
+
let(:provided_variables) {
|
21
|
+
{"animals" => "YAK"}
|
22
|
+
}
|
23
|
+
it "coerces single items into one-element lists" do
|
24
|
+
assert_equal ["YAK"], variables["animals"]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -8,6 +8,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
|
|
8
8
|
yakSource: searchDairy(product: [{source: COW, fatContent: 1.1}]) { source }
|
9
9
|
badSource: searchDairy(product: [{source: 1.1}]) { source }
|
10
10
|
missingSource: searchDairy(product: [{fatContent: 1.1}]) { source }
|
11
|
+
listCoerce: cheese(id: 1) { similarCheese(source: YAK) }
|
11
12
|
}
|
12
13
|
|
13
14
|
fragment cheeseFields on Cheese {
|
@@ -53,7 +54,7 @@ describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
|
|
53
54
|
|
54
55
|
fragment_error = {
|
55
56
|
"message"=>"Argument 'source' on Field 'similarCheese' has an invalid value",
|
56
|
-
"locations"=>[{"line"=>
|
57
|
+
"locations"=>[{"line"=>12, "column"=>7}]
|
57
58
|
}
|
58
59
|
assert_includes(errors, fragment_error)
|
59
60
|
end
|
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.10.
|
4
|
+
version: 0.10.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parslet
|
@@ -150,8 +150,8 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '10.4'
|
153
|
-
description:
|
154
|
-
static validation, type definition, and query execution.
|
153
|
+
description: A GraphQL server implementation for Ruby. Includes schema definition,
|
154
|
+
query parsing, static validation, type definition, and query execution.
|
155
155
|
email:
|
156
156
|
- rdmosolgo@gmail.com
|
157
157
|
executables: []
|
@@ -283,6 +283,7 @@ files:
|
|
283
283
|
- spec/graphql/query/context_spec.rb
|
284
284
|
- spec/graphql/query/executor_spec.rb
|
285
285
|
- spec/graphql/query/type_resolver_spec.rb
|
286
|
+
- spec/graphql/query/variables_spec.rb
|
286
287
|
- spec/graphql/query_spec.rb
|
287
288
|
- spec/graphql/scalar_type_spec.rb
|
288
289
|
- spec/graphql/schema/field_validator_spec.rb
|
@@ -341,7 +342,7 @@ rubyforge_project:
|
|
341
342
|
rubygems_version: 2.4.5
|
342
343
|
signing_key:
|
343
344
|
specification_version: 4
|
344
|
-
summary: A GraphQL implementation for Ruby
|
345
|
+
summary: A GraphQL server implementation for Ruby
|
345
346
|
test_files:
|
346
347
|
- spec/graphql/base_type_spec.rb
|
347
348
|
- spec/graphql/directive_spec.rb
|
@@ -365,6 +366,7 @@ test_files:
|
|
365
366
|
- spec/graphql/query/context_spec.rb
|
366
367
|
- spec/graphql/query/executor_spec.rb
|
367
368
|
- spec/graphql/query/type_resolver_spec.rb
|
369
|
+
- spec/graphql/query/variables_spec.rb
|
368
370
|
- spec/graphql/query_spec.rb
|
369
371
|
- spec/graphql/scalar_type_spec.rb
|
370
372
|
- spec/graphql/schema/field_validator_spec.rb
|