api-regulator 0.1.12 → 0.1.13

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: 3ea87a83a858e36a72f427eff54620d66b3fefed07f08fece744d37be1eda137
4
- data.tar.gz: c4dff679bea1f264fd80f03fdd5114141f92a9558aedd814b1cf24758b76a18e
3
+ metadata.gz: dd01d986f35199767ed09aeca6b5a5b0b19441113fa10b2fa5b34a511a4773ab
4
+ data.tar.gz: 02e722bd4b5df9a728a9ff1a339922cd891e9ae0eca9bf516b653bab3132c379
5
5
  SHA512:
6
- metadata.gz: 9ae28b6dd8b6bb657ce4716be12d69592471a3b7e43571302251ff4ba65327eb0526936553cfcfdacf5fb6517ea51b3995aed9cf3e20a241e02397df3235e372
7
- data.tar.gz: 9cff73f12977b516793c6fc702312b92cf3302dd359fc2ffadaa9e2da4d51b2e1a593fe7835e826367b78d8823cfb06307bd28ed4dc2d2aed4efbc790a279a9a
6
+ metadata.gz: 42b77076b73dffc526ef004bc182c63cd3c45bbfaa8d5102796a92964c951da6351311bce75a89955f74cb851221b566c3188f5477ccb51355c09c588d70fc59
7
+ data.tar.gz: 50888b26e95137d81dad5b8cb2777a065613f87fe537e2a1b456bcfe986b41a9e2fa45ce23c77688098421c4e5f8aebe31184f3065764e83dbf44d3c9e6caa4b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- api-regulator (0.1.12)
4
+ api-regulator (0.1.13)
5
5
  activemodel (~> 8.0)
6
6
  activesupport (~> 8.0)
7
7
 
@@ -81,26 +81,27 @@ GEM
81
81
  uri (>= 0.13.1)
82
82
  base64 (0.2.0)
83
83
  benchmark (0.4.0)
84
- bigdecimal (3.1.8)
84
+ bigdecimal (3.1.9)
85
85
  builder (3.3.0)
86
86
  byebug (11.1.3)
87
- concurrent-ruby (1.3.4)
88
- connection_pool (2.4.1)
87
+ concurrent-ruby (1.3.5)
88
+ connection_pool (2.5.0)
89
89
  crass (1.0.6)
90
90
  date (3.4.1)
91
91
  diff-lcs (1.5.1)
92
92
  drb (2.2.1)
93
- erubi (1.13.0)
93
+ erubi (1.13.1)
94
94
  globalid (1.2.1)
95
95
  activesupport (>= 6.1)
96
- i18n (1.14.6)
96
+ i18n (1.14.7)
97
97
  concurrent-ruby (~> 1.0)
98
- io-console (0.7.2)
99
- irb (1.14.1)
98
+ io-console (0.8.0)
99
+ irb (1.15.1)
100
+ pp (>= 0.6.0)
100
101
  rdoc (>= 4.0.0)
101
102
  reline (>= 0.4.2)
102
- logger (1.6.3)
103
- loofah (2.23.1)
103
+ logger (1.6.5)
104
+ loofah (2.24.0)
104
105
  crass (~> 1.0.2)
105
106
  nokogiri (>= 1.12.0)
106
107
  mail (2.8.1)
@@ -112,7 +113,7 @@ GEM
112
113
  mini_mime (1.1.5)
113
114
  mini_portile2 (2.8.8)
114
115
  minitest (5.25.4)
115
- net-imap (0.5.2)
116
+ net-imap (0.5.5)
116
117
  date
117
118
  net-protocol
118
119
  net-pop (0.1.2)
@@ -122,18 +123,23 @@ GEM
122
123
  net-smtp (0.5.0)
123
124
  net-protocol
124
125
  nio4r (2.7.4)
125
- nokogiri (1.17.2)
126
+ nokogiri (1.18.2)
126
127
  mini_portile2 (~> 2.8.2)
127
128
  racc (~> 1.4)
128
- nokogiri (1.17.2-arm64-darwin)
129
+ nokogiri (1.18.2-arm64-darwin)
129
130
  racc (~> 1.4)
130
- psych (5.2.0)
131
+ pp (0.6.2)
132
+ prettyprint
133
+ prettyprint (0.2.0)
134
+ psych (5.2.3)
135
+ date
131
136
  stringio
132
137
  racc (1.8.1)
133
138
  rack (3.1.8)
134
- rack-session (2.0.0)
139
+ rack-session (2.1.0)
140
+ base64 (>= 0.1.0)
135
141
  rack (>= 3.0.0)
136
- rack-test (2.1.0)
142
+ rack-test (2.2.0)
137
143
  rack (>= 1.3)
138
144
  rackup (2.2.1)
139
145
  rack (>= 3)
@@ -167,9 +173,9 @@ GEM
167
173
  thor (~> 1.0, >= 1.2.2)
168
174
  zeitwerk (~> 2.6)
169
175
  rake (13.2.1)
170
- rdoc (6.8.1)
176
+ rdoc (6.11.0)
171
177
  psych (>= 4.0.0)
172
- reline (0.5.11)
178
+ reline (0.6.0)
173
179
  io-console (~> 0.5)
174
180
  rspec (3.13.0)
175
181
  rspec-core (~> 3.13.0)
@@ -191,8 +197,8 @@ GEM
191
197
  rspec-expectations (~> 3.10)
192
198
  rspec-mocks (~> 3.10)
193
199
  rspec-support (~> 3.10)
194
- rspec-support (3.13.1)
195
- securerandom (0.4.0)
200
+ rspec-support (3.13.2)
201
+ securerandom (0.4.1)
196
202
  stringio (3.1.2)
197
203
  thor (1.3.2)
198
204
  timeout (0.4.3)
@@ -200,7 +206,8 @@ GEM
200
206
  concurrent-ruby (~> 1.0)
201
207
  uri (1.0.2)
202
208
  useragent (0.16.11)
203
- websocket-driver (0.7.6)
209
+ websocket-driver (0.7.7)
210
+ base64
204
211
  websocket-extensions (>= 0.1.0)
205
212
  websocket-extensions (0.1.5)
206
213
  zeitwerk (2.7.1)
@@ -46,13 +46,14 @@ module ApiRegulator
46
46
  return false if @options[:presence].nil?
47
47
 
48
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)
49
+ if context.nil?
50
+ true # No context provided
51
+ elsif @options[:presence][:required_on].present?
52
+ Array(@options[:presence][:required_on]).map(&:to_sym).include?(context.to_sym)
53
+ elsif @options[:presence][:required_except_on].present?
54
+ Array(@options[:presence][:required_except_on]).map(&:to_sym).exclude?(context.to_sym)
53
55
  else
54
- # Should we try to handle :if or :unless procs?
55
- true
56
+ true # TODO: should we try to handle :if or :unless procs?
56
57
  end
57
58
  else
58
59
  !!@options[:presence]
@@ -10,39 +10,43 @@ module ApiRegulator
10
10
  end
11
11
 
12
12
  class_methods do
13
- def define_attribute_and_validations(param, parent_key = nil)
13
+ def define_attribute_and_validations(param, parent_key: nil, validation_context: nil)
14
14
  # Construct the full key
15
15
  full_key = parent_key ? "#{parent_key}.#{param.name}".to_sym : param.name.to_sym
16
16
 
17
17
  case param.type
18
18
  when :array
19
- define_array_validations(param, full_key)
19
+ define_array_validations(param, full_key, validation_context)
20
20
  when :object
21
- define_object_validations(param, full_key)
21
+ define_object_validations(param, full_key, validation_context)
22
22
  else
23
- define_scalar_validations(param, full_key)
23
+ define_scalar_validations(param, full_key, validation_context)
24
24
  end
25
25
  end
26
26
 
27
- def define_scalar_validations(param, full_key)
27
+ def define_scalar_validations(param, full_key, validation_context)
28
28
  # Define scalar attributes
29
29
  attribute full_key, param.type if param.type
30
30
  self.defined_attributes += [full_key]
31
31
 
32
32
  param.options.each do |option, value|
33
- validates full_key, option => value, allow_blank: !param.required?
33
+ validates full_key, option => value, if: ->(record) {
34
+ param.required?(validation_context) || record.raw_attributes.key?(param.name)
35
+ }
34
36
  end
35
37
 
36
38
  # Add type-specific validations
37
- validate -> { validate_boolean(full_key) } if param.type == :boolean
38
- validate -> { validate_integer(full_key) } if param.type == :integer
39
- validate -> { validate_string(full_key) } if param.type == :string
39
+ case param.type
40
+ when :boolean then validate -> { validate_boolean(full_key) }
41
+ when :integer then validate -> { validate_integer(full_key) }
42
+ when :string then validate -> { validate_string(full_key) }
43
+ end
40
44
  end
41
45
 
42
46
 
43
- def define_object_validations(param, full_key)
47
+ def define_object_validations(param, full_key, validation_context)
44
48
  # Build nested validator class
45
- nested_validator_class = build_nested_validator_class(param.children, param.name, self)
49
+ nested_validator_class = build_nested_validator_class(param.children, param.name, self, validation_context)
46
50
 
47
51
  # Add a custom validation for the nested object
48
52
  validate -> { validate_nested_object(full_key, nested_validator_class, param) }
@@ -51,10 +55,10 @@ module ApiRegulator
51
55
  nested_validators[full_key] = nested_validator_class
52
56
  end
53
57
 
54
- def define_array_validations(param, full_key)
58
+ def define_array_validations(param, full_key, validation_context)
55
59
  if param.children.any?
56
60
  # Build a nested validator class for array items
57
- item_validator_class = build_nested_validator_class(param.children, param.name, self)
61
+ item_validator_class = build_nested_validator_class(param.children, param.name, self, validation_context)
58
62
  validate -> { validate_array_of_objects(full_key, item_validator_class, param) }
59
63
 
60
64
  # Store the nested validator
@@ -68,7 +72,7 @@ module ApiRegulator
68
72
  end
69
73
  end
70
74
 
71
- def build_nested_validator_class(children, parent_key, parent_class)
75
+ def build_nested_validator_class(children, parent_key, parent_class, validation_context)
72
76
  # Create a unique class name based on the parent key
73
77
  class_name = "#{parent_key.to_s.camelize}"
74
78
 
@@ -83,6 +87,8 @@ module ApiRegulator
83
87
  include ActiveModel::Attributes
84
88
  include AttributeDefinitionMixin
85
89
 
90
+ attr_reader :raw_attributes
91
+
86
92
  def initialize(attributes = {})
87
93
  @raw_attributes = attributes
88
94
  allowed_attributes = attributes.slice(*self.class.defined_attributes.map(&:to_sym))
@@ -91,7 +97,7 @@ module ApiRegulator
91
97
 
92
98
  # Add child attributes and validations
93
99
  children.each do |child|
94
- define_attribute_and_validations(child)
100
+ define_attribute_and_validations(child, validation_context:)
95
101
  end
96
102
  end
97
103
 
@@ -242,7 +248,7 @@ module ApiRegulator
242
248
  def self.build_all(api_definitions)
243
249
  api_definitions.each do |api_definition|
244
250
  class_name = "#{api_definition.controller_path}/#{api_definition.action_name}".gsub("/", "_").camelcase
245
- validator_class = build_class(api_definition.params)
251
+ validator_class = build_class(api_definition.params, api_definition.action_name)
246
252
  @validators[[api_definition.controller_path, api_definition.action_name]] = validator_class
247
253
  Validator.const_set(class_name, validator_class)
248
254
  end
@@ -253,7 +259,7 @@ module ApiRegulator
253
259
  api_definition.responses.each do |code, params|
254
260
  class_name = "#{api_definition.controller_path}/#{api_definition.action_name}/Response#{code}".gsub("/", "_").camelcase
255
261
 
256
- validator_class = build_class(params.children)
262
+ validator_class = build_class(params.children, api_definition.action_name)
257
263
  @validators[[api_definition.controller_path, api_definition.action_name, code]] = validator_class
258
264
  Validator.const_set(class_name, validator_class)
259
265
  end
@@ -264,22 +270,23 @@ module ApiRegulator
264
270
  @validators[[controller.to_s, action.to_s, code].compact]
265
271
  end
266
272
 
267
- def self.build_class(params)
273
+ def self.build_class(params, validation_context)
268
274
  Class.new do
269
275
  include ActiveModel::Model
270
276
  include ActiveModel::Attributes
271
277
  include AttributeDefinitionMixin
272
278
 
279
+ attr_reader :raw_attributes
280
+
273
281
  def initialize(attributes = {})
274
282
  attributes = {} if attributes.blank?
275
283
  @raw_attributes = attributes.deep_symbolize_keys
276
- self.class.defined_attributes
277
284
  allowed_attributes = attributes.slice(*self.class.defined_attributes.map(&:to_sym))
278
285
  super(allowed_attributes)
279
286
  end
280
287
 
281
288
  params.each do |param|
282
- define_attribute_and_validations(param)
289
+ define_attribute_and_validations(param, validation_context:)
283
290
  end
284
291
  end
285
292
  end
@@ -1,3 +1,3 @@
1
1
  module ApiRegulator
2
- VERSION = "0.1.12"
2
+ VERSION = "0.1.13"
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.12
4
+ version: 0.1.13
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-22 00:00:00.000000000 Z
11
+ date: 2025-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport