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 +4 -4
- data/Gemfile.lock +28 -21
- data/lib/api_regulator/param.rb +7 -6
- data/lib/api_regulator/validator.rb +27 -20
- data/lib/api_regulator/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd01d986f35199767ed09aeca6b5a5b0b19441113fa10b2fa5b34a511a4773ab
|
4
|
+
data.tar.gz: 02e722bd4b5df9a728a9ff1a339922cd891e9ae0eca9bf516b653bab3132c379
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
84
|
+
bigdecimal (3.1.9)
|
85
85
|
builder (3.3.0)
|
86
86
|
byebug (11.1.3)
|
87
|
-
concurrent-ruby (1.3.
|
88
|
-
connection_pool (2.
|
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.
|
93
|
+
erubi (1.13.1)
|
94
94
|
globalid (1.2.1)
|
95
95
|
activesupport (>= 6.1)
|
96
|
-
i18n (1.14.
|
96
|
+
i18n (1.14.7)
|
97
97
|
concurrent-ruby (~> 1.0)
|
98
|
-
io-console (0.
|
99
|
-
irb (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.
|
103
|
-
loofah (2.
|
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.
|
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.
|
126
|
+
nokogiri (1.18.2)
|
126
127
|
mini_portile2 (~> 2.8.2)
|
127
128
|
racc (~> 1.4)
|
128
|
-
nokogiri (1.
|
129
|
+
nokogiri (1.18.2-arm64-darwin)
|
129
130
|
racc (~> 1.4)
|
130
|
-
|
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.
|
139
|
+
rack-session (2.1.0)
|
140
|
+
base64 (>= 0.1.0)
|
135
141
|
rack (>= 3.0.0)
|
136
|
-
rack-test (2.
|
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.
|
176
|
+
rdoc (6.11.0)
|
171
177
|
psych (>= 4.0.0)
|
172
|
-
reline (0.
|
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.
|
195
|
-
securerandom (0.4.
|
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.
|
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)
|
data/lib/api_regulator/param.rb
CHANGED
@@ -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
|
50
|
-
|
51
|
-
elsif @options[:presence][:
|
52
|
-
Array(@options[:presence][:
|
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
|
-
#
|
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
|
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,
|
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
|
-
|
38
|
-
validate -> {
|
39
|
-
validate -> {
|
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
|
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.
|
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-
|
11
|
+
date: 2025-01-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|