graphql-client 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/lib/graphql/client.rb +14 -0
- data/lib/graphql/client/document.rb +47 -0
- data/lib/graphql/client/fragment.rb +32 -0
- data/lib/graphql/client/node.rb +36 -0
- data/lib/graphql/client/query.rb +30 -0
- data/lib/graphql/client/query_result.rb +102 -0
- data/lib/graphql/language/nodes/deep_freeze_ext.rb +21 -0
- data/lib/graphql/language/nodes/inject_selection_ext.rb +44 -0
- data/lib/graphql/language/nodes/query_result_class_ext.rb +69 -0
- data/lib/graphql/language/nodes/replace_fragment_spread_ext.rb +44 -0
- data/lib/graphql/language/nodes/selection_ext.rb +37 -0
- data/lib/graphql/language/nodes/validate_ext.rb +45 -0
- data/lib/graphql/relay/node_query.rb +19 -0
- metadata +114 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2c235ea2f0b7616533466fbc80031bf4d8d5a7ee
|
4
|
+
data.tar.gz: fc4192d111b17dc3cdf5e28a21e70818e2534695
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d21e6ae9e95bc4ce084d566d49d67ed08e7863aab08df6c35099714dee0e2bab0fa6ea581b5139a4cbed08306510b3278c020c4a5b57d7658ebb6d6a560445d7
|
7
|
+
data.tar.gz: d5ee1964fd2c9f01e0f60b4c99166a27eb8201928a10000f59b70414d84385abaa06600ad1d494399287db46a01cc6a771b29fd61012e3a86332ea92cdb94a42
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2016 GitHub, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql/client/document"
|
3
|
+
require "graphql/client/fragment"
|
4
|
+
require "graphql/client/node"
|
5
|
+
require "graphql/client/query_result"
|
6
|
+
require "graphql/client/query"
|
7
|
+
|
8
|
+
module GraphQL
|
9
|
+
module Client
|
10
|
+
class << self
|
11
|
+
attr_accessor :schema
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql/client/fragment"
|
3
|
+
require "graphql/client/node"
|
4
|
+
require "graphql/client/query"
|
5
|
+
require "graphql/language/nodes/deep_freeze_ext"
|
6
|
+
require "graphql/language/nodes/inject_selection_ext"
|
7
|
+
require "graphql/language/nodes/replace_fragment_spread_ext"
|
8
|
+
require "graphql/language/nodes/validate_ext"
|
9
|
+
|
10
|
+
module GraphQL
|
11
|
+
module Client
|
12
|
+
class Document < Node
|
13
|
+
def self.parse(str, schema: GraphQL::Client.schema)
|
14
|
+
str = str.strip
|
15
|
+
str, fragments = scan_interpolated_fragments(str)
|
16
|
+
|
17
|
+
document = GraphQL.parse(str)
|
18
|
+
document = document.inject_selection(GraphQL::Language::Nodes::Field.new(name: "__typename"))
|
19
|
+
|
20
|
+
document.definitions.each do |definition|
|
21
|
+
fragments[definition.name.to_sym] = definition if definition.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
|
22
|
+
end
|
23
|
+
|
24
|
+
document = document.replace_fragment_spread(fragments)
|
25
|
+
|
26
|
+
document.definitions.inject({}) do |doc, definition|
|
27
|
+
name = definition.name.to_sym
|
28
|
+
|
29
|
+
case definition
|
30
|
+
when GraphQL::Language::Nodes::OperationDefinition
|
31
|
+
query = GraphQL::Client::Query.new(definition.deep_freeze, fragments.values).freeze
|
32
|
+
query.node.validate!(schema: schema) if schema
|
33
|
+
doc[name] = query
|
34
|
+
|
35
|
+
when GraphQL::Language::Nodes::FragmentDefinition
|
36
|
+
definition = GraphQL::Language::Nodes::InlineFragment.new(type: definition.type, directives: definition.directives, selections: definition.selections)
|
37
|
+
fragment = GraphQL::Client::Fragment.new(definition.deep_freeze, fragments.values).freeze
|
38
|
+
fragment.node.validate!(schema: schema) if schema
|
39
|
+
doc[name] = fragment
|
40
|
+
end
|
41
|
+
|
42
|
+
doc
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql/client/node"
|
3
|
+
require "graphql/language/nodes/deep_freeze_ext"
|
4
|
+
require "graphql/language/nodes/inject_selection_ext"
|
5
|
+
require "graphql/language/nodes/replace_fragment_spread_ext"
|
6
|
+
require "graphql/language/nodes/validate_ext"
|
7
|
+
|
8
|
+
module GraphQL
|
9
|
+
module Client
|
10
|
+
class Fragment < Node
|
11
|
+
def self.parse(str, schema: GraphQL::Client.schema)
|
12
|
+
str = str.strip
|
13
|
+
str, fragments = scan_interpolated_fragments(str)
|
14
|
+
|
15
|
+
if str.start_with?("fragment")
|
16
|
+
str = str.sub(/^fragment on /, "fragment __anonymous__ on ")
|
17
|
+
doc = GraphQL.parse(str)
|
18
|
+
doc = doc.inject_selection(GraphQL::Language::Nodes::Field.new(name: "__typename"))
|
19
|
+
doc = doc.replace_fragment_spread(fragments)
|
20
|
+
fragment = doc.definitions.first
|
21
|
+
node = GraphQL::Language::Nodes::InlineFragment.new(type: fragment.type, directives: fragment.directives, selections: fragment.selections)
|
22
|
+
else
|
23
|
+
raise ArgumentError, "expected string to be a fragment:\n#{str}"
|
24
|
+
end
|
25
|
+
|
26
|
+
fragment = new(node.deep_freeze, fragments.values).freeze
|
27
|
+
fragment.node.validate!(schema: schema) if schema
|
28
|
+
fragment
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "active_support/inflector"
|
2
|
+
require "graphql"
|
3
|
+
require "graphql/language/nodes/query_result_class_ext"
|
4
|
+
|
5
|
+
module GraphQL
|
6
|
+
module Client
|
7
|
+
class Node
|
8
|
+
def self.scan_interpolated_fragments(str)
|
9
|
+
fragments, index = {}, 1
|
10
|
+
str = str.gsub(/\.\.\.([a-zA-Z0-9_]+(::[a-zA-Z0-9_]+)+)/) { |m|
|
11
|
+
index += 1
|
12
|
+
name = "__fragment#{index}__"
|
13
|
+
fragments[name.to_sym] = ActiveSupport::Inflector.constantize($1).node
|
14
|
+
"...#{name}"
|
15
|
+
}
|
16
|
+
return str, fragments
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :node
|
20
|
+
|
21
|
+
attr_reader :fragments
|
22
|
+
|
23
|
+
attr_reader :type
|
24
|
+
|
25
|
+
def initialize(node, fragments)
|
26
|
+
@node = node
|
27
|
+
@fragments = fragments
|
28
|
+
@type = node.query_result_class(shadow: fragments)
|
29
|
+
end
|
30
|
+
|
31
|
+
def new(*args)
|
32
|
+
type.new(*args)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql/client/node"
|
3
|
+
require "graphql/language/nodes/deep_freeze_ext"
|
4
|
+
require "graphql/language/nodes/inject_selection_ext"
|
5
|
+
require "graphql/language/nodes/replace_fragment_spread_ext"
|
6
|
+
require "graphql/language/nodes/validate_ext"
|
7
|
+
|
8
|
+
module GraphQL
|
9
|
+
module Client
|
10
|
+
class Query < Node
|
11
|
+
def self.parse(str, schema: GraphQL::Client.schema)
|
12
|
+
str = str.strip
|
13
|
+
str, fragments = scan_interpolated_fragments(str)
|
14
|
+
|
15
|
+
if str.start_with?("query")
|
16
|
+
doc = GraphQL.parse(str)
|
17
|
+
doc = doc.inject_selection(GraphQL::Language::Nodes::Field.new(name: "__typename"))
|
18
|
+
doc = doc.replace_fragment_spread(fragments)
|
19
|
+
node = doc.definitions.first
|
20
|
+
else
|
21
|
+
raise ArgumentError, "expected string to be a query:\n#{str}"
|
22
|
+
end
|
23
|
+
|
24
|
+
query = new(node.deep_freeze, fragments.values).freeze
|
25
|
+
query.node.validate!(schema: schema) if schema
|
26
|
+
query
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "active_support/inflector"
|
3
|
+
|
4
|
+
module GraphQL
|
5
|
+
module Client
|
6
|
+
class QueryResult
|
7
|
+
def self.fields
|
8
|
+
@fields
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.define(fields: {})
|
12
|
+
Class.new(self) do
|
13
|
+
@fields = {}
|
14
|
+
|
15
|
+
fields.each do |field, type|
|
16
|
+
@fields[field.to_sym] = type
|
17
|
+
|
18
|
+
send :attr_reader, field
|
19
|
+
|
20
|
+
# Convert GraphQL camelcase to snake case: commitComments -> commit_comments
|
21
|
+
field_alias = ActiveSupport::Inflector.underscore(field)
|
22
|
+
if field != field_alias
|
23
|
+
send :alias_method, field_alias, field
|
24
|
+
end
|
25
|
+
|
26
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
27
|
+
def #{field_alias}?
|
28
|
+
#{field_alias} ? true : false
|
29
|
+
end
|
30
|
+
RUBY
|
31
|
+
end
|
32
|
+
|
33
|
+
assigns = fields.map do |field, type|
|
34
|
+
if type
|
35
|
+
<<-RUBY
|
36
|
+
@#{field} = self.class.fields[:#{field}].cast(@data["#{field}"])
|
37
|
+
RUBY
|
38
|
+
else
|
39
|
+
<<-RUBY
|
40
|
+
@#{field} = @data["#{field}"]
|
41
|
+
RUBY
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class_eval <<-RUBY, __FILE__, __LINE__
|
46
|
+
def initialize(data)
|
47
|
+
@data = data
|
48
|
+
#{assigns.join("\n")}
|
49
|
+
freeze
|
50
|
+
end
|
51
|
+
RUBY
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.inspect
|
56
|
+
"#<GraphQL::Client::QueryResult fields=#{@fields.keys.inspect}>"
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.cast(obj)
|
60
|
+
case obj
|
61
|
+
when Hash
|
62
|
+
new(obj)
|
63
|
+
when QueryResult
|
64
|
+
cast(obj.to_h)
|
65
|
+
when Array
|
66
|
+
obj.map { |e| cast(e) }
|
67
|
+
when NilClass
|
68
|
+
nil
|
69
|
+
else
|
70
|
+
raise TypeError, "#{obj.class}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.new(obj)
|
75
|
+
case obj
|
76
|
+
when Hash
|
77
|
+
super
|
78
|
+
else
|
79
|
+
cast(obj)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
attr_reader :data
|
84
|
+
alias_method :to_h, :data
|
85
|
+
|
86
|
+
def inspect
|
87
|
+
ivars = (self.class.fields.keys - [:__typename]).map { |sym| "#{sym}=#{instance_variable_get("@#{sym}").inspect}" }
|
88
|
+
buf = "#<GraphQL::Client::QueryResult"
|
89
|
+
buf << " " << @__typename if @__typename
|
90
|
+
buf << " " << ivars.join(" ") if ivars.any?
|
91
|
+
buf << ">"
|
92
|
+
buf
|
93
|
+
end
|
94
|
+
|
95
|
+
def method_missing(*args)
|
96
|
+
super
|
97
|
+
rescue NoMethodError => e
|
98
|
+
raise NoMethodError, "undefined method `#{e.name}' for #{inspect}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "graphql"
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Language
|
5
|
+
module Nodes
|
6
|
+
class AbstractNode
|
7
|
+
# Public: Freeze entire Node tree
|
8
|
+
#
|
9
|
+
# Returns self Node.
|
10
|
+
def deep_freeze
|
11
|
+
self.class.child_attributes.each do |attr_name|
|
12
|
+
public_send(attr_name).freeze.each do |node|
|
13
|
+
node.deep_freeze
|
14
|
+
end
|
15
|
+
end
|
16
|
+
freeze
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql/language/nodes/selection_ext"
|
3
|
+
|
4
|
+
module GraphQL
|
5
|
+
module Language
|
6
|
+
module Nodes
|
7
|
+
module Selections
|
8
|
+
def inject_selection(*selections)
|
9
|
+
other = self.dup
|
10
|
+
other.selections = selections + self.selections.map do |selection|
|
11
|
+
case selection
|
12
|
+
when Selections
|
13
|
+
selection.inject_selection(*selections)
|
14
|
+
else
|
15
|
+
selection
|
16
|
+
end
|
17
|
+
end
|
18
|
+
other
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Document < AbstractNode
|
23
|
+
def inject_selection(*args)
|
24
|
+
other = self.dup
|
25
|
+
other.definitions = self.definitions.map do |definition|
|
26
|
+
case definition
|
27
|
+
when Selections
|
28
|
+
definition.inject_selection(*args)
|
29
|
+
else
|
30
|
+
definition
|
31
|
+
end
|
32
|
+
end
|
33
|
+
other
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class Field < AbstractNode
|
38
|
+
def inject_selection(*selections)
|
39
|
+
self.selections.any? ? super : self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql/language/nodes/selection_ext"
|
3
|
+
require "graphql/client/query_result"
|
4
|
+
require "set"
|
5
|
+
|
6
|
+
module GraphQL
|
7
|
+
module Language
|
8
|
+
module Nodes
|
9
|
+
module Selections
|
10
|
+
# Public: Get GraphQL::QueryResult class for result of query.
|
11
|
+
#
|
12
|
+
# Returns subclass of QueryResult or nil.
|
13
|
+
def query_result_class(**kargs)
|
14
|
+
GraphQL::Client::QueryResult.define(fields: selections_query_result_classes(**kargs))
|
15
|
+
end
|
16
|
+
|
17
|
+
def selection_query_result_classes(**kargs)
|
18
|
+
selections_query_result_classes(**kargs)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Internal: Gather QueryResult classes for each selection.
|
22
|
+
#
|
23
|
+
# Returns a Hash[String => (QueryResult|nil)].
|
24
|
+
def selections_query_result_classes(shadow: Set.new, **kargs)
|
25
|
+
self.selections.inject({}) do |h, selection|
|
26
|
+
case selection
|
27
|
+
when Selection
|
28
|
+
if shadow.include?(selection)
|
29
|
+
{}
|
30
|
+
else
|
31
|
+
h.merge!(selection.selection_query_result_classes(shadow: shadow, **kargs))
|
32
|
+
end
|
33
|
+
else
|
34
|
+
raise TypeError, "expected selection to be of type Selection, but was #{selection.class}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class Field < AbstractNode
|
41
|
+
# Public: Get GraphQL::QueryResult class for result of query.
|
42
|
+
#
|
43
|
+
# Returns subclass of QueryResult or nil.
|
44
|
+
def query_result_class(**kargs)
|
45
|
+
if self.selections.any?
|
46
|
+
super
|
47
|
+
else
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def selection_query_result_classes(**kargs)
|
53
|
+
name = self.alias || self.name
|
54
|
+
{ name => query_result_class(**kargs) }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
class FragmentSpread < AbstractNode
|
59
|
+
def selection_query_result_classes(fragments: {}, shadow: Set.new, **kargs)
|
60
|
+
unless fragment = fragments[name.to_sym]
|
61
|
+
raise ArgumentError, "missing fragment '#{name}'"
|
62
|
+
end
|
63
|
+
return {} if shadow.include?(fragment)
|
64
|
+
fragment.selection_query_result_classes(fragments: fragments, shadow: shadow, **kargs)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql/language/nodes/selection_ext"
|
3
|
+
|
4
|
+
module GraphQL
|
5
|
+
module Language
|
6
|
+
module Nodes
|
7
|
+
module Selections
|
8
|
+
def replace_fragment_spread(fragments)
|
9
|
+
other = self.dup
|
10
|
+
other.selections = self.selections.map do |selection|
|
11
|
+
case selection
|
12
|
+
when FragmentSpread
|
13
|
+
if fragment = fragments[selection.name.to_sym]
|
14
|
+
InlineFragment.new(type: fragment.type, directives: fragment.directives, selections: fragment.selections)
|
15
|
+
else
|
16
|
+
selection
|
17
|
+
end
|
18
|
+
when Selections
|
19
|
+
selection.replace_fragment_spread(fragments)
|
20
|
+
else
|
21
|
+
selection
|
22
|
+
end
|
23
|
+
end
|
24
|
+
other
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Document < AbstractNode
|
29
|
+
def replace_fragment_spread(fragments)
|
30
|
+
other = self.dup
|
31
|
+
other.definitions = self.definitions.map do |definition|
|
32
|
+
case definition
|
33
|
+
when Selections
|
34
|
+
definition.replace_fragment_spread(fragments)
|
35
|
+
else
|
36
|
+
definition
|
37
|
+
end
|
38
|
+
end
|
39
|
+
other
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "graphql"
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Language
|
5
|
+
module Nodes
|
6
|
+
# Public: Define shared trait for Nodes that have a "selections" collection.
|
7
|
+
module Selections
|
8
|
+
end
|
9
|
+
|
10
|
+
# Public: Define shared trait for Nodes that may be in a "selections" collection.
|
11
|
+
module Selection
|
12
|
+
end
|
13
|
+
|
14
|
+
class Field < AbstractNode
|
15
|
+
include Selection
|
16
|
+
include Selections
|
17
|
+
end
|
18
|
+
|
19
|
+
class FragmentDefinition < AbstractNode
|
20
|
+
include Selections
|
21
|
+
end
|
22
|
+
|
23
|
+
class FragmentSpread < AbstractNode
|
24
|
+
include Selection
|
25
|
+
end
|
26
|
+
|
27
|
+
class InlineFragment < AbstractNode
|
28
|
+
include Selection
|
29
|
+
include Selections
|
30
|
+
end
|
31
|
+
|
32
|
+
class OperationDefinition < AbstractNode
|
33
|
+
include Selections
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require "graphql"
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class ValidationError < GraphQL::ExecutionError
|
5
|
+
end
|
6
|
+
|
7
|
+
module Language
|
8
|
+
module Nodes
|
9
|
+
class Document < AbstractNode
|
10
|
+
def validate!(schema:, rules: StaticValidation::ALL_RULES)
|
11
|
+
validator = StaticValidation::Validator.new(schema: schema, rules: rules)
|
12
|
+
query = Query.new(schema, document: self)
|
13
|
+
|
14
|
+
validator.validate(query).fetch(:errors).each do |error|
|
15
|
+
raise ValidationError, error["message"]
|
16
|
+
end
|
17
|
+
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class FragmentDefinition < AbstractNode
|
23
|
+
def validate!(schema:, **kargs)
|
24
|
+
document = Document.new(definitions: [self])
|
25
|
+
rules = StaticValidation::ALL_RULES - [StaticValidation::FragmentsAreUsed]
|
26
|
+
document.validate!(schema: schema, rules: rules, **kargs)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class OperationDefinition < AbstractNode
|
31
|
+
def validate!(schema:, **kargs)
|
32
|
+
document = Document.new(definitions: [self])
|
33
|
+
document.validate!(schema: schema, **kargs)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class InlineFragment < AbstractNode
|
38
|
+
def validate!(schema:, **kargs)
|
39
|
+
fragment = FragmentDefinition.new(name: "FooFragment", type: self.type, directives: self.directives, selections: self.selections)
|
40
|
+
fragment.validate!(schema: schema, **kargs)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "graphql"
|
2
|
+
require "graphql/language/nodes/deep_freeze_ext"
|
3
|
+
|
4
|
+
module GraphQL
|
5
|
+
module Relay
|
6
|
+
NODE_QUERY = GraphQL.parse(<<-'GRAPHQL').definitions.first.deep_freeze
|
7
|
+
query($id: ID!) {
|
8
|
+
node(id: $id) {
|
9
|
+
...NodeFragment
|
10
|
+
}
|
11
|
+
}
|
12
|
+
GRAPHQL
|
13
|
+
|
14
|
+
def self.NodeQuery(fragment)
|
15
|
+
fragment = GraphQL::Language::Nodes::FragmentDefinition.new(name: "NodeFragment", type: fragment.type, selections: fragment.selections)
|
16
|
+
GraphQL::Language::Nodes::Document.new(definitions: [NODE_QUERY, fragment])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: graphql-client
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- GitHub
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-08-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: graphql
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.17'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.17'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '5.9'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '5.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '11.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '11.2'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files: []
|
74
|
+
files:
|
75
|
+
- LICENSE
|
76
|
+
- lib/graphql/client.rb
|
77
|
+
- lib/graphql/client/document.rb
|
78
|
+
- lib/graphql/client/fragment.rb
|
79
|
+
- lib/graphql/client/node.rb
|
80
|
+
- lib/graphql/client/query.rb
|
81
|
+
- lib/graphql/client/query_result.rb
|
82
|
+
- lib/graphql/language/nodes/deep_freeze_ext.rb
|
83
|
+
- lib/graphql/language/nodes/inject_selection_ext.rb
|
84
|
+
- lib/graphql/language/nodes/query_result_class_ext.rb
|
85
|
+
- lib/graphql/language/nodes/replace_fragment_spread_ext.rb
|
86
|
+
- lib/graphql/language/nodes/selection_ext.rb
|
87
|
+
- lib/graphql/language/nodes/validate_ext.rb
|
88
|
+
- lib/graphql/relay/node_query.rb
|
89
|
+
homepage:
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 2.3.0
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.5.1
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: "???"
|
113
|
+
test_files: []
|
114
|
+
has_rdoc:
|