validate-params 0.6.1 → 0.7.0
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 +356 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +2 -1
- data/README.md +2 -0
- data/docker-compose.yml +12 -0
- data/lib/validate_params/param_builder.rb +19 -0
- data/lib/validate_params/param_validator.rb +92 -0
- data/lib/validate_params/types/array.rb +25 -0
- data/lib/validate_params/types/date.rb +32 -19
- data/lib/validate_params/types/date_time.rb +11 -1
- data/lib/validate_params/types/integer.rb +15 -10
- data/lib/validate_params/types/string.rb +11 -0
- data/lib/validate_params/validatable.rb +89 -120
- data/lib/validate_params/version.rb +1 -1
- data/lib/validate_params.rb +2 -2
- data/validate_params.gemspec +1 -0
- metadata +21 -3
- data/lib/validate_params/validators/date.rb +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7626ebe2f24591c008739bce05f28938e39094dc057ce65b227e7f99130c21cc
|
4
|
+
data.tar.gz: 10f86e031e06e0c8723792d399881d4cc9baa64d9841eca1a1123c13606519ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b90773a69bdb7d7a8f65df932f78c3c0da3b4937540d4da8ca89695a0113548dffbe45760ff49ee0d6e89b718fb1d689c3f778a0887562290d2e5092956e13a7
|
7
|
+
data.tar.gz: 18a1f5f2d8b0aec4210e8ad50f9d1a715e6f1aa01ab7cf74af77c4fffdbbe4b1f0c16a38b9b57a1df2a83cb3834bb7a9d908ff1b981a71206131e2c4ffaa7726
|
data/.rubocop.yml
CHANGED
@@ -1,13 +1,365 @@
|
|
1
1
|
AllCops:
|
2
|
-
TargetRubyVersion: 2.7
|
2
|
+
TargetRubyVersion: 2.7.0
|
3
3
|
|
4
|
+
# https://edgeguides.rubyonrails.org/contributing_to_ruby_on_rails.html#follow-the-coding-conventions
|
5
|
+
|
6
|
+
# No blank line after access modifiers
|
7
|
+
Layout/EmptyLinesAroundAccessModifier:
|
8
|
+
EnforcedStyle: only_before
|
9
|
+
|
10
|
+
# Hard to use with WSL2
|
11
|
+
Layout/EndOfLine:
|
12
|
+
Enabled: false
|
13
|
+
|
14
|
+
# First element shall always be relative to the first position of the line where the opening bracket is
|
15
|
+
Layout/FirstArrayElementIndentation:
|
16
|
+
EnforcedStyle: consistent
|
17
|
+
|
18
|
+
# First key shall always be relative to the first position of the line where the opening brace is
|
19
|
+
Layout/FirstHashElementIndentation:
|
20
|
+
EnforcedStyle: consistent
|
21
|
+
|
22
|
+
# Table-like left alignment of keys, hash rockets, and values
|
23
|
+
Layout/HashAlignment:
|
24
|
+
EnforcedHashRocketStyle: table
|
25
|
+
|
26
|
+
# Method definitions after access modifiers isolated calls need one extra level of indentation
|
27
|
+
Layout/IndentationConsistency:
|
28
|
+
EnforcedStyle: indented_internal_methods
|
29
|
+
|
30
|
+
# The second operand should be indented is binary operations that span more than one line
|
31
|
+
Layout/MultilineOperationIndentation:
|
32
|
+
EnforcedStyle: indented
|
33
|
+
|
34
|
+
# Braces around single line blocks, do..end around multi-line blocks, except for multi-line blocks
|
35
|
+
# whose return value is being chained with another method
|
36
|
+
Style/BlockDelimiters:
|
37
|
+
EnforcedStyle: braces_for_chaining
|
38
|
+
|
39
|
+
# Enforce the block end operator to go on its own line in empty methods
|
40
|
+
Style/EmptyMethod:
|
41
|
+
EnforcedStyle: expanded
|
42
|
+
|
43
|
+
# Enforce absence of braces around hash literal as a last array item
|
44
|
+
Style/HashAsLastArrayItem:
|
45
|
+
EnforcedStyle: no_braces
|
46
|
+
|
47
|
+
# Use double quotes for string literals
|
4
48
|
Style/StringLiterals:
|
5
|
-
Enabled: true
|
6
49
|
EnforcedStyle: double_quotes
|
7
50
|
|
51
|
+
# Use double quotes inside expressions in interpolated strings
|
8
52
|
Style/StringLiteralsInInterpolation:
|
9
|
-
Enabled: true
|
10
53
|
EnforcedStyle: double_quotes
|
11
54
|
|
55
|
+
# Use %w or %W for arrays of words whose element count is greater than or equal to 5
|
56
|
+
Style/WordArray:
|
57
|
+
MinSize: 5
|
58
|
+
|
59
|
+
Style/BlockComments:
|
60
|
+
Enabled: false
|
61
|
+
|
62
|
+
Style/ClassAndModuleChildren:
|
63
|
+
Enabled: false
|
64
|
+
|
65
|
+
Style/Documentation:
|
66
|
+
Enabled: false
|
67
|
+
|
68
|
+
Style/HashSyntax:
|
69
|
+
EnforcedShorthandSyntax: never
|
70
|
+
|
71
|
+
Style/FrozenStringLiteralComment:
|
72
|
+
Enabled: false
|
73
|
+
|
74
|
+
Bundler/OrderedGems:
|
75
|
+
Enabled: false
|
76
|
+
|
77
|
+
Metrics/AbcSize:
|
78
|
+
Enabled: false
|
79
|
+
|
80
|
+
Metrics/BlockLength:
|
81
|
+
Enabled: false
|
82
|
+
|
83
|
+
Metrics/BlockNesting:
|
84
|
+
Enabled: false
|
85
|
+
|
86
|
+
Metrics/ClassLength:
|
87
|
+
Enabled: false
|
88
|
+
|
89
|
+
Metrics/CyclomaticComplexity:
|
90
|
+
Enabled: false
|
91
|
+
|
92
|
+
Metrics/MethodLength:
|
93
|
+
Enabled: false
|
94
|
+
|
95
|
+
Metrics/ModuleLength:
|
96
|
+
Enabled: false
|
97
|
+
|
98
|
+
Metrics/ParameterLists:
|
99
|
+
Enabled: false
|
100
|
+
|
101
|
+
Metrics/PerceivedComplexity:
|
102
|
+
Enabled: false
|
103
|
+
|
104
|
+
# ┌──────────────────────────────────────────────────────────┐
|
105
|
+
# │TODO: Consider refactoring and applying the following cops│
|
106
|
+
# └──────────────────────────────────────────────────────────┘
|
107
|
+
|
108
|
+
Style/ClassVars:
|
109
|
+
Enabled: false
|
110
|
+
|
111
|
+
Style/CombinableLoops:
|
112
|
+
Enabled: false
|
113
|
+
|
114
|
+
Style/For:
|
115
|
+
Enabled: false
|
116
|
+
|
117
|
+
Style/FloatDivision:
|
118
|
+
Enabled: false
|
119
|
+
|
120
|
+
Style/GlobalVars:
|
121
|
+
Enabled: false
|
122
|
+
|
123
|
+
Style/GuardClause:
|
124
|
+
Enabled: false
|
125
|
+
|
126
|
+
Style/HashLikeCase:
|
127
|
+
Enabled: false
|
128
|
+
|
129
|
+
Style/IdenticalConditionalBranches:
|
130
|
+
Enabled: false
|
131
|
+
|
132
|
+
Style/IfUnlessModifier:
|
133
|
+
Enabled: false
|
134
|
+
|
135
|
+
Style/InfiniteLoop:
|
136
|
+
Enabled: false
|
137
|
+
|
138
|
+
Style/InverseMethods:
|
139
|
+
Enabled: false
|
140
|
+
|
141
|
+
Style/KeywordParametersOrder:
|
142
|
+
Enabled: false
|
143
|
+
|
144
|
+
Style/Lambda:
|
145
|
+
Enabled: false
|
146
|
+
|
147
|
+
Style/LineEndConcatenation:
|
148
|
+
Enabled: false
|
149
|
+
|
150
|
+
Style/MixinUsage:
|
151
|
+
Enabled: false
|
152
|
+
|
153
|
+
Style/NegatedIf:
|
154
|
+
Enabled: false
|
155
|
+
|
156
|
+
Style/Next:
|
157
|
+
Enabled: false
|
158
|
+
|
159
|
+
Style/Not:
|
160
|
+
Enabled: false
|
161
|
+
|
162
|
+
Style/NumericLiterals:
|
163
|
+
Enabled: false
|
164
|
+
|
165
|
+
Style/MultilineBlockChain:
|
166
|
+
Enabled: false
|
167
|
+
|
168
|
+
Style/MultilineIfModifier:
|
169
|
+
Enabled: false
|
170
|
+
|
171
|
+
Style/MultipleComparison:
|
172
|
+
Enabled: false
|
173
|
+
|
174
|
+
Style/MultilineTernaryOperator:
|
175
|
+
Enabled: false
|
176
|
+
|
177
|
+
Style/MutableConstant:
|
178
|
+
Enabled: false
|
179
|
+
|
180
|
+
Style/NestedParenthesizedCalls:
|
181
|
+
Enabled: false
|
182
|
+
|
183
|
+
Style/NestedTernaryOperator:
|
184
|
+
Enabled: false
|
185
|
+
|
186
|
+
Style/NumericLiteralPrefix:
|
187
|
+
Enabled: false
|
188
|
+
|
189
|
+
Style/NumericPredicate:
|
190
|
+
Enabled: false
|
191
|
+
|
192
|
+
Style/OptionalBooleanParameter:
|
193
|
+
Enabled: false
|
194
|
+
|
195
|
+
Style/OrAssignment:
|
196
|
+
Enabled: false
|
197
|
+
|
198
|
+
Style/PerlBackrefs:
|
199
|
+
Enabled: false
|
200
|
+
|
201
|
+
Style/PreferredHashMethods:
|
202
|
+
Enabled: false
|
203
|
+
|
204
|
+
Style/RaiseArgs:
|
205
|
+
Enabled: false
|
206
|
+
|
207
|
+
Style/RedundantAssignment:
|
208
|
+
Enabled: false
|
209
|
+
|
210
|
+
Style/RedundantFetchBlock:
|
211
|
+
Enabled: false
|
212
|
+
|
213
|
+
Style/RedundantInterpolation:
|
214
|
+
Enabled: false
|
215
|
+
|
216
|
+
Style/RedundantRegexpEscape:
|
217
|
+
Enabled: false
|
218
|
+
|
219
|
+
Style/RedundantSelf:
|
220
|
+
Enabled: false
|
221
|
+
|
222
|
+
Style/RegexpLiteral:
|
223
|
+
Enabled: false
|
224
|
+
|
225
|
+
Style/RescueModifier:
|
226
|
+
Enabled: false
|
227
|
+
|
228
|
+
Style/RescueStandardError:
|
229
|
+
Enabled: false
|
230
|
+
|
231
|
+
Style/SafeNavigation:
|
232
|
+
Enabled: false
|
233
|
+
|
234
|
+
Style/SignalException:
|
235
|
+
Enabled: false
|
236
|
+
|
237
|
+
Style/SlicingWithRange:
|
238
|
+
Enabled: false
|
239
|
+
|
240
|
+
Style/SoleNestedConditional:
|
241
|
+
Enabled: false
|
242
|
+
|
243
|
+
Style/StringConcatenation:
|
244
|
+
Enabled: false
|
245
|
+
|
246
|
+
Style/StructInheritance:
|
247
|
+
Enabled: false
|
248
|
+
|
249
|
+
Style/SymbolArray:
|
250
|
+
Enabled: false
|
251
|
+
|
252
|
+
Style/SymbolProc:
|
253
|
+
Enabled: false
|
254
|
+
|
255
|
+
Style/UnlessElse:
|
256
|
+
Enabled: true
|
257
|
+
|
258
|
+
Style/WhileUntilDo:
|
259
|
+
Enabled: false
|
260
|
+
|
261
|
+
Style/WhileUntilModifier:
|
262
|
+
Enabled: false
|
263
|
+
|
264
|
+
Lint/AssignmentInCondition:
|
265
|
+
Enabled: false
|
266
|
+
|
267
|
+
Lint/BinaryOperatorWithIdenticalOperands:
|
268
|
+
Enabled: false
|
269
|
+
|
270
|
+
Lint/BooleanSymbol:
|
271
|
+
Enabled: false
|
272
|
+
|
273
|
+
Lint/CircularArgumentReference:
|
274
|
+
Enabled: false
|
275
|
+
|
276
|
+
Lint/DisjunctiveAssignmentInConstructor:
|
277
|
+
Enabled: false
|
278
|
+
|
279
|
+
Lint/DuplicateMethods:
|
280
|
+
Enabled: false
|
281
|
+
|
282
|
+
Lint/EmptyConditionalBody:
|
283
|
+
Enabled: false
|
284
|
+
|
285
|
+
Lint/EmptyWhen:
|
286
|
+
Enabled: false
|
287
|
+
|
288
|
+
Style/IfInsideElse:
|
289
|
+
Enabled: false
|
290
|
+
|
291
|
+
Lint/IneffectiveAccessModifier:
|
292
|
+
Enabled: false
|
293
|
+
|
294
|
+
Lint/MissingSuper:
|
295
|
+
Enabled: false
|
296
|
+
|
297
|
+
Lint/NestedMethodDefinition:
|
298
|
+
Enabled: false
|
299
|
+
|
300
|
+
Lint/NonDeterministicRequireOrder:
|
301
|
+
Enabled: false
|
302
|
+
|
303
|
+
Lint/ParenthesesAsGroupedExpression:
|
304
|
+
Enabled: false
|
305
|
+
|
306
|
+
Lint/RedundantWithIndex:
|
307
|
+
Enabled: false
|
308
|
+
|
309
|
+
Lint/RequireParentheses:
|
310
|
+
Enabled: false
|
311
|
+
|
312
|
+
Lint/RescueException:
|
313
|
+
Enabled: false
|
314
|
+
|
315
|
+
Lint/ShadowedArgument:
|
316
|
+
Enabled: false
|
317
|
+
|
318
|
+
Lint/SuppressedException:
|
319
|
+
Enabled: false
|
320
|
+
|
321
|
+
Lint/ToJSON:
|
322
|
+
Enabled: false
|
323
|
+
|
324
|
+
Lint/UnusedBlockArgument:
|
325
|
+
Enabled: false
|
326
|
+
|
327
|
+
Lint/UnusedMethodArgument:
|
328
|
+
Enabled: false
|
329
|
+
|
330
|
+
Lint/UriRegexp:
|
331
|
+
Enabled: false
|
332
|
+
|
333
|
+
Lint/UselessAccessModifier:
|
334
|
+
Enabled: false
|
335
|
+
|
12
336
|
Layout/LineLength:
|
13
|
-
|
337
|
+
Enabled: false
|
338
|
+
|
339
|
+
Naming/AccessorMethodName:
|
340
|
+
Enabled: false
|
341
|
+
|
342
|
+
Naming/MemoizedInstanceVariableName:
|
343
|
+
Enabled: false
|
344
|
+
|
345
|
+
Naming/MethodParameterName:
|
346
|
+
Enabled: false
|
347
|
+
|
348
|
+
Naming/PredicateName:
|
349
|
+
Enabled: false
|
350
|
+
|
351
|
+
Naming/VariableNumber:
|
352
|
+
Enabled: false
|
353
|
+
|
354
|
+
# ┌──────────────────────────────────────────────────────────┐
|
355
|
+
# │Enabled pending cops. Remove when added to default config │
|
356
|
+
# └──────────────────────────────────────────────────────────┘
|
357
|
+
|
358
|
+
Style/StringChars:
|
359
|
+
Enabled: true
|
360
|
+
|
361
|
+
Style/RedundantInitialize:
|
362
|
+
Enabled: true
|
363
|
+
|
364
|
+
Style/CaseEquality:
|
365
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -26,6 +26,8 @@ class TestController < ActionController::Base
|
|
26
26
|
p.param :name, String, default: "John Doe"
|
27
27
|
p.param :occurred_on, Date, required: true, default: proc { Date.today }
|
28
28
|
p.param :quantity, Integer, required: true, in: [1, 2, 3]
|
29
|
+
p.param :user_ids, Array, of: Integer, default: [1, 2, 3]
|
30
|
+
p.param :states, Array, of: String, default: ["active", "inactive"]
|
29
31
|
p.param :date_of_birth, Hash do |pp|
|
30
32
|
pp.param :gt, Date
|
31
33
|
pp.param :lt, Date
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ValidateParams
|
4
|
+
module Validatable
|
5
|
+
class ParamBuilder
|
6
|
+
def initialize(parent_field = nil)
|
7
|
+
@parent_field = parent_field
|
8
|
+
@params_validations = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def param(field, type, options = {})
|
12
|
+
return { field: field, type: type, options: options } if @parent_field.nil?
|
13
|
+
|
14
|
+
@params_validations << { field: { @parent_field => field }, type: type, options: options }
|
15
|
+
@params_validations
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/inflector"
|
4
|
+
|
5
|
+
module ValidateParams
|
6
|
+
module Validatable
|
7
|
+
class ParamValidator
|
8
|
+
def self.call(**args)
|
9
|
+
new(**args).call
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(type:, field:, value:, errors:, options: {})
|
13
|
+
@type = type
|
14
|
+
@field = field
|
15
|
+
@value = value
|
16
|
+
@errors = errors
|
17
|
+
@options = options
|
18
|
+
end
|
19
|
+
|
20
|
+
def call
|
21
|
+
return if @value.blank? && !@options[:required]
|
22
|
+
|
23
|
+
if @value.blank? && @options[:required]
|
24
|
+
@errors << { message: required_error_message }
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
send(@type.to_s.underscore)
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
def array
|
33
|
+
return if Types::Array.valid?(@value, of: @options[:of])
|
34
|
+
|
35
|
+
@errors << { message: error_message }
|
36
|
+
end
|
37
|
+
|
38
|
+
def date
|
39
|
+
return if Types::Date.valid?(@value)
|
40
|
+
|
41
|
+
@errors << { message: error_message }
|
42
|
+
end
|
43
|
+
|
44
|
+
def date_time
|
45
|
+
return if Types::DateTime.valid?(@value)
|
46
|
+
|
47
|
+
@errors << { message: error_message }
|
48
|
+
end
|
49
|
+
|
50
|
+
def integer
|
51
|
+
unless Types::Integer.valid?(@value)
|
52
|
+
@errors << { message: error_message }
|
53
|
+
return
|
54
|
+
end
|
55
|
+
|
56
|
+
validate_inclusion if @options[:in].present?
|
57
|
+
end
|
58
|
+
|
59
|
+
def string
|
60
|
+
validate_inclusion if @options[:in].present?
|
61
|
+
end
|
62
|
+
|
63
|
+
def validate_inclusion
|
64
|
+
return if @options[:in].include?(value)
|
65
|
+
|
66
|
+
@errors << {
|
67
|
+
message: I18n.t("validate_params.invalid_in", param: error_param_name),
|
68
|
+
valid_values: @options[:in]
|
69
|
+
}
|
70
|
+
end
|
71
|
+
|
72
|
+
def error_param_name
|
73
|
+
case @field
|
74
|
+
when Array
|
75
|
+
"#{@field[0]}[#{@field[1]}]"
|
76
|
+
when Hash
|
77
|
+
@field.map { |k, v| "#{k}[#{v}]" }.first
|
78
|
+
else
|
79
|
+
@field
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def error_message
|
84
|
+
I18n.t("validate_params.invalid_type", param: error_param_name, type: @type)
|
85
|
+
end
|
86
|
+
|
87
|
+
def required_error_message
|
88
|
+
I18n.t("validate_params.required", param: error_param_name)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ValidateParams
|
4
|
+
class Types
|
5
|
+
class Array
|
6
|
+
def self.valid?(value, of: String)
|
7
|
+
case of.to_s
|
8
|
+
when "Integer"
|
9
|
+
value.all? { |item| Types::Integer.valid?(item) }
|
10
|
+
else
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.cast(raw_value, of: String)
|
16
|
+
case of.to_s
|
17
|
+
when "Integer"
|
18
|
+
raw_value.map { |item| Types::Integer.cast(item) }
|
19
|
+
else
|
20
|
+
raw_value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -1,19 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ValidateParams
|
4
|
+
class Types
|
5
|
+
class Date
|
6
|
+
FORMAT = "%Y-%m-%d"
|
7
|
+
|
8
|
+
def self.valid?(value)
|
9
|
+
value = value.to_s
|
10
|
+
return false unless /\d{4}-\d{2}-\d{2}/.match?(value)
|
11
|
+
|
12
|
+
parsed_date = begin
|
13
|
+
::Date.strptime(value, FORMAT)
|
14
|
+
rescue StandardError
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
return false if parsed_date.nil?
|
18
|
+
return false if parsed_date.year > 9999
|
19
|
+
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.cast(raw_value)
|
24
|
+
return raw_value if raw_value.is_a?(::Date)
|
25
|
+
|
26
|
+
::Date.strptime(raw_value.to_s, FORMAT)
|
27
|
+
rescue StandardError
|
28
|
+
raw_value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ValidateParams
|
2
4
|
class Types
|
3
5
|
class DateTime
|
@@ -7,6 +9,14 @@ module ValidateParams
|
|
7
9
|
rescue ArgumentError, TypeError
|
8
10
|
false
|
9
11
|
end
|
12
|
+
|
13
|
+
def self.cast(raw_value)
|
14
|
+
return raw_value if raw_value.is_a?(::Time)
|
15
|
+
|
16
|
+
Time.at(Integer(raw_value))
|
17
|
+
rescue ArgumentError, TypeError
|
18
|
+
raw_value
|
19
|
+
end
|
10
20
|
end
|
11
21
|
end
|
12
|
-
end
|
22
|
+
end
|
@@ -1,10 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ValidateParams
|
4
|
+
class Types
|
5
|
+
class Integer
|
6
|
+
def self.valid?(value)
|
7
|
+
/\A[-+]?\d+\z/ === value.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.cast(raw_value)
|
11
|
+
raw_value.to_i
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -3,6 +3,11 @@
|
|
3
3
|
require "validate_params/types/date"
|
4
4
|
require "validate_params/types/date_time"
|
5
5
|
require "validate_params/types/integer"
|
6
|
+
require "validate_params/types/array"
|
7
|
+
require_relative "param_builder"
|
8
|
+
require_relative "param_validator"
|
9
|
+
|
10
|
+
require "active_support/concern"
|
6
11
|
|
7
12
|
module ValidateParams
|
8
13
|
module Validatable
|
@@ -48,142 +53,106 @@ module ValidateParams
|
|
48
53
|
end
|
49
54
|
|
50
55
|
private
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
end
|
70
|
-
|
71
|
-
def set_params_defaults
|
72
|
-
params_validations.each do |params_validation|
|
73
|
-
next if params_validation[:options][:default].blank?
|
74
|
-
|
75
|
-
if params_validation[:field].is_a?(Hash)
|
76
|
-
params_validation[:field].each_key do |key|
|
77
|
-
# Skip in case hash is configured and string is passed
|
78
|
-
next if params.dig(key).is_a? Hash
|
79
|
-
next if params.dig(key, params_validation[:field][key])
|
80
|
-
|
56
|
+
def set_params_defaults
|
57
|
+
params_validations.each do |params_validation|
|
58
|
+
next unless params_validation[:options].key?(:default)
|
59
|
+
|
60
|
+
if params_validation[:field].is_a?(Hash)
|
61
|
+
params_validation[:field].each_key do |key|
|
62
|
+
# Skip in case hash is configured and string is passed
|
63
|
+
next if params[key].is_a? Hash
|
64
|
+
next if params.dig(key, params_validation[:field][key])
|
65
|
+
|
66
|
+
value = if params_validation[:options][:default].is_a?(Proc)
|
67
|
+
params_validation[:options][:default].call
|
68
|
+
else
|
69
|
+
params_validation[:options][:default]
|
70
|
+
end
|
71
|
+
params.deep_merge!(key => { params_validation[:field][key] => value })
|
72
|
+
end
|
73
|
+
else
|
81
74
|
value = if params_validation[:options][:default].is_a?(Proc)
|
82
75
|
params_validation[:options][:default].call
|
83
76
|
else
|
84
77
|
params_validation[:options][:default]
|
85
78
|
end
|
86
|
-
params.merge!(key => { params_validation[:field][key] => value })
|
87
|
-
end
|
88
|
-
else
|
89
|
-
value = if params_validation[:options][:default].is_a?(Proc)
|
90
|
-
params_validation[:options][:default].call
|
91
|
-
else
|
92
|
-
params_validation[:options][:default]
|
93
|
-
end
|
94
|
-
|
95
|
-
params[params_validation[:field]] ||= value
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
def perform_validate_params
|
101
|
-
return unless controller_action.present? && controller_action == action_name.to_sym
|
102
|
-
|
103
|
-
errors = []
|
104
79
|
|
105
|
-
|
106
|
-
# Skip in case hash is configured and string is passed
|
107
|
-
next if params_validation[:field].is_a?(Hash) &&
|
108
|
-
params.dig(params_validation[:field].keys.first).is_a?(String)
|
80
|
+
params[params_validation[:field]] ||= value
|
109
81
|
|
110
|
-
parameter_value = if params_validation[:field].is_a? Hash
|
111
|
-
params.dig(params_validation[:field].keys.first,
|
112
|
-
params_validation[:field][params_validation[:field].keys.first])
|
113
|
-
else
|
114
|
-
params[params_validation[:field]]
|
115
|
-
end
|
116
|
-
|
117
|
-
next if parameter_value.blank? && !params_validation[:options][:required]
|
118
|
-
|
119
|
-
if parameter_value.blank? && params_validation[:options][:required]
|
120
|
-
errors << { message: build_required_message(error_param_name(params_validation[:field])) }
|
121
|
-
next
|
122
|
-
end
|
123
|
-
|
124
|
-
case params_validation[:type].to_s
|
125
|
-
when "Date"
|
126
|
-
unless ValidateParams::Types::Date.valid?(parameter_value)
|
127
|
-
errors << {
|
128
|
-
message: build_error_message(error_param_name(params_validation[:field]), params_validation[:type])
|
129
|
-
}
|
130
|
-
end
|
131
|
-
when "DateTime"
|
132
|
-
unless ValidateParams::Types::DateTime.valid?(parameter_value)
|
133
|
-
errors << {
|
134
|
-
message: build_error_message(error_param_name(params_validation[:field]), params_validation[:type])
|
135
|
-
}
|
136
|
-
end
|
137
|
-
when "Integer"
|
138
|
-
unless ValidateParams::Types::Integer.valid?(parameter_value)
|
139
|
-
errors << {
|
140
|
-
message: build_error_message(error_param_name(params_validation[:field]), params_validation[:type])
|
141
|
-
}
|
142
|
-
next
|
143
|
-
end
|
144
|
-
|
145
|
-
parameter_value = parameter_value.to_i
|
146
|
-
if params_validation[:options][:in].present? && !params_validation[:options][:in].include?(parameter_value)
|
147
|
-
errors << {
|
148
|
-
message: I18n.t("validate_params.invalid_in", param: error_param_name(params_validation[:field])),
|
149
|
-
valid_values: params_validation[:options][:in]
|
150
|
-
}
|
151
|
-
end
|
152
|
-
when "String"
|
153
|
-
parameter_value = parameter_value.to_s
|
154
|
-
if params_validation[:options][:in].present? && !params_validation[:options][:in].include?(parameter_value)
|
155
|
-
errors << {
|
156
|
-
message: I18n.t("validate_params.invalid_in", param: error_param_name(params_validation[:field])),
|
157
|
-
valid_values: params_validation[:options][:in]
|
158
|
-
}
|
159
82
|
end
|
160
83
|
end
|
161
84
|
end
|
162
85
|
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
86
|
+
def cast_param_values
|
87
|
+
params_validations.each do |params_validation|
|
88
|
+
if params_validation[:field].is_a?(Hash)
|
89
|
+
params_validation[:field].each_key do |key|
|
90
|
+
next unless params[key].is_a?(Hash)
|
91
|
+
|
92
|
+
value = params.dig(key, params_validation[:field][key])
|
93
|
+
next if value.blank?
|
94
|
+
|
95
|
+
params.deep_merge!(
|
96
|
+
key => {
|
97
|
+
params_validation[:field][key] => if params_validation[:type].name == "Array"
|
98
|
+
Types.const_get(params_validation[:type].name).cast(value,
|
99
|
+
of: params_validation[:options][:of])
|
100
|
+
else
|
101
|
+
Types.const_get(params_validation[:type].name).cast(value)
|
102
|
+
end
|
103
|
+
}
|
104
|
+
)
|
105
|
+
end
|
106
|
+
else
|
107
|
+
value = params[params_validation[:field]]
|
108
|
+
next if value.blank?
|
109
|
+
|
110
|
+
params[params_validation[:field]] = if params_validation[:type].name == "Array"
|
111
|
+
Types.const_get(params_validation[:type].name).cast(value, of: params_validation[:options][:of])
|
112
|
+
else
|
113
|
+
Types.const_get(params_validation[:type].name).cast(value)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
170
117
|
end
|
171
|
-
end
|
172
118
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
119
|
+
def perform_validate_params
|
120
|
+
return unless controller_action.present? && controller_action == action_name.to_sym
|
121
|
+
|
122
|
+
errors = []
|
123
|
+
|
124
|
+
params_validations.each do |params_validation|
|
125
|
+
# Skip in case hash is configured and string is passed
|
126
|
+
next if params_validation[:field].is_a?(Hash) &&
|
127
|
+
params[params_validation[:field].keys.first].is_a?(String)
|
128
|
+
|
129
|
+
parameter_value = if params_validation[:field].is_a? Hash
|
130
|
+
params.dig(params_validation[:field].keys.first,
|
131
|
+
params_validation[:field][params_validation[:field].keys.first])
|
132
|
+
else
|
133
|
+
params[params_validation[:field]]
|
134
|
+
end
|
135
|
+
|
136
|
+
ParamValidator.call(
|
137
|
+
type: params_validation[:type],
|
138
|
+
field: params_validation[:field],
|
139
|
+
value: parameter_value,
|
140
|
+
errors: errors,
|
141
|
+
options: params_validation[:options]
|
142
|
+
)
|
143
|
+
end
|
178
144
|
|
179
|
-
|
180
|
-
|
181
|
-
return
|
145
|
+
if errors.empty?
|
146
|
+
cast_param_values
|
147
|
+
return
|
182
148
|
end
|
183
149
|
|
184
|
-
|
185
|
-
|
150
|
+
case response_format
|
151
|
+
when :html
|
152
|
+
head :bad_request
|
153
|
+
else
|
154
|
+
render json: { success: false, errors: errors }, status: :bad_request
|
155
|
+
end
|
186
156
|
end
|
187
|
-
end
|
188
157
|
end
|
189
158
|
end
|
data/lib/validate_params.rb
CHANGED
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
require_relative "validate_params/version"
|
4
4
|
require_relative "validate_params/validatable"
|
5
|
-
|
6
|
-
Dir[File.join(__dir__,
|
5
|
+
|
6
|
+
Dir[File.join(__dir__, "validate_params/types", "*.rb")].sort.each { |file| require file }
|
7
7
|
|
8
8
|
module ValidateParams
|
9
9
|
class Error < StandardError; end
|
data/validate_params.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validate-params
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dcherevatenko
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 6.1.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: i18n
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.6'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.6'
|
83
97
|
description: Provides a clean DSL to validate params for controller actions.
|
84
98
|
email:
|
85
99
|
- 'denis.cherevatenko@peopleforce.io '
|
@@ -95,12 +109,16 @@ files:
|
|
95
109
|
- README.md
|
96
110
|
- Rakefile
|
97
111
|
- config/locales/en.yml
|
112
|
+
- docker-compose.yml
|
98
113
|
- lib/validate_params.rb
|
114
|
+
- lib/validate_params/param_builder.rb
|
115
|
+
- lib/validate_params/param_validator.rb
|
116
|
+
- lib/validate_params/types/array.rb
|
99
117
|
- lib/validate_params/types/date.rb
|
100
118
|
- lib/validate_params/types/date_time.rb
|
101
119
|
- lib/validate_params/types/integer.rb
|
120
|
+
- lib/validate_params/types/string.rb
|
102
121
|
- lib/validate_params/validatable.rb
|
103
|
-
- lib/validate_params/validators/date.rb
|
104
122
|
- lib/validate_params/version.rb
|
105
123
|
- sig/validate_params.rbs
|
106
124
|
- validate_params.gemspec
|
File without changes
|