search_object_graphql 1.0.0 → 1.0.3
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 +4 -4
- data/.rubocop.yml +6 -0
- data/.travis.yml +2 -1
- data/CHANGELOG.md +13 -1
- data/README.md +17 -3
- data/example/app/graphql/resolvers/category_search.rb +2 -2
- data/example/app/graphql/resolvers/post_search.rb +6 -6
- data/example/app/graphql/types/base_argument.rb +11 -0
- data/example/app/graphql/types/base_field.rb +7 -0
- data/example/app/graphql/types/base_object.rb +1 -0
- data/lib/search_object/plugin/graphql/version.rb +1 -1
- data/lib/search_object/plugin/graphql.rb +12 -8
- data/search_object_graphql.gemspec +1 -1
- data/spec/search_object/plugin/graphql_spec.rb +116 -5
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4743546d8933b7412977b5b2736eca71fd8950ef016ca5e4f766a73e7f75d0dd
|
4
|
+
data.tar.gz: a9772b5cb3cfda0e8cbc334a68d24d919b964e81af00be8696a91b3bc0d60947
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5c1400ac1875e40b26a1ef4c8e5180e2324cc5e671b715e61172f5dd51cce443fce19dfaa92d5783791a3d8cc06de9c6d1a238b2f9e9c3158aab35cee21c58d6
|
7
|
+
data.tar.gz: ff5bd7c05cc45cd815a8682423dee031ea720d7c3da766a8aa19e9df1d52d9013592ed4bf58255c218ab9dc0e8c1c0c2a6fd95c91e7961f04f346fe0f3a2bf1f
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## Version 1.0.
|
3
|
+
## Version 1.0.2
|
4
|
+
|
5
|
+
* __[fix]__ Support GraphQL 2.0 gem (@rstankov)
|
6
|
+
|
7
|
+
## Version 1.0.1
|
8
|
+
|
9
|
+
* __[feature]__ Added `argument_options` to `options` (@wuz)
|
10
|
+
|
11
|
+
## Version 1.0.1
|
12
|
+
|
13
|
+
* __[fix]__ `camelize` defaults to false when not specified (@haines)
|
14
|
+
|
15
|
+
## Version 1.0.0
|
4
16
|
|
5
17
|
* __[break]__ Removed support for defining types via `type` method (@rstankov)
|
6
18
|
* __[break]__ Require `GraphQL::Schema::Resolver` inheritance (@rstankov)
|
data/README.md
CHANGED
@@ -99,8 +99,8 @@ class PostResolver < GraphQL::Schema::Resolver
|
|
99
99
|
|
100
100
|
description 'Lists all posts'
|
101
101
|
|
102
|
-
option(:name, type:
|
103
|
-
option(:published, type:
|
102
|
+
option(:name, type: String, description: 'Fuzzy name matching') { ... }
|
103
|
+
option(:published, type: Boolean, description: 'Find published/unpublished') { ... }
|
104
104
|
end
|
105
105
|
```
|
106
106
|
|
@@ -112,7 +112,21 @@ class PostResolver < GraphQL::Schema::Resolver
|
|
112
112
|
|
113
113
|
scope { Post.all }
|
114
114
|
|
115
|
-
option(:published, type:
|
115
|
+
option(:published, type: Boolean, default: true) { |scope, value| value ? scope.published : scope.unpublished }
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
### Additional Argument Options
|
120
|
+
|
121
|
+
Sometimes you need to pass additional options to the graphql argument method.
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
class PostResolver < GraphQL::Schema::Resolver
|
125
|
+
include SearchObject.module(:graphql)
|
126
|
+
|
127
|
+
scope { Post.all }
|
128
|
+
|
129
|
+
option(:published, type: Boolean, argument_options: { pundit_role: :read }) { |scope, value| value ? scope.published : scope.unpublished }
|
116
130
|
end
|
117
131
|
```
|
118
132
|
|
@@ -14,8 +14,8 @@ module Resolvers
|
|
14
14
|
|
15
15
|
scope { Category.all }
|
16
16
|
|
17
|
-
option :id, type:
|
18
|
-
option :name, type:
|
17
|
+
option :id, type: String, with: :apply_id_filter
|
18
|
+
option :name, type: String, with: :apply_name_filter
|
19
19
|
option :order, type: OrderEnum, default: 'RECENT'
|
20
20
|
|
21
21
|
def apply_id_filter(scope, value)
|
@@ -16,12 +16,12 @@ module Resolvers
|
|
16
16
|
|
17
17
|
scope { object.respond_to?(:posts) ? object.posts : Post.all }
|
18
18
|
|
19
|
-
option :id, type:
|
20
|
-
option :title, type:
|
21
|
-
option :body, type:
|
22
|
-
option :categoryId, type:
|
23
|
-
option :categoryName, type:
|
24
|
-
option :published, type:
|
19
|
+
option :id, type: String, with: :apply_id_filter
|
20
|
+
option :title, type: String, with: :apply_title_filter
|
21
|
+
option :body, type: String, with: :apply_body_filter
|
22
|
+
option :categoryId, type: String, with: :apply_category_id_filter
|
23
|
+
option :categoryName, type: String, with: :apply_category_name_filter
|
24
|
+
option :published, type: Boolean, with: :apply_published_filter
|
25
25
|
option :order, type: OrderEnum, default: 'RECENT'
|
26
26
|
|
27
27
|
def apply_id_filter(scope, value)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Types
|
4
|
+
class BaseArgument < GraphQL::Schema::Argument
|
5
|
+
def initialize(*args, permission: true, **kwargs, &block)
|
6
|
+
super(*args, **kwargs, &block)
|
7
|
+
|
8
|
+
raise GraphQL::ExecutionError, 'No permission' unless permission
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -29,19 +29,23 @@ module SearchObject
|
|
29
29
|
module ClassMethods
|
30
30
|
def option(name, options = {}, &block)
|
31
31
|
type = options.fetch(:type) { raise MissingTypeDefinitionError, name }
|
32
|
-
options[:enum] = type.values.map { |value, enum_value| enum_value.value || value } if type.respond_to?(:values)
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
)
|
33
|
+
argument_options = options[:argument_options] || {}
|
34
|
+
|
35
|
+
argument_options[:required] = options[:required] || false
|
36
|
+
|
37
|
+
argument_options[:camelize] = options[:camelize] if options.include?(:camelize)
|
38
|
+
argument_options[:default_value] = options[:default] if options.include?(:default)
|
39
|
+
argument_options[:description] = options[:description] if options.include?(:description)
|
40
|
+
|
41
|
+
argument(name.to_s, type, **argument_options)
|
42
|
+
|
43
|
+
options[:enum] = type.values.map { |value, enum_value| enum_value.value || value } if type.respond_to?(:values)
|
41
44
|
|
42
45
|
super(name, options, &block)
|
43
46
|
end
|
44
47
|
|
48
|
+
# NOTE(rstankov): This is removed in GraphQL 2.0.0
|
45
49
|
def types
|
46
50
|
GraphQL::Define::TypeDefiner.instance
|
47
51
|
end
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
|
23
|
-
spec.add_dependency 'graphql', '
|
23
|
+
spec.add_dependency 'graphql', '> 1.8'
|
24
24
|
spec.add_dependency 'search_object', '~> 1.2.2'
|
25
25
|
|
26
26
|
spec.add_development_dependency 'coveralls'
|
@@ -17,7 +17,20 @@ end
|
|
17
17
|
|
18
18
|
describe SearchObject::Plugin::Graphql do
|
19
19
|
def define_schema(&block)
|
20
|
+
argument_type = Class.new(GraphQL::Schema::Argument) do
|
21
|
+
def initialize(*args, permission: true, **kwargs, &block)
|
22
|
+
super(*args, **kwargs, &block)
|
23
|
+
|
24
|
+
raise 'No permission' unless permission
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
field_type = Class.new(GraphQL::Schema::Field) do
|
29
|
+
argument_class argument_type
|
30
|
+
end
|
31
|
+
|
20
32
|
query_type = Class.new(GraphQL::Schema::Object) do
|
33
|
+
field_class field_type
|
21
34
|
graphql_name 'Query'
|
22
35
|
|
23
36
|
instance_eval(&block)
|
@@ -31,7 +44,16 @@ describe SearchObject::Plugin::Graphql do
|
|
31
44
|
end
|
32
45
|
|
33
46
|
def define_search_class(&block)
|
47
|
+
argument_type = Class.new(GraphQL::Schema::Argument) do
|
48
|
+
def initialize(*args, permission: true, **kwargs, &block)
|
49
|
+
super(*args, **kwargs, &block)
|
50
|
+
|
51
|
+
raise 'No permission' unless permission
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
34
55
|
Class.new(GraphQL::Schema::Resolver) do
|
56
|
+
argument_class argument_type
|
35
57
|
include SearchObject.module(:graphql)
|
36
58
|
|
37
59
|
scope { [] }
|
@@ -70,7 +92,7 @@ describe SearchObject::Plugin::Graphql do
|
|
70
92
|
|
71
93
|
type [post_type], null: 1
|
72
94
|
|
73
|
-
option(:id, type:
|
95
|
+
option(:id, type: GraphQL::Types::ID) { |scope, value| scope.select { |p| p.id == value } }
|
74
96
|
end
|
75
97
|
|
76
98
|
schema = define_schema do
|
@@ -203,7 +225,7 @@ describe SearchObject::Plugin::Graphql do
|
|
203
225
|
|
204
226
|
it 'accepts default type' do
|
205
227
|
schema = define_search_class_and_return_schema do
|
206
|
-
option(:id, type:
|
228
|
+
option(:id, type: String, default: 'default') do |_scope, value|
|
207
229
|
[Post.new(value)]
|
208
230
|
end
|
209
231
|
end
|
@@ -217,9 +239,45 @@ describe SearchObject::Plugin::Graphql do
|
|
217
239
|
)
|
218
240
|
end
|
219
241
|
|
242
|
+
it 'sets default_value on the argument' do
|
243
|
+
schema = define_search_class_and_return_schema do
|
244
|
+
type PostType, null: true
|
245
|
+
|
246
|
+
option('option', type: String, default: 'default') { [] }
|
247
|
+
end
|
248
|
+
|
249
|
+
result = schema.execute <<~GRAPHQL
|
250
|
+
{
|
251
|
+
__type(name: "Query") {
|
252
|
+
name
|
253
|
+
fields {
|
254
|
+
args {
|
255
|
+
name
|
256
|
+
defaultValue
|
257
|
+
}
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}
|
261
|
+
GRAPHQL
|
262
|
+
|
263
|
+
expect(result).to eq(
|
264
|
+
'data' => {
|
265
|
+
'__type' => {
|
266
|
+
'name' => 'Query',
|
267
|
+
'fields' => [{
|
268
|
+
'args' => [{
|
269
|
+
'name' => 'option',
|
270
|
+
'defaultValue' => '"default"'
|
271
|
+
}]
|
272
|
+
}]
|
273
|
+
}
|
274
|
+
}
|
275
|
+
)
|
276
|
+
end
|
277
|
+
|
220
278
|
it 'accepts "required"' do
|
221
279
|
schema = define_search_class_and_return_schema do
|
222
|
-
option(:id, type:
|
280
|
+
option(:id, type: String, required: true) do |_scope, value|
|
223
281
|
[Post.new(value)]
|
224
282
|
end
|
225
283
|
end
|
@@ -229,11 +287,30 @@ describe SearchObject::Plugin::Graphql do
|
|
229
287
|
expect(result['errors'][0]['message']).to eq("Field 'posts' is missing required arguments: id")
|
230
288
|
end
|
231
289
|
|
290
|
+
it 'accepts "argument_options"' do
|
291
|
+
argument_options = {
|
292
|
+
permission: true
|
293
|
+
}
|
294
|
+
schema = define_search_class_and_return_schema do
|
295
|
+
option(:id, type: String, argument_options: argument_options) do |_scope, value|
|
296
|
+
[Post.new(value)]
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
result = schema.execute '{ posts(id: "2") { id } }'
|
301
|
+
|
302
|
+
expect(result).to eq(
|
303
|
+
'data' => {
|
304
|
+
'posts' => [Post.new('2').to_json]
|
305
|
+
}
|
306
|
+
)
|
307
|
+
end
|
308
|
+
|
232
309
|
it 'accepts description' do
|
233
310
|
schema = define_search_class_and_return_schema do
|
234
311
|
type PostType, null: true
|
235
312
|
|
236
|
-
option('option', type:
|
313
|
+
option('option', type: String, description: 'what this argument does') { [] }
|
237
314
|
end
|
238
315
|
|
239
316
|
result = schema.execute <<-SQL
|
@@ -269,7 +346,7 @@ describe SearchObject::Plugin::Graphql do
|
|
269
346
|
schema = define_search_class_and_return_schema do
|
270
347
|
type PostType, null: true
|
271
348
|
|
272
|
-
option('option_field', type:
|
349
|
+
option('option_field', type: String, camelize: false)
|
273
350
|
end
|
274
351
|
|
275
352
|
result = schema.execute <<-SQL
|
@@ -299,6 +376,40 @@ describe SearchObject::Plugin::Graphql do
|
|
299
376
|
)
|
300
377
|
end
|
301
378
|
|
379
|
+
it 'does not override the default camelize option' do
|
380
|
+
schema = define_search_class_and_return_schema do
|
381
|
+
type PostType, null: true
|
382
|
+
|
383
|
+
option('option_field', type: String)
|
384
|
+
end
|
385
|
+
|
386
|
+
result = schema.execute <<~GRAPHQL
|
387
|
+
{
|
388
|
+
__type(name: "Query") {
|
389
|
+
name
|
390
|
+
fields {
|
391
|
+
args {
|
392
|
+
name
|
393
|
+
}
|
394
|
+
}
|
395
|
+
}
|
396
|
+
}
|
397
|
+
GRAPHQL
|
398
|
+
|
399
|
+
expect(result.to_h).to eq(
|
400
|
+
'data' => {
|
401
|
+
'__type' => {
|
402
|
+
'name' => 'Query',
|
403
|
+
'fields' => [{
|
404
|
+
'args' => [{
|
405
|
+
'name' => 'optionField'
|
406
|
+
}]
|
407
|
+
}]
|
408
|
+
}
|
409
|
+
}
|
410
|
+
)
|
411
|
+
end
|
412
|
+
|
302
413
|
it 'raises error when no type is given' do
|
303
414
|
expect { define_search_class { option :name } }.to raise_error described_class::MissingTypeDefinitionError
|
304
415
|
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: search_object_graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Radoslav Stankov
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.8'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.8'
|
27
27
|
- !ruby/object:Gem::Dependency
|
@@ -140,7 +140,9 @@ files:
|
|
140
140
|
- example/app/graphql/resolvers/post_search.rb
|
141
141
|
- example/app/graphql/schema.rb
|
142
142
|
- example/app/graphql/types/.keep
|
143
|
+
- example/app/graphql/types/base_argument.rb
|
143
144
|
- example/app/graphql/types/base_enum.rb
|
145
|
+
- example/app/graphql/types/base_field.rb
|
144
146
|
- example/app/graphql/types/base_input_object.rb
|
145
147
|
- example/app/graphql/types/base_interface.rb
|
146
148
|
- example/app/graphql/types/base_object.rb
|
@@ -190,7 +192,7 @@ homepage: https://github.com/RStankov/SearchObjectGraphQL
|
|
190
192
|
licenses:
|
191
193
|
- MIT
|
192
194
|
metadata: {}
|
193
|
-
post_install_message:
|
195
|
+
post_install_message:
|
194
196
|
rdoc_options: []
|
195
197
|
require_paths:
|
196
198
|
- lib
|
@@ -206,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
208
|
version: '0'
|
207
209
|
requirements: []
|
208
210
|
rubygems_version: 3.0.3
|
209
|
-
signing_key:
|
211
|
+
signing_key:
|
210
212
|
specification_version: 4
|
211
213
|
summary: Maps search objects to GraphQL resolvers
|
212
214
|
test_files:
|