search_object_graphql 0.3.2 → 1.0.0

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
  SHA256:
3
- metadata.gz: 2ab34781a81c8808d0b9702dcf9742955e9859c5827461e00e1b1a431f1df216
4
- data.tar.gz: b5ed30f8e4b39c36d4fb1e9d28b1f2118a7bfd1507a045fac76286a61e8345ac
3
+ metadata.gz: 49fd6817f69aa33a15ce7cc2e768bd239020c3f7f6b6e385e1f12d3c9d5c30ff
4
+ data.tar.gz: c6c4a8d82f1d5afa85519a1e8aee726b321495b2305e63fa0d5e986db75066fb
5
5
  SHA512:
6
- metadata.gz: 93701d2abfb6a521f6aa199aaaf4a0fee641367a20de4b2806cbaeac45539909289529183590ca924c7329aeb7ce9cf53d3c5b581205208338c0ef8200e97874
7
- data.tar.gz: 209b6af6cea55e752c7c76cbdb9769e8af18bed61c124982e58e502f7e10d8136f3a29653875c7b25d876676db0bdb3cb9faa0605132dfca3356a614288255ee
6
+ metadata.gz: a71588bac7cc2fba645d1e4007bfeed111749c0016d4a2de7e832990ff33f37e1656c08a47fd3a52f18664e594bbefee3939d1412aa3fc5d679dd9c3d875d533
7
+ data.tar.gz: 4c9bfd49332eafbd37b10be48bc58c65bfffa0546dc7c394a7b77e3e146769ee77083f39bbd40f101302ad7ffb967d8b7e0054b6512c35febdcedc0e00c94855
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## Version 1.0.0 (unreleased)
4
+
5
+ * __[break]__ Removed support for defining types via `type` method (@rstankov)
6
+ * __[break]__ Require `GraphQL::Schema::Resolver` inheritance (@rstankov)
7
+ * __[break]__ Removed support for legacy `GraphQL::Function` (@rstankov)
8
+ * __[break]__ `type` creates type based on `GraphQL::Schema::Object`, not the deprecated `GraphQL::ObjectType.define` (@rstankov)
9
+
3
10
  ## Version 0.3.2
4
11
 
5
12
  * __[feature]__ Added `camelize` argument to `option`, *`true` by default* (@glenbray)
data/README.md CHANGED
@@ -57,7 +57,7 @@ require 'search_object/plugin/graphql'
57
57
  Just include the ```SearchObject.module``` and define your search options and their types:
58
58
 
59
59
  ```ruby
60
- class PostResolver
60
+ class PostResolver < GraphQL::Schema::Resolver
61
61
  include SearchObject.module(:graphql)
62
62
 
63
63
  type [PostType], null: false
@@ -94,7 +94,7 @@ You can find example of most important features and plugins - [here](https://git
94
94
  Search object itself can be documented, as well as its options:
95
95
 
96
96
  ```ruby
97
- class PostResolver
97
+ class PostResolver < GraphQL::Schema::Resolver
98
98
  include SearchObject.module(:graphql)
99
99
 
100
100
  description 'Lists all posts'
@@ -107,7 +107,7 @@ end
107
107
  ### Default Values
108
108
 
109
109
  ```ruby
110
- class PostResolver
110
+ class PostResolver < GraphQL::Schema::Resolver
111
111
  include SearchObject.module(:graphql)
112
112
 
113
113
  scope { Post.all }
@@ -121,7 +121,7 @@ end
121
121
  Sometimes you want to scope posts based on parent object, it is accessible as `object` property:
122
122
 
123
123
  ```ruby
124
- class PostResolver
124
+ class PostResolver < GraphQL::Schema::Resolver
125
125
  include SearchObject.module(:graphql)
126
126
 
127
127
  # lists only posts from certain category
@@ -168,7 +168,7 @@ end
168
168
  Search objects can be used as [Relay Connections](https://graphql-ruby.org/relay/connections.html):
169
169
 
170
170
  ```ruby
171
- class PostResolver
171
+ class PostResolver < GraphQL::Schema::Resolver
172
172
  include SearchObject.module(:graphql)
173
173
 
174
174
  type PostType.connection_type, null: false
@@ -181,22 +181,6 @@ end
181
181
  field :posts, resolver: PostResolver
182
182
  ```
183
183
 
184
- ### Legacy Function Support
185
-
186
- ```ruby
187
- class PostResolver
188
- include SearchObject.module(:graphql)
189
-
190
- type [PostType], null: false
191
-
192
- # ...
193
- end
194
- ```
195
-
196
- ```ruby
197
- field :posts, function: PostResolver
198
- ```
199
-
200
184
  ## Contributing
201
185
 
202
186
  1. Fork it
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Resolvers
4
+ class BaseResolver < GraphQL::Schema::Resolver
5
+ end
6
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Resolvers
4
- class BaseSearchResolver
4
+ class BaseSearchResolver < BaseResolver
5
5
  include SearchObject.module(:graphql)
6
6
 
7
7
  def escape_search_term(term)
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Resolvers
4
4
  class CategorySearch < Resolvers::BaseSearchResolver
5
- type Types::CategoryType.connection_type
5
+ type Types::CategoryType.connection_type, null: false
6
6
  description 'Lists categories'
7
7
 
8
8
  class OrderEnum < Types::BaseEnum
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Resolvers
4
4
  class PostSearch < Resolvers::BaseSearchResolver
5
- type Types::PostType.connection_type
5
+ type Types::PostType.connection_type, null: false
6
6
  description 'Lists posts'
7
7
 
8
8
  class OrderEnum < Types::BaseEnum
@@ -4,6 +4,6 @@ module Types
4
4
  class CategoryType < BaseObject
5
5
  field :id, ID, null: false
6
6
  field :name, String, null: false
7
- field :posts, function: Resolvers::PostSearch
7
+ field :posts, resolver: Resolvers::PostSearch
8
8
  end
9
9
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Types
4
4
  class QueryType < Types::BaseObject
5
- field :categories, function: Resolvers::CategorySearch
5
+ field :categories, resolver: Resolvers::CategorySearch
6
6
  field :posts, resolver: Resolvers::PostSearch
7
7
  end
8
8
  end
@@ -4,8 +4,9 @@ module SearchObject
4
4
  module Plugin
5
5
  module Graphql
6
6
  def self.included(base)
7
+ raise NotIncludedInResolverError, base unless base.ancestors.include? GraphQL::Schema::Resolver
8
+
7
9
  base.include SearchObject::Plugin::Enum
8
- base.include ::GraphQL::Schema::Member::GraphQLTypeNames
9
10
  base.extend ClassMethods
10
11
  end
11
12
 
@@ -26,114 +27,29 @@ module SearchObject
26
27
  end
27
28
 
28
29
  module ClassMethods
29
- KEYS = %i[type default description required camelize].freeze
30
30
  def option(name, options = {}, &block)
31
- config[:arguments] ||= {}
32
- config[:arguments][name.to_s] = KEYS.inject({}) do |acc, key|
33
- acc[key] = options[key] if options.key?(key)
34
- acc
35
- end
36
-
37
31
  type = options.fetch(:type) { raise MissingTypeDefinitionError, name }
38
32
  options[:enum] = type.values.map { |value, enum_value| enum_value.value || value } if type.respond_to?(:values)
39
33
 
40
- super(name, options, &block)
41
- end
42
-
43
- def type(value = :default, null: true, &block)
44
- return config[:type] if value == :default && !block_given?
45
-
46
- config[:type] = block_given? ? GraphQL::ObjectType.define(&block) : value
47
- config[:null] = null
48
- end
49
-
50
- def complexity(value = :default)
51
- return config[:complexity] || 1 if value == :default
52
-
53
- config[:complexity] = value
54
- end
55
-
56
- def description(value = :default)
57
- return config[:description] if value == :default
58
-
59
- config[:description] = value
60
- end
61
-
62
- def deprecation_reason(value = :default)
63
- return config[:deprecation_reason] if value == :default
34
+ argument(
35
+ name.to_s,
36
+ options[:type],
37
+ required: options[:required] || false,
38
+ description: options[:description],
39
+ camelize: options[:camelize]
40
+ )
64
41
 
65
- config[:deprecation_reason] = value
66
- end
67
-
68
- # NOTE(rstankov): GraphQL::Function interface (deprecated in favour of GraphQL::Schema::Resolver)
69
- # Documentation - http://graphql-ruby.org/guides
70
- def call(object, args, context)
71
- new(filters: args.to_h, object: object, context: context).results
42
+ super(name, options, &block)
72
43
  end
73
44
 
74
- # NOTE(rstankov): Used for GraphQL::Function
75
45
  def types
76
46
  GraphQL::Define::TypeDefiner.instance
77
47
  end
48
+ end
78
49
 
79
- # NOTE(rstankov): Used for GraphQL::Function
80
- def arguments
81
- (config[:arguments] || {}).inject({}) do |acc, (name, options)|
82
- argument = GraphQL::Argument.new
83
- argument.name = name.to_s
84
- argument.type = options.fetch(:type) { raise MissingTypeDefinitionError, name }
85
- argument.default_value = options[:default] if options.key? :default
86
- argument.description = options[:description] if options.key? :description
87
-
88
- acc[name] = argument
89
- acc
90
- end
91
- end
92
-
93
- # NOTE(rstankov): Used for GraphQL::Schema::Resolver
94
- def field_options
95
- {
96
- type: type,
97
- description: description,
98
- extras: [],
99
- resolver_method: :resolve_with_support,
100
- resolver_class: self,
101
- deprecation_reason: deprecation_reason,
102
- arguments: (config[:arguments] || {}).inject({}) do |acc, (name, options)|
103
- if options.fetch(:camelize) { true }
104
- name = name.to_s.split('_').map(&:capitalize).join
105
- name[0] = name[0].downcase
106
- end
107
-
108
- acc[name] = ::GraphQL::Schema::Argument.new(
109
- name: name.to_s,
110
- type: options.fetch(:type) { raise MissingTypeDefinitionError, name },
111
- description: options[:description],
112
- required: !!options[:required],
113
- camelize: !!options[:camelize],
114
- default_value: options.fetch(:default) { ::GraphQL::Schema::Argument::NO_DEFAULT },
115
- owner: self
116
- )
117
- acc
118
- end,
119
- null: !!config[:null],
120
- complexity: complexity
121
- }
122
- end
123
-
124
- # NOTE(rstankov): Used for GraphQL::Schema::Resolver
125
- def visible?(_context)
126
- true
127
- end
128
-
129
- # NOTE(rstankov): Used for GraphQL::Schema::Resolver
130
- def accessible?(_context)
131
- true
132
- end
133
-
134
- # NOTE(rstankov): Used for GraphQL::Schema::Resolver
135
- def authorized?(_object, _context)
136
- true
50
+ class NotIncludedInResolverError < ArgumentError
51
+ def initialize(base)
52
+ super "#{base.name} should inherit from GraphQL::Schema::Resolver. Current ancestors #{base.ancestors}"
137
53
  end
138
54
  end
139
55
 
@@ -3,7 +3,7 @@
3
3
  module SearchObject
4
4
  module Plugin
5
5
  module Graphql
6
- VERSION = '0.3.2'
6
+ VERSION = '1.0.0'
7
7
  end
8
8
  end
9
9
  end
@@ -31,7 +31,7 @@ describe SearchObject::Plugin::Graphql do
31
31
  end
32
32
 
33
33
  def define_search_class(&block)
34
- Class.new do
34
+ Class.new(GraphQL::Schema::Resolver) do
35
35
  include SearchObject.module(:graphql)
36
36
 
37
37
  scope { [] }
@@ -52,6 +52,12 @@ describe SearchObject::Plugin::Graphql do
52
52
  end
53
53
  end
54
54
 
55
+ it 'requires class to inherit from GraphQL::Schema::Resolver' do
56
+ expect do
57
+ Class.new { include SearchObject.module(:graphql) }
58
+ end.to raise_error SearchObject::Plugin::Graphql::NotIncludedInResolverError
59
+ end
60
+
55
61
  it 'can be used as GraphQL::Schema::Resolver' do
56
62
  post_type = Class.new(GraphQL::Schema::Object) do
57
63
  graphql_name 'Post'
@@ -62,7 +68,7 @@ describe SearchObject::Plugin::Graphql do
62
68
  search_object = define_search_class do
63
69
  scope { [Post.new('1'), Post.new('2'), Post.new('3')] }
64
70
 
65
- type [post_type]
71
+ type [post_type], null: 1
66
72
 
67
73
  option(:id, type: !types.ID) { |scope, value| scope.select { |p| p.id == value } }
68
74
  end
@@ -80,34 +86,6 @@ describe SearchObject::Plugin::Graphql do
80
86
  )
81
87
  end
82
88
 
83
- it 'can be used as GraphQL::Function' do
84
- post_type = GraphQL::ObjectType.define do
85
- name 'Post'
86
-
87
- field :id, !types.ID
88
- end
89
-
90
- search_object = define_search_class do
91
- scope { [Post.new('1'), Post.new('2'), Post.new('3')] }
92
-
93
- type types[post_type]
94
-
95
- option(:id, type: !types.ID) { |scope, value| scope.select { |p| p.id == value } }
96
- end
97
-
98
- schema = define_schema do
99
- field :posts, function: search_object
100
- end
101
-
102
- result = schema.execute '{ posts(id: "2") { id } }'
103
-
104
- expect(result).to eq(
105
- 'data' => {
106
- 'posts' => [Post.new('2').to_json]
107
- }
108
- )
109
- end
110
-
111
89
  it 'can access to parent object' do
112
90
  search_object = define_search_class do
113
91
  scope { object.posts }
@@ -164,81 +142,6 @@ describe SearchObject::Plugin::Graphql do
164
142
  )
165
143
  end
166
144
 
167
- it 'can define a custom type' do
168
- schema = define_search_class_and_return_schema do
169
- type do
170
- name 'Test'
171
-
172
- field :title, types.String
173
- end
174
-
175
- description 'Test description'
176
- end
177
-
178
- result = schema.execute <<-SQL
179
- {
180
- __type(name: "Query") {
181
- name
182
- fields {
183
- name
184
- deprecationReason
185
- type {
186
- name
187
- fields {
188
- name
189
- }
190
- }
191
- }
192
- }
193
- }
194
- SQL
195
-
196
- expect(result).to eq(
197
- 'data' => {
198
- '__type' => {
199
- 'name' => 'Query',
200
- 'fields' => [{
201
- 'name' => 'posts',
202
- 'deprecationReason' => nil,
203
- 'type' => {
204
- 'name' => 'Test',
205
- 'fields' => [{
206
- 'name' => 'title'
207
- }]
208
- }
209
- }]
210
- }
211
- }
212
- )
213
- end
214
-
215
- it 'can be marked as deprecated' do
216
- schema = define_search_class_and_return_schema do
217
- type [PostType]
218
- deprecation_reason 'Not needed any more'
219
- end
220
-
221
- result = schema.execute <<-QUERY
222
- {
223
- __type(name: "Query") {
224
- name
225
- fields {
226
- name
227
- }
228
- }
229
- }
230
- QUERY
231
-
232
- expect(result.to_h).to eq(
233
- 'data' => {
234
- '__type' => {
235
- 'name' => 'Query',
236
- 'fields' => []
237
- }
238
- }
239
- )
240
- end
241
-
242
145
  describe 'option' do
243
146
  it 'converts GraphQL::Schema::Enum to SearchObject enum' do
244
147
  schema = define_search_class_and_return_schema do
@@ -271,8 +174,8 @@ describe SearchObject::Plugin::Graphql do
271
174
 
272
175
  it 'converts GraphQL::EnumType to SearchObject enum' do
273
176
  schema = define_search_class_and_return_schema do
274
- enum_type = GraphQL::EnumType.define do
275
- name 'TestEnum'
177
+ enum_type = Class.new(GraphQL::Schema::Enum) do
178
+ graphql_name 'TestEnum'
276
179
 
277
180
  value 'PRICE'
278
181
  value 'DATE'
@@ -328,7 +231,7 @@ describe SearchObject::Plugin::Graphql do
328
231
 
329
232
  it 'accepts description' do
330
233
  schema = define_search_class_and_return_schema do
331
- type PostType
234
+ type PostType, null: true
332
235
 
333
236
  option('option', type: types.String, description: 'what this argument does') { [] }
334
237
  end
@@ -364,7 +267,7 @@ describe SearchObject::Plugin::Graphql do
364
267
 
365
268
  it 'accepts camelize' do
366
269
  schema = define_search_class_and_return_schema do
367
- type PostType
270
+ type PostType, null: true
368
271
 
369
272
  option('option_field', type: types.String, camelize: false)
370
273
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_object_graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Radoslav Stankov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-07 00:00:00.000000000 Z
11
+ date: 2021-02-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -134,6 +134,7 @@ files:
134
134
  - example/app/controllers/application_controller.rb
135
135
  - example/app/controllers/graphql_controller.rb
136
136
  - example/app/graphql/mutations/.keep
137
+ - example/app/graphql/resolvers/base_resolver.rb
137
138
  - example/app/graphql/resolvers/base_search_resolver.rb
138
139
  - example/app/graphql/resolvers/category_search.rb
139
140
  - example/app/graphql/resolvers/post_search.rb