graphql 0.18.0 → 0.18.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 02de1641b3342ae2dfb6688305141f876b853641
4
- data.tar.gz: bca7585eba3aae30e0804b1f6a475df2cf390adc
3
+ metadata.gz: 4320e19052975ac0ba38fac054d7d56d044657e1
4
+ data.tar.gz: 2045f552c2acd454a57f4c0ec80f9547f7c6b875
5
5
  SHA512:
6
- metadata.gz: f2fd6a0147a92875211ff050335d0c476e8119754bc47738f05237e48be231ffb221c3743b70bf3df2ed654b08bffec4f760b9279a63331624046af295d22218
7
- data.tar.gz: 5b27edb6d609026598ed2f91a17dd34ec622d666c8dfc1cb95f06bc55aa6152363b690960e790b794ffb25d5b1d72ddf9dd7aa7f163ad6a680a5528697ed0aba
6
+ metadata.gz: 0db74452c453b954039a685aaa25ad875325de13c0f7eb152dd4ff09a139048b73c83ce637cc84b7824ffb4311ce1de0041b671444a4a208131bb49ed71c6dc9
7
+ data.tar.gz: bf2b4faf5545b8d13ee5ab3b370e9ea4ab4954e40f458a87b2551bf666e97e4d27270b618b2644b1cdc56f48d7681b48edf3ac74171ce9cc37d113a6bff5d7d6
@@ -3,8 +3,26 @@ require "graphql/define/assign_connection"
3
3
  require "graphql/define/assign_enum_value"
4
4
  require "graphql/define/assign_global_id_field"
5
5
  require "graphql/define/assign_object_field"
6
- require "graphql/define/assignment_dictionary"
7
6
  require "graphql/define/defined_object_proxy"
8
7
  require "graphql/define/instance_definable"
9
8
  require "graphql/define/non_null_with_bang"
10
9
  require "graphql/define/type_definer"
10
+
11
+ module GraphQL
12
+ module Define
13
+ # A helper for definitions that store their value in `#metadata`.
14
+ #
15
+ # @example Storing application classes with GraphQL types
16
+ # # Make a custom definition
17
+ # GraphQL::ObjectType.accepts_definitions(resolves_to_class_names: GraphQL::Define.assign_metadata_key(:resolves_to_class_names))
18
+ #
19
+ # # After definition, read the key from metadata
20
+ # PostType.metadata[:resolves_to_class_names] # => [...]
21
+ #
22
+ # @param [Object] the key to assign in metadata
23
+ # @return [#call(defn, value)] an assignment for `.accepts_definitions` which writes `key` to `#metadata`
24
+ def self.assign_metadata_key(key)
25
+ GraphQL::Define::InstanceDefinable::AssignMetadataKey.new(key)
26
+ end
27
+ end
28
+ end
@@ -1,22 +1,36 @@
1
1
  module GraphQL
2
2
  module Define
3
- # This module provides the `.define { ... }` API for {GraphQL::BaseType}, {GraphQL::Field}, {GraphQL::Argument} and {GraphQL::Directive}.
3
+ # This module provides the `.define { ... }` API for
4
+ # {GraphQL::BaseType}, {GraphQL::Field} and others.
5
+ #
6
+ # Calling `.accepts_definitions(...)` creates:
7
+ #
8
+ # - a keyword to the `.define` method
9
+ # - a helper method in the `.define { ... }` block
10
+ #
11
+ # The `.define { ... }` block will be called lazily. To be sure it has been
12
+ # called, use the private method `#ensure_defined`. That will call the
13
+ # definition block if it hasn't been called already.
4
14
  #
5
15
  # The goals are:
16
+ #
6
17
  # - Minimal overhead in consuming classes
7
18
  # - Independence between consuming classes
8
19
  # - Extendable by third-party libraries without monkey-patching or other nastiness
9
20
  #
10
21
  # @example Make a class definable
11
22
  # class Car
12
- # attr_accessor :make, :model, :all_wheel_drive
13
- #
23
+ # attr_accessor :make, :model
14
24
  # accepts_definitions(
15
25
  # # These attrs will be defined with plain setters, `{attr}=`
16
26
  # :make, :model,
17
27
  # # This attr has a custom definition which applies the config to the target
18
28
  # doors: -> (car, doors_count) { doors_count.times { car.doors << Door.new } }
19
29
  # )
30
+ #
31
+ # def initialize
32
+ # @doors = []
33
+ # end
20
34
  # end
21
35
  #
22
36
  # # Create an instance with `.define`:
@@ -31,7 +45,7 @@ module GraphQL
31
45
  #
32
46
  # @example Extending the definition of a class
33
47
  # # Add some definitions:
34
- # Car.accepts_definitions(:all_wheel_drive)
48
+ # Car.accepts_definitions(all_wheel_drive: GraphQL::Define.assign_metadata_key(:all_wheel_drive))
35
49
  #
36
50
  # # Use it in a definition
37
51
  # subaru_baja = Car.define do
@@ -39,6 +53,9 @@ module GraphQL
39
53
  # all_wheel_drive true
40
54
  # end
41
55
  #
56
+ # # Access it from metadata
57
+ # subaru_baja.metadata[:all_wheel_drive] # => true
58
+ #
42
59
  module InstanceDefinable
43
60
  def self.included(base)
44
61
  base.extend(ClassMethods)
@@ -50,6 +67,14 @@ module GraphQL
50
67
  @definition_proc = defn_block
51
68
  end
52
69
 
70
+ # `metadata` can store arbitrary key-values with an object.
71
+ #
72
+ # @return [Hash<Object, Object>] Hash for user-defined storage
73
+ def metadata
74
+ ensure_defined
75
+ @metadata ||= {}
76
+ end
77
+
53
78
  private
54
79
 
55
80
  # Run the definition block if it hasn't been run yet.
@@ -91,7 +116,17 @@ module GraphQL
91
116
  # Each symbol in `accepts` will be assigned with `{key}=`.
92
117
  # The last entry in accepts may be a hash of name-proc pairs for custom definitions.
93
118
  def accepts_definitions(*accepts)
94
- @own_dictionary = own_dictionary.merge(AssignmentDictionary.create(*accepts))
119
+ new_assignments = if accepts.last.is_a?(Hash)
120
+ accepts.pop.dup
121
+ else
122
+ {}
123
+ end
124
+
125
+ accepts.each do |key|
126
+ new_assignments[key] = AssignAttribute.new(key)
127
+ end
128
+
129
+ @own_dictionary = own_dictionary.merge(new_assignments)
95
130
  end
96
131
 
97
132
  # Define a reader and writer for each of `attr_names` which
@@ -125,6 +160,26 @@ module GraphQL
125
160
  @own_dictionary ||= {}
126
161
  end
127
162
  end
163
+
164
+ class AssignMetadataKey
165
+ def initialize(key)
166
+ @key = key
167
+ end
168
+
169
+ def call(defn, value)
170
+ defn.metadata[@key] = value
171
+ end
172
+ end
173
+
174
+ class AssignAttribute
175
+ def initialize(attr_name)
176
+ @attr_assign_method = :"#{attr_name}="
177
+ end
178
+
179
+ def call(defn, value)
180
+ defn.public_send(@attr_assign_method, value)
181
+ end
182
+ end
128
183
  end
129
184
  end
130
185
  end
@@ -10,4 +10,5 @@ require 'graphql/relay/relation_connection'
10
10
  require 'graphql/relay/global_id_resolve'
11
11
  require 'graphql/relay/mutation'
12
12
  require 'graphql/relay/connection_field'
13
+ require 'graphql/relay/connection_resolve'
13
14
  require 'graphql/relay/connection_type'
@@ -18,7 +18,7 @@ module GraphQL
18
18
 
19
19
  # apply first / last limit results
20
20
  def paged_nodes
21
- @paged_nodes = begin
21
+ @paged_nodes ||= begin
22
22
  items = sliced_nodes
23
23
 
24
24
  if limit
@@ -31,10 +31,7 @@ module GraphQL
31
31
 
32
32
  # Apply cursors to edges
33
33
  def sliced_nodes
34
- @sliced_nodes ||= begin
35
- items = object
36
- items[starting_offset..-1]
37
- end
34
+ @sliced_nodes ||= nodes[starting_offset..-1]
38
35
  end
39
36
 
40
37
  def index_from_cursor(cursor)
@@ -6,11 +6,13 @@ module GraphQL
6
6
  # - {#paged_nodes}, which applies `first` & `last` limits
7
7
  #
8
8
  # In a subclass, you have access to
9
- # - {#object}, the object which the connection will wrap
9
+ # - {#nodes}, the collection which the connection will wrap
10
10
  # - {#first}, {#after}, {#last}, {#before} (arguments passed to the field)
11
11
  # - {#max_page_size} (the specified maximum page size that can be returned from a connection)
12
12
  #
13
13
  class BaseConnection
14
+ extend Gem::Deprecate
15
+
14
16
  # Just to encode data in the cursor, use something that won't conflict
15
17
  CURSOR_SEPARATOR = "---"
16
18
 
@@ -18,49 +20,57 @@ module GraphQL
18
20
  # eg {"Array" => ArrayConnection}
19
21
  CONNECTION_IMPLEMENTATIONS = {}
20
22
 
21
- # Find a connection implementation suitable for exposing `items`
22
- #
23
- # @param [Object] A collection of items (eg, Array, AR::Relation)
24
- # @return [subclass of BaseConnection] a connection Class for wrapping `items`
25
- def self.connection_for_items(items)
26
- # We check class membership by comparing class names rather than
27
- # identity to prevent this from being broken by Rails autoloading.
28
- # Changes to the source file for ItemsClass in Rails apps cause it to be
29
- # reloaded as a new object, so if we were to use `is_a?` here, it would
30
- # no longer match any registered custom connection types.
31
- ancestor_names = items.class.ancestors.map(&:name)
32
- implementation = CONNECTION_IMPLEMENTATIONS.find do |items_class_name, connection_class|
33
- ancestor_names.include? items_class_name
23
+ class << self
24
+ extend Gem::Deprecate
25
+
26
+ # Find a connection implementation suitable for exposing `nodes`
27
+ #
28
+ # @param [Object] A collection of nodes (eg, Array, AR::Relation)
29
+ # @return [subclass of BaseConnection] a connection Class for wrapping `nodes`
30
+ def connection_for_nodes(nodes)
31
+ # Check for class _names_ because classes can be redefined in Rails development
32
+ ancestor_names = nodes.class.ancestors.map(&:name)
33
+ implementation = CONNECTION_IMPLEMENTATIONS.find do |nodes_class_name, connection_class|
34
+ ancestor_names.include? nodes_class_name
35
+ end
36
+ if implementation.nil?
37
+ raise("No connection implementation to wrap #{nodes.class} (#{nodes})")
38
+ else
39
+ implementation[1]
40
+ end
34
41
  end
35
- if implementation.nil?
36
- raise("No connection implementation to wrap #{items.class} (#{items})")
37
- else
38
- implementation[1]
42
+
43
+ # Add `connection_class` as the connection wrapper for `nodes_class`
44
+ # eg, `RelationConnection` is the implementation for `AR::Relation`
45
+ # @param [Class] A class representing a collection (eg, Array, AR::Relation)
46
+ # @param [Class] A class implementing Connection methods
47
+ def register_connection_implementation(nodes_class, connection_class)
48
+ CONNECTION_IMPLEMENTATIONS[nodes_class.name] = connection_class
39
49
  end
40
- end
41
50
 
42
- # Add `connection_class` as the connection wrapper for `items_class`
43
- # eg, `RelationConnection` is the implementation for `AR::Relation`
44
- # @param [Class] A class representing a collection (eg, Array, AR::Relation)
45
- # @param [Class] A class implementing Connection methods
46
- def self.register_connection_implementation(items_class, connection_class)
47
- CONNECTION_IMPLEMENTATIONS[items_class.name] = connection_class
51
+ # @deprecated use {#connection_for_nodes} instead
52
+ alias :connection_for_items :connection_for_nodes
53
+ deprecate(:connection_for_items, :connection_for_nodes, 2016, 9)
48
54
  end
49
55
 
50
- attr_reader :object, :arguments, :max_page_size, :parent
56
+ attr_reader :nodes, :arguments, :max_page_size, :parent
51
57
 
52
- # Make a connection, wrapping `object`
53
- # @param The collection of results
58
+ # Make a connection, wrapping `nodes`
59
+ # @param [Object] The collection of nodes
54
60
  # @param Query arguments
55
61
  # @param max_page_size [Int] The maximum number of results to return
56
62
  # @param parent [Object] The object which this collection belongs to
57
- def initialize(object, arguments, max_page_size: nil, parent: nil)
58
- @object = object
63
+ def initialize(nodes, arguments, max_page_size: nil, parent: nil)
64
+ @nodes = nodes
59
65
  @arguments = arguments
60
66
  @max_page_size = max_page_size
61
67
  @parent = parent
62
68
  end
63
69
 
70
+ # @deprecated use {#nodes} instead
71
+ alias :object :nodes
72
+ deprecate(:object, :nodes, 2016, 9)
73
+
64
74
  # Provide easy access to provided arguments:
65
75
  METHODS_FROM_ARGUMENTS = [:first, :after, :last, :before, :order]
66
76
 
@@ -80,7 +90,7 @@ module GraphQL
80
90
  end
81
91
  end
82
92
 
83
- # These are the items to render for this connection,
93
+ # These are the nodes to render for this connection,
84
94
  # probably wrapped by {GraphQL::Relay::Edge}
85
95
  def edge_nodes
86
96
  @edge_nodes ||= paged_nodes
@@ -127,11 +137,11 @@ module GraphQL
127
137
  private
128
138
 
129
139
  def paged_nodes
130
- raise NotImplementedError, "must return items for this connection after paging"
140
+ raise NotImplementedError, "must return nodes for this connection after paging"
131
141
  end
132
142
 
133
143
  def sliced_nodes
134
- raise NotImplementedError, "must return all items for this connection after chopping off first and last"
144
+ raise NotImplementedError, "must return all nodes for this connection after chopping off first and last"
135
145
  end
136
146
  end
137
147
  end
@@ -1,11 +1,11 @@
1
1
  module GraphQL
2
2
  module Relay
3
- # Provided a GraphQL field which returns a collection of items,
4
- # `ConnectionField.create` modifies that field to expose those items
3
+ # Provided a GraphQL field which returns a collection of nodes,
4
+ # `ConnectionField.create` modifies that field to expose those nodes
5
5
  # as a collection.
6
6
  #
7
- # The original resolve proc is used to fetch items,
8
- # then a connection implementation is fetched with {BaseConnection.connection_for_items}.
7
+ # The original resolve proc is used to fetch nodes,
8
+ # then a connection implementation is fetched with {BaseConnection.connection_for_nodes}.
9
9
  class ConnectionField
10
10
  ARGUMENT_DEFINITIONS = [
11
11
  ["first", GraphQL::INT_TYPE, "Returns the first _n_ elements from the list."],
@@ -27,28 +27,15 @@ module GraphQL
27
27
  # Turn A GraphQL::Field into a connection by:
28
28
  # - Merging in the default arguments
29
29
  # - Transforming its resolve function to return a connection object
30
- # @param [GraphQL::Field] A field which returns items to be wrapped as a connection
31
- # @param max_page_size [Integer] The maximum number of items which may be requested (if a larger page is requested, it is limited to this number)
32
- # @return [GraphQL::Field] A field which serves a connections
30
+ # @param [GraphQL::Field] A field which returns nodes to be wrapped as a connection
31
+ # @param max_page_size [Integer] The maximum number of nodes which may be requested (if a larger page is requested, it is limited to this number)
32
+ # @return [GraphQL::Field] The same field, modified to resolve to a connection object
33
33
  def self.create(underlying_field, max_page_size: nil)
34
34
  underlying_field.arguments = DEFAULT_ARGUMENTS.merge(underlying_field.arguments)
35
35
  original_resolve = underlying_field.resolve_proc
36
- underlying_field.resolve = get_connection_resolve(underlying_field.name, original_resolve, max_page_size: max_page_size)
36
+ underlying_field.resolve = GraphQL::Relay::ConnectionResolve.new(underlying_field.name, original_resolve, max_page_size: max_page_size)
37
37
  underlying_field
38
38
  end
39
-
40
- private
41
-
42
- # Wrap the original resolve proc
43
- # so you capture its value, then wrap it in a
44
- # connection implementation
45
- def self.get_connection_resolve(field_name, underlying_resolve, max_page_size: nil)
46
- -> (obj, args, ctx) {
47
- items = underlying_resolve.call(obj, args, ctx)
48
- connection_class = GraphQL::Relay::BaseConnection.connection_for_items(items)
49
- connection_class.new(items, args, max_page_size: max_page_size, parent: obj)
50
- }
51
- end
52
39
  end
53
40
  end
54
41
  end
@@ -0,0 +1,17 @@
1
+ module GraphQL
2
+ module Relay
3
+ class ConnectionResolve
4
+ def initialize(field_name, underlying_resolve, max_page_size: nil)
5
+ @field_name = field_name
6
+ @underlying_resolve = underlying_resolve
7
+ @max_page_size = max_page_size
8
+ end
9
+
10
+ def call(obj, args, ctx)
11
+ nodes = @underlying_resolve.call(obj, args, ctx)
12
+ connection_class = GraphQL::Relay::BaseConnection.connection_for_nodes(nodes)
13
+ connection_class.new(nodes, args, max_page_size: @max_page_size, parent: obj)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -22,18 +22,12 @@ module GraphQL
22
22
 
23
23
  # apply first / last limit results
24
24
  def paged_nodes
25
- @paged_nodes ||= begin
26
- items = sliced_nodes
27
- items.limit(limit)
28
- end
25
+ @paged_nodes ||= sliced_nodes.limit(limit)
29
26
  end
30
27
 
31
28
  # Apply cursors to edges
32
29
  def sliced_nodes
33
- @sliced_nodes ||= begin
34
- items = object
35
- items.offset(starting_offset)
36
- end
30
+ @sliced_nodes ||= nodes.offset(starting_offset)
37
31
  end
38
32
 
39
33
  def offset_from_cursor(cursor)
@@ -1,3 +1,3 @@
1
1
  module GraphQL
2
- VERSION = "0.18.0"
2
+ VERSION = "0.18.1"
3
3
  end
data/readme.md CHANGED
@@ -122,13 +122,7 @@ If you're building a backend for [Relay](http://facebook.github.io/relay/), you'
122
122
 
123
123
  ## To Do
124
124
 
125
- - Accept type name as `type` argument?
126
- - Goal: accept `field :post, "Post"` to look up a type named `"Post"` in the schema
127
- - Problem: how does a field know which schema to look up the name from?
128
- - Problem: how can we load types in Rails without accessing the constant?
129
- - Maybe support by third-party library? `type("Post!")` could implement "type_missing", keeps `graphql-ruby` very simple
130
125
  - StaticValidation improvements
131
- - Include `path: [...]` in validation errors
132
126
  - Use catch-all type/field/argument definitions instead of terminating traversal
133
127
  - Reduce ad-hoc traversals?
134
128
  - Validators are order-dependent, is this a smell?
@@ -142,4 +136,3 @@ If you're building a backend for [Relay](http://facebook.github.io/relay/), you'
142
136
  - Reduce duplication in ArrayConnection / RelationConnection
143
137
  - Improve API for creating edges (better RANGE_ADD support)
144
138
  - If the new edge isn't a member of the connection's objects, raise a nice error
145
- - Rename `Connection#object` => `Connection#collection` with deprecation
@@ -75,5 +75,45 @@ describe GraphQL::Analysis do
75
75
  assert_equal "Variable cheeseId of type Int! was provided invalid value", error["message"]
76
76
  end
77
77
  end
78
+
79
+ describe "when processing fields" do
80
+ let(:connection_counter) {
81
+ -> (memo, visit_type, irep_node) {
82
+ memo ||= Hash.new { |h,k| h[k] = 0 }
83
+ if visit_type == :enter
84
+ if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field)
85
+ irep_node.definitions.each do |type_defn, field_defn|
86
+ if field_defn.resolve_proc.is_a?(GraphQL::Relay::ConnectionResolve)
87
+ memo["connection"] += 1
88
+ else
89
+ memo["field"] += 1
90
+ end
91
+ end
92
+ end
93
+ end
94
+ memo
95
+ }
96
+ }
97
+ let(:analyzers) { [connection_counter] }
98
+ let(:reduce_result) { GraphQL::Analysis.analyze_query(query, analyzers) }
99
+ let(:query) { GraphQL::Query.new(StarWarsSchema, query_string, variables: variables) }
100
+ let(:query_string) {%|
101
+ query getBases {
102
+ empire {
103
+ basesByName(first: 30) { edges { cursor } }
104
+ bases(first: 30) { edges { cursor } }
105
+ }
106
+ }
107
+ |}
108
+
109
+ it "knows which fields are connections" do
110
+ connection_counts = reduce_result.first
111
+ expected_connection_counts = {
112
+ "field" => 5,
113
+ "connection" => 2
114
+ }
115
+ assert_equal expected_connection_counts, connection_counts
116
+ end
117
+ end
78
118
  end
79
119
  end
@@ -21,4 +21,8 @@ describe GraphQL::BaseType do
21
21
  GraphQL::ListType.new(of_type: !MilkType)
22
22
  )
23
23
  end
24
+
25
+ it "Accepts arbitrary metadata" do
26
+ assert_equal ["Cheese"], CheeseType.metadata[:class_names]
27
+ end
24
28
  end
@@ -12,7 +12,7 @@ module Garden
12
12
  class Vegetable
13
13
  include GraphQL::Define::InstanceDefinable
14
14
  lazy_defined_attr_accessor :name, :start_planting_on, :end_planting_on
15
- accepts_definitions :name, plant_between: DefinePlantBetween
15
+ accepts_definitions :name, plant_between: DefinePlantBetween, color: GraphQL::Define.assign_metadata_key(:color)
16
16
 
17
17
  # definition added later:
18
18
  lazy_defined_attr_accessor :height
@@ -61,4 +61,11 @@ describe GraphQL::Define::InstanceDefinable do
61
61
  assert_equal Date.new(2000, 7, 1), okra.end_planting_on
62
62
  end
63
63
  end
64
+
65
+ describe "#metadata" do
66
+ it "gets values from definitions" do
67
+ arugula = Garden::Vegetable.define(name: "Arugula", color: :green)
68
+ assert_equal :green, arugula.metadata[:color]
69
+ end
70
+ end
64
71
  end
@@ -17,7 +17,6 @@ describe GraphQL::Field do
17
17
  assert_equal(DairyProductUnion, field.type)
18
18
  end
19
19
 
20
-
21
20
  describe ".property " do
22
21
  let(:field) do
23
22
  GraphQL::Field.define do
@@ -107,4 +106,11 @@ describe GraphQL::Field do
107
106
  assert_equal "Xyz", resolved_source
108
107
  end
109
108
  end
109
+
110
+ describe "#metadata" do
111
+ it "accepts user-defined metadata" do
112
+ similar_cheese_field = CheeseType.get_field("similarCheese")
113
+ assert_equal [:cheeses, :milks], similar_cheese_field.metadata[:joins]
114
+ end
115
+ end
110
116
  end
@@ -2,6 +2,9 @@ require_relative "./dairy_data"
2
2
 
3
3
  class NoSuchDairyError < StandardError; end
4
4
 
5
+ GraphQL::Field.accepts_definitions(joins: GraphQL::Define.assign_metadata_key(:joins))
6
+ GraphQL::BaseType.accepts_definitions(class_names: GraphQL::Define.assign_metadata_key(:class_names))
7
+
5
8
  EdibleInterface = GraphQL::InterfaceType.define do
6
9
  name "Edible"
7
10
  description "Something you can eat, yum"
@@ -26,6 +29,7 @@ end
26
29
 
27
30
  CheeseType = GraphQL::ObjectType.define do
28
31
  name "Cheese"
32
+ class_names ["Cheese"]
29
33
  description "Cultured dairy product"
30
34
  interfaces [EdibleInterface, AnimalProductInterface]
31
35
 
@@ -39,6 +43,8 @@ CheeseType = GraphQL::ObjectType.define do
39
43
 
40
44
  # Or can define by block, `resolve ->` should override `property:`
41
45
  field :similarCheese, CheeseType, "Cheeses like this one", property: :this_should_be_overriden do
46
+ # metadata test
47
+ joins [:cheeses, :milks]
42
48
  argument :source, !types[!DairyAnimalEnum]
43
49
  resolve -> (t, a, c) {
44
50
  # get the strings out:
@@ -47,7 +47,7 @@ BaseConnectionWithTotalCountType = BaseType.define_connection do
47
47
  name "BasesConnectionWithTotalCount"
48
48
  field :totalCount do
49
49
  type types.Int
50
- resolve -> (obj, args, ctx) { obj.object.count }
50
+ resolve -> (obj, args, ctx) { obj.nodes.count }
51
51
  end
52
52
  end
53
53
 
@@ -75,7 +75,7 @@ CustomEdgeBaseConnectionType = BaseType.define_connection(edge_class: CustomBase
75
75
 
76
76
  field :totalCountTimes100 do
77
77
  type types.Int
78
- resolve -> (obj, args, ctx) { obj.object.count * 100 }
78
+ resolve -> (obj, args, ctx) { obj.nodes.count * 100 }
79
79
  end
80
80
  end
81
81
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.0
4
+ version: 0.18.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-04 00:00:00.000000000 Z
11
+ date: 2016-08-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codeclimate-test-reporter
@@ -260,7 +260,6 @@ files:
260
260
  - lib/graphql/define/assign_enum_value.rb
261
261
  - lib/graphql/define/assign_global_id_field.rb
262
262
  - lib/graphql/define/assign_object_field.rb
263
- - lib/graphql/define/assignment_dictionary.rb
264
263
  - lib/graphql/define/defined_object_proxy.rb
265
264
  - lib/graphql/define/instance_definable.rb
266
265
  - lib/graphql/define/non_null_with_bang.rb
@@ -333,6 +332,7 @@ files:
333
332
  - lib/graphql/relay/array_connection.rb
334
333
  - lib/graphql/relay/base_connection.rb
335
334
  - lib/graphql/relay/connection_field.rb
335
+ - lib/graphql/relay/connection_resolve.rb
336
336
  - lib/graphql/relay/connection_type.rb
337
337
  - lib/graphql/relay/edge.rb
338
338
  - lib/graphql/relay/edge_type.rb
@@ -1,26 +0,0 @@
1
- module GraphQL
2
- module Define
3
- # Create a hash of definitions out of provided arguments.
4
- #
5
- # @example Create definitions (some default, some custom)
6
- # hash = AssignmentDictionary.create(:name, :description, field: (value, field_name) -> { value.create_field(field) })
7
- #
8
- module AssignmentDictionary
9
- # Turn `keys` into a hash suitable for {GraphQL::Define::InstanceDefinable}
10
- # @param Any number of symbols for default assignment, followed by an (optional) hash of custom assignment procs.
11
- # @return [Hash] keys are attributes which may be defined. values are procs which assign values to the target object.
12
- def self.create(*keys)
13
- initial = if keys.last.is_a?(Hash)
14
- keys.pop
15
- else
16
- {}
17
- end
18
- keys.inject(initial) do |memo, key|
19
- assign_key = "#{key}="
20
- memo[key] = -> (target, value) { target.public_send(assign_key, value) }
21
- memo
22
- end
23
- end
24
- end
25
- end
26
- end