filterable-by 0.5.2 → 0.6.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
  SHA256:
3
- metadata.gz: 8a45bdeb246550581221e6a721af41f27e355b9d87d1fd8dd791731142bba9cd
4
- data.tar.gz: 06f4640997ef9fbfc88b6cedb943cf0840c0e643c7012ffd441700e52495113e
3
+ metadata.gz: e0b24315b28f7b165d4158fe6ef43860a346e342732ef53ffd02595bbd34e511
4
+ data.tar.gz: 90b3ec26188bf9337758320f222730bfaf19f0b2525bfec8b25080f0c6d5f258
5
5
  SHA512:
6
- metadata.gz: c292090ad77af10f1729f4ad652fb84595fe20d866bf4ab221d642465fc56fa4073dc7cc2ed2469b9a92169e418f2860f44ea4702bbf4cbf34e1591b07645077
7
- data.tar.gz: '08a1ec2870b5da50e5b41b35a06e8adf5b72f375c50fb2bc3009d9a4c17f5140b4f44f44ffc764aa8f73703a9f041610b37075ebbedabfd84db362690562b9a2'
6
+ metadata.gz: c84a6573838b6acd0f7c9136cfdd2853146edaff7dd9e9fb74967bd7dedce782a54ed800674489717ade4b6923d882de9f53ba4ad0ff3d7e8444807e925435a0
7
+ data.tar.gz: 11aa00c16d9e85daab300757381e783d6006fa874d3a33a7f40a412c176a6ca75120cee413409a1434c59d33658443f2f3af68168abfaa99eb6287db29509ee6
@@ -1,4 +1,4 @@
1
- name: Ruby
1
+ name: Test
2
2
 
3
3
  on:
4
4
  push:
@@ -7,11 +7,14 @@ on:
7
7
  branches: [main]
8
8
 
9
9
  jobs:
10
- test:
10
+ ruby:
11
11
  runs-on: ubuntu-latest
12
12
  strategy:
13
13
  matrix:
14
- ruby-version: ["2.6", "2.7", "3.0"]
14
+ ruby-version: ["2.7", "3.0", "3.1"]
15
+ gemfiles: ["Gemfile", "Gemfile.rails6"]
16
+ env:
17
+ BUNDLE_GEMFILE: ${{ matrix.gemfile }}
15
18
  steps:
16
19
  - uses: actions/checkout@v2
17
20
  - uses: ruby/setup-ruby@v1
data/.rubocop.yml CHANGED
@@ -6,6 +6,6 @@ inherit_mode:
6
6
  - Exclude
7
7
 
8
8
  AllCops:
9
- TargetRubyVersion: "2.6"
9
+ TargetRubyVersion: "2.7"
10
10
  Naming/FileName:
11
11
  Exclude: [lib/filterable-by.rb]
data/Gemfile.lock CHANGED
@@ -1,86 +1,77 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- filterable-by (0.5.2)
4
+ filterable-by (0.6.1)
5
5
  activerecord
6
6
  activesupport
7
7
 
8
8
  GEM
9
9
  remote: http://rubygems.org/
10
10
  specs:
11
- activemodel (6.1.3)
12
- activesupport (= 6.1.3)
13
- activerecord (6.1.3)
14
- activemodel (= 6.1.3)
15
- activesupport (= 6.1.3)
16
- activesupport (6.1.3)
11
+ activemodel (7.0.2.3)
12
+ activesupport (= 7.0.2.3)
13
+ activerecord (7.0.2.3)
14
+ activemodel (= 7.0.2.3)
15
+ activesupport (= 7.0.2.3)
16
+ activesupport (7.0.2.3)
17
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
18
18
  i18n (>= 1.6, < 2)
19
19
  minitest (>= 5.1)
20
20
  tzinfo (~> 2.0)
21
- zeitwerk (~> 2.3)
22
21
  ast (2.4.2)
23
- concurrent-ruby (1.1.8)
24
- diff-lcs (1.4.4)
25
- i18n (1.8.9)
22
+ concurrent-ruby (1.1.9)
23
+ diff-lcs (1.5.0)
24
+ i18n (1.10.0)
26
25
  concurrent-ruby (~> 1.0)
27
- minitest (5.14.4)
28
- parallel (1.20.1)
29
- parser (3.0.0.0)
26
+ minitest (5.15.0)
27
+ parallel (1.21.0)
28
+ parser (3.1.1.0)
30
29
  ast (~> 2.4.1)
31
- rack (2.2.3)
32
- rainbow (3.0.0)
33
- rake (13.0.3)
34
- regexp_parser (2.1.1)
35
- rexml (3.2.4)
36
- rspec (3.10.0)
37
- rspec-core (~> 3.10.0)
38
- rspec-expectations (~> 3.10.0)
39
- rspec-mocks (~> 3.10.0)
40
- rspec-core (3.10.1)
41
- rspec-support (~> 3.10.0)
42
- rspec-expectations (3.10.1)
30
+ rainbow (3.1.1)
31
+ rake (13.0.6)
32
+ regexp_parser (2.2.1)
33
+ rexml (3.2.5)
34
+ rspec (3.11.0)
35
+ rspec-core (~> 3.11.0)
36
+ rspec-expectations (~> 3.11.0)
37
+ rspec-mocks (~> 3.11.0)
38
+ rspec-core (3.11.0)
39
+ rspec-support (~> 3.11.0)
40
+ rspec-expectations (3.11.0)
43
41
  diff-lcs (>= 1.2.0, < 2.0)
44
- rspec-support (~> 3.10.0)
45
- rspec-mocks (3.10.2)
42
+ rspec-support (~> 3.11.0)
43
+ rspec-mocks (3.11.0)
46
44
  diff-lcs (>= 1.2.0, < 2.0)
47
- rspec-support (~> 3.10.0)
48
- rspec-support (3.10.2)
49
- rubocop (1.11.0)
45
+ rspec-support (~> 3.11.0)
46
+ rspec-support (3.11.0)
47
+ rubocop (1.26.0)
50
48
  parallel (~> 1.10)
51
- parser (>= 3.0.0.0)
49
+ parser (>= 3.1.0.0)
52
50
  rainbow (>= 2.2.2, < 4.0)
53
51
  regexp_parser (>= 1.8, < 3.0)
54
52
  rexml
55
- rubocop-ast (>= 1.2.0, < 2.0)
53
+ rubocop-ast (>= 1.16.0, < 2.0)
56
54
  ruby-progressbar (~> 1.7)
57
55
  unicode-display_width (>= 1.4.0, < 3.0)
58
- rubocop-ast (1.4.1)
59
- parser (>= 2.7.1.5)
60
- rubocop-bsm (0.5.4)
56
+ rubocop-ast (1.16.0)
57
+ parser (>= 3.1.1.0)
58
+ rubocop-bsm (0.6.0)
61
59
  rubocop (~> 1.0)
62
60
  rubocop-performance
63
- rubocop-rails
64
61
  rubocop-rake
65
62
  rubocop-rspec
66
- rubocop-performance (1.10.1)
67
- rubocop (>= 0.90.0, < 2.0)
63
+ rubocop-performance (1.13.3)
64
+ rubocop (>= 1.7.0, < 2.0)
68
65
  rubocop-ast (>= 0.4.0)
69
- rubocop-rails (2.9.1)
70
- activesupport (>= 4.2.0)
71
- rack (>= 1.1)
72
- rubocop (>= 0.90.0, < 2.0)
73
- rubocop-rake (0.5.1)
74
- rubocop
75
- rubocop-rspec (2.2.0)
66
+ rubocop-rake (0.6.0)
76
67
  rubocop (~> 1.0)
77
- rubocop-ast (>= 1.1.0)
68
+ rubocop-rspec (2.9.0)
69
+ rubocop (~> 1.19)
78
70
  ruby-progressbar (1.11.0)
79
71
  sqlite3 (1.4.2)
80
72
  tzinfo (2.0.4)
81
73
  concurrent-ruby (~> 1.0)
82
- unicode-display_width (2.0.0)
83
- zeitwerk (2.4.2)
74
+ unicode-display_width (2.1.0)
84
75
 
85
76
  PLATFORMS
86
77
  ruby
@@ -94,4 +85,4 @@ DEPENDENCIES
94
85
  sqlite3
95
86
 
96
87
  BUNDLED WITH
97
- 2.1.4
88
+ 2.3.6
data/Gemfile.rails6 ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
3
+
4
+ gem 'activerecord', '~> 6.1'
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ filterable-by (0.6.1)
5
+ activerecord
6
+ activesupport
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activemodel (6.1.4.7)
12
+ activesupport (= 6.1.4.7)
13
+ activerecord (6.1.4.7)
14
+ activemodel (= 6.1.4.7)
15
+ activesupport (= 6.1.4.7)
16
+ activesupport (6.1.4.7)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (>= 1.6, < 2)
19
+ minitest (>= 5.1)
20
+ tzinfo (~> 2.0)
21
+ zeitwerk (~> 2.3)
22
+ ast (2.4.2)
23
+ concurrent-ruby (1.1.9)
24
+ diff-lcs (1.5.0)
25
+ i18n (1.10.0)
26
+ concurrent-ruby (~> 1.0)
27
+ minitest (5.15.0)
28
+ parallel (1.21.0)
29
+ parser (3.1.1.0)
30
+ ast (~> 2.4.1)
31
+ rainbow (3.1.1)
32
+ rake (13.0.6)
33
+ regexp_parser (2.2.1)
34
+ rexml (3.2.5)
35
+ rspec (3.11.0)
36
+ rspec-core (~> 3.11.0)
37
+ rspec-expectations (~> 3.11.0)
38
+ rspec-mocks (~> 3.11.0)
39
+ rspec-core (3.11.0)
40
+ rspec-support (~> 3.11.0)
41
+ rspec-expectations (3.11.0)
42
+ diff-lcs (>= 1.2.0, < 2.0)
43
+ rspec-support (~> 3.11.0)
44
+ rspec-mocks (3.11.0)
45
+ diff-lcs (>= 1.2.0, < 2.0)
46
+ rspec-support (~> 3.11.0)
47
+ rspec-support (3.11.0)
48
+ rubocop (1.26.0)
49
+ parallel (~> 1.10)
50
+ parser (>= 3.1.0.0)
51
+ rainbow (>= 2.2.2, < 4.0)
52
+ regexp_parser (>= 1.8, < 3.0)
53
+ rexml
54
+ rubocop-ast (>= 1.16.0, < 2.0)
55
+ ruby-progressbar (~> 1.7)
56
+ unicode-display_width (>= 1.4.0, < 3.0)
57
+ rubocop-ast (1.16.0)
58
+ parser (>= 3.1.1.0)
59
+ rubocop-bsm (0.6.0)
60
+ rubocop (~> 1.0)
61
+ rubocop-performance
62
+ rubocop-rake
63
+ rubocop-rspec
64
+ rubocop-performance (1.13.3)
65
+ rubocop (>= 1.7.0, < 2.0)
66
+ rubocop-ast (>= 0.4.0)
67
+ rubocop-rake (0.6.0)
68
+ rubocop (~> 1.0)
69
+ rubocop-rspec (2.9.0)
70
+ rubocop (~> 1.19)
71
+ ruby-progressbar (1.11.0)
72
+ sqlite3 (1.4.2)
73
+ tzinfo (2.0.4)
74
+ concurrent-ruby (~> 1.0)
75
+ unicode-display_width (2.1.0)
76
+ zeitwerk (2.5.4)
77
+
78
+ PLATFORMS
79
+ x86_64-linux
80
+
81
+ DEPENDENCIES
82
+ activerecord (~> 6.1)
83
+ bundler
84
+ filterable-by!
85
+ rake
86
+ rspec
87
+ rubocop-bsm
88
+ sqlite3
89
+
90
+ BUNDLED WITH
91
+ 2.3.9
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Filterable By
2
2
 
3
+ [![Test](https://github.com/bsm/filterable-by/actions/workflows/test.yml/badge.svg)](https://github.com/bsm/filterable-by/actions/workflows/test.yml)
4
+
3
5
  ActiveRecord plugin to parse e.g. a `filter` query parameter apply scopes. Useful for [JSON-API][jsonapi] compatibility.
4
6
 
5
7
  [jsonapi]: http://jsonapi.org/format/#fetching-filtering
@@ -15,15 +17,15 @@ class Comment < ActiveRecord::Base
15
17
  belongs_to :post
16
18
 
17
19
  filterable_by :post_id, :user_id
18
- filterable_by :post_author_id do |scope, value|
19
- scope.joins(:posts).where(:'posts.author_id' => value)
20
+ filterable_by :post_author_id do |value|
21
+ joins(:posts).where(:'posts.author_id' => value)
20
22
  end
21
- filterable_by :only do |scope, value, **opts|
23
+ filterable_by :only do |value, **opts|
22
24
  case value
23
25
  when 'mine'
24
- scope.where(user_id: opts[:user_id]) if opts[:user_id]
26
+ where(user_id: opts[:user_id]) if opts[:user_id]
25
27
  else
26
- scope
28
+ all
27
29
  end
28
30
  end
29
31
  end
@@ -37,6 +39,12 @@ Simple use cases:
37
39
  Comment.filter_by({ 'post_id' => '1' })
38
40
  # => WHERE post_id = 1
39
41
 
42
+ Comment.filter_by({ 'post_id' => ['1', '2'] })
43
+ # => WHERE post_id IN (1, 2)
44
+
45
+ Comment.filter_by({ 'post_id_not' => '3' })
46
+ # => WHERE post_id != 3
47
+
40
48
  Comment.filter_by({ 'user_id' => '2', 'ignored' => '3' })
41
49
  # => WHERE user_id = 2
42
50
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'filterable-by'
3
- s.version = '0.5.2'
3
+ s.version = '0.6.1'
4
4
  s.authors = ['Dimitrij Denissenko']
5
5
  s.email = ['dimitrij@blacksquaremedia.com']
6
6
  s.summary = 'Generate white-listed filter scopes from URL parameter values'
@@ -11,7 +11,7 @@ Gem::Specification.new do |s|
11
11
  s.files = `git ls-files -z`.split("\x0").reject {|f| f.match(%r{^spec/}) }
12
12
  s.test_files = `git ls-files -z -- spec/*`.split("\x0")
13
13
  s.require_paths = ['lib']
14
- s.required_ruby_version = '>= 2.6'
14
+ s.required_ruby_version = '>= 2.7'
15
15
 
16
16
  s.add_dependency 'activerecord'
17
17
  s.add_dependency 'activesupport'
@@ -21,4 +21,5 @@ Gem::Specification.new do |s|
21
21
  s.add_development_dependency 'rspec'
22
22
  s.add_development_dependency 'rubocop-bsm'
23
23
  s.add_development_dependency 'sqlite3'
24
+ s.metadata['rubygems_mfa_required'] = 'true'
24
25
  end
data/lib/filterable_by.rb CHANGED
@@ -13,6 +13,33 @@ module ActiveRecord
13
13
  end
14
14
  end
15
15
 
16
+ def self.merge(scope, unscoped, hash, name, **opts, &block)
17
+ key = name
18
+ positive = normalize(hash[key]) if hash.key?(key)
19
+ if positive.present?
20
+ sub = block.arity == 2 ? yield(unscoped, positive, **opts) : yield(positive, **opts)
21
+ return nil unless sub
22
+
23
+ scope = scope.merge(sub)
24
+ end
25
+
26
+ key = "#{name}_not"
27
+ negative = normalize(hash[key]) if hash.key?(key)
28
+ if negative.present?
29
+ sub = block.arity == 2 ? yield(unscoped, negative, **opts) : yield(negative, **opts)
30
+ return nil unless sub
31
+
32
+ if sub.respond_to?(:invert_where)
33
+ sub = sub.invert_where
34
+ else
35
+ sub.where_clause = sub.where_clause.invert
36
+ end
37
+ scope = scope.merge(sub)
38
+ end
39
+
40
+ scope
41
+ end
42
+
16
43
  module ClassMethods
17
44
  def self.extended(base) # :nodoc:
18
45
  base.class_attribute :_filterable_by_config, instance_accessor: false, instance_predicate: false
@@ -26,28 +53,29 @@ module ActiveRecord
26
53
  end
27
54
 
28
55
  def filterable_by(*names, &block)
56
+ if block && block.arity > 1
57
+ ActiveSupport::Deprecation.warn('using scope in filterable_by blocks is deprecated. Please use filterable_by(:x) {|val| where(field: val) } instead.')
58
+ end
59
+
29
60
  names.each do |name|
30
- _filterable_by_config[name.to_s] = block || ->(scope, value, **) { scope.where(name.to_sym => value) }
61
+ _filterable_by_config[name.to_s] = block || ->(value, **) { where(name.to_sym => value) }
31
62
  end
32
63
  end
33
64
 
34
- # @param [Hash] hash the filter params
65
+ # @param [Hash|ActionController::Parameters] the filter params
35
66
  # @return [ActiveRecord::Relation] the scoped relation
36
67
  def filter_by(hash = nil, **opts)
37
68
  if hash.nil?
38
69
  hash = opts
39
70
  opts = {}
40
71
  end
72
+
41
73
  scope = all
42
- return scope unless hash.is_a?(Hash)
74
+ return scope unless hash.respond_to?(:key?) && hash.respond_to?(:[])
43
75
 
44
76
  _filterable_by_config.each do |name, block|
45
- next unless hash.key?(name)
46
-
47
- value = FilterableBy.normalize(hash[name])
48
- next if value.blank?
49
-
50
- scope = block.call(scope, value, **opts)
77
+ scope = FilterableBy.merge(scope, unscoped, hash, name, **opts, &block)
78
+ break unless scope
51
79
  end
52
80
 
53
81
  scope || none
@@ -8,8 +8,8 @@ describe ActiveRecord::FilterableBy do
8
8
  let(:bpost) { POSTS[:bobs] }
9
9
 
10
10
  it 'has config' do
11
- expect(Comment.send(:_filterable_by_config).count).to eq(3)
12
- expect(Rating.send(:_filterable_by_config).count).to eq(2)
11
+ expect(Comment.send(:_filterable_by_config).count).to eq(5)
12
+ expect(Rating.send(:_filterable_by_config).count).to eq(4)
13
13
  expect(Post.send(:_filterable_by_config).count).to eq(2)
14
14
  end
15
15
 
@@ -50,9 +50,23 @@ describe ActiveRecord::FilterableBy do
50
50
  expect(scope.pluck(:title)).to match_array(%w[AB BB])
51
51
  end
52
52
 
53
+ it 'generates negated scopes' do
54
+ expect(Comment.filter_by('author_id_not' => alice.id).pluck(:title)).to match_array(%w[BA BB])
55
+ expect(Comment.filter_by('author_id_not' => [alice.id, bob.id]).pluck(:title)).to match_array(%w[])
56
+ expect(Comment.filter_by('post_id_not' => apost.id).pluck(:title)).to match_array(%w[AB BB])
57
+ expect(Comment.filter_by('post_author_id_not' => alice.id).pluck(:title)).to match_array(%w[AB BB])
58
+ expect(Comment.filter_by('author_id' => bob.id, 'post_id_not' => bpost.id).pluck(:title)).to match_array(['BA'])
59
+ end
60
+
53
61
  it 'combines with other scopes' do
54
62
  scope = Comment.where(author_id: alice.id).filter_by('post_id' => apost.id)
55
63
  expect(scope.pluck(:title)).to match_array(['AA'])
64
+
65
+ expect(alice.posts.filter_by('post_id' => apost.id).count).to be(1)
66
+ expect(alice.posts.filter_by('author_id' => alice.id).count).to be(1)
67
+ expect(alice.posts.filter_by('author_id_not' => bob.id).count).to be(1)
68
+ expect(alice.posts.filter_by('author_id' => bob.id).count).to be_zero
69
+ expect(alice.posts.filter_by('author_id_not' => alice.id).count).to be_zero
56
70
  end
57
71
 
58
72
  it 'allows custom options' do
@@ -77,4 +91,10 @@ describe ActiveRecord::FilterableBy do
77
91
  expect(Post.filter_by('post_id' => bpost.id).count).to eq(2)
78
92
  expect(Rating.filter_by('post_author_id' => bob.id).count).to eq(1)
79
93
  end
94
+
95
+ it 'supports deprecated scoping' do
96
+ expect(Comment.filter_by('deprecated' => alice.id).pluck(:title)).to match_array(%w[AA AB])
97
+ expect(Comment.filter_by('deprecated_with_opts' => alice.id).pluck(:title)).to match_array(%w[AA AB])
98
+ expect(Comment.filter_by('deprecated_not' => alice.id).pluck(:title)).to match_array(%w[BA BB])
99
+ end
80
100
  end
data/spec/spec_helper.rb CHANGED
@@ -22,18 +22,19 @@ ActiveRecord::Base.connection.instance_eval do
22
22
  end
23
23
 
24
24
  class Author < ActiveRecord::Base
25
+ has_many :posts
25
26
  end
26
27
 
27
28
  class Post < ActiveRecord::Base
28
29
  belongs_to :author
29
30
 
30
31
  filterable_by :author_id
31
- filterable_by :only do |scope, value, **opts|
32
+ filterable_by :only do |value, **opts|
32
33
  case value
33
34
  when 'me'
34
- scope.where(author_id: opts[:user_id]) if opts[:user_id]
35
+ where(author_id: opts[:user_id]) if opts[:user_id]
35
36
  else
36
- scope
37
+ all
37
38
  end
38
39
  end
39
40
  end
@@ -43,11 +44,20 @@ class Feedback < ActiveRecord::Base
43
44
  belongs_to :post
44
45
 
45
46
  filterable_by :post_id, :author_id
47
+
48
+ ActiveSupport::Deprecation.silence do
49
+ filterable_by :deprecated do |scope, value|
50
+ scope.where(author_id: value)
51
+ end
52
+ filterable_by :deprecated_with_opts do |scope, value, **_opts|
53
+ scope.where(author_id: value)
54
+ end
55
+ end
46
56
  end
47
57
 
48
58
  class Comment < Feedback
49
- filterable_by :post_author_id do |scope, value|
50
- scope.joins(:post).where(Post.arel_table[:author_id].eq(value))
59
+ filterable_by :post_author_id do |value|
60
+ joins(:post).where(Post.arel_table[:author_id].eq(value))
51
61
  end
52
62
  end
53
63
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: filterable-by
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dimitrij Denissenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-02 00:00:00.000000000 Z
11
+ date: 2022-03-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -115,11 +115,13 @@ executables: []
115
115
  extensions: []
116
116
  extra_rdoc_files: []
117
117
  files:
118
- - ".github/workflows/ruby.yml"
118
+ - ".github/workflows/test.yml"
119
119
  - ".gitignore"
120
120
  - ".rubocop.yml"
121
121
  - Gemfile
122
122
  - Gemfile.lock
123
+ - Gemfile.rails6
124
+ - Gemfile.rails6.lock
123
125
  - LICENSE
124
126
  - README.md
125
127
  - Rakefile
@@ -131,7 +133,8 @@ files:
131
133
  homepage: https://github.com/bsm/filterable-by
132
134
  licenses:
133
135
  - MIT
134
- metadata: {}
136
+ metadata:
137
+ rubygems_mfa_required: 'true'
135
138
  post_install_message:
136
139
  rdoc_options: []
137
140
  require_paths:
@@ -140,14 +143,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
140
143
  requirements:
141
144
  - - ">="
142
145
  - !ruby/object:Gem::Version
143
- version: '2.6'
146
+ version: '2.7'
144
147
  required_rubygems_version: !ruby/object:Gem::Requirement
145
148
  requirements:
146
149
  - - ">="
147
150
  - !ruby/object:Gem::Version
148
151
  version: '0'
149
152
  requirements: []
150
- rubygems_version: 3.1.4
153
+ rubygems_version: 3.3.3
151
154
  signing_key:
152
155
  specification_version: 4
153
156
  summary: Generate white-listed filter scopes from URL parameter values