gql 0.0.2 → 0.0.3
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 +4 -4
- data/README.md +60 -60
- data/lib/gql/call.rb +46 -7
- data/lib/gql/config.rb +23 -0
- data/lib/gql/connection.rb +22 -22
- data/lib/gql/errors.rb +15 -11
- data/lib/gql/executor.rb +8 -7
- data/lib/gql/field.rb +26 -2
- data/lib/gql/fields/connection.rb +26 -12
- data/lib/gql/fields/object.rb +28 -8
- data/lib/gql/node.rb +75 -90
- data/lib/gql/parser.rb +214 -284
- data/lib/gql/parser.y +40 -110
- data/lib/gql/version.rb +1 -1
- data/lib/gql.rb +33 -16
- metadata +3 -3
- data/lib/gql/schema.rb +0 -21
data/lib/gql/node.rb
CHANGED
@@ -3,138 +3,123 @@ require 'active_support/core_ext/string/inflections'
|
|
3
3
|
|
4
4
|
module GQL
|
5
5
|
class Node
|
6
|
-
class_attribute :call_classes
|
7
|
-
self.call_classes = {}
|
6
|
+
class_attribute :call_classes, :field_classes, instance_accessor: false, instance_predicate: false
|
8
7
|
|
9
|
-
|
8
|
+
self.call_classes = {}
|
10
9
|
self.field_classes = {}
|
11
10
|
|
12
11
|
class << self
|
13
12
|
def cursor(method_name)
|
14
13
|
define_method :cursor do
|
15
|
-
|
14
|
+
target.send(method_name).to_s
|
16
15
|
end
|
17
16
|
end
|
18
17
|
|
19
|
-
def call(
|
20
|
-
|
21
|
-
function = block || lambda { |*args| target.public_send(name, *args) }
|
22
|
-
|
23
|
-
if result_class.is_a? Array
|
24
|
-
result_class.unshift Connection if result_class.size == 1
|
25
|
-
result_class.unshift Fields::Connection if result_class.size == 2
|
26
|
-
|
27
|
-
field_class, connection_class, node_class = result_class
|
18
|
+
def call(*names, &block)
|
19
|
+
names_with_result_class = names.extract_options!
|
28
20
|
|
29
|
-
|
30
|
-
|
31
|
-
result_class = Class.new(field_class)
|
32
|
-
result_class.const_set :NODE_CLASS, node_class
|
33
|
-
result_class.const_set :CONNECTION_CLASS, connection_class
|
34
|
-
else
|
35
|
-
raise Errors::InvalidNodeClass.new(result_class, Node) unless result_class.nil? || result_class < Node
|
21
|
+
names.each do |name|
|
22
|
+
names_with_result_class[name] = nil
|
36
23
|
end
|
37
24
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
self.const_set "#{name.to_s.camelize}Call", call_class
|
43
|
-
self.call_classes = call_classes.merge(name => call_class)
|
44
|
-
end
|
25
|
+
names_with_result_class.each do |name, result_class|
|
26
|
+
method = block || lambda { |*args| target.public_send(name, *args) }
|
27
|
+
call_class = Call.build_class(result_class, method)
|
45
28
|
|
46
|
-
|
47
|
-
|
29
|
+
self.const_set "#{name.to_s.camelize}Call", call_class
|
30
|
+
self.call_classes = call_classes.merge(name => call_class)
|
31
|
+
end
|
48
32
|
end
|
49
33
|
|
50
|
-
def field(*names,
|
51
|
-
|
52
|
-
|
34
|
+
def field(*names, field_type_class: nil, connection_class: nil, node_class: nil, &block)
|
35
|
+
names.each do |name|
|
36
|
+
method = block || lambda { target.public_send(name) }
|
37
|
+
field_type_class ||= Field
|
53
38
|
|
54
|
-
|
39
|
+
unless field_type_class <= Field
|
40
|
+
raise Errors::InvalidNodeClass.new(field_type_class, Field)
|
41
|
+
end
|
55
42
|
|
56
|
-
field_class =
|
57
|
-
|
58
|
-
field_class.const_set :NODE_CLASS, node_class
|
59
|
-
field_class.const_set :CONNECTION_CLASS, connection_class
|
43
|
+
field_class = field_type_class.build_class(method, connection_class, node_class)
|
60
44
|
|
61
45
|
self.const_set "#{name.to_s.camelize}Field", field_class
|
62
|
-
|
63
|
-
result.merge name => field_class
|
46
|
+
self.field_classes = field_classes.merge(name => field_class)
|
64
47
|
end
|
65
|
-
|
66
|
-
self.field_classes = field_classes.merge(classes)
|
67
48
|
end
|
68
49
|
|
69
|
-
def method_missing(method, *
|
70
|
-
if
|
71
|
-
options =
|
50
|
+
def method_missing(method, *names, &block)
|
51
|
+
if field_type_class = GQL.field_types[method]
|
52
|
+
options = names.extract_options!
|
72
53
|
|
73
|
-
field(*
|
54
|
+
field(*names, options.merge(field_type_class: field_type_class), &block)
|
74
55
|
else
|
75
56
|
super
|
76
57
|
end
|
77
58
|
rescue NoMethodError => exc
|
78
|
-
raise Errors::
|
59
|
+
raise Errors::UndefinedFieldType, method
|
79
60
|
end
|
80
61
|
end
|
81
62
|
|
82
|
-
attr_reader :
|
63
|
+
attr_reader :ast_node, :target, :variables, :context
|
83
64
|
|
84
65
|
def initialize(ast_node, target, variables, context)
|
85
|
-
@ast_node, @
|
86
|
-
@variables, @
|
66
|
+
@ast_node, @target = ast_node, target
|
67
|
+
@variables, @context = variables, context
|
87
68
|
end
|
88
69
|
|
89
|
-
def
|
90
|
-
if ast_call =
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
call = call_class.new(self, ast_call, __target, @variables, __context)
|
96
|
-
call.execute
|
97
|
-
elsif ast_fields = @ast_node.fields
|
98
|
-
ast_fields.reduce({}) do |memo, ast_field|
|
99
|
-
key = ast_field.alias_name || ast_field.name
|
100
|
-
|
101
|
-
val =
|
102
|
-
case key
|
103
|
-
when :node
|
104
|
-
field = self.class.new(ast_field, __target, @variables, __context)
|
105
|
-
field.__value
|
106
|
-
when :cursor
|
107
|
-
cursor
|
108
|
-
else
|
109
|
-
target = public_send(ast_field.name)
|
110
|
-
field_class = self.class.field_classes[ast_field.name]
|
111
|
-
|
112
|
-
raise Errors::UndefinedField.new(ast_field.name, self.class) if field_class.nil?
|
113
|
-
raise Errors::InvalidNodeClass.new(field_class.superclass, Field) unless field_class <= Field
|
114
|
-
|
115
|
-
field = field_class.new(ast_field, target, @variables, __context)
|
116
|
-
field.__value
|
117
|
-
end
|
118
|
-
|
119
|
-
memo.merge key => val
|
120
|
-
end
|
70
|
+
def value
|
71
|
+
if ast_call = ast_node.call
|
72
|
+
value_of_call ast_call
|
73
|
+
elsif ast_fields = ast_node.fields
|
74
|
+
value_of_fields ast_fields
|
121
75
|
else
|
122
|
-
|
76
|
+
raw_value
|
123
77
|
end
|
124
78
|
end
|
125
79
|
|
126
|
-
def
|
127
|
-
|
80
|
+
def value_of_call(ast_call)
|
81
|
+
call_class = self.class.call_classes[ast_call.name]
|
82
|
+
|
83
|
+
if call_class.nil?
|
84
|
+
raise Errors::UndefinedCall.new(ast_call.name, self.class.superclass)
|
85
|
+
end
|
86
|
+
|
87
|
+
call = call_class.new(self, ast_call, target, variables, context)
|
88
|
+
call.execute
|
89
|
+
end
|
90
|
+
|
91
|
+
def value_of_fields(ast_fields)
|
92
|
+
ast_fields.reduce({}) do |memo, ast_field|
|
93
|
+
key = ast_field.alias_name || ast_field.name
|
94
|
+
|
95
|
+
memo.merge key => value_of_field(ast_field)
|
96
|
+
end
|
128
97
|
end
|
129
98
|
|
130
|
-
def
|
131
|
-
|
132
|
-
|
99
|
+
def value_of_field(ast_field)
|
100
|
+
case ast_field.name
|
101
|
+
when :node
|
102
|
+
field = self.class.new(ast_field, target, variables, context)
|
103
|
+
field.value
|
104
|
+
when :cursor
|
105
|
+
cursor
|
133
106
|
else
|
134
|
-
|
107
|
+
method = Field::Method.new(target, context)
|
108
|
+
field_class = self.class.field_classes[ast_field.name]
|
109
|
+
|
110
|
+
if field_class.nil?
|
111
|
+
raise Errors::UndefinedField.new(ast_field.name, self.class)
|
112
|
+
end
|
113
|
+
|
114
|
+
next_target = method.execute(field_class.method)
|
115
|
+
|
116
|
+
field = field_class.new(ast_field, next_target, variables, context)
|
117
|
+
field.value
|
135
118
|
end
|
136
|
-
|
137
|
-
|
119
|
+
end
|
120
|
+
|
121
|
+
def raw_value
|
122
|
+
nil
|
138
123
|
end
|
139
124
|
end
|
140
125
|
end
|