graphql-client 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c735cc6d34d7372e777934b15cbf86540cf994a
4
- data.tar.gz: 329f6769cf02065e726dd26e9006cb1143f3f8df
3
+ metadata.gz: 3207be7a370ae7995dd3355381f4dfc6d839e100
4
+ data.tar.gz: 80b877dd6c13310c10217a6a65a375728a6a9cb6
5
5
  SHA512:
6
- metadata.gz: fd69bd130b837dff72de557d1b0c51e7a4f0b499af231af00d8b2df65a638116021f45660be83c8695aa27bbf808741db5317d4791e68f6bf0db9f059dbf9273
7
- data.tar.gz: 20d75c1fa9d08f56a096328cf499e163eea4b7d13bfc9767f8fa743004e87c9a611d32d6533cbc0f28d72770b41635eff526549baf81bd52cc319ed0437ccb4c
6
+ metadata.gz: 036b98757f630e799ca5f8b111aad802d77f2723bc0cc73dae113c24687189cbfd6ad440224a6ba952902dc401a57a6f7cfa33523c6b764aa83f37e526a3452f
7
+ data.tar.gz: db865264342c1e9dc7b42d07fbe4ae5d01319514ca884c92bee4aff7e3980436e5fad4a851768f1c97bd371d1ae3a0b7c6460e3c0b895a48bf81dd2d0e3153d8
@@ -110,32 +110,37 @@ module GraphQL
110
110
 
111
111
  definition_dependencies = Set.new
112
112
 
113
- str = str.gsub(/\.\.\.([a-zA-Z0-9_]+(::[a-zA-Z0-9_]+)+)/) do
113
+ str = str.gsub(/\.\.\.([a-zA-Z0-9_]+(::[a-zA-Z0-9_]+)*)/) do
114
114
  match = Regexp.last_match
115
115
  const_name = match[1]
116
- begin
117
- fragment = ActiveSupport::Inflector.constantize(const_name)
118
- rescue NameError
119
- fragment = nil
120
- end
121
116
 
122
- case fragment
123
- when FragmentDefinition
124
- definition_dependencies.merge(fragment.document.definitions)
125
- "...#{fragment.definition_name}"
117
+ if str.match(/fragment\s*#{const_name}/)
118
+ match[0]
126
119
  else
127
- if fragment
128
- message = "expected #{const_name} to be a #{FragmentDefinition}, but was a #{fragment.class}."
129
- if fragment.is_a?(Module) && fragment.constants.any?
130
- message += " Did you mean #{fragment}::#{fragment.constants.first}?"
131
- end
132
- else
133
- message = "uninitialized constant #{const_name}"
120
+ begin
121
+ fragment = ActiveSupport::Inflector.constantize(const_name)
122
+ rescue NameError
123
+ fragment = nil
134
124
  end
135
125
 
136
- error = ValidationError.new(message)
137
- error.set_backtrace(["#{filename}:#{lineno + match.pre_match.count("\n") + 1}"] + caller)
138
- raise error
126
+ case fragment
127
+ when FragmentDefinition
128
+ definition_dependencies.merge(fragment.document.definitions)
129
+ "...#{fragment.definition_name}"
130
+ else
131
+ if fragment
132
+ message = "expected #{const_name} to be a #{FragmentDefinition}, but was a #{fragment.class}."
133
+ if fragment.is_a?(Module) && fragment.constants.any?
134
+ message += " Did you mean #{fragment}::#{fragment.constants.first}?"
135
+ end
136
+ else
137
+ message = "uninitialized constant #{const_name}"
138
+ end
139
+
140
+ error = ValidationError.new(message)
141
+ error.set_backtrace(["#{filename}:#{lineno + match.pre_match.count("\n") + 1}"] + caller)
142
+ raise error
143
+ end
139
144
  end
140
145
  end
141
146
 
@@ -76,7 +76,7 @@ module GraphQL
76
76
 
77
77
  def type
78
78
  # TODO: Fix type indirection
79
- @type ||= GraphQL::Client::QueryResult.wrap(self, definition_node, name: "#{name}.type")
79
+ @type ||= GraphQL::Client::QueryResult.wrap(self, definition_node, document_types[definition_node], name: "#{name}.type")
80
80
  end
81
81
  end
82
82
  end
@@ -31,6 +31,9 @@ module GraphQL
31
31
  visitor[GraphQL::Language::Nodes::FragmentDefinition] << ->(node, _parent) do
32
32
  fields[node] = type_stack.object_types.last
33
33
  end
34
+ visitor[GraphQL::Language::Nodes::InlineFragment] << ->(node, _parent) do
35
+ fields[node] = type_stack.object_types.last
36
+ end
34
37
  visitor[GraphQL::Language::Nodes::Field] << ->(node, _parent) do
35
38
  fields[node] = type_stack.field_definitions.last.type
36
39
  end
@@ -22,41 +22,114 @@ module GraphQL
22
22
  # Internal: Get QueryResult class for result of query.
23
23
  #
24
24
  # Returns subclass of QueryResult or nil.
25
- def self.wrap(source_definition, node, name: nil)
26
- fields = {}
25
+ def self.wrap(source_definition, node, type, name: nil)
26
+ case type
27
+ when GraphQL::NonNullType
28
+ NonNullWrapper.new(wrap(source_definition, node, type.of_type, name: name))
29
+ when GraphQL::ListType
30
+ ListWrapper.new(wrap(source_definition, node, type.of_type, name: name))
31
+ when GraphQL::ScalarType
32
+ ScalarWrapper.new(type)
33
+ when GraphQL::ObjectType, GraphQL::InterfaceType, GraphQL::UnionType
34
+ fields = {}
35
+
36
+ node.selections.each do |selection|
37
+ case selection
38
+ when Language::Nodes::FragmentSpread
39
+ nil
40
+ when Language::Nodes::Field
41
+ field_name = selection.alias || selection.name
42
+ selection_type = source_definition.document_types[selection]
43
+ selection_type = GraphQL::STRING_TYPE if field_name == "__typename"
44
+ field_klass = wrap(source_definition, selection, selection_type, name: "#{name}[:#{field_name}]")
45
+ fields[field_name] ? fields[field_name] |= field_klass : fields[field_name] = field_klass
46
+ when Language::Nodes::InlineFragment
47
+ selection_type = source_definition.document_types[selection]
48
+ wrap(source_definition, selection, selection_type, name: name).fields.each do |fragment_name, klass|
49
+ fields[fragment_name.to_s] ? fields[fragment_name.to_s] |= klass : fields[fragment_name.to_s] = klass
50
+ end
51
+ end
52
+ end
27
53
 
28
- node.selections.each do |selection|
29
- case selection
30
- when Language::Nodes::FragmentSpread
54
+ define(name: name, type: type, source_definition: source_definition, source_node: node, fields: fields)
55
+ else
56
+ raise TypeError, "unexpected #{type.class}"
57
+ end
58
+ end
59
+
60
+ class ListWrapper
61
+ def initialize(type)
62
+ @of_klass = type
63
+ end
64
+
65
+ def cast(value, errors)
66
+ case value
67
+ when Array
68
+ List.new(value.each_with_index.map { |e, idx|
69
+ @of_klass.cast(e, errors.filter_by_path(idx))
70
+ }, errors)
71
+ else
72
+ raise ArgumentError, "expected list value to be an Array, but was #{value.class}"
73
+ end
74
+ end
75
+
76
+ def |(other)
77
+ if self.class == other.class
78
+ self.of_klass | other.of_klass
79
+ else
80
+ raise TypeError, "expected other to be a #{self.class}"
81
+ end
82
+ end
83
+ end
84
+
85
+ class NonNullWrapper
86
+ attr_reader :of_klass
87
+
88
+ def initialize(type)
89
+ @of_klass = type
90
+ end
91
+
92
+ def cast(value, errors)
93
+ case value
94
+ when NilClass
95
+ # TODO
96
+ # raise ArgumentError, "expected non-nullable value to be present"
31
97
  nil
32
- when Language::Nodes::Field
33
- field_name = selection.alias || selection.name
34
- field_klass = nil
35
- if selection.selections.any?
36
- field_klass = wrap(source_definition, selection, name: "#{name}[:#{field_name}]")
37
- end
38
- fields[field_name] ? fields[field_name] |= field_klass : fields[field_name] = field_klass
39
- when Language::Nodes::InlineFragment
40
- wrap(source_definition, selection, name: name).fields.each do |fragment_name, klass|
41
- fields[fragment_name.to_s] ? fields[fragment_name.to_s] |= klass : fields[fragment_name.to_s] = klass
42
- end
98
+ else
99
+ @of_klass.cast(value, errors)
43
100
  end
44
101
  end
45
102
 
46
- define(name: name, source_definition: source_definition, source_node: node, fields: fields)
103
+ def |(other)
104
+ if self.class == other.class
105
+ self.of_klass | other.of_klass
106
+ else
107
+ raise TypeError, "expected other to be a #{self.class}"
108
+ end
109
+ end
47
110
  end
48
111
 
49
112
  # :nodoc:
50
- class Scalar
113
+ class ScalarWrapper
51
114
  def initialize(type)
52
115
  @type = type
53
116
  end
54
117
 
55
118
  def cast(value, _errors = nil)
56
119
  if value.is_a? Array
57
- value.map { |item| @type.coerce_input(item) }
120
+ value.map { |item|
121
+ if @type.respond_to?(:coerce_isolated_input)
122
+ @type.coerce_isolated_input(item)
123
+ else
124
+ @type.coerce_input(item)
125
+ end
126
+ }
58
127
  else
59
- @type.coerce_input(value)
128
+ if @type.respond_to?(:coerce_isolated_input)
129
+ @type.coerce_isolated_input(value)
130
+ else
131
+ @type.coerce_input(value)
132
+ end
60
133
  end
61
134
  end
62
135
 
@@ -67,10 +140,7 @@ module GraphQL
67
140
  end
68
141
 
69
142
  # Internal
70
- def self.define(name:, source_definition:, source_node:, fields: {})
71
- type = source_definition.document_types[source_node]
72
- type = type.unwrap if type
73
-
143
+ def self.define(name:, type:, source_definition:, source_node:, fields: {})
74
144
  Class.new(self) do
75
145
  @name = name
76
146
  @type = type
@@ -81,13 +151,6 @@ module GraphQL
81
151
  field_readers = Set.new
82
152
 
83
153
  fields.each do |field, klass|
84
- if @type.is_a?(GraphQL::ObjectType)
85
- field_node = @type.get_field(field.to_s)
86
- if field_node && field_node.type.unwrap.is_a?(GraphQL::ScalarType)
87
- klass = Scalar.new(field_node.type.unwrap)
88
- end
89
- end
90
-
91
154
  @fields[field.to_sym] = klass
92
155
 
93
156
  send :attr_reader, field
@@ -107,18 +170,12 @@ module GraphQL
107
170
  end
108
171
 
109
172
  assigns = @fields.map do |field, klass|
110
- if klass
111
- <<-RUBY
112
- @#{field} = self.class.fields[:#{field}].cast(@data["#{field}"], @errors.filter_by_path("#{field}"))
113
- RUBY
114
- else
115
- <<-RUBY
116
- @#{field} = @data["#{field}"]
117
- RUBY
118
- end
173
+ <<-RUBY
174
+ @#{field} = self.class.fields[:#{field}].cast(@data["#{field}"], @errors.filter_by_path("#{field}"))
175
+ RUBY
119
176
  end
120
177
 
121
- if @type && @type.is_a?(GraphQL::ObjectType)
178
+ if @type.is_a?(GraphQL::ObjectType)
122
179
  assigns.unshift "@__typename = self.class.type.name"
123
180
  end
124
181
 
@@ -177,12 +234,10 @@ module GraphQL
177
234
  raise TypeError, "#{self.source_definition.name} is not included in #{obj.class.source_definition.name}"
178
235
  end
179
236
  cast(obj.to_h, obj.errors)
180
- when Array
181
- List.new(obj.each_with_index.map { |e, idx| cast(e, errors.filter_by_path(idx)) }, errors)
182
237
  when NilClass
183
238
  nil
184
239
  else
185
- raise TypeError, obj.class.to_s
240
+ raise TypeError, "expected #{obj.inspect} to be a Hash"
186
241
  end
187
242
  end
188
243
 
@@ -219,7 +274,7 @@ module GraphQL
219
274
  end
220
275
  end
221
276
  # TODO: Picking first source node seems error prone
222
- define(name: self.name, source_definition: source_definition, source_node: source_node, fields: new_fields)
277
+ define(name: self.name, type: self.type, source_definition: source_definition, source_node: source_node, fields: new_fields)
223
278
  end
224
279
 
225
280
  # Public: Return errors associated with data.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-04 00:00:00.000000000 Z
11
+ date: 2017-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport