gql 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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
- class_attribute :field_classes
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
- __target.send(method_name).to_s
14
+ target.send(method_name).to_s
16
15
  end
17
16
  end
18
17
 
19
- def call(name, options = {}, &block)
20
- result_class = options[:returns]
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
- raise Errors::InvalidNodeClass.new(field_class, Fields::Connection) unless field_class <= Fields::Connection
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
- call_class = Class.new(Call)
39
- call_class.const_set :Function, function
40
- call_class.const_set :Result, result_class
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
- def fields(&block)
47
- instance_eval &block
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, base_class: nil, node_class: nil, connection_class: nil)
51
- classes = names.reduce({}) do |result, name|
52
- base_class ||= Field
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
- raise Errors::InvalidNodeClass.new(base_class, Field) unless base_class <= Field
39
+ unless field_type_class <= Field
40
+ raise Errors::InvalidNodeClass.new(field_type_class, Field)
41
+ end
55
42
 
56
- field_class = Class.new(base_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, *args, &block)
70
- if base_class = Schema.fields[method]
71
- options = args.extract_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(*args, options.merge(base_class: base_class))
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::UndefinedType, method
59
+ raise Errors::UndefinedFieldType, method
79
60
  end
80
61
  end
81
62
 
82
- attr_reader :__target, :__context
63
+ attr_reader :ast_node, :target, :variables, :context
83
64
 
84
65
  def initialize(ast_node, target, variables, context)
85
- @ast_node, @__target = ast_node, target
86
- @variables, @__context = variables, context
66
+ @ast_node, @target = ast_node, target
67
+ @variables, @context = variables, context
87
68
  end
88
69
 
89
- def __value
90
- if ast_call = @ast_node.call
91
- call_class = self.class.call_classes[ast_call.name]
92
-
93
- raise Errors::UndefinedCall.new(ast_call.name, self.class.superclass) if call_class.nil?
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
- __raw_value
76
+ raw_value
123
77
  end
124
78
  end
125
79
 
126
- def __raw_value
127
- nil
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 method_missing(method, *args, &block)
131
- if __target.respond_to? method
132
- __target.public_send method, *args, &block
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
- super
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
- rescue NoMethodError => exc
137
- raise Errors::UndefinedField.new(method, self.class)
119
+ end
120
+
121
+ def raw_value
122
+ nil
138
123
  end
139
124
  end
140
125
  end