api-regulator 0.1.10 → 0.1.12

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: 812fb74cb8ccd8e73304ba80e95fb06c1d7bf0c91e78337c0b13cb3cd39ff189
4
- data.tar.gz: e761379ba9cd5b8eb2452a6508d9e6d261f63b9fe68f33e4cab133993a74a742
3
+ metadata.gz: 3ea87a83a858e36a72f427eff54620d66b3fefed07f08fece744d37be1eda137
4
+ data.tar.gz: c4dff679bea1f264fd80f03fdd5114141f92a9558aedd814b1cf24758b76a18e
5
5
  SHA512:
6
- metadata.gz: 8703cb89b3bd4d291c75ded89e4cfe5bb4c9a82d8312822a2011062484548beb8f54b624b968b8a860a8a3ec1ab01f235d914d3cd96f96515eaeaea28c6cc599
7
- data.tar.gz: f51e863849f482218c4fa4e0b918e6973c63745cbee5be20356ad7eac6edb750d17aff5a918c0389bc5b4bb81e2a3efa229551a4ce0062b0d73e55058349d5ab
6
+ metadata.gz: 9ae28b6dd8b6bb657ce4716be12d69592471a3b7e43571302251ff4ba65327eb0526936553cfcfdacf5fb6517ea51b3995aed9cf3e20a241e02397df3235e372
7
+ data.tar.gz: 9cff73f12977b516793c6fc702312b92cf3302dd359fc2ffadaa9e2da4d51b2e1a593fe7835e826367b78d8823cfb06307bd28ed4dc2d2aed4efbc790a279a9a
@@ -0,0 +1,26 @@
1
+ name: Release Gem
2
+
3
+ on:
4
+ workflow_dispatch: # Manual trigger
5
+
6
+ jobs:
7
+ release:
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - name: Checkout code
12
+ uses: actions/checkout@v4
13
+
14
+ - name: Set up Ruby
15
+ uses: ruby/setup-ruby@v1
16
+ with:
17
+ ruby-version: '3.3.6'
18
+ bundler-cache: true
19
+
20
+ - name: Build and Push Gem
21
+ env:
22
+ GEM_HOST_API_KEY: ${{ secrets.GEM_HOST_API_KEY }}
23
+ run: |
24
+ chmod +x bin/release
25
+ bin/release
26
+
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- api-regulator (0.1.10)
4
+ api-regulator (0.1.12)
5
5
  activemodel (~> 8.0)
6
6
  activesupport (~> 8.0)
7
7
 
data/README.md CHANGED
@@ -19,15 +19,7 @@ ApiRegulator relies on **Active Model validations** for parameter validation, ma
19
19
  Share common response schemas across multiple endpoints for DRY definitions.
20
20
 
21
21
  ## ToDo
22
- - [ ] More tests
23
- - [ ] Invalid Configurations (errors for invalid types)
24
- - [ ] Empty Shared Schemas
25
- - [ ] Custom Length and Numericality Options
26
- - [ ] Publish to rubygems
27
- - [ ] See if we're missing any other OpenAPI directives we could use
28
- - [ ] nullable params
29
22
  - [ ] Handling of extra undocumented params
30
- - [ ] Set up CI / CD
31
23
 
32
24
  ## Installation
33
25
 
@@ -149,5 +141,13 @@ Generate OpenAPI documentation using the provided Rake tasks:
149
141
  4. Push to the branch (git push origin feature/new-feature).
150
142
  5. Open a pull request.
151
143
 
144
+ ## Releasing a new version
145
+ `api-regulator` is published to [rubygems](https://rubygems.org/gems/api-regulator). To release a new version,
146
+ 1. In your PR, bump the version in `lib/api_regulator/version.rb`
147
+ 2. Run `bundle install` (this should update your `Gemfile.lock`)
148
+ 3. Go through code review and merge your PR
149
+ 4. Trigger the [`Release Gem`](https://github.com/Stellarcred/api-regulator/actions/workflows/release.yml) workflow from the main branch.
150
+ 5. Verify your new version is available in [rubygems](https://rubygems.org/gems/api-regulator).
151
+
152
152
  ## License
153
153
  This gem is available as open-source software under the [MIT License](https://mit-license.org/).
@@ -17,7 +17,7 @@ module ApiRegulator
17
17
  end
18
18
 
19
19
  def param(name, type = nil, item_type: nil, desc: "", location: :body, **options, &block)
20
- param = Param.new(name, type, item_type: item_type, desc: desc, location: location, **options, &block)
20
+ param = Param.new(name, type, item_type: item_type, desc: desc, location: location, api: self, **options, &block)
21
21
  @params << param
22
22
  end
23
23
 
@@ -8,7 +8,7 @@ module ApiRegulator
8
8
  end
9
9
 
10
10
  validator = validator_class.new(api_params)
11
- unless validator.valid?
11
+ unless validator.valid?(params[:action].to_sym)
12
12
  raise ApiRegulator::ValidationError.new(validator.errors)
13
13
  end
14
14
  end
@@ -78,7 +78,7 @@ module ApiRegulator
78
78
  end
79
79
 
80
80
  # Add to required array if marked as required
81
- schema[:required] << param.name if param.options[:presence]
81
+ schema[:required] << param.name if param.required?
82
82
  end
83
83
 
84
84
  # Remove the required key if it's empty (not needed in OpenAPI spec)
@@ -107,7 +107,7 @@ module ApiRegulator
107
107
  generate_param_schema(p)
108
108
  .merge({
109
109
  name: p.name,
110
- required: p.location == :path || p.options[:presence] || false
110
+ required: p.location == :path || p.required? || false
111
111
  })
112
112
  end
113
113
  end
@@ -1,8 +1,8 @@
1
1
  module ApiRegulator
2
2
  class Param
3
- attr_reader :name, :type, :options, :item_type, :desc, :location, :children
3
+ attr_reader :name, :type, :options, :item_type, :desc, :location, :children, :api
4
4
 
5
- def initialize(name, type = nil, item_type: nil, desc: "", location: :body, **options, &block)
5
+ def initialize(name, type = nil, item_type: nil, desc: "", location: :body, api: nil, **options, &block)
6
6
  @name = name
7
7
  @type = type&.to_sym || (block_given? ? :object : :string)
8
8
  @item_type = item_type
@@ -10,12 +10,13 @@ module ApiRegulator
10
10
  @desc = desc
11
11
  @options = options
12
12
  @children = []
13
+ @api = api
13
14
 
14
15
  instance_eval(&block) if block_given?
15
16
  end
16
17
 
17
18
  def param(name, type = nil, item_type: nil, desc: "", location: :body, **options, &block)
18
- child = Param.new(name, type, item_type: item_type, desc: desc, location: location, **options, &block)
19
+ child = Param.new(name, type, item_type: item_type, desc: desc, location: location, api: api, **options, &block)
19
20
  @children << child
20
21
  end
21
22
 
@@ -37,8 +38,25 @@ module ApiRegulator
37
38
  end
38
39
  end
39
40
 
40
- def required?
41
- !!@options[:presence]
41
+ def api_action_name
42
+ api&.action_name
43
+ end
44
+
45
+ def required?(context = api_action_name)
46
+ return false if @options[:presence].nil?
47
+
48
+ if @options[:presence].is_a?(Hash)
49
+ if @options[:presence][:on].present?
50
+ Array(@options[:presence][:on]).map(&:to_sym).include?(context.to_sym)
51
+ elsif @options[:presence][:except_on].present?
52
+ Array(@options[:presence][:on]).map(&:to_sym).exclude?(context.to_sym)
53
+ else
54
+ # Should we try to handle :if or :unless procs?
55
+ true
56
+ end
57
+ else
58
+ !!@options[:presence]
59
+ end
42
60
  end
43
61
 
44
62
  def body?
@@ -123,7 +123,7 @@ module ApiRegulator
123
123
  end
124
124
 
125
125
  validator = item_validator_class.new(value)
126
- unless validator.valid?
126
+ unless validator.valid?(validation_context)
127
127
  validator.errors.each do |error|
128
128
  nested_attr = "#{attribute}[#{index}].#{error.attribute}"
129
129
  errors.add(nested_attr, error.message)
@@ -202,7 +202,7 @@ module ApiRegulator
202
202
  validator = nested_validator_class.new(raw_value)
203
203
 
204
204
  # If validation fails, propagate errors
205
- unless validator.valid?
205
+ unless validator.valid?(validation_context)
206
206
  validator.errors.each do |error|
207
207
  nested_attr = "#{attribute}.#{error.attribute}"
208
208
  errors.add(nested_attr, error.message)
@@ -271,6 +271,7 @@ module ApiRegulator
271
271
  include AttributeDefinitionMixin
272
272
 
273
273
  def initialize(attributes = {})
274
+ attributes = {} if attributes.blank?
274
275
  @raw_attributes = attributes.deep_symbolize_keys
275
276
  self.class.defined_attributes
276
277
  allowed_attributes = attributes.slice(*self.class.defined_attributes.map(&:to_sym))
@@ -287,11 +288,11 @@ module ApiRegulator
287
288
  validator_class = get(controller, action, code)
288
289
 
289
290
  unless validator_class
290
- raise "No validator found"
291
+ raise "No validator found for controller: #{controller}, action: #{action}, code: #{code}"
291
292
  end
292
293
 
293
294
  validator = validator_class.new(body)
294
- unless validator.valid?
295
+ unless validator.valid?(:response) # using :response for validation context
295
296
  raise ApiRegulator::ValidationError.new(validator.errors)
296
297
  end
297
298
  end
@@ -1,3 +1,3 @@
1
1
  module ApiRegulator
2
- VERSION = "0.1.10"
2
+ VERSION = "0.1.12"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api-regulator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.12
5
5
  platform: ruby
6
6
  authors:
7
7
  - Geoff Massanek
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-01-15 00:00:00.000000000 Z
11
+ date: 2025-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -130,6 +130,7 @@ executables: []
130
130
  extensions: []
131
131
  extra_rdoc_files: []
132
132
  files:
133
+ - ".github/workflows/release.yml"
133
134
  - ".github/workflows/spec.yml"
134
135
  - ".gitignore"
135
136
  - ".rspec"