graphql-client 0.0.2
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 +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:
|