graphql 0.18.0 → 0.18.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: 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